[Trigger] Teleporting Strike[passive]

Status
Not open for further replies.
Level 3
Joined
May 28, 2015
Messages
41
Since it concerns triggers i think it is a better idea to post it there.

Hey there again! I'm trying to make a passive ability that would teleport enemy away from the caster on attack and i need that to be MUI since there might be multiple caster.

here's what i've done:

i got two triggers VS2 start and VS2 effect. The start one checks if attacking unit have the skill at all, then whether the skill occur on this attack, then if attacking unit have the mana required. After that it sets attacking unit to be the caster and attacked unit to be the target with current vsIndex value for an arrays and finily runs the VS1 effect trigger and reduce caster's mana by the "manacost" amount.

  • VS2 start
    • Events
      • Unit - A unit is attacked
    • Conditions
      • (Random integer number between 1 and 100) is less than 17
      • (Level of r6 vanishing strike lv2 for (Attacking unit)) is more than 0
      • (Mana of (Attacking unit)) is more or equals 15.00
    • Actions
      • Set vsCaster[vsIndex] = (Attacking unit)
      • Set vsTarget[vsIndex] = (Attacked unit)
      • Trigger - Add to VS1 effect <gen> the event (Unit - vsTarget[vsIndex] recieves damage)
      • Unit - Set mana of (vsCaster[vsIndex]) to ((Mana of (vsCaster[vsIndex])) - 15.00)
Now to the effect trigger i use to make enemy dissapear when he actually take damage. So as the event Unit - (vsTaget[vsIndex]) recieves damage is added the actions is as follows:

  • VS2 effect
    • Events
    • Conditions
    • Actions
      • Unit - Move vsTarget[vsIndex] instantly to ((Position of vsTarget[vsIndex]) offset by 400.00 towards (Facing of vsCaster[vsIndex]) degrees)
      • Set vsIndex = (vsIndex + 1)
i assume it leaks the position of unit which should be dealt with by storing unit's position in varaible and then destroying it, but i just cant get the hold of that idea so if smone would explain that to me or link me to a good tutorial about that one specificaly (not the whole "leaks removal" ones) that would be much appreciated.

But in general: am i doing it right? or is it still needs fixing? the first " buggy " thing i encountered from that trigger is that i cannot increase the vsIndex right after the effect trigger should be run like this:

  • Actions
    • Set vsCaster[vsIndex] = (Attacking unit)
    • Set vsTarget[vsIndex] = (Attacked unit)
    • Trigger - Add to VS1 effect <gen> the event (Unit - vsTarget[vsIndex] recieves damage)
    • Set vsIndex = (vsIndex +1)
and i'm a litle woried that this part could mess everything when 3 or more units would cast that skill simultaniously and the index would increase only after the first target would take damage thus making it possible to reset vsCaster and vsTarget to a new values discarding the first units effect leaving the first target in the same place.

The second problem is that the targeted unit gets thrown back a greater distance instead of what is required (i assume it multipies the base value by 2 or smth like that) with each consecutive hit. Could that be because i do not store the location in a variable or is it caused by smth else?

And finily is it really MUI? I started to experiment with indexing units a while ago so might do it wrong.

Thx for your time!
 
Last edited:
It is not MUI.

First of all, you should use Damage detection system (DDS) instead of what you have right now.
The whole problem here is that you have no idea who the attacked unit is, hence you add it into the "damage taken" event once said unit is attacked.

This has various problems associated with it.
First problem: "A unit is attacked" event fires when an attacker starts the attack. However before the actual attack hits there is a delay (which varies from unit-type to unit-type).
Imagine this yourself in real life situation:
When you swing a wooden stick at someone, you don't hit them immediately. The "Attacked" event is when you start swinging, the "Take damage" event when you hit the enemy. There is definitely a time delay between the two.
So what is the problem here? You can spam "stop" button! So even if your spell has only a 17% chance to fire, I can make it fire basically nonstop by pressing stop button. With stop button pressed, the unit immediately ceases all action, but because of its standard AI, it will attempt to attack the enemy again, hence once again triggering the "Is attacked" event.

Second problem: you add the attacked unit into the second trigger each time it is attacked.
For simplicity, let's say your spell has 100% chance to fire.
First attack on an enemy: He is add into the second trigger.
Second attack on the same enemy: He is add again.
Third attack: Add again.
And so on and so on.

Third problem: You can add an event to trigger, but you can never remove an event from trigger. When unit dies, it does not get removed from the event! The more events one trigger has, the slower the trigger is until you hit a limit and it collapses, so your spell would very well malfunction after some time.
Normally the chance of hitting the limit is not much of an issue, but in your case (adding (same) units into the event on each attack, with this spell being used by multiple units at the same time) it is pretty bad.


Fourth problem: Your indexing. The idea of indexing is to do these steps in the exact order:
1) increase index value
2) index units/other stuff you need
3) do something with all indexed stuff
4) deindex units which should no longer be affected.
5) decrease index value

See your problem here? You first index units, do something with it and then when something happens you increase index. And you don't deindex.

All your indexed units are still indexed, however your trigger will still collapse, because after some time with the way you have it triggered your index will get over the 8191 index limit (the last allowed index) and the next attack will cause trigger collapse in better case, worst case game crash.


Why is your trigger not MUI? Because you increase index everytime the same unit takes damage (hence why it's not so hard for your trigger to get over from index 0 to index 8191). Add to it that that one unit is many times in the event, so each time it takes damage it fires the trigger multiple times.
Let's show you example situations. Again, for simplicity let's say your spell has 100% chance to proc now:
1st example: Only one unit - UNIT_A repeatedly attacking other unit - UNIT_B.

Attack #1:
UNIT_B is attacked.
Index = 1
UNIT_A = Caster[1], UNIT_B = Target[1]
UNIT_B is add into "On_damage" trigger.
On_damage trigger fires.
move UNIT_B (saved as Target[1])
Set index = index + 1 = 2


Attack #2:
UNIT_B is attacked.
Index = 2
UNIT_A = Caster[2], UNIT_B = Target[2]
UNIT_B is add into "On_damage" trigger.
On_damage trigger fires for Target[1].
move UNIT_B (saved as Target[1])
Set index = index + 1 = 3
On_damage trigger fires for Target[2]
move UNIT_B (saved as Target[2])
Set index = index + 1 = 4



Attack #3:
UNIT_B is attacked.
Index = 4
UNIT_A = Caster[4], UNIT_B = Target[4]
UNIT_B is add into "On_damage" trigger.
On_damage trigger fires for Target[1].
move UNIT_B (saved as Target[1])
Set index = index + 1 = 5
On_damage trigger fires for Target[2]
move UNIT_B (saved as Target[2])
Set index = index + 1 = 6

On_damage trigger fires for Target[4]
move UNIT_B (saved as Target[4])
Set index = index + 1 = 7

As you can see, after 3 attacks on the same unit the index is 7 and the spell's effect fires for the same unit repeatedly.

2nd example: UNIT_A and UNIT_B attacking UNIT_C.

Attack #1 from both units:
UNIT_C is attacked by UNIT_A
Index = 1
UNIT_A = Caster[1], UNIT_C = Target[1]
UNIT_C is add into "On_damage" trigger.

UNIT_C is attacked by UNIT_B before UNIT_A landed its attack. (this is what I wrote about in First Problem - the delay between "Is Attacked" and "Takes damage" events)
Index = 1
UNIT_B = Caster[1], UNIT_C = Target[1]
UNIT_C is add again into "On_damage" trigger.

On_damage fires for UNIT_C when UNIT_A lands its attack.
move UNIT_C
Set index = index + 1 = 2
On_damage fires again for UNIT_C because it was add twice into the event (once by UNIT_A and second time by UNIT_B)
move UNIT_C
Set index = index + 1 = 3


On_damage fires for UNIT_C when UNIT_B lands its attack
move UNIT_C
Set index = index + 1 = 4
On_damage fires again, because UNIT_C was add twice into on_damage trigger.
move UNIT_C
Set index = index + 1 = 5



Attack #2 from both units:
I won't even bother here, it would be way too long.

Do you see what is happening here? Hence why it is not MUI.
So sadly, your trigger is quite a mess because of the above and it won't work properly.


Your problems can be entirely solved by DDS.
So why use DDS? First of all, DDS destroys and recreates the "on damage" triggers, meaning there are no events for units which are no longer in game and each unit is there only once.
This solves your whole problem basically.
Then your trigger would be like this:
  • MyTrigger
  • Events
    • Game - DDS's event value becomes 1.00
  • Conditions
    • RandInt <= 17
    • Level of spell is greater than 0
    • Mana of damager is greater than 15.00
  • Actions
    • Set mana of damager to mana of damager - 15.00
    • Unit - Move target somewhere
Notice you have no need for indexing units, etc.


About the point leak.
Yes that does leak. This thread: https://www.hiveworkshop.com/forums/triggers-scripts-269/things-leak-35124/ documents each type of leak and how to remove them.
In case of point leaks it is simple:
1) Create variable of type "POINT"
2) Set the location into the variable
3) Refer in your actions to the variable
4) Once you are done using the location, call a RemoveLocation function to remove the location.

In triggers:
  • Set my_point = *somewhere* //sets location into variable of type point
  • *do stuff involving the location*
  • Unit - Move my_unit to my_point
  • * other stuff with locations*
  • Custom script: call RemoveLocation(udg_my_point) //destroy location
Notice: In custom scripts, all your variables have to have the prefix udg_, so the variable my_point is written as "udg_my_point".


I hope this helped you and gave you insight into what is happening in your spell.
 
I hope this helped you and gave you insight into what is happening in your spell.

it is indeed helped a lot! with that reply you clarified a lot of questions i might have had and explained how the things go around. It's sometimes hard to get a detailed reply instead of "it's not right! use DDS noob" so thanks a-bloody-lot!

the only thing i need now is to find a simple though functional DDS that i could implement in my man...

would
HTML:

would that one be any good for my purposes? or you could recomend another easy-to-use DDS?
 
The one you posted, or you can take a look at this one: https://www.hiveworkshop.com/forums...6/?prev=search=damage%20detection&d=list&r=20 or this one: https://www.hiveworkshop.com/forums...ev=search=damage%20detection&d=list&r=20&t=65 (this last one also detects if damage is physical, spell or code damage).

i think i'll use Bribe's one for it was inspired by the DDS i've found and i don't think i'll need that differentiation of damage type just yet in my map.

Thank you Nichilus for you allowed me to continue the map development! i promice to make an english version of the map as soon as i get the damn thing to the first really playable version 8)

---upd---

Okay there...i've incorporated the DDS in my map and it makes it perfectly good but there are still a few questions:

i use move unit to point with polar offset to throw it back from the attacking unit...so it looks like this:

  • Unit - move attacked unit instantly to ((position of attacked unit) offset by 400 towards (facing of attacking unit) deegrees)
and if the attacking unit would turn before the attacked unit gets to a new location that offset would be turned with the unit also throwing him not "back" but "left" or "right" depending on whre the unit has turned. how can that be fixed to teleport target in a correct direction?

---upd---

this is the only skill i've encountered problems with...all the rest were quickly remade to use the DDS and work perfectly! thx Nichilus for helping me make first really playable version of the map! as soon as i'll get it to the minimum of what i want it to be i'll translate the map for you guys here 8)
 
Last edited:
Is the attacking unit a ranged damager or are you using some kind of wait before moving the unit?

that is correct...it's ranged though i think the issue would not be of a great problem since the player have no direct control over units.

but it would be nice to know the solution...i thought about creating a dummy unit and making it face the direction of the attacker then teleport the enemy with that dummy's facing angle instead the one of the caster and then removing it or simply adding the expiring timer of some 1-2 seconds to deal with it...but haven't tried it yet...was consumed by developing a good "balancing scheme" 8))
 
Well, the solution this problem is impossible to solve.
What I mean is that you don't know from where the arrow hits the unit. Imagine situation like this:
Code:
              X
     O

---------------------

     O
X
The example above consists of two situations.
The first case (the upper one = the one above the line of --------- chars) is where a unit (displayed as 'O') shoots an arrow at an enemy (displayed as 'X').
The second case shows X that teleported behind O before the arrow hit X.
Now, by default the arrow will turn and fly after the unit X (projectiles by default fly after their targets even if their path does not look natural).
Normally, when the arrow finally hits unit X, it should move from our view away from unit O. But try as you might, you will never get a good code that solves the problem above.

The only solution here that I can think of would be to use projectile system. Projectile system uses units (which have the model of projectile and locust ability so they cannot be targeted by player) which imitate projectiles.
Because now you have full control over your projectiles (since they're basically standard units), you can also get position of the "arrow" (=the unit that acts as projectile).
Once you have position of the "arrow" and position of the target, you can easily determine the angle between them and correctly move unit.
 
Status
Not open for further replies.
Back
Top