• 🏆 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!

[Solved] Ability projectile won't pass through corpses.

Status
Not open for further replies.
Hey all.

I'm using kawas11's Breath of Fire spell and it seems to be working fine. However, despite being told to only damage Alive units, the spell seems to try and damage dead units as the projectiles won't go pass their corpses.

Here's the boolean that specifies it to only damage alive units:
Code:
private function DamageFilter takes unit target, player owner returns boolean
        return (UnitAlive(target)) and (not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)) and (not IsUnitType(target, UNIT_TYPE_STRUCTURE)) and (not IsUnitType(target, UNIT_TYPE_FLYING)) and (IsUnitEnemy(target, owner))
    endfunction

Thanks in advance.
 
Code:
static method onCollide takes Missile missile, unit hit returns boolean
            if DamageFilter(hit, missile.owner) then
       
                call UnitDamageTarget(missile.source, hit, missile.damage, false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
                call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, hit, DAMAGE_EFFECT_ATTACH))

This is the only one that I can find. It deals damage when the projectile comes to an impact with a unit under those specific conditions.
 
Level 39
Joined
Feb 27, 2007
Messages
5,008
I understand what you're saying, but that's not what I'm asking. UnitAlive is actually declared somewhere in the script like this: native UnitAlive takes unit whichUnit returns boolean?

I'm suggesting you reduce that filter return value to: return (UnitAlive(target)) //and (not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)) and (not IsUnitType(target, UNIT_TYPE_STRUCTURE)) and (not IsUnitType(target, UNIT_TYPE_FLYING)) and (IsUnitEnemy(target, owner)) to see if that actually makes the dead checking work (of course the other checks are important too).

Instead of UnitAlive you can use GetWidgetLife(target) > 0.405.
 
Aah, I see. Sorry, my Jass is very poor.
Here's what the native looks like: native UnitAlive takes unit id returns boolean

I'm suggesting you reduce that filter return value to: return (UnitAlive(target)) //and (not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)) and (not IsUnitType(target, UNIT_TYPE_STRUCTURE)) and (not IsUnitType(target, UNIT_TYPE_FLYING)) and (IsUnitEnemy(target, owner)) to see if that actually makes the dead checking work (of course the other checks are important too).

Instead of UnitAlive you can use GetWidgetLife(target) > 0.405.

I tried these, but still didn't work. The projectiles still won't go through corpses.
 
Level 39
Joined
Feb 27, 2007
Messages
5,008
That UnitAlive looks fine. What if you just put return false there? It shouldn't collide with anything (and also do no damage) but if for some reason it does then something is funky somewhere else. Also try that alternative life check method I put above.
 
Level 39
Joined
Feb 27, 2007
Messages
5,008
Sorry not being clear, I didn't mean modifying the unitalive native definition. I meant:
JASS:
private function DamageFilter takes unit target, player owner returns boolean
    return false //(UnitAlive(target)) and (not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)) and (not IsUnitType(target, UNIT_TYPE_STRUCTURE)) and (not IsUnitType(target, UNIT_TYPE_FLYING)) and (IsUnitEnemy(target, owner))
endfunction

//or this:
private function DamageFilter takes unit target, player owner returns boolean
    return GetWidgetLife(target) > 0.405 //and (not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)) and (not IsUnitType(target, UNIT_TYPE_STRUCTURE)) and (not IsUnitType(target, UNIT_TYPE_FLYING)) and (IsUnitEnemy(target, owner))
endfunction
 
JASS:
private function DamageFilter takes unit target, player owner returns boolean
    return false //(UnitAlive(target)) and (not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)) and (not IsUnitType(target, UNIT_TYPE_STRUCTURE)) and (not IsUnitType(target, UNIT_TYPE_FLYING)) and (IsUnitEnemy(target, owner))
endfunction

This one doesn't damage enemies and still collide with corpses.
JASS:
private function DamageFilter takes unit target, player owner returns boolean
    return GetWidgetLife(target) > 0.405 //and (not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)) and (not IsUnitType(target, UNIT_TYPE_STRUCTURE)) and (not IsUnitType(target, UNIT_TYPE_FLYING)) and (IsUnitEnemy(target, owner))
endfunction

This one damages enemies and also collide with corpses.

So I guess something funky is going on somewhere else? I could post the entire jass if you need it.
 
Level 39
Joined
Feb 27, 2007
Messages
5,008
Yes, something weird is happening elsewhere, since with false there it should never find a target and not collide with anything. I would guess in whatever missile system that spell uses there is a unitsinrange check that doesn't properly ignore dead units.
 
Level 39
Joined
Feb 27, 2007
Messages
5,008
It's not the missile system; it's a silly implementation of a global 'remove when hitting a unit or tree' flag. Right now the missile will end on any unit, not just units that match the flag. You need to replace this method:
JASS:
        static method onCollide takes Missile missile, unit hit returns boolean
            if DamageFilter(hit, missile.owner) then
      
                call UnitDamageTarget(missile.source, hit, missile.damage, false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
                call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, hit, DAMAGE_EFFECT_ATTACH))
              
            endif
          
            return REMOVE
      
        endmethod
With this:
JASS:
        static method onCollide takes Missile missile, unit hit returns boolean
            if DamageFilter(hit, missile.owner) then
      
                call UnitDamageTarget(missile.source, hit, missile.damage, false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
                call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, hit, DAMAGE_EFFECT_ATTACH))

                return REMOVE
            endif
          
            return false
      
        endmethod
 
It's not the missile system; it's a silly implementation of a global 'remove when hitting a unit or tree' flag. Right now the missile will end on any unit, not just units that match the flag. You need to replace this method:
JASS:
        static method onCollide takes Missile missile, unit hit returns boolean
            if DamageFilter(hit, missile.owner) then
     
                call UnitDamageTarget(missile.source, hit, missile.damage, false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
                call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, hit, DAMAGE_EFFECT_ATTACH))
             
            endif
         
            return REMOVE
     
        endmethod
With this:
JASS:
        static method onCollide takes Missile missile, unit hit returns boolean
            if DamageFilter(hit, missile.owner) then
     
                call UnitDamageTarget(missile.source, hit, missile.damage, false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
                call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, hit, DAMAGE_EFFECT_ATTACH))

                return REMOVE
            endif
         
            return false
     
        endmethod


Wow, it works perfectly now. Big thanks for your help!

Thread solved.
 
Status
Not open for further replies.
Top