| 07-04-2009, 10:33 PM | #1 |
Hey there, I'm making a knockback trigger for a speed map of mine and I could swear I've seen a trigger about how to check if a unit will be blocked. Right now units get knocked back straight through trees. IIRC the thread had some way of placing an item and then checking if it was still in the placed position, so I tried that and it borked (so I commented it out). My other question is, how do I properly make units 'bounce' off edges? Right now I just do set direction=direction+180, which doesn't exactly work correctly. Here's the code: JASS:globals trigger tDDKB //item iChecker=CreateItem('shwd',1,-325) endglobals scope damageDetectedKnockback initializer i private struct kData unit u real direction integer power endstruct globals private timer time=CreateTimer() private kData array kDB private integer dbIndex=-1 endglobals //private function CheckLoc takes real x, real y returns boolean //call SetItemPosition(iChecker,x,y) //call SetItemVisible(iChecker,true) //if GetItemX(iChecker)==x and GetItemY(iChecker)==y then //call SetItemVisible(iChecker,false) //return true //endif //call SetItemVisible(iChecker,false) //return false //endfunction private function p takes nothing returns nothing local integer index=0 local kData tempDat local real x local real y loop exitwhen index>dbIndex set tempDat=kDB[index] set x=GetUnitX(tempDat.u)+tempDat.power*Cos(tempDat.direction*bj_DEGTORAD) set y=GetUnitY(tempDat.u)+tempDat.power*Sin(tempDat.direction*bj_DEGTORAD) if IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY)==false then // and CheckLoc(x,y) then call SetUnitX(tempDat.u,x) call SetUnitY(tempDat.u,y) else set tempDat.direction=tempDat.direction+180 set tempDat.power=tempDat.power*3/4 endif set tempDat.power=tempDat.power-1 if GetUnitState(tempDat.u,UNIT_STATE_LIFE)<1 then set tempDat.power=tempDat.power-1 endif if GetUnitMoveSpeed(tempDat.u)<270 then set tempDat.power=tempDat.power-1 endif if tempDat.power<0 then call tempDat.destroy() set kDB[index]=kDB[dbIndex] set dbIndex=dbIndex-1 if dbIndex==-1 then call PauseTimer(time) endif endif set index=index+1 endloop endfunction private function a takes nothing returns nothing local kData tempDat local unit source=GetEventDamageSource() local unit target=GetTriggerUnit() local location lS=GetUnitLoc(source) local location lT=GetUnitLoc(target) local real direction=AngleBetweenPoints(lS,lT) local real power=15+GetEventDamage()/2 if power>65 then set power=65 endif if GetUnitTypeId(source)=='hrif' or GetUnitTypeId(source)=='hgyr' or GetUnitTypeId(source)=='hgry' or GetUnitTypeId(source)=='hdhw' then set power=power/2 endif if IsUnitType(target,UNIT_TYPE_FLYING)!=true and IsUnitType(target,UNIT_TYPE_STRUCTURE)!=true then set tempDat=kData.create() set tempDat.u=target set tempDat.direction=direction set tempDat.power=R2I(power) set dbIndex=dbIndex+1 set kDB[dbIndex]=tempDat if dbIndex==0 then call TimerStart(time,.03,true,function p) endif endif call RemoveLocation(lS) call RemoveLocation(lT) endfunction private function i takes nothing returns nothing set tDDKB=CreateTrigger() call TriggerAddAction(tDDKB,function a) endfunction endscope Thanks, |
| 07-04-2009, 11:10 PM | #2 |
You mean this? Bouncing is more tricky, though. You need to consider the possibility of bouncing off unpathable terrain as well as destructables, which makes the code kind of long and complicated. |
| 07-05-2009, 12:35 AM | #3 |
Yes! That's what I was looking for. Thanks much. I just want the unit to bounce properly regardless of what's stopped it (in the else after it was checked for walkability, I want it to bounce regardless of what stopped it) Could you show me the math I would use? |
| 07-05-2009, 12:45 AM | #4 |
Last time I did something like this was over three years ago. Aside from terrible amounts of gamecache usage, the principles of that spell should still be useful. |
