hedgewars/uGearsHandlersMess.pas
changeset 12898 8a40ce061d94
parent 12837 31dd78cbf729
child 12914 0de553fb7e89
equal deleted inserted replaced
12891:856570ddd409 12898:8a40ce061d94
   137 procedure doStepAddAmmo(Gear: PGear);
   137 procedure doStepAddAmmo(Gear: PGear);
   138 procedure doStepGenericFaller(Gear: PGear);
   138 procedure doStepGenericFaller(Gear: PGear);
   139 //procedure doStepCreeper(Gear: PGear);
   139 //procedure doStepCreeper(Gear: PGear);
   140 procedure doStepKnife(Gear: PGear);
   140 procedure doStepKnife(Gear: PGear);
   141 procedure doStepDuck(Gear: PGear);
   141 procedure doStepDuck(Gear: PGear);
       
   142 procedure doStepMinigunWork(Gear: PGear);
       
   143 procedure doStepMinigun(Gear: PGear);
       
   144 procedure doStepMinigunBullet(Gear: PGear);
   142 
   145 
   143 var
   146 var
   144     upd: Longword;
   147     upd: Longword;
   145     snowLeft,snowRight: LongInt;
   148     snowLeft,snowRight: LongInt;
   146 
   149 
  1232 
  1235 
  1233             VGear^.Timer := 200;
  1236             VGear^.Timer := 200;
  1234             end;
  1237             end;
  1235 end;
  1238 end;
  1236 
  1239 
       
  1240 procedure LineShoveHelp(Gear: PGear; oX, oY, tX, tY, dX, dY: hwFloat; count: LongWord);
       
  1241 var dmg,power: LongInt;
       
  1242 begin
       
  1243     if ((Gear^.Kind = gtMinigunBullet) or (Gear^.Damage > 0))
       
  1244     and (hwSqr(tX - oX) + hwSqr(tY - oY) > _0_25) then
       
  1245     begin
       
  1246         if (Gear^.AmmoType = amDEagle) or (Gear^.AmmoType = amMinigun) then
       
  1247             dmg:= Gear^.Boom
       
  1248         else
       
  1249             dmg:= Gear^.Timer * Gear^.Boom div 100000;
       
  1250         if (Gear^.AmmoType = amMinigun) then
       
  1251             power:= 10
       
  1252         else
       
  1253             power:= 20;
       
  1254         AmmoShoveLine(Gear, dmg, power, oX, oY, tX, tY);
       
  1255     end;
       
  1256     if Gear^.Damage > 0 then
       
  1257     begin
       
  1258         DrawTunnel(oX, oY, dX, dY, count, 1);
       
  1259         dec(Gear^.Health, Gear^.Damage);
       
  1260         Gear^.Damage := 0
       
  1261     end;
       
  1262 end;
       
  1263 
  1237 procedure doStepBulletWork(Gear: PGear);
  1264 procedure doStepBulletWork(Gear: PGear);
  1238 var
  1265 var
  1239     i, x, y, iInit: LongWord;
  1266     i, x, y, iInit: LongWord;
  1240     oX, oY, tX, tY, tDx, tDy: hwFloat;
  1267     oX, oY, tX, tY, tDx, tDy: hwFloat;
  1241     VGear: PVisualGear;
  1268     VGear: PVisualGear;
       
  1269     LandFlags: Word;
       
  1270     isDigging: Boolean;
       
  1271     isDead: Boolean;
  1242 begin
  1272 begin
  1243     AllInactive := false;
  1273     AllInactive := false;
  1244     inc(Gear^.Timer);
  1274     inc(Gear^.Timer);
  1245     iInit := 80;
  1275     iInit := 100;
  1246     i := iInit;
  1276     i := iInit;
       
  1277     isDigging := false;
       
  1278     isDead := false;
  1247     oX := Gear^.X;
  1279     oX := Gear^.X;
  1248     oY := Gear^.Y;
  1280     oY := Gear^.Y;
  1249     repeat
  1281     repeat
  1250         Gear^.X := Gear^.X + Gear^.dX;
  1282         Gear^.X := Gear^.X + Gear^.dX;
  1251         Gear^.Y := Gear^.Y + Gear^.dY;
  1283         Gear^.Y := Gear^.Y + Gear^.dY;
  1253         tY:= Gear^.Y;
  1285         tY:= Gear^.Y;
  1254         tDx:= Gear^.dX;
  1286         tDx:= Gear^.dX;
  1255         tDy:= Gear^.dY;
  1287         tDy:= Gear^.dY;
  1256         if (Gear^.PortalCounter < 30) and WorldWrap(Gear) then
  1288         if (Gear^.PortalCounter < 30) and WorldWrap(Gear) then
  1257             begin
  1289             begin
  1258             DrawTunnel(oX, oY, tDx, tDy, iInit + 2 - i, 1);
  1290             LineShoveHelp(Gear, oX, oY, tX, tY, tDx, tDy, iInit + 2 - i);
  1259             SpawnBulletTrail(Gear, tX, tY);
  1291             SpawnBulletTrail(Gear, tX, tY);
  1260             iInit:= i;
  1292             iInit:= i;
  1261             oX:= Gear^.X;
  1293             oX:= Gear^.X;
  1262             oY:= Gear^.Y;
  1294             oY:= Gear^.Y;
  1263             inc(Gear^.PortalCounter);
  1295             inc(Gear^.PortalCounter);
  1266             SpawnBulletTrail(Gear, Gear^.X, Gear^.Y);
  1298             SpawnBulletTrail(Gear, Gear^.X, Gear^.Y);
  1267             end;
  1299             end;
  1268         x := hwRound(Gear^.X);
  1300         x := hwRound(Gear^.X);
  1269         y := hwRound(Gear^.Y);
  1301         y := hwRound(Gear^.Y);
  1270 
  1302 
  1271         if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] <> 0) then
  1303         if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) then
  1272             inc(Gear^.Damage);
  1304         begin
  1273         // let's interrupt before a collision to give portals a chance to catch the bullet
  1305             LandFlags:= Land[y, x];
  1274         if (Gear^.Damage = 1) and (Gear^.Tag = 0) and (not CheckLandValue(x, y, lfLandMask)) then
  1306             if LandFlags <> 0 then inc(Gear^.Damage);
       
  1307             isDigging:= (LandFlags and lfLandMask) <> 0;
       
  1308         end;
       
  1309         // let's interrupt before a collision with land to give portals a chance to catch the bullet
       
  1310         if isDigging and (Gear^.Tag = 0) then
  1275             begin
  1311             begin
  1276             Gear^.Tag := 1;
  1312             Gear^.Tag := 1;
  1277             Gear^.Damage := 0;
  1313             dec(Gear^.Damage);
  1278             Gear^.X := Gear^.X - Gear^.dX;
  1314             Gear^.X := Gear^.X - Gear^.dX;
  1279             Gear^.Y := Gear^.Y - Gear^.dY;
  1315             Gear^.Y := Gear^.Y - Gear^.dY;
  1280             CheckGearDrowning(Gear);
  1316             CheckGearDrowning(Gear);
  1281             break;
  1317             break;
  1282             end
  1318             end
  1283         else
  1319         else if (not isDigging) then
  1284             Gear^.Tag := 0;
  1320             Gear^.Tag := 0;
  1285 
  1321 
  1286         if Gear^.Damage > 5 then
  1322         //Shove static gears to remove the mask and stop damaging the bullet
  1287             begin
  1323         if (not isDigging) and (Gear^.Damage > 5) and (Gear^.Kind <> gtMinigunBullet) then
  1288             if Gear^.AmmoType = amDEagle then
  1324             begin
  1289                 AmmoShove(Gear, Gear^.Boom, 20)
  1325             LineShoveHelp(Gear, oX, oY, tX, tY, tDx, tDy, iInit + 2 - i);
  1290             else
  1326             SpawnBulletTrail(Gear, tX, tY);
  1291                 AmmoShove(Gear, Gear^.Timer * Gear^.Boom div 100000, 20);
  1327             iInit:= i;
  1292             end;
  1328             oX:= Gear^.X;
       
  1329             oY:= Gear^.Y;
       
  1330             end;
       
  1331 
  1293         CheckGearDrowning(Gear);
  1332         CheckGearDrowning(Gear);
       
  1333         case Gear^.Kind of
       
  1334             gtMinigunBullet: isDead:= isDigging;
       
  1335             gtDEagleShot, gtSniperRifleShot: isDead:= Gear^.Damage >= Gear^.Health;
       
  1336         end;
  1294         dec(i)
  1337         dec(i)
  1295     until (i = 0) or (Gear^.Damage > Gear^.Health) or ((Gear^.State and gstDrowning) <> 0);
  1338     until (i = 0) or (isDead) or ((Gear^.State and gstDrowning) <> 0);
  1296 
  1339 
  1297     if Gear^.Damage > 0 then
  1340     LineShoveHelp(Gear, oX, oY, Gear^.X, Gear^.Y,
  1298         begin
  1341                   Gear^.dX, Gear^.dY, iInit + 2 - i);
  1299         DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, iInit + 2 - i, 1);
       
  1300         dec(Gear^.Health, Gear^.Damage);
       
  1301         Gear^.Damage := 0
       
  1302         end;
       
  1303 
  1342 
  1304     if ((Gear^.State and gstDrowning) <> 0) and (Gear^.Health > 0) then
  1343     if ((Gear^.State and gstDrowning) <> 0) and (Gear^.Health > 0) then
  1305         begin
  1344         begin
  1306         // draw bubbles
  1345         // draw bubbles
  1307         if (not SuddenDeathDmg and (WaterOpacity < $FF)) or (SuddenDeathDmg and (SDWaterOpacity < $FF)) then
  1346         if (not SuddenDeathDmg and (WaterOpacity < $FF)) or (SuddenDeathDmg and (SDWaterOpacity < $FF)) then
  1316             end;
  1355             end;
  1317         // bullet dies underwater
  1356         // bullet dies underwater
  1318         Gear^.Health:= 0;
  1357         Gear^.Health:= 0;
  1319         end;
  1358         end;
  1320 
  1359 
  1321     if (Gear^.Health <= 0)
  1360     if (isDead)
  1322         or (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0)
  1361         or (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0)
  1323         or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then
  1362         or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then
  1324             begin
  1363             begin
  1325             if (Gear^.Kind = gtSniperRifleShot) then
  1364             if (Gear^.Kind = gtSniperRifleShot) then
  1326                 cLaserSightingSniper := false;
  1365                 cLaserSightingSniper := false;
  1328                 cArtillery := false;
  1367                 cArtillery := false;
  1329 
  1368 
  1330         // Bullet Hit
  1369         // Bullet Hit
  1331             if ((Gear^.State and gstDrowning) = 0) and (hwRound(Gear^.X) and LAND_WIDTH_MASK = 0) and (hwRound(Gear^.Y) and LAND_HEIGHT_MASK = 0) then
  1370             if ((Gear^.State and gstDrowning) = 0) and (hwRound(Gear^.X) and LAND_WIDTH_MASK = 0) and (hwRound(Gear^.Y) and LAND_HEIGHT_MASK = 0) then
  1332                 begin
  1371                 begin
  1333                 VGear := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBulletHit);
  1372                 if Gear^.Kind = gtMinigunBullet then
       
  1373                     begin
       
  1374                     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 5,
       
  1375                                     Gear^.Hedgehog, EXPLNoDamage{ or EXPLDontDraw or EXPLNoGfx});
       
  1376                     VGear := AddVisualGear(hwRound(Gear^.X + Gear^.dX * 5), hwRound(Gear^.Y + Gear^.dY * 5), vgtBulletHit);
       
  1377                     end
       
  1378                 else
       
  1379                     VGear := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBulletHit);
       
  1380 
  1334                 if VGear <> nil then
  1381                 if VGear <> nil then
  1335                     begin
  1382                     begin
  1336                     VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY);
  1383                     VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY);
  1337                     end;
  1384                     end;
  1338                 end;
  1385                 end;
  1339 
  1386 
  1340             spawnBulletTrail(Gear, Gear^.X, Gear^.Y);
  1387             spawnBulletTrail(Gear, Gear^.X, Gear^.Y);
       
  1388             if Gear^.Kind = gtMinigunBullet then
       
  1389                 ClearHitOrderLeq(Gear^.Tag);
  1341             Gear^.doStep := @doStepShotIdle
  1390             Gear^.doStep := @doStepShotIdle
  1342             end;
  1391             end;
  1343 end;
  1392 end;
  1344 
  1393 
  1345 procedure doStepDEagleShot(Gear: PGear);
  1394 procedure doStepDEagleShot(Gear: PGear);
  1355     Gear^.Y := Gear^.Y + Gear^.dY * 2;
  1404     Gear^.Y := Gear^.Y + Gear^.dY * 2;
  1356     Gear^.doStep := @doStepBulletWork
  1405     Gear^.doStep := @doStepBulletWork
  1357 end;
  1406 end;
  1358 
  1407 
  1359 procedure doStepSniperRifleShot(Gear: PGear);
  1408 procedure doStepSniperRifleShot(Gear: PGear);
  1360 var
  1409 var HHGear: PGear;
  1361     HHGear: PGear;
       
  1362     shell: PVisualGear;
  1410     shell: PVisualGear;
  1363 begin
  1411 begin
  1364 
  1412 
  1365     cArtillery := true;
  1413     cArtillery := true;
  1366     HHGear := Gear^.Hedgehog^.Gear;
  1414     HHGear := Gear^.Hedgehog^.Gear;
  4452 
  4500 
  4453         if iterator^.Kind = gtDuck then
  4501         if iterator^.Kind = gtDuck then
  4454             // Make duck go into “falling” mode again
  4502             // Make duck go into “falling” mode again
  4455             iterator^.Pos:= 0;
  4503             iterator^.Pos:= 0;
  4456 
  4504 
  4457         isbullet:= (iterator^.Kind in [gtShotgunShot, gtDEagleShot, gtSniperRifleShot, gtSineGunShot]);
  4505         isbullet:= (iterator^.Kind in [gtShotgunShot, gtDEagleShot, gtSniperRifleShot, gtSineGunShot, gtMinigunBullet]);
  4458 
  4506 
  4459         r:= int2hwFloat(iterator^.Radius);
  4507         r:= int2hwFloat(iterator^.Radius);
  4460 
  4508 
  4461         if not (isbullet or iscake) then
  4509         if not (isbullet or iscake) then
  4462             begin
  4510             begin
  4479 
  4527 
  4480             if (hwRound(Distance(Gear^.X-ox,Gear^.Y-oy)) > Gear^.Radius + 1 ) then
  4528             if (hwRound(Distance(Gear^.X-ox,Gear^.Y-oy)) > Gear^.Radius + 1 ) then
  4481                 continue;
  4529                 continue;
  4482             end;
  4530             end;
  4483 
  4531 
  4484         if (iterator^.Kind = gtDEagleShot) or (iterator^.Kind = gtSniperRifleShot) then
  4532         if (iterator^.Kind in [gtDEagleShot, gtSniperRifleShot, gtMinigunBullet]) then
  4485             begin
  4533             begin
  4486             // draw bullet trail
  4534             // draw bullet trail
  4487             spawnBulletTrail(iterator, iterator^.X, iterator^.Y);
  4535             spawnBulletTrail(iterator, iterator^.X, iterator^.Y);
  4488             // the bullet can now hurt the hog that fired it
  4536             // the bullet can now hurt the hog that fired it
  4489             iterator^.Data:= nil;
  4537             iterator^.Data:= nil;
  6562         Gear^.RenderTimer:= false;
  6610         Gear^.RenderTimer:= false;
  6563 
  6611 
  6564     dec(Gear^.Timer);
  6612     dec(Gear^.Timer);
  6565 end;
  6613 end;
  6566 
  6614 
       
  6615 ////////////////////////////////////////////////////////////////////////////////
       
  6616 procedure doStepMinigunWork(Gear: PGear);
       
  6617 var HHGear: PGear;
       
  6618     i: LongWord;
       
  6619     shell: PVisualGear;
       
  6620     bullet: PGear;
       
  6621     rx, ry: hwFloat;
       
  6622     gX, gY: LongInt;
       
  6623 begin
       
  6624     AllInactive:= false;
       
  6625     HHGear := Gear^.Hedgehog^.Gear;
       
  6626     if HHGear = nil then
       
  6627     begin
       
  6628         ClearHitOrder();
       
  6629         DeleteGear(gear);
       
  6630         exit
       
  6631     end;
       
  6632 
       
  6633     HedgehogChAngle(HHGear);
       
  6634 
       
  6635     dec(Gear^.Timer);
       
  6636     if (Gear^.Timer mod 50) = 0 then
       
  6637     begin
       
  6638         Gear^.Tag := ((Gear^.Tag - 1) and 1) + 2;
       
  6639 
       
  6640         gX := hwRound(Gear^.X) + GetLaunchX(amMinigun, hwSign(HHGear^.dX), HHGear^.Angle);
       
  6641         gY := hwRound(Gear^.Y) + GetLaunchY(amMinigun, HHGear^.Angle);
       
  6642         rx := rndSign(getRandomf * _0_2);
       
  6643         ry := rndSign(getRandomf * _0_2);
       
  6644 
       
  6645         bullet:= AddGear(gx, gy, gtMinigunBullet, 0, SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx, AngleCos(HHGear^.Angle) * ( - _0_8) + ry, 0);
       
  6646         bullet^.CollisionMask:= lfNotCurrentMask;
       
  6647         bullet^.WDTimer := Gear^.WDTimer;
       
  6648         Inc(Gear^.WDTimer);
       
  6649 
       
  6650         shell := AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell);
       
  6651         if shell <> nil then
       
  6652         begin
       
  6653             shell^.dX := gear^.dX.QWordValue / -17179869184;
       
  6654             shell^.dY := gear^.dY.QWordValue / -17179869184;
       
  6655             shell^.Frame := 0
       
  6656         end;
       
  6657     end;
       
  6658 
       
  6659     if (Gear^.Timer = 0) or ((HHGear^.State and gstHHDriven) = 0) then
       
  6660     begin
       
  6661         HHGear^.State := HHGear^.State and (not gstNotKickable);
       
  6662         ClearHitOrder();
       
  6663         DeleteGear(Gear);
       
  6664         AfterAttack
       
  6665     end
       
  6666 end;
       
  6667 
       
  6668 procedure doStepMinigun(Gear: PGear);
       
  6669 var HHGear: PGear;
       
  6670 begin
       
  6671     dec(Gear^.Timer);
       
  6672     if (Gear^.Timer mod 100) = 0 then
       
  6673         Gear^.Tag := (Gear^.Tag + 1) and 1;
       
  6674 
       
  6675     if Gear^.Timer = 0 then
       
  6676         begin
       
  6677         Gear^.Tag := 2;
       
  6678         HHGear := Gear^.Hedgehog^.Gear;
       
  6679         HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown));
       
  6680         HHGear^.State := HHGear^.State or gstNotKickable;
       
  6681 
       
  6682         Gear^.Timer := 3501;
       
  6683         Gear^.WDTimer := 0; // Order of the next bullet;
       
  6684         ClearHitOrder();
       
  6685         Gear^.doStep := @doStepMinigunWork
       
  6686         end;
       
  6687 end;
       
  6688 
       
  6689 ////////////////////////////////////////////////////////////////////////////////
       
  6690 
       
  6691 procedure doStepMinigunBullet(Gear: PGear);
       
  6692 begin
       
  6693     Gear^.Data:= nil;
       
  6694     // remember who fired this
       
  6695     if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.Gear <> nil) then
       
  6696         Gear^.Data:= Pointer(Gear^.Hedgehog^.Gear);
       
  6697 
       
  6698     PlaySound(sndGun);
       
  6699     Gear^.X := Gear^.X + Gear^.dX * 2;
       
  6700     Gear^.Y := Gear^.Y + Gear^.dY * 2;
       
  6701     Gear^.doStep := @doStepBulletWork
       
  6702 end;
       
  6703 
  6567 (*
  6704 (*
  6568  This didn't end up getting used, but, who knows, might be reasonable for javellin or something
  6705  This didn't end up getting used, but, who knows, might be reasonable for javellin or something
  6569 // Make the knife initial angle based on the hog attack angle, or is that too hard?
  6706 // Make the knife initial angle based on the hog attack angle, or is that too hard?
  6570 procedure doStepKnife(Gear: PGear);
  6707 procedure doStepKnife(Gear: PGear);
  6571 var t,
  6708 var t,