| 10-25-2006, 07:21 PM | #1 |
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. 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 |
| 10-25-2006, 07:27 PM | #2 |
Unit is attacked occurs before attack, and thus projectile, are actually initiated. |
| 10-25-2006, 07:40 PM | #3 | |
Quote:
JASS:(a,t,50*l,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_MAGIC,null) |
| 10-25-2006, 08:07 PM | #4 |
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 |
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 |
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 | |
Quote:
|
| 10-25-2006, 10:22 PM | #8 |
unless it is a homing projectile |
| 10-26-2006, 08:55 AM | #9 |
JASS:function SleepX takes real I returns integer call TriggerSleepAction(I) return 0 endfunction use functions like this for w8 before locals JASS:local integer X = SleepX(10) |
| 10-26-2006, 09:31 AM | #10 |
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 |
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 |
Could you explain how to do this in JASS? I would assume that you intiate the projectile like this? 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 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 | |
Quote:
You can then move the unit around and simulate the projectile. Also -- JASS:call AddSpecialEffect("model", ux, uy) set e = GetLastCreatedEffectBJ() |
| 10-26-2006, 01:01 PM | #14 | |
Quote:
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: JASS:function AddSpecialEffectLocBJ takes location where, string modelName returns effect set bj_lastCreatedEffect = AddSpecialEffectLoc(modelName, where) return bj_lastCreatedEffect endfunction or 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. JASS:function GetLastCreatedEffectBJ takes nothing returns effect return bj_lastCreatedEffect endfunction |
| 10-26-2006, 02:03 PM | #15 |
I spent a while thinking and other than 1 problem this should work...i think, just make sure i understand timers etc. properly: 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 |
