- Joined
- Feb 8, 2015
- Messages
- 93
Hello Hive
This is going to be rather an extensive thread, because I need lots of help with lots of things. Any and all advice would be hugely appreciated - if you're looking for +rep, I guess this is the thread
I'm working on a map. A really big map. A huge map for 10 players (hard to get full house these days...). A map akin to strategy maps like Dark Ages of Warcraft or Azeroth Wars, ripe with Heroes, factions events, and different units.
But I wanted my map to be better than Azeroth Wars (hubris alert). I wanted it to have more fun heroes, more efficient triggering, and more beautiful landscape (see spoiler below).
The map has lots of triggered spells (I cleaned all leaks to my knowledge), but I feel like they must be horribly inefficient somehow. I don't know JASS, so it's all done in GUI.
The map also has a lot of forests, swamps, cities, mountain ranges, etc. And it all adds up to tons of doodads, because I tried to make it pretty with dense foliation and such.
Any way, if you've read this far I already owe you my thanks, but for those looking for something more concrete, I'll attach a few pictures of terrain and the infamous loop trigger.
NOTE: I don't expect anyone to read through the entirety of the trigger, but if anyone could give some general pointers on JASS optimization, that would be much appreciated:
And some screen shots, showing off the huge doodad counts.
Thanks a lot for reading or even just casually skimming/browing through this thread. I appreciate any and all help!
This is going to be rather an extensive thread, because I need lots of help with lots of things. Any and all advice would be hugely appreciated - if you're looking for +rep, I guess this is the thread
I'm working on a map. A really big map. A huge map for 10 players (hard to get full house these days...). A map akin to strategy maps like Dark Ages of Warcraft or Azeroth Wars, ripe with Heroes, factions events, and different units.
But I wanted my map to be better than Azeroth Wars (hubris alert). I wanted it to have more fun heroes, more efficient triggering, and more beautiful landscape (see spoiler below).
- I wanted my triggers to be more efficient
- Should not be too hard, considering that Azeroth Wars triggers don't even have proper leak clearing, making the game unplayable in some late-game cases.
- I wanted my map to have more fun Heroes. Unique abilities and fun systems that allowed more micro-management than ordinary warcraft 3 spells (hail the Channel ability) and I have dozens upon dozens of custom triggered spells. Some of these naturally act over time, so I have a periodic trigger running once a second, doing triggered healing, counting down curse durations or passive cooldowns, etc.
The difference between the loop trigger being turned on/off is roughly 10 frames per second. That's a problem. It makes my map nigh unplayable (without taking actual gameplay into account). - I wanted my map to be beautiful. The terrain should not just be the setting of battles, but also a treat for the eyes on its own. A combination of functuality and aesthetics.
So naturally the map has about 47000 doodads. That's a problem.
It also hurts framerate hugely. - Custom models - The map as of now is on 4.7mb. But do custom models really take that much processing power? I don't use any "high poly-count" models to my knowledge - though I do use tree models ripped from World of Warcraft, because Blizzard trees... physically hurt me.
The map has lots of triggered spells (I cleaned all leaks to my knowledge), but I feel like they must be horribly inefficient somehow. I don't know JASS, so it's all done in GUI.
The map also has a lot of forests, swamps, cities, mountain ranges, etc. And it all adds up to tons of doodads, because I tried to make it pretty with dense foliation and such.
Any way, if you've read this far I already owe you my thanks, but for those looking for something more concrete, I'll attach a few pictures of terrain and the infamous loop trigger.
NOTE: I don't expect anyone to read through the entirety of the trigger, but if anyone could give some general pointers on JASS optimization, that would be much appreciated:
-
OneSec Loop Triggers
-
Events
-
Time - Every 1.00 seconds of game time
-
-
Conditions
-
Actions
-
-------- NOMAD HERO - Storm Ward - Periodic AoE DPS --------
-
Set StomWard_buffgroup = (Units in (Playable map area) matching (((((Matching unit) has buff Nomad: Storm Ward I (Frost Armor)) Equal to True) or ((((Matching unit) has buff Nomad: Storm Ward II (Frost Armor)) Equal to True) or ((((Matching unit) has buff Nomad: Storm Ward III (Frost
-
Unit Group - Pick every unit in StomWard_buffgroup and do (Actions)
-
Loop - Actions
-
Set StomWard_Tempu1 = (Picked unit)
-
Set StomWard_Boolean[1] = (StomWard_Tempu1 has buff Nomad: Storm Ward I (Frost Armor))
-
Set StomWard_Boolean[2] = (StomWard_Tempu1 has buff Nomad: Storm Ward II (Frost Armor))
-
Set StomWard_Boolean[3] = (StomWard_Tempu1 has buff Nomad: Storm Ward III (Frost Armor))
-
Set StomWard_Boolean[4] = (StomWard_Tempu1 has buff Nomad: Storm Ward IV (Frost Armor))
-
Set StomWard_Boolean[5] = (StomWard_Tempu1 has buff Nomad: Storm Ward V (Frost Armor))
-
Set StomWard_Tempp1 = (Position of StomWard_Tempu1)
-
Set StomWard_Tempug = (Units within 250.00 of StomWard_Tempp1 matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is A flying unit) Equal to False) and ((((Matching unit) is dead) Equal to False) and ((((Matching unit) is Magic Immune) Equal to False
-
Unit Group - Pick every unit in StomWard_Tempug and do (Actions)
-
Loop - Actions
-
Set StomWard_Tempu2 = (Picked unit)
-
-------- Checks the level of the buff --------
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
StomWard_Boolean[1] Equal to True
-
-
Then - Actions
-
Set StomWard_i = 1
-
-
Else - Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
StomWard_Boolean[2] Equal to True
-
-
Then - Actions
-
Set StomWard_i = 2
-
-
Else - Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
StomWard_Boolean[3] Equal to True
-
-
Then - Actions
-
Set StomWard_i = 3
-
-
Else - Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
StomWard_Boolean[4] Equal to True
-
-
Then - Actions
-
Set StomWard_i = 4
-
-
Else - Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
StomWard_Boolean[5] Equal to True
-
-
Then - Actions
-
Set StomWard_i = 5
-
-
Else - Actions
-
-
-
-
-
-
-
-
-
-
Set StomWard_Tempr1 = (((Real(StomWard_i)) x 5.00) + 5.00)
-
Unit - Cause StomWard_Tempu1 to damage StomWard_Tempu2, dealing StomWard_Tempr1 damage of attack type Spells and damage type Normal
-
Special Effect - Create a special effect attached to the chest of StomWard_Tempu2 using Abilities\Spells\Orc\LightningShield\LightningShieldBuff.mdl
-
Special Effect - Destroy (Last created special effect)
-
-
-
-
-
Custom script: call DestroyGroup(udg_StomWard_buffgroup)
-
Custom script: call DestroyGroup(udg_StomWard_Tempug)
-
Custom script: call RemoveLocation(udg_StomWard_Tempp1)
-
-------- RIFTSEEKRS HERO - Twisted Path - Periodic AoE HPS --------
-
Set TwisPath_Tempug1 = (Units in (Playable map area) matching ((((Matching unit) has buff Sekr: Twisted Path (Immolation)) Equal to True) and ((Unit-type of (Matching unit)) Equal to Ferulizar (Cult - Strength Hero))))
-
Unit Group - Pick every unit in TwisPath_Tempug1 and do (Actions)
-
Loop - Actions
-
Set TwisPath_Tempu1 = (Picked unit)
-
Set TwisPath_r1 = (1.00 + (6.00 x (Real((Level of Sekr: Twisted Path (FallenDragonW - Immolation) for TwisPath_Tempu1)))))
-
Set TwisPath_Tempp1 = (Position of TwisPath_Tempu1)
-
Set TwisPath_Tempug2 = (Units within 300.00 of TwisPath_Tempp1 matching ((((Matching unit) belongs to an ally of (Owner of TwisPath_Tempu1)) Equal to True) and ((((Matching unit) is dead) Equal to False) and (((Matching unit) Not equal to TwisPath_Tempu1) and ((((Matching unit) is
-
Custom script: call RemoveLocation(udg_TwisPath_Tempp1)
-
Unit Group - Pick every unit in TwisPath_Tempug2 and do (Actions)
-
Loop - Actions
-
Set TwisPath_Tempu2 = (Picked unit)
-
Unit - Set life of TwisPath_Tempu2 to ((Life of TwisPath_Tempu2) + TwisPath_r1)
-
-
-
-
-
-------- DARK ELF HERO - Blest of the Sun Duration Countdown (and DPS) --------
-
Unit Group - Pick every unit in BlestotSun_ugFriendly and do (Actions)
-
Loop - Actions
-
Set BlestotSun_picked = (Picked unit)
-
Set BlestotSun_handle = (Custom value of BlestotSun_picked)
-
Set BlestotSun_time = (Load 0 of BlestotSun_handle from BlestotSun_hash)
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
BlestotSun_time Greater than 0.00
-
-
Then - Actions
-
Unit - Make BlestotSun_picked Invulnerable
-
Special Effect - Create a special effect attached to the chest of BlesWind_picked using Abilities\Spells\Human\DivineShield\DivineShieldTarget.mdl
-
Special Effect - Destroy (Last created special effect)
-
Set BlestotSun_time = (BlestotSun_time - 1.00)
-
Hashtable - Save BlestotSun_time as 0 of BlestotSun_handle in BlestotSun_hash
-
-
Else - Actions
-
Unit - Make BlestotSun_picked Vulnerable
-
Hashtable - Clear all child hashtables of child BlestotSun_handle in BlestotSun_hash
-
Unit Group - Remove BlestotSun_picked from BlestotSun_ugFriendly
-
-
-
-
-
Unit Group - Pick every unit in BlestotSun_ugHostile and do (Actions)
-
Loop - Actions
-
Set BlestotSun_picked = (Picked unit)
-
Set BlestotSun_handle = (Custom value of BlestotSun_picked)
-
Set BlestotSun_time = (Load 0 of BlestotSun_handle from BlestotSun_hash)
-
Set BlestotSun_cast = (Load 1 of BlestotSun_handle in BlestotSun_hash)
-
Set BlestotSun_dam1 = (Load 2 of BlestotSun_handle from BlestotSun_hash)
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
BlestotSun_time Greater than 0.00
-
-
Then - Actions
-
Set BlestotSun_time = (BlestotSun_time - 1.00)
-
Unit - Cause BlestotSun_targ to damage BlestotSun_picked, dealing (BlestotSun_dam1 / 3.00) damage of attack type Spells and damage type Normal
-
Special Effect - Create a special effect attached to the chest of BlesWind_picked using Abilities\Spells\Other\BreathOfFire\BreathOfFireDamage.mdl
-
Special Effect - Destroy (Last created special effect)
-
Hashtable - Save BlestotSun_time as 0 of BlestotSun_handle in BlestotSun_hash
-
-
Else - Actions
-
Hashtable - Clear all child hashtables of child BlestotSun_handle in BlestotSun_hash
-
Unit Group - Remove BlestotSun_picked from BlestotSun_ugHostile
-
-
-
-
-
-------- DARK ELF HERO - Grand Confession AoE DPS and HPS --------
-
Unit Group - Pick every unit in GConfess_castgroup and do (Actions)
-
Loop - Actions
-
Set GConfess_caster = (Picked unit)
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
(Current order of GConfess_caster) Equal to (Order(tranquility))
-
-
Then - Actions
-
-------- Setup --------
-
Set PuriStack_tempr = (Real(PuriStack_i[(Custom value of Splendour_cast)]))
-
Set GConfess_dmg = ((0.25 x PuriStack_tempr) + (10.00 + (10.00 x (Real((Level of DarkElf: Grand Confession (GrandMissionaryR - Tranquility Dummy) for GConfess_caster))))))
-
Set GConfess_dmg = ((0.25 x PuriStack_tempr) + (5.00 + (5.00 x (Real((Level of DarkElf: Grand Confession (GrandMissionaryR - Tranquility Dummy) for GConfess_caster))))))
-
Set GConfess_Tempp = (Position of GConfess_caster)
-
Set GConfess_Tempug1 = (Units within 900.00 of GConfess_Tempp matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is Magic Immune) Equal to False) and ((((Matching unit) belongs to an enemy of (Owner of GConfess_caster)) Equal to True) and ((((Matchin
-
Set GConfess_Tempug2 = (Units within 900.00 of GConfess_Tempp matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is Mechanical) Equal to False) and ((((Matching unit) belongs to an enemy of (Owner of GConfess_caster)) Equal to False) and ((((Matching
-
-------- Effect --------
-
Unit Group - Pick every unit in GConfess_Tempug1 and do (Actions)
-
Loop - Actions
-
Set GConfess_picked = (Picked unit)
-
Unit - Cause GConfess_caster to damage GConfess_picked, dealing GConfess_dmg damage of attack type Spells and damage type Normal
-
-
-
Unit Group - Pick every unit in GConfess_Tempug2 and do (Actions)
-
Loop - Actions
-
Set GConfess_picked = (Picked unit)
-
Unit - Set life of GConfess_picked to ((Life of GConfess_picked) + GConfess_heal)
-
-
-
-
Else - Actions
-
-
-
-
-------- DRAGONBLOOD HERO - Firewalk Mana cost --------
-
Unit Group - Pick every unit in FireWalk_group and do (Actions)
-
Loop - Actions
-
Unit - Set mana of (Picked unit) to ((Mana of (Picked unit)) - 20.00)
-
-
-
-------- DRAGONBLOOD UNIT - Blood Champion Cooldowns --------
-
Custom script: set bj_wantDestroyGroup = true
-
Unit Group - Pick every unit in (Units in (Playable map area) matching ((Unit-type of (Matching unit)) Equal to Blood Champion (Dragonblood - Elite Infantry Melee))) and do (Actions)
-
Loop - Actions
-
Set BC_picked = (Picked unit)
-
Set BC_index = (Custom value of BC_picked)
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
(BC_picked has buff Dragonblood: Craze (Berserk)) Equal to False
-
-
Then - Actions
-
Set BCPulverize_cd[BC_index] = (BCPulverize_cd[BC_index] - 1.00)
-
Set BCRevel_cd[BC_index] = (BCRevel_cd[BC_index] - 1.00)
-
-
Else - Actions
-
Set BCPulverize_cd[BC_index] = (BCPulverize_cd[BC_index] - 2.00)
-
Set BCRevel_cd[BC_index] = (BCRevel_cd[BC_index] - 2.00)
-
-
-
-
-
-------- TROLL HERO - Healing Waters AoE HPS --------
-
Set HealWatr_Tempug = (Units in (Playable map area) matching (((Unit-type of (Matching unit)) Equal to The Blue Warrior (Troll - Strength Hero)) and (((Matching unit) has buff Troll: Healing Waters (Rejuvenation)) Equal to True)))
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
(Number of units in HealWatr_Tempug) Equal to 0
-
-
Then - Actions
-
-------- No units with the buff - does nothing --------
-
-
Else - Actions
-
Unit Group - Pick every unit in HealWatr_Tempug and do (Actions)
-
Loop - Actions
-
Set HealWatr_cast = (Picked unit)
-
Set HealWatr_Tempp1 = (Position of HealWatr_cast)
-
Set HealWatr_r1 = ((200.00 x (Real((Level of (Ability being cast) for HealWatr_cast)))) / 20.00)
-
Set HealWatr_Tempug = (Units within 350.00 of HealWatr_Tempp2 matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) belongs to an ally of (Owner of HealWatr_cast)) Equal to True) and ((((Matching unit) is dead) Equal to False) and ((((Matching unit) is
-
Unit Group - Pick every unit in HealWatr_Tempug and do (Actions)
-
Loop - Actions
-
Set HealWatr_Tempu = (Picked unit)
-
Unit - Set life of HealWatr_Tempu to ((Life of HealWatr_Tempu) + HealWatr_r1)
-
Set HealWatr_Tempp2 = (Position of HealWatr_Tempu)
-
Unit - Create 1 Dummy Heal Effect for Neutral Passive at HealWatr_Tempp2 facing Default building facing degrees
-
Unit - Add a 0.98 second Generic expiration timer to (Last created unit)
-
-
-
-
-
-
-
-------- Cleaning --------
-
Custom script: call RemoveLocation(udg_HealWatr_Tempp1)
-
Custom script: call RemoveLocation(udg_HealWatr_Tempp2)
-
Custom script: call DestroyGroup(udg_HealWatr_Tempug)
-
-------- TROLL HERO - Blood Howl duration check --------
-
Unit Group - Pick every unit in BlodHowl_ug and do (Actions)
-
Loop - Actions
-
Set BlodHowl_u1 = (Picked unit)
-
Set BlodHowl_time = (Load 0 of (Custom value of BlodHowl_u1) from BlodHowl_hash)
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
BlodHowl_time Less than or equal to 0.00
-
-
Then - Actions
-
Unit - Set BlodHowl_u1 movement speed to (Default movement speed of BlodHowl_u1)
-
Set BlodHowl_u2 = (Load 1 of (Custom value of BlodHowl_u1) in BlodHowl_hash)
-
Unit - Set BlodHowl_u2 movement speed to (Default movement speed of BlodHowl_u2)
-
Hashtable - Clear all child hashtables of child (Custom value of BlodHowl_u1) in BlodHowl_hash
-
-
Else - Actions
-
Unit Group - Remove BlodHowl_u1 from BlodHowl_ug
-
Set BlodHowl_time = (BlodHowl_time - 1.00)
-
-
-
-
-
-------- TROLL HERO - Rakjesh attack damage per missing hp% --------
-
Set AtdMissHP_Tempug = (Units in (Playable map area) matching ((((Matching unit) is alive) Equal to True) or (((Unit-type of (Matching unit)) Equal to The Howling Scourge (Trolls - Agility Hero)) or ((Unit-type of (Matching unit)) Equal to The Howling Scourge (Trolls - Agility Hero
-
Unit Group - Pick every unit in AtdMissHP_Tempug and do (Actions)
-
Loop - Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
(Level of Troll: Frenzy (HowlingScourgeE - Critical Strike) for (Picked unit)) Greater than or equal to 1
-
-
Then - Actions
-
Set RakHealthPrc_array[(Custom value of (Picked unit))] = (Percentage life of (Picked unit))
-
Unit - Set level of Conclave Increasing AS No Icon (2% per 1% missing health) for (Picked unit) to (Integer(RakHealthPrc_array[(Custom value of (Picked unit))]))
-
-
Else - Actions
-
-
-
-
-------- ITC UNIT - Mana Flood --------
-
Set ManFlo_r1 = 50.00
-
Set ManFlo_area = 350.00
-
Set ManFlo_ug1 = (Units in (Playable map area) matching (((Unit-type of (Matching unit)) Equal to Illusionist (ITC - Basic CasterE)) and (((Matching unit) is dead) Equal to False)))
-
Unit Group - Pick every unit in ManFlo_ug1 and do (Actions)
-
Loop - Actions
-
Set ManFlo_Tempi = (Random integer number between 1 and 10)
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
ManFlo_Tempi Less than or equal to 2
-
-
Then - Actions
-
-------- If the unit won the 20% chance above, proceeds to save variables --------
-
Set ManFlo_u1 = (Picked unit)
-
Set ManFlo_Tempp1 = (Position of ManFlo_u1)
-
Set ManFlo_ug2 = (Units within ManFlo_area of ManFlo_Tempp1 matching ((((Matching unit) is dead) Equal to False) and ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) belongs to an ally of (Owner of ManFlo_u1)) Equal to True) and (((Max mana of (Matchi
-
-------- Checks for viable targets, if none are found the below If/Then/Else does nothing --------
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
(Number of units in ManFlo_ug2) Greater than 0
-
-
Then - Actions
-
-------- Only actually uses mana restore if there are any viable targets --------
-
Set ManFlo_RandomUg = (Random 1 units from ManFlo_ug2)
-
Unit Group - Pick every unit in ManFlo_RandomUg and do (Actions)
-
Loop - Actions
-
Set ManFlo_u2 = (Picked unit)
-
Set ManFlo_Tempp2 = (Position of ManFlo_u2)
-
Unit - Set mana of ManFlo_u2 to ((Mana of ManFlo_u2) + ManFlo_r1)
-
Special Effect - Create a special effect at ManFlo_Tempp2 using Abilities\Spells\Undead\ReplenishMana\ReplenishManaCasterOverhead.mdl
-
Special Effect - Destroy (Last created special effect)
-
-
-
Special Effect - Create a special effect at ManFlo_Tempp1 using Abilities\Spells\Undead\ReplenishMana\SpiritTouchTarget.mdl
-
Special Effect - Destroy (Last created special effect)
-
-------- Cleanup --------
-
Custom script: call RemoveLocation(udg_ManFlo_Tempp2)
-
Custom script: call DestroyGroup(udg_ManFlo_RandomUg)
-
-
Else - Actions
-
-------- If no viable targets were found, simply proceeds to remove variables --------
-
-
-
Custom script: call DestroyGroup(udg_ManFlo_ug2)
-
Custom script: call RemoveLocation(udg_ManFlo_Tempp1)
-
-
Else - Actions
-
-
-
-
Custom script: call DestroyGroup(udg_ManFlo_ug1)
-
-------- LEGION UNIT - Curse of Rot Mind --------
-
Set CurMinRot_hpdam = 7.00
-
Set CurMinRot_manadam = 4.00
-
Set CurMinRot_ug = (Units in (Playable map area) matching ((((Matching unit) has buff Legion: Curse of Mind Rot ) Equal to True) and (((Matching unit) is dead) Equal to False)))
-
Unit Group - Pick every unit in CurMinRot_ug and do (Actions)
-
Loop - Actions
-
Set CurMinRot_tempu = (Picked unit)
-
Unit - Set life of CurMinRot_tempu to ((Life of CurMinRot_tempu) - CurMinRot_hpdam)
-
Unit - Set mana of CurMinRot_tempu to ((Mana of CurMinRot_tempu) - CurMinRot_manadam)
-
-
-
Custom script: call DestroyGroup(udg_CurMinRot_ug)
-
-------- VARIOUS - Attack speed per missing health% --------
-
Set ASMissHP_Tempug = (Units in (Playable map area) matching ((((Matching unit) is alive) Equal to True) or (((Unit-type of (Matching unit)) Equal to ConclaveBerserker_uType) or (((Unit-type of (Matching unit)) Equal to ConclaveOverseer_uType) or (((Unit-type of (Matching unit)) E
-
Unit Group - Pick every unit in ASMissHP_Tempug and do (Actions)
-
Loop - Actions
-
Set ConclaveHealthPercent[(Custom value of (Picked unit))] = (100 - (Integer((Percentage life of (Picked unit)))))
-
Unit - Set level of Conclave Increasing AS No Icon (2% per 1% missing health) for (Picked unit) to ConclaveHealthPercent[(Custom value of (Picked unit))]
-
-
-
Custom script: call DestroyGroup(udg_ASMissHP_Tempug)
-
-
And some screen shots, showing off the huge doodad counts.
Thanks a lot for reading or even just casually skimming/browing through this thread. I appreciate any and all help!