| 10-23-2007, 02:05 PM | #1 |
My charge spell still goes over cliffs. Using "IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY)" only stops the unit from charging over water. How do I stop my charging hero from going over cliffs? |
| 10-23-2007, 02:54 PM | #2 |
You'll have to post some code... |
| 10-23-2007, 07:23 PM | #3 |
One problem may be that IsTerrainPathable returns false if it is pathable and true if it isn't. Just stick a "not" in front of it: if not(IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY)) then |
| 10-23-2007, 08:49 PM | #4 |
I don't know if reading my code is the fastest way to find my answer, but I now posted it at the bottom of this post. The important part is in the function Phase2Update, which is this line: JASS:
if collidingdestructables > 0 or not IsTerrainPathable(newx+collisionradius*str.maxxvelocity/maxvelocity,newy+collisionradius*str.maxyvelocity/maxvelocity,PATHING_TYPE_WALKABILITY) then
//hero has crashed into something.
call End(str) JASS:scope Rampage globals //public constant integer SpellId = 'A009' public constant integer SpellId = 'A04Q' public constant integer ShockwaveId = 'h005' private constant real moveinterval = 0.02 private constant real accelmod = 0.01 private constant real collisionradius = 150.0 private constant real switchdistance = 400.0 private constant real minimumrange = switchdistance + 100.0 private constant real shockahead = 60.0 private constant real slowmod = 300.0/PointsPerMeter private constant real dmgmod = 50.0 private constant real crashslow = 150.0/PointsPerMeter private constant real slowduration = 2.0 private constant real maxvelocity = 20.0*PointsPerMeter private constant string slowmodel = "Abilities\\Spells\\Orc\\StasisTrap\\StasisTotemTarget.mdl" endglobals struct Rampage_Struct unit hero unit shockwave timer updatetimer = CreateTimer() real runningtime = 0 real maxxvelocity real maxyvelocity real targetx real targety real switchx real switchy real facing real slow real dmg real vx0 real vy0 endstruct private function End takes Rampage_Struct str returns nothing call PauseUnit(str.hero,false) call FlushHandleLocals(str.updatetimer) call PauseTimer(str.updatetimer) call DestroyTimer(str.updatetimer) call ResetUnitAnimation(str.hero) call RemoveUnit(str.shockwave) call SetUnitBusy(str.hero,false) call Msg("RampageEnd") endfunction private function Phase2Collision takes nothing returns nothing local unit subject = GetEnumUnit() local unit hero = udg_tempunit local real subjectx = GetWidgetX(subject) local real subjecty = GetWidgetY(subject) local integer hi = H2I(hero) local string ss = I2S(H2I(subject)) call SetUnitPosition(subject, subjectx, subjecty) if GetStoredInteger(MainGamecache,ss,"slowedbymamak") != hi then call DestroyEffectWait(AddSpecialEffectTarget(slowmodel, subject, "overhead"), slowduration) call SlowUnit(subject,udg_tempreal,slowduration) call UnitDamageTargetNew(hero,subject,udg_tempreal2, 2, 0, 0) call StoreInteger(MainGamecache,ss,"slowedbymamak",hi) call TriggerSleepAction(slowduration) if GetStoredInteger(MainGamecache,ss,"slowedbymamak") == hi then call StoreInteger(MainGamecache,ss,"slowedbymamak",0) endif endif set hero = null set subject = null endfunction private function Phase2CollisionWrapper takes nothing returns nothing call ExecuteFunc(SCOPE_PRIVATE+"Phase2Collision") endfunction private function CollisionCondition takes nothing returns boolean if TargetTypeConditionEasy(GetFilterUnit(),udg_tempunit,0,1,0,0,0,0,0,0,0,0,2) then call Msg("collider = "+GetUnitName(GetFilterUnit())) endif return TargetTypeConditionEasy(GetFilterUnit(),udg_tempunit,0,1,0,0,0,0,0,0,0,0,2) endfunction private function DestructableCollision takes nothing returns nothing set udg_tempint = udg_tempint + 1 endfunction private function Phase2Update takes nothing returns nothing local timer updatetimer = GetExpiredTimer() local Rampage_Struct str = GetHandleInt(updatetimer,"struct") local real herox = GetWidgetX(str.hero) local real heroy = GetWidgetY(str.hero) local real vmod local real xvelocity local real yvelocity local integer groupsize local real newx local real newy local group collisiongroup = CreateGroup() local location newheroloc local integer collidingdestructables local real dx local real dy set str.runningtime = str.runningtime+moveinterval set vmod = (1-Pow(bj_E,-accelmod*str.runningtime)) set xvelocity = str.vx0+(str.maxxvelocity-str.vx0)*vmod set yvelocity = str.vy0+(str.maxyvelocity-str.vy0)*vmod set dx = xvelocity*moveinterval set dy = yvelocity*moveinterval set newx = herox + dx set newy = heroy + dy set newheroloc = Location(newx,newy) //call Msg("RampagePhase2Update") set udg_tempunit = str.hero set udg_tempint = 0 call EnumDestructablesInCircleBJ(collisionradius,newheroloc,function DestructableCollision) set collidingdestructables = udg_tempint if collidingdestructables > 0 or not IsTerrainPathable(newx+collisionradius*str.maxxvelocity/maxvelocity,newy+collisionradius*str.maxyvelocity/maxvelocity,PATHING_TYPE_WALKABILITY) then //crash call End(str) call SlowUnit(str.hero,crashslow,slowduration) call DestroyEffectWait(AddSpecialEffectTarget(slowmodel, str.hero, "overhead"), slowduration) call Msg("RampageCrash2") else call SetUnitCor(str.hero, newx, newy) call SetUnitCor(str.shockwave, GetWidgetX(str.shockwave) + dx, GetWidgetY(str.shockwave) + dy) endif set udg_tempunit = str.hero set udg_tempreal = str.slow set udg_tempreal2 = str.dmg call GroupEnumUnitsInRange(collisiongroup,newx,newy,collisionradius,Condition(function CollisionCondition)) call ForGroup(collisiongroup, function Phase2CollisionWrapper) if xvelocity > 0 then if newx > str.targetx then //rampageend call End(str) else //maybe no phase2 if yvelocity > 0 then if newy > str.targety then //rampageend call End(str) else //no phase2 endif else if newy < str.targety then //rampageend call End(str) else //no phase2 endif endif endif else if newx < str.targetx then //rampageend call End(str) else //maybe no phase2 if yvelocity > 0 then if newy > str.targety then //rampageend call End(str) else //no phase2 endif else if newy < str.targety then //rampageend call End(str) else //no phase2 endif endif endif endif call DestroyGroup(collisiongroup) set collisiongroup = null call RemoveLocation(newheroloc) set newheroloc = null set updatetimer = null endfunction private function Phase2Start takes Rampage_Struct str, real herox, real heroy returns nothing set str.shockwave = CreateUnit(Player(15), ShockwaveId, herox + shockahead*Cos(str.facing), heroy + shockahead*Sin(str.facing), str.facing*bj_RADTODEG) call TimerStart(str.updatetimer, moveinterval, true, function Phase2Update) call Msg("RampagePhase2Start") endfunction private function Phase1Update takes nothing returns nothing local timer updatetimer = GetExpiredTimer() local Rampage_Struct str = GetHandleInt(updatetimer,"struct") local real herox = GetWidgetX(str.hero) local real heroy = GetWidgetY(str.hero) local real vmod local real xvelocity local real yvelocity local real newx local real newy local integer groupsize local group collisiongroup = CreateGroup() local location newheroloc local integer collidingdestructables set str.runningtime = str.runningtime+moveinterval set vmod = (1-Pow(bj_E,-accelmod*str.runningtime)) set xvelocity = str.vx0+(str.maxxvelocity-str.vx0)*vmod set yvelocity = str.vy0+(str.maxyvelocity-str.vy0)*vmod set newx = herox + xvelocity*moveinterval set newy = heroy + yvelocity*moveinterval set newheroloc = Location(newx,newy) //call Msg("RampageUpdate") set udg_tempunit = str.hero set udg_tempint = 0 call EnumDestructablesInCircleBJ(collisionradius,newheroloc,function DestructableCollision) set collidingdestructables = udg_tempint if collidingdestructables == 0 then set collisiongroup = CreateGroup() call GroupEnumUnitsInRange(collisiongroup,newx,newy,collisionradius,Condition(function CollisionCondition)) set groupsize = CountUnitsInGroup(collisiongroup) call DestroyGroup(collisiongroup) set collisiongroup = null endif if groupsize > 0 or collidingdestructables > 0 or not IsTerrainPathable(newx+collisionradius*str.maxxvelocity/maxvelocity,newy+collisionradius*str.maxyvelocity/maxvelocity,PATHING_TYPE_WALKABILITY) then call End(str) call SlowUnit(str.hero,crashslow,slowduration) call DestroyEffectWait(AddSpecialEffectTarget(slowmodel, str.hero, "overhead"), slowduration) call Msg("RampageCrash1") else call SetUnitCor(str.hero, newx, newy) if xvelocity > 0 then if newx > str.switchx then //phase2 call Phase2Start(str,herox,heroy) else //maybe no phase2 if yvelocity > 0 then if newy > str.switchy then //phase2 call Phase2Start(str,herox,heroy) else //no phase2 endif else if newy < str.switchy then //phase2 call Phase2Start(str,herox,heroy) else //no phase2 endif endif endif else if newx < str.switchx then //phase2 call Phase2Start(str,herox,heroy) else //maybe no phase2 if yvelocity > 0 then if newy > str.switchy then //phase2 call Phase2Start(str,herox,heroy) else //no phase2 endif else if newy < str.switchy then //phase2 call Phase2Start(str,herox,heroy) else //no phase2 endif endif endif endif endif call RemoveLocation(newheroloc) set newheroloc = null set updatetimer = null endfunction public function Starts takes nothing returns nothing local Rampage_Struct str = Rampage_Struct.create() local player p = GetTriggerPlayer() local location targetloc = GetSpellTargetLoc() local real herox local real heroy local real castdistancesqr local real movespeed local real wait local real levelmod local real herolevelmod local real cosfacing local real sinfacing set str.hero = GetTriggerUnit() set levelmod = SquareRoot(GetUnitAbilityLevel(str.hero,SpellId)) set herolevelmod = SquareRoot(I2R(GetHeroLevel(str.hero))) set str.dmg = dmgmod * levelmod * herolevelmod set str.slow = slowmod * levelmod / herolevelmod set movespeed = GetUnitMoveSpeed(str.hero) set herox = GetWidgetX(str.hero) set heroy = GetWidgetY(str.hero) set str.targetx = GetLocationX(targetloc) set str.targety = GetLocationY(targetloc) set str.facing = Angle(herox, heroy, str.targetx, str.targety) set cosfacing = Cos(str.facing) set sinfacing = Sin(str.facing) set str.vx0 = cosfacing*movespeed set str.vy0 = sinfacing*movespeed set str.maxxvelocity = cosfacing*maxvelocity*PointsPerMeter set str.maxyvelocity = sinfacing*maxvelocity*PointsPerMeter set str.switchx = herox + cosfacing*switchdistance set str.switchy = heroy + sinfacing*switchdistance set castdistancesqr = DistanceSqr(herox,heroy,str.targetx,str.targety) call SetHandleInt(str.updatetimer,"struct",str) call SetUnitBusy(str.hero,true) call TriggerSleepAction(0) call PauseUnit(str.hero, true) call SetUnitFacing(str.hero,str.facing*bj_RADTODEG) //I DUNNO. call SetUnitAnimationByIndex(str.hero,1) set wait = GetSmallestAngleAbs(str.facing,GetUnitFacing(str.hero)*bj_DEGTORAD)/turnspeed call TriggerSleepAction(wait) call SetUnitAnimationByIndex(str.hero,3) call PlaySoundOnUnitBJ(gg_snd_Shockwave, 100, str.hero) call TimerStart(str.updatetimer, moveinterval, true, function Phase1Update) call RemoveLocation(targetloc) set targetloc = null set p = null call Msg("RampageStart") endfunction public function Cast takes nothing returns nothing local unit hero = GetTriggerUnit() local player p = GetTriggerPlayer() local real facing local real herox = GetWidgetX(hero) local real heroy = GetWidgetY(hero) local location targetloc = GetSpellTargetLoc() local real targetx = GetLocationX(targetloc) local real targety = GetLocationY(targetloc) local real castdistancesqr = DistanceSqr(herox,heroy,targetx,targety) local real mindistancesqr = minimumrange*minimumrange if castdistancesqr < mindistancesqr then call SimError(p,"Cannot cast within minimum range") call IssueImmediateOrder(hero,"stop") endif call RemoveLocation(targetloc) set targetloc = null set hero = null set p = null endfunction endscope //Rampage |
| 10-23-2007, 10:32 PM | #5 |
please use jass tags. Code:
[jass] call PolledWait(1.00)[/jass] JASS:call PolledWait(1.00) |
