- Joined
- Feb 27, 2007
- Messages
- 5,578
Could you be more specific? Perhaps there is a solution.NOTE: This ability can be buggy and i would advise only using it for not user controlled units
(1 ratings)
Instructions:
1 Go into file => preferences => check "Automatically create unknown variables while pasting trigger data".
2.1 Copy part of VariableIntialization with variables from spell that you want to copy(if you want all spells, then just copy whole trigger).
2.2 You can change most variables(in VariableIntialization) however you wish, outside of hashtable and few variables specified to not be changed.
3 Run VariableIntialization at the initialization of your map.
4 Copy Folder with spell you want to use.
5 Follow Instructions in Read Trigger Comment for copied spell.
6 Abilitiies Jingu Mastery and Mischief require Damage Engine(you can use alternative, but then of course you need to change part of triggers to fit your need) so just copy whole folder(Damage Engine) to your map if you want use either of these two abilities.
Boundless Strike:
Monkey King enlarges his staff and slams it against the ground, stunning enemies in a line and damaging them with a critical hit based on his attack. Has True Strike.
Level 1 - 2.2 times normal damage, 1.4 second stun.
Level 2 - 2.6 times normal damage, 1.6 second stun.
Level 3 - 3 times normal damage, 1.8 second stun.
Statue:
Monkey King uses his secret energy to create statue of himself. Statue is invulnerable, uncontrollable, slowed, deals 100% damage of Monkey King and attacks random targets.
Level 1 - Lasts 15 seconds, cost 80 mana, coldown 30seconds.
Level 2 - Lasts 20 seconds, costs 65 mana, cooldown 25seconds.
Level 3 - Lasts 25 seconds, cost 50 mana, cooldown 20seconds.
Jingu Mastery:
Monkey King's attacks awaken the Jingu Bang's power. Upon the fourth hit, Monkey King earns four charged attacks that have bonus damage and lifesteal.
Level 1 - 20 damage bonus, 30% lifesteal.
Level 2 - 35 damage bonus, 50% lifesteal.
Level 3 - 50 damage bonus, 70% lifesteal.
Wukong's Command:
Monkey King creates a circular formation, in which enemy units will be damaged every 1 second by Monkey King base damage, If Monkey King leaves the circle his formation disperse.
Wukong's Command v2.0:
Monkey King creates a circular formation with his statue around. If Monkey King leaves the circle his formation disperse.
NOTE: it is alternative to Wukong's Command it is not better or worse, it is just a little bit diffrent
Tree Dance:
Monkey King jumps to a tree and perches atop it. While perched, he gains the Primal Spring ability-a channeled leap attack. Primal Spring will deal damage and slow in area based off channeling time.
Level 1 - Primal spring damage 50-125, slow 10%-40%.
Level 2 - Primal spring damage 75-195, slow 15%-60%.
Level 3 - Primal spring damage 100-265, slow 20%-80%.
Primal Spring:
Monkey King springs out from his tree perch, damaging and slowing enemies based of his lvl of Tree Dance in the area where he lands.
Mischief:
Changes Monkey King's shape to deceive opponents. Taking damage, or dealing damage breaks Monkey King's disguise. Also reduce damage taken to 0.
Could you be more specific? Perhaps there is a solution.NOTE: This ability can be buggy and i would advise only using it for not user controlled units
I done this ability by creating two abilities based on chaos and created one unit that is exactly same as Monkey King. And then add one chaos ability that changes unit into they morphed or unmorphed version and remove second ability. Only bug that i found is that unit will have day vision during night. But since it is pretty hacky way to do that, i suspect there are some others bugs that could occure in some weird scenario, I left this ability in pack just because it shouldn't cause problems if used for boss unit for example. Also there is probably no other way around to change model of unit via trigger.Could you be more specific? Perhaps there is a solution.
I think Hero Passive Transformation is somewhat-dated, since now you can set a unit's skin/attack point/damage point.Instead of chaos, this has no downsides: Hero passive transformation
Using skin/s solved problem, I thought that skins in warcraft are the same as in other games, where you buy hats and then you have cowboy hat on paladin model, but they replace unit with diffrent unit, while keeping stats and abilities. And luckily have gui method for changing skin when you just have to input "string" integer, but you cant, making it pretty much worthless in a sense(since you can save "string" integer using Jass and then pass is it).I think Hero Passive Transformation is somewhat-dated, since now you can set a unit's skin/attack point/damage point.
added new bugs
native RemoveRect takes rect whichRect returns nothing
.FlushChildHashtable
instead of the wrapper.native FlushChildHashtable takes hashtable whichHashtable, integer parentKey
function FlushChildHashtableBJ takes integer parentKey, hashtable whichHashtable
Thanks for feedback, may I ask Why do you suggest using "A unit starts the effect of an ability" instead of "unit finishes casting an ability", is it because of perfomence or some gameplay diffrence in fringe scenarios.Neat. If I recall, Monkey King was the first Dota 2 exclusive Hero to be introduced. It would be poetic justice to see that it is one of the first Dota 2 exclusive Heroes to be properly (re)introduced back into Warcraft 3. Anyway, here's the code/trigger review:
- In the trigger BoundleStrike (Boundle):
- BoundleAngle appears to be causing a memory leak by referring to an unstored generated location handle in (Position of BoundleStrikeUnit). You could fix that by making it refer to BoundleStartingPosition, moving the initialization of BoundleStartingPosition before it.
- In the same vein, BoundleEndingPoint should refer to BoundleStartingPosition.
From the looks of things, there's no need to nest the conditions within the else block. Just move the inner if-then block out of the outer if-then-else block.
For each (Integer A) from 1 to 3 , do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(X of BoundleCorners[(Integer A)]) Greater than BoundleMaxX
Then - Actions
Set Variable Set BoundleMaxX = (X of BoundleCorners[(Integer A)])
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(X of BoundleCorners[(Integer A)]) Less than BoundleMinX
Then - Actions
Set Variable Set BoundleMinX = (X of BoundleCorners[(Integer A)])
Else - Actions
1.) It looks like a JASS rect (GUI region) handle is being created without being referenced and subsequently cleaned up. You can clean this up using the following function:
-------- Picking Unit Affecte by Boundle --------
Custom script: set bj_wantDestroyGroup = true
Unit Group - Pick every unit in (Units in (Region(BoundleMinX, BoundleMinY, BoundleMaxX, BoundleMaxY)) matching ((((Matching unit) belongs to an enemy of (Owner of BoundleStrikeUnit).) Equal to True) and ((((Matching unit) is A flying unit) Equal to False) and ((((Matching unit) is Magic Immune) Equal to False) and (((Matching unit) is Mechanical) Equal to False))))) and do (Actions)
Loop - Actions
-------- Finding point of center of unit in rotated env --------
Set Variable Set RotatedPositionOfUnit = ((Point(BoundleCenterX, BoundleCenterY)) offset by (Distance between (Position of (Picked unit)) and (Point(BoundleCenterX, BoundleCenterY))) towards ((Angle from (Position of (Picked unit)) to (Point(BoundleCenterX, BoundleCenterY))) - (BoundleAngle - 90.00)) degrees.)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
And - All (Conditions) are true
Conditions
(X of RotatedPositionOfUnit) Less than or equal to (X of BotRightCornerInRotatedBoundle)
(X of RotatedPositionOfUnit) Greater than or equal to (X of BotLeftCornerInRotatedBoundle)
(Y of RotatedPositionOfUnit) Greater than or equal to (Y of BotLeftCornerInRotatedBoundle)
(Y of RotatedPositionOfUnit) Less than or equal to (Y of TopLeftCornerInRotatedBoundle)
Then - Actions
Unit Group - Add (Picked unit) to UnitsAffectedByBoundle
-------- Continue would be nice there istead of else if to have less indentation --------
Else - Actions
-------- Finding closest Y to rotated position of unit --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Y of RotatedPositionOfUnit) Greater than (Y of TopLeftCornerInRotatedBoundle)
Then - Actions
Set Variable Set ClosestYToRotatedPoint = (Y of TopLeftCornerInRotatedBoundle)
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Y of RotatedPositionOfUnit) Less than (Y of BotLeftCornerInRotatedBoundle)
Then - Actions
Set Variable Set ClosestXToRotatedPoint = (X of BotRightCornerInRotatedBoundle)
Set Variable Set ClosestYToRotatedPoint = (Y of BotLeftCornerInRotatedBoundle)
Else - Actions
Set Variable Set ClosestYToRotatedPoint = (Y of RotatedPositionOfUnit)
-------- Finding closest X to rotated position of unit --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(X of RotatedPositionOfUnit) Less than (X of BotLeftCornerInRotatedBoundle)
Then - Actions
Set Variable Set ClosestXToRotatedPoint = (X of BotLeftCornerInRotatedBoundle)
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(X of RotatedPositionOfUnit) Greater than (X of BotRightCornerInRotatedBoundle)
Then - Actions
Set Variable Set ClosestXToRotatedPoint = (X of BotRightCornerInRotatedBoundle)
Else - Actions
Set Variable Set ClosestXToRotatedPoint = (X of RotatedPositionOfUnit)
Set Variable Set BoundleDistanceToEdge = (Square root(((Power((Abs(((X of RotatedPositionOfUnit) - ClosestXToRotatedPoint))), 2.00)) + (Power((Abs(((Y of RotatedPositionOfUnit) - ClosestYToRotatedPoint))), 2.00)))))
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Collision Size of (Picked unit)) Greater than or equal to BoundleDistanceToEdge
Then - Actions
Unit Group - Add (Picked unit) to UnitsAffectedByBoundle
Else - Actions
native RemoveRect takes rect whichRect returns nothing
.
2.) The inner filter function in the nested matching condition statement can look quite ugly really fast with a lot of conditions. Try filtering them out within the Actions block instead. Check out this tutorial for more info: Convenient Unit Group Filtering in GUI
3.) The liberal use of (Position of (Picked unit)) translates to more memory leaks.
4.) You can use Skip Remaining Actions in the Then - Actions block on the first If-then-else block as a quasi-continue statement, since the function (Pick all units in n group) generates a new thread for each picked unit. (Memory leaks that have been created before that point will have to be cleaned up, though).
5.) (Picked unit) is called an awful lot within this block. Perhaps you might want to store that in a temp variable?
- The floating text should only show the integer value of the amount of damage dealt, not the real value. (250 instead of 250.16, for example).
- In the trigger Jingu Lifesteal:
- You can directly call
FlushChildHashtable
instead of the wrapper.
- API difference between the two functions:
JASS:native FlushChildHashtable takes hashtable whichHashtable, integer parentKey function FlushChildHashtableBJ takes integer parentKey, hashtable whichHashtable
- In the trigger Jingu Check for Buff:
- Don't be shy with the interval period. Even when not enabled and disabled properly, this trigger should not be too costly. I'd recommend a 0.50 second interval.
- In the trigger ArenaCreate:
- The (A unit starts the effect of an ability) event would be more suitable here.
- In the trigger Arena Damage (may also apply in ArenaSoldiersV2):
- (Position of MonkeyArena) and (Position of MonkeyArenaCreator) is not stored.
Readability of the filter function can be improved. Also, another location handle (Position of MonkeyArena) has been generated and not cleaned up.
Set Variable Set MonkeyArenaToDamageLeft = ((Load 2 of (Key (Picked unit).) from MonkeyArenaHastable.) - 0.04)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
MonkeyArenaToDamageLeft Less than or equal to 0.00
Then - Actions
Set Variable Set MonkeyArenaToDamageLeft = MonkeyArenaDamageInterval
Custom script: set bj_wantDestroyGroup = true
Unit Group - Pick every unit in (Units within MonkeyArenaSize of (Position of MonkeyArena) matching (((Matching unit) belongs to an ally of (Owner of MonkeyArenaCreator).) Equal to False).) and do (Actions)
Loop - Actions
Unit - Cause MonkeyArenaCreator to damage (Picked unit) , dealing ((Real((Base Damage of MonkeyArenaCreator for weapon index 1))) x MonkeyArenaDamageMult) damage of attack type Hero and damage type Normal
Else - Actions
I suggest resetting the MonkeyArena unit's animation instead of replacing the MonkeyArena unit (model) every 12 seconds.
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
((MonkeyArenaDuration - MonkeyArenaDurationLeft) mod 12.00) Equal to 0.00
Then - Actions
-------- Model of arena will disapear around12 seconds, so we swap arena for new, it is looks a little weird since dragon will change positiom, but it is better than nothing --------
Unit - Replace MonkeyArena with a Monkey Arena using The old unit's relative life and mana
Animation - Change (Last replaced unit) 's size to ( (100.00 x MonkeyArenaScale) %, (100.00 x MonkeyArenaScale) %, 100.00 %) of its original size
Set Variable Set MonkeyArena = (Last replaced unit)
Hashtable - Save Handle Of MonkeyArena as 0 of (Key (Picked unit).) in MonkeyArenaHastable .
Else - Actions
- In the triggers Statue Cast and Mischief:
- (A unit finishes casting an ability) -> (A unit starts the effect of an ability).
- In the Tree Dance Folder:
- In trigger IncreaseLvl:
- In the if-then conditional block, (Picked unit) is used over (Learning Hero). Given the event, (Picked unit) will always return null, leading to the condition never evaluating as true (Level Equal to 1?).
- There may be a lot more things I'd like to point out here, but I will leave it for another day.
Phew, that was a lot to write. Interesting and functional as it currently is, there are a too many instances of memory leaks that need to be removed for me to approve of this right now, so I'll have to put it in Awaiting Update.
Version Reviewed:
- v.1.0.1 (?) - Released 22nd of June, 2022.
Status:
- Awaiting Update