1-------------------------------- 2-- HIGHLANDER / HOGS OF WAR 3-- by mikade 4-------------------------------- 5 6------------------------- 7-- ideas for the future 8------------------------- 9-- add structure 10-- allow switcher, resurrector 11-- nerf teleport 12-- balance weapon distribution across entire team / all teams 13-- add other inequalities/bonuses like... ??? 14-- * some hogs start off with an extra 25 health? 15-- * some hogs start off poisoned? 16-- * some hogs start off with a rope and 2 drills but die after their turn? 17 18------------------ 19-- script follows 20------------------ 21 22HedgewarsScriptLoad("/Scripts/Locale.lua") 23HedgewarsScriptLoad("/Scripts/Tracker.lua") 24HedgewarsScriptLoad("/Scripts/Params.lua") 25 26-- These define weapons allowed by the script. 27local atkWeps = { 28 [amBazooka]=true, [amBee]=true, [amMortar]=true, [amDrill]=true, [amSnowball]=true, 29 [amGrenade]=true, [amClusterBomb]=true, [amMolotov]=true, [amWatermelon]=true, 30 [amHellishBomb]=true, [amGasBomb]=true, [amShotgun]=true, [amDEagle]=true, 31 [amFlamethrower]=true, [amSniperRifle]=true, [amSineGun]=true, [amMinigun]=true, 32 [amFirePunch]=true, [amWhip]=true, [amBaseballBat]=true, [amKamikaze]=true, 33 [amSeduction]=true, [amHammer]=true, [amMine]=true, [amDynamite]=true, [amCake]=true, 34 [amBallgun]=true, [amSMine]=true, [amRCPlane]=true, [amBirdy]=true, [amKnife]=true, 35 [amAirAttack]=true, [amMineStrike]=true, [amNapalm]=true, [amDrillStrike]=true, [amPiano]=true, [amAirMine] = true, 36 [amCreeper]=true, 37} 38 39local utilWeps = { 40 [amBlowTorch]=true, [amPickHammer]=true, [amGirder]=true, [amPortalGun]=true, 41 [amRope]=true, [amParachute]=true, [amTeleport]=true, [amJetpack]=true, 42 [amInvulnerable]=true, [amLaserSight]=true, [amVampiric]=true, 43 [amLowGravity]=true, [amExtraDamage]=true, [amExtraTime]=true, 44 [amLandGun]=true, [amRubber]=true, [amIceGun]=true, 45} 46 47-- Intentionally left out: 48-- * Resurrector (guaranteed to screw up the game) 49-- * Time Box 50-- * Switch Hedgehog (not sure why) 51 52local wepArray = {} 53 54local atkChoices = {} 55local utilChoices = {} 56 57local currHog 58local lastHog 59local started = false 60local switchStage = 0 61 62local lastWep = amNothing 63local shotsFired = 0 64 65local probability = {1,2,5,10,20,50,200,500,1000000}; 66local atktot = 0 67local utiltot = 0 68 69local teleportConverted = false -- used for special handling of teleport when gfPlaceHog is active 70 71-- Script parameter stuff 72 73--[[ Loyal Highlander. 74If true, killing hogs of your own clan doesn't give you their weapons. 75Otherwise, killing any hog gives you their weapons. ]] 76local loyal = false 77 78 79--[[ Multiple weapon usages. 80This is a bit tricky to explain. 81First, remind yourselves that hogs can never hold more than 1 of the same ammo type. 82 83This param changes how ammo will be restocked after killing a hog if you 84already owned this ammo. 85Basically this is about if you can use the same weapon multiple times in a 86turn by killing enemies in a clever way. 87We need to distinguish between your current inventory and the “reset inventory”, 88that is, the state to which your inventory will get reset in the next turn. 89 90No Multi-Use (default): 91 If you kill a hog who owns a weapon you currently have in your reset inventory, 92 but not your inventory, you DO NOT get this weapon again. 93 94Multi-Use: 95 If you kill a hog who owns a weapon you currently have in your reset inventory, 96 but not your inventory, you DO get this weapon. 97 98Example 1: 99 You have a ballgun, and use it to kill a hog who also owns a ballgun. 100 No Multi-Use: You will NOT get another ballgun, since it's in your 101 reset inventory. 102 Multi-Use: You get another ballgun. 103 104Example 2: 105 You have a grenade and a bazooka in your inventory. You use the bazooka 106 to kill a hedgehog who owns a grenade. 107 In both ammo limit modes, you do NOT win any ammo since you already have 108 a grenade in your inventory (not just your reset inventory), and the 109 rule “no more than 1 ammo per type” applies. 110]] 111local multiUse = false 112 113function onParameters() 114 parseParams() 115 multiUse = params["multiuse"] == "true" 116 loyal = params["loyal"] == "true" 117end 118 119function CheckForWeaponSwap() 120 if GetCurAmmoType() ~= lastWep then 121 shotsFired = 0 122 end 123 lastWep = GetCurAmmoType() 124end 125 126function onSlot() 127 CheckForWeaponSwap() 128end 129 130function onSetWeapon() 131 CheckForWeaponSwap() 132end 133 134function onHogAttack() 135 CheckForWeaponSwap() 136 shotsFired = shotsFired + 1 137end 138 139function StartingSetUp(gear) 140 for i = 0, AmmoTypeMax do 141 if i ~= amNothing then 142 setGearValue(gear,i,0) 143 end 144 end 145 for w,c in pairs(wepArray) do 146 if c == 9 and (atkWeps[w] or utilWeps[w]) then 147 setGearValue(gear,w,1) 148 end 149 end 150 151 setGearValue(gear,amSkip,100) 152 153 local r = 0 154 if atktot > 0 then 155 r = GetRandom(atktot)+1 156 for i = 0, AmmoTypeMax do 157 if i ~= amNothing then 158 if atkChoices[i] >= r then 159 setGearValue(gear,i,1) 160 break 161 end 162 end 163 end 164 end 165 if utiltot > 0 then 166 r = GetRandom(utiltot)+1 167 for i = 0, AmmoTypeMax do 168 if i ~= amNothing then 169 if utilChoices[i] >= r then 170 setGearValue(gear,i,1) 171 break 172 end 173 end 174 end 175 end 176end 177 178function ConvertValues(gear) 179 for w,c in pairs(wepArray) do 180 -- Add hog ammo loadout, but don't touch teleport if in hog placement phase. 181 -- If in hog placement phase, teleport will be touched later (see onNewTurn). 182 if not (GetGameFlag(gfPlaceHog) and TotalRounds == -1 and (w == amTeleport)) then 183 AddAmmo(gear, w, getGearValue(gear,w) ) 184 end 185 end 186end 187 188-- this is called when a hog dies 189function TransferWeps(gear) 190 191 if CurrentHedgehog ~= nil and CurrentHedgehog ~= gear and (not loyal or (GetHogClan(CurrentHedgehog) ~= GetHogClan(gear))) then 192 193 local x,y,color 194 local vgear 195 local dspl = IsHogLocal(CurrentHedgehog) 196 local ammolist = '' 197 198 if dspl then 199 x,y = GetGearPosition(CurrentHedgehog) 200 color = GetClanColor(GetHogClan(CurrentHedgehog)) 201 end 202 203 for w,c in pairs(wepArray) do 204 local val = getGearValue(gear,w) 205 if val ~= 0 and (multiUse or (wepArray[w] ~= 9 and getGearValue(CurrentHedgehog, w) == 0)) then 206 setGearValue(CurrentHedgehog, w, val) 207 208 -- if you are using multi-shot weapon, gimme one more 209 if (GetCurAmmoType() == w) and (shotsFired ~= 0) then 210 AddAmmo(CurrentHedgehog, w, val+1) 211 -- assign ammo as per normal 212 else 213 AddAmmo(CurrentHedgehog, w, val) 214 end 215 if dspl then 216 if ammolist == '' then 217 ammolist = GetAmmoName(w) 218 else 219 ammolist = ammolist .. ' • ' .. GetAmmoName(w) 220 end 221 x = x + 2 222 y = y + 32 223 vgear = AddVisualGear(x, y, vgtAmmo, 0, true) 224 if vgear ~= nil then 225 local vgtFrame = w 226 SetVisualGearValues(vgear,nil,nil,nil,nil,nil,vgtFrame) 227 end 228 end 229 230 end 231 end 232 233 if dspl and ammolist ~= '' then 234 PlaySound(sndShotgunReload); 235 AddCaption(ammolist, color, capgrpAmmoinfo) 236 end 237 end 238 239end 240 241function onGameInit() 242 EnableGameFlags(gfInfAttack, gfPerHogAmmo) 243 DisableGameFlags(gfResetWeps, gfSharedAmmo) 244 HealthCaseProb = 100 245 if loyal then 246 Goals = loc("Loyal Highlander: Eliminate enemy hogs to take their weapons") .. "|" 247 else 248 Goals = loc("Highlander: Eliminate hogs to take their weapons") .. "|" 249 end 250 Goals = Goals .. loc("Replenishment: Weapons are restocked on turn start of a new hog") .. "|" .. 251 loc("Ammo Limit: Hogs can’t have more than 1 ammo per type") .. "|" 252 if multiUse then 253 Goals = Goals .. loc("Multi-Use: You can take and use the same ammo type multiple times in a turn") 254 else 255 Goals = Goals .. loc("No Multi-Use: Once you used an ammo, you can’t take it again in this turn") 256 end 257end 258 259function onGameStart() 260 -- Remove air strikes in maps with border 261 if MapHasBorder() or GetGameFlag(gfBorder) then 262 atkWeps[amAirAttack] = nil 263 atkWeps[amMineStrike] = nil 264 atkWeps[amNapalm] = nil 265 atkWeps[amDrillStrike] = nil 266 atkWeps[amPiano] = nil 267 end 268 -- Disable redundant utilities 269 if GetGameFlag(gfVampiric) then 270 utilWeps[amVampiric] = nil 271 end 272 if GetGameFlag(gfLowGravity) then 273 utilWeps[amLowGravity] = nil 274 end 275 if GetGameFlag(gfLaserSight) then 276 utilWeps[amLaserSight] = nil 277 end 278 if GetGameFlag(gfInvulnerable) then 279 utilWeps[amInvulnerable] = nil 280 end 281 if TurnTime > 999000 then 282 utilWeps[amExtraTime] = nil 283 end 284 utilChoices[amSkip] = 0 285 local c = 0 286 for i = 0, AmmoTypeMax do 287 if i ~= amNothing then 288 atkChoices[i] = 0 289 utilChoices[i] = 0 290 if i ~= 7 then 291 wepArray[i] = 0 292 c = GetAmmo(i) 293 if c > 8 then 294 c = 9 295 end 296 wepArray[i] = c 297 if c < 9 and c > 0 then 298 if atkWeps[i] then 299 atktot = atktot + probability[c] 300 atkChoices[i] = atktot 301 elseif utilWeps[i] then 302 utiltot = utiltot + probability[c] 303 utilChoices[i] = utiltot 304 end 305 end 306 end 307 end 308 end 309 310 runOnGears(StartingSetUp) 311 runOnGears(ConvertValues) 312end 313 314function CheckForHogSwitch() 315 316 --[[ Restock the weapons of the hog on turn start, provided it is not the same hog as before. 317 This exception is done do avoid a single hog receiving tons of weapons when it is the only unfrozen 318 hog and takes consecutive turns. ]] 319 320 if (CurrentHedgehog ~= nil) then 321 322 currHog = CurrentHedgehog 323 324 if currHog ~= lastHog then 325 326 -- re-assign ammo to this guy, so that his entire ammo set will 327 -- be visible during another player's turn 328 if lastHog ~= nil and GetHealth(lastHog) then 329 ConvertValues(lastHog) 330 end 331 332 -- give the new hog what he is supposed to have, too 333 ConvertValues(CurrentHedgehog) 334 335 end 336 337 lastHog = currHog 338 339 end 340 341end 342 343function onNewTurn() 344 CheckForHogSwitch() 345 346 -- If hog placement phase is over, set the hog's actual teleport loadout 347 if GetGameFlag(gfPlaceHog) and TotalRounds == 0 and not teleportConverted then 348 runOnHogs(function(gear) 349 AddAmmo(gear, amTeleport, getGearValue(gear, amTeleport)) 350 end) 351 -- This makes sure this code is only run once 352 teleportConverted = true 353 end 354end 355 356function onGearAdd(gear) 357 358 if (GetGearType(gear) == gtHedgehog) then 359 trackGear(gear) 360 end 361 362end 363 364function onGearDelete(gear) 365 366 if (GetGearType(gear) == gtHedgehog) then 367 TransferWeps(gear) 368 trackDeletion(gear) 369 end 370 371end 372