library CombatSystem requires UnitIndexing, TimerUtils, CombatSnippets
globals
private unit attacker = null
private unit defender = null
private integer FIRST_STRIKE = 'A00A'
private integer LAST_STRIKE = 'A00D'
private integer CHARGE = 'A00G'
private integer BLOCK = 'A00N'
private integer PARRY = 'A00M'
private integer HOLD_YOUR_GROUND = 'A01E'
private integer TRAMPLE = 'A00H'
endglobals
function Combat_Attacking takes unit u, unit t returns nothing
local integer i = 1 /// positive = attacker goes first. negative = defender first///
local integer uid = GetUnitId(u)
local integer tid = GetUnitId(t)
local boolean openingstrike
local integer d
local boolean charge
local boolean trample
local boolean block
local boolean parry
local boolean hold
call IssueImmediateOrder(u, "stop")
call DisplayTextToForce(GetPlayersAll(), "Combat_Attacking is running")
///test
set Unit_Attacks[uid] = GetHeroStr(u, true)
set Unit_Attacks[tid] = GetHeroStr(t, true)
///
///Setting who attacks first: ///
if GetUnitAbilityLevel(t, HOLD_YOUR_GROUND) > 0 then
if IsUnitClassified(u, "mounted") and ( GetUnitAbilityLevel(u, TRAMPLE) == 0 or Unit_Charging[uid] == false) then ///If unit didnt move, he has no trample
set i = i - 2
set hold = true
elseif GetUnitAbilityLevel(u, TRAMPLE) > 0 then
set trample = true
endif
endif
if GetUnitAbilityLevel(t, FIRST_STRIKE) > 0 then
if GetUnitAbilityLevel(u, FIRST_STRIKE) == 0 then
set i = i - 2
endif
endif
if GetUnitAbilityLevel(u, LAST_STRIKE) > 0 and Unit_Charging[uid] == false then ///checking if the unit has moved. If he did, Last Strike has no effect
if GetUnitAbilityLevel(t, LAST_STRIKE) == 0 then
set i = i - 2
endif
endif
if GetUnitAbilityLevel(u, CHARGE) > 0 and Unit_Charging[uid] then
set charge = true
endif
if GetUnitAbilityLevel(t, BLOCK) > 0 then
set block = true
endif
if GetUnitAbilityLevel(u, PARRY) > 0 then
set parry = true
endif
///Order has been made///
if i> 0 then
call DisplayTextToForce(GetPlayersAll(), "Order has been made, attacker goes first")
else
call DisplayTextToForce(GetPlayersAll(), "Order has been made, defender goes first")
endif
if i > 0 then ///attacker first, defender second
///The attacker:
if Unit_Attacks[uid] > 0 then //And is unit alive??? (for later)
if Unit_Attacks[uid] == GetHeroStr(u, true) then
set openingstrike = true
endif
call SetUnitAnimation(u, "attack")
set d = GetRandomInt(Unit_DamageMin[uid], Unit_DamageMax[uid]) - Unit_Armor[tid]
if openingstrike and charge then
set d = d + 1
endif
if openingstrike and block then
set d = d - 1
///SPECIAL EFFECT - BLOCK
endif
if hold then
set d = d - 1
endif
call UnitDamageTarget(u, t, I2R(d), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
set Unit_Attacks[uid] = Unit_Attacks[uid] - 1
set openingstrike = false
call DisplayTextToForce(GetPlayersAll(), "Attacker hit for: "+I2S(d)+" damage!")
endif
///The defender:
if Unit_Attacks[tid] > 0 then ///(and is unit alive?) for later
call SetUnitAnimation(t, "attack")
set d = GetRandomInt(Unit_DamageMin[tid], Unit_DamageMax[tid]) - Unit_Armor[uid]
if parry then
set d = d - 1
///SPECIAL EFFECT - PARRY
endif
if hold then
set d = d + 1
endif
call UnitDamageTarget(t, u, I2R(d), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
set Unit_Attacks[tid] = Unit_Attacks[tid] - 1
call DisplayTextToForce(GetPlayersAll(), "Defender hit for: "+I2S(d)+" damage!")
endif
else
///The defender:
if Unit_Attacks[tid] > 0 then // is unit alive?
call SetUnitAnimation(t, "attack")
set d = GetRandomInt(Unit_DamageMin[tid], Unit_DamageMax[tid]) - Unit_Armor[uid]
if hold then
set d = d + 1
endif
call UnitDamageTarget(t, u, I2R(d), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
set Unit_Attacks[tid] = Unit_Attacks[tid] - 1
call DisplayTextToForce(GetPlayersAll(), "Defender hit for: "+I2S(d)+" damage!")
endif
///The Attacker:
if Unit_Attacks[uid] > 0 then //is unit alive?
call SetUnitAnimation(u, "attack")
set d = GetRandomInt(Unit_DamageMin[uid], Unit_DamageMax[uid]) - Unit_Armor[tid]
if hold then
set d = d - 1
endif
call UnitDamageTarget(u, t, I2R(d), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
set Unit_Attacks[uid] = Unit_Attacks[uid] - 1
call DisplayTextToForce(GetPlayersAll(), "Attacker hit for: "+I2S(d)+" damage!")
endif
endif
endfunction
private function callback takes nothing returns nothing
local timer T = GetExpiredTimer()
if IsUnitInRange(attacker, defender, 70.) then
call ReleaseTimer(T)
call DisplayTextToForce( GetPlayersAll(), "Unit is in range now" )
call Combat_Attacking(attacker, defender)
set attacker = null
set defender = null
endif
endfunction
function Combat_MoveUnit takes unit u, unit t returns nothing
local timer T = NewTimer()
if GetUnitAbilityLevel(t, BLOCK) > 0 then
call SetUnitAnimation(t, "stand defend")
endif
call DisplayTextToForce( GetPlayersAll(), "Unit is moving" )
call IssuePointOrder(u, "move", GetUnitX(t), GetUnitY(t))
set attacker = u
set defender = t
call TimerStart(T, 0.05, true, function callback)
set u = null
set t = null
endfunction
endlibrary