hedgewars/GSHandlers.inc
changeset 3571 5c99b239340e
parent 3570 3836fa355f96
child 3572 c968aacba708
equal deleted inserted replaced
3570:3836fa355f96 3571:5c99b239340e
  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;