Faust
You can change this now in User CP.
- Reaction score
- 123
Now, you really need some patience if you try to help me - and please, do
I have a hero with an ability, which when activated, fades the hero out, moves into the target position, and fades it in ("slowly"), by setting it's alpha value.
This hero has another, PASSIVE ability, that constantly changes the GREEN and BLUE values of it, to make it red ("slowly")
The redding stops when the hero is "fully charged", and when it delivers an attack, the redding starts all over again.
Since you can't detect a unit's alpha or RGB, I need to use the same struct for both of these abilities.
The hero also gains "pain", when it takes damage, it is a key element in the hero.
Here I have the codes (brace yourselves!) :
1: PainGainLossStrike:
Sorry sorry, I know it's not very easy to read, and know which function does what (added comments)
Here is the Shift ability(no, there is no reason or difference in using structB):
Now, the problems:
1) LossHandler stops working after like 40-60 seconds, it displays nothing.
2) When I use Shift, it works well, except it starts spamming my screen with error messages: Double free of type : PGL (first in some kind of purple, then white), and SetColor stops working forever, and next time I try using Shift it doesn't do anything.
3) I tried merging the two codes (just a wild idea)
Looked like this:
And got an error:
PainGainLossStrike___A is not a member of PGL
on the line:
(well, dat.PainGainLossStrike___A in the error window)
and I don't know why
Please help me T_T
I have a hero with an ability, which when activated, fades the hero out, moves into the target position, and fades it in ("slowly"), by setting it's alpha value.
This hero has another, PASSIVE ability, that constantly changes the GREEN and BLUE values of it, to make it red ("slowly")
The redding stops when the hero is "fully charged", and when it delivers an attack, the redding starts all over again.
Since you can't detect a unit's alpha or RGB, I need to use the same struct for both of these abilities.
The hero also gains "pain", when it takes damage, it is a key element in the hero.
Here I have the codes (brace yourselves!) :
1: PainGainLossStrike:
JASS:
scope PainGainLossStrike initializer Init
struct PGL
//! runtextmacro PUI()
unit hero
integer G = 255
integer B = 255
integer A = 255
real percent
real pain = 0
timer clock = CreateTimer()
timer clockS = CreateTimer()
timer clock2 = CreateTimer()
integer ticks = 0
integer ticks2 = 0
real tx
real ty
unit target
method onDestroy takes nothing returns nothing
set .hero = null
call PauseTimer(.clock2)
call DestroyTimer(.clock2)
call PauseTimer(.clock)
call DestroyTimer(.clock)
endmethod
endstruct
private function PC2 takes nothing returns boolean
return GetUnitTypeId(GetTriggerUnit()) == 039;H005039;
endfunction
private function Death takes nothing returns nothing //The hero gains more pain when dies (not important right now)
local PGL dat = PGL[GetTriggerUnit()]
if GetUnitAbilityLevel(GetTriggerUnit(), 039;A01Y039;) > 0 then
set dat.pain = dat.pain + 200 + 50 * GetUnitAbilityLevel(GetTriggerUnit(), 039;A01Y039;)
endif
endfunction
private function SetColor takes nothing returns nothing //This is the function that sets the GREEN and BLUE of the hero
local PGL dat = GetTimerStructA(GetExpiredTimer())
local integer ticks = GetUnitAbilityLevel(dat.hero, 039;A01Y039;) + 8
call BJDebugMsg("RUNS")
set dat.G = dat.G - ticks * 1
set dat.B = dat.B - ticks * 1
set dat.percent = dat.percent + 0.01
call SetUnitVertexColor(dat.hero, 255, dat.G, dat.B, dat.A)
set dat.ticks = dat.ticks + 1
if dat.ticks < ticks then
call BJDebugMsg("First true")
if GetUnitAbilityLevel(dat.hero, 039;B00J039;) > 0 then
call BJDebugMsg("Second true")
call TimerStart(dat.clock2, 0.1, false, function SetColor)
else
call BJDebugMsg("Second false")
call TimerStart(dat.clock2, 0.4, false, function SetColor)
endif
else
call BJDebugMsg("FULLY CHARGED")
endif
call BJDebugMsg(I2S(dat.G))
call BJDebugMsg(I2S(dat.B))
call BJDebugMsg(R2S(dat.percent))
call BJDebugMsg(R2S(dat.pain))
endfunction
private function Gain takes nothing returns nothing // The hero gains pain with this
local PGL dat = PGL[GetTriggerUnit()]
if dat != 0 then
if GetUnitAbilityLevel(dat.hero, 039;A01Y039;) > 0 then
set dat.pain = dat.pain + R2I((((GetEventDamage() * I2R(GetUnitAbilityLevel(dat.hero, 039;A01Y039;))) / GetUnitState(GetTriggerUnit(), UNIT_STATE_MAX_LIFE)) * 100.00))
endif
endif
endfunction
private function LossHandler takes nothing returns nothing // This displays the current amount of "pain" the hero has each two seconds with a floating text
local PGL dat = GetTimerStructA(GetExpiredTimer())
local texttag painamount
local force owner = CreateForce()
call ForceAddPlayer(owner, GetOwningPlayer(dat.hero))
if dat.pain >= 2 then
set dat.pain = dat.pain - 2
set painamount = CreateTextTagUnitBJ("|c" + ColorTextTag(GetOwningPlayer(dat.hero)) + R2S(dat.pain), dat.hero, -50, 10, 100, 100, 100, 0)
else
set dat.pain = 0
set painamount = CreateTextTagUnitBJ("|c" + ColorTextTag(GetOwningPlayer(dat.hero)) + "No pain", dat.hero, -50, 10, 100, 100, 100, 0)
endif
call SetTextTagVelocityBJ(painamount, 20, 270)
call SetTextTagPermanent(painamount, false)
call SetTextTagLifespan(painamount, 1.99)
call SetTextTagFadepoint(painamount, 1.99)
if IsPlayerInForce(GetLocalPlayer(), owner) != true then
call SetTextTagVisibility(painamount, false)
endif
call DestroyForce(owner)
set owner = null
endfunction
private function Damager takes nothing returns nothing // This gives the bonus damage (percentage of it's stored pain)
local PGL dat = PGL[GetEventDamageSource()]
if dat == 0 then
return
endif
if GetUnitAbilityLevel(GetEventDamageSource(), 039;A01Y039;) > 0 then
call PauseTimer(dat.clock2)
call SetUnitVertexColor(dat.hero, 255, 255, 255, dat.A)
call PlaySoundOnUnitBJ(gg_snd_Shout, 100, GetEventDamageSource())
call DisableTrigger(GetTriggeringTrigger())
call UnitDamageTarget(GetEventDamageSource(), GetTriggerUnit(), dat.pain * dat.percent, true, false, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
set dat.pain = dat.pain - dat.pain * dat.percent
set dat.percent = 0
set dat.ticks = 0
set dat.G = 255
set dat.B = 255
if dat.pain < 2 then
set dat.pain = 0
endif
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Orc\\FeralSpirit\\feralspiritdone.mdl", GetTriggerUnit(), "chest"))
call EnableTrigger(GetTriggeringTrigger())
call TimerStart(dat.clock, 0.01, false, function SetColor)
endif
endfunction
private function Reg takes nothing returns nothing //registers when this type of hero is bought in the tavern, and learns it's key ability automatically
local PGL dat = PGL.create ()
set dat.hero = GetTriggerUnit()
set dat.pain = 10
call BJDebugMsg(GetUnitName(dat.hero))
if PC2() != true then
call dat.destroy()
else
call SelectHeroSkill(GetTriggerUnit(), 039;A01Y039;)
call SetTimerStructA(dat.clock, dat)
call SetTimerStructA(dat.clock2, dat)
call TimerStart(dat.clock2, 0.1, false, function SetColor)
call TimerStart(dat.clock, 2, true, function LossHandler)
set PGL[dat.hero] = dat
endif
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger tgain = CreateTrigger()
local trigger tdeath = CreateTrigger()
local trigger treg = CreateTrigger()
local trigger tdmg = CreateTrigger()
local region rectRegion = CreateRegion()
local playerunitevent pue = EVENT_PLAYER_UNIT_DEATH
call TriggerRegisterAnyUnitDamaged(tgain)
call TriggerRegisterAnyUnitDamaged(tdmg)
call RegionAddRect(rectRegion, bj_mapInitialPlayableArea)
call TriggerRegisterEnterRegion(treg, rectRegion, Condition(function SafeFilt))
call TriggerAddAction(tdeath, function Death)
call TriggerAddAction(treg, function Reg)
call TriggerAddAction(tgain, function Gain)
call TriggerAddAction(tdmg, function Damager)
call TriggerAddCondition(tgain, Condition (function PC2))
endfunction
endscope
Sorry sorry, I know it's not very easy to read, and know which function does what (added comments)
Here is the Shift ability(no, there is no reason or difference in using structB):
JASS:
scope Shift initializer Init
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 039;A01S039;
endfunction
private function Handler2 takes nothing returns nothing //Fades the hero in
local PGL dat = GetTimerStructB(GetExpiredTimer())
if dat.ticks2 >= 25 then
set dat.A = 255
call dat.destroy()
else
set dat.ticks2 = dat.ticks2 + 1
set dat.A = dat.A + 11
call SetUnitVertexColor(dat.hero, 255, dat.G, dat.B, dat.A)
endif
endfunction
private function Handler takes nothing returns nothing // Fades the hero out
local PGL dat = GetTimerStructB(GetExpiredTimer())
local integer level = GetUnitAbilityLevel(dat.hero, 039;A01S039;)
local real damage = 15 * I2R(level)
if dat.target != null then
set dat.tx = GetUnitX(dat.target)
set dat.ty = GetUnitY(dat.target)
endif
if dat.ticks2 == 25 then
call PauseTimer(dat.clockS)
set dat.ticks2 = 0
call SetTimerStructB(dat.clockS, dat)
call TimerStart(dat.clockS, 0.01, true, function Handler2)
call SetUnitPosition(dat.hero, dat.tx, dat.ty)
if dat.target != null then
call IssueTargetOrder(dat.hero, "attack", dat.target)
call UnitDamageTarget(dat.hero, dat.target, damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
endif
call SetUnitTimeScale(dat.hero, 1.00)
else
set dat.ticks2 = dat.ticks2 + 1
set dat.A = dat.A - 11
call SetUnitVertexColor(dat.hero, 255, dat.G, dat.B, dat.A)
endif
endfunction
private function A takes nothing returns nothing // checks if the target was a unit or just ground
local PGL dat = PGL[GetTriggerUnit()]
local location tpoint
call SetTimerStructB(dat.clockS, dat)
call TimerStart(dat.clockS, 0.01, true, function Handler)
set dat.target = GetSpellTargetUnit()
if dat.target == null then
set tpoint = GetSpellTargetLoc()
set dat.tx = GetLocationX(tpoint)
set dat.ty = GetLocationY(tpoint)
else
set dat.tx = GetUnitX(dat.target)
set dat.ty = GetUnitY(dat.target)
endif
call RemoveLocation(tpoint)
set tpoint = null
call SetUnitTimeScale(dat.hero, .25)
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
local playerunitevent pue = EVENT_PLAYER_UNIT_SPELL_EFFECT
set udg_tx = trig
call TriggerRegisterAnyUnitEvent(udg_tx, pue)
call TriggerAddCondition(trig, Condition(function Conditions))
call TriggerAddAction(trig, function A)
endfunction
endscope
Now, the problems:
1) LossHandler stops working after like 40-60 seconds, it displays nothing.
2) When I use Shift, it works well, except it starts spamming my screen with error messages: Double free of type : PGL (first in some kind of purple, then white), and SetColor stops working forever, and next time I try using Shift it doesn't do anything.
3) I tried merging the two codes (just a wild idea)
Looked like this:
JASS:
scope PainGainLossStrike initializer Init
struct PGL
//! runtextmacro PUI()
unit hero
integer G = 255
integer B = 255
integer A = 255
real percent
real pain = 0
timer clock = CreateTimer()
timer clockS = CreateTimer()
timer clock2 = CreateTimer()
integer ticks = 0
integer ticks2 = 0
real tx
real ty
unit target
method onDestroy takes nothing returns nothing
set .hero = null
call PauseTimer(.clock2)
call DestroyTimer(.clock2)
call PauseTimer(.clock)
call DestroyTimer(.clock)
endmethod
endstruct
private function PC2 takes nothing returns boolean
return GetUnitTypeId(GetTriggerUnit()) == 039;H005039;
endfunction
private function Death takes nothing returns nothing
local PGL dat = PGL[GetTriggerUnit()]
if GetUnitAbilityLevel(GetTriggerUnit(), 039;A01Y039;) > 0 then
set dat.pain = dat.pain + 200 + 50 * GetUnitAbilityLevel(GetTriggerUnit(), 039;A01Y039;)
endif
endfunction
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 039;A01S039;
endfunction
private function Handler2 takes nothing returns nothing
local PGL dat = GetTimerStructB(GetExpiredTimer())
if dat.ticks2 >= 25 then
set dat.A = 255
call dat.destroy()
else
set dat.ticks2 = dat.ticks2 + 1
set dat.A = dat.A + 11
call SetUnitVertexColor(dat.hero, 255, dat.G, dat.B, dat.A)
endif
endfunction
private function Handler takes nothing returns nothing
local PGL dat = GetTimerStructB(GetExpiredTimer())
local integer level = GetUnitAbilityLevel(dat.hero, 039;A01S039;)
local real damage = 15 * I2R(level)
if dat.target != null then
set dat.tx = GetUnitX(dat.target)
set dat.ty = GetUnitY(dat.target)
endif
if dat.ticks2 == 25 then
call PauseTimer(dat.clockS)
set dat.ticks2 = 0
call SetTimerStructB(dat.clockS, dat)
call TimerStart(dat.clockS, 0.01, true, function Handler2)
call SetUnitPosition(dat.hero, dat.tx, dat.ty)
if dat.target != null then
call IssueTargetOrder(dat.hero, "attack", dat.target)
call UnitDamageTarget(dat.hero, dat.target, damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
endif
call SetUnitTimeScale(dat.hero, 1.00)
else
set dat.ticks2 = dat.ticks2 + 1
set dat.A = dat.A - 11
call SetUnitVertexColor(dat.hero, 255, dat.G, dat.B, dat.A)
endif
endfunction
private function A takes nothing returns nothing
local PGL dat = PGL[GetTriggerUnit()]
local location tpoint
call SetTimerStructB(dat.clockS, dat)
call TimerStart(dat.clockS, 0.01, true, function Handler)
set dat.target = GetSpellTargetUnit()
if dat.target == null then
set tpoint = GetSpellTargetLoc()
set dat.tx = GetLocationX(tpoint)
set dat.ty = GetLocationY(tpoint)
else
set dat.tx = GetUnitX(dat.target)
set dat.ty = GetUnitY(dat.target)
endif
call RemoveLocation(tpoint)
set tpoint = null
call SetUnitTimeScale(dat.hero, .25)
endfunction
private function SetColor takes nothing returns nothing
local PGL dat = GetTimerStructA(GetExpiredTimer())
local integer ticks = GetUnitAbilityLevel(dat.hero, 039;A01Y039;) + 8
call BJDebugMsg("RUNS")
set dat.G = dat.G - ticks * 1
set dat.B = dat.B - ticks * 1
set dat.percent = dat.percent + 0.01
call SetUnitVertexColor(dat.hero, 255, dat.G, dat.B, dat.A)
set dat.ticks = dat.ticks + 1
if dat.ticks < ticks then
call BJDebugMsg("First true")
if GetUnitAbilityLevel(dat.hero, 039;B00J039;) > 0 then
call BJDebugMsg("Second true")
call TimerStart(dat.clock2, 0.1, false, function SetColor)
else
call BJDebugMsg("Second false")
call TimerStart(dat.clock2, 0.4, false, function SetColor)
endif
else
call BJDebugMsg("FULLY CHARGED")
endif
call BJDebugMsg(I2S(dat.G))
call BJDebugMsg(I2S(dat.B))
call BJDebugMsg(R2S(dat.percent))
call BJDebugMsg(R2S(dat.pain))
endfunction
private function Gain takes nothing returns nothing
local PGL dat = PGL[GetTriggerUnit()]
if dat != 0 then
if GetUnitAbilityLevel(dat.hero, 039;A01Y039;) > 0 then
set dat.pain = dat.pain + R2I((((GetEventDamage() * I2R(GetUnitAbilityLevel(dat.hero, 039;A01Y039;))) / GetUnitState(GetTriggerUnit(), UNIT_STATE_MAX_LIFE)) * 100.00))
endif
endif
endfunction
private function LossHandler takes nothing returns nothing
local PGL dat = GetTimerStructA(GetExpiredTimer())
local texttag painamount
local force owner = CreateForce()
call ForceAddPlayer(owner, GetOwningPlayer(dat.hero))
if dat.pain >= 2 then
set dat.pain = dat.pain - 2
set painamount = CreateTextTagUnitBJ("|c" + ColorTextTag(GetOwningPlayer(dat.hero)) + R2S(dat.pain), dat.hero, -50, 10, 100, 100, 100, 0)
else
set dat.pain = 0
set painamount = CreateTextTagUnitBJ("|c" + ColorTextTag(GetOwningPlayer(dat.hero)) + "No pain", dat.hero, -50, 10, 100, 100, 100, 0)
endif
call SetTextTagVelocityBJ(painamount, 20, 270)
call SetTextTagPermanent(painamount, false)
call SetTextTagLifespan(painamount, 1.99)
call SetTextTagFadepoint(painamount, 1.99)
if IsPlayerInForce(GetLocalPlayer(), owner) != true then
call SetTextTagVisibility(painamount, false)
endif
call DestroyForce(owner)
set owner = null
endfunction
private function Damager takes nothing returns nothing
local PGL dat = PGL[GetEventDamageSource()]
if dat == 0 then
return
endif
if GetUnitAbilityLevel(GetEventDamageSource(), 039;A01Y039;) > 0 then
call PauseTimer(dat.clock2)
call SetUnitVertexColor(dat.hero, 255, 255, 255, dat.A)
call PlaySoundOnUnitBJ(gg_snd_Shout, 100, GetEventDamageSource())
call DisableTrigger(GetTriggeringTrigger())
call UnitDamageTarget(GetEventDamageSource(), GetTriggerUnit(), dat.pain * dat.percent, true, false, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
set dat.pain = dat.pain - dat.pain * dat.percent
set dat.percent = 0
set dat.ticks = 0
set dat.G = 255
set dat.B = 255
if dat.pain < 2 then
set dat.pain = 0
endif
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Orc\\FeralSpirit\\feralspiritdone.mdl", GetTriggerUnit(), "chest"))
call EnableTrigger(GetTriggeringTrigger())
call TimerStart(dat.clock, 0.01, false, function SetColor)
endif
endfunction
private function Reg takes nothing returns nothing
local PGL dat = PGL.create ()
set dat.hero = GetTriggerUnit()
set dat.pain = 10
call BJDebugMsg(GetUnitName(dat.hero))
if PC2() != true then
call dat.destroy()
else
call SelectHeroSkill(GetTriggerUnit(), 039;A01Y039;)
call SetTimerStructA(dat.clock, dat)
call SetTimerStructA(dat.clock2, dat)
call TimerStart(dat.clock2, 0.1, false, function SetColor)
call TimerStart(dat.clock, 2, true, function LossHandler)
set PGL[dat.hero] = dat
endif
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
local trigger tgain = CreateTrigger()
local trigger tdeath = CreateTrigger()
local trigger treg = CreateTrigger()
local trigger tdmg = CreateTrigger()
local region rectRegion = CreateRegion()
local playerunitevent pue = EVENT_PLAYER_UNIT_DEATH
call TriggerRegisterAnyUnitDamaged(tgain)
call TriggerRegisterAnyUnitDamaged(tdmg)
call RegionAddRect(rectRegion, bj_mapInitialPlayableArea)
call TriggerRegisterEnterRegion(treg, rectRegion, Condition(function SafeFilt))
call TriggerAddAction(tdeath, function Death)
call TriggerAddAction(treg, function Reg)
call TriggerAddAction(tgain, function Gain)
call TriggerAddAction(tdmg, function Damager)
call TriggerAddCondition(tgain, Condition (function PC2))
set pue = EVENT_PLAYER_UNIT_SPELL_EFFECT
set udg_tx = trig
call TriggerRegisterAnyUnitEvent(udg_tx, pue)
call TriggerAddCondition(trig, Condition(function Conditions))
call TriggerAddAction(trig, function A)
endfunction
endscope
And got an error:
PainGainLossStrike___A is not a member of PGL
on the line:
JASS:
call SetUnitVertexColor(dat.hero, 255, dat.G, dat.B, dat.A)
(well, dat.PainGainLossStrike___A in the error window)
and I don't know why
Please help me T_T