• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] Making a spell system.

Status
Not open for further replies.
Level 14
Joined
Jun 27, 2008
Messages
1,325
If you only want the different damage types (fire, frost arcane,..) to be used in spells you dont even need a DDS system (DDS Systems are for detecting normal attack).

Just write a new function that replaces the normal "DamageTarget" function, for example:
JASS:
function damageTargetCustom takes unit attacker, unit target, real damage, integer damageType returns nothing
    // here you can apply damage to "target" by checking what damage type "damageType" is and how much resistance the target has.

Then you can simply call this function in your triggered spells. If something changes in your damage formula you only have to alter this single function, kinda like a bottleneck where all your spell damage is applied through.

To avoid conflicts with DDS systems i recommend not actually applying damage, but rather adjusting the target units hp.

I once did something similar (function "unitDamageTarget"):
https://github.com/muzzel/APT/blob/master/wurst/src/damage/DamageHandler.wurst
However in my case the custom damage function covered ALL types of damage, so both the custom triggered spells and the normal attacks (a DDS system which detects the attacks is included along with an aggro system).

This isnt the simplest solution, but the most flexible. If you want full control, ALWAYS apply damage yourself (namely via such a bottleneck function) and use DDS only to detect attacks, but make sure the attacks dont reduce hp (block them / use gameplay constants). This requires you to trigger ALL your spells, if you use standard spells this approach will break.
 
Level 11
Joined
Oct 11, 2012
Messages
711
Just write a new function that replaces the normal "DamageTarget" function, for example:
JASS:
function damageTargetCustom takes unit attacker, unit target, real damage, integer damageType returns nothing
    // here you can apply damage to "target" by checking what damage type "damageType" is and how much resistance the target has.

Then you can simply call this function in your triggered spells. If something changes in your damage formula you only have to alter this single function, kinda like a bottleneck where all your spell damage is applied through.

Thanks for the reply, but I don't quite get it. :( Please see the following example:
JASS:
//Define the function
function damageTargetCustom takes unit attacker, unit target, real damage, integer damageType returns nothing
    if damageType == 1 then
        call UnitDamageTarget(attacker,target,damage,true,false,ATTACK_TYPE_CHAOS,damageType,null)
    endif
endfunction

//Doing damage by using the customed function
function run takes nothing returns nothing
    call damageTargetCustom(att,TARGET,100.,DAMAGE_TYPE_FIRE)
endfunction

//Modified the damage
function a takes nothing returns nothing
    if damageType == 1 then
        //increase damage
    endif
endfunction

function InitTrig_test takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterUnitEvent( t, TARGET, EVENT_UNIT_DAMAGED )
    call TriggerAddCondition(t,Condition(function a))
    set t = null
endfunction

Is this what you mean, muzzel?

@Bannar, I will check that, thnx.
 
Level 14
Joined
Jun 27, 2008
Messages
1,325
Something like this: (free hand, dont have a WE here..)

JASS:
// Define your custom damage types (just an example, you can use keys or structs or whatever...):
globals
    constant integer CUSTOM_DAMAGE_FIRE = 1
    constant integer CUSTOM_DAMAGE_ARCANE = 2
    ...
endglobals

//Define the function
function damageTargetCustom takes unit attacker, unit target, real damage, integer damageType returns nothing
    local real resistance = 0.
    if damageType == CUSTOM_DAMAGE_FIRE then
        set resistance = getFireResistance(target)
    else if damageType == CUSTOM_DAMAGE_ARCANE then
        set resistance = getArcaneResistance(target)
    endif
    call setUnitLife(target, getUnitLife(target) - damage * (1 - resistance))
    // Create a floating text with damage value or whatever...
endfunction

//Modify the damage
function a takes nothing returns nothing
    call damageTargetCustom(att,TARGET,100.,CUSTOM_DAMAGE_FIRE)
endfunction

//You will further need to somehow save the resistance values for your units.
function getFireResistance(unit target) returns real
    return 0.15 // if all units are supposed to have 15% fire resistance
endfunction
function getArcaneResistance(unit target) returns real
    return LoadReal(myHash, GetHandleId(target), ...) // maybe read resistance values from a hashtable or whatever...
endfunction

function InitTrig_test takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterUnitEvent( t, TARGET, EVENT_UNIT_DAMAGED )
    call TriggerAddCondition(t,Condition(function a))
    set t = null
endfunction

Storing the resistance values for all units is a different task. You will need to think about how you want to do that. Ive seen several Jass systems here on THW which manage custom stats, but honestly i didnt like any of them. You can take a look at what i wrote for Wurst, its a rather extensive solution but maybe a bit too complicated for this simple task:
http://www.hiveworkshop.com/forums/lab-715/wurst-stathandler-249028/ or https://github.com/muzzel/APT/tree/master/wurst/lib/StatHandler

Note: this system is used for the .getStat(Stat.<statname>) calls in the code i linked in my last post. target.getStat(Stat.ARMOR), target.getStat(Stat.EVA), ...
 
Level 11
Joined
Oct 11, 2012
Messages
711
Something like this: (free hand, dont have a WE here..)

JASS:
// Define your custom damage types (just an example, you can use keys or structs or whatever...):
globals
    constant integer CUSTOM_DAMAGE_FIRE = 1
    constant integer CUSTOM_DAMAGE_ARCANE = 2
    ...
endglobals

//Define the function
function damageTargetCustom takes unit attacker, unit target, real damage, integer damageType returns nothing
    local real resistance = 0.
    if damageType == CUSTOM_DAMAGE_FIRE then
        set resistance = getFireResistance(target)
    else if damageType == CUSTOM_DAMAGE_ARCANE then
        set resistance = getArcaneResistance(target)
    endif
    call setUnitLife(target, getUnitLife(target) - damage * (1 - resistance))
    // Create a floating text with damage value or whatever...
endfunction

//Modify the damage
function a takes nothing returns nothing
    call damageTargetCustom(att,TARGET,100.,CUSTOM_DAMAGE_FIRE)
endfunction

//You will further need to somehow save the resistance values for your units.
function getFireResistance(unit target) returns real
    return 0.15 // if all units are supposed to have 15% fire resistance
endfunction
function getArcaneResistance(unit target) returns real
    return LoadReal(myHash, GetHandleId(target), ...) // maybe read resistance values from a hashtable or whatever...
endfunction

function InitTrig_test takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterUnitEvent( t, TARGET, EVENT_UNIT_DAMAGED )
    call TriggerAddCondition(t,Condition(function a))
    set t = null
endfunction

Storing the resistance values for all units is a different task. You will need to think about how you want to do that. Ive seen several Jass systems here on THW which manage custom stats, but honestly i didnt like any of them. You can take a look at what i wrote for Wurst, its a rather extensive solution but maybe a bit too complicated for this simple task:
http://www.hiveworkshop.com/forums/lab-715/wurst-stathandler-249028/ or https://github.com/muzzel/APT/tree/master/wurst/lib/StatHandler

Note: this system is used for the .getStat(Stat.<statname>) calls in the code i linked in my last post. target.getStat(Stat.ARMOR), target.getStat(Stat.EVA), ...

Thanks for the detailed example! :D I will take your advice.

+Rep to you and Bannar.
 
Status
Not open for further replies.
Top