HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Effect happening before it should

10-25-2006, 07:21 PM#1
aidan_124
This trigger should:
When the unit attacks and has a specific ability:
Calculates the time the projectile/missile takes to reach the target (both speeds are 900) then has a 20% chance to add an effect and deal damage to the unit. However the effect etc. is triggering before the projectile hits the unit. Also no effect occurs when the units hp is too low.
Collapse JASS:
function Conductance_Conditions takes nothing returns boolean
return GetUnitTypeId(GetAttacker()) == 'H000'
endfunction

function Conductance_Damage takes nothing returns nothing
local string s = I2S(H2I(GetExpiredTimer()))
local gamecache gc = udg_Ability_Cache
local unit a = I2U(GetStoredInteger(gc,s,"attacker"))
local unit t = I2U(GetStoredInteger(gc,s,"attacked"))
local integer l = GetUnitAbilityLevel(a,'A001')
local integer u
set u = GetRandomInt(1,100)
call DisplayTextToForce(bj_FORCE_ALL_PLAYERS,"debug")
if u <= 20 then
call AddSpecialEffectTarget("Abilities\\Spells\\Orc\\Purge\\PurgeBuffTarget.mdl" ,t,"origin")
call UnitDamageTarget(a,t,50*l,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_MAGIC,null)
endif
set gc = null
set s = null
set a = null
set t = null
endfunction

function Conductance_angle takes real x, real y, real ux, real uy returns real
return Atan2((uy-y),(ux-x))
endfunction

function Conductance_distance takes real x, real y, real ux, real uy returns real
local real y_distance
local real x_distance
local real distance
set y_distance = (uy-y)
set x_distance = (ux-x)
set distance = SquareRoot((Pow(y_distance,2) + Pow(x_distance,2)))
return distance
endfunction

function Conductance_projectile_speed takes nothing returns real
//set the projectile speed of your unit here
return 900.00
endfunction

function Conductance_projectile_time takes unit u, unit p returns real
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real ux = GetUnitX(p)
local real uy = GetUnitY(p)
local real dist = Conductance_distance(x,y,ux,uy)
local real speed = 900
local real time
set time = dist/speed
return time
endfunction

function Conductance_Actions takes nothing returns nothing
local integer i
local timer t  = CreateTimer()
local gamecache gc = udg_Ability_Cache
local string s = I2S(H2I(t))
local unit a = GetAttacker()
local unit b = GetAttackedUnitBJ()
set i = GetRandomInt(1,5)
if GetUnitAbilityLevel(a,'A001')>0 then                              
call StoreInteger(gc,s,"attacker",U2I(GetAttacker()))
call StoreInteger(gc,s,"attacked",U2I(GetAttackedUnitBJ()))
call TimerStart(t,Conductance_projectile_time(a,b),false,function Conductance_Damage)
endif
set t = null
call DestroyTimer(t)
set s = null
set gc= null
set a = null
set b = null
endfunction

function InitTrig_Conductance takes nothing returns nothing
local trigger gg_trg_Conductance
set gg_trg_Conductance = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(gg_trg_Conductance,EVENT_PLAYER_UNIT_ATTACKED)
call TriggerAddCondition(gg_trg_Conductance,Condition(function Conductance_Conditions))
call TriggerAddAction(gg_trg_Conductance,function Conductance_Actions)
endfunction
Any ideas to what needs fixing in this trigger...excluding using distance between points.
10-25-2006, 07:27 PM#2
Captain Griffen
Unit is attacked occurs before attack, and thus projectile, are actually initiated.
10-25-2006, 07:40 PM#3
darkwulfv
Quote:
time the projectile/missile takes to reach the target
Perhaps adding a wait at the beginning (after local calls) equal to the time it takes for the projectile to hit? That way, the trigger will be stalled until it needs to continue.

Collapse JASS:
(a,t,50*l,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_MAGIC,null)
and just for the sake of simple reading, put a space after each comma. (just so its easier for others to read.)
10-25-2006, 08:07 PM#4
Thunder_Eye
You cant really get the time for the projectile from when its created to when it hits the target because the target might move which thus increases the time.
10-25-2006, 08:20 PM#5
Chuckle_Brother
Put in a BJDebugMsg to test the distance/time returned by your Conductance_projectile_time function and tell us what it says.
10-25-2006, 09:10 PM#6
aidan_124
Would it be easier just to use JASS to program the projectile? Then i could use the functions to calculate the wait time?
Also here are some values in format (distance - time):
268.540 - 0.298
160.281 - 0.178
622.552 - 0.692
643.400 - 0.715

Edit: Also@ Thunder Eye...0.05 s due to movement is barely noticeable...unfortunately killing the unit before the projectile has spwaned is :/
Edit2: Also just realized...missile arc also has problems so seems to me the method with jass is the only possible method?
10-25-2006, 10:02 PM#7
Anitarf
Quote:
Originally Posted by aidan_124
Would it be easier just to use JASS to program the projectile?
No, it would be easier just to use JASS to detect when the projectile hits via the unit takes damage event.
10-25-2006, 10:22 PM#8
Vexorian
unless it is a homing projectile
10-26-2006, 08:55 AM#9
DioD
Collapse JASS:
function SleepX takes real I returns integer
call TriggerSleepAction(I)
return 0
endfunction

use functions like this for w8 before locals

Collapse JASS:
local integer X = SleepX(10)
10-26-2006, 09:31 AM#10
aidan_124
Only problem is if i use the UnitTakeDamage event then it would need to be able to detect if it were an attack or a spell, and is there any way to do that?
10-26-2006, 10:06 AM#11
The)TideHunter(
Just dont use a wait, and use a homing projectile, use a timer instead, update the projectile until it reaches your target, when it does, just fire off a trigger/timer for the stuff after the wait.
10-26-2006, 10:24 AM#12
aidan_124
Could you explain how to do this in JASS?
I would assume that you intiate the projectile like this?
Collapse JASS:
function projectile takes unit u, unit v returns nothing
local real ux = GetUnitX(u)
local real uy = GetUnitY(u)
local real uz = GetUnitFlyHeight(u)
local real vx = GetUnitX(v)
local real vy = GetUnitY(v)
local real vz = GetUnitFlyHeight(v)
local effect e
call AddSpecialEffect("model", ux, uy)
set e = GetLastCreatedEffectBJ()
//moving projectile here to vx,vy,vz and gradually change z height
endfunction
However, I can't find a way to move a special effect exluding CS :(
Edit: Or would you create a dummy unit with locust ability and add the projectile to the unit and move the unit from one unit to the other?
10-26-2006, 12:14 PM#13
Rising_Dusk
Quote:
However, I can't find a way to move a special effect exluding CS :(
You can't, it has to be a unit with either an attached model of an FX or with the base model of an FX.
You can then move the unit around and simulate the projectile.

Also --
Collapse JASS:
call AddSpecialEffect("model", ux, uy)
set e = GetLastCreatedEffectBJ()
Could just be set e = AddSpecialEffect("model", ux, uy)
10-26-2006, 01:01 PM#14
The)TideHunter(
Quote:
Originally Posted by Rising_Dusk
also --
Collapse JASS:
call AddSpecialEffect("model", ux, uy)
set e = GetLastCreatedEffectBJ()
Could just be set e = AddSpecialEffect("model", ux, uy)

Yea, watch out for that, even though you should do it on one line, i'll warn you that AddSpecialEffect does not set GetLastCreatedEffectBJ, so it will not return the correct effect.
Its just a native, when GetLastCreatedEffectBJ is not.

native AddSpecialEffect takes string modelName, real x, real y returns effect
So using GetLastCreatedEffectBJ only works for when you use either of the functions:

Collapse JASS:
function AddSpecialEffectLocBJ takes location where, string modelName returns effect
    set bj_lastCreatedEffect = AddSpecialEffectLoc(modelName, where)
    return bj_lastCreatedEffect
endfunction

or

Collapse JASS:
function AddSpecialEffectTargetUnitBJ takes string attachPointName, widget targetWidget, string modelName returns effect
    set bj_lastCreatedEffect = AddSpecialEffectTarget(modelName, targetWidget, attachPointName)
    return bj_lastCreatedEffect
endfunction

Notice these, and only these 2 functions set bj_lastCreatedEffect, and GetLastCreatedEffectBJ() just returns that.

Collapse JASS:
function GetLastCreatedEffectBJ takes nothing returns effect
    return bj_lastCreatedEffect
endfunction
10-26-2006, 02:03 PM#15
aidan_124
I spent a while thinking and other than 1 problem this should work...i think, just make sure i understand timers etc. properly:
Collapse JASS:
function Projectile takes nothing returns boolean
return GetUnitTypeId(GetAttacker()) == 'H000'
endfunction

function Projectile_angle takes real x, real y, real ux, real uy returns real
return Atan2((uy-y),(ux-x))
endfunction

function Projectile_distance takes real x, real y, real ux, real uy returns real
local real y_distance
local real x_distance
local real distance
set y_distance = (uy-y)
set x_distance = (ux-x)
set distance = SquareRoot((Pow(y_distance,2) + Pow(x_distance,2)))
return distance
endfunction

function Projectile_move takes unit u, unit v, boolean b returns nothing
local real ux = GetUnitX(u)
local real uy = GetUnitY(u)
local real uz = GetUnitFlyHeight(u)
local real vx = GetUnitX(v)
local real vy = GetUnitY(v)
local real vz = GetUnitFlyHeight(v)
local real dz = vz-uz
local real dist = Projectile_distance(ux,uy,vx,vy)
local real ang = Projectile_angle(ux,uy,vx,vy)
local gamecache gc = udg_Ability_Cache
local real dur = GetStoredReal(gc,"proj","dur")
if dur<10 then
if GetStoredBoolean(gc,"proj","set") == false then
    call StoreReal(gc,"proj","x_dist",vx-ux)
    call StoreReal(gc,"proj","y_dist",vy-uy)
    call StoreReal(gc,"proj","z_dist",dz)
endif
    call SetUnitPositionLoc(u,Location(ux+GetStoredReal(gc,"proj","x_dist")/10.00,uy+GetStoredReal(gc,"proj","x_dist")/10.00))
    call SetUnitFlyHeight(u,uz+GetStoredReal(gc,"proj","z_dist")/10,100)
    call StoreBoolean(gc,"proj","set",true)
    call StoreReal(gc,"proj","dur",dur+1)
endif
endfunction

function Projectile_move_init takes unit u, unit v, boolean b returns nothing
local real ux = GetUnitX(u)
local real uy = GetUnitY(u)
local real uz = GetUnitFlyHeight(u)
local real vx = GetUnitX(v)
local real vy = GetUnitY(v)
local real vz = GetUnitFlyHeight(v)
local real dz = vz-uz
local real dist = Projectile_distance(ux,uy,vx,vy)
local real ang = Projectile_angle(ux,uy,vx,vy)
local real time = dist/900.00
local gamecache gc = udg_Ability_Cache
local timer t = CreateTimer()

call TimerStart(t, time/10.00, true, function Projectile_move(u,v,b))
call StoreBoolean(gc,"proj","set",false)
//rest of actions when projectile reaches
endfunction

function Projectile_actions takes nothing returns nothing
local unit u = GetAttacker()
local unit v  = GetAttackedUnitBJ()
local unit a
local real ux = GetUnitX(u)
local real uy = GetUnitY(u)
local real uz = GetUnitFlyHeight(u)
local real vx = GetUnitX(v)
local real vy = GetUnitY(v)
local real vz = GetUnitFlyHeight(v)

local integer i = GetUnitAbilityLevel(u,'A001')
local integer r = GetRandomInt(1,100)           
set a = CreateUnit(Player(15), 'uloc', ux, uy, Projectile_angle(ux, uy, vx, vy))
if i > 1 and r <= 20 then
    call AddSpecialEffectTarget("Abilities\\Spells\\Orc\\LightningBolt\\LightningBoltMissile.mdl",a,"origin")
    call Projectile_move_init(a,v,true)
else             
    call AddSpecialEffectTarget("Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl" ,a,"origin")
    call Projectile_move_init(a,v,false)
endif


endfunction