share/hedgewars/Data/Scripts/Multiplayer/Construction_Mode.lua
changeset 12950 a260d233cef3
parent 12949 4fa79a6a1883
child 12951 37b81c20358b
equal deleted inserted replaced
12949:4fa79a6a1883 12950:a260d233cef3
    53 
    53 
    54 HedgewarsScriptLoad("/Scripts/Locale.lua")
    54 HedgewarsScriptLoad("/Scripts/Locale.lua")
    55 HedgewarsScriptLoad("/Scripts/Tracker.lua")
    55 HedgewarsScriptLoad("/Scripts/Tracker.lua")
    56 HedgewarsScriptLoad("/Scripts/Params.lua")
    56 HedgewarsScriptLoad("/Scripts/Params.lua")
    57 
    57 
    58 ----------------------------------------------
    58 -- Structures stuff
    59 -- STRUCTURES STUFF
       
    60 ----------------------------------------------
       
    61 
       
    62 local strucID = {}
    59 local strucID = {}
    63 local strucGear = {}
    60 local strucGear = {}
    64 local strucClan = {}
    61 local strucClan = {}
    65 local strucType = {}
    62 local strucType = {}
    66 local strucCost = {}
    63 local strucCost = {}
    70 local strucCircCol = {}
    67 local strucCircCol = {}
    71 local strucCircRadius = {}
    68 local strucCircRadius = {}
    72 local strucCircType = {}
    69 local strucCircType = {}
    73 local strucAltDisplay = {}
    70 local strucAltDisplay = {}
    74 
    71 
    75 local fortMode = false
    72 -- Clan stuff
    76 
    73 local clanPower = {} -- current power for each clan. Used to build stuff
    77 local placedExpense = 0
    74 local clanPowerTag = nil -- visual gear ID of displayed clan power
    78 
    75 
    79 local globalTempID = nil
    76 local clanUsedExtraTime = {} -- has used extra time in this round?
    80 
    77 local clanCratesSpawned = {} -- number of crates spawned in this round
    81 local sUID = 0
    78 local clanFirstTurn = {}
    82 
       
    83 local cGear = nil
       
    84 
       
    85 local colorRed = 0xff0000ff
       
    86 local colorGreen = 0x00ff00ff
       
    87 
    79 
    88 local clanBoundsSX = {}
    80 local clanBoundsSX = {}
    89 local clanBoundsSY = {}
    81 local clanBoundsSY = {}
    90 local clanBoundsEX = {}
    82 local clanBoundsEX = {}
    91 local clanBoundsEY = {}
    83 local clanBoundsEY = {}
    92 
    84 
    93 local clanPower = {}
    85 -- For tracking previous mode selection per-team
    94 local clanID = {}
       
    95 
       
    96 -- for ease of use let's track previous selection
       
    97 local teamLStructIndex = {}
    86 local teamLStructIndex = {}
    98 local teamLObjectMode = {}
    87 local teamLObjectMode = {}
    99 local teamLCrateMode = {}
    88 local teamLCrateMode = {}
   100 local teamLMineIndex = {}
    89 local teamLMineIndex = {}
   101 local teamLWeapIndex = {}
    90 local teamLWeapIndex = {}
   102 local teamLUtilIndex = {}
    91 local teamLUtilIndex = {}
   103 
    92 
   104 local clanUsedExtraTime = {}
    93 -- Wall stuff
   105 local clanCratesSpawned = {}
       
   106 local clanFirstTurn = {}
       
   107 
       
   108 local effectTimer = 0
       
   109 
       
   110 local wallsVisible = false
    94 local wallsVisible = false
   111 local wX = {}
    95 local wX = {}
   112 local wY = {}
    96 local wY = {}
   113 local wWidth = {}
    97 local wWidth = {}
   114 local wHeight = {}
    98 local wHeight = {}
   115 local wCol = {}
    99 local wCol = {}
   116 local margin = 20
   100 local wMargin = 20
   117 
   101 local borderEffectTimer = 0 -- timer for border clan sparkles
   118 local clanPowerTag = nil
   102 
   119 local lastWep = nil
   103 -- Other stuff
   120 
   104 local placedExpense = 0 -- Cost of current selected thing
       
   105 local curWep = amNothing -- current weapon, used to reduce # of calls to GetCurAmmoType()
       
   106 
       
   107 local fortMode = false -- is using a fort map?
       
   108 local tempID_CheckProximity = nil -- temporary structure variable for CheckProximity
       
   109 local cGear = nil -- detects placement of girders and objects (using airattack)
       
   110 local uniqueStructureID = 0 -- Counter and ID for structures. Is incremented each time a structure spawns
       
   111 
       
   112 --[[ Hacky workaround for object placer: Since this thing is
       
   113 based on the drill strike, it allows the 5 timer keys to be
       
   114 pressed, causing the announcer to show up.
       
   115 This variable counts the number of ticks to count down until
       
   116 to overwrite this anouncer message.
       
   117 -1 means “do nothing”. ]]
   121 local checkForSpecialWeaponsIn = -1
   118 local checkForSpecialWeaponsIn = -1
       
   119 local lastWep = amNothing -- helper variable to track the previous hack
       
   120 
       
   121 -- Colors
       
   122 local colorRed = 0xff0000ff
       
   123 local colorGreen = 0x00ff00ff
   122 
   124 
   123 -- Fake ammo types, for the overwritten weapons in Construction Mode
   125 -- Fake ammo types, for the overwritten weapons in Construction Mode
   124 local amCMStructurePlacer = amAirAttack
   126 local amCMStructurePlacer = amAirAttack
   125 local amCMCratePlacer = amNapalm
   127 local amCMCratePlacer = amNapalm
   126 local amCMObjectPlacer = amDrillStrike
   128 local amCMObjectPlacer = amDrillStrike
   135 -- CRATE DEFINITIONS --
   137 -- CRATE DEFINITIONS --
   136 -----------------------
   138 -----------------------
   137 -- format:
   139 -- format:
   138 -- { ammoType, ammoTypeString, unused, cost }
   140 -- { ammoType, ammoTypeString, unused, cost }
   139 
   141 
   140 -- Cost factor
   142 local costFactor = 20
   141 local placeholder = 20
       
   142 
   143 
   143 -- WEAPON CRATES 
   144 -- WEAPON CRATES 
   144 -- Weapons which shouldn't be aded:
   145 -- Weapons which shouldn't be aded:
   145 -- Air attack, napalm, drillstrike: Overwritten weapons for the Construction Mode tools
   146 -- Air attack, napalm, drillstrike: Overwritten weapons for the Construction Mode tools
   146 local atkArray = {
   147 local atkArray = {
   147 	{amBazooka, 		"amBazooka",		0, 2*placeholder},
   148 	{amBazooka, 		"amBazooka",		0, 2*costFactor},
   148 	--{amBee, 		"amBee",		0, 4*placeholder},
   149 	--{amBee, 		"amBee",		0, 4*costFactor},
   149 	{amMortar, 		"amMortar",		0, 1*placeholder},
   150 	{amMortar, 		"amMortar",		0, 1*costFactor},
   150 	{amDrill, 		"amDrill",		0, 3*placeholder},
   151 	{amDrill, 		"amDrill",		0, 3*costFactor},
   151 	{amSnowball, 		"amSnowball",		0, 3*placeholder},
   152 	{amSnowball, 		"amSnowball",		0, 3*costFactor},
   152 
   153 
   153 	{amGrenade,		"amGrenade",		0, 2*placeholder},
   154 	{amGrenade,		"amGrenade",		0, 2*costFactor},
   154 	{amClusterBomb,		"amClusterBomb",	0, 3*placeholder},
   155 	{amClusterBomb,		"amClusterBomb",	0, 3*costFactor},
   155 	{amWatermelon, 		"amWatermelon",		0, 25*placeholder},
   156 	{amWatermelon, 		"amWatermelon",		0, 25*costFactor},
   156 	{amHellishBomb,		"amHellishBomb",	0, 25*placeholder},
   157 	{amHellishBomb,		"amHellishBomb",	0, 25*costFactor},
   157 	{amMolotov, 		"amMolotov",		0, 3*placeholder},
   158 	{amMolotov, 		"amMolotov",		0, 3*costFactor},
   158 	{amGasBomb, 		"amGasBomb",		0, 3*placeholder},
   159 	{amGasBomb, 		"amGasBomb",		0, 3*costFactor},
   159 
   160 
   160 	{amShotgun,		"amShotgun",		0, 2*placeholder},
   161 	{amShotgun,		"amShotgun",		0, 2*costFactor},
   161 	{amDEagle,		"amDEagle",		0, 2*placeholder},
   162 	{amDEagle,		"amDEagle",		0, 2*costFactor},
   162 	{amSniperRifle,		"amSniperRifle",	0, 3*placeholder},
   163 	{amSniperRifle,		"amSniperRifle",	0, 3*costFactor},
   163 	--{amSineGun, 		"amSineGun",		0, 6*placeholder},
   164 	--{amSineGun, 		"amSineGun",		0, 6*costFactor},
   164 	{amFlamethrower,	"amFlamethrower",	0, 4*placeholder},
   165 	{amFlamethrower,	"amFlamethrower",	0, 4*costFactor},
   165 	{amIceGun, 		"amIceGun",		0, 15*placeholder},
   166 	{amIceGun, 		"amIceGun",		0, 15*costFactor},
   166 
   167 
   167 	{amFirePunch, 		"amFirePunch",		0, 3*placeholder},
   168 	{amFirePunch, 		"amFirePunch",		0, 3*costFactor},
   168 	{amWhip,		"amWhip",		0, 1*placeholder},
   169 	{amWhip,		"amWhip",		0, 1*costFactor},
   169 	{amBaseballBat, 	"amBaseballBat",	0, 7*placeholder},
   170 	{amBaseballBat, 	"amBaseballBat",	0, 7*costFactor},
   170 	--{amKamikaze, 		"amKamikaze",		0, 1*placeholder},
   171 	--{amKamikaze, 		"amKamikaze",		0, 1*costFactor},
   171 	{amSeduction, 		"amSeduction",		0, 1*placeholder},
   172 	{amSeduction, 		"amSeduction",		0, 1*costFactor},
   172 	{amHammer,		"amHammer",		0, 1*placeholder},
   173 	{amHammer,		"amHammer",		0, 1*costFactor},
   173 
   174 
   174 	{amMine, 		"amMine",		0, 1*placeholder},
   175 	{amMine, 		"amMine",		0, 1*costFactor},
   175 	{amDynamite, 		"amDynamite",		0, 9*placeholder},
   176 	{amDynamite, 		"amDynamite",		0, 9*costFactor},
   176 	{amCake, 		"amCake",		0, 25*placeholder},
   177 	{amCake, 		"amCake",		0, 25*costFactor},
   177 	{amBallgun, 		"amBallgun",		0, 40*placeholder},
   178 	{amBallgun, 		"amBallgun",		0, 40*costFactor},
   178 	--{amRCPlane,		"amRCPlane",		0, 25*placeholder},
   179 	--{amRCPlane,		"amRCPlane",		0, 25*costFactor},
   179 	{amSMine,		"amSMine",		0, 5*placeholder},
   180 	{amSMine,		"amSMine",		0, 5*costFactor},
   180 
   181 
   181 	--{amMineStrike,	"amMineStrike",		0, 15*placeholder},
   182 	--{amMineStrike,	"amMineStrike",		0, 15*costFactor},
   182 	--{amPiano,		"amPiano",		0, 40*placeholder},
   183 	--{amPiano,		"amPiano",		0, 40*costFactor},
   183 
   184 
   184 	{amPickHammer,		"amPickHammer",		0, 2*placeholder},
   185 	{amPickHammer,		"amPickHammer",		0, 2*costFactor},
   185 	{amBlowTorch, 		"amBlowTorch",		0, 4*placeholder},
   186 	{amBlowTorch, 		"amBlowTorch",		0, 4*costFactor},
   186 	{amKnife,		"amKnife",		0, 2*placeholder},
   187 	{amKnife,		"amKnife",		0, 2*costFactor},
   187 
   188 
   188 	{amBirdy,		"amBirdy",		0, 7*placeholder},
   189 	{amBirdy,		"amBirdy",		0, 7*costFactor},
   189 
   190 
   190 	{amDuck,		"amDuck",		0, 2*placeholder}
   191 	{amDuck,		"amDuck",		0, 2*costFactor}
   191 }
   192 }
   192 
   193 
   193 -- UTILITY CRATES --
   194 -- UTILITY CRATES --
   194 
   195 
   195 -- Utilities which shouldn't be added:
   196 -- Utilities which shouldn't be added:
   199 -- * Resurrector: We have the resurrector structure for this
   200 -- * Resurrector: We have the resurrector structure for this
   200 
   201 
   201 -- Utilities which might be weird for this mode:
   202 -- Utilities which might be weird for this mode:
   202 -- * Tardis: Randomly teleports hog, maybe even into enemy clan's area
   203 -- * Tardis: Randomly teleports hog, maybe even into enemy clan's area
   203 local utilArray = {
   204 local utilArray = {
   204 	{amLandGun,		"amLandGun",		0, 5*placeholder},
   205 	{amLandGun,		"amLandGun",		0, 5*costFactor},
   205 
   206 
   206 	{amRope, 		"amRope",		0, 7*placeholder},
   207 	{amRope, 		"amRope",		0, 7*costFactor},
   207 	{amParachute, 		"amParachute",		0, 2*placeholder},
   208 	{amParachute, 		"amParachute",		0, 2*costFactor},
   208 	{amJetpack,		"amJetpack",		0, 8*placeholder},
   209 	{amJetpack,		"amJetpack",		0, 8*costFactor},
   209 	{amPortalGun,		"amPortalGun",		0, 15*placeholder},
   210 	{amPortalGun,		"amPortalGun",		0, 15*costFactor},
   210 
   211 
   211 	{amInvulnerable,	"amInvulnerable",	0, 5*placeholder},
   212 	{amInvulnerable,	"amInvulnerable",	0, 5*costFactor},
   212 	{amLaserSight,		"amLaserSight",		0, 2*placeholder},
   213 	{amLaserSight,		"amLaserSight",		0, 2*costFactor},
   213 	{amVampiric,		"amVampiric",		0, 6*placeholder},
   214 	{amVampiric,		"amVampiric",		0, 6*costFactor},
   214 
   215 
   215 	{amLowGravity, 		"amLowGravity",		0, 4*placeholder},
   216 	{amLowGravity, 		"amLowGravity",		0, 4*costFactor},
   216 	{amExtraDamage, 	"amExtraDamage",	0, 6*placeholder},
   217 	{amExtraDamage, 	"amExtraDamage",	0, 6*costFactor},
   217 	{amExtraTime,		"amExtraTime",		0, 8*placeholder}
   218 	{amExtraTime,		"amExtraTime",		0, 8*costFactor}
   218 }
   219 }
   219 
   220 
   220 ----------------------------
   221 ----------------------------
   221 -- Placement stuff
   222 -- Placement stuff
   222 ----------------------------
   223 ----------------------------
   223 
       
   224 local cGear = nil -- detects placement of girders and objects (using airattack)
       
   225 local curWep = amNothing
       
   226 
   224 
   227 -- primary placement categories
   225 -- primary placement categories
   228 local cIndex = 1 -- category index
   226 local cIndex = 1 -- category index
   229 local cat = {
   227 local cat = {
   230 	"Girder Placement Mode",
   228 	"Girder Placement Mode",
   257 
   255 
   258 
   256 
   259 local pMode = {}	-- pMode contains custom subsets of the main categories
   257 local pMode = {}	-- pMode contains custom subsets of the main categories
   260 local pIndex = 1
   258 local pIndex = 1
   261 
   259 
   262 local CGR = 1 -- current girder rotation, we actually need this as HW remembers what rotation you last used
   260 local currentGirderRotation = 1 -- current girder rotation, we actually need this as HW remembers what rotation you last used
   263 
       
   264 local placedX = {}
       
   265 local placedY = {}
       
   266 local placedSpec = {}
       
   267 local placedSuperSpec = {}
       
   268 local placedType = {}
       
   269 local placedCount = 0
       
   270 
       
   271 local sCirc -- circle that appears around selected gears
       
   272 local sGear = nil
       
   273 
       
   274 local tCirc = {} -- array of circles that appear around tagged gears
       
   275 
       
   276 
       
   277 
   261 
   278 function DrawClanPowerTag()
   262 function DrawClanPowerTag()
   279 
   263 
   280 	local zoomL = 1.1
   264 	local zoomL = 1.1
   281 	local xOffset = 45
   265 	local xOffset = 45
   333 
   317 
   334 end
   318 end
   335 
   319 
   336 function HandleBorderEffects()
   320 function HandleBorderEffects()
   337 
   321 
   338 	effectTimer = effectTimer + 1
   322 	borderEffectTimer = borderEffectTimer + 1
   339 	if effectTimer > 15 then
   323 	if borderEffectTimer > 15 then
   340 		effectTimer = 1
   324 		borderEffectTimer = 1
   341 		for i = 1, #wX do
   325 		for i = 1, #wX do
   342 			BorderSpark(wX[i],wY[i],wWidth[i],wHeight[i], wCol[i])
   326 			BorderSpark(wX[i],wY[i],wWidth[i],wHeight[i], wCol[i])
   343 		end
   327 		end
   344 	end
   328 	end
   345 
   329 
   448 	end
   432 	end
   449 end
   433 end
   450 
   434 
   451 function AddStruc(pX,pY, pType, pClan)
   435 function AddStruc(pX,pY, pType, pClan)
   452 
   436 
   453 	sUID = sUID + 1
   437 	uniqueStructureID = uniqueStructureID + 1
   454 
   438 
   455 	local tempG = AddGear(0, 0, gtTarget, 0, 0, 0, 0)
   439 	local tempG = AddGear(0, 0, gtTarget, 0, 0, 0, 0)
   456 	SetGearPosition(tempG, pX, pY)
   440 	SetGearPosition(tempG, pX, pY)
   457 	setGearValue(tempG, "sUID", sUID)
   441 	setGearValue(tempG, "uniqueStructureID", uniqueStructureID)
   458 
   442 
   459 	local tempCirc = AddVisualGear(0,0,vgtCircle,0,true)
   443 	local tempCirc = AddVisualGear(0,0,vgtCircle,0,true)
   460 
   444 
   461 	SetVisualGearValues(tempCirc, 0, 0, 100, 255, 1, 100, 0, 500, 1, 0xFFFFFF00)
   445 	SetVisualGearValues(tempCirc, 0, 0, 100, 255, 1, 100, 0, 500, 1, 0xFFFFFF00)
   462 
   446 
   463 	table.insert(strucID, sUID)
   447 	table.insert(strucID, uniqueStructureID)
   464 	table.insert(strucType, pType)
   448 	table.insert(strucType, pType)
   465 	table.insert(strucGear,tempG)
   449 	table.insert(strucGear,tempG)
   466 	table.insert(strucClan,pClan)
   450 	table.insert(strucClan,pClan)
   467 	table.insert(strucCost,2)
   451 	table.insert(strucCost,2)
   468 
   452 
   532 function CheckGearForStructureLink(gear)
   516 function CheckGearForStructureLink(gear)
   533 
   517 
   534 	local respawnerDestroyed = false
   518 	local respawnerDestroyed = false
   535 
   519 
   536 	for i = 1, #strucID do
   520 	for i = 1, #strucID do
   537 		if strucID[i] == getGearValue(gear,"sUID") then
   521 		if strucID[i] == getGearValue(gear,"uniqueStructureID") then
   538 
   522 
   539 			if strucType[i] == loc("Respawner") then
   523 			if strucType[i] == loc("Respawner") then
   540 				respawnerDestroyed = true
   524 				respawnerDestroyed = true
   541 			end
   525 			end
   542 
   526 
   657 end
   641 end
   658 
   642 
   659 --Check for proximity of gears to structures, and make structures behave accordingly
   643 --Check for proximity of gears to structures, and make structures behave accordingly
   660 function CheckProximity(gear)
   644 function CheckProximity(gear)
   661 
   645 
   662 	local dist = GetDistFromGearToXY(gear, GetX(strucGear[globalTempID]), GetY(strucGear[globalTempID]))
   646 	local sID = tempID_CheckProximity
       
   647 
       
   648 	local dist = GetDistFromGearToXY(gear, GetX(strucGear[sID]), GetY(strucGear[sID]))
   663 	if not dist then
   649 	if not dist then
   664 		return
   650 		return
   665 	end
   651 	end
   666 
   652 
   667 	-- calculate my real radius if I am an aura
   653 	-- calculate my real radius if I am an aura
   668 	local NR
   654 	local NR
   669 	if strucCircType[globalTempID] == 0 then
   655 	if strucCircType[sID] == 0 then
   670 		NR = strucCircRadius[globalTempID]
   656 		NR = strucCircRadius[sID]
   671 	else
   657 	else
   672 		NR = (48/100*strucCircRadius[globalTempID])/2
   658 		NR = (48/100*strucCircRadius[sID])/2
   673 	end
   659 	end
   674 
   660 
   675 	-- we're in business
   661 	-- we're in business
   676 	if dist <= NR*NR then
   662 	if dist <= NR*NR then
   677 
   663 
   678 		-- heal clan hogs
   664 		-- heal clan hogs
   679 		if strucType[globalTempID] == loc("Healing Station") then
   665 		if strucType[sID] == loc("Healing Station") then
   680 
   666 
   681 			if GetGearType(gear) == gtHedgehog then
   667 			if GetGearType(gear) == gtHedgehog then
   682 				if GetHogClan(gear) == strucClan[globalTempID] then
   668 				if GetHogClan(gear) == strucClan[sID] then
   683 
   669 
   684 					local hogLife = GetHealth(gear)
   670 					local hogLife = GetHealth(gear)
   685 					-- Heal hog by 1 HP, up to 150 HP total
   671 					-- Heal hog by 1 HP, up to 150 HP total
   686 					if hogLife < 150 then
   672 					if hogLife < 150 then
   687 						if ((hogLife + 1) % 5) == 0 then
   673 						if ((hogLife + 1) % 5) == 0 then
   691 							SetHealth(gear, hogLife+1)
   677 							SetHealth(gear, hogLife+1)
   692 						end
   678 						end
   693 					end
   679 					end
   694 
   680 
   695 					-- change this to the med kit sprite health ++++s later
   681 					-- change this to the med kit sprite health ++++s later
   696 					local tempE = AddVisualGear(GetX(strucGear[globalTempID]), GetY(strucGear[globalTempID]), vgtSmoke, 0, true)
   682 					local tempE = AddVisualGear(GetX(strucGear[sID]), GetY(strucGear[sID]), vgtSmoke, 0, true)
   697 					SetVisualGearValues(tempE, nil, nil, nil, nil, nil, nil, nil, nil, nil, colorGreen)
   683 					SetVisualGearValues(tempE, nil, nil, nil, nil, nil, nil, nil, nil, nil, colorGreen)
   698 
   684 
   699 				end
   685 				end
   700 			end
   686 			end
   701 
   687 
   702 		-- explode enemy clan hogs
   688 		-- explode enemy clan hogs
   703 		elseif strucType[globalTempID] == loc("Bio-Filter") then
   689 		elseif strucType[sID] == loc("Bio-Filter") then
   704 
   690 
   705 			if GetGearType(gear) == gtHedgehog then
   691 			if GetGearType(gear) == gtHedgehog then
   706 				if (GetHogClan(gear) ~= strucClan[globalTempID]) and (GetHealth(gear) > 0) then
   692 				if (GetHogClan(gear) ~= strucClan[sID]) and (GetHealth(gear) > 0) then
   707 					AddGear(GetX(gear), GetY(gear), gtGrenade, 0, 0, 0, 1)
   693 					AddGear(GetX(gear), GetY(gear), gtGrenade, 0, 0, 0, 1)
   708 				end
   694 				end
   709 			end
   695 			end
   710 
   696 
   711 		-- were those weapons in your pocket, or were you just happy to see me?
   697 		-- were those weapons in your pocket, or were you just happy to see me?
   712 		elseif strucType[globalTempID] == loc("Weapon Filter") then
   698 		elseif strucType[sID] == loc("Weapon Filter") then
   713 
   699 
   714 			if GetGearType(gear) == gtHedgehog then
   700 			if GetGearType(gear) == gtHedgehog then
   715 				if (GetHogClan(gear) ~= strucClan[globalTempID]) then
   701 				if (GetHogClan(gear) ~= strucClan[sID]) then
   716 
   702 
   717 					for wpnIndex = 1, #atkArray do
   703 					for wpnIndex = 1, #atkArray do
   718 						AddAmmo(gear, atkArray[wpnIndex][1], 0)
   704 						AddAmmo(gear, atkArray[wpnIndex][1], 0)
   719 					end
   705 					end
   720 
   706 
   728 
   714 
   729 				end
   715 				end
   730 			end
   716 			end
   731 
   717 
   732 		-- BOUNCE! POGO! POGO! POGO! POGO!
   718 		-- BOUNCE! POGO! POGO! POGO! POGO!
   733 		elseif strucType[globalTempID] == loc("Reflector Shield") then
   719 		elseif strucType[sID] == loc("Reflector Shield") then
   734 
   720 
   735 			-- add check for whose projectile it is
   721 			-- add check for whose projectile it is
   736 			if gearCanBeDeflected(gear) == true then
   722 			if gearCanBeDeflected(gear) == true then
   737 
   723 
   738 				local gOwner = getGearValue(gear,"owner")
   724 				local gOwner = getGearValue(gear,"owner")
   741 
   727 
   742 				if gDeflects >= 3 then
   728 				if gDeflects >= 3 then
   743 					DeleteGear(gear)
   729 					DeleteGear(gear)
   744 					AddVisualGear(GetX(gear), GetY(gear), vgtSmoke, 0, false)
   730 					AddVisualGear(GetX(gear), GetY(gear), vgtSmoke, 0, false)
   745 					PlaySound(sndVaporize)
   731 					PlaySound(sndVaporize)
   746 				elseif gOwner ~= strucClan[globalTempID] then
   732 				elseif gOwner ~= strucClan[sID] then
   747 					--whether to vaporize gears or bounce them
   733 					--whether to vaporize gears or bounce them
   748 					if gDmg ~= 0 then
   734 					if gDmg ~= 0 then
   749 						local dx, dy = GetGearVelocity(gear)
   735 						local dx, dy = GetGearVelocity(gear)
   750 
   736 
   751 						if (dx == 0) and (dy == 0) then
   737 						if (dx == 0) and (dy == 0) then
   761 							setGearValue(gear,"deflects",(gDeflects+1))
   747 							setGearValue(gear,"deflects",(gDeflects+1))
   762 
   748 
   763 							AddVisualGear(GetX(gear), GetY(gear), vgtExplosion, 0, false)
   749 							AddVisualGear(GetX(gear), GetY(gear), vgtExplosion, 0, false)
   764 							PlaySound(sndExplosion)
   750 							PlaySound(sndExplosion)
   765 
   751 
   766 							strucHealth[globalTempID] = strucHealth[globalTempID] - gDmg
   752 							strucHealth[sID] = strucHealth[sID] - gDmg
   767 							strucCircCol[globalTempID] = strucCircCol[globalTempID] - gDmg
   753 							strucCircCol[sID] = strucCircCol[sID] - gDmg
   768 
   754 
   769 							if strucHealth[globalTempID] <= 0 then
   755 							if strucHealth[sID] <= 0 then
   770 								AddVisualGear(GetX(strucGear[globalTempID]), GetY(strucGear[globalTempID]), vgtExplosion, 0, false)
   756 								AddVisualGear(GetX(strucGear[sID]), GetY(strucGear[sID]), vgtExplosion, 0, false)
   771 								DeleteGear(strucGear[globalTempID])
   757 								DeleteGear(strucGear[sID])
   772 								PlaySound(sndExplosion)
   758 								PlaySound(sndExplosion)
   773 							end
   759 							end
   774 
   760 
   775 						end
   761 						end
   776 
   762 
   781 					end
   767 					end
   782 				end
   768 				end
   783 			end
   769 			end
   784 
   770 
   785 		--mark as within range of a teleporter node
   771 		--mark as within range of a teleporter node
   786 		elseif strucType[globalTempID] == loc("Teleportation Node") then
   772 		elseif strucType[sID] == loc("Teleportation Node") then
   787 
   773 
   788 			if GetGearType(gear) == gtHedgehog then
   774 			if GetGearType(gear) == gtHedgehog then
   789 				if GetHogClan(gear) == strucClan[globalTempID] then
   775 				if GetHogClan(gear) == strucClan[sID] then
   790 
   776 
   791 					for i = 1, #sProx do
   777 					for i = 1, #sProx do
   792 						if sProx[i][1] == loc("Teleportation Mode") then
   778 						if sProx[i][1] == loc("Teleportation Mode") then
   793 							sProx[i][2] = true
   779 							sProx[i][2] = true
   794 						end
   780 						end
   798 			end
   784 			end
   799 
   785 
   800 		-- mark as within range of construction station
   786 		-- mark as within range of construction station
   801 		-- and thus allow menu access to placement modes
   787 		-- and thus allow menu access to placement modes
   802 		-- for girders, mines, sticky mines and barrels
   788 		-- for girders, mines, sticky mines and barrels
   803 		elseif strucType[globalTempID] == loc("Construction Station") then
   789 		elseif strucType[sID] == loc("Construction Station") then
   804 
   790 
   805 			if GetGearType(gear) == gtHedgehog then
   791 			if GetGearType(gear) == gtHedgehog then
   806 				if GetHogClan(gear) == strucClan[globalTempID] then
   792 				if GetHogClan(gear) == strucClan[sID] then
   807 					AddVisualGear(GetX(strucGear[globalTempID]), GetY(strucGear[globalTempID]), vgtSmoke, 0, true)
   793 					AddVisualGear(GetX(strucGear[sID]), GetY(strucGear[sID]), vgtSmoke, 0, true)
   808 
   794 
   809 					for i = 1, #sProx do
   795 					for i = 1, #sProx do
   810 						if ((sProx[i][1] == loc("Girder Placement Mode"))
   796 						if ((sProx[i][1] == loc("Girder Placement Mode"))
   811 						or (sProx[i][1] == loc("Rubber Placement Mode"))
   797 						or (sProx[i][1] == loc("Rubber Placement Mode"))
   812 						or (sProx[i][1] == loc("Mine Placement Mode"))
   798 						or (sProx[i][1] == loc("Mine Placement Mode"))
   822 			end
   808 			end
   823 
   809 
   824 		-- mark as within stupport station range
   810 		-- mark as within stupport station range
   825 		-- and thus allow menu access to placement modes
   811 		-- and thus allow menu access to placement modes
   826 		-- for weapon, utility, and med crates
   812 		-- for weapon, utility, and med crates
   827 		elseif strucType[globalTempID] == loc("Support Station") then
   813 		elseif strucType[sID] == loc("Support Station") then
   828 
   814 
   829 			if GetGearType(gear) == gtHedgehog then
   815 			if GetGearType(gear) == gtHedgehog then
   830 				if GetHogClan(gear) == strucClan[globalTempID] then
   816 				if GetHogClan(gear) == strucClan[sID] then
   831 					AddVisualGear(GetX(strucGear[globalTempID]), GetY(strucGear[globalTempID]), vgtSmoke, 0, true)
   817 					AddVisualGear(GetX(strucGear[sID]), GetY(strucGear[sID]), vgtSmoke, 0, true)
   832 
   818 
   833 					for i = 1, #sProx do
   819 					for i = 1, #sProx do
   834 						if ((sProx[i][1] == loc("Health Crate Placement Mode"))
   820 						if ((sProx[i][1] == loc("Health Crate Placement Mode"))
   835 						or (sProx[i][1] == loc("Weapon Crate Placement Mode"))
   821 						or (sProx[i][1] == loc("Weapon Crate Placement Mode"))
   836 						or (sProx[i][1] == loc("Utility Crate Placement Mode")))
   822 						or (sProx[i][1] == loc("Utility Crate Placement Mode")))
   876 
   862 
   877 	for i = 1, #strucID do
   863 	for i = 1, #strucID do
   878 
   864 
   879 		SetVisualGearValues(strucCirc[i], GetX(strucGear[i]), GetY(strucGear[i]), nil, nil, nil, nil, nil, strucCircRadius[i], nil, strucCircCol[i])
   865 		SetVisualGearValues(strucCirc[i], GetX(strucGear[i]), GetY(strucGear[i]), nil, nil, nil, nil, nil, strucCircRadius[i], nil, strucCircCol[i])
   880 
   866 
   881 		globalTempID = i
   867 		tempID_CheckProximity = i
   882 
   868 
   883 		SetVisualGearValues(strucAltDisplay[i], GetX(strucGear[i]), GetY(strucGear[i]), 0, 0, nil, nil, 800000, sprTarget)
   869 		SetVisualGearValues(strucAltDisplay[i], GetX(strucGear[i]), GetY(strucGear[i]), 0, 0, nil, nil, 800000, sprTarget)
   884 
   870 
   885 		if GameTime % 100 == 0 then
   871 		if GameTime % 100 == 0 then
   886 			-- Check For proximity of stuff to our structures
   872 			-- Check For proximity of stuff to our structures
   991 
   977 
   992 -- essentially called when user clicks the mouse
   978 -- essentially called when user clicks the mouse
   993 -- with girders or an airattack
   979 -- with girders or an airattack
   994 function PlaceObject(x,y)
   980 function PlaceObject(x,y)
   995 
   981 
   996 	placedX[placedCount] = x
       
   997 	placedY[placedCount] = y
       
   998 	placedType[placedCount] = cat[cIndex]
       
   999 	placedSpec[placedCount] = pMode[pIndex]
       
  1000 
       
  1001 	if (clanUsedExtraTime[GetHogClan(CurrentHedgehog)] == true) and (cat[cIndex] == "Utility Crate Placement Mode") and (utilArray[pIndex][1] == amExtraTime) then
   982 	if (clanUsedExtraTime[GetHogClan(CurrentHedgehog)] == true) and (cat[cIndex] == "Utility Crate Placement Mode") and (utilArray[pIndex][1] == amExtraTime) then
  1002 		AddCaption(loc("You may only place 1 Extra Time crate per turn."),0xffba00ff,capgrpVolume)
   983 		AddCaption(loc("You may only place 1 Extra Time crate per turn."),0xffba00ff,capgrpVolume)
  1003 		PlaySound(sndDenied)
   984 		PlaySound(sndDenied)
  1004 	elseif (conf_cratesPerRound ~= "inf" and clanCratesSpawned[GetHogClan(CurrentHedgehog)] >= conf_cratesPerRound) and ( (cat[cIndex] == "Health Crate Placement Mode") or (cat[cIndex] == "Utility Crate Placement Mode") or (cat[cIndex] == "Weapon Crate Placement Mode")  )  then
   985 	elseif (conf_cratesPerRound ~= "inf" and clanCratesSpawned[GetHogClan(CurrentHedgehog)] >= conf_cratesPerRound) and ( (cat[cIndex] == "Health Crate Placement Mode") or (cat[cIndex] == "Utility Crate Placement Mode") or (cat[cIndex] == "Weapon Crate Placement Mode")  )  then
  1005 		AddCaption(string.format(loc("You may only place %d crates per round."), conf_cratesPerRound),0xffba00ff,capgrpVolume)
   986 		AddCaption(string.format(loc("You may only place %d crates per round."), conf_cratesPerRound),0xffba00ff,capgrpVolume)
  1009 	then
   990 	then
  1010 		-- For checking if the actual placement succeeded
   991 		-- For checking if the actual placement succeeded
  1011 		local placed = false
   992 		local placed = false
  1012 		local gear
   993 		local gear
  1013 		if cat[cIndex] == "Girder Placement Mode" then
   994 		if cat[cIndex] == "Girder Placement Mode" then
  1014 			placed = PlaceGirder(x, y, CGR)
   995 			placed = PlaceGirder(x, y, currentGirderRotation)
  1015 			placedSpec[placedCount] = CGR
       
  1016 		elseif cat[cIndex] == "Rubber Placement Mode" then
   996 		elseif cat[cIndex] == "Rubber Placement Mode" then
  1017 			placed = PlaceRubber(x, y, CGR)
   997 			placed = PlaceRubber(x, y, currentGirderRotation)
  1018 			placedSpec[placedCount] = CGR
       
  1019 		elseif cat[cIndex] == "Health Crate Placement Mode" then
   998 		elseif cat[cIndex] == "Health Crate Placement Mode" then
  1020 			gear = SpawnHealthCrate(x,y)
   999 			gear = SpawnHealthCrate(x,y)
  1021 			if gear ~= nil then
  1000 			if gear ~= nil then
  1022 				placed = true
  1001 				placed = true
  1023 				SetHealth(gear, pMode[pIndex])
  1002 				SetHealth(gear, pMode[pIndex])
  1026 			end
  1005 			end
  1027 		elseif cat[cIndex] == "Weapon Crate Placement Mode" then
  1006 		elseif cat[cIndex] == "Weapon Crate Placement Mode" then
  1028 			gear = SpawnAmmoCrate(x, y, atkArray[pIndex][1])
  1007 			gear = SpawnAmmoCrate(x, y, atkArray[pIndex][1])
  1029 			if gear ~= nil then
  1008 			if gear ~= nil then
  1030 				placed = true
  1009 				placed = true
  1031 				placedSpec[placedCount] = atkArray[pIndex][2]
       
  1032 				setGearValue(gear,"caseType","ammo")
  1010 				setGearValue(gear,"caseType","ammo")
  1033 				setGearValue(gear,"contents",atkArray[pIndex][2])
  1011 				setGearValue(gear,"contents",atkArray[pIndex][2])
  1034 				clanCratesSpawned[GetHogClan(CurrentHedgehog)] = clanCratesSpawned[GetHogClan(CurrentHedgehog)] +1
  1012 				clanCratesSpawned[GetHogClan(CurrentHedgehog)] = clanCratesSpawned[GetHogClan(CurrentHedgehog)] +1
  1035 			end
  1013 			end
  1036 		elseif cat[cIndex] == "Utility Crate Placement Mode" then
  1014 		elseif cat[cIndex] == "Utility Crate Placement Mode" then
  1037 			gear = SpawnUtilityCrate(x, y, utilArray[pIndex][1])
  1015 			gear = SpawnUtilityCrate(x, y, utilArray[pIndex][1])
  1038 			if gear ~= nil then
  1016 			if gear ~= nil then
  1039 				placed = true
  1017 				placed = true
  1040 				placedSpec[placedCount] = utilArray[pIndex][2]
       
  1041 				setGearValue(gear,"caseType","util")
  1018 				setGearValue(gear,"caseType","util")
  1042 				setGearValue(gear,"contents",utilArray[pIndex][2])
  1019 				setGearValue(gear,"contents",utilArray[pIndex][2])
  1043 				if utilArray[pIndex][1] == amExtraTime then
  1020 				if utilArray[pIndex][1] == amExtraTime then
  1044 					clanUsedExtraTime[GetHogClan(CurrentHedgehog)] = true
  1021 					clanUsedExtraTime[GetHogClan(CurrentHedgehog)] = true
  1045 				end
  1022 				end
  1065 			placed = true
  1042 			placed = true
  1066 		end
  1043 		end
  1067 
  1044 
  1068 		if placed then
  1045 		if placed then
  1069 			clanPower[GetHogClan(CurrentHedgehog)] = clanPower[GetHogClan(CurrentHedgehog)] - placedExpense
  1046 			clanPower[GetHogClan(CurrentHedgehog)] = clanPower[GetHogClan(CurrentHedgehog)] - placedExpense
  1070 			placedCount = placedCount + 1
       
  1071 		else
  1047 		else
  1072 			AddCaption(loc("Invalid Placement"),0xffba00ff,capgrpVolume)
  1048 			AddCaption(loc("Invalid Placement"),0xffba00ff,capgrpVolume)
  1073 			PlaySound(sndDenied)
  1049 			PlaySound(sndDenied)
  1074 		end
  1050 		end
  1075 
  1051 
  1098 	end
  1074 	end
  1099 
  1075 
  1100 	local team = GetHogTeamName(CurrentHedgehog)
  1076 	local team = GetHogTeamName(CurrentHedgehog)
  1101 
  1077 
  1102 	if cat[cIndex] == "Girder Placement Mode" then
  1078 	if cat[cIndex] == "Girder Placement Mode" then
  1103 		pIndex = CGR
  1079 		pIndex = currentGirderRotation
  1104 		pMode = {loc("Girder")}
  1080 		pMode = {loc("Girder")}
  1105 	elseif cat[cIndex] == "Rubber Placement Mode" then
  1081 	elseif cat[cIndex] == "Rubber Placement Mode" then
  1106 		pIndex = CGR
  1082 		pIndex = currentGirderRotation
  1107 		pMode = {loc("Rubber")}
  1083 		pMode = {loc("Rubber")}
  1108 		placedExpense = 3
  1084 		placedExpense = 3
  1109 	elseif cat[cIndex] == "Barrel Placement Mode" then
  1085 	elseif cat[cIndex] == "Barrel Placement Mode" then
  1110 		pMode = {60}
  1086 		pMode = {60}
  1111 		placedExpense = 10
  1087 		placedExpense = 10
  1258 
  1234 
  1259 				CheckTeleport(cGear, x, y)
  1235 				CheckTeleport(cGear, x, y)
  1260 				cGear = nil
  1236 				cGear = nil
  1261 		elseif GetGearType(cGear) == gtGirder then
  1237 		elseif GetGearType(cGear) == gtGirder then
  1262 
  1238 
  1263 			CGR = GetState(cGear)
  1239 			currentGirderRotation = GetState(cGear)
  1264 
  1240 
  1265 			PlaceObject(x, y)
  1241 			PlaceObject(x, y)
  1266 		end
  1242 		end
  1267 
  1243 
  1268 	end
  1244 	end
  1419 				updateIndex()
  1395 				updateIndex()
  1420 			end
  1396 			end
  1421 		end
  1397 		end
  1422 	end
  1398 	end
  1423 
  1399 
  1424 	-- Hacky workaround for object placer: Since this is based on the drill strike, it
       
  1425 	-- allows the 5 timer keys to be pressed, causing the announcer to show up
       
  1426 	-- This triggers code in 1 tick to send other message to mask the earlier one.
       
  1427 	checkForSpecialWeaponsIn = 1
  1400 	checkForSpecialWeaponsIn = 1
  1428 
  1401 
  1429 end
  1402 end
  1430 
  1403 
  1431 -- [Switch]: Set mine time to 0 (only in mine placement mode)
  1404 -- [Switch]: Set mine time to 0 (only in mine placement mode)
  1591 		loc("Up/down: Choose object type|1-5/Switch/Left/Right: Choose mine timer|Cursor: Place object")
  1564 		loc("Up/down: Choose object type|1-5/Switch/Left/Right: Choose mine timer|Cursor: Place object")
  1592 	)
  1565 	)
  1593 
  1566 
  1594 	SetAmmoDescriptionAppendix(amTeleport, loc("It only works in teleportation nodes of your own clan."))
  1567 	SetAmmoDescriptionAppendix(amTeleport, loc("It only works in teleportation nodes of your own clan."))
  1595 	
  1568 	
  1596 	sCirc = AddVisualGear(0,0,vgtCircle,0,true)
  1569 	local sCirc = AddVisualGear(0,0,vgtCircle,0,true)
  1597 	SetVisualGearValues(sCirc, 0, 0, 100, 255, 1, 10, 0, 40, 3, 0x00000000)
  1570 	SetVisualGearValues(sCirc, 0, 0, 100, 255, 1, 10, 0, 40, 3, 0x00000000)
  1598 
  1571 
  1599 	for i = 0, ClansCount-1 do
  1572 	for i = 0, ClansCount-1 do
  1600 		clanPower[i] = math.min(conf_initialEnergy, conf_maxEnergy)
  1573 		clanPower[i] = math.min(conf_initialEnergy, conf_maxEnergy)
  1601 
  1574 
  1634 		clanBoundsSY[i] = TopY
  1607 		clanBoundsSY[i] = TopY
  1635 		clanBoundsEX[i] = LeftX+(clanInterval*slot)+clanInterval-20
  1608 		clanBoundsEX[i] = LeftX+(clanInterval*slot)+clanInterval-20
  1636 		clanBoundsEY[i] = WaterLine
  1609 		clanBoundsEY[i] = WaterLine
  1637 
  1610 
  1638 		--top and bottom
  1611 		--top and bottom
  1639 		AddWall(LeftX+(clanInterval*slot),TopY,clanInterval,margin,color)
  1612 		AddWall(LeftX+(clanInterval*slot),TopY,clanInterval,wMargin,color)
  1640 		AddWall(LeftX+(clanInterval*slot),WaterLine-25,clanInterval,margin,color)
  1613 		AddWall(LeftX+(clanInterval*slot),WaterLine-25,clanInterval,wMargin,color)
  1641 
  1614 
  1642 		--add a wall to the left and right
  1615 		--add a wall to the left and right
  1643 		AddWall(LeftX+(clanInterval*slot)+20,TopY,margin,WaterLine,color)
  1616 		AddWall(LeftX+(clanInterval*slot)+20,TopY,wMargin,WaterLine,color)
  1644 		AddWall(LeftX+(clanInterval*slot)+clanInterval-20,TopY,margin,WaterLine,color)
  1617 		AddWall(LeftX+(clanInterval*slot)+clanInterval-20,TopY,wMargin,WaterLine,color)
  1645 
  1618 
  1646 	end
  1619 	end
  1647 
  1620 
  1648 	runOnHogs(initialSetup)
  1621 	runOnHogs(initialSetup)
  1649 
  1622 
  1692 end
  1665 end
  1693 
  1666 
  1694 -- track hedgehogs and placement gears
  1667 -- track hedgehogs and placement gears
  1695 function onGearAdd(gear)
  1668 function onGearAdd(gear)
  1696 
  1669 
  1697 	if GetGearType(gear) == gtHedgehog then
  1670 	local gt = GetGearType(gear)
  1698 	elseif (GetGearType(gear) == gtAirAttack) or (GetGearType(gear) == gtTeleport) or (GetGearType(gear) == gtGirder) then
  1671 	if (gt == gtAirAttack) or (gt == gtTeleport) or (gt == gtGirder) then
  1699 		cGear = gear
  1672 		cGear = gear
  1700 
  1673 	elseif (gt == gtMine) or (gt == gtExplosives) or (gt == gtSMine) then
       
  1674 		curWep = GetCurAmmoType()
       
  1675 		if curWep == amCMObjectPlacer then
       
  1676 			checkForSpecialWeaponsIn = 1
       
  1677 		end
  1701 	end
  1678 	end
  1702 
  1679 
  1703 	if isATrackedGear(gear) then
  1680 	if isATrackedGear(gear) then
  1704 		trackGear(gear)
  1681 		trackGear(gear)
  1705 	elseif gearCanBeDeflected(gear) then
  1682 	elseif gearCanBeDeflected(gear) then
  1719 		cGear = nil
  1696 		cGear = nil
  1720 	end
  1697 	end
  1721 
  1698 
  1722 	if (isATrackedGear(gear) or gearCanBeDeflected(gear)) then
  1699 	if (isATrackedGear(gear) or gearCanBeDeflected(gear)) then
  1723 
  1700 
  1724 		if getGearValue(gear, "tCirc") ~= nil then
       
  1725 			DeleteVisualGear(getGearValue(gear, "tCirc"))
       
  1726 		end
       
  1727 
       
  1728 		trackDeletion(gear)
  1701 		trackDeletion(gear)
  1729 
  1702 
  1730 	end
  1703 	end
  1731 
  1704 
  1732 end
  1705 end