Custom complex damage system

Level 20
Joined
Jul 14, 2011
Messages
3,213
Hi! I call it this way because it's complex for me to achieve this :)

I want my units to have bonus elemental damage. So each hero has a % of of the original damage dealt in elemental damage. Example

If the unit hits 100-100 and has 15% Fire dmg, 10% water damage, should deal:

100-100 Dmg (Reduced by target unit armor) + 15 Fire Damage + 10 Water Damage...

Also give units elemental resistance, so if it's an 'Ice Lich' doesn't takes Water damage, but only fire damage bonus, and null water/lightning/poison, etc. damage types.

Any idea on how to achieve this?

BTW: I know I'll have to manage a lot of variables and else, and surely some JASS or vJASS...
 
Level 7
Joined
Apr 1, 2010
Messages
289
you'll need a Damage Detection system, and then have a hashtable that has every unit types elemental reduction, and every unit types elemental damage, and then in your trigger you would want to add checks for buffs, and abilities on units that reduce/add elemental damage.

vjass isn't necessary, jass sin't really necessary, but if you don't use jass you will a trigger that has a lot events on it that are for dead units.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Those were four words... and a dot ;). Thanks a lot Spinnaker. I'll check it out, and surely use it. I am already using Weep's GDD, should I replace that one with Bribe's, or use both?
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,141
Only two words actually, count only after ':', plus comma isn't a word but a mark ;P

Weep's GDD is good; but it's only purpose it to detect damage event (EVENT_UNIT_DAMAGED).
Bribe's one is total overkill now if you need just damage detection. If just that, Weeps will be a better option (Bribe created at first Damage Event, but latter combined it with Intuitive damage functions and Damage Modifier creating powerfull and monstrous Damage Engine).

Bribe's stuff:
- detect damage event
- damage event manipulation (enhancing/reducing etc.)
- 100% safe damage block (after last update :p)
- intuitive damage dealing meaning that, if damage from ALL your custom/ladder spells used by units in map is reduced to 0.00, system allows you to have fun with some cool stuff like: detect if damage is dealt from spell/attack source etc.

- it requires Unit Indexer; it's enables you to respond unit-enters-(Playable area) by checking OnIndex event;
- additionaly provides adventage with OnDeindex event

For advanced GUI map maker, there is basically ton of stuff you can do with that, plus those make your life much easier.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Great.. Spinnie.. but, I'm a bit confused. A bit ashamed, I don't know how to use it, though I read the instructions xD

How to set the different damage types? I want Pure, Fire, Water, Lightning, Earth. I Know there's already 3 damage listed there (Spell, DOT, and Ranged)... But I can add more there and they're already used in the trigger automatically or something?...

And, how to add specific defense types to each creep using that system?

BTW; I have already spend some time reading and thinking about this, I ask when I definitely find no solution.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Actually, a damage detection system won't work for this because you won't know whether the damage came from a spell or an attack... you'll have to have a complete custom damage system that handles melee damage, projectiles, and spells. I was going to code one at one point, but nobody would help me figure out how to find the loci of a steiner circumellipse given the triangle so that project was called off. I'd go back to coding it if someone would help me, but nobody wants to, soo.. and yes, some people knew how to do it, they just didn't want to ; p.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
But I can use temporal value increase.

Item Example
Lets say that Fire Sword deals 25% of common damage in FireDamage, and the target unit has 10% fire resistance.

- A unit Equips Fire Sword.
- Set FireDmg[ThisUnit] = (Fire Damage + (25/100))

When the unit attacks another unit:
Event - Damage is Dealt
Action - Cause Dmg_Source deal Damage = ((Damage_Dealt x (FireDmg[DmgSource] / 100)) - DamagedUnit FireResist)

If damage dealt is 100, the unit would receive 100 Physical Damage (Reduced by armor) and 15 Fire Damage.

Skill Example
Firebolt would deal 100% Fire damage.

When unit casts firebolt to same unit: I add Fire Buff to the unit.
Event - Damage is dealt
Condition - Damaged_Unit has Fire Buff.
Action - Cause Dmg_Source deal Damage = (Damage_Dealt - FireResist[DamagedUnit])
Action - Remove 'Fire Buff'

The thing is, it would deal damage twice, common damage and triggered damage (based on common damage dealt).

But, as Narogog sayd, I would need a hashtable to store all the damages and resistances of units :) And i have no idea how :D

Each damage dealt would have to check Pure, Fire, Water, Wind, Earth damage values on the attacking unit, and Fire, Water, Wind, Earth resistance values on the attacked unit.

---------------
MAAAYBEEE
---------------

I can use Piercing, Normal, Siege, Chaos and Magic damage to work as other types of damage.

Common physic attacks would be 'Hero'

Pure - Chaos
Earth - Siege
Water - Piercing
Wind - Normal
Fire - Magic

I can make Spells work on a dummy poison that adds a buff that lasts 1 second. If it's firebolt, when damage event occurs check if the unit has 'Fire' buff, deal X amount of 'Magic' damage to the unit, and remove the buff.

And, again, I would have to give every unit a elemental damage value, and every time a unit attacks, order that unit to deal each one of the damage types to the other unit... :p At least the resistances would be based on natural WC3 system

So, what do you think? How crazy am I?
 
Last edited:
Level 8
Joined
Apr 26, 2011
Messages
403
First, you need to solve this problem :
How do you give unit normal damage: 100-100 and has 15% Fire dmg, 10% water damage.

because the answer is difference depend on if you use item, spell or vJASS's hastable

---------

here is an example :
modified damage table on world editor (as well as armor table)
Pure - Chaos
Earth - Siege
Water - Piercing
Wind - Normal
Fire - Magic

then,
- every unit can only have 1 damage type (eg Earth - Siege)
- you can add 2nd damage to unit by spell (base on orb of lightning)

now:
damage table is use as "resistance table"
Orb spell = normal damage (by pass "resistance table")
attack type = element damage (base on your damage table)

with this system, you can't have more than 1 "element" damage
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Yeah, I noticed that using WC3 armor and damage system wouldn't be really efficient for complex system. Maybe for some summons and units, but not a whole RPG.

Each unit would have 8 variable values: Fire / Water / Earth / Wind damage and resistance. And every time damage is dealt the trigger would retrieve the data from a hashtable, do the formulas, and then the damage.

Normal damage would be common WC3 damage on hit. To add the element % of damage would take the damage dealt by the unit, and take the % of that damage to each element. The thing is, I don't know if the system takes the total damage dealt (before system reduction) or after the reduction.

If DamageSource has 15% Bonus Fire Damage and 10% water damage on the hashtable, then take:
- Damage dealt (100)
- add 15% (15) of fire damage
- and 10% of water damage (10)

WC3 armor system already reduces physical damage by %, then I need to reduce those 15% and 10% fire and water damage by:

- DamagedUnit Fire resistance (Lets say 20)
- Water resistance (80).
- Physycal resistance (default WC3) 13%

it would deal:
Physycal Dmg: 100 - 13% = 87
+
Fire Damage: 15 - 20% = 12
+
Water Damage: 10 - 80% = 2
=
Total Damage: 87 + 12 + 2 = 101
 
Level 8
Joined
Apr 26, 2011
Messages
403
so you already have a way to save/read 8 variable, then it should easy:
  • Trigger - unit is attacked
  • condition - none
  • action
  • // calculate "extra" damage
  • set damage_integer = 0
  • loop 1-8 and do / 1-8 is element damage type
    • set temp_integer = load your damage variable for attacking unit
    • set temp_integer2 = load your resistance variable for attacked unit
    • set temp_integer3 = calculate damage for this element type (eg temp_integer /temp_integer2 )
    • set damage_integer = damage_integer + temp_integer3
  • end loop
  • deal damage_integer to attacked unit
  • display "damage_integer" as text above attacked unit

so you don't have to worry about normal damage, (just let warcraft handle it)

all you do is write trigger to calculate element damage, and display "element damage text" above's unit head
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Exactly... just set the values in the hash and it's done... The thing is I don't know how to use hashtable.If someone could help me making one or two based on this system, I could learn and do the rest.
 
Level 8
Joined
Apr 26, 2011
Messages
403
you don't really need hastable, here is how to store/save 8 element into array :

Create 3 array :
Index_Array_boolean[0-max] // index = custom value of unit
Damage_Array_integer[0-max] // element damage in integer value
Resistance_Array_real[0-max] // element resistance in decimal value

1, Spawn a unit :

set temp_inter = count unit in game
set temp_index = 0
loop from 0 to temp_inter and do:
if Index_Array_boolean[loop_A] == false
then temp_index = loop_A // find out which index is un-used
break loop
endloop

set custom value of unit to temp_index // so you know the index for every unit

// each unit take 10 array slot to store element damage data
set temp_index = temp_index x 10
Damage_Array_integer[temp_index+0] = 10 // fire damage
Damage_Array_integer[temp_index+1] = 10 // water damage
Damage_Array_integer[temp_index+2] = 10 // wind
Damage_Array_integer[temp_index+3] = 10 // earth
Damage_Array_integer[temp_index+4] = 10 // dark
Damage_Array_integer[temp_index+5] = 10 // light
Damage_Array_integer[temp_index+6] = 10 // diease
Damage_Array_integer[temp_index+7] = 10 // poison
Damage_Array_integer[temp_index+8] = 10 // holy
Damage_Array_integer[temp_index+9] = 10 // hero

Resistance_Array_real[temp_index+0] = 0.08 // fire resist
....
Resistance_Array_real[temp_index+9] = 1.00 // hero damage resist

---------

when unit die :
set temp_integer = custom value of unit
set Index_Array_boolean[temp_integer ] = false // this index can re-use again

---------
when unit attack :
set temp_integer = custom value of unit
set temp_index = temp_integer x 10
set element_damage =0
loop from 0 to 9 and do :
set element_damage = element_damage + Damage_Array_integer[temp_index +Loop_a ] x Resistance_Array_real[temp_index + Loop_a ]
end loop
//now element_damage is total damage from element
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
So... I can create each unit Type on the map init, set those values, then remove the unit, and those values will aready work for all the units of the same type?

Do I Have to implement Bribe's unit indexer?
 
Level 8
Joined
Apr 26, 2011
Messages
403
So... I can create each unit Type on the map init, set those values, then remove the unit, and those values will aready work for all the units of the same type?

Do I Have to implement Bribe's unit indexer?

It depend on how you use index.

if you don't like custom value (eg, you may use custom value for differecce system), then you try find difference value :

inside world editor unit's stat, there are 2 other "value" :
- Total gold cost or value <-- can't remember
- level

I am not sure if there are any cap on "level", but it is safer to use first field ( Total gold cost or value, can't remember)

so you just set difference "value" for difference unit in world editor.

then on game init :
- set up Damage_Array_integer[0-max]
- set up Resistance_Array_real[0-max]
- No need to create unit and remove

now, you can use them for whole game. (as long as unit have "value")

(I can't remember what this value call because don't have world editor with me atm, it is next to unit's HP, I think it is above. and there are GUI function to read this value )
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
I'd like to save 'Unit Custom Value' for Bribes indexing system. Right now I don't have any indexing system, but I plan to use Bribe's, since a lot of spells work with it, and it proves to be efficient.

Please don't get me wrong HuanAk, I understand what you say, I just want to be sure that I am using the best system as a base. I don't want to change hundreds of unit data later just because I found a better way to do it. Hope you understand. Thanks a lot for all your help. I feel near to a solution :) thanks to you.

I'm not very good on JASS or vJASS (not at all actually, I just make small modifications to already existing systems) but I use systems like Adiktuz drop system, and The_Witcher equipment system, and -Kobas- Ability level up system, wich takes the unit raw code and adds values to it. This example is based on -Kobas- ability system, modified for units. Would something like this work somehow?


JASS:
globals
    integer array UnitID
    integer array FD         // Fire Damage
    integer array FR         // Fire Resist
    integer array WD         // Water Damage
    integer array WR         // Water Resistance
    integer array ED         // Earth Damage
    integer array ER         // Earth Resistance
    integer array WD         // Wind Damage
    integer array WR         // Wind Resistance
    integer array PD         // Pure Damage
    integer i = 0
endglobals

function UnitEle_Setup takes nothing returns nothing

    //Footman
    set i = i + 1
    set UnitID = 'h000'       
    set FD[i] = 0
    set FR[i] = 10
    set WD[i] = 0
    set WR[i] = 10
    set ED[i] = 20
    set ER[i] = 50
    set WD[i] = 0
    set WR[i] = 0
    set PD[i] 0
    
    //Archer
    set i = i + 1
    set UnitID = 'h001'       
    set FD[i] = 0
    set FR[i] = 0
    set WD[i] = 0
    set WR[i] = 50
    set ED[i] = 0
    set ER[i] = 0
    set WD[i] = 50
    set WR[i] = 50
    set PD[i] 0
    
//===========================================================================
function InitTrig_ThisTrig takes nothing returns nothing
    set gg_trg_ThisTrig = CreateTrigger(  )
    call TriggerAddAction( gg_trg_ThisTrig, function UnitEle_Setup )
endfunction

I know I can add udg_* to use them as GUI variables. I'm not very sure on how to call this data when damage is dealt...

I index my heroes under udg_Heroes[Player number]. So far, I'm not sure about how to add the elemental values to the heroes, and how to manipulate them with auras or items... I have only one hero type.
 
Last edited:
Level 20
Joined
Jul 14, 2011
Messages
3,213
Yeah, well.. thinking about the time that will take for me to set all those values to different unit types... the AuraStruct will be working for sure :D Anyway... What else do I need to make that work?

EDIT: If I'm using those values, wouldn't it be easier to use Reals instead of Integers? and, do I have to set real values to '0,00' or is just fine with '0'?

I have no idea on how to do JASS or Librarys, or functions, or scopes, nor any of that :D Just set the values with a certain logic. I really need a bit of help with this.
 
Last edited:
Level 31
Joined
Jul 10, 2007
Messages
6,306
A bit of help with it anyone?


It's better to do it yourself than to go floundering about begging for help ; ). That's what I've learned ^)^.


A long time ago, I knew nothing about programming and always wanted other people to do the programming stuff in projects because I didn't know it. Now I know it and I code whatever I want ; p.


You do the same =).
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Damn you're right... I ask for help because it's really easy to do (I know it's, can't be harder than what you said), but (at least for me) is hard to learn about hash and IDs, and a bit of JASS, and Index, and vJASS, and custom scripts, and else. But well.. I guess I can't try my frustration limits while doing this :p
 
Top