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 |
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); |
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, |