1----------------------------------------------------------- 2--- HEDGE EDITOR (for use with Hedgewars 0.9.22 and up) --- 3----------------------------------------------------------- 4-- A not-so-horrible mission editor. 5-- Place gears like a boss! 6 7-- Original author: mikade 8 9-- feel free to shower me with your adoration and/or hate mail 10-- more info can be found at https://hedgewars.org/HedgeEditor 11 12-- special thanks to nemo, unC0Rr, sheepluva and koda for their assistance 13 14--------------------------------------- 15-- GETTING STARTED (for best results!) 16--------------------------------------- 17-- create a weaponset that has NO DELAYS on any weapons, and that gives you 1 ammo per crate 18 19-- (optional) copy GameLogExtractor.html, jquery-1.js 20-- into your Documents/Hedgewars/Logs folder 21 22-- (optional) copy hwpmapconverter somewhere easily accessible 23 24-- (optional) profit?? 25 26--------------------------------------- 27-- CORE FEATURES as of latest version 28--------------------------------------- 29-- togglable help (press PRECISE + 1, while you have a tool (e.g. airstrike) selected) 30 31-- place girders, rubberbands and custom sprites anywhere on the map. 32-- the above objects may be destructible, indestructible, icy, or bouncy. 33 34-- place mines, sticky mines, air mines, barrels, weapon crates, utility crates, 35-- health crates, targets, and cleavers anywhere on the map. 36 37-- select, reposition, modify, or delete placed objects. 38 39-- read in data from a previously generated map and allow the map to be edited/saved again 40 41-- contextual cursor and menu graphics 42-- placement sounds that are slightly more soothing 43 44-- upon saving, all level data will be output to logs/game0.log. 45-- game0.log also includes a lot of other data so if you only want to see the relevant lines of code 46-- you can use GameLogExtractor.html to extract and prune the log into a cleaner form of data, 47-- specifically: either as an automagically generated template mission, just core data, or hwmap points. 48-- from there, please copy and paste any lines relevant to your interest into an existing 49-- (or totally empty!) script and edit them according to taste. 50 51-------------------------- 52-- MODE SPECIFIC SUPPORT 53-------------------------- 54-- FOR CUSTOM MISSIONS/CAMPAIGN LEVELS: 55-- the names/hats/flags/voices/graves of any teams/hogs that you use to play this script can be saved, 56-- as can (most of) the settings from your scheme and weapons selection. 57-- HOWEVER, you can also use the 'hog identity' tool to give hogs preset names/hats/weapons/health 58-- or use the 'team identity' tool to give an entire team themed names/hats. 59-- give hogs differing health by using the health modification tool 60-- create goals by tagging gears with victory/defeat/collection markers (somewhat implemented) 61-- flavor text, as well as victory/defeat conditions will be generated based on these tags. 62 63-- SHOPPA BALANCE / CONSTRUCTION MODE (partial and/or possibly decremented): 64-- Press 1-5 while repositioning hogs with the reposition tool to assign them (their position) a rank. 65-- This value will be expressed as a colour that is intended to represent how "good" or "bad" 66-- a position on the map is. These ranks/points will be output along with other game data to game0.log 67-- This data could be pasted into the ShoppaBalance script to create balances for additional maps. 68 69-- TECH RACER / HEDGE EDITOR / POINT INTERPRETER: 70-- place/remove waypoints/special points 71-- use the ScriptParameter in the frontend scheme editor to set additional options, e.g. 72-- ufoFuel=1000 (Flying Saucer will start with half the normal fuel. A value of 2000 is infinite fuel) 73-- portalDistance=15 (This is the distance portals can travel before fizzling) 74-- m=3 (load a particular map from the map library of Data/Scripts/TechMaps 75 76-- when saving data, points for conversion to HWMAP are also generated and placed inside block comments. 77-- copy paste/these points at the START of a converted HWMAP and then convert the map back to HWMAP format. 78-- following the above procedure it is then possible to load the map in frontend and play it using a 79-- script like TechRacer (or HedgeEditor itself) that can interpret the points using InterpretPoints() 80 81--------------------------------------- 82-- MIKADE'S DISCLAIMER 83--------------------------------------- 84-- well, I really just made this for myself, so it's usage might be a little complicated for others. 85-- it also probably has a million errors, and has grown rather bloated over time due to the addition of 86-- more and more features that my initial design didn't take into account. 87 88-- anyway, I've tried to make it more user-friendly by including more comments and gradually adding 89-- some basic guidelines such as those listed above, and also the in-game Help displays for each tool. 90 91----------------------------------------- 92-- GIANT "TO DO" LIST / OTHER NOTES 93----------------------------------------- 94 95-- try to prune waypoint list and portal/ufo fuel in the mission template 96-- for gamelog extractor 97 98-- I should probably check if there are tagged gears on save 99-- and if there are enable gfOneClanMode so that user can't 100-- just destroy all hogs to win map. 101-- (what happens if we lose all our hogs?) 102 103-- I might be able to make the flavor text even better (assassinate hogName) by 104-- checking if there is only 1 hog, etc. 105 106-- possibly try show landflag addcaption constantly like we do for superdelete when 107-- using girders / rubbers. 108 109-- How about a weapons profile tool that is used with team ammo 110-- and then hog identity tool would only be available if gfPerHogAmmo is set 111 112-- [high] check if we lose a mission when the enemy collects our crate (we should) 113 114-- [high] waypoints don't reload yet 115 116-- [high] add missing ammo types as they appear 117 118-- [med] add a limited form of save/load within level before mass-output 119 120-- [med] maybe incorporate portal effects / ufo tracking into the template generated script if 121-- you want the missions to use it 122 123-- [med] improve ammo handling (if possible, take more scheme settings into account) 124 125-- [low] break up the division of labor of the tools into airstrike, minestrike, napalm, etc. 126 --[[ 127 girder = "Girder Placement Mode", 128 rubber = "Rubber Placement Mode", 129 130 airstrike = (target sprite) (gear placement) 131 "Mine Placement Mode", 132 "Sticky Mine Placement Mode", 133 "Air Mine Placement Mode", 134 "Barrel Placement Mode", 135 "Target Placement Mode", 136 "Cleaver Placement Mode", 137 138 drillstrike = crate sprite (crate placement mode) 139 "Health Crate Placement Mode", 140 "Weapon Crate Placement Mode", 141 "Utility Crate Placement Mode", 142 143 144 napalm = arrow sprite (selection/modification/deletion mode) 145 "Repositioning Mode", -- also include a delete 146 "Goal Editing Mode", 147 "Hog Identity Mode", 148 "Team Identity Mode", 149 "Health Modification Mode", 150 "Sprite Testing Mode", 151 "Sprite Modification Mode", 152 "Sprite Placement Mode", 153 "Waypoint Editing Mode" 154 }]] 155 156-- [low] improve support for ShoppaBalance and ConstructionMode, see ranking) 157 158-- [low] eventually incorporate scripted structures into the editor / mission mode 159 160-- [low] some kind of support for single team training missions 161-- we could possibly add gfOneClanMode and kill the other team we're playing with? 162 163-- [never?] more detailed goal tagging and multi-stage triggers 164 165-- [never?] add a pulsing glow thing for sprites you have selected, 166-- kind of like the invaders in SpaceInvader (currently they are just displayed as purple) 167 168-- [never?] add GUIs for editing ammo, init settings, additional gear attributes 169-- perhaps using precise with timer to enable/disable certain features 170 171--[[ gui menu ideas that have long since been abandoned 172INITIALISATION MENU 173 --gameFlags, etc 174 175 Map 176 Theme 177 TurnTime 178 Explosives 179 MinesNum 180 CaseFreq 181 Delay 182 183 HealthCaseProb 184 HealthCaseAmount 185 DamagePercent 186 MinesTime 187 MineDudPercent 188 SuddenDeathTurns 189 WaterRise 190 HealthDecrease 191HOG MENU 192 health 193 name (can be randomly generated from the list of hog names already in localisation) 194 poisoned (true/false) 195 hat 196 hog level? 197TEAM MENU 198 name (can be randomly generated as above?) should there be an array of teams with an array of names 199 colour 200 grave 201 fort 202 voicepack 203 flag 204 205-- this below stuff is less important 206STICKY MINE MENU 207 timer? 208MINE MENU 209 timer / dud 210MEDKIT MENU / EXPLOSIVE MENU 211 health amount 212WEP AND UTIL CRATE MENU 213 contents 214 215---------------------------------------- 216-- MAP IDEAS 217---------------------------------------- 218-- try to create a portal race (limit portal distance) 219-- for portal race, include barriers that you need to drill shoot through to get lazer site crates 220 221-- try make a map that uses sinegun to jump between bouncy boxes (not easy until we get better control over landflags) 222 223-- how about a mission where you have to trap / freeze all the enemy hogs 224-- and aren't allowed to kill them? 225-- can set it on the islands map. 226-- landgun 227-- girder 228-- mudball 229-- hammer 230-- seduction? (call a hog who has firepunch into a ditch 231-- icegun (do this so you can freeze guys in an area and then blowtorch/explode an obstacle) 232-- jump across a bridge that has been mined and then bat the enemy to the other side. 233 234-- possibly the same as part of the above, possibly different, what about a heist mission 235-- the objective is to steal 3 enemy crates 236-- the first one you have to fall through an invul tunnel of sticky mines and then parachute. 237-- the second one you have to drill rocket / portal. 238-- the third one you have to underwater ufo into, but only after opening it up with an underwater bee. 239 240]] 241 242--------------------------------------------------------- 243-- HEDGE EDITOR, SCRIPT BEGINS (Hey yo, it's about time) 244--------------------------------------------------------- 245 246-- Tell other scripts that we exist 247HedgeEditor = true 248 249HedgewarsScriptLoad("/Scripts/Locale.lua") 250HedgewarsScriptLoad("/Scripts/Tracker.lua") 251HedgewarsScriptLoad("/Scripts/Params.lua") 252HedgewarsScriptLoad("/Scripts/TechMaps.lua") 253 254-- Fake ammo type for the gear placement tool 255local amCMGearPlacementTool = amAirAttack 256 257-- Special frames in Ammos.png/Ammos_bw.png 258local ammoFrameAirAttack = 63 259 260-- Caption colors 261local colorErrorMessage = 0xFFFFFFFF 262local colorInfoMessage = 0xFFFFFFFF 263local colorPlaceMode1 = 0xFFBA00FF -- Main placement mode 264local colorPlaceMode2 = 0xFFDE85FF -- Secondary mode 265 266----------------------------------------- 267-- tracking vars for save/load purposes 268----------------------------------------- 269 270local teamCounter = 0 271local lastRecordedTeam = "" 272local hhs = {} 273 274local waypointList = {} 275local girderList = {} 276local rubberList = {} 277local spriteList = {} 278 279local mineList = {} 280local sMineList = {} 281local airMineList = {} 282local targetList = {} 283local knifeList = {} 284local explosivesList = {} 285local healthCrateList = {} 286local wepCrateList = {} 287local utilCrateList = {} 288local hogDataList = {} 289local AIHogDataList = {} 290local hFlagList = {} 291local previewDataList = {} 292 293local shoppaPointList = {} 294local shoppaPX = {} 295local shoppaPY = {} 296local shoppaPR = {} 297 298-- Misc. state variables 299local hedgeEditorMissionPanelShown = false 300 301local tagCursorX, tagCursorY 302 303--------------------------------- 304-- crates are made of this stuff 305--------------------------------- 306 307local atkArray = 308 { 309 310 {amBazooka, "amBazooka"}, 311 {amBee, "amBee"}, 312 {amMortar, "amMortar"}, 313 {amDrill, "amDrill"}, 314 {amSnowball, "amSnowball"}, 315 {amKnife, "amKnife"}, 316 317 {amGrenade, "amGrenade"}, 318 {amClusterBomb, "amClusterBomb"}, 319 {amWatermelon, "amWatermelon"}, 320 {amHellishBomb, "amHellishBomb"}, 321 {amMolotov, "amMolotov"}, 322 {amGasBomb, "amGasBomb"}, 323 324 {amShotgun, "amShotgun"}, 325 {amDEagle, "amDEagle"}, 326 {amSniperRifle, "amSniperRifle"}, 327 {amSineGun, "amSineGun"}, 328 {amIceGun, "amIceGun"}, 329 {amMinigun, "amMinigun"}, 330 331 {amFirePunch, "amFirePunch"}, 332 {amWhip, "amWhip"}, 333 {amBaseballBat, "amBaseballBat"}, 334 {amKamikaze, "amKamikaze"}, 335 {amSeduction, "amSeduction"}, 336 {amHammer, "amHammer"}, 337 338 {amMine, "amMine"}, 339 {amDynamite, "amDynamite"}, 340 {amCake, "amCake"}, 341 {amBallgun, "amBallgun"}, 342 {amRCPlane, "amRCPlane"}, 343 {amSMine, "amSMine"}, 344 345 {amAirAttack, "amAirAttack", ammoFrameAirAttack}, -- overwritten icon in Ammos.png 346 {amMineStrike, "amMineStrike"}, 347 {amNapalm, "amNapalm"}, 348 {amPiano, "amPiano"}, 349 {amDrillStrike, "amDrillStrike"}, 350 {amAirMine, "amAirMine"}, 351 352 {amPickHammer, "amPickHammer"}, 353 {amBlowTorch, "amBlowTorch"}, 354 {amFlamethrower,"amFlamethrower"}, 355 356 {amBirdy, "amBirdy"}, 357 358 } 359 360local utilArray = 361 { 362 {amGirder, "amGirder"}, 363 {amLandGun, "amLandGun"}, 364 {amRubber, "amRubber"}, 365 366 {amRope, "amRope"}, 367 {amParachute, "amParachute"}, 368 {amTeleport, "amTeleport"}, 369 {amJetpack, "amJetpack"}, 370 {amPortalGun, "amPortalGun"}, 371 372 {amInvulnerable,"amInvulnerable"}, 373 {amLaserSight, "amLaserSight"}, 374 {amVampiric, "amVampiric"}, 375 {amResurrector, "amResurrector"}, 376 {amTardis, "amTardis"}, 377 378 {amSwitch, "amSwitch"}, 379 {amLowGravity, "amLowGravity"}, 380 {amExtraDamage, "amExtraDamage"}, 381 {amExtraTime, "amExtraTime"}, 382 383 } 384 385 --skiphog is 6 386 387local effectArray = { heInvulnerable, hePoisoned, heResurrectable, heResurrected, heFrozen, heArtillery } 388local effectStr = { "heInvulnerable", "hePoisoned", "heResurrectable", "heResurrected", "heFrozen", "heArtillery" } 389 390---------------------------- 391-- hog and map editing junk 392---------------------------- 393 394local preMadeTeam = { 395 396 { 397 loc_noop("Clowns"), 398 {"WhySoSerious","clown-copper","clown-crossed","clown","Joker"}, 399 {loc_noop("Baggy"),loc_noop("Bingo"),loc_noop("Bobo"),loc_noop("Bozo"),loc_noop("Buster"),loc_noop("Chester"),loc_noop("Copper"),loc_noop("Heckles"),loc_noop("Giggles"),loc_noop("Jingo"),loc_noop("Molly"),loc_noop("Loopy"),loc_noop("Patches"),loc_noop("Tatters")}, 400 "R","cm_balls","Mobster","Rubberduck","Castle" 401 }, 402 403 { 404 loc_noop("Street Fighters"), 405 {"sf_balrog","sf_blanka","sf_chunli","sf_guile","sf_honda","sf_ken","sf_ryu","sf_vega"}, 406 {loc_noop("Balrog"),loc_noop("Blanka"),loc_noop("Chunli"),loc_noop("Guile"),loc_noop("Honda"),loc_noop("Ken"),loc_noop("Ryu"),loc_noop("Vega")}, 407 "F","cm_balrog","Surfer","dragonball","Castle" 408 }, 409 410 { 411 loc_noop("Cybernetic Empire"), 412 {"cyborg1","cyborg2"}, 413 {loc_noop("Unit 189"),loc_noop("Unit 234"),loc_noop("Unit 333"),loc_noop("Unit 485"),loc_noop("Unit 527"),loc_noop("Unit 638"),loc_noop("Unit 709"),loc_noop("Unit 883")}, 414 "R","cm_binary","Robot","Grave","Castle" 415 }, 416 417 { 418 loc_noop("Color Squad"), 419 {"hair_blue","hair_green","hair_red","hair_yellow","hair_purple","hair_grey","hair_orange","hair_pink"}, 420 {loc_noop("Blue"),loc_noop("Green"),loc_noop("Red"),loc_noop("Yellow"),loc_noop("Purple"),loc_noop("Grey"),loc_noop("Orange"),loc_noop("Pink")}, 421 "F","mauritius","Singer","Grave","Castle" 422 }, 423 424 { 425 loc_noop("Fruit"), 426 {"fr_apple","fr_banana","fr_lemon","fr_orange","fr_pumpkin","fr_tomato"}, 427 {loc_noop("Juicy"),loc_noop("Squishy"),loc_noop("Sweet"),loc_noop("Sour"),loc_noop("Bitter"),loc_noop("Ripe"),loc_noop("Rotten"),loc_noop("Fruity")}, 428 "R","cm_mog","Default","Cherry","Castle" 429 }, 430 431 { 432 loc_noop("The Police"), 433 {"bobby","bobby2v","policecap","policegirl","royalguard"}, 434 {loc_noop("Hightower"),loc_noop("Lassard"),loc_noop("Callahan"),loc_noop("Jones"),loc_noop("Harris"),loc_noop("Thompson"),loc_noop("Mahoney"),loc_noop("Hooks"),loc_noop("Tackleberry")}, 435 "R","cm_star","British","Statue","Castle" 436 }, 437 438 { 439 loc_noop("The Ninja-Samurai Alliance"), 440 {"NinjaFull","NinjaStraight","NinjaTriangle","Samurai","StrawHat","StrawHatEyes","StrawHatFacial","naruto"}, 441 {loc_noop("Bushi"),loc_noop("Tatsujin"),loc_noop("Itami"),loc_noop("Arashi"),loc_noop("Shinobi"),loc_noop("Ukemi"),loc_noop("Godai"),loc_noop("Kenshi"),loc_noop("Ninpo")}, 442 "R","japan","Default","octopus","Castle" 443 }, 444 445 { 446 loc_noop("Pokémon"), 447 {"poke_ash","poke_charmander","poke_chikorita","poke_jigglypuff","poke_lugia","poke_mudkip","poke_pikachu","poke_slowpoke","poke_squirtle","poke_voltorb"}, 448 {loc_noop("Ash"),loc_noop("Charmander"),loc_noop("Chikorita"),loc_noop("Jigglypuff"),loc_noop("Lugia"),loc_noop("Mudkip"),loc_noop("Pikachu"),loc_noop("Slowpoke"),loc_noop("Squirtle"),loc_noop("Voltorb")}, 449 "FR","cm_pokemon","Default","pokeball","Castle" 450 }, 451 452 { 453 loc_noop("The Zoo"), 454 {"zoo_Bat","zoo_Beaver","zoo_Bunny","zoo_Deer","zoo_Hedgehog","zoo_Moose","zoo_Pig","zoo_Porkey","zoo_Sheep","zoo_chicken","zoo_elephant","zoo_fish","zoo_frog","zoo_snail","zoo_turtle"}, 455 {loc_noop("Batty"),loc_noop("Tails"),loc_noop("Bunny"),loc_noop("Deer"),loc_noop("Spikes"),loc_noop("Horns"),loc_noop("Bacon"),loc_noop("Porkey"),loc_noop("Sheepy"),loc_noop("Chicken"),loc_noop("Trunks"),loc_noop("Fishy"),loc_noop("Legs"),loc_noop("Slimer"),loc_noop("Roshi")}, 456 "FR","cm_birdy","Default","Bone","Castle" 457 }, 458 459 { 460 loc_noop("The Devs"), 461 {"ushanka","zoo_Sheep","bb_bob","Skull","poke_mudkip","lambda","WizardHat","sf_ryu","android","fr_lemon","mp3"}, 462 {loc_noop("unC0Rr"), loc_noop("sheepluva"), loc_noop("nemo"), loc_noop("mikade"), loc_noop("koda"), loc_noop("burp"),loc_noop("HeneK"),loc_noop("Tiyuri"),loc_noop("Xeli"),loc_noop("Displacer"),loc_noop("szczur")}, 463 "FR","cm_hw","Classic","Statue","Castle" 464 }, 465 466 { 467 loc_noop("Mushroom Kingdom"), 468 {"sm_daisy","sm_luigi","sm_mario","sm_peach","sm_toad","sm_wario","NoHat","NoHat"}, 469 {loc_noop("Daisy"),loc_noop("Luigi"),loc_noop("Mario"),loc_noop("Princess Peach"),loc_noop("Toad"),loc_noop("Wario"),loc_noop("Yoshi"),loc_noop("Waluigi")}, 470 "FR","comoros","Default","Badger","Castle" 471 }, 472 473 { 474 loc_noop("Pirates"), 475 {"pirate_jack","pirate_jack_bandana"}, 476 {loc_noop("Rusted Diego"),loc_noop("Fuzzy Beard"),loc_noop("Al.Kaholic"),loc_noop("Morris"),loc_noop("Yumme Gunpowder"),loc_noop("Cutlass Cain"),loc_noop("Jim Morgan"),loc_noop("Silver"),loc_noop("Dubloon Devil"),loc_noop("Ugly Mug"),loc_noop("Fair Wind"),loc_noop("Scallywag"),loc_noop("Salty Dog"),loc_noop("Bearded Beast"),loc_noop("Timbers"),loc_noop("Both Barrels"),loc_noop("Jolly Roger")}, 477 "R","cm_pirate","Pirate","chest","Castle" 478 }, 479 480 { 481 loc_noop("Gangsters"), 482 {"Moustache","Cowboy","anzac","Bandit","thug","Jason","NinjaFull","chef"}, 483 {loc_noop("The Boss"),loc_noop("Jimmy"),loc_noop("Frankie"),loc_noop("Morris"),loc_noop("Mooney"),loc_noop("Knives"),loc_noop("Tony"),loc_noop("Meals")}, 484 "F","cm_anarchy","Mobster","deadhog","Castle" 485 }, 486 487 488 { 489 loc_noop("Twenty-Twenty"), 490 {"Glasses","lambda","SunGlasses","Sniper","Terminator_Glasses","Moustache_glasses","doctor","punkman","rasta"}, 491 {loc_noop("Specs"),loc_noop("Speckles"),loc_noop("Spectator"),loc_noop("Glasses"),loc_noop("Glassy"),loc_noop("Harry Potter"),loc_noop("Goggles"),loc_noop("Clark Kent"),loc_noop("Goggs"),loc_noop("Lightbender"),loc_noop("Specs Appeal"),loc_noop("Four Eyes")}, 492 "R","cm_face","Default","eyecross","Castle" 493 }, 494 495 496 { 497 loc_noop("Monsters"), 498 {"Skull","Jason","ShaggyYeti","Zombi","cyclops","Mummy","hogpharoah","vampirichog"}, 499 {loc_noop("Bones"),loc_noop("Jason"),loc_noop("Yeti"),loc_noop("Zombie"),loc_noop("Old One Eye"),loc_noop("Ramesses"),loc_noop("Xerxes"),loc_noop("Count Hogula")}, 500 "FR","cm_vampire","Default","octopus","Castle" 501 }, 502 503 { 504 loc_noop("The Iron Curtain"), 505 {"ushanka","war_sovietcomrade1","war_sovietcomrade1","ushanka"}, 506 {loc_noop("Alex"),loc_noop("Sergey"),loc_noop("Vladimir"),loc_noop("Andrey"),loc_noop("Dimitry"),loc_noop("Ivan"),loc_noop("Oleg"),loc_noop("Kostya"),loc_noop("Anton"),loc_noop("Eugene")}, 507 "R","cm_soviet","Russian","skull","Castle" 508 }, 509 510 { 511 loc_noop("Desert Storm"), 512 {"war_desertofficer","war_desertgrenadier1","war_desertmedic","war_desertsapper1","war_desertgrenadier2","war_desertgrenadier4","war_desertsapper2","war_desertgrenadier5"}, 513 {loc_noop("Brigadier Briggs"),loc_noop("Lt. Luke"),loc_noop("Sgt. Smith"),loc_noop("Corporal Calvin"),loc_noop("Frank"),loc_noop("Joe"),loc_noop("Sam"),loc_noop("Donald")}, 514 "F","bhutan","Default","Grave","Castle" 515 }, 516 517 { 518 loc_noop("The Hospital"), 519 {"doctor","nurse","war_britmedic","war_desertmedic","war_germanww2medic"}, 520 {loc_noop("Dr. Blackwell"),loc_noop("Dr. Drew"),loc_noop("Dr. Harvey"),loc_noop("Dr. Crushing"),loc_noop("Dr. Jenner"),loc_noop("Dr. Barnard"),loc_noop("Dr. Parkinson"),loc_noop("Dr. Banting"),loc_noop("Dr. Horace"),loc_noop("Dr. Hollows"),loc_noop("Dr. Jung")}, 521 "R","cm_firstaid","Default","heart","Castle" 522 } 523 524 } 525 526local preMadeTeamNamesTranslated = {} 527local preMadeTeamNamesOriginal = {} 528for i=1, #preMadeTeam do 529 table.insert(preMadeTeamNamesOriginal, preMadeTeam[i][1]) 530 table.insert(preMadeTeamNamesTranslated, loc(preMadeTeam[i][1])) 531end 532 533local gameFlagList = { 534 {"gfOneClanMode", false, gfOneClanMode}, 535 {"gfMultiWeapon", false, gfMultiWeapon}, 536 {"gfSolidLand", false, gfSolidLand}, 537 {"gfBorder", false, gfBorder}, 538 {"gfDivideTeams", false, gfDivideTeams}, 539 {"gfLowGravity", false, gfLowGravity}, 540 {"gfLaserSight", true, gfLaserSight}, 541 {"gfInvulnerable", false, gfInvulnerable}, 542 {"gfResetHealth", false, gfResetHealth}, 543 {"gfVampiric", false, gfVampiric}, 544 {"gfKarma", false, gfKarma}, 545 {"gfArtillery", false, gfArtillery}, 546 {"gfSwitchHog", false, gfSwitchHog}, 547 {"gfRandomOrder", false, gfRandomOrder}, 548 {"gfKing", false, gfKing}, 549 {"gfPlaceHog", false, gfPlaceHog}, 550 {"gfSharedAmmo", false, gfSharedAmmo}, 551 {"gfDisableGirders", false, gfDisableGirders}, 552 {"gfDisableLandObjects", false, gfDisableLandObjects}, 553 {"gfAISurvival", false, gfAISurvival}, 554 {"gfInfAttack", true, gfInfAttack}, 555 {"gfResetWeps", false, gfResetWeps}, 556 {"gfPerHogAmmo", false, gfPerHogAmmo}, 557 {"gfDisableWind", false, gfDisableWind}, 558 {"gfMoreWind", false, gfMoreWind}, 559 {"gfTagTeam", false, gfTagTeam}, 560 {"gfShoppaBorder", false, gfShoppaBorder}, 561 } 562 563 local reducedSpriteIDArray = { 564 sprTargetBee, sprAmGirder, sprAmRubber, sprIceTexture, sprHHTelepMask, 565 sprAMAmmos, sprAMAmmosBW, sprAMSlot, sprAMCorners, sprTurnsLeft, sprBotlevels, 566 sprSpeechCorner, sprSpeechEdge, sprSpeechTail, sprThoughtCorner, sprThoughtEdge, sprThoughtTail, 567 sprShoutCorner, sprShoutEdge, sprShoutTail, } 568 569 -- Set in onGameInit 570 local reducedSpriteIDArrayFrames 571 572 local reducedSpriteTextArray = { 573 "sprTargetBee", "sprAmGirder", "sprAmRubber", "sprIceTexture", "sprHHTelepMask", 574 "sprAMAmmos", "sprAMAmmosBW", "sprAMSlot", "sprAMCorners", "sprTurnsLeft", "sprBotlevels", 575 "sprSpeechCorner", "sprSpeechEdge", "sprSpeechTail", "sprThoughtCorner", "sprThoughtEdge", "sprThoughtTail", 576 "sprShoutCorner", "sprShoutEdge", "sprShoutTail", } 577 578---------------------------- 579-- placement shite 580---------------------------- 581 582local landType = 0 583local superDelete = false 584local ufoGear = nil 585ufoFuel = 0 586mapID = 1 587local portalDistance = 5000/5 588local helpDisabled = false --determines whether help popups pop up 589local CG = nil -- this is the visual gear displayed at CursorX, CursorY 590local crateSprite = nil-- this is a visual gear aid for crate placement 591local crateSpriteBorer = nil 592local waypointPreviewSprite = nil 593 594local cGear = nil -- detects placement of girders and objects (using airattack) 595local cGearPlacementDone = false 596local curWep = amNothing 597local leftHeld = false 598local rightHeld = false 599local preciseOn = false 600 601-- primary placement categories 602local cIndex = 1 -- category index 603local cat = { 604 loc("Girder Placement Mode"), 605 loc("Rubber Placement Mode"), 606 loc("Mine Placement Mode"), 607 loc("Dud Mine Placement Mode"), 608 loc("Sticky Mine Placement Mode"), 609 loc("Air Mine Placement Mode"), 610 loc("Barrel Placement Mode"), 611 loc("Health Crate Placement Mode"), 612 loc("Weapon Crate Placement Mode"), 613 loc("Utility Crate Placement Mode"), 614 loc("Target Placement Mode"), 615 loc("Cleaver Placement Mode"), 616 loc("Repositioning Mode"), 617 loc("Goal Definition Mode"), 618 loc("Hog Identity Mode"), 619 loc("Team Identity Mode"), 620 loc("Health Modification Mode"), 621 loc("Sprite Placement Mode"), 622 loc("Sprite Modification Mode"), 623 loc("Waypoint Editing Mode") 624 } 625 626 627local pMode = {} -- pMode contains custom subsets of the main categories 628local pIndex = 1 629local sFrame = 0 -- frame in sprite placement mode 630 631local genTimer = 0 632 633local CGR = 1 -- current girder rotation, we actually need this as HW remembers what rotation you last used 634 635local placedX = {} -- x coord of placed object 636local placedY = {} -- y coord of placed object 637local placedSpec = {} -- this is different depending on what was placed, for mines it is their time, for crates it is their content, (for girders/rubbers it used to be their rotation, and for sprites, their name, but this has been moved to different variables to allow more complex / smooth editing) 638local placedType = {} -- what kind of object was placed: mine, crate, girder, rubber, barrel, etc. 639 640local placedTint = {} -- only girders/rubbers/sprites use this, it is their tint / colouration 641local placedSprite = {} -- what sprite was placed 642local placedFrame = {} -- what frame of sprite was placed (rotation for girders / rubber) 643local placedLandFlags = {} 644local placedHWMapFlag = {} -- this is what HWMapConverter uses 645local placedCount = 0 -- do we really need this? 646 647local sSprite -- sprite overlay that glows to show selected sprites 648local sCirc -- circle that appears around selected gears 649local sGear = nil 650local closestDist 651local closestGear = nil 652local closestSpriteID = nil 653 654local wpRadius = 450 655 656------------------------ 657-- SOME GENERAL METHODS 658------------------------ 659 660function BoolToString(boo) 661 if boo == true then 662 return("true") 663 else 664 return("false") 665 end 666end 667 668function GetDistFromGearToXY(gear, g2X, g2Y) 669 670 g1X, g1Y = GetGearPosition(gear) 671 q = g1X - g2X 672 w = g1Y - g2Y 673 674 return ( (q*q) + (w*w) ) 675 676end 677 678------------------------------------------------------------ 679-- STUFF FOR LOADING SPECIAL POINTS / HWMAP CONVERSION 680------------------------------------------------------------ 681 682local specialPointsX = {} 683local specialPointsY = {} 684local specialPointsFlag = {} 685local specialPointsCount = 0 686 687function onSpecialPoint(x,y,flag) 688 specialPointsX[specialPointsCount] = x 689 specialPointsY[specialPointsCount] = y 690 specialPointsFlag[specialPointsCount] = flag 691 specialPointsCount = specialPointsCount + 1 692end 693 694-- you know you could probably add multiple layers to this to get more points 695-- after the first set is expended have the last 1 be 127 696-- and then increment some other counter so like 697 698-- this function interprets special points that have been embedded into an HWPMAP 699function InterpretPoints() 700 701 -- flags run from 0 to 127 702 for i = 0, (specialPointsCount-1) do 703 704 -- Mines 705 if specialPointsFlag[i] == 1 then 706 SetTimer(AddGear(specialPointsX[i], specialPointsY[i], gtMine, 0, 0, 0, 0), 1) 707 elseif specialPointsFlag[i] == 2 then 708 SetTimer(AddGear(specialPointsX[i], specialPointsY[i], gtMine, 0, 0, 0, 0), 1000) 709 elseif specialPointsFlag[i] == 3 then 710 SetTimer(AddGear(specialPointsX[i], specialPointsY[i], gtMine, 0, 0, 0, 0), 2000) 711 elseif specialPointsFlag[i] == 4 then 712 SetTimer(AddGear(specialPointsX[i], specialPointsY[i], gtMine, 0, 0, 0, 0), 3000) 713 elseif specialPointsFlag[i] == 5 then 714 SetTimer(AddGear(specialPointsX[i], specialPointsY[i], gtMine, 0, 0, 0, 0), 4000) 715 elseif specialPointsFlag[i] == 6 then 716 SetTimer(AddGear(specialPointsX[i], specialPointsY[i], gtMine, 0, 0, 0, 0), 5000) 717 718 -- Sticky Mines 719 elseif specialPointsFlag[i] == 7 then 720 AddGear(specialPointsX[i], specialPointsY[i], gtSMine, 0, 0, 0, 0) 721 722 -- Air Mines 723 elseif specialPointsFlag[i] == 8 then 724 AddGear(specialPointsX[i], specialPointsY[i], gtAirMine, 0, 0, 0, 0) 725 726 -- Health Crates 727 elseif specialPointsFlag[i] == 9 then 728 SetHealth(SpawnHealthCrate(specialPointsX[i],specialPointsY[i]),25) 729 elseif specialPointsFlag[i] == 10 then 730 SetHealth(SpawnHealthCrate(specialPointsX[i],specialPointsY[i]),50) 731 elseif specialPointsFlag[i] == 11 then 732 SetHealth(SpawnHealthCrate(specialPointsX[i],specialPointsY[i]),75) 733 elseif specialPointsFlag[i] == 12 then 734 SetHealth(SpawnHealthCrate(specialPointsX[i],specialPointsY[i]),100) 735 736 -- Cleaver 737 elseif specialPointsFlag[i] == 13 then 738 AddGear(specialPointsX[i], specialPointsY[i], gtKnife, 0, 0, 0, 0) 739 740 -- Target 741 elseif specialPointsFlag[i] == 14 then 742 AddGear(specialPointsX[i], specialPointsY[i], gtTarget, 0, 0, 0, 0) 743 744 --Barrels 745 elseif specialPointsFlag[i] == 15 then 746 SetHealth(AddGear(specialPointsX[i], specialPointsY[i], gtExplosives, 0, 0, 0, 0),1) 747 elseif specialPointsFlag[i] == 16 then 748 SetHealth(AddGear(specialPointsX[i], specialPointsY[i], gtExplosives, 0, 0, 0, 0),25) 749 elseif specialPointsFlag[i] == 17 then 750 SetHealth(AddGear(specialPointsX[i], specialPointsY[i], gtExplosives, 0, 0, 0, 0),50) 751 elseif specialPointsFlag[i] == 18 then 752 SetHealth(AddGear(specialPointsX[i], specialPointsY[i], gtExplosives, 0, 0, 0, 0),75) 753 elseif specialPointsFlag[i] == 19 then 754 SetHealth(AddGear(specialPointsX[i], specialPointsY[i], gtExplosives, 0, 0, 0, 0),100) 755 756 -- There are about 58+- weps / utils 757 -- Weapon Crates 758 elseif (specialPointsFlag[i] >= 20) and (specialPointsFlag[i] < (#atkArray+20)) then 759 tempG = SpawnAmmoCrate(specialPointsX[i],specialPointsY[i],atkArray[specialPointsFlag[i]-19][1]) 760 setGearValue(tempG,"contents",atkArray[specialPointsFlag[i]-19][2]) 761 762 763 -- Utility Crates 764 elseif (specialPointsFlag[i] >= (#atkArray+20)) and (specialPointsFlag[i] < (#atkArray+20+#utilArray)) then 765 tempG = SpawnUtilityCrate(specialPointsX[i],specialPointsY[i],utilArray[specialPointsFlag[i]-19-#atkArray][1]) 766 setGearValue(tempG,"contents",utilArray[specialPointsFlag[i]-19-#atkArray][2]) 767 768 --79-82 (reserved for future wep crates) 769 --89,88,87,86 and 85,84,83,82 (reserved for the 2 custom sprites and their landflags) 770 771 --90-99 reserved for scripted structures 772 773 elseif specialPointsFlag[i] == 98 then 774 portalDistance = div(specialPointsX[i],5) 775 ufoFuel = specialPointsY[i] 776 777 -- Normal Girders 778 elseif specialPointsFlag[i] == 100 then 779 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 0, U_LAND_TINT_NORMAL, nil, nil, nil, lfNormal) 780 elseif specialPointsFlag[i] == 101 then 781 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 1, U_LAND_TINT_NORMAL, nil, nil, nil, lfNormal) 782 elseif specialPointsFlag[i] == 102 then 783 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 2, U_LAND_TINT_NORMAL, nil, nil, nil, lfNormal) 784 elseif specialPointsFlag[i] == 103 then 785 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 3, U_LAND_TINT_NORMAL, nil, nil, nil, lfNormal) 786 elseif specialPointsFlag[i] == 104 then 787 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 4, U_LAND_TINT_NORMAL, nil, nil, nil, lfNormal) 788 elseif specialPointsFlag[i] == 105 then 789 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 5, U_LAND_TINT_NORMAL, nil, nil, nil, lfNormal) 790 elseif specialPointsFlag[i] == 106 then 791 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 6, U_LAND_TINT_NORMAL, nil, nil, nil, lfNormal) 792 elseif specialPointsFlag[i] == 107 then 793 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 7, U_LAND_TINT_NORMAL, nil, nil, nil, lfNormal) 794 795 -- Invulnerable Girders 796 elseif specialPointsFlag[i] == 108 then 797 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 0, U_LAND_TINT_INDESTRUCTIBLE, nil, nil, nil, lfIndestructible) 798 elseif specialPointsFlag[i] == 109 then 799 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 1, U_LAND_TINT_INDESTRUCTIBLE, nil, nil, nil, lfIndestructible) 800 elseif specialPointsFlag[i] == 110 then 801 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 2, U_LAND_TINT_INDESTRUCTIBLE, nil, nil, nil, lfIndestructible) 802 elseif specialPointsFlag[i] == 111 then 803 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 3, U_LAND_TINT_INDESTRUCTIBLE, nil, nil, nil, lfIndestructible) 804 elseif specialPointsFlag[i] == 112 then 805 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 4, U_LAND_TINT_INDESTRUCTIBLE, nil, nil, nil, lfIndestructible) 806 elseif specialPointsFlag[i] == 113 then 807 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 5, U_LAND_TINT_INDESTRUCTIBLE, nil, nil, nil, lfIndestructible) 808 elseif specialPointsFlag[i] == 114 then 809 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 6, U_LAND_TINT_INDESTRUCTIBLE, nil, nil, nil, lfIndestructible) 810 elseif specialPointsFlag[i] == 115 then 811 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 7, U_LAND_TINT_INDESTRUCTIBLE, nil, nil, nil, lfIndestructible) 812 813 -- Icy Girders 814 elseif specialPointsFlag[i] == 116 then 815 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 0, U_LAND_TINT_ICE, nil, nil, nil, lfIce) 816 elseif specialPointsFlag[i] == 117 then 817 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 1, U_LAND_TINT_ICE, nil, nil, nil, lfIce) 818 elseif specialPointsFlag[i] == 118 then 819 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 2, U_LAND_TINT_ICE, nil, nil, nil, lfIce) 820 elseif specialPointsFlag[i] == 119 then 821 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 3, U_LAND_TINT_ICE, nil, nil, nil, lfIce) 822 elseif specialPointsFlag[i] == 120 then 823 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 4, U_LAND_TINT_ICE, nil, nil, nil, lfIce) 824 elseif specialPointsFlag[i] == 121 then 825 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 5, U_LAND_TINT_ICE, nil, nil, nil, lfIce) 826 elseif specialPointsFlag[i] == 121 then 827 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 6, U_LAND_TINT_ICE, nil, nil, nil, lfIce) 828 elseif specialPointsFlag[i] == 123 then 829 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmGirder, 7, U_LAND_TINT_ICE, nil, nil, nil, lfIce) 830 831 -- Rubber Bands 832 elseif specialPointsFlag[i] == 124 then 833 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmRubber, 0, U_LAND_TINT_NORMAL, nil, nil, nil, lfBouncy) 834 elseif specialPointsFlag[i] == 125 then 835 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmRubber, 1, U_LAND_TINT_NORMAL, nil, nil, nil, lfBouncy) 836 elseif specialPointsFlag[i] == 126 then 837 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmRubber, 2, U_LAND_TINT_NORMAL, nil, nil, nil, lfBouncy) 838 elseif specialPointsFlag[i] == 127 then 839 PlaceSprite(specialPointsX[i], specialPointsY[i], sprAmRubber, 3, U_LAND_TINT_NORMAL, nil, nil, nil, lfBouncy) 840 841 -- Waypoints 842 else -- 0 / no value 843 PlaceWaypoint(specialPointsX[i],specialPointsY[i]) 844 end 845 846 end 847 848end 849 850--shoppabalance crap 851function AddShoppaPoint(x,y,c) 852 table.insert(shoppaPX, x) 853 table.insert(shoppaPY, y) 854 table.insert(shoppaPR, c) 855end 856 857function GetRankedColour(r) 858 if r == 1 then 859 return(0xFF0000FF) 860 elseif r == 2 then 861 return(0xFFFF00FF) 862 elseif r == 3 then 863 return(0x00FF00FF) 864 elseif r == 4 then 865 return(0x0000FFFF) 866 elseif r == 5 then 867 return(0xFF00FFFF) 868 end 869end 870 871----------------------------------------- 872-- PRIMARY HEDGE EDITOR PLACEMENT STUFF 873----------------------------------------- 874 875function GetClosestGear() 876 closestDist = 999999999 877 closestGear = nil 878 runOnGears(SelectGear) 879 return(closestGear) 880end 881 882function SelectGear(gear) 883 884 d = GetDistFromGearToXY(gear, placedX[placedCount], placedY[placedCount]) 885 886 if d < closestDist then 887 closestDist = d 888 closestGear = gear 889 end 890 891end 892 893function PlaceWaypoint(x,y) 894 895 placedX[placedCount] = x 896 placedY[placedCount] = y 897 placedType[placedCount] = loc("Waypoint Editing Mode") 898 placedLandFlags[placedCount] = nil -- use this to specify waypoint type maybe 899 placedHWMapFlag[placedCount] = 0 900 901 placedSprite[placedCount] = vgtCircle 902 placedSpec[placedCount] = AddVisualGear(x,y,vgtCircle,0,true) 903 placedTint[placedCount] = 0xFF0000FF 904 placedFrame[placedCount] = 1 905 SetVisualGearValues(placedSpec[placedCount], x, y, 164, 224, 1, 10, 0, wpRadius, 5, placedTint[placedCount]) 906 placedCount = placedCount +1 907 908end 909 910function LoadSprite(pX, pY, pSprite, pFrame, pTint, p1, p2, p3, pLandFlags) 911 912 placedX[placedCount] = pX 913 placedY[placedCount] = pY 914 placedSpec[placedCount] = nil 915 916 if pSprite == sprAmGirder then 917 918 placedType[placedCount] = loc("Girder Placement Mode") 919 920 --newHWMapStuff 921 if pLandFlags == lfIndestructible then specialMod = 1 922 elseif pLandFlags == lfIce then specialMod = 2 923 else specialMod = 0 924 end 925 placedHWMapFlag[placedCount] = pFrame+100+(8*specialMod) 926 927 928 elseif pSprite == sprAmRubber then 929 930 placedType[placedCount] = loc("Rubber Placement Mode") 931 932 --newHWMapStuff 933 if pFrame == 0 then placedHWMapFlag[placedCount] = 124 934 elseif pFrame == 1 then placedHWMapFlag[placedCount] = 125 935 elseif pFrame == 2 then placedHWMapFlag[placedCount] = 126 936 elseif pFrame == 3 then placedHWMapFlag[placedCount] = 127 937 end 938 939 else 940 placedType[placedCount] = loc("Sprite Placement Mode") 941 end 942 943 if pLandFlags == lfIce then 944 placedLandFlags[placedCount] = "lfIce" 945 elseif pLandFlags == lfIndestructible then 946 placedLandFlags[placedCount] = "lfIndestructible" 947 elseif pLandFlags == lfBouncy then 948 placedLandFlags[placedCount] = "lfBouncy" 949 else 950 placedLandFlags[placedCount] = "lfNormal" 951 end 952 953 placedTint[placedCount] = pTint 954 placedFrame[placedCount] = pFrame 955 956 placedSprite[placedCount] = pSprite 957 958 local success = PlaceSprite(pX, pY, pSprite, pFrame, pTint, nil, nil, nil, pLandFlags) 959 if succcess then 960 placedCount = placedCount + 1 961 end 962 963end 964 965function CallPlaceSprite(pID, silent) 966 967 if silent == nil then 968 silent = false 969 end 970 971 if landType == lfIce then 972 placedLandFlags[pID] = "lfIce" 973 placedTint[pID] = U_LAND_TINT_ICE 974 elseif landType == lfIndestructible then 975 placedLandFlags[pID] = "lfIndestructible" 976 placedTint[pID] = U_LAND_TINT_INDESTRUCTIBLE 977 elseif landType == lfBouncy then 978 placedLandFlags[pID] = "lfBouncy" 979 placedTint[pID] = U_LAND_TINT_BOUNCY 980 else 981 placedLandFlags[pID] = "lfNormal" 982 placedTint[pID] = U_LAND_TINT_NORMAL 983 end 984 985 -- Special case: Placing amAirAttack of the ammos sprite (since this one is overwritten) 986 local actualDisplayedImage = placedFrame[pID] 987 if (placedSprite[pID] == sprAMAmmos or placedSprite[pID] == sprAMAmmosBW) and (actualDisplayedImage == (amAirAttack - 1)) then 988 actualDisplayedImage = ammoFrameAirAttack 989 end 990 991 local success = PlaceSprite(placedX[pID], placedY[pID], placedSprite[pID], actualDisplayedImage, 992 placedTint[pID], 993 nil, -- overrite existing land 994 nil, nil, -- this stuff specifies flipping 995 landType) 996 997 if not silent then 998 if success then 999 PlaySound(sndPlaced) 1000 else 1001 PlaySound(sndDenied) 1002 end 1003 end 1004 1005 return success 1006 1007end 1008 1009function SelectClosestSprite() 1010 1011 closestDist = 999999999 1012 closestSpriteID = nil -- just in case 1013 1014 for i = 0, (placedCount-1) do 1015 if (placedType[i] == loc("Girder Placement Mode")) 1016 or (placedType[i] == loc("Rubber Placement Mode")) 1017 or (placedType[i] == loc("Sprite Placement Mode")) 1018 then 1019 q = placedX[i] - placedX[placedCount] 1020 w = placedY[i] - placedY[placedCount] 1021 d = ( (q*q) + (w*w) ) 1022 if d < closestDist then 1023 closestDist = d 1024 closestSpriteID = i 1025 1026 newTint = 0xFF00FFFF 1027 1028 SetVisualGearValues(sSprite, placedX[i], placedY[i], 0, 0, nil, placedFrame[i], 10000, placedSprite[i], 10000, newTint ) 1029 1030 end 1031 end 1032 end 1033 1034end 1035 1036function EraseClosestSprite() 1037 if closestSpriteID ~= nil then 1038 EraseSprite(placedX[closestSpriteID], placedY[closestSpriteID], placedSprite[closestSpriteID], placedFrame[closestSpriteID], 1039 nil, -- erase land only where the pixels match the land flag provided 1040 nil, -- only erase the provided land flags. don't touch other land flags or LandPixels 1041 nil, -- flip sprite horizontally 1042 nil, -- flip sprite vertically 1043 placedLandFlags[closestSpriteID]) 1044 1045 PlaySound(sndBump) 1046 1047 placedX[closestSpriteID] = nil 1048 placedY[closestSpriteID] = nil 1049 placedSpec[closestSpriteID] = nil 1050 placedType[closestSpriteID] = nil 1051 placedTint[closestSpriteID] = nil 1052 placedSprite[closestSpriteID] = nil 1053 placedFrame[closestSpriteID] = nil 1054 placedLandFlags[closestSpriteID] = nil 1055 closestSpriteID = nil 1056 SetVisualGearValues(sSprite, 0, 0, 0, 0, 0, 1, 10000, sprAmGirder, 10000, 0x00000000 ) 1057 else 1058 PlaySound(sndDenied) 1059 end 1060end 1061 1062-- work this into the above two functions and edit them, later 1063function EraseClosestWaypoint() 1064 1065 closestDist = 999999999 1066 closestSpriteID = nil -- just in case 1067 1068 for i = 0, (placedCount-1) do 1069 if (placedType[i] == loc("Waypoint Editing Mode")) then 1070 local q = placedX[i] - placedX[placedCount] 1071 local w = placedY[i] - placedY[placedCount] 1072 local d = ( (q*q) + (w*w) ) 1073 if d < closestDist then 1074 closestDist = d 1075 closestSpriteID = i 1076 1077 SetVisualGearValues(sSprite, placedX[i], placedY[i], 0, 0, nil, placedFrame[i], 10000, placedSprite[i], 10000, newTint ) 1078 end 1079 end 1080 end 1081 1082 if closestSpriteID ~= nil then 1083 DeleteVisualGear(placedSpec[closestSpriteID]) 1084 placedX[closestSpriteID] = nil 1085 placedY[closestSpriteID] = nil 1086 placedSpec[closestSpriteID] = nil 1087 placedType[closestSpriteID] = nil 1088 placedTint[closestSpriteID] = nil 1089 placedSprite[closestSpriteID] = nil 1090 placedFrame[closestSpriteID] = nil 1091 placedLandFlags[closestSpriteID] = nil 1092 closestSpriteID = nil 1093 SetVisualGearValues(sSprite, 0, 0, 0, 0, 0, 1, 10000, sprAmGirder, 10000, 0x00000000 ) 1094 PlaySound(sndBump) 1095 else 1096 PlaySound(sndDenied) 1097 end 1098end 1099 1100 1101-- essentially called when user clicks the mouse 1102-- with girders or an airattack 1103function PlaceObject(x,y) 1104 1105 placedX[placedCount] = x 1106 placedY[placedCount] = y 1107 placedType[placedCount] = cat[cIndex] 1108 placedSpec[placedCount] = pMode[pIndex] 1109 placedTint[placedCount] = nil 1110 placedFrame[placedCount] = nil 1111 placedLandFlags[placedCount] = nil 1112 placedSprite[placedCount] = nil 1113 placedHWMapFlag[placedCount] = nil 1114 placementSucceeded = true -- We assume success unless the placement logic said otherwise 1115 1116 if cat[cIndex] == loc("Girder Placement Mode") then 1117 1118 if superDelete == false then 1119 --lfObject and lfBasic 1120 placedFrame[placedCount] = CGR 1121 placedSprite[placedCount] = sprAmGirder 1122 placementSucceeded = CallPlaceSprite(placedCount) 1123 1124 if placementSucceeded then 1125 if landType == lfIndestructible then specialMod = 1 1126 elseif landType == lfIce then specialMod = 2 1127 else specialMod = 0 1128 end 1129 placedHWMapFlag[placedCount] = CGR+100+(8*specialMod) 1130 else 1131 placedType[placedCount] = "bogus" 1132 end 1133 else 1134 placedType[placedCount] = "bogus" -- we need this so we don't think we've placed a new girder and are trying to erase the things we just placed?? 1135 SelectClosestSprite() 1136 EraseClosestSprite() 1137 end 1138 1139 elseif cat[cIndex] == loc("Rubber Placement Mode") then 1140 1141 if superDelete == false then 1142 placedFrame[placedCount] = CGR 1143 placedSprite[placedCount] = sprAmRubber 1144 1145 --new ermagerd 1146 placedLandFlags[placedCount] = "lfBouncy" 1147 placedTint[placedCount] = U_LAND_TINT_NORMAL 1148 placementSucceeded = PlaceSprite(placedX[placedCount], placedY[placedCount], placedSprite[placedCount], placedFrame[placedCount], 1149 placedTint[placedCount], 1150 nil, 1151 nil, nil, 1152 landType) 1153 1154 if placementSucceeded then 1155 if CGR == 0 then placedHWMapFlag[placedCount] = 124 1156 elseif CGR == 1 then placedHWMapFlag[placedCount] = 125 1157 elseif CGR == 2 then placedHWMapFlag[placedCount] = 126 1158 elseif CGR == 3 then placedHWMapFlag[placedCount] = 127 1159 end 1160 PlaySound(sndPlaced) 1161 else 1162 placedType[placedCount] = "bogus" 1163 PlaySound(sndDenied) 1164 end 1165 else 1166 placedType[placedCount] = "bogus" 1167 SelectClosestSprite() 1168 EraseClosestSprite() 1169 end 1170 1171 elseif cat[cIndex] == loc("Target Placement Mode") then 1172 gear = AddGear(x, y, gtTarget, 0, 0, 0, 0) 1173 elseif cat[cIndex] == loc("Cleaver Placement Mode") then 1174 gear = AddGear(x, y, gtKnife, 0, 0, 0, 0) 1175 elseif cat[cIndex] == loc("Health Crate Placement Mode") then 1176 gear = SpawnHealthCrate(x,y) 1177 SetHealth(gear, pMode[pIndex]) 1178 elseif cat[cIndex] == loc("Weapon Crate Placement Mode") then 1179 gear = SpawnAmmoCrate(x, y, atkArray[pIndex][1]) 1180 placedSpec[placedCount] = atkArray[pIndex][2] 1181 setGearValue(gear,"contents",atkArray[pIndex][2]) 1182 elseif cat[cIndex] == loc("Utility Crate Placement Mode") then 1183 gear = SpawnUtilityCrate(x, y, utilArray[pIndex][1]) 1184 placedSpec[placedCount] = utilArray[pIndex][2] 1185 setGearValue(gear,"contents",utilArray[pIndex][2]) 1186 elseif cat[cIndex] == loc("Barrel Placement Mode") then 1187 gear = AddGear(x, y, gtExplosives, 0, 0, 0, 0) 1188 SetHealth(gear, pMode[pIndex]) 1189 elseif cat[cIndex] == loc("Mine Placement Mode") then 1190 gear = AddGear(x, y, gtMine, 0, 0, 0, 0) 1191 SetTimer(gear, pMode[pIndex]) 1192 elseif cat[cIndex] == loc("Dud Mine Placement Mode") then 1193 gear = AddGear(x, y, gtMine, 0, 0, 0, 0) 1194 SetHealth(gear, 0) 1195 SetGearValues(gear, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 36 - pMode[pIndex]) 1196 elseif cat[cIndex] == loc("Sticky Mine Placement Mode") then 1197 gear = AddGear(x, y, gtSMine, 0, 0, 0, 0) 1198 SetTimer(gear, pMode[pIndex]) 1199 elseif cat[cIndex] == loc("Air Mine Placement Mode") then 1200 gear = AddGear(x, y, gtAirMine, 0, 0, 0, 0) 1201 SetTimer(gear, pMode[pIndex]) 1202 SetGearValues(gear, nil, nil, pMode[pIndex]) 1203 elseif cat[cIndex] == loc("Repositioning Mode") then 1204 1205 if pMode[pIndex] == loc("Selection Mode") then 1206 sGear = GetClosestGear() 1207 if sGear ~= nil then 1208 PlaySound(sndPortalSwitch) 1209 end 1210 elseif pMode[pIndex] == loc("Placement Mode") then 1211 if sGear ~= nil then 1212 SetGearPosition(sGear, x, y) 1213 PlaySound(sndWarp) 1214 end 1215 elseif pMode[pIndex] == loc("Deletion Mode") then 1216 sGear = GetClosestGear() 1217 if (sGear == nil) then 1218 AddCaption(loc("Please click on a gear."), colorErrorMessage, capgrpVolume) 1219 PlaySound(sndDenied) 1220 elseif (GetGearType(sGear) == gtHedgehog) then 1221 AddCaption(loc("Hedgehogs can not be deleted."), colorErrorMessage, capgrpVolume) 1222 PlaySound(sndDenied) 1223 else 1224 DeleteGear(sGear) 1225 PlaySound(sndBump) 1226 end 1227 sGear = nil 1228 end 1229 1230 elseif (cat[cIndex] == loc("Hog Identity Mode")) or (cat[cIndex] == loc("Team Identity Mode")) then 1231 1232 sGear = GetClosestGear() 1233 if (sGear ~= nil) and (GetGearType(sGear) == gtHedgehog) then 1234 if (cat[cIndex] == loc("Hog Identity Mode")) then 1235 SetHogProfile(sGear, pMode[pIndex]) 1236 else -- set for the whole team 1237 SetTeamIdentity(sGear) 1238 end 1239 PlaySound(sndHello, sGear) 1240 else 1241 AddCaption(loc("Please click on a hedgehog."), colorErrorMessage, capgrpVolume) 1242 PlaySound(sndDenied) 1243 end 1244 1245 1246 1247 elseif cat[cIndex] == loc("Health Modification Mode") then 1248 1249 sGear = GetClosestGear() 1250 local gt = GetGearType(sGear) 1251 if gt == gtHedgehog or gt == gtExplosives or (gt == gtCase and GetGearPos(sGear) == 0x2) then 1252 local oldHealth, hDiff = GetHealth(sGear) 1253 if pMode[pIndex][2] == "set" then 1254 SetHealth(sGear, pMode[pIndex][1]) 1255 hDiff = pMode[pIndex][1] - oldHealth 1256 elseif pMode[pIndex][2] == "mod" then 1257 local min 1258 if gt == gtCase then min = 0 else min = 1 end 1259 local newHealth = math.max(min, GetHealth(sGear) + tonumber(pMode[pIndex][1])) 1260 SetHealth(sGear, newHealth) 1261 hDiff = newHealth - oldHealth 1262 end 1263 PlaySound(sndPortalSwitch) 1264 if gt == gtHedgehog and hDiff < 0 then 1265 local snd = { sndOw1, sndOw2, sndOw3 } 1266 PlaySound(snd[math.random(1, #snd)], sGear) 1267 end 1268 elseif gt == gtMine and GetHealth(sGear) == 0 then 1269 local newHealth 1270 if pMode[pIndex][2] == "set" then 1271 newHealth = pMode[pIndex][1] 1272 elseif pMode[pIndex][2] == "mod" then 1273 local _, oldHealth 1274 _,_,_,_,_,_,_,_,_,_,_, oldHealth = GetGearValues(sGear) 1275 oldHealth = 36 - oldHealth 1276 newHealth = math.max(1, oldHealth + tonumber(pMode[pIndex][1])) 1277 end 1278 if newHealth ~= nil then 1279 SetGearValues(sGear, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 36 - newHealth) 1280 PlaySound(sndPortalSwitch) 1281 end 1282 else 1283 AddCaption(loc("Please click on a hedgehog, barrel, health crate or dud mine."), colorErrorMessage, capgrpVolume) 1284 PlaySound(sndDenied) 1285 end 1286 1287 elseif cat[cIndex] == loc("Sprite Modification Mode") then 1288 1289 SelectClosestSprite() 1290 1291 if closestSpriteID ~= nil then 1292 if pMode[pIndex] == loc("LandFlag Modification Mode") then 1293 EraseSprite(placedX[closestSpriteID], placedY[closestSpriteID], placedSprite[closestSpriteID], placedFrame[closestSpriteID], nil, nil, nil, nil, placedLandFlags[closestSpriteID]) 1294 placementSucceeded = CallPlaceSprite(closestSpriteID, true) 1295 if placementSucceeded then 1296 closestSpriteID = nil 1297 SetVisualGearValues(sSprite, 0, 0, 0, 0, 0, 1, 10000, sprAmGirder, 10000, 0x00000000 ) 1298 PlaySound(sndPortalSwitch) 1299 else 1300 PlaySound(sndDenied) 1301 end 1302 elseif pMode[pIndex] == loc("Sprite Erasure Mode") then 1303 1304 EraseClosestSprite() 1305 1306 end 1307 else 1308 PlaySound(sndDenied) 1309 end 1310 1311 1312 elseif cat[cIndex] == loc("Goal Definition Mode") then 1313 1314 sGear = GetClosestGear() 1315 if sGear ~= nil then -- used to be closestGear 1316 1317 if getGearValue(sGear,"tag") == nil then 1318 1319 if pMode[pIndex] == loc("Victory Condition: Collect") then 1320 if GetGearType(sGear) == gtCase then 1321 setGearValue(sGear, "tag","collection") 1322 PlaySound(sndPortalSwitch) 1323 else 1324 AddCaption(loc("Please click on a crate."), colorErrorMessage, capgrpVolume) 1325 PlaySound(sndDenied) 1326 end 1327 else 1328 if pMode[pIndex] == loc("Victory Condition: Destroy") then 1329 setGearValue(sGear, "tag","victory") 1330 PlaySound(sndPortalSwitch) 1331 elseif pMode[pIndex] == loc("Losing Condition: Destroy") then 1332 setGearValue(sGear, "tag","failure") 1333 PlaySound(sndPortalSwitch) 1334 end 1335 end 1336 1337 else 1338 -- remove tag and delete circ 1339 setGearValue(sGear, "tag", nil) 1340 DeleteVisualGear(getGearValue(sGear,"tCirc")) 1341 setGearValue(sGear, "tCirc", nil) 1342 PlaySound(sndBump) 1343 end 1344 1345 1346 1347 end 1348 1349 1350 elseif cat[cIndex] == loc("Sprite Placement Mode") then 1351 1352 if superDelete == false then 1353 placedFrame[placedCount] = sFrame 1354 placedSprite[placedCount] = reducedSpriteIDArray[pIndex] 1355 placementSucceeded = CallPlaceSprite(placedCount) 1356 else 1357 placedType[placedCount] = "bogus" 1358 SelectClosestSprite() 1359 EraseClosestSprite() 1360 end 1361 1362 elseif cat[cIndex] == loc("Waypoint Editing Mode") then 1363 1364 1365 if pMode[pIndex] == loc("Delete Waypoint") then 1366 placedType[placedCount] = "bogus" 1367 EraseClosestWaypoint() 1368 else 1369 PlaceWaypoint(x,y) 1370 placedCount = placedCount - 1 1371 PlaySound(sndPlaced) 1372 end 1373 1374 end 1375 1376 placedCount = placedCount + 1 1377end 1378 1379-- called when user changes primary selection 1380-- either via up/down keys 1381-- or selecting girder/airattack 1382function RedefineSubset() 1383 1384 superDelete = false -- fairly new addition 1385 landType = 0 --- fairly new addition 1386 pIndex = 1 1387 pMode = {} 1388 1389 if cat[cIndex] == loc("Girder Placement Mode") then 1390 pIndex = CGR 1391 pMode = {loc("Girder")} 1392 elseif cat[cIndex] == loc("Rubber Placement Mode") then 1393 pIndex = CGR 1394 pMode = {loc("Rubber")} 1395 landType = lfBouncy -- for now, let's not allow anything else (-- fairly new addition) 1396 elseif cat[cIndex] == loc("Target Placement Mode") then 1397 pMode = {loc("Target")} 1398 elseif cat[cIndex] == loc("Cleaver Placement Mode") then 1399 pMode = {loc("Cleaver")} 1400 elseif cat[cIndex] == loc("Barrel Placement Mode") then 1401 pMode = {60,80,100,120,160,200,240,1,10,20,30,40,50} 1402 elseif cat[cIndex] == loc("Health Crate Placement Mode") then 1403 pMode = {25,30,40,50,75,100,150,200,0,5,10,15,20} 1404 elseif cat[cIndex] == loc("Weapon Crate Placement Mode") then 1405 for i = 1, #atkArray do 1406 pMode[i] = GetAmmoName(atkArray[i][1], true) 1407 end 1408 elseif cat[cIndex] == loc("Utility Crate Placement Mode") then 1409 for i = 1, #utilArray do 1410 pMode[i] = GetAmmoName(utilArray[i][1], true) 1411 end 1412 elseif cat[cIndex] == loc("Mine Placement Mode") then 1413 pMode = {3000,4000,5000,0,1000,2000} 1414 elseif cat[cIndex] == loc("Dud Mine Placement Mode") then 1415 pMode = {36,48,60,72,96,1,6,12,18,24} 1416 elseif cat[cIndex] == loc("Mine Placement Mode") then 1417 pMode = {3000,4000,5000,0,1000,2000} 1418 elseif cat[cIndex] == loc("Sticky Mine Placement Mode") then 1419 pMode = {500,1000,1500,2000,2500,0} 1420 elseif cat[cIndex] == loc("Air Mine Placement Mode") then 1421 pMode = {750,1000,1250,0,250,500} 1422 elseif cat[cIndex] == loc("Repositioning Mode") then 1423 pMode = {loc("Selection Mode"),loc("Placement Mode"), loc("Deletion Mode")} 1424 elseif cat[cIndex] == loc("Goal Definition Mode") then 1425 pMode = {loc("Victory Condition: Destroy"),loc("Losing Condition: Destroy"),loc("Victory Condition: Collect")} 1426 elseif cat[cIndex] == loc("Hog Identity Mode") then 1427 pMode = {loc("Soldier"),loc("Grenadier"),loc("Sniper"),loc("Pyro"),loc("Ninja"),loc("Commander"),loc("Chef"),loc("Engineer"),loc("Physicist"),loc("Trapper"),loc("Saint"),loc("Clown")} 1428 elseif cat[cIndex] == loc("Team Identity Mode") then 1429 pMode = preMadeTeamNamesTranslated 1430 elseif cat[cIndex] == loc("Health Modification Mode") then 1431 pMode = { {100, "set"}, {125, "set"}, {150, "set"}, {200, "set"}, {300, "set"}, {1000, "set"}, 1432 {"-100", "mod"}, {"-10", "mod"}, {"-1", "mod"}, {"+1", "mod"}, {"+10", "mod"}, {"+100", "mod"}, 1433 {1, "set"}, {10, "set"}, {15, "set"}, {20, "set"}, {25, "set"}, {30, "set"}, {40, "set"}, {50, "set"}, {75, "set"}, 1434} 1435 elseif cat[cIndex] == loc("Sprite Modification Mode") then 1436 pMode = {loc("LandFlag Modification Mode"),loc("Sprite Erasure Mode")} 1437 elseif cat[cIndex] == loc("Sprite Testing Mode") or cat[cIndex] == loc("Sprite Placement Mode") then 1438 for i = 1, #reducedSpriteTextArray do 1439 pMode[i] = reducedSpriteTextArray[i] 1440 end 1441 sFrame = 0 1442 elseif cat[cIndex] == loc("Waypoint Editing Mode") then 1443 pMode = {loc("Place Waypoint"), loc("Delete Waypoint")} 1444 end 1445 1446end 1447 1448------------------------------------------------ 1449-- LOADING AND SAVING DATA STUFF 1450------------------------------------------------ 1451 1452-- paste data you have saved previously here 1453function LoadLevelData() 1454 1455 if (mapID == nil) or (mapID == 0) then 1456 LoadMap(1) 1457 else 1458 LoadMap(mapID) 1459 end 1460 1461 for i = 1, techCount-1 do 1462 PlaceWaypoint(techX[i],techY[i]) 1463 end 1464 1465end 1466 1467-- When you save your level, this function 1468-- generates the AddTeam and AddHog function calls for onGameInit() 1469function GetDataForSavingHogs(gear) 1470 1471 --this is a quick hack so that the human team(s) will always be 1472 --given the first move ahead of the AI 1473 local tempDataList = {} 1474 if GetHogLevel(gear) == 0 then 1475 tempDataList = hogDataList 1476 else 1477 tempDataList = AIHogDataList 1478 end 1479 1480 if GetHogTeamName(gear) ~= lastRecordedTeam then 1481 1482 teamCounter = teamCounter + 1 1483 if teamCounter == 9 then 1484 teamCounter = 1 1485 end 1486 1487 -- Color argument for AddTeam; using the 1488 -- default clan color format. 1489 local tColor = -(GetHogClan(gear)+1) 1490 1491 local tFort, tGrave, tFlag, tVoice 1492 if getGearValue(gear,"grave") == nil then 1493 tFort = GetHogFort(gear) 1494 tGrave = GetHogGrave(gear) 1495 tFlag = GetHogFlag(gear) 1496 tVoice = GetHogVoicepack(gear) 1497 else 1498 tGrave = getGearValue(gear,"grave") 1499 tFort = getGearValue(gear,"fort") 1500 tFlag = getGearValue(gear,"flag") 1501 tVoice = getGearValue(gear,"voice") 1502 end 1503 if not tFort then tFort = "Castle" end 1504 if not tGrave then tGrave = "Statue" end 1505 if not tFlag then tFlag= "hedgewars" end 1506 if not tVoice then tVoice = "Default" end 1507 1508 lastRecordedTeam = GetHogTeamName(gear) 1509 1510 table.insert(tempDataList, "") 1511 1512 local oTeamName = getGearValue(gear, "originalTeamName") 1513 if oTeamName == nil or oTeamName == "" then 1514 oTeamName = GetHogTeamName(gear) 1515 end 1516 table.insert (tempDataList, 1517 " AddTeam(loc(\"" .. 1518 oTeamName .. "\")" .. 1519 ", " .. tColor .. 1520 ", " .. "\"" .. tGrave .. "\"" .. 1521 ", " .. "\"" .. tFort .. "\"" .. 1522 ", " .. "\"" .. tVoice .. "\"" .. 1523 ", " .. "\"" .. tFlag .. "\"" .. 1524 ")" 1525 ) 1526 1527 end 1528 1529 table.insert(hhs, gear) 1530 1531 local oName = getGearValue(gear, "originalName") 1532 if oName == nil or oName == "" then 1533 oName = GetHogName(gear) 1534 end 1535 table.insert (tempDataList, " hhs[" .. #hhs .."] = AddHog(loc(\"" .. 1536 oName .. "\"), " .. 1537 GetHogLevel(gear) .. ", " .. 1538 GetHealth(gear) .. ", \"" .. 1539 GetHogHat(gear) .. "\"" .. 1540 ")" 1541 ) 1542 1543 table.insert (tempDataList," SetGearPosition(hhs[" .. #hhs .. "], " .. GetX(gear) .. ", " .. GetY(gear) .. ")") 1544 1545 for e=1, #effectArray do 1546 if GetEffect(gear, effectArray[e]) ~= 0 then 1547 table.insert (tempDataList," SetEffect(hhs[" .. #hhs .. "], " .. effectStr[e] .. ", " .. GetEffect(gear, effectArray[e]) .. ")") 1548 end 1549 end 1550 local dX, _ = GetGearVelocity(gear) 1551 if dX < 0 then 1552 table.insert (tempDataList," HogTurnLeft(hhs[" .. #hhs .. "], true)") 1553 end 1554 1555 if getGearValue(gear,"tag") ~= nil then 1556 table.insert (tempDataList," setGearValue(hhs[" .. #hhs .. "], \"tag\", \"" .. getGearValue(gear,"tag") .. "\")") 1557 end 1558 1559 -- save the ammo values for each gear, we will call this later 1560 -- when we want to output it to console 1561 1562 if getGearValue(gear,"ranking") ~= nil then 1563 table.insert(shoppaPointList, "AddShoppaPoint(" .. GetX(gear) .. ", " .. GetY(gear) .. ", " .. getGearValue(gear,"ranking") .. ")") 1564 end 1565 1566 for i = 1, #atkArray do 1567 setGearValue(gear, atkArray[i][1], GetAmmoCount(gear, atkArray[i][1])) 1568 end 1569 1570 for i = 1, #utilArray do 1571 setGearValue(gear, utilArray[i][1], GetAmmoCount(gear, utilArray[i][1])) 1572 end 1573 1574 if GetHogLevel(gear) == 0 then 1575 hogDataList = tempDataList 1576 else 1577 AIHogDataList = tempDataList 1578 end 1579 1580end 1581 1582-- output hog and team data to the console 1583function SaveHogData() 1584 1585 teamCounter = 0 1586 lastRecordedTeam = "" 1587 hhs = {} 1588 1589 runOnHogs(GetDataForSavingHogs) 1590 1591 WriteLnToConsole(" ------ TEAM LIST ------") 1592 1593 for i = 1, #hogDataList do 1594 WriteLnToConsole(hogDataList[i]) 1595 end 1596 1597 for i = 1, #AIHogDataList do 1598 WriteLnToConsole(AIHogDataList[i]) 1599 end 1600 1601 WriteLnToConsole("") 1602 1603 if #shoppaPointList > 0 then 1604 WriteLnToConsole(" ------ SHOPPA POINT LIST ------") 1605 for i = 1, #shoppaPointList do 1606 WriteLnToConsole(shoppaPointList[i]) 1607 end 1608 end 1609 1610 1611end 1612 1613-- generates an onGameInit() template with scheme data, team adds, and hogs 1614function SaveConfigData() 1615 1616 WriteLnToConsole("function onGameInit()") 1617 WriteLnToConsole("") 1618 1619 temp = " EnableGameFlags(gfDisableWind" 1620 for i = 1, #gameFlagList do 1621 if gameFlagList[i][2] == true then 1622 temp = temp .. ", ".. gameFlagList[i][1] 1623 end 1624 end 1625 1626 WriteLnToConsole(" ClearGameFlags()") 1627 WriteLnToConsole(temp .. ")") 1628 1629 WriteLnToConsole(" Map = \"" .. Map .. "\"") 1630 WriteLnToConsole(" Seed = \"" .. Seed .. "\"") 1631 WriteLnToConsole(" Theme = \"" .. Theme .. "\"") 1632 WriteLnToConsole(" MapGen = " .. MapGen) 1633 WriteLnToConsole(" MapFeatureSize = " .. MapFeatureSize) 1634 WriteLnToConsole(" TemplateFilter = " .. TemplateFilter) 1635 WriteLnToConsole(" TemplateNumber = " .. TemplateNumber) 1636 WriteLnToConsole(" TurnTime = " .. TurnTime) 1637 WriteLnToConsole(" Explosives = " .. Explosives) 1638 WriteLnToConsole(" MinesNum = " .. MinesNum) 1639 WriteLnToConsole(" CaseFreq = " .. CaseFreq) 1640 WriteLnToConsole(" Delay = " .. Delay) 1641 1642 WriteLnToConsole(" HealthCaseProb = " .. HealthCaseProb) 1643 WriteLnToConsole(" HealthCaseAmount = " .. HealthCaseAmount) 1644 WriteLnToConsole(" DamagePercent = " .. DamagePercent) 1645 WriteLnToConsole(" RopePercent = " .. RopePercent) 1646 WriteLnToConsole(" MinesTime = " .. MinesTime) 1647 WriteLnToConsole(" MineDudPercent = " .. MineDudPercent) 1648 WriteLnToConsole(" SuddenDeathTurns = " .. SuddenDeathTurns) 1649 WriteLnToConsole(" WaterRise = " .. WaterRise) 1650 WriteLnToConsole(" HealthDecrease = " .. HealthDecrease) 1651 1652 WriteLnToConsole(" Ready = " .. Ready) 1653 WriteLnToConsole(" AirMinesNum = " .. AirMinesNum) 1654 WriteLnToConsole(" GetAwayTime = " .. GetAwayTime) 1655 WriteLnToConsole(" WorldEdge = " .. WorldEdge) 1656 1657 -- ScriptParam intentionally left out, it doesn't make sense for missions. 1658 1659 WriteLnToConsole("") 1660 1661 SaveHogData() 1662 1663 WriteLnToConsole("") 1664 WriteLnToConsole("end") 1665 1666end 1667 1668-- output gear data as special points to be placed in a converted HWMAP, readable by InterpretPoints() 1669function ConvertGearDataToHWPText() 1670 1671 WriteLnToConsole("") 1672 WriteLnToConsole("--BEGIN HWMAP CONVERTER POINTS--") 1673 WriteLnToConsole("-- You can paste this data into the HWMAP converter if needed.") 1674 WriteLnToConsole("--[[") 1675 WriteLnToConsole("") 1676 1677 for i = 1, #hFlagList do 1678 WriteLnToConsole(hFlagList[i]) 1679 end 1680 1681 WriteLnToConsole("") 1682 WriteLnToConsole("]]") 1683 WriteLnToConsole("--END HWMAP CONVERTER POINTS--") 1684 WriteLnToConsole("") 1685 1686end 1687 1688-- sigh 1689-- gradually got more bloated with the addition of hwpoint tracking and 1690-- distinction betweeen the need to track victory/win conditions or not 1691function GetDataForGearSaving(gear) 1692 1693 local temp = nil 1694 local specialFlag = nil 1695 local arrayList = nil 1696 1697 if GetGearType(gear) == gtMine then 1698 1699 temp = " tempG = AddGear(" .. 1700 GetX(gear) .. ", " .. 1701 GetY(gear) .. ", gtMine, 0, 0, 0, 0)" 1702 table.insert(mineList, temp) 1703 table.insert(mineList, " SetTimer(tempG, " .. GetTimer(gear) .. ")") 1704 if (GetHealth(gear) == 0) then 1705 table.insert(mineList, " SetHealth(tempG, 0)") 1706 local _, damage 1707 _,_,_,_,_,_,_,_,_,_,_,damage = GetGearValues(gear) 1708 if damage ~= 0 then 1709 table.insert(mineList, " SetGearValues(tempG, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "..damage..")") 1710 end 1711 end 1712 if (getGearValue(gear, "tag") ~= nil) then 1713 table.insert(mineList, " setGearValue(tempG, \"tag\", \"" .. getGearValue(gear,"tag") .. "\")") 1714 end 1715 1716 if GetTimer(gear) == 0 then specialFlag = 1 1717 elseif GetTimer(gear) == 1000 then specialFlag = 2 1718 elseif GetTimer(gear) == 2000 then specialFlag = 3 1719 elseif GetTimer(gear) == 3000 then specialFlag = 4 1720 elseif GetTimer(gear) == 4000 then specialFlag = 5 1721 elseif GetTimer(gear) == 5000 then specialFlag = 6 1722 end 1723 1724 elseif GetGearType(gear) == gtSMine then 1725 1726 arrayList = sMineList 1727 temp = " tempG = AddGear(" .. 1728 GetX(gear) .. ", " .. 1729 GetY(gear) .. ", gtSMine, 0, 0, 0, 0)" 1730 table.insert(sMineList, temp) 1731 table.insert(sMineList, " SetTimer(tempG, " .. GetTimer(gear) .. ")") 1732 specialFlag = 7 1733 1734 elseif GetGearType(gear) == gtAirMine then 1735 1736 temp = " tempG = AddGear(" .. 1737 GetX(gear) .. ", " .. 1738 GetY(gear) .. ", gtAirMine, 0, 0, 0, 0)" 1739 table.insert(airMineList, temp) 1740 table.insert(airMineList, " SetTimer(tempG, " .. GetTimer(gear) .. ")") 1741 table.insert(airMineList, " SetGearValues(tempG, nil, nil, " .. GetTimer(gear) .. ")") 1742 if (getGearValue(gear, "tag") ~= nil) then 1743 table.insert(airMineList, " setGearValue(tempG, \"tag\", \"" .. getGearValue(gear,"tag") .. "\")") 1744 end 1745 1746 table.insert(previewDataList, " PreviewPlacedGear(" .. GetX(gear) ..", " .. GetY(gear) .. ")") 1747 specialFlag = 8 1748 1749 elseif GetGearType(gear) == gtExplosives then 1750 1751 temp = " tempG = AddGear(" .. 1752 GetX(gear) .. ", " .. 1753 GetY(gear) .. ", gtExplosives, 0, 0, 0, 0)" 1754 table.insert(explosivesList, temp) 1755 table.insert(explosivesList, " SetHealth(tempG, " .. GetHealth(gear) .. ")") 1756 if (getGearValue(gear, "tag") ~= nil) then 1757 table.insert(explosivesList, " setGearValue(tempG, \"tag\", \"" .. getGearValue(gear,"tag") .. "\")") 1758 end 1759 1760 table.insert(previewDataList, " PreviewPlacedGear(" .. GetX(gear) ..", " .. GetY(gear) .. ")") 1761 1762 if GetHealth(gear) == 1 then specialFlag = 15 1763 elseif GetHealth(gear) == 25 then specialFlag = 16 1764 elseif GetHealth(gear) == 50 then specialFlag = 17 1765 elseif GetHealth(gear) == 75 then specialFlag = 18 1766 elseif GetHealth(gear) == 100 then specialFlag = 19 1767 end 1768 1769 elseif GetGearType(gear) == gtTarget then 1770 1771 arrayList = targetList 1772 temp = " tempG = AddGear(" .. 1773 GetX(gear) .. ", " .. 1774 GetY(gear) .. ", gtTarget, 0, 0, 0, 0)" 1775 table.insert(targetList, temp) 1776 specialFlag = 14 1777 1778 elseif GetGearType(gear) == gtKnife then 1779 1780 arrayList = knifeList 1781 temp = " tempG = AddGear(" .. 1782 GetX(gear) .. ", " .. 1783 GetY(gear) .. ", gtKnife, 0, 0, 0, 0)" 1784 table.insert(knifeList, temp) 1785 specialFlag = 13 1786 1787 elseif GetGearType(gear) == gtCase then 1788 1789 table.insert(previewDataList, " PreviewPlacedGear(" .. GetX(gear) ..", " .. GetY(gear) .. ")") 1790 1791 -- Health crate 1792 if band(GetGearPos(gear), 0x2) ~= 0 then 1793 1794 temp = " tempG = SpawnHealthCrate(" .. 1795 GetX(gear) ..", " .. 1796 GetY(gear) ..", " .. 1797 GetHealth(gear) .. ")" 1798 table.insert(healthCrateList, temp) 1799 if (getGearValue(gear, "tag") ~= nil) then 1800 table.insert(healthCrateList, " setGearValue(tempG, \"tag\", \"" .. getGearValue(gear,"tag") .. "\")") 1801 end 1802 1803 if GetHealth(gear) == 25 then specialFlag = 9 1804 elseif GetHealth(gear) == 50 then specialFlag = 10 1805 elseif GetHealth(gear) == 75 then specialFlag = 11 1806 elseif GetHealth(gear) == 100 then specialFlag = 12 1807 end 1808 1809 -- Ammo crate 1810 elseif band(GetGearPos(gear), 0x1) ~= 0 then 1811 1812 arrayList = wepCrateList 1813 temp = " tempG = SpawnAmmoCrate(" .. 1814 GetX(gear) ..", " .. 1815 GetY(gear) ..", " .. 1816 getGearValue(gear,"contents") .. 1817 ")" 1818 table.insert(wepCrateList, temp) 1819 1820 tempV = getGearValue(gear,"contents") 1821 for i = 1, #atkArray do 1822 if tempV == atkArray[i][2] then 1823 specialFlag = i + 19 1824 end 1825 end 1826 1827 --dammit, we probably need more entries if we want to allow editing of existing maps 1828 table.insert(wepCrateList, " setGearValue(tempG, \"contents\", \"" .. getGearValue(gear,"contents") .. "\")") 1829 1830 -- Utility crate 1831 elseif band(GetGearPos(gear), 0x4) ~= 0 then 1832 1833 arrayList = utilCrateList 1834 temp = " tempG = SpawnUtilityCrate(" .. 1835 GetX(gear) ..", " .. 1836 GetY(gear) ..", " .. 1837 getGearValue(gear,"contents") .. 1838 ")" 1839 table.insert(utilCrateList, temp) 1840 1841 tempV = getGearValue(gear,"contents") 1842 for i = 1, #utilArray do 1843 if tempV == utilArray[i][2] then 1844 specialFlag = i + 19 + #atkArray 1845 end 1846 end 1847 1848 --dammit, we probably need more entries if we want to allow editing of existing maps 1849 table.insert(utilCrateList, " setGearValue(tempG, \"contents\", \"" .. getGearValue(gear,"contents") .. "\")") 1850 1851 end 1852 1853 end 1854 1855 -- add tracking of simple win/lose for simpler gears that have a tempG = listed above 1856 if (getGearValue(gear, "tag") ~= nil) and (arrayList ~= nil) then 1857 table.insert(arrayList, " setGearValue(tempG, \"tag\", \"" .. getGearValue(gear,"tag") .. "\")") 1858 end 1859 1860 -- this creates a big, messy list of special flags for use in hwmaps 1861 if specialFlag ~= nil then 1862 table.insert(hFlagList, " " .. GetX(gear) .. " " .. GetY(gear) .. " " .. specialFlag) 1863 end 1864 1865end 1866 1867-- generate a title and list all the gears if there is at least 1 of them in the list 1868function AppendGearList(gearList, consoleLine) 1869 if #gearList > 0 then 1870 WriteLnToConsole(consoleLine) 1871 for i = 1, #gearList do 1872 WriteLnToConsole(gearList[i]) 1873 end 1874 WriteLnToConsole("") 1875 end 1876end 1877 1878-- new attempt at doing shit a bit cleaner: 1879-- it may be a bit verbose, but this should generate a comprehensive, human-readable 1880-- list of gears, broken up into sections and output it to the console 1881function SaveGearData() 1882 1883 runOnGears(GetDataForGearSaving) 1884 1885 AppendGearList(healthCrateList, " ------ HEALTH CRATE LIST ------") 1886 AppendGearList(wepCrateList, " ------ AMMO CRATE LIST ------") 1887 AppendGearList(utilCrateList, " ------ UTILITY CRATE LIST ------") 1888 AppendGearList(explosivesList, " ------ BARREL LIST ------") 1889 AppendGearList(mineList, " ------ MINE LIST ------") 1890 AppendGearList(sMineList, " ------ STICKY MINE LIST ------") 1891 AppendGearList(airMineList, " ------ AIR MINE LIST ------") 1892 AppendGearList(targetList, " ------ TARGET LIST ------") 1893 AppendGearList(knifeList, " ------ CLEAVER LIST ------") 1894 1895end 1896 1897function DoAmmoLoop(i) 1898 1899 for x = 1, #atkArray do 1900 if getGearValue(hhs[i],atkArray[x][1]) ~= 0 then 1901 WriteLnToConsole(" AddAmmo(hhs[" .. i .. "], " .. atkArray[x][2] .. ", " .. getGearValue(hhs[i],atkArray[x][1]) .. ")") 1902 end 1903 end 1904 1905 for x = 1, #utilArray do 1906 if getGearValue(hhs[i],utilArray[x][1]) ~= 0 then 1907 WriteLnToConsole(" AddAmmo(hhs[" .. i .. "], " .. utilArray[x][2] .. ", " .. getGearValue(hhs[i],utilArray[x][1]) .. ")") 1908 end 1909 end 1910 1911 WriteLnToConsole("") 1912 1913end 1914 1915-- this is called when a tagged gear is deleted during a mission 1916-- it determines if the game is ready to conclude in victory/defeat 1917function CheckForConclusion(gear) 1918 1919 -- failure gears must always all be protected, so if any of them are destroyed the player loses 1920 if getGearValue(gear,"tag") == "failure" then 1921 EndGameIn("failure") 1922 else 1923 1924 -- the presence of other tagged gears means that the goal of this mission is not 1925 -- simply to kill every hedgehog. Thus, we need to count the remaining tagged objects 1926 -- to see how close we are to completing the mission successfully. 1927 victoryObj = 0 1928 failObj = 0 1929 collectObj = 0 1930 runOnGears(CheckForConditions) 1931 1932 if GetGearType(gear) ~= gtCase then 1933 1934 -- non-crates can only be tagged as victory or failure, and as this wasn't tagged 1935 -- "failure" in our earlier check, this must be a victory tagged gear. Let's adust 1936 -- the number of objects accordingly as it's in the process of being destroyed. 1937 victoryObj = victoryObj - 1 1938 1939 -- if there are no objectives left to complete, end the game in victory 1940 if (victoryObj == 0) and (collectObj == 0) then 1941 EndGameIn("victory") 1942 end 1943 1944 else 1945 -- this crate was deleted, but was it collected or destroyed, and how does that match 1946 -- the goals of our mission? 1947 if (GetGearMessage(gear) == 256) and (getGearValue(gear,"tag") == "collection") then 1948 if GetHogLevel(CurrentHedgehog) == 0 then 1949 -- the enemy stole our crate 1950 EndGameIn("failure") 1951 else 1952 collectObj = collectObj - 1 1953 if (victoryObj == 0) and (collectObj == 0) then 1954 EndGameIn("victory") 1955 end 1956 end 1957 elseif (GetGearMessage(gear) == 0) and (getGearValue(gear,"tag") == "victory") then 1958 victoryObj = victoryObj - 1 1959 if (victoryObj == 0) and (collectObj == 0) then 1960 EndGameIn("victory") 1961 end 1962 else 1963 -- unfortunately, we messed up our mission. 1964 EndGameIn("failure") 1965 end 1966 1967 end 1968 1969 end 1970 1971end 1972 1973--------------------------------- 1974-- THE BIG ONE 1975--------------------------------- 1976-- saving process starts here 1977-- saves all level data to logs/game0.log and generates a simple script template 1978function SaveLevelData() 1979 1980 waypointList = {} 1981 girderList = {} 1982 rubberList = {} 1983 spriteList = {} 1984 mineList = {} 1985 sMineList = {} 1986 airMineList = {} 1987 targetList = {} 1988 knifeList = {} 1989 explosivesList = {} 1990 healthCrateList = {} 1991 wepCrateList = {} 1992 utilCrateList = {} 1993 hFlagList = {} 1994 previewDataList = {} 1995 shoppaPointList = {} 1996 hogDataList = {} 1997 AIHogDataList = {} 1998 1999 WriteLnToConsole("------ BEGIN SCRIPT ------") 2000 WriteLnToConsole("-- Copy and Paste this text into an empty text file, and save it as") 2001 WriteLnToConsole("-- YOURTITLEHERE.lua, in your Data/Missions/Training/ folder.") 2002 2003 WriteLnToConsole("") 2004 2005 WriteLnToConsole("HedgewarsScriptLoad(\"/Scripts/Locale.lua\")") 2006 WriteLnToConsole("HedgewarsScriptLoad(\"/Scripts/Tracker.lua\")") 2007 WriteLnToConsole("HedgewarsScriptLoad(\"/Scripts/Utils.lua\")") 2008 2009 WriteLnToConsole("") 2010 WriteLnToConsole("local hhs = {}") 2011 WriteLnToConsole("") 2012 2013 SaveConfigData() 2014 2015 2016 WriteLnToConsole("") 2017 WriteLnToConsole("function LoadHogWeapons()") 2018 WriteLnToConsole("") 2019 2020 if band(GameFlags, gfPerHogAmmo) ~= 0 then -- per hog ammo 2021 for i = 1, #hhs do 2022 DoAmmoLoop(i) 2023 end 2024 2025 else -- team-based ammo 2026 2027 teamCounter = 0 2028 lastRecordedTeam = "" 2029 for i = 1, #hhs do 2030 2031 if GetHogTeamName(hhs[i]) ~= lastRecordedTeam then 2032 lastRecordedTeam = GetHogTeamName(hhs[i]) 2033 teamCounter = teamCounter + 1 2034 if teamCounter == 9 then 2035 teamCounter = 1 2036 end 2037 DoAmmoLoop(i) 2038 end 2039 2040 end 2041 2042 end 2043 2044 2045 WriteLnToConsole("end") 2046 WriteLnToConsole("") 2047 2048 WriteLnToConsole("") 2049 WriteLnToConsole("function LoadSprite(pX, pY, pSprite, pFrame, pTint, p1, p2, p3, pLandFlags)") 2050 WriteLnToConsole(" PlaceSprite(pX, pY, pSprite, pFrame, pTint, p1, p2, p3, pLandFlags)") 2051 WriteLnToConsole("end") 2052 WriteLnToConsole("") 2053 2054 WriteLnToConsole("") 2055 WriteLnToConsole("function LoadGearData()") 2056 WriteLnToConsole("") 2057 2058 WriteLnToConsole(" --BEGIN CORE DATA--") 2059 WriteLnToConsole("") 2060 2061 WriteLnToConsole(" ------ PORTAL DISTANCE and UFO FUEL ------") 2062 WriteLnToConsole(" ufoFuel = " .. ufoFuel) 2063 WriteLnToConsole(" portalDistance = " .. portalDistance*5) 2064 table.insert(hFlagList, " " .. portalDistance*5 .. " " .. ufoFuel .. " " .. 98) 2065 WriteLnToConsole("") 2066 2067 for i = 0, (placedCount-1) do 2068 if placedType[i] == loc("Waypoint Editing Mode") then 2069 --[[ TODO/FIXME: Somehow incorporate the waypoints in an actual useful manner. 2070 The functions AddWayPoint and PreviewWayPoint do not exist and will thus be commented-out 2071 in the output code. They are added anyway so the user sees the coordinates 2072 ]] 2073 table.insert(waypointList, 2074 "-- AddWayPoint(" .. 2075 placedX[i] ..", " .. 2076 placedY[i] ..")" 2077 ) 2078 table.insert(hFlagList, " " .. placedX[i] .. " " .. placedY[i] .. " " .. "0") 2079 table.insert(previewDataList, "-- PreviewWayPoint(" .. placedX[i] ..", " .. placedY[i] .. ")") 2080 end 2081 end 2082 2083 -- Helper table to convert tint color value to printable string 2084 local tint2String = { 2085 [U_LAND_TINT_INDESTRUCTIBLE] = "U_LAND_TINT_INDESTRUCTIBLE", 2086 [U_LAND_TINT_ICE] = "U_LAND_TINT_ICE", 2087 [U_LAND_TINT_BOUNCY] = "U_LAND_TINT_BOUNCY", 2088 [U_LAND_TINT_NORMAL] = "U_LAND_TINT_NORMAL", 2089 } 2090 for i = 0, (placedCount-1) do 2091 if placedType[i] == loc("Girder Placement Mode") then 2092 table.insert(girderList, 2093 " LoadSprite(" .. 2094 placedX[i] ..", " .. 2095 placedY[i] ..", sprAmGirder, " .. 2096 placedFrame[i] .. -- the rotation/frame 2097 ", " .. 2098 tint2String[placedTint[i]] ..", " .. -- color 2099 "nil, nil, nil, " .. 2100 placedLandFlags[i] .. ")" --the landType 2101 ) 2102 table.insert(hFlagList, " " .. placedX[i] .. " " .. placedY[i] .. " " .. placedHWMapFlag[i]) 2103 table.insert(previewDataList, " PreviewGirder(" .. placedX[i] ..", " .. placedY[i] .. ", " .. placedFrame[i] .. ")") 2104 end 2105 end 2106 2107 for i = 0, (placedCount-1) do 2108 if placedType[i] == loc("Rubber Placement Mode") then 2109 table.insert(rubberList, 2110 " LoadSprite(" .. 2111 placedX[i] ..", " .. 2112 placedY[i] ..", sprAmRubber, " .. 2113 placedFrame[i] .. 2114 ", " .. 2115 tint2String[placedTint[i]] ..", " .. -- color 2116 "nil, nil, nil, " .. 2117 "lfBouncy)" --the landType 2118 ) 2119 table.insert(hFlagList, " " .. placedX[i] .. " " .. placedY[i] .. " " .. placedHWMapFlag[i]) 2120 table.insert(previewDataList, " PreviewRubber(" .. placedX[i] ..", " .. placedY[i] .. ", " .. placedFrame[i] .. ")") 2121 end 2122 end 2123 2124 for i = 0, (placedCount-1) do 2125 if placedType[i] == loc("Sprite Placement Mode") then 2126 table.insert(spriteList, 2127 " LoadSprite(" .. 2128 placedX[i] ..", " .. 2129 placedY[i] ..", " .. placedSprite[i] .. ", " .. 2130 placedFrame[i] .. -- I think this is the frame, can't remember 2131 ", " .. 2132 tint2String[placedTint[i]] ..", " .. -- color 2133 "nil, nil, nil, " .. 2134 placedLandFlags[i] .. ")" --the landType 2135 ) 2136 end 2137 end 2138 2139 AppendGearList(waypointList, " ------ WAYPOINT LIST ------") 2140 AppendGearList(girderList, " ------ GIRDER LIST ------") 2141 AppendGearList(rubberList, " ------ RUBBER LIST ------") 2142 AppendGearList(spriteList, " ------ SPRITE LIST ------") 2143 2144 SaveGearData() 2145 2146 WriteLnToConsole(" --END CORE DATA--") 2147 2148 2149 WriteLnToConsole("") 2150 WriteLnToConsole(" LoadHogWeapons()") 2151 WriteLnToConsole("") 2152 WriteLnToConsole("end") 2153 WriteLnToConsole("") 2154 2155 WriteLnToConsole("") 2156 WriteLnToConsole("function onGameStart()") 2157 WriteLnToConsole("") 2158 WriteLnToConsole(" LoadGearData()") 2159 WriteLnToConsole(" DetermineMissionGoal()") 2160 WriteLnToConsole("") 2161 WriteLnToConsole("end") 2162 WriteLnToConsole("") 2163 2164 WriteLnToConsole("") 2165 WriteLnToConsole("function onNewTurn()") 2166 WriteLnToConsole(" --insert code according to taste") 2167 WriteLnToConsole("end") 2168 WriteLnToConsole("") 2169 2170 WriteLnToConsole("") 2171 WriteLnToConsole("function onGameTick()") 2172 WriteLnToConsole(" runOnGears(UpdateTagCircles)") 2173 WriteLnToConsole("end") 2174 WriteLnToConsole("") 2175 2176 WriteLnToConsole("function UpdateTagCircles(gear)") 2177 WriteLnToConsole(" if getGearValue(gear,\"tag\") ~= nil then") 2178 WriteLnToConsole(" if getGearValue(gear,\"tCirc\") == nil then") 2179 WriteLnToConsole(" setGearValue(gear, \"tCirc\",AddVisualGear(0,0,vgtCircle,0,true))") 2180 WriteLnToConsole(" end") 2181 WriteLnToConsole("") 2182 WriteLnToConsole(" if getGearValue(gear,\"tag\") == \"victory\" then") 2183 WriteLnToConsole(" SetVisualGearValues(getGearValue(gear,\"tCirc\"), GetX(gear), GetY(gear), 100, 255, 1, 10, 0, 150, 3, 0xff0000ff)") 2184 WriteLnToConsole(" elseif getGearValue(gear,\"tag\") == \"failure\" then") 2185 WriteLnToConsole(" SetVisualGearValues(getGearValue(gear,\"tCirc\"), GetX(gear), GetY(gear), 100, 255, 1, 10, 0, 150, 3, 0x00ff00ff)") 2186 WriteLnToConsole(" elseif getGearValue(gear,\"tag\") == \"collection\" then") 2187 WriteLnToConsole(" SetVisualGearValues(getGearValue(gear,\"tCirc\"), GetX(gear), GetY(gear), 100, 255, 1, 10, 0, 150, 3, 0x0000ffff)") 2188 WriteLnToConsole(" end") 2189 WriteLnToConsole(" end") 2190 WriteLnToConsole("end") 2191 WriteLnToConsole("") 2192 2193 WriteLnToConsole("function CheckForConditions(gear)") 2194 WriteLnToConsole(" if getGearValue(gear,\"tag\") == \"victory\" then") 2195 WriteLnToConsole(" victoryObj = victoryObj +1") 2196 WriteLnToConsole(" elseif getGearValue(gear,\"tag\") == \"failure\" then") 2197 WriteLnToConsole(" failObj = failObj +1") 2198 WriteLnToConsole(" elseif getGearValue(gear,\"tag\") == \"collection\" then") 2199 WriteLnToConsole(" collectObj = collectObj +1") 2200 WriteLnToConsole(" end") 2201 WriteLnToConsole("end") 2202 WriteLnToConsole("") 2203 2204 WriteLnToConsole("function CheckForConclusion(gear)") 2205 WriteLnToConsole("") 2206 WriteLnToConsole(" if getGearValue(gear,\"tag\") == \"failure\" then ") 2207 WriteLnToConsole(" EndGameIn(\"failure\")") 2208 WriteLnToConsole(" else ") 2209 WriteLnToConsole("") 2210 WriteLnToConsole(" victoryObj = 0") 2211 WriteLnToConsole(" failObj = 0") 2212 WriteLnToConsole(" collectObj = 0") 2213 WriteLnToConsole(" runOnGears(CheckForConditions)") 2214 WriteLnToConsole("") 2215 WriteLnToConsole(" if GetGearType(gear) ~= gtCase then") 2216 WriteLnToConsole("") 2217 WriteLnToConsole(" victoryObj = victoryObj - 1 ") 2218 WriteLnToConsole("") 2219 WriteLnToConsole(" if (victoryObj == 0) and (collectObj == 0) then") 2220 WriteLnToConsole(" EndGameIn(\"victory\")") 2221 WriteLnToConsole(" end") 2222 WriteLnToConsole("") 2223 WriteLnToConsole(" else") 2224 WriteLnToConsole("") 2225 WriteLnToConsole(" if (GetGearMessage(gear) == 256) and (getGearValue(gear,\"tag\") == \"collection\") then ") 2226 WriteLnToConsole(" if GetHogLevel(CurrentHedgehog) ~= 0 then") 2227 WriteLnToConsole(" EndGameIn(\"failure\")") 2228 WriteLnToConsole(" else") 2229 WriteLnToConsole(" collectObj = collectObj - 1") 2230 WriteLnToConsole(" if (victoryObj == 0) and (collectObj == 0) then") 2231 WriteLnToConsole(" EndGameIn(\"victory\")") 2232 WriteLnToConsole(" end") 2233 WriteLnToConsole(" end") 2234 WriteLnToConsole(" elseif (GetGearMessage(gear) == 0) and (getGearValue(gear,\"tag\") == \"victory\") then") 2235 WriteLnToConsole(" victoryObj = victoryObj - 1") 2236 WriteLnToConsole(" if (victoryObj == 0) and (collectObj == 0) then ") 2237 WriteLnToConsole(" EndGameIn(\"victory\")") 2238 WriteLnToConsole(" end") 2239 WriteLnToConsole(" else") 2240 WriteLnToConsole(" EndGameIn(\"failure\")") 2241 WriteLnToConsole(" end") 2242 WriteLnToConsole("") 2243 WriteLnToConsole(" end") 2244 WriteLnToConsole("") 2245 WriteLnToConsole(" end") 2246 WriteLnToConsole("") 2247 WriteLnToConsole("end") 2248 WriteLnToConsole("") 2249 2250 WriteLnToConsole("function DetermineMissionGoal()") 2251 WriteLnToConsole("") 2252 WriteLnToConsole(" victoryObj = 0") 2253 WriteLnToConsole(" failObj = 0") 2254 WriteLnToConsole(" collectObj = 0") 2255 WriteLnToConsole(" vComment = \"\"") 2256 WriteLnToConsole(" fComment = \"\"") 2257 WriteLnToConsole(" collectComment = \"\"") 2258 WriteLnToConsole("") 2259 WriteLnToConsole(" runOnGears(CheckForConditions)") 2260 WriteLnToConsole("") 2261 WriteLnToConsole(" if victoryObj > 0 then ") 2262 WriteLnToConsole(" if victoryObj == 1 then ") 2263 WriteLnToConsole([[ vComment = loc("- Destroy the red target") .. "|"]]) 2264 WriteLnToConsole(" else ") 2265 WriteLnToConsole([[ vComment = loc("- Destroy the red targets") .. "|"]]) 2266 WriteLnToConsole(" end") 2267 WriteLnToConsole(" end") 2268 WriteLnToConsole("") 2269 WriteLnToConsole(" if collectObj > 0 then ") 2270 WriteLnToConsole(" if collectObj == 1 then ") 2271 WriteLnToConsole([[ collectComment = loc("- Collect the blue crate") .. "|"]]) 2272 WriteLnToConsole(" else ") 2273 WriteLnToConsole([[ collectComment = loc("- Collect all the blue crates") .. "|"]]) 2274 WriteLnToConsole(" end") 2275 WriteLnToConsole(" end") 2276 WriteLnToConsole("") 2277 WriteLnToConsole(" if (collectObj == 0) and (victoryObj == 0) then") 2278 WriteLnToConsole([[ vComment = loc("- Destroy the enemy") .. "|"]]) 2279 WriteLnToConsole(" end") 2280 WriteLnToConsole("") 2281 WriteLnToConsole(" if failObj > 0 then ") 2282 WriteLnToConsole(" if failObj == 1 then ") 2283 WriteLnToConsole([[ fComment = loc("- The green target must survive") .. "|"]]) 2284 WriteLnToConsole(" else ") 2285 WriteLnToConsole([[ fComment = loc("- The green targets must survive") .. "|"]]) 2286 WriteLnToConsole(" end") 2287 WriteLnToConsole(" end") 2288 WriteLnToConsole("") 2289 WriteLnToConsole([[ ShowMission(loc("User Mission"), loc("Mission"), collectComment .. vComment .. fComment, 1, 0)]]) 2290 WriteLnToConsole("") 2291 WriteLnToConsole("end") 2292 2293 WriteLnToConsole("") 2294 WriteLnToConsole("function isATrackedGear(gear)") 2295 WriteLnToConsole(" if (GetGearType(gear) == gtHedgehog) or") 2296 WriteLnToConsole(" (GetGearType(gear) == gtExplosives) or") 2297 WriteLnToConsole(" (GetGearType(gear) == gtMine) or") 2298 WriteLnToConsole(" (GetGearType(gear) == gtSMine) or") 2299 WriteLnToConsole(" (GetGearType(gear) == gtAirMine) or") 2300 WriteLnToConsole(" (GetGearType(gear) == gtTarget) or") 2301 WriteLnToConsole(" (GetGearType(gear) == gtKnife) or") 2302 WriteLnToConsole(" (GetGearType(gear) == gtPortal) or") 2303 WriteLnToConsole(" (GetGearType(gear) == gtCase)") 2304 WriteLnToConsole(" then") 2305 WriteLnToConsole(" return(true)") 2306 WriteLnToConsole(" else") 2307 WriteLnToConsole(" return(false)") 2308 WriteLnToConsole(" end") 2309 WriteLnToConsole("end") 2310 WriteLnToConsole("") 2311 2312 WriteLnToConsole("") 2313 WriteLnToConsole("function onGearAdd(gear)") 2314 2315 2316 WriteLnToConsole(" if isATrackedGear(gear) then") 2317 WriteLnToConsole(" trackGear(gear)") 2318 2319 WriteLnToConsole(" end") 2320 WriteLnToConsole("end") 2321 WriteLnToConsole("") 2322 2323 WriteLnToConsole("") 2324 WriteLnToConsole("function EndGameIn(c)") 2325 WriteLnToConsole("") 2326 WriteLnToConsole(" teamCounter = 0") 2327 WriteLnToConsole(" lastRecordedTeam = \"\" ") 2328 WriteLnToConsole(" for i = 1, #hhs do") 2329 WriteLnToConsole("") 2330 WriteLnToConsole(" if GetHogTeamName(hhs[i]) ~= lastRecordedTeam then --er, is this okay without nill checks?") 2331 WriteLnToConsole("") 2332 WriteLnToConsole(" lastRecordedTeam = GetHogTeamName(hhs[i])") 2333 WriteLnToConsole(" teamCounter = teamCounter + 1") 2334 WriteLnToConsole(" if teamCounter == 9 then") 2335 WriteLnToConsole(" teamCounter = 1") 2336 WriteLnToConsole(" end") 2337 WriteLnToConsole("") 2338 WriteLnToConsole(" if (c == \"victory\") and (GetHogLevel(hhs[i]) ~= 0) then") 2339 WriteLnToConsole(" DismissTeam(GetHogTeamName(hhs[i]))") 2340 WriteLnToConsole([[ AddCaption(loc("Victory!"), capcolDefault, capgrpGameState)]]) 2341 WriteLnToConsole([[ ShowMission(loc("User Mission"), loc("Mission"), loc("Mission succeeded!"), 0, 0)]]) 2342 WriteLnToConsole(" elseif (c == \"failure\") and (GetHogLevel(hhs[i]) == 0) then") 2343 WriteLnToConsole(" DismissTeam(GetHogTeamName(hhs[i]))") 2344 WriteLnToConsole([[ AddCaption(loc("Defeat!"), capcolDefault, capgrpGameState)]]) 2345 WriteLnToConsole([[ ShowMission(loc("User Mission"), loc("Mission"), loc("Mission failed!"), -amSkip, 0)]]) 2346 WriteLnToConsole(" elseif (c == \"victory\") and (GetHogLevel(hhs[i]) == 0) then") 2347 WriteLnToConsole(" PlaySound(sndVictory,hhs[i]) -- check if we actually need this") 2348 WriteLnToConsole(" end") 2349 WriteLnToConsole("") 2350 WriteLnToConsole(" end") 2351 WriteLnToConsole("") 2352 WriteLnToConsole(" end") 2353 WriteLnToConsole("") 2354 WriteLnToConsole("end") 2355 WriteLnToConsole("") 2356 2357 WriteLnToConsole("") 2358 WriteLnToConsole("function onGearDelete(gear)") 2359 WriteLnToConsole("") 2360 WriteLnToConsole(" --insert code according to taste") 2361 WriteLnToConsole("") 2362 WriteLnToConsole(" if isATrackedGear(gear) then") 2363 WriteLnToConsole("") 2364 WriteLnToConsole(" if getGearValue(gear,\"tag\") ~= nil then") 2365 WriteLnToConsole(" CheckForConclusion(gear)") 2366 WriteLnToConsole(" end") 2367 2368 WriteLnToConsole("") 2369 WriteLnToConsole(" if getGearValue(gear, \"tCirc\") ~= nil then") 2370 WriteLnToConsole(" DeleteVisualGear(getGearValue(gear, \"tCirc\"))") 2371 WriteLnToConsole(" end") 2372 WriteLnToConsole("") 2373 WriteLnToConsole(" trackDeletion(gear)") 2374 WriteLnToConsole("") 2375 WriteLnToConsole(" end") 2376 WriteLnToConsole("") 2377 WriteLnToConsole("end") 2378 WriteLnToConsole("") 2379 2380 WriteLnToConsole("") 2381 WriteLnToConsole("--enable and/or alter code according to taste") 2382 WriteLnToConsole("function onAmmoStoreInit()") 2383 WriteLnToConsole("") 2384 2385 WriteLnToConsole(" for i = 0, AmmoTypeMax do") 2386 WriteLnToConsole(" if i ~= amNothing then") 2387 WriteLnToConsole(" SetAmmo(i, 0, 0, 0, 1)") 2388 WriteLnToConsole(" end") 2389 WriteLnToConsole(" end") 2390 WriteLnToConsole("") 2391 WriteLnToConsole(" SetAmmo(amSkip, 9, 0, 0, 0)") 2392 WriteLnToConsole("") 2393 WriteLnToConsole("end") 2394 WriteLnToConsole("") 2395 2396 WriteLnToConsole("------ END GENERATED MISSION ------") 2397 2398 -- at this point, generation for the missions/training output is intended to stop 2399 2400 WriteLnToConsole("") 2401 WriteLnToConsole("function GeneratePreviewData()") 2402 WriteLnToConsole("") 2403 for i = 1, #previewDataList do 2404 WriteLnToConsole(previewDataList[i]) 2405 end 2406 WriteLnToConsole("") 2407 WriteLnToConsole("end") 2408 WriteLnToConsole("") 2409 2410 ConvertGearDataToHWPText() 2411 2412 WriteLnToConsole("------ END GENERATED SCRIPT ------") 2413 2414 AddCaption(loc("Level Data Saved!"), colorInfoMessage, capgrpGameState) 2415 2416end 2417 2418---------------------------------- 2419-- some special effects handling 2420---------------------------------- 2421function SmokePuff(x,y,c) 2422 tempE = AddVisualGear(x, y, vgtSmoke, 0, false) 2423 SetVisualGearValues(tempE, nil, nil, nil, nil, nil, nil, nil, 1, nil, c ) 2424end 2425 2426function HandleGearBasedRankingEffects(gear) 2427 if getGearValue(gear, "ranking") ~= nil then 2428 SmokePuff(GetX(gear), GetY(gear),GetRankedColour(getGearValue(gear, "ranking"))) 2429 end 2430end 2431 2432function HandleRankingEffects() 2433 for i = 1, #shoppaPX do 2434 SmokePuff(shoppaPX[i], shoppaPY[i], GetRankedColour(shoppaPR[i])) 2435 end 2436 runOnHogs(HandleGearBasedRankingEffects) 2437end 2438 2439function UpdateTagCircles(gear) 2440 2441 if getGearValue(gear,"tag") ~= nil then 2442 2443 if cat[cIndex] == loc("Goal Definition Mode") then 2444 2445 -- generate circs for tagged gears that don't have a circ yet (new) 2446 if getGearValue(gear,"tCirc") == nil then 2447 setGearValue(gear, "tCirc",AddVisualGear(0,0,vgtCircle,0,true)) 2448 end 2449 2450 if getGearValue(gear,"tag") == "victory" then 2451 SetVisualGearValues(getGearValue(gear,"tCirc"), GetX(gear), GetY(gear), 100, 255, 1, 10, 0, 150, 3, 0xff0000ff) 2452 elseif getGearValue(gear,"tag") == "failure" then 2453 SetVisualGearValues(getGearValue(gear,"tCirc"), GetX(gear), GetY(gear), 100, 255, 1, 10, 0, 150, 3, 0x00ff00ff) 2454 elseif getGearValue(gear,"tag") == "collection" then 2455 SetVisualGearValues(getGearValue(gear,"tCirc"), GetX(gear), GetY(gear), 100, 255, 1, 10, 0, 150, 3, 0x0000ffff) 2456 end 2457 2458 else 2459 SetVisualGearValues(getGearValue(gear,"tCirc"), GetX(gear), GetY(gear), 0, 1, 1, 10, 0, 1, 1, 0x00000000) 2460 end 2461 2462 end 2463 2464end 2465 2466-- handle short range portal gun 2467function PortalEffects(gear) 2468 2469 if GetGearType(gear) == gtPortal then 2470 2471 local tag = GetTag(gear) 2472 local col 2473 if tag == 0 then 2474 col = 0xfab02aFF -- orange ball 2475 elseif tag == 1 then 2476 col = 0x00FF00FF -- orange portal 2477 elseif tag == 2 then 2478 col = 0x364df7FF -- blue ball 2479 elseif tag == 3 then 2480 col = 0xFFFF00FF -- blue portal 2481 end 2482 2483 if (tag == 0) or (tag == 2) then -- i.e ball form 2484 local remLife = getGearValue(gear,"life") 2485 remLife = remLife - 1 2486 setGearValue(gear, "life", remLife) 2487 2488 -- Destroy portal ball when max. distance reached 2489 if remLife == 0 then 2490 2491 local tempE = AddVisualGear(GetX(gear)+15, GetY(gear), vgtSmoke, 0, false) 2492 SetVisualGearValues(tempE, nil, nil, nil, nil, nil, nil, nil, nil, nil, col) 2493 2494 tempE = AddVisualGear(GetX(gear)-15, GetY(gear), vgtSmoke, 0, false) 2495 SetVisualGearValues(tempE, nil, nil, nil, nil, nil, nil, nil, nil, nil, col) 2496 2497 tempE = AddVisualGear(GetX(gear), GetY(gear)+15, vgtSmoke, 0, false) 2498 SetVisualGearValues(tempE, nil, nil, nil, nil, nil, nil, nil, nil, nil, col) 2499 2500 tempE = AddVisualGear(GetX(gear), GetY(gear)-15, vgtSmoke, 0, false) 2501 SetVisualGearValues(tempE, nil, nil, nil, nil, nil, nil, nil, nil, nil, col) 2502 2503 PlaySound(sndVaporize) 2504 DeleteGear(gear) 2505 2506 end 2507 2508 end 2509 2510 end 2511 2512end 2513 2514function updateHelp(curAmmoType) 2515 if curAmmoType == nil then 2516 curAmmoType = GetCurAmmoType() 2517 end 2518 2519 if (curAmmoType ~= amGirder) and (curAmmoType ~= amRubber) and (curAmmoType ~= amCMGearPlacementTool) then 2520 2521 if not hedgeEditorMissionPanelShown then 2522 showHedgeEditorMissionPanel() 2523 end 2524 2525 elseif cat[cIndex] == loc("Girder Placement Mode") then 2526 2527 ShowMission ( 2528 loc("GIRDER PLACEMENT MODE"), 2529 loc("Place girders"), 2530 loc("Place Girder: [Left Click]") .. "|" .. 2531 loc("Change Rotation: [Left], [Right]") .. "|" .. 2532 " " .. "|" .. 2533 loc("Normal Girder: [1]") .. "|" .. 2534 loc("Indestructible Girder: [2]") .. "|" .. 2535 loc("Icy Girder: [3]") .. "|" .. 2536 loc("Bouncy Girder: [4]") .. "|" .. 2537 " " .. "|" .. 2538 loc("Deletion Mode: [5]") .. "|" .. 2539 " " .. "|" .. 2540 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2541 "", -amGirder, 60000, not helpDisabled 2542 ) 2543 hedgeEditorMissionPanelShown = false 2544 2545 elseif cat[cIndex] == loc("Rubber Placement Mode") then 2546 2547 ShowMission ( 2548 loc("RUBBER PLACEMENT MODE"), 2549 loc("Place rubber"), 2550 loc("Place Object: [Left Click]") .. "|" .. 2551 loc("Change Rotation: [Left], [Right]") .. "|" .. 2552 " " .. "|" .. 2553 loc("Normal Rubber: [1]") .. "|" .. 2554 " " .. "|" .. 2555 loc("Deletion Mode: [5]") .. "|" .. 2556 " " .. "|" .. 2557 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2558 "", -amRubber, 60000, not helpDisabled 2559 ) 2560 hedgeEditorMissionPanelShown = false 2561 2562 elseif cat[cIndex] == loc("Barrel Placement Mode") then 2563 2564 ShowMission ( 2565 loc("BARREL PLACEMENT MODE"), 2566 loc("Place barrels"), 2567 loc("Place Object: [Left Click]") .. "|" .. 2568 loc("Change Health: [Left], [Right]") .. "|" .. 2569 " " .. "|" .. 2570 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2571 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2572 "", 8, 60000, not helpDisabled 2573 ) 2574 hedgeEditorMissionPanelShown = false 2575 2576 elseif cat[cIndex] == loc("Cleaver Placement Mode") then 2577 2578 ShowMission ( 2579 loc("CLEAVER PLACEMENT MODE"), 2580 loc("Place cleavers"), 2581 loc("Place Object: [Left Click]") .. "|" .. 2582 " " .. "|" .. 2583 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2584 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2585 "", -amKnife, 60000, not helpDisabled 2586 ) 2587 hedgeEditorMissionPanelShown = false 2588 2589 elseif cat[cIndex] == loc("Target Placement Mode") then 2590 2591 ShowMission ( 2592 loc("TARGET PLACEMENT MODE"), 2593 loc("Place targets"), 2594 loc("Place Object: [Left Click]") .. "|" .. 2595 " " .. "|" .. 2596 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2597 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2598 "", 1, 60000, not helpDisabled 2599 ) 2600 hedgeEditorMissionPanelShown = false 2601 2602 elseif cat[cIndex] == loc("Waypoint Editing Mode") then 2603 2604 ShowMission ( 2605 loc("WAYPOINT EDITING MODE"), 2606 loc("Place or delete waypoints"), 2607 loc("Place/Delete Waypoint: [Left Click]") .. "|" .. 2608 loc("Toggle Placement/Deletion: [Left], [Right]") .. "|" .. 2609 " " .. "|" .. 2610 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2611 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2612 "", -amCMGearPlacementTool, 60000, not helpDisabled 2613 ) 2614 hedgeEditorMissionPanelShown = false 2615 2616 elseif cat[cIndex] == loc("Mine Placement Mode") then 2617 2618 ShowMission ( 2619 loc("MINE PLACEMENT MODE"), 2620 loc("Place mines"), 2621 loc("Place Object: [Left Click]") .. "|" .. 2622 loc("Change Timer: [Left], [Right]") .. "|" .. 2623 " " .. "|" .. 2624 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2625 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2626 "", -amMine, 60000, not helpDisabled 2627 ) 2628 hedgeEditorMissionPanelShown = false 2629 2630 elseif cat[cIndex] == loc("Dud Mine Placement Mode") then 2631 2632 ShowMission ( 2633 loc("DUD MINE PLACEMENT MODE"), 2634 loc("Place dud mines"), 2635 loc("Place Object: [Left Click]") .. "|" .. 2636 loc("Change Health: [Left], [Right]") .. "|" .. 2637 " " .. "|" .. 2638 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2639 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2640 "", 9, 60000, not helpDisabled 2641 ) 2642 hedgeEditorMissionPanelShown = false 2643 2644 elseif cat[cIndex] == loc("Sticky Mine Placement Mode") then 2645 2646 ShowMission ( 2647 loc("STICKY MINE PLACEMENT MODE"), 2648 loc("Place sticky mines"), 2649 loc("Place Object: [Left Click]") .. "|" .. 2650 loc("Change Timer: [Left], [Right]") .. "|" .. 2651 " " .. "|" .. 2652 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2653 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2654 "", -amSMine, 60000, not helpDisabled 2655 ) 2656 hedgeEditorMissionPanelShown = false 2657 2658 elseif cat[cIndex] == loc("Air Mine Placement Mode") then 2659 2660 ShowMission ( 2661 loc("AIR MINE PLACEMENT MODE"), 2662 loc("Place air mines"), 2663 loc("Place Object: [Left Click]") .. "|" .. 2664 loc("Change Timer: [Left], [Right]") .. "|" .. 2665 " " .. "|" .. 2666 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2667 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2668 "", -amAirMine, 60000, not helpDisabled 2669 ) 2670 hedgeEditorMissionPanelShown = false 2671 2672 elseif cat[cIndex] == loc("Weapon Crate Placement Mode") then 2673 2674 ShowMission ( 2675 loc("WEAPON CRATE PLACEMENT MODE"), 2676 loc("Place weapon crates"), 2677 loc("Place Object: [Left Click]") .. "|" .. 2678 loc("Change Content: [Left], [Right]") .. "|" .. 2679 " " .. "|" .. 2680 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2681 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2682 "", 7, 60000, not helpDisabled 2683 ) 2684 hedgeEditorMissionPanelShown = false 2685 2686 elseif cat[cIndex] == loc("Utility Crate Placement Mode") then 2687 2688 ShowMission ( 2689 loc("UTILITY CRATE PLACEMENT MODE"), 2690 loc("Place utility crates"), 2691 loc("Place Object: [Left Click]") .. "|" .. 2692 loc("Change Content: [Left], [Right]") .. "|" .. 2693 " " .. "|" .. 2694 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2695 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2696 "", 5, 60000, not helpDisabled 2697 ) 2698 hedgeEditorMissionPanelShown = false 2699 2700 elseif cat[cIndex] == loc("Health Crate Placement Mode") then 2701 2702 ShowMission ( 2703 loc("HEALTH CRATE PLACEMENT MODE"), 2704 loc("Place health crates"), 2705 loc("Place Object: [Left Click]") .. "|" .. 2706 loc("Change Health Boost: [Left], [Right]") .. "|" .. 2707 " " .. "|" .. 2708 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2709 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2710 "", 6, 60000, not helpDisabled 2711 ) 2712 hedgeEditorMissionPanelShown = false 2713 2714 elseif cat[cIndex] == loc("Repositioning Mode") then 2715 2716 ShowMission ( 2717 loc("REPOSITIONING MODE"), 2718 loc("Select, reposition and delete gears"), 2719 loc("Select/Place/Delete Gear: [Left Click]") .. "|" .. 2720 loc("Choose Selection/Placement/Deletion: [Left], [Right]") .. "|" .. 2721 " " .. "|" .. 2722 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2723 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2724 "", -amCMGearPlacementTool, 60000, not helpDisabled 2725 ) 2726 hedgeEditorMissionPanelShown = false 2727 2728 elseif cat[cIndex] == loc("Sprite Modification Mode") then 2729 2730 ShowMission ( 2731 loc("SPRITE MODIFICATION MODE"), 2732 loc("Select, modify, or delete girders, rubbers and sprites"), 2733 loc("Modify Sprite under Cursor: [Left Click]") .. "|" .. 2734 loc("Change modification mode: [Left], [Right]") .."|".. 2735 loc("While in modification mode, you can change|the LandFlag by clicking on an object.") .. "|" .. 2736 " " .. "|" .. 2737 loc("Normal Land: [1]") .. "|" .. 2738 loc("Indestructible Land: [2]") .. "|" .. 2739 loc("Icy Land: [3]") .. "|" .. 2740 loc("Bouncy Land: [4]") .. "|" .. 2741 " " .. "|" .. 2742 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2743 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2744 "", 2, 60000, not helpDisabled 2745 ) 2746 hedgeEditorMissionPanelShown = false 2747 2748 elseif cat[cIndex] == loc("Sprite Placement Mode") then 2749 2750 ShowMission ( 2751 loc("SPRITE PLACEMENT MODE"), 2752 loc("Place sprites to build land"), 2753 loc("Place Sprite: [Left Click]") .. "|" .. 2754 loc("Change Sprite: [Left], [Right]") .. "|" .. 2755 loc("Change Sprite Frame: [Precise]+[Left], [Precise]+[Right]") .. "|" .. 2756 " " .. "|" .. 2757 loc("Normal Land: [1]") .. "|" .. 2758 loc("Indestructible Land: [2]") .. "|" .. 2759 loc("Icy Land: [3]") .. "|" .. 2760 loc("Bouncy Land: [4]") .. "|" .. 2761 " " .. "|" .. 2762 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2763 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2764 "", -amCMGearPlacementTool, 60000, not helpDisabled 2765 ) 2766 hedgeEditorMissionPanelShown = false 2767 2768 elseif cat[cIndex] == loc("Goal Definition Mode") then 2769 2770 ShowMission ( 2771 loc("GOAL DEFINITION MODE"), 2772 loc("Mark gears for win/lose conditions"), 2773 loc("Mark/unmark gear: [Left Click]") .. "|" .. 2774 loc("Select win/lose condition: [Left], [Right]") .. "|" .. 2775 " " .. "|" .. 2776 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2777 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2778 "", 0, 60000, not helpDisabled 2779 ) 2780 hedgeEditorMissionPanelShown = false 2781 elseif cat[cIndex] == loc("Hog Identity Mode") then 2782 2783 ShowMission ( 2784 loc("HOG IDENTITY MODE"), 2785 loc("Give a hog a preset identity and weapons"), 2786 loc("Set Identity: [Left Click]") .. "|" .. 2787 loc("[Left], [Right]: Change between identities.") .. "|" .. 2788 " " .. "|" .. 2789 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2790 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2791 "", 3, 60000, not helpDisabled 2792 ) 2793 hedgeEditorMissionPanelShown = false 2794 2795 elseif cat[cIndex] == loc("Team Identity Mode") then 2796 2797 ShowMission ( 2798 loc("TEAM IDENTITY MODE"), 2799 loc("Give an entire team themed hats and names"), 2800 loc("Set Identity: [Left Click]") .. "|" .. 2801 loc("[Left], [Right]: Change between identities.") .. "|" .. 2802 " " .. "|" .. 2803 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2804 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2805 "", 3, 60000, not helpDisabled 2806 ) 2807 hedgeEditorMissionPanelShown = false 2808 2809 elseif cat[cIndex] == loc("Health Modification Mode") then 2810 2811 ShowMission ( 2812 loc("HEALTH MODIFICATION MODE"), 2813 loc("Set the health of hogs, health crates, barrels and duds"), 2814 loc("Set Health: [Left Click]") .. "|" .. 2815 loc("[Left], [Right]: Change health value.") .. "|" .. 2816 " " .. "|" .. 2817 loc("Change Placement Mode: [Up], [Down]") .. "|" .. 2818 loc("Toggle Help: [Precise]+[1]") .. "|" .. 2819 "", 2, 60000, not helpDisabled 2820 ) 2821 hedgeEditorMissionPanelShown = false 2822 2823 end 2824 2825 2826 if helpDisabled == true then 2827 HideMission() 2828 hedgeEditorMissionPanelShown = false 2829 end 2830 2831end 2832 2833function onSetWeapon(ammoType) 2834 curWep = ammoType 2835 updateHelp(ammoType) 2836end 2837 2838function onSlot() 2839 curWep = GetCurAmmoType() 2840 updateHelp(ammoType) 2841end 2842 2843function onScreenResize() 2844 updateCursorCoords() 2845end 2846 2847-- Display the X and Y coordinates of the cursor while the cursor is active 2848function updateCursorCoords() 2849 if band(GetState(CurrentHedgehog), gstChooseTarget) ~= 0 and CursorX ~= NO_CURSOR then 2850 local x1, y 2851 if INTERFACE == "touch" then 2852 x1, y = 126, 32 2853 else 2854 x1, y = 12, 24 2855 end 2856 if tagCursorX then 2857 DeleteVisualGear(tagCursorX) 2858 end 2859 tagCursorX = AddVisualGear(-div(ScreenWidth, 2)+x1, y, vgtHealthTag, CursorX, true) 2860 SetVisualGearValues(tagCursorX, nil, nil, 0, 0, nil, 1, nil, nil, 240000, 0xFFFFFFFF) 2861 2862 local x2 2863 if string.len(tostring(CursorX)) > 6 then 2864 x2 = x1 + 100 2865 else 2866 x2 = x1 + 60 2867 end 2868 if tagCursorY then 2869 DeleteVisualGear(tagCursorY) 2870 end 2871 tagCursorY = AddVisualGear(-div(ScreenWidth, 2)+x2, y, vgtHealthTag, CursorY, true) 2872 SetVisualGearValues(tagCursorY, nil, nil, 0, 0, nil, 1, nil, nil, 240000, 0xFFFFFFFF) 2873 else 2874 if tagCursorX then 2875 DeleteVisualGear(tagCursorX) 2876 end 2877 if tagCursorY then 2878 DeleteVisualGear(tagCursorY) 2879 end 2880 end 2881end 2882 2883-- called in onGameTick() 2884function HandleHedgeEditor() 2885 if CurrentHedgehog ~= nil then 2886 2887 genTimer = genTimer + 1 2888 2889 tSprCol = 0x00000000 2890 tempFrame = 0 2891 xDisplacement = 42 2892 yDisplacement = 42 2893 2894 if (curWep == amCMGearPlacementTool) then 2895 2896 SetSoundMask(sndIncoming, true) 2897 2898 --wowaweewa, holyeeeee shite this is badly hacked (please rewrite when less lazy/morefeatures) 2899 dCol = 0xFFFFFFFF 2900 dFrame = 0 2901 dAngle = 0 2902 if (cat[cIndex] == loc("Mine Placement Mode")) then 2903 dSprite = sprCustom2 2904 elseif (cat[cIndex] == loc("Dud Mine Placement Mode")) then 2905 dSprite = sprCustom4 2906 elseif (cat[cIndex] == loc("Sticky Mine Placement Mode")) then 2907 dSprite = sprCustom3 2908 elseif (cat[cIndex] == loc("Air Mine Placement Mode")) then 2909 dSprite = sprAirMine 2910 elseif (cat[cIndex] == loc("Barrel Placement Mode")) then 2911 dSprite = sprExplosives 2912 elseif (cat[cIndex] == loc("Health Crate Placement Mode")) then 2913 dSprite = sprFAid 2914 elseif (cat[cIndex] == loc("Weapon Crate Placement Mode")) then 2915 dSprite = sprCase 2916 elseif (cat[cIndex] == loc("Utility Crate Placement Mode")) then 2917 dSprite = sprUtility 2918 elseif (cat[cIndex] == loc("Target Placement Mode")) then 2919 dSprite = sprTarget 2920 elseif (cat[cIndex] == loc("Cleaver Placement Mode")) then 2921 dAngle = 270 2922 dSprite = sprKnife 2923 elseif (cat[cIndex] == loc("Sprite Placement Mode")) then 2924 dSprite = reducedSpriteIDArray[pIndex] 2925 dFrame = sFrame 2926 if ((dSprite == sprAMAmmos) or (dSprite == sprAMAmmosBW)) and (dFrame == (amCMGearPlacementTool - 1)) then 2927 -- Special case: Air attack icon of ammos sprite needs to be fixed (since this icon is overwritten) 2928 dFrame = ammoFrameAirAttack 2929 end 2930 else 2931 dCol = 0xFFFFFF00 2932 dSprite = sprArrow 2933 end 2934 2935 if CG == nil then 2936 CG = AddVisualGear(CursorX, CursorY, vgtStraightShot,0,true,3) 2937 end 2938 SetVisualGearValues(CG, CursorX, CursorY, 0, 0, dAngle, dFrame, 1000, dSprite, 1000, dCol) 2939 2940 2941 2942 if crateSprite == nil then 2943 crateSprite = AddVisualGear(CursorX, CursorY-35, vgtStraightShot,0,true,3) 2944 crateSpriteBorder = AddVisualGear(CursorX, CursorY-35, vgtStraightShot,0,true,3) 2945 end 2946 2947 2948 if (cat[cIndex] == loc("Weapon Crate Placement Mode")) or (cat[cIndex] == loc("Utility Crate Placement Mode")) then 2949 if (cat[cIndex] == loc("Weapon Crate Placement Mode")) then 2950 tArr = atkArray 2951 else 2952 tArr = utilArray 2953 end 2954 2955 tSprCol = 0xFFFFFFFF 2956 -- Get ammo icon 2957 if tArr[pIndex][3] then 2958 -- Overwritten ammo icon 2959 tempFrame = tArr[pIndex][3] 2960 else 2961 -- Use default ammo icon 2962 tempFrame = tArr[pIndex][1] - 1 2963 end 2964 end 2965 2966 -- Waypoint outline 2967 if (cat[cIndex] == loc("Waypoint Editing Mode")) and (pMode[pIndex] == loc("Place Waypoint")) then 2968 if not waypointPreviewSprite then 2969 waypointPreviewSprite = AddVisualGear(CursorX, CursorY, vgtCircle, 0, true) 2970 SetVisualGearValues(waypointPreviewSprite, CursorX, CursorY, 244, 224, 0, 0, 0, div(wpRadius, 5), 5, 0xFF0000FF) 2971 end 2972 elseif waypointPreviewSprite then 2973 DeleteVisualGear(waypointPreviewSprite) 2974 waypointPreviewSprite = nil 2975 end 2976 if waypointPreviewSprite then 2977 SetVisualGearValues(waypointPreviewSprite, CursorX, CursorY) 2978 end 2979 2980 else 2981 SetSoundMask(sndIncoming, false) 2982 if CG ~= nil then 2983 SetVisualGearValues(CG, 0, 0, 0, 0, 0, 0, 1000, sprArrow, 1000, 0xFFFFFF00) 2984 end 2985 end 2986 2987 SetVisualGearValues(crateSprite, CursorX+xDisplacement, CursorY+yDisplacement, 0, 0, dAngle, tempFrame, 1000, sprAMAmmos, 1000, tSprCol) 2988 SetVisualGearValues(crateSpriteBorder, CursorX+xDisplacement, CursorY+yDisplacement, 0, 0, 0, 0, 1000, sprCustom1, 1000, tSprCol) 2989 2990 if genTimer >= 100 then 2991 2992 genTimer = 0 2993 2994 curWep = GetCurAmmoType() 2995 2996 HandleRankingEffects() 2997 runOnGears(PortalEffects) 2998 2999 -- change to girder mode on weapon swap 3000 if (cIndex ~= 1) and (curWep == amGirder) then 3001 cIndex = 1 3002 RedefineSubset() 3003 updateHelp() 3004 elseif (cIndex ~=2) and (curWep == amRubber) then 3005 cIndex = 2 3006 RedefineSubset() 3007 updateHelp() 3008 -- change to generic mode if girder no longer selected 3009 elseif (cIndex == 1) and (curWep ~= amGirder) then 3010 cIndex = 3 -- was 2 3011 RedefineSubset() 3012 elseif (cIndex == 2) and (curWep ~= amRubber) then 3013 cIndex = 3 --new 3014 RedefineSubset() 3015 end 3016 3017 if curWep == amGirder or curWep == amRubber then 3018 SetSoundMask(sndDenied, true) 3019 else 3020 SetSoundMask(sndDenied, false) 3021 end 3022 3023 -- update display selection criteria 3024 if (curWep == amGirder) or (curWep == amRubber) or (curWep == amCMGearPlacementTool) then 3025 AddCaption(cat[cIndex], colorPlaceMode1, capgrpMessage) 3026 showSecondaryMessage() 3027 if superDelete == true then 3028 AddCaption(loc("Deletion Mode"), colorPlaceMode1, capgrpAmmoinfo) 3029 end 3030 end 3031 3032 3033 if sSprite ~= nil then 3034 SetVisualGearValues(sSprite, nil, nil, 0, 0, nil, nil, 10000, nil, 10000 ) 3035 end 3036 3037 updateHelp() 3038 3039 end 3040 3041 end 3042 3043 3044 if (ufoFuel ~= 0) then 3045 if ufoFuel == 2000 then 3046 SetHealth(ufoGear, 2000) 3047 end 3048 end 3049 3050 -- kinda lazy, but at least we don't have to do elaborate tacking elsewhere 3051 SetVisualGearValues(sCirc, 0, 0, 0, 1, 1, 10, 0, 1, 1, 0x00000000) 3052 --update selected gear display 3053 if (cat[cIndex] == loc("Repositioning Mode")) and (sGear ~= nil) then 3054 SetVisualGearValues(sCirc, GetX(sGear), GetY(sGear), 100, 255, 1, 10, 0, 300, 3, 0xff00ffff) 3055 elseif (cat[cIndex] == loc("Sprite Modification Mode")) and (sSprite ~= nil) then 3056 SetVisualGearValues(sSprite, nil, nil, 0, 0, nil, nil, 10000, nil, 10000) 3057 elseif (cat[cIndex] == loc("Goal Definition Mode")) then 3058 if (sGear ~= nil) or (closestGear ~= nil) then 3059 closestGear = nil 3060 sGear = nil 3061 end 3062 end 3063 3064 3065 runOnGears(UpdateTagCircles) 3066 3067 3068 -- some kind of target detected, tell me your story 3069 if cGear ~= nil then 3070 3071 x,y = GetGearTarget(cGear) 3072 3073 if GetGearType(cGear) == gtAirAttack and GetCurAmmoType() == amCMGearPlacementTool then 3074 SetGearMessage(cGear, bor(GetGearMessage(cGear), gmDestroy)) 3075 if not cGearPlacementDone then 3076 PlaceObject(x, y) 3077 cGearPlacementDone = true 3078 end 3079 elseif GetGearType(cGear) == gtGirder and not cGearPlacementDone then 3080 CGR = GetState(cGear) 3081 PlaceObject(x, y) 3082 cGearPlacementDone = true 3083 end 3084 3085 end 3086 3087 -- Show cursor coords 3088 updateCursorCoords() 3089 3090end 3091 3092-------------------------------------------------- 3093-- EVENT HANDLERS 3094-------------------------------------------------- 3095 3096function commandMode() 3097 if (preciseOn == true) and ((GetCurAmmoType() == amNothing) or (GetCurAmmoType() == amSkip)) then 3098 return(true) 3099 else 3100 return(false) 3101 end 3102end 3103 3104function onTimer(s) 3105 3106 superDelete = false 3107 if (commandMode() == true) and (s == 4) then 3108 SaveLevelData() -- positions of crates, etc 3109 elseif (commandMode() == true) and (s == 2) then 3110 if GetAmmoCount(CurrentHedgehog, amCMGearPlacementTool) == 100 then 3111 SetEditingWeps(0) 3112 AddCaption(loc("The editor weapons and tools have been removed!"), colorInfoMessage, capgrpGameState) 3113 else 3114 SetEditingWeps(100) 3115 AddCaption(loc("The editor weapons and tools have been added!"), colorInfoMessage, capgrpGameState) 3116 end 3117 elseif (preciseOn == true) and (s == 1) then 3118 helpDisabled = not(helpDisabled) 3119 if helpDisabled then 3120 AddCaption(loc("Help Disabled"), colorInfoMessage, capgrpVolume) 3121 else 3122 AddCaption(loc("Help Enabled"), colorInfoMessage, capgrpVolume) 3123 end 3124 updateHelp() 3125 elseif (cat[cIndex] == loc("Sprite Placement Mode")) or (cat[cIndex] == loc("Girder Placement Mode")) or (cat[cIndex] == loc("Rubber Placement Mode")) or (cat[cIndex] == loc("Sprite Modification Mode")) then 3126 3127 if (cat[cIndex] == loc("Rubber Placement Mode")) then 3128 if s == 1 then 3129 landType = lfBouncy 3130 AddCaption(loc("Bouncy Land"), colorPlaceMode1, capgrpAmmoinfo) 3131 elseif s == 5 then 3132 superDelete = true 3133 end 3134 elseif s == 1 then 3135 landType = 0 3136 AddCaption(loc("Normal Land"), colorPlaceMode1, capgrpAmmoinfo) 3137 elseif s == 2 then 3138 landType = lfIndestructible 3139 AddCaption(loc("Indestructible Land"), colorPlaceMode1, capgrpAmmoinfo) 3140 elseif s == 3 then 3141 landType = lfIce 3142 AddCaption(loc("Icy Land"), colorPlaceMode1, capgrpAmmoinfo) 3143 elseif (s == 4) then 3144 landType = lfBouncy 3145 AddCaption(loc("Bouncy Land"), colorPlaceMode1, capgrpAmmoinfo) 3146 elseif (s == 5) and (cat[cIndex] ~= loc("Sprite Modification Mode")) and (cat[cIndex] ~= loc("Sprite Placement Mode")) then 3147 superDelete = true 3148 end 3149 elseif pMode[pIndex] == loc("Selection Mode") then 3150 if sGear ~= nil and GetGearType(sGear) == gtHedgehog then 3151 setGearValue(sGear, "ranking", s) 3152 end 3153 end 3154 3155end 3156 3157function onPrecise() 3158 3159 preciseOn = true 3160 3161end 3162 3163function onPreciseUp() 3164 preciseOn = false 3165end 3166 3167function showSecondaryMessage() 3168 local caption2 3169 if curWep == amGirder then 3170 caption2 = loc("Girder") 3171 elseif curWep == amRubber then 3172 caption2 = loc("Rubber") 3173 elseif cat[cIndex] == loc("Mine Placement Mode") or cat[cIndex] == loc("Sticky Mine Placement Mode") or cat[cIndex] == loc("Air Mine Placement Mode") then 3174 caption2 = string.format(loc("%d ms"), pMode[pIndex]) 3175 elseif cat[cIndex] == loc("Dud Mine Placement Mode") or cat[cIndex] == loc("Barrel Placement Mode") or cat[cIndex] == loc("Health Crate Placement Mode") then 3176 caption2 = string.format(loc("Health: %d"), pMode[pIndex]) 3177 elseif cat[cIndex] == loc("Health Modification Mode") then 3178 local health = tonumber(pMode[pIndex][1]) 3179 local mode = pMode[pIndex][2] 3180 if mode == "set" then 3181 caption2 = string.format(loc("Set to %d"), health) 3182 elseif mode == "mod" then 3183 if health < 0 then 3184 caption2 = string.format(loc("Subtract %d"), math.abs(health)) 3185 else 3186 caption2 = string.format(loc("Add %d"), health) 3187 end 3188 else 3189 caption2 = "ERROR" 3190 end 3191 elseif type(pMode[pIndex]) == "table" then 3192 caption2 = tostring(pMode[pIndex][1]) 3193 else 3194 caption2 = tostring(pMode[pIndex]) 3195 end 3196 AddCaption(caption2, colorPlaceMode2, capgrpMessage2) 3197end 3198 3199--------------------------------------------------------------- 3200-- Cycle through selection subsets (by changing pIndex, pMode) 3201-- i.e health of barrels, medikits, 3202-- timer of mines 3203-- contents of crates etc. 3204--------------------------------------------------------------- 3205function onLeft() 3206 3207 if (curWep == amCMGearPlacementTool) then 3208 leftHeld = true 3209 rightHeld = false 3210 3211 if preciseOn then 3212 if cat[cIndex] == loc("Sprite Placement Mode") then 3213 sFrame = sFrame - 1 3214 if sFrame < 0 then 3215 sFrame = reducedSpriteIDArrayFrames[pIndex] - 1 3216 end 3217 end 3218 else 3219 pIndex = pIndex - 1 3220 if pIndex == 0 then 3221 pIndex = #pMode 3222 end 3223 if cat[cIndex] == loc("Sprite Placement Mode") then 3224 sFrame = math.min(sFrame, reducedSpriteIDArrayFrames[pIndex] - 1) 3225 end 3226 3227 if (curWep == amGirder) or (curWep == amRubber) or (curWep == amCMGearPlacementTool) then 3228 showSecondaryMessage() 3229 end 3230 end 3231 end 3232 3233end 3234 3235function onRight() 3236 3237 if (curWep == amCMGearPlacementTool) then 3238 leftHeld = false 3239 rightHeld = true 3240 3241 if preciseOn then 3242 if cat[cIndex] == loc("Sprite Placement Mode") then 3243 sFrame = sFrame + 1 3244 if sFrame >= reducedSpriteIDArrayFrames[pIndex] then 3245 sFrame = 0 3246 end 3247 end 3248 else 3249 pIndex = pIndex + 1 3250 if pIndex > #pMode then 3251 pIndex = 1 3252 end 3253 if cat[cIndex] == loc("Sprite Placement Mode") then 3254 sFrame = math.min(sFrame, reducedSpriteIDArrayFrames[pIndex] - 1) 3255 end 3256 3257 if (curWep == amGirder) or (curWep == amRubber) or (curWep == amCMGearPlacementTool) then 3258 showSecondaryMessage() 3259 end 3260 end 3261 end 3262 3263end 3264 3265--------------------------------------------------------- 3266-- Cycle through primary categories (by changing cIndex) 3267-- i.e mine, sticky mine, barrels 3268-- health/weapon/utility crate, placement of gears 3269--------------------------------------------------------- 3270function onUp() 3271 3272 if (curWep == amCMGearPlacementTool) then 3273 cIndex = cIndex - 1 3274 if (cIndex == 1) or (cIndex == 2) then --1 --we no longer hit girder by normal means 3275 cIndex = #cat 3276 end 3277 3278 RedefineSubset() 3279 updateHelp() 3280 3281 end 3282 3283end 3284 3285function onDown() 3286 3287 if (curWep == amCMGearPlacementTool) then 3288 cIndex = cIndex + 1 3289 if cIndex > #cat then 3290 cIndex = 3 -- 2 ----we no longer hit girder by normal means 3291 end 3292 3293 RedefineSubset() 3294 updateHelp() 3295 3296 end 3297 3298end 3299 3300function onParameters() 3301 3302 parseParams() 3303 3304 ufoFuel = tonumber(params["ufoFuel"]) 3305 if ufoFuel == nil then 3306 ufoFuel = 0 3307 end 3308 3309 mapID = tonumber(params["m"]) 3310 3311 --15 is a good short range portal, for what it's worth 3312 if tonumber(params["portalDistance"]) ~= nil then 3313 portalDistance = div(tonumber(params["portalDistance"]),5) 3314 end 3315 3316 if portalDistance == nil then 3317 portalDistance = 5000 3318 end 3319 3320 if mapID == nil then 3321 mapID = 1 3322 end 3323 3324end 3325 3326function onGameInit() 3327 3328 -- perhaps we can get some of this better info in parsecommandoverride 3329 3330 if mapID == nil then 3331 mapID = 1 3332 end 3333 3334 -- read gameflags and assign their values to the gameflaglist array 3335 for i = 1, #gameFlagList do 3336 if band(GameFlags, gameFlagList[i][3]) ~= 0 then 3337 gameFlagList[i][2] = true 3338 else 3339 gameFlagList[i][2] = false 3340 end 3341 end 3342 3343 reducedSpriteIDArrayFrames = { 3344 1, 8, 4, 1, 1, 3345 AmmoTypeMax, AmmoTypeMax, 3, 4, 8, 1, 3346 1, 1, 1, 1, 1, 1, 3347 1, 1, 1, 1, 1, 3348 } 3349 3350 Explosives = 0 3351 MinesNum = 0 3352 AirMinesNum = 0 3353 3354 EnableGameFlags(gfInfAttack, gfDisableWind) 3355 3356 RedefineSubset() 3357 3358end 3359 3360function showHedgeEditorMissionPanel() 3361 ShowMission ( 3362 loc("HEDGEEDITOR"), 3363 loc("An experimental editing tool for missions and more"), 3364 loc("Manual: https://hedgewars.org/hedgeeditor") .. "|" .. 3365 " " .. "|" .. 3366 loc("Place Girder: Girder") .. "|" .. 3367 loc("Place Rubber: Rubber") .. "|" .. 3368 loc("Place Gears (and more): Gear Placement Tool") .. "|" .. 3369 loc("Toggle Help: [Precise]+[1]") .. "|" .. 3370 " " .. "|" .. 3371 loc("Editing Commands: (Use while no weapon is selected)") .. "|" .. 3372 loc("Save Level: [Precise]+[4]") .. "|" .. 3373 loc("Toggle Editing Weapons and Tools: [Precise]+[2]") 3374 , 4, 5000 3375 ) 3376 3377 SetAmmoTexts(amCMGearPlacementTool, 3378 loc("Gear Placement Tool"), 3379 loc("HedgeEditor tool"), 3380 loc("Place, modify and delete gears (e.g. objects)|and waypoints, edit hedgehog settings, values,|victory conditions, and more.") .. "|" .. 3381 loc("Select a placement mode and read the infos|in the mission panel to learn how to use it.") .. "|" .. 3382 loc("Up/Down: Change placement mode") .. "|" .. 3383 loc("Cursor: Mode action")) 3384 3385 hedgeEditorMissionPanelShown = true 3386end 3387 3388function onGameStart() 3389 3390 trackTeams() 3391 3392 3393 InterpretPoints() 3394 LoadLevelData() 3395 3396 showHedgeEditorMissionPanel() 3397 3398 sCirc = AddVisualGear(0,0,vgtCircle,0,true) 3399 SetVisualGearValues(sCirc, 0, 0, 100, 255, 1, 10, 0, 40, 3, 0xffba00ff) 3400 3401 --[[ This is a small hack to disable Hedgewars' girder placement since we do it on our own; 3402 this will remove the "girder circle" and gets rid of the placement failure animation ]] 3403 SetMaxBuildDistance(1) 3404 3405 frameID = 1 3406 visualSprite = sprAmGirder 3407 sSprite = AddVisualGear(0, 0, vgtStraightShot, 0, true,1) 3408 SetVisualGearValues(sSprite, 1, 1, 0, 0, nil, frameID, 20000, visualSprite, 20000, 0 ) 3409 3410 SetAmmoDelay(amCMGearPlacementTool,0) 3411 SetAmmoDelay(amGirder,0) 3412 SetAmmoDelay(amRubber,0) 3413 3414end 3415 3416function SetEditingWeps(ammoCount) 3417 3418 AddAmmo(CurrentHedgehog, amCMGearPlacementTool, ammoCount) 3419 AddAmmo(CurrentHedgehog, amGirder, ammoCount) 3420 AddAmmo(CurrentHedgehog, amRubber, ammoCount) 3421 AddAmmo(CurrentHedgehog, amTeleport, ammoCount) 3422 AddAmmo(CurrentHedgehog, amRope, ammoCount) 3423 AddAmmo(CurrentHedgehog, amSwitch, 100) 3424 AddAmmo(CurrentHedgehog, amSkip, 100) 3425 3426end 3427 3428function clearAmmo(gear) 3429 for i = 1, #atkArray do 3430 AddAmmo(gear,atkArray[i][1],0) 3431 end 3432 for i = 1, #utilArray do 3433 AddAmmo(gear,utilArray[i][1],0) 3434 end 3435end 3436 3437-- the below two functions allow you to set up a themed team. 3438-- one day, it'd be nice to be able to set their voice/flag/grave 3439-- ingame at this point, too, but for now, this is impossible 3440function SetTeamIdentity(gear) 3441 tName = pMode[pIndex] 3442 hIndex = 1 3443 hArr = {} 3444 for i = 1,#preMadeTeam[pIndex][2] do 3445 table.insert(hArr,preMadeTeam[pIndex][2][i]) 3446 end 3447 nArr = {} 3448 for i = 1,#preMadeTeam[pIndex][3] do 3449 table.insert(nArr,preMadeTeam[pIndex][3][i]) 3450 end 3451 SetHogTeamName(gear, tName) 3452 runOnHogs(AssignTeam) 3453end 3454 3455function AssignTeam(gear) 3456 3457 if GetHogTeamName(gear) == tName then 3458 3459 setGearValue(gear,"flag",preMadeTeam[pIndex][5]) 3460 setGearValue(gear,"voice",preMadeTeam[pIndex][6]) 3461 setGearValue(gear,"grave",preMadeTeam[pIndex][7]) 3462 setGearValue(gear,"fort",preMadeTeam[pIndex][8]) 3463 setGearValue(gear,"originalTeamName",preMadeTeamNamesOriginal[pIndex]) 3464 3465 if preMadeTeam[pIndex][4] == "R" then -- random team 3466 3467 if #hArr > 0 then 3468 --if there are unchosen hats left, choose one 3469 --then remove it from the available list of hats 3470 i = 1+GetRandom(#hArr) 3471 SetHogHat(gear,hArr[i]) 3472 table.remove(hArr,i) 3473 else 3474 -- choose any hat randomly 3475 SetHogHat(gear,preMadeTeam[pIndex][2][1+GetRandom(#preMadeTeam[pIndex][2])]) 3476 end 3477 3478 if #nArr > 0 then 3479 i = 1+GetRandom(#nArr) 3480 SetHogNameAndTranslate(gear, nArr[i]) 3481 table.remove(nArr,i) 3482 else 3483 SetHogNameAndTranslate(gear, preMadeTeam[pIndex][3][1+GetRandom(#preMadeTeam[pIndex][3])]) 3484 end 3485 3486 elseif preMadeTeam[pIndex][4] == "F" then -- fixed team w/ exactly 8 guys 3487 SetHogNameAndTranslate(gear, preMadeTeam[pIndex][3][hIndex]) 3488 SetHogHat(gear,preMadeTeam[pIndex][2][hIndex]) 3489 hIndex = hIndex +1 3490 else -- FR fixed random team with more or less than 8 guys 3491 3492 if #hArr > 0 then 3493 i = 1+GetRandom(#hArr) 3494 SetHogHat(gear,hArr[i]) 3495 SetHogNameAndTranslate(gear, nArr[i]) 3496 table.remove(hArr,i) 3497 table.remove(nArr,i) 3498 else 3499 SetHogHat(gear,"NoHat") 3500 SetHogNameAndTranslate(gear,loc_noop("Hedgehog")) 3501 end 3502 3503 end 3504 3505 end 3506 3507end 3508 3509-- allows you to set a sort of identity and weapon profile for a given hog 3510-- this should only really be used when perHogAmmo is enabled 3511function SetHogProfile(gear, pro) 3512 3513 clearAmmo(gear) 3514 3515 if pro == loc("Sniper") then 3516 3517 SetHogNameAndTranslate(gear, "Sniper") 3518 SetHogHat(gear, "Sniper") 3519 SetHealth(gear, 50) 3520 AddAmmo(gear, amSniperRifle, 100) 3521 AddAmmo(gear, amDEagle, 100) 3522 3523 elseif pro == loc("Pyro") then 3524 3525 SetHogNameAndTranslate(gear, "Pyro") 3526 SetHogHat(gear, "Gasmask") 3527 SetHealth(gear, 80) 3528 AddAmmo(gear, amFlamethrower, 100) 3529 AddAmmo(gear, amMolotov, 100) 3530 AddAmmo(gear, amNapalm, 1) 3531 3532 elseif pro == loc("Soldier") then 3533 3534 SetHogNameAndTranslate(gear, "Soldier") 3535 SetHogHat(gear, "war_americanww2helmet") 3536 SetHealth(gear, 100) 3537 AddAmmo(gear, amBazooka, 100) 3538 AddAmmo(gear, amShotgun, 100) 3539 AddAmmo(gear, amMortar, 100) 3540 3541 elseif pro == loc("Grenadier") then 3542 3543 SetHogNameAndTranslate(gear, "Grenadier") 3544 SetHogHat(gear, "war_desertgrenadier1") 3545 SetHealth(gear, 100) 3546 AddAmmo(gear, amGrenade, 100) 3547 AddAmmo(gear, amClusterBomb, 100) 3548 AddAmmo(gear, amGasBomb, 100) 3549 3550 elseif pro == loc("Chef") then 3551 3552 SetHogNameAndTranslate(gear, "Chef") 3553 SetHogHat(gear, "chef") 3554 SetHealth(gear, 65) 3555 AddAmmo(gear, amGasBomb, 100) 3556 AddAmmo(gear, amKnife, 100) 3557 AddAmmo(gear, amCake, 1) 3558 3559 elseif pro == loc("Ninja") then 3560 3561 SetHogNameAndTranslate(gear, "Ninja") 3562 SetHogHat(gear, "NinjaFull") 3563 SetHealth(gear, 80) 3564 AddAmmo(gear, amRope, 100) 3565 AddAmmo(gear, amFirePunch, 100) 3566 AddAmmo(gear, amParachute, 1) 3567 3568 elseif pro == loc("Commander") then 3569 3570 SetHogNameAndTranslate(gear, "Commander") 3571 SetHogHat(gear, "sf_vega") 3572 SetHealth(gear, 120) 3573 AddAmmo(gear, amDEagle, 100) 3574 AddAmmo(gear, amAirAttack, 2) 3575 AddAmmo(gear, amNapalm, 1) 3576 AddAmmo(gear, amDrillStrike, 1) 3577 AddAmmo(gear, amMineStrike, 1) 3578 3579 elseif pro == loc("Engineer") then 3580 3581 SetHogNameAndTranslate(gear, "Engineer") 3582 SetHogHat(gear, "Glasses") 3583 SetHealth(gear, 45) 3584 AddAmmo(gear, amGirder, 4) 3585 AddAmmo(gear, amRubber, 2) 3586 AddAmmo(gear, amLandGun, 2) 3587 AddAmmo(gear, amBlowTorch, 100) 3588 AddAmmo(gear, amPickHammer, 100) 3589 3590 elseif pro == loc("Physicist") then 3591 3592 SetHogNameAndTranslate(gear, "Physicist") 3593 SetHogHat(gear, "lambda") 3594 SetHealth(gear, 80) 3595 AddAmmo(gear, amIceGun, 2) 3596 AddAmmo(gear, amSineGun, 100) 3597 AddAmmo(gear, amBee, 2) 3598 AddAmmo(gear, amLowGravity, 100) 3599 3600 elseif pro == loc("Trapper") then 3601 3602 SetHogNameAndTranslate(gear, "Trapper") 3603 SetHogHat(gear, "Skull") 3604 SetHealth(gear, 100) 3605 AddAmmo(gear, amMine, 100) 3606 AddAmmo(gear, amSMine, 4) 3607 AddAmmo(gear, amAirMine, 2) 3608 AddAmmo(gear, amMolotov, 100) 3609 3610 elseif pro == loc("Saint") then 3611 3612 SetHogNameAndTranslate(gear, "Saint") 3613 SetHogHat(gear, "angel") 3614 SetHealth(gear, 200) 3615 AddAmmo(gear, amSeduction, 100) 3616 AddAmmo(gear, amInvulnerable, 100) 3617 AddAmmo(gear, amIceGun, 2) 3618 AddAmmo(gear, amHammer, 100) 3619 AddAmmo(gear, amResurrector, 100) 3620 3621 elseif pro == loc("Clown") then 3622 3623 SetHogNameAndTranslate(gear, "Clown") 3624 SetHogHat(gear, "clown-copper") 3625 SetHealth(gear, 70) 3626 AddAmmo(gear, amBaseballBat, 100) 3627 AddAmmo(gear, amGasBomb, 100) 3628 AddAmmo(gear, amBallgun, 1) 3629 AddAmmo(gear, amKamikaze, 1) 3630 3631 -- some other ideas/roles 3632 -- relocator: portal, teleport, tardis, extra time, lasersite 3633 -- vampire: vampire, whip, birdy, extra damage, seduction 3634 -- flyboy: rc plane, deagle, whip, parachute, kamikaze 3635 -- demo: drill, dynamite, mine, smine, blowtorch 3636 -- alien: ufo, sine-gun, drill rocket 3637 -- terminator: tardis, shotgun, cake, girder 3638 -- yeti: ice-gun, firepunch, blowtorch 3639 3640 end 3641 3642 AddAmmo(gear, amSwitch, 100) 3643 AddAmmo(gear, amSkip, 100) 3644 3645end 3646 3647function onNewTurn() 3648 3649 -- regardless of our other ammo, give stuff that is useful for editing 3650 SetEditingWeps(100) 3651 if GetHogLevel(CurrentHedgehog) == 0 then 3652 SetTurnTimeLeft(MAX_TURN_TIME) 3653 else 3654 SkipTurn() -- skip the computer's turn 3655 end 3656 3657end 3658 3659function onGameTick() 3660 HandleHedgeEditor() 3661end 3662 3663function isATrackedGear(gear) 3664 if (GetGearType(gear) == gtHedgehog) or 3665 (GetGearType(gear) == gtGrenade) or 3666 (GetGearType(gear) == gtExplosives) or 3667 (GetGearType(gear) == gtTarget) or 3668 (GetGearType(gear) == gtKnife) or 3669 (GetGearType(gear) == gtMine) or 3670 (GetGearType(gear) == gtSMine) or 3671 (GetGearType(gear) == gtPortal) or 3672 (GetGearType(gear) == gtAirMine) or 3673 (GetGearType(gear) == gtCase) 3674 then 3675 return(true) 3676 else 3677 return(false) 3678 end 3679end 3680 3681function SetHogNameAndTranslate(gear, originalName) 3682 SetHogName(gear, loc(originalName)) 3683 --[[ Store the original (usually English) hog name, since we need it for exporting. 3684 This way, we can display the translated name in the editor and export the properly 3685 loc()'ed original name afterwards ]] 3686 setGearValue(gear, "originalName", originalName) 3687end 3688 3689-- track hedgehogs and placement gears 3690function onGearAdd(gear) 3691 3692 if GetGearType(gear) == gtJetpack then 3693 ufoGear = gear 3694 if (ufoFuel ~= 0) then 3695 SetHealth(ufoGear, ufoFuel) 3696 end 3697 end 3698 3699 if (GetGearType(gear) == gtAirAttack and GetCurAmmoType() == amCMGearPlacementTool) or (GetGearType(gear) == gtGirder) then 3700 cGear = gear 3701 cGearPlacementDone = false 3702 end 3703 3704 local tagTint 3705 3706 if isATrackedGear(gear) then 3707 trackGear(gear) 3708 3709 if GetGearType(gear) == gtPortal then 3710 setGearValue(gear,"life",portalDistance) 3711 end 3712 3713 end 3714 3715end 3716 3717function onGearDelete(gear) 3718 local gt = GetGearType(gear) 3719 3720 if gt == gtJetpack then 3721 ufoGear = nil 3722 end 3723 3724 if (gt == gtAirAttack and GetGearPos(gear) == 0) or gt == gtGirder then 3725 cGear = nil 3726 end 3727 3728 if isATrackedGear(gear) then 3729 3730 if getGearValue(gear, "tCirc") ~= nil then 3731 DeleteVisualGear(getGearValue(gear, "tCirc")) 3732 end 3733 3734 trackDeletion(gear) 3735 3736 end 3737 3738end 3739 3740function onVisualGearDelete(vGear) 3741 if vGear == tagCursorX then 3742 tagCursorX = nil 3743 end 3744 if vGear == tagCursorY then 3745 tagCursorY = nil 3746 end 3747end 3748