- Joined
- May 16, 2021
- Messages
- 5
Hi, I'm Bloom. Recently, I've been looking into vJass and the whole Warcraft3 coding and map making and got an idea: what if I make my custom combat system inside the game. Definitely easy for a rookie like me. So I put together some code, but the results, surprisingly, weren't ideal. It does not work, and I have no idea why.
What each lib does:
OriginCommands/SmallScriptA: This is where I defined all the custom functions I use for the later systems. Fuctions that help me get and set my custom values.
OriginDamageSystem/SmallScriptB: This is where I define what integer each value has, calculate damage, and execute said damage.
UnitValueStorage/SmallScriptC: This is where I set values to specific unit types. So it should be like: All Footmen(hfoo) have Blaze origin, Force damage type and X% Resistances.
How the code should behave: So I'm making classic rock, paper, scissors combat system with some added special elements (called origins inside the code). What I want it to do is:
A: Set origin, damage type and resistances to this all units of this unit type.
B: When damage is dealt, take origin of the attacker/caster and target, and calculate damage based on a certain logic (for example, Blaze origin unit attacking Growth origin unit should deal bonus +30% damage).
C: Show the damage as a text (works).
Problem: No values are being set, even though they should be... And many more problems, I'm trying to debug this code 3 days, and this is the simplest iteration of it... before, it at least set the values, now it doesn't even do that...
Additional info: I'm also using Bribe's Damage Engine 5.A.0.0 to register damage. I'm on the newest Warcraft3 version (unfortunately). I'm using the editor that comes with the wc3 version.
Below, I'm attaching files with the code and some additional pictures. Yes, this post is me basically asking, please run me through this thing. Or at least tell me if I'm on the right track or should never touch my keyboard again. For any advice or comment, thanks in advance.
The System In-depth:
Each unit has a Origin. They define Counters - bonus damage dealt. For example: Blaze deals bonus damage to Growth, but deals reduced damage to Tide.
Each unit deals either Force or Energy Damage.
Each unit has both Force and Energy Resistance, which reduce Force and Energy damage respectively.
The damage formula should be like this: BaseDamage the ability does * counter bonus * resistance reduction.
Edit 2.12.2025: Updated the code in the spoiler and attachments to reflect the up to date version Nichilus and Uncle helped me with.
What each lib does:
OriginCommands/SmallScriptA: This is where I defined all the custom functions I use for the later systems. Fuctions that help me get and set my custom values.
OriginDamageSystem/SmallScriptB: This is where I define what integer each value has, calculate damage, and execute said damage.
UnitValueStorage/SmallScriptC: This is where I set values to specific unit types. So it should be like: All Footmen(hfoo) have Blaze origin, Force damage type and X% Resistances.
How the code should behave: So I'm making classic rock, paper, scissors combat system with some added special elements (called origins inside the code). What I want it to do is:
A: Set origin, damage type and resistances to this all units of this unit type.
B: When damage is dealt, take origin of the attacker/caster and target, and calculate damage based on a certain logic (for example, Blaze origin unit attacking Growth origin unit should deal bonus +30% damage).
C: Show the damage as a text (works).
Problem: No values are being set, even though they should be... And many more problems, I'm trying to debug this code 3 days, and this is the simplest iteration of it... before, it at least set the values, now it doesn't even do that...
Additional info: I'm also using Bribe's Damage Engine 5.A.0.0 to register damage. I'm on the newest Warcraft3 version (unfortunately). I'm using the editor that comes with the wc3 version.
Below, I'm attaching files with the code and some additional pictures. Yes, this post is me basically asking, please run me through this thing. Or at least tell me if I'm on the right track or should never touch my keyboard again. For any advice or comment, thanks in advance.
The System In-depth:
Each unit has a Origin. They define Counters - bonus damage dealt. For example: Blaze deals bonus damage to Growth, but deals reduced damage to Tide.
Each unit deals either Force or Energy Damage.
Each unit has both Force and Energy Resistance, which reduce Force and Energy damage respectively.
The damage formula should be like this: BaseDamage the ability does * counter bonus * resistance reduction.
JASS:
library OriginCommands
globals
//This hashtable stores all the custom values of the combat system for each unittype present
//in the campaign.
hashtable CustomValues = InitHashtable()
//Child keys for CustomValues. Parent key is the specific unit's unittype ex: hfoo
constant integer KEY_ORIGIN = 0
constant integer KEY_DMGTYPE = 1
constant integer KEY_FRES = 2
constant integer KEY_ERES = 3
endglobals
//Getters
function getUOrigin takes unit u returns integer //get unit's u Origin
return LoadInteger(CustomValues, GetUnitTypeId(u), KEY_ORIGIN)
endfunction
function getUDmgType takes unit u returns integer //get unit's u DmgType
return LoadInteger(CustomValues, GetUnitTypeId(u), KEY_DMGTYPE)
endfunction
function getUFRES takes unit u returns real //get unit's u Force Resistance
return LoadReal(CustomValues, GetUnitTypeId(u), KEY_FRES)
endfunction
function getUERES takes unit u returns real //get unit's u Energy Resistance
return LoadReal(CustomValues, GetUnitTypeId(u), KEY_ERES)
endfunction
//Setters - 't' is unittype, so all unit's of one type will get the value. All Footman will have same values.
function setUOrigin takes integer t, integer origin returns nothing //set's t's origin
call SaveInteger(CustomValues, t, KEY_ORIGIN, origin)
endfunction
function setUDmgType takes integer t, integer dmgtype returns nothing //set's t's dmgtype
call SaveInteger(CustomValues, t, KEY_DMGTYPE, dmgtype)
endfunction
function setUFRes takes integer t, real fres returns nothing //set's t's force res
call SaveReal(CustomValues, t, KEY_FRES, fres)
endfunction
function setUERes takes integer t, real eres returns nothing //set's t's energy res
call SaveReal(CustomValues, t, KEY_ERES, eres)
endfunction
endlibrary
JASS:
library OriginDamageSystem initializer InitOriginDamageSystem requires DamageEngine, OriginCommands, UnitValueStorage
//META
globals
//counter Multipliers
constant real COUNTERS = 1.3 //When unit counters another
constant real COUNTERED = 0.9 //When unit is countered by another
constant real BASE = 1.0 //Normal damage without counter multipliers
constant real LDCOUNTERS = 1.15 //Light and Decay only deal +15% Dmg when countering another
constant real BUILTRES = 0.5 //Built takes -50% dmg from Force and Energy
constant real BUILTMULT = 1.5 //Siege dmg deals +50% dmg to Built origin
//origins
constant integer NORMAL = 1
constant integer PURE = 2
constant integer BLAZE = 3
constant integer TIDE = 4
constant integer GROWTH = 5
constant integer LIGHT = 6
constant integer DECAY = 7
constant integer BUILT = 8 //For special units eg.: Buildings, Battle Mechanisms, Siege Weapons, etc.
//damage types
constant integer FORCE = 1
constant integer ENERGY = 2
constant integer SIEGE = 3 //Special kind for dealing damage to Built Origin
endglobals
//Counter Damage Logic: Rock, Paper, Scissors, Nuclear Bomb
function CounterLogic takes unit src, unit tgt returns real
local integer caster = getUOrigin(src)
local integer target = getUOrigin(tgt)
local integer casterdmgtype = getUDmgType(src)
if target == BUILT then //if target is Built, then it doesn't matter what Origin is caster
if casterdmgtype == SIEGE then
return BUILTMULT
else //If caster has Siege damage type, then it gains bonus, otherwise, penalty
return BUILTRES
endif
elseif caster == NORMAL or caster == PURE then //NORMAL and PURE deal neutral damage to all,
if target != LIGHT and target != DECAY then //but are countered by LIGHT and DECAY
return COUNTERED
else
return BASE
endif
elseif caster == BLAZE then //BLAZE counters GROWTH, but is countered by TIDE
if target == GROWTH then
return COUNTERS
elseif target == TIDE then
return COUNTERED
else
return BASE
endif
elseif caster == TIDE then //TIDE counters BLAZE, but is countered by GROWTH
if target == BLAZE then
return COUNTERS
elseif target == GROWTH then
return COUNTERED
else
return BASE
endif
elseif caster == GROWTH then //GROWTH counters TIDE, but is countered by BLAZE
if target == TIDE then
return COUNTERS
elseif target == BLAZE then
return COUNTERED
else
return BASE
endif
elseif caster == LIGHT or caster == DECAY then //LIGHT and DECAY counter all (but itself) and
if caster != target then //are immune to damage penalty.
return LDCOUNTERS
else
return BASE
endif
endif
return 0.0 //unit has no Origin
endfunction
//Resistances.
function ResistanceLogic takes unit src, unit tgt returns real
local integer caster = getUDmgType(src)
local real targetFRes = getUFRES(tgt)
local real targetERes = getUERES(tgt)
local real resist = 0.0
if caster == SIEGE then
return resist
elseif caster == FORCE then
set resist = targetFRes
else
set resist = targetERes
endif
return resist
endfunction
function CalculateSystemDmg takes unit src, unit tgt returns real
local real base = udg_DamageEventAmount //DamageEngine 5.A.0.0 var, should store damage dealt
local real mult = CounterLogic(src, tgt)
local real res = ResistanceLogic(src,tgt)
local real final = 0.0
set final = base*mult*(1-res) //base damage * counter multiplier * corresponding resistance
return final
endfunction
function OnDamageTaken takes nothing returns nothing
local real final
// only run for basic attacks
if not BlzGetEventIsAttack() then
return
endif
// calculate damage
set final = CalculateSystemDmg(GetEventDamageSource(), BlzGetEventDamageTarget())
// debug log it
call BJDebugMsg("OnDamageCustom fired!")
call BJDebugMsg(R2S(final))
// apply damage
call BlzSetEventDamage(final)
endfunction
private function InitOriginDamageSystem takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DAMAGING)
call TriggerAddAction(t, function OnDamageTaken)
set t = null
// EVENT_PLAYER_UNIT_DAMAGING // "About to take damage"
// EVENT_PLAYER_UNIT_DAMAGED // "Takes damage"
endfunction
endlibrary
JASS:
library UnitValueStorage initializer InitValueStorage requires OriginCommands
function setValues takes integer u, integer origin, integer dmgtype, real fr, real er returns nothing
call setUOrigin(u, origin)
call setUDmgType(u, dmgtype)
call setUFRes(u, fr)
call setUERes(u, er)
endfunction
function InitValueStorage takes nothing returns nothing
call BJDebugMsg("ValueStorage initialized")
call setValues('hfoo', BLAZE, FORCE, 0.0, 0.0) //Footman
call BJDebugMsg("Now UnitOrigin['hfoo'] = " + I2S(UnitOrigin['hfoo']))
call setValues('hpea', GROWTH, FORCE,0.0 ,0.0) //Peasant
call BJDebugMsg("Now UnitOrigin['hpea'] = " + I2S(UnitOrigin['hpea']))
endfunction
endlibrary
Edit 2.12.2025: Updated the code in the spoiler and attachments to reflect the up to date version Nichilus and Uncle helped me with.
Attachments
-
obrázok_2025-11-30_230734221.png10.9 KB · Views: 18 -
Snímka obrazovky 2025-11-30 230604.png173.8 KB · Views: 28 -
Snímka obrazovky 2025-11-30 230641.png299.4 KB · Views: 22 -
Snímka obrazovky 2025-11-30 230651.png36.3 KB · Views: 23 -
SmallScriptA.j1.9 KB · Views: 26
-
SmallScriptC.j620 bytes · Views: 19
-
smallscriptE.j5.2 KB · Views: 25
Last edited:
