3203 end; |
3203 end; |
3204 |
3204 |
3205 procedure doStepPortal(Gear: PGear); |
3205 procedure doStepPortal(Gear: PGear); |
3206 var |
3206 var |
3207 iterator, conPortal: PGear; |
3207 iterator, conPortal: PGear; |
3208 s, acptRadius, itdist, nx, ny, pspeed, nspeed: hwFloat; |
3208 s, acptRadius, nx, ny, ox, oy, poffs, noffs, pspeed, nspeed: hwFloat; |
3209 noTrap, hasdxy: Boolean; |
3209 noTrap, hasdxy: Boolean; |
3210 begin |
3210 begin |
3211 doPortalColorSwitch(); |
3211 doPortalColorSwitch(); |
3212 |
3212 |
3213 // destroy portal if ground it was attached too is gone |
3213 // destroy portal if ground it was attached too is gone |
3238 // check all gears for stuff to port through |
3238 // check all gears for stuff to port through |
3239 iterator := nil; |
3239 iterator := nil; |
3240 while true do |
3240 while true do |
3241 begin |
3241 begin |
3242 |
3242 |
|
3243 // iterate through GearsList |
3243 if iterator = nil then |
3244 if iterator = nil then |
3244 iterator := GearsList // start |
3245 iterator := GearsList |
3245 else |
3246 else |
3246 iterator := iterator^.NextGear; |
3247 iterator := iterator^.NextGear; |
3247 // iterate through GearsList |
3248 |
3248 |
3249 // end of list? |
3249 if iterator = nil then |
3250 if iterator = nil then |
3250 break; |
3251 break; |
3251 // end of list |
|
3252 |
3252 |
3253 // don't port portals or other gear that wouldn't make sense |
3253 // don't port portals or other gear that wouldn't make sense |
3254 if (iterator^.Kind = gtPortal) or (iterator^.Kind = gtRope) or (iterator^.PortalCounter > 20) then |
3254 if (iterator^.Kind = gtPortal) or (iterator^.Kind = gtRope) or (iterator^.PortalCounter > 20) then |
3255 continue; |
3255 continue; |
3256 |
3256 |
3258 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) |
3258 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) |
3259 and (iterator = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = |
3259 and (iterator = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = |
3260 gtRope) then |
3260 gtRope) then |
3261 continue; |
3261 continue; |
3262 |
3262 |
|
3263 // check if gear fits through portal |
3263 if (iterator^.Radius > Gear^.Radius) then |
3264 if (iterator^.Radius > Gear^.Radius) then |
3264 continue; |
3265 continue; |
3265 // sorry, you're too fat! |
3266 |
3266 |
3267 // this is the max range we accept incoming gears in |
3267 // this is the range we accept incoming gears in |
|
3268 acptRadius := Int2hwFloat(iterator^.Radius+Gear^.Radius); |
3268 acptRadius := Int2hwFloat(iterator^.Radius+Gear^.Radius); |
3269 |
3269 |
|
3270 // too far away? |
3270 if (iterator^.X < Gear^.X - acptRadius) |
3271 if (iterator^.X < Gear^.X - acptRadius) |
3271 or (iterator^.X > Gear^.X + acptRadius) |
3272 or (iterator^.X > Gear^.X + acptRadius) |
3272 or (iterator^.Y < Gear^.Y - acptRadius) |
3273 or (iterator^.Y < Gear^.Y - acptRadius) |
3273 or (iterator^.Y > Gear^.Y + acptRadius) then |
3274 or (iterator^.Y > Gear^.Y + acptRadius) then |
3274 continue; |
3275 continue; |
3275 // too far away! |
|
3276 |
3276 |
3277 hasdxy := ((iterator^.dX.QWordValue <> 0) or (iterator^.dY.QWordValue <> 0)); |
3277 hasdxy := ((iterator^.dX.QWordValue <> 0) or (iterator^.dY.QWordValue <> 0)); |
3278 |
3278 |
|
3279 // won't port stuff that moves away from me! |
3279 if hasdxy and not (Gear^.dX*iterator^.dX + Gear^.dY*iterator^.dY).isNegative then |
3280 if hasdxy and not (Gear^.dX*iterator^.dX + Gear^.dY*iterator^.dY).isNegative then |
3280 continue; |
3281 continue; |
3281 // won't port stuff that moves away from me! |
3282 |
3282 |
3283 if (iterator^.Kind <> gtCake) then |
3283 // wow! good candidate there, let's see if the distance really is small enough! |
3284 begin |
3284 itdist := Distance(Gear^.X-iterator^.X,Gear^.Y-iterator^.Y); |
3285 // wow! good candidate there, let's see if the distance and direction is okay! |
3285 if (itdist > acptRadius) then |
3286 if hasdxy then |
3286 continue; |
3287 begin |
|
3288 s := int2hwFloat(iterator^.Radius) / Distance(iterator^.dX, iterator^.dY); |
|
3289 ox:= iterator^.X + s * iterator^.dX; |
|
3290 oy:= iterator^.Y + s * iterator^.dY; |
|
3291 end |
|
3292 else |
|
3293 begin |
|
3294 ox:= iterator^.X; |
|
3295 oy:= iterator^.Y + Int2hwFloat(iterator^.Radius); |
|
3296 end; |
|
3297 |
|
3298 if (hwRound(Distance(Gear^.X-ox,Gear^.Y-oy)) > Gear^.Radius) then |
|
3299 continue; |
|
3300 end; |
|
3301 |
3287 (* |
3302 (* |
3288 noTrap := ((not Gear^.dY.isNegative or (Gear^.dY.QWordValue = 0)) |
3303 noTrap := ((not Gear^.dY.isNegative or (Gear^.dY.QWordValue = 0)) |
3289 // can't be entered from above |
3304 // can't be entered from above |
3290 or ((conPortal^.dY.isNegative and not (conPortal^.dY.QWordValue = 0)))); |
3305 or ((conPortal^.dY.isNegative and not (conPortal^.dY.QWordValue = 0)))); |
3291 // can't be left downwards; |
3306 // can't be left downwards; |
3300 |
3315 |
3301 // Until loops are reliably broken |
3316 // Until loops are reliably broken |
3302 inc(iterator^.PortalCounter); |
3317 inc(iterator^.PortalCounter); |
3303 |
3318 |
3304 // find out how much speed parallel to the portal vector |
3319 // find out how much speed parallel to the portal vector |
3305 // the gear has |
3320 // the gear has, also get the vector offset |
3306 pspeed:= (Gear^.dX * iterator^.dX + Gear^.dY * iterator^.dY ); |
3321 pspeed:= (Gear^.dX * iterator^.dX + Gear^.dY * iterator^.dY); |
|
3322 ox := (iterator^.X - Gear^.X); |
|
3323 oy := (iterator^.Y - Gear^.Y); |
|
3324 poffs:= (Gear^.dX * ox + Gear^.dY * oy); |
3307 // create a normal of the portal vector |
3325 // create a normal of the portal vector |
3308 nx := - Gear^.dY; |
3326 nx := - Gear^.dY; |
3309 ny := Gear^.dX; |
3327 ny := Gear^.dX; |
3310 // pick the normal vector that's pointing skywards |
3328 // pick the normal vector that's pointing skywards |
3311 if (not ny.isNegative) then |
3329 if (not ny.isNegative) then |
3314 ny.isNegative := not ny.isNegative; |
3332 ny.isNegative := not ny.isNegative; |
3315 end; |
3333 end; |
3316 // now let's find out how much speed the gear has in the |
3334 // now let's find out how much speed the gear has in the |
3317 // direction of that normal |
3335 // direction of that normal |
3318 nspeed:= (nx * iterator^.dX + ny * iterator^.dY); |
3336 nspeed:= (nx * iterator^.dX + ny * iterator^.dY); |
|
3337 noffs:= (nx * ox + ny * oy); |
3319 |
3338 |
3320 // now let's project those back to the connected portal's vectors |
3339 // now let's project those back to the connected portal's vectors |
3321 nx := - conPortal^.dY; |
3340 nx := - conPortal^.dY; |
3322 ny := conPortal^.dX; |
3341 ny := conPortal^.dX; |
3323 if ny.isNegative then |
3342 if ny.isNegative then |
3324 begin |
3343 begin |
3325 nx.isNegative := not nx.isNegative; |
3344 nx.isNegative := not nx.isNegative; |
3326 ny.isNegative := not ny.isNegative; |
3345 ny.isNegative := not ny.isNegative; |
3327 end; |
3346 end; |
3328 iterator^.dX := -pspeed * conPortal^.dX + -nspeed * nx; |
3347 //AddFileLog('poffs:'+cstr(poffs)+' noffs:'+cstr(noffs)+' pspeed:'+cstr(pspeed)+' nspeed:'+cstr(nspeed)); |
3329 iterator^.dY := -pspeed * conPortal^.dY + -nspeed * ny; |
3348 iterator^.dX := -pspeed * conPortal^.dX + nspeed * nx; |
|
3349 iterator^.dY := -pspeed * conPortal^.dY + nspeed * ny; |
3330 if iterator^.Kind = gtCake then |
3350 if iterator^.Kind = gtCake then |
3331 itdist := int2hwFloat(iterator^.Radius) - _0_1; |
3351 poffs := poffs * _0_5; |
3332 s := itdist / Distance(iterator^.dX, iterator^.dY); |
3352 iterator^.X := conPortal^.X + poffs * conPortal^.dX + noffs * nx; |
3333 iterator^.X := conPortal^.X + s * iterator^.dX; |
3353 iterator^.Y := conPortal^.Y + poffs * conPortal^.dY + noffs * ny; |
3334 iterator^.Y := conPortal^.Y + s * iterator^.dY; |
|
3335 end; |
|
3336 |
3354 |
3337 FollowGear := iterator; |
3355 FollowGear := iterator; |
|
3356 //AddFileLog('portal''d'); |
3338 |
3357 |
3339 { |
3358 { |
3340 s := _0_2 + _0_008 * Gear^.Health; |
3359 s := _0_2 + _0_008 * Gear^.Health; |
3341 iterator^.dX := s * iterator^.dX; |
3360 iterator^.dX := s * iterator^.dX; |
3342 iterator^.dY := s * iterator^.dY; |
3361 iterator^.dY := s * iterator^.dY; |
3352 s := _0_96 / Distance(iterator^.dX, iterator^.dY); |
3371 s := _0_96 / Distance(iterator^.dX, iterator^.dY); |
3353 iterator^.dX := s * iterator^.dX; |
3372 iterator^.dX := s * iterator^.dX; |
3354 iterator^.dY := s * iterator^.dX; |
3373 iterator^.dY := s * iterator^.dX; |
3355 end; |
3374 end; |
3356 } |
3375 } |
|
3376 end; |
3357 end; |
3377 end; |
3358 |
3378 |
3359 procedure doStepMovingPortal_real(Gear: PGear); |
3379 procedure doStepMovingPortal_real(Gear: PGear); |
3360 var |
3380 var |
3361 x, y, tx, ty: LongInt; |
3381 x, y, tx, ty: LongInt; |