HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Killing Units without the death scene.

04-04-2006, 12:41 PM#1
knutz
I'm attempting to make an AoE Dark Conversion spell which can target any race. I've almost got it working, except I end up with less zombies than dead units.

Here's what I think is problem:
Victims take too long to die and their bodies are getting in the way of the zombie creation.

Because I need the victims to die for other triggers, I cant replace or remove the victims.

Here's what I need:
A way to instantly kill units, skipping the death scene. I'd like to be able to do this without cutting death time to zero in the object editor, as that would affect any kind of death, and I only want this one to be instant.


Any ideas?
04-04-2006, 01:06 PM#2
Captain Griffen
Explode them?
04-04-2006, 03:25 PM#3
blu_da_noob
Trigger:
Animation - Change Footman 0000 <gen>'s animation speed to 10000.00% of its original speed
Unit - Kill Footman 0000 <gen>
04-04-2006, 03:28 PM#4
Thunder_Eye
Hmm wouldn't the "Decay Flesh" animation speed up to?

Else maybe you can
Kill Unit
Play DecayFlesh animation.

not sure if you can play animations on dead units though..
04-04-2006, 05:15 PM#5
Anitarf
Animations don't have anything to do with it, his concern is that the dying units are getting in the way of new unit creation, which they would do no matter what animation they are playing.

The whole idea seems absurd anyway, out of two reasons: one, I think the unit stops taking up space the moment it dies, not when it's death time ends, and two, if a unit cannot be created at a point because other units are in the way, it is created at the nearest point possible. Either way, it is created. Your problem must lie somewhere else.
04-04-2006, 09:18 PM#6
knutz
Quote:
Originally Posted by Anitarf
Animations don't have anything to do with it, his concern is that the dying units are getting in the way of new unit creation, which they would do no matter what animation they are playing.

The whole idea seems absurd anyway, out of two reasons: one, I think the unit stops taking up space the moment it dies, not when it's death time ends, and two, if a unit cannot be created at a point because other units are in the way, it is created at the nearest point possible. Either way, it is created. Your problem must lie somewhere else.

I guess it's in the code then. Well, here's the bit that's giving me trouble:
Collapse JASS:
        set a = GetUnitFacing(v)
        call KillUnit( v )
        call CreateNUnitsAtLoc( 1, DarkConversion_ZombieUnitId(l), GetOwningPlayer(c), loc,a )
        call AddSpecialEffectLocBJ( loc, "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl" )
        

v = victim or target
DarkConversion_ZombieID() returns the raw code of the zombie to create
c = casting unit
loc = location of v


This code executes when the remaining life of v is less than or equal to the amount of damage to be done.

I'm at a loss. It looks ok to me.

Edited by Blade.dk. Reason: Use jass tags!
04-04-2006, 09:45 PM#7
Blade.dk
Please STOP ignoring the announcements, stickies, editing messages that appears on all your posts and the warning I gave you. Please learn to use the correct tags, it is so simple.

http://www.wc3campaigns.net/showthread.php?t=78403
04-04-2006, 10:05 PM#8
Anitarf
Please post the entire code, all the functions that you use. I can tell nothing from those four lines. Also, a more detailed description would help, do you get the effect on all units when they die, or just on the ones that spawn zombies?
04-04-2006, 11:01 PM#9
Yukitan
The way I see it you would be better by Hiding the Unit or to Turn it's collision off.
04-04-2006, 11:23 PM#10
Vuen
Quote:
Originally Posted by Yukitan
The way I see it you would be better by Hiding the Unit or to Turn it's collision off.

That won't work. Turning a unit's collision off makes it ignore collisions when it moves, not the other way around. Other units will still consider it a collision target.

Anitarf is completely correct; when a unit dies it is no longer considered a valid collision target instantly, and even if that weren't the case, the zombies would still be created anyway, just at a different location.

Your script seems to anticipate when a unit should die and then tries to kill them itself. What's probably happening is that some of the units are dying on their own, rather than being killed by your script, so those that are missed by the script aren't zombified. Instead of killing them when you think they should die, let them die normally and catch all death events. Program the death events to check for your dark conversion and create zombies appropriately.
04-04-2006, 11:36 PM#11
Yukitan
Actually, yes, catching all death events would work (imo) much better than anticipating their death.
04-05-2006, 12:07 AM#12
Immoralis
cant you just remove the dying unit and create a corpse of the dying unit there, the death animation is skipped then
04-05-2006, 12:59 AM#13
shadow1500
i think
Collapse JASS:
call KillUnit(u)
call RemoveUnit(u)
will still activate the events, even though the unit is removed.

EDIT: use the create corpse trigger then.
04-05-2006, 01:12 AM#14
TaintedReality
Yes it does. But he says he doesn't want the bodies removed, which I think is the main problem.
04-05-2006, 06:05 AM#15
knutz
Quote:
Originally Posted by TaintedReality
Yes it does. But he says he doesn't want the bodies removed, which I think is the main problem.

I'd like to remove the bodies, but don't want the map to think I'm removing the units from the game, or it might give me trouble with revival triggers. If that's not the case, then I'll do that.

Quote:
Originally Posted by Blade.dk
Please STOP ignoring the announcements, stickies, editing messages that appears on all your posts and the warning I gave you. Please learn to use the correct tags, it is so simple.

Um, sorry. I think I've got the hang of it now.

Quote:
Originally Posted by Anitarf
Please post the entire code, all the functions that you use. I can tell nothing from those four lines. Also, a more detailed description would help, do you get the effect on all units when they die, or just on the ones that spawn zombies?

All units that die while under the influence of the spell should spawn zombies. OK, here's the whole thing. Please bear in mind, it's my first attempt at JASS, so is a bit clumsy and any suggestions would be gratefully accepted.

Spell: Dark Conversion AoE. Puts enemy non-structure units in AoE to sleep, periodically damages them for a period of time and raises zombies if they die before the wake-up call.

Collapse JASS:
//Implementation
//---------------------------------------------------------------------------------------------------
function DarkConversion_SpellId takes nothing returns integer 
    //Radcode of the triggering spell.
    return 'A001' 
endfunction
//---------------------------------------------------------------------------------------------------
function DarkConversion_SleepSpellId takes nothing returns integer 
    //Rawcode of the sleep dummy spell.
    return 'A000' 
endfunction
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
function DarkConversion_AnimateDeadSpellId takes nothing returns integer 
    //Rawcode of the sleep dummy spell.
    return 'A002' 
endfunction
//---------------------------------------------------------------------------------------------------
function DarkConversion_SleepSpellOrder takes nothing returns string
    //Order of the sleep dummy spell.
    return "sleep" 
endfunction
//---------------------------------------------------------------------------------------------------
function DarkConversion_ZombieUnitId takes integer level returns integer
    local integer array ZOMBIE
    set ZOMBIE[1] = 'nzom' //Rawcode of the level 1 zombie
    set ZOMBIE[2] = 'n000' //Rawcode of the level 2 zombie
    set ZOMBIE[3] = 'n001' //Rawcode of the level 3 zombie
    set ZOMBIE[4] = 'n002' //Rawcode of the level 4 zombie
    return ZOMBIE[level] 
endfunction
//---------------------------------------------------------------------------------------------------
function DarkConversion_UnitDamage takes integer level returns real 
    return I2R(level)*55   //Damage for non-heros 
endfunction
//---------------------------------------------------------------------------------------------------
function DarkConversion_HeroDamage takes integer level returns real 
    return I2R(level)*55   //Damage for heros 
endfunction
//---------------------------------------------------------------------------------------------------
function DarkConversion_UnitDuration takes integer level returns integer 
    return level*2  //How many seconds asleep 
endfunction
//---------------------------------------------------------------------------------------------------
function DarkConversion_HeroDuration takes integer level returns integer 
    return level+1  //How many seconds asleep 
endfunction
//---------------------------------------------------------------------------------------------------
function DarkConversion_AoE takes real level returns real 
    return 150+(100*level)//AoE of the spell 
endfunction
//---------------------------------------------------------------------------------------------------
function DarkConversion_TargetOptions takes integer level returns integer
    return DamageTypes(ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC)+DamageOnlyEnemies()+DamageOnlyTo(UNIT_TYPE_GROUND)+DamageIgnore(UNIT_TYPE_STRUCTURE) // Damage options used for finding which unit will be put to sleep.
endfunction
//---------------------------------------------------------------------------------------------------

function Trig_DarkConversion_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == DarkConversion_SpellId() ) ) then
        return false
    endif
    return true
endfunction

function DarkConversion_DamageDone takes timer t returns nothing
    call CleanAttachedVars_NoSets(t)
    call DestroyTimer(t)
endfunction

function DarkConversion_Damage takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local real dmg = GetAttachedReal(t,"damage")
    local integer l = GetAttachedInt(t,"level")
    local integer count = GetAttachedInt(t,"count")    
    local unit c = GetAttachedUnit(t,"caster")
    local unit v = GetAttachedUnit(t,"victim")
    //local real x = GetUnitX(v)
    //local real y = GetUnitY(v)
    local location loc = GetUnitLoc(v)
    local real a 
    local unit u 
    local real check = GetUnitStateSwap(UNIT_STATE_LIFE, v)
    call CreateNUnitsAtLoc( 1, Caster_UnitId(), GetOwningPlayer(c), loc,0 )
    set u = GetLastCreatedUnit()
    call CleanAttachedVars_NoSets(t)

    if ( check > dmg ) then
        call UnitDamageTargetBJ( u, v, dmg, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL )
        
        if ( count == 0 ) then
            call DarkConversion_DamageDone(t)
            call UnitWakeUpBJ( v )
        else
            call AttachInt(t,"count",count-1)
            call TimerStart(t, 1.0, true, function DarkConversion_Damage)
        endif

    else
        set a = GetUnitFacing(v)
        call KillUnit( v )
        call CreateNUnitsAtLoc( 1, DarkConversion_ZombieUnitId(l), GetOwningPlayer(c), loc,a )
        call AddSpecialEffectLocBJ( loc, "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl" )
        call DarkConversion_DamageDone(t) 
    endif

    call RemoveLocation(loc)
    set c = null
    set v = null
    set u = null
    set t = null
endfunction

function DarkConversion_Sleep takes nothing returns nothing
    local real o //target validation    
    local unit e
    local integer i = 0
    local timer t = GetExpiredTimer()
    local timer array d
    local unit c = GetAttachedUnit(t,"caster")
    local real x = GetAttachedReal(t,"x")
    local real y = GetAttachedReal(t,"y")
    local location loc = Location(x,y)
    local group g = GetAttachedGroup(t, "group")
    local integer v = GetAttachedInt(t,"level")
    local unit u 
    call CreateNUnitsAtLoc( 1, Caster_UnitId(), GetOwningPlayer(c), loc,0 )
    set u = GetLastCreatedUnit()

    call UnitAddAbilityBJ( DarkConversion_SleepSpellId(), u )
    call SetUnitAbilityLevelSwapped( DarkConversion_SleepSpellId(), u, v)

    loop
        set e = FirstOfGroup(g)
        exitwhen e == null
        set o = GetDamageFactorByOptions(c, e, DarkConversion_TargetOptions(v))
        if o > 0 then
            call IssueTargetOrderBJ( u, "sleep", e)
            set d[i]=CreateTimer()
            call AttachObject(d[i],"victim",e)
            call AttachObject(d[i],"caster",c) 
            call AttachInt(d[i],"level",v)
            if IsUnitType(e, UNIT_TYPE_HERO) then
                call AttachReal(d[i],"damage",DarkConversion_HeroDamage(v))
                call AttachInt(d[i],"count",DarkConversion_HeroDuration(v))
            else
                call AttachReal(d[i],"damage",DarkConversion_UnitDamage(v))
                call AttachInt(d[i],"count",DarkConversion_UnitDuration(v))
            endif
            call TimerStart(d[i], 1.0, true, function DarkConversion_Damage)
            set d[i] = null
            set i = i + 1            
        endif
        call GroupRemoveUnit(g,e)
    endloop
    call GroupClear(g)
    call DestroyGroup(g)
    call CleanAttachedVars_NoSets(t)
    call DestroyTimer(t)
    call UnitApplyTimedLifeBJ( 1.50, 'BTLF', u )
    set t = null
    set c = null
    set u = null
    set e = null
    set g = null
    call RemoveLocation(loc)
endfunction

function Trig_DarkConversion_Actions takes nothing returns nothing
    local unit c = GetSpellAbilityUnit()
    local integer v = GetUnitAbilityLevelSwapped(DarkConversion_SpellId(), c)
    local location loc = GetSpellTargetLoc()
    local timer t = CreateTimer()
    local group g = CreateGroup()

    call GroupAddGroup( GetUnitsInRangeOfLocAll(( DarkConversion_AoE(I2R(v)) ) , loc), g )
    call AttachObject(t,"caster",c)
    call AttachObject(t,"group",g)
    call AttachInt(t,"level",v)
    call AttachReal(t,"x",GetLocationX(loc))
    call AttachReal(t,"y",GetLocationY(loc))
    call TimerStart(t, 0.01, true, function DarkConversion_Sleep)
    call RemoveLocation(loc)
    set c = null
    set t = null
    set g = null
 
endfunction

//===========================================================================
function InitTrig_DarkConversion takes nothing returns nothing
    set gg_trg_DarkConversion = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_DarkConversion, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_DarkConversion, Condition( function Trig_DarkConversion_Conditions ) )
    call TriggerAddAction( gg_trg_DarkConversion, function Trig_DarkConversion_Actions )
endfunction