• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Trigger] Spell should damage units, but doesn't. Help.

Status
Not open for further replies.
Level 20
Joined
Apr 14, 2012
Messages
2,901
Hello; I have recently been given by Radicool the trigger of a spell called Sharpnel (Dota). (It wasn't MUI yet but I added a few tweaks. Is it MUI now?)The spell is based off on Dispel Magic. It's supposed to damage units in an area but it doesn't. Please help :)

  • Dwarven Snipers Sharpnel 1
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Shrapnel
    • Actions
      • Set SharpnelCounter = (SharpnelCounter + 1)
      • Set SharpnelCaster[SharpnelCounter] = (Triggering unit)
      • Trigger - Turn on Dwarven Snipers Sharpnel 2 <gen>
      • Wait 8.00 seconds
      • Trigger - Turn off Dwarven Snipers Sharpnel 2 <gen>
  • Dwarven Snipers Sharpnel 2//initially off
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Set SharpnelTmpPoint = (Target point of ability being cast)
      • -------- This is a formula to calculate the damage. This is the actual damage in dota too. --------
      • -------- 12, 24, 36, 48 --------
      • Set SharpnelDamage = (12 x (Level of Shrapnel for SharpnelCaster[SharpnelCounter]))
      • -------- Picks all units that are an enemy of the caster --------
      • Set SharpnelGroup = (Units within 350.00 of SharpnelTmpPoint matching (((Matching unit) belongs to an enemy of (Owner of SharpnelCaster[SharpnelCounter])) Equal to True))
      • Unit Group - Pick every unit in SharpnelGroup and do (Actions)
        • Loop - Actions
          • -------- Checks if the unit is a structure or not. --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) is A structure) Equal to True
            • Then - Actions
              • -------- Divides damage by 3 if its a structure --------
              • Unit - Cause (Casting unit) to damage (Picked unit), dealing ((Real(SharpnelDamage)) / 3.00) damage of attack type Chaos and damage type Normal
            • Else - Actions
              • -------- Otherwise normal damage is applied --------
              • Unit - Cause (Casting unit) to damage (Picked unit), dealing (Real(SharpnelDamage)) damage of attack type Chaos and damage type Normal
          • -------- Here we create the dummy to slow the enemy --------
          • Unit - Create 1 Dummy Unit for (Owner of SharpnelCaster[SharpnelCounter]) at SharpnelTmpPoint facing Default building facing degrees
          • Unit - Order (Last created unit) to Human Sorceress - Slow (Picked unit)
          • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Custom script: call RemoveLocation (udg_SharpnelTmpPoint)
 
Level 8
Joined
Feb 3, 2013
Messages
277
I see that you're using an array, but that doesn't make your spell completely MUI
But for starters, yes Cause SharpnelCaster[SharpnelCounter] to damage [Picked Unit] will work

i guess.. you can set an array for every variable you use and then

do an if SharpnelCounter = 8191
then set SharpnelCounter = 0
else set SharpnelCounter = SharpnelCounter + 1

so on the first trigger, mark every variable with an array using [SharpnelCounter]

SharpnelTmpPoint[SharpnelCounter]
SharpnelDamage[SharpnelCounter]
SharpnelGroup[SharpnelCounter]

... but this will leak like eff lol, maybe you can use an indexing system
 
Last edited:

Wrda

Spell Reviewer
Level 26
Joined
Nov 18, 2012
Messages
1,886
I see that you're using an array, but that doesn't make your spell completely MUI
But for starters, yes Cause SharpnelCaster[SharpnelCounter] to damage [Picked Unit] will work

i guess.. you can set an array for every variable you use and then

do an if SharpnelCounter = 8191
then set SharpnelCounter = 0
else set SharpnelCounter = SharpnelCounter + 1

so on the first trigger, mark every variable with an array using [SharpnelCounter]

SharpnelTmpPoint[SharpnelCounter]
SharpnelDamage[SharpnelCounter]
SharpnelGroup[SharpnelCounter]

... but this will leak like eff lol, maybe you can use an indexing system

Horrible way. We need to lower the index -1 when the spell has finished so that it doesn't reach 8192, not 8191.
@ MasterTrainer, you need to save the caster in a variable so that you can use in the other triggers, any "event response" that doesn't correspond to the event isn't found
 
Level 4
Joined
Jan 27, 2010
Messages
133
Is it MUI now?

A good basic test for MUI is to imagine just 2 units, with the second starting the spell while the first one is still going on.

In this case: <Unit 1> casts spell - Trigger Shrapnel2 is turned on.
<Unit 1> Waits for 5 seconds, but then
<Unit 2> Casts spell
<Unit 1> Waits the remaining 3 seconds
<Unit 1> Turns off Trigger Shrapnel2

Now notice that unit 2 only got the effect for 3 seconds, before the first unit's spell-cast turned off the trigger.

...a trigger of a spell called Sharpnel (Dota)
I'm fairly certain that DotA uses custom script/jass and not triggers.
 
Level 20
Joined
Apr 14, 2012
Messages
2,901
Whoa that trigger, omg my eyes hoirt so much.

That is not even close to "MUI".
Do you accept a remake of that spell ?

@defskull; yes I accept a remake of that spell :thumbs_up: Also, sorry that your eyes hurt so much when you looked at the trigger (since I think that you found many errors or actually the whole trigger is an error or, your eyes hurt because the spell is really, really, really far from MUI), thanks; :smile:
 
Level 20
Joined
Apr 14, 2012
Messages
2,901
Horrible way. We need to lower the index -1 when the spell has finished so that it doesn't reach 8192, not 8191.
@ MasterTrainer, you need to save the caster in a variable so that you can use in the other triggers, any "event response" that doesn't correspond to the event isn't found

But I already stored it in a variable (array): SharpnelCaster[SharpnelCounter]. And by "lower the index - 1" do you mean:
  • Dwarven Snipers Sharpnel 1
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Sharpnel
    • Actions
      • Set SharpnelCounter = (SharpnelCounter + 1)
      • Set SharpnelCaster[SharpnelCounter] = (Casting unit)
      • Set SharpnelTmpPoint = (Target point of ability being cast)
      • Trigger - Turn on Dwarven Snipers Sharpnel 2 <gen>
      • Wait 8.00 seconds
      • Trigger - Turn off Dwarven Snipers Sharpnel 2 <gen>
      • Set SharpnelCounter = (SharpnelCounter - 1)
or
  • Dwarven Snipers Sharpnel 3
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • (Ability being cast) Equal to Sharpnel
    • Actions
      • Set SharpnelCounter = (SharpnelCounter - 1)
If both wrong, can you show me what you mean?
 
Level 8
Joined
Feb 3, 2013
Messages
277
Horrible way. We need to lower the index -1 when the spell has finished so that it doesn't reach 8192, not 8191.
@ MasterTrainer, you need to save the caster in a variable so that you can use in the other triggers, any "event response" that doesn't correspond to the event isn't found

he's right^^ lol

maybe master, you should focus on getting it to work first;;

then focus on MUI later...
 
Level 20
Joined
Apr 14, 2012
Messages
2,901
It damages the units in the group, but now it seems that the damage is dealt once only (one big damage instead of many small damages):

  • Dwarven Snipers Sharpnel 2
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • -------- This is a formula to calculate the damage. This is the actual damage in dota too. --------
      • -------- 12, 24, 36, 48 --------
      • Set SharpnelDamage = (12 x (Level of Sharpnel for SharpnelCaster[SharpnelCounter]))
      • -------- Picks all units that are an enemy of the caster --------
      • Set SharpnelGroup = (Units within 500.00 of SharpnelTmpPoint matching (((Matching unit) belongs to an enemy of (Owner of SharpnelCaster[SharpnelCounter])) Equal to True))
      • Unit Group - Pick every unit in SharpnelGroup and do (Actions)
        • Loop - Actions
          • Unit Group - Pick every unit in SharpnelGroup and do (Actions)
            • Loop - Actions
              • -------- Checks if the unit is a structure or not. --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is A structure) Equal to True
                • Then - Actions
                  • -------- Divides damage by 3 if its a structure --------
                  • Unit - Cause SharpnelCaster[SharpnelCounter] to damage (Picked unit), dealing ((Real(SharpnelDamage)) / 3.00) damage of attack type Chaos and damage type Normal
                • Else - Actions
                  • -------- Otherwise normal damage is applied --------
                  • Unit - Cause SharpnelCaster[SharpnelCounter] to damage (Picked unit), dealing (Real(SharpnelDamage)) damage of attack type Chaos and damage type Normal
      • Custom script: call RemoveLocation (udg_SharpnelTmpPoint)
I don't know what else I should change. What am I doing wrong?
 
Level 8
Joined
Feb 3, 2013
Messages
277
Um.. I'm not really sure how to make it in GUI..
but master, instead I made a shrapnel like spell for you in vJASS, but.. I just realized you may not be used to vJASS

But still I will try to explain what i've done;;

This requires 2 spells(1 for the hero to cast (does nothing) - based off Dispel Magic; and 1 for the shrapnel visuals - death and decay with changed visuals and deals no damage), a dummy unit,the TimerUtils system, and JNGP :).
what this does, is upon casting creates a dummy unit to use shrapnel visual spell at the spell target location and then
stores the caster, the dummy, (x,y) values of the target location, time remaining (initially 8), and the damage(12* level of ability)
using a struct, into a timer via the TimerUtils system. I then start the timer, as a repeating timer with a expiration time of 1 second.

Each time the timer expires, I call a function that starts out by loading the data saved into the expired timer and create a group within 350 distance from the saved target location.
Then I check if the remaining time of the spell is greater than 0.
IF IT IS, then I use the FirstofGroup loop to damage targets in the group(I determine if the unit is a enemy structure or an enemy unit before dealing damage). And after each timer expiration, I save the time remaining of the spell into the expired timer.
ELSE, i pause the timer and destroy it and the dummy unit casting the visual effects spell

Its completely MUI, but not leakless - cuz i rushed it. Here are some links to help you understand structs, How to Use Timers, and FirstOfGroup Loop for Enumerations
JASS:
scope Shrapnel initializer init

    globals
        private constant integer dummy = 'h001'
        private constant integer AB_ID = 'A000'
        private constant integer FX_ID = 'A001'
    endglobals
    
    private struct data
        unit caster
        unit dummy
        real x
        real y
        real damage
        integer sec
    endstruct
    
    private function S_Cond takes nothing returns boolean
        return GetSpellAbilityId() == AB_ID
    endfunction
    
    private function S_Damage takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local data s = GetTimerData(t)
        local group g = CreateGroup()
        local unit fog = null
        
        call GetTimerData(t)
        
        call GroupEnumUnitsInRange(g, s.x, s.y, 350, null)
        
        if s.sec > 0 then
            loop 
                set fog = FirstOfGroup(g)
                exitwhen fog == null
                    if IsUnitEnemy(fog, GetOwningPlayer(s.caster)) and IsUnitType(fog, UNIT_TYPE_STRUCTURE) then
                        call UnitDamageTarget(s.caster, fog, s.damage * .5, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
                    elseif IsUnitEnemy(fog, GetOwningPlayer(s.caster)) then
                        call UnitDamageTarget(s.caster, fog, s.damage, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
                    endif
                call GroupRemoveUnit(g, fog)
            endloop
            set s.sec = s.sec - 1
            call DestroyGroup(g)
            set g = null
            call SetTimerData(t, s)
        else
            call DestroyGroup(g)
            set g = null
            call RemoveUnit(s.dummy)
            call PauseTimer(t)
            call ReleaseTimer(t)
        endif
    endfunction
        
    private function S_Actions takes nothing returns nothing
        local data s = data.create()
        local timer t = NewTimer()
        
        set s.caster = GetTriggerUnit()
        set s.x = GetSpellTargetX()
        set s.y = GetSpellTargetY()
        set s.damage = 12 * I2R(GetUnitAbilityLevel(s.caster, AB_ID))
        set s.sec = 8
        set s.dummy = CreateUnit(GetOwningPlayer(s.caster), dummy, s.x, s.y, 0)
        call UnitAddAbility(s.dummy, FX_ID)
        call IssuePointOrder(s.dummy, "deathanddecay", s.x, s.y)
        
        call SetTimerData(t, s)
        call TimerStart(t, 1.00, true, function S_Damage)
    endfunction
//===========================================================================
    private function init takes nothing returns nothing
        local trigger t = CreateTrigger(  )
        local integer i = 0
            loop
                exitwhen i == 15
                call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
                set i = i + 1
            endloop
        call TriggerAddCondition( t, Condition(function S_Cond))
        call TriggerAddAction( t, function S_Actions )
    endfunction

endscope
 

Attachments

  • Shrapnel.w3x
    30.3 KB · Views: 35
Last edited:
Status
Not open for further replies.
Top