HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

A Mana Shield that doesn't use Mana

03-30-2006, 12:19 AM#1
QuatreDan
Ok, well, I happen to be one of the people who plays Defense of the Ancients Allstars (DotA).

I like thinking about how they get many of their different custom spells to work, however, lately, one has me stumped. In DotA, there is a hero with a spell that surrounds a target with a shield for a certain period of time. It absorbs a set amount of damage, and when that amount is reached, the shield bursts dealing that damage to a local area around the shielded unit.

The ability absorbs damage just like mana shield, except, as you can read, it does not consume mana in the process of absorbing damage.

Now, I would really just like to know how the heck they did that. I have always wanted to have an ability like that at my disposal for my maps. However, I've tried myself, and I'm stumped. Thanks.
03-30-2006, 01:40 AM#2
SeasonsOfLove
What they do is they store the damage as a variable, and when the unit takes damage, they subtract from that variable. When the variable runs out, the damage stops being absorbed and the spell duration ends.

If enough single-hit damage is done to kill the hero, it will kill them, before the shield gets to take its effect. There are flaws, obviously. And I don't know the coding, I'm not a mapmaker, I just know how this specific one works.
03-30-2006, 03:54 AM#3
QuatreDan
Erm, that's all fine, but you haven't explained where the damage goes. Something has to take it. It can't just vanish. They're able to get hit with attacks both normal and spells and the shield absorbs it.

Sure, one can keep track of how much damage a unit takes with a variable and do something when it reaches a certain amount, but that doesn't explain how they take no damage while the shield is active. And, FYI, they don't alter the units armor type and the unit takes absolutely no damage with the shield. Their health regeneration can be seen...regenerating, as well. So, it's not that they're holding the health points in place or anything like that. It's tricky, whatever it is.

Is this spell like old news that no one cares to explain?
03-30-2006, 10:14 AM#4
Jacek
They take damage, but it is healed instantly so you won't notice:

set life of xxx unit to ((Life of xxx unit) + Damage taken)
03-30-2006, 10:54 AM#5
harel
If you don’t want to trigger the shield just use Berserk ability and use the maximum negative value allowed in damage taken increase.
04-06-2006, 05:33 PM#6
BertTheJasser
I would say, you should have a look at shadow1500's shield template (is availiable at wc3campaigns.net)
04-06-2006, 07:49 PM#7
PipeDream
I don't believe it does a refund deal, because IceFrog notes other spells that use refunds and will not stop lethal damage. For example, bristleback's rear armor:

Collapse JASS:
function JM takes nothing returns boolean

    if(IsUnitType(GetEventDamageSource(),UNIT_TYPE_STRUCTURE))then
        return false
    endif
    return true
endfunction

function Jn takes nothing returns nothing
    local unit JN=GetTriggerUnit()
    local unit Jo=GetEventDamageSource()
    local real JO=GetUnitFacing(Jo)
    local real Jp=GetUnitFacing(JN)
    local real JP
    local real Jq
    local real JQ
    local real Jr=GetEventDamage()

    if(GetEventDamage()>10)then
        set Jq=GetUnitStateSwap(UNIT_STATE_LIFE,JN)

        if((Jp-JO)<(-180.))then
            set JP=(Jp-JO+360)
        else

            if((Jp-JO)>180.)then
                set JP=(Jp-JO-360)
            else
                set JP=(Jp-JO)
            endif
        endif

        if(RAbsBJ(JP)<=60)then
            set JQ=Jq+(GetUnitAbilityLevel(JN,'A0M3')*.15*GetEventDamage())
            call SetWidgetLife(JN,JQ)
        endif
    endif
endfunction

Abaddon's ultimate is the same sort of thing. Looks like I was wrong about aphotic shield, I think this is it:
Collapse JASS:
function nd takes nothing returns boolean

    if(IsUnitAlly(GetFilterUnit(),GetOwningPlayer(GetTriggerUnit())))then
        return false
    endif

    if(GetUnitAbilityLevelSwapped('A04R',GetFilterUnit())!=0)then
        return false
    endif

    if(IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE))then
        return false
    endif
    return true
endfunction

function nD takes nothing returns nothing
    set bj_lastCreatedUnit=CreateUnit(GetOwningPlayer(bp),'e00E',GetUnitX(GetTriggerUnit()),GetUnitY(GetTriggerUnit()),bj_UNIT_FACING)
    call UnitAddAbility(bj_lastCreatedUnit,'A0MJ')
    call SetUnitAbilityLevel(bj_lastCreatedUnit,'A0MJ',GetUnitAbilityLevel(bp,'A0MF'))
    call IssueTargetOrderById(bj_lastCreatedUnit,852587,GetEnumUnit())
endfunction

function ne takes nothing returns nothing
    local location gF=GetUnitLoc(GetTriggerUnit())
    local group F3=GetUnitsInRangeOfLocMatching(500,gF,Condition(function nd))
    call ForGroup(F3,function nD)
    call DestroyGroup(F3)
    call RemoveLocation(gF)
endfunction

function nE takes nothing returns nothing

    if(bo<GetEventDamage())then
        call SetUnitState(GetTriggerUnit(),UNIT_STATE_LIFE,GetUnitState(GetTriggerUnit(),UNIT_STATE_LIFE)+bo)
        set bo=0
        call DestroyEffect(br)
        call DisableTrigger(bS)
        set bT=true
        call ne()
    elseif(GetEventDamage()>0)then
        call SetUnitState(GetTriggerUnit(),UNIT_STATE_LIFE,GetUnitState(GetTriggerUnit(),UNIT_STATE_LIFE)+GetEventDamage())
        set bo=bo-GetEventDamage()
    endif
endfunction

function nf takes nothing returns nothing

    if(bT)then
        set bp=GetTriggerUnit()
        set bo=50+50*GetUnitAbilityLevel(GetTriggerUnit(),'A0MF')
        set br=AddSpecialEffectTargetUnitBJ("chest",GetSpellTargetUnit(),"war3mapImported\\Defensive Barrier big.mdx")
        call UnitRemoveBuffsBJ(1,GetSpellTargetUnit())
        set bS=CreateTrigger()
        call TriggerAddAction(bS,function nE)
        call TriggerRegisterUnitEvent(bS,GetSpellTargetUnit(),EVENT_UNIT_DAMAGED)
        set bT=false
        call PolledWait(20)

        if(bT==false)then
            set bT=true
            call DisableTrigger(bS)
            call DestroyEffect(br)
        endif
    endif
endfunction
04-06-2006, 07:50 PM#8
The)TideHunter(
In their triggers, they just have 2 abilities, 1 mana shield type ability, and the actual 1 you see, and can cast on people. When the spell is cast on somebody, it adds the mana shield type ability to them, activates it, and has a local real, using GetEventDamage() and some spell 1 and records it, when the real exceeds the limit, it removes the ability.

Thats the base of how it works, not 100% the same though
04-06-2006, 07:55 PM#9
Mezzer
The problem with spells like that is really detecting the actual damage, not the spell itself btw
05-02-2006, 05:12 PM#10
BertTheJasser
Collapse JASS:
native GetEventDamage takes nothing returns real
That's it. Where's the problem?
07-02-2006, 02:28 AM#11
moonliterhythm
You can't just "add mana shield and activate it" without showing an icon.. can you?
07-02-2006, 02:53 AM#12
shadow1500
Allright, first of all, its possible to block a 1000 damage spell on a 1 hp unit and it wont die (see my shield system). To block the damage a unit takes, you need to be able to detect when it takes the damage, then you use my Damage Modify function to block any amount of damage from the given damage, (so you can only block 50% for example). Once you have the stuff mentioned above, making a shield that blocks damage is easy, just store the shield value in a handle/table variable, and decrease it when damage is blocked, again my shield system does this job for you.

Second,
Quote:
They take damage, but it is healed instantly so you won't notice:

set life of xxx unit to ((Life of xxx unit) + Damage taken)
That method has 2 flaws, it doesnt block fetal damage, and it wont block all/some damage if the unit has full or almost full hp, cause the unit damaged event is activated BEFORE the damage is caused to the unit.

EDIT:
Quote:
You can't just "add mana shield and activate it" without showing an icon.. can you?
The OP asked for a shield that doesnt use mana, if you use mana shield, you have to either take away mana or take away nothing, in the latter you can just use the barserk ability with the damage recived field set to 0.
07-02-2006, 09:22 PM#13
COOLer
Basically what you want is what we did for protoss shields in PR. First you need a GC hash table for each unit. In this table you store the damage type/armor and damage (You will have to enter this data by hand) You need this for every unit that will attack your "shielded” Unit. Next set all damage types to do 0.0 on hit. For every unit on the map add an event when the unit takes damage to a single trigger using the GC hash table for unit damage type/armor and damage you can calculate what hp to set the unit that was hit. This system is very flexible as it is a damage engine.
07-02-2006, 09:47 PM#14
shadow1500
Quote:
Basically what you want is what we did for protoss shields in PR. First you need a GC hash table for each unit. In this table you store the damage type/armor and damage (You will have to enter this data by hand) You need this for every unit that will attack your "shielded” Unit. Next set all damage types to do 0.0 on hit. For every unit on the map add an event when the unit takes damage to a single trigger using the GC hash table for unit damage type/armor and damage you can calculate what hp to set the unit that was hit. This system is very flexible as it is a damage engine.
This requires too much work, loading the damage types and damage of each unit to GC is tedius work, especially if you have lots of units. My way blocks damage perfectly without any setup or whatever.
07-03-2006, 01:54 AM#15
COOLer
Quote:
Originally Posted by shadow1500
This requires too much work, loading the damage types and damage of each unit to GC is tedius work, especially if you have lots of units. My way blocks damage perfectly without any setup or whatever.
We found a way to read slks data directly in Jass but since this is not publicly available yet (and will not be for some time) you have to enter this data by hand.