27 function AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear; |
27 function AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear; |
28 function SpawnCustomCrateAt(x, y: LongInt; crate: TCrateType; content: Longword ): PGear; |
28 function SpawnCustomCrateAt(x, y: LongInt; crate: TCrateType; content: Longword ): PGear; |
29 procedure ResurrectHedgehog(gear: PGear); |
29 procedure ResurrectHedgehog(gear: PGear); |
30 procedure ProcessGears; |
30 procedure ProcessGears; |
31 procedure EndTurnCleanup; |
31 procedure EndTurnCleanup; |
32 procedure ApplyDamage(Gear: PGear; Damage: Longword; Source: TDamageSource); |
32 procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource); |
33 procedure SetAllToActive; |
33 procedure SetAllToActive; |
34 procedure SetAllHHToActive; |
34 procedure SetAllHHToActive; |
35 procedure DrawGears; |
35 procedure DrawGears; |
36 procedure FreeGearsList; |
36 procedure FreeGearsList; |
37 procedure AddMiscGears; |
37 procedure AddMiscGears; |
48 uses uStore, uSound, uTeams, uRandom, uCollisions, uIO, uLandGraphics, |
48 uses uStore, uSound, uTeams, uRandom, uCollisions, uIO, uLandGraphics, |
49 uAIMisc, uLocale, uAI, uAmmos, uStats, uVisualGears, uScript, GLunit, uMobile, uVariables, |
49 uAIMisc, uLocale, uAI, uAmmos, uStats, uVisualGears, uScript, GLunit, uMobile, uVariables, |
50 uCommands, uUtils, uTextures, uRenderUtils, uGearsRender, uCaptions, uDebug, uLandTexture; |
50 uCommands, uUtils, uTextures, uRenderUtils, uGearsRender, uCaptions, uDebug, uLandTexture; |
51 |
51 |
52 |
52 |
53 procedure doMakeExplosion(X, Y, Radius: LongInt; Mask: LongWord); forward; |
53 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord = $FFFFFFFF); forward; |
54 procedure doMakeExplosion(X, Y, Radius: LongInt; Mask, Tint: LongWord); forward; |
|
55 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); forward; |
54 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); forward; |
56 //procedure AmmoFlameWork(Ammo: PGear); forward; |
55 //procedure AmmoFlameWork(Ammo: PGear); forward; |
57 function GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): TPGearArray; forward; |
56 function GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): TPGearArray; forward; |
58 function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear; forward; |
57 function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear; forward; |
59 procedure SpawnBoxOfSmth; forward; |
58 procedure SpawnBoxOfSmth; forward; |
203 gear^.uid:= Counter; |
202 gear^.uid:= Counter; |
204 gear^.SoundChannel:= -1; |
203 gear^.SoundChannel:= -1; |
205 gear^.ImpactSound:= sndNone; |
204 gear^.ImpactSound:= sndNone; |
206 gear^.nImpactSounds:= 0; |
205 gear^.nImpactSounds:= 0; |
207 |
206 |
208 if CurrentTeam <> nil then |
207 if CurrentHedgehog <> nil then |
209 begin |
208 begin |
210 gear^.Hedgehog:= CurrentHedgehog; |
209 gear^.Hedgehog:= CurrentHedgehog; |
211 gear^.IntersectGear:= CurrentHedgehog^.Gear |
210 gear^.IntersectGear:= CurrentHedgehog^.Gear |
212 end; |
211 end; |
213 |
212 |
557 begin |
556 begin |
558 t:= max(Gear^.Damage, Gear^.Health); |
557 t:= max(Gear^.Damage, Gear^.Health); |
559 Gear^.Damage:= t; |
558 Gear^.Damage:= t; |
560 if ((not SuddenDeathDmg and (cWaterOpacity < $FF)) or (SuddenDeathDmg and (cWaterOpacity < $FF))) and (hwRound(Gear^.Y) < cWaterLine + 256) then |
559 if ((not SuddenDeathDmg and (cWaterOpacity < $FF)) or (SuddenDeathDmg and (cWaterOpacity < $FF))) and (hwRound(Gear^.Y) < cWaterLine + 256) then |
561 spawnHealthTagForHH(Gear, t); |
560 spawnHealthTagForHH(Gear, t); |
562 uStats.HedgehogDamaged(Gear) |
561 |
|
562 // should be not CurrentHedgehog, but hedgehog of the last gear which caused damage to this hog |
|
563 // same stand for CheckHHDamage |
|
564 uStats.HedgehogDamaged(Gear, CurrentHedgehog) |
563 end; |
565 end; |
564 |
566 |
565 team:= Gear^.Hedgehog^.Team; |
567 team:= Gear^.Hedgehog^.Team; |
566 if CurrentHedgehog^.Gear = Gear then |
568 if CurrentHedgehog^.Gear = Gear then |
567 FreeActionsList; // to avoid ThinkThread on drawned gear |
569 FreeActionsList; // to avoid ThinkThread on drawned gear |
614 if (not isInMultiShoot) then inc(Gear^.Damage, Gear^.Karma); |
616 if (not isInMultiShoot) then inc(Gear^.Damage, Gear^.Karma); |
615 if (Gear^.Damage <> 0) and |
617 if (Gear^.Damage <> 0) and |
616 (not Gear^.Invulnerable) then |
618 (not Gear^.Invulnerable) then |
617 begin |
619 begin |
618 CheckNoDamage:= false; |
620 CheckNoDamage:= false; |
619 uStats.HedgehogDamaged(Gear); |
621 |
620 dmg:= Gear^.Damage; |
622 dmg:= Gear^.Damage; |
621 if Gear^.Health < dmg then |
623 if Gear^.Health < dmg then |
622 begin |
624 begin |
623 Gear^.Active:= true; |
625 Gear^.Active:= true; |
624 Gear^.Health:= 0 |
626 Gear^.Health:= 0 |
799 if cHealthDecrease <> 0 then |
801 if cHealthDecrease <> 0 then |
800 begin |
802 begin |
801 SuddenDeathDmg:= true; |
803 SuddenDeathDmg:= true; |
802 ChangeToSDClouds; |
804 ChangeToSDClouds; |
803 ChangeToSDFlakes; |
805 ChangeToSDFlakes; |
|
806 glClearColor(SDSkyColor.r / 255, SDSkyColor.g / 255, SDSkyColor.b / 255, 0.99); |
804 end; |
807 end; |
805 AddCaption(trmsg[sidSuddenDeath], cWhiteColor, capgrpGameState); |
808 AddCaption(trmsg[sidSuddenDeath], cWhiteColor, capgrpGameState); |
806 playSound(sndSuddenDeath); |
809 playSound(sndSuddenDeath); |
807 MusicFN:= SDMusic; |
810 MusicFN:= SDMusic; |
808 ChangeMusic |
811 ChangeMusic |
984 if (GameFlags and gfResetHealth) <> 0 then |
987 if (GameFlags and gfResetHealth) <> 0 then |
985 for i:= 0 to Pred(TeamsCount) do |
988 for i:= 0 to Pred(TeamsCount) do |
986 RecountTeamHealth(TeamsArray[i]) |
989 RecountTeamHealth(TeamsArray[i]) |
987 end; |
990 end; |
988 |
991 |
989 procedure ApplyDamage(Gear: PGear; Damage: Longword; Source: TDamageSource); |
992 procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource); |
990 var s: shortstring; |
993 var s: shortstring; |
991 vampDmg, tmpDmg, i: Longword; |
994 vampDmg, tmpDmg, i: Longword; |
992 vg: PVisualGear; |
995 vg: PVisualGear; |
993 begin |
996 begin |
994 if (Gear^.Kind = gtHedgehog) and (Damage>=1) then |
997 if (Gear^.Kind = gtHedgehog) and (Damage>=1) then |
995 begin |
998 begin |
|
999 uStats.HedgehogDamaged(Gear, AttackerHog); |
996 HHHurt(Gear^.Hedgehog, Source); |
1000 HHHurt(Gear^.Hedgehog, Source); |
997 AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), Damage, Gear^.Hedgehog^.Team^.Clan^.Color); |
1001 AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), Damage, Gear^.Hedgehog^.Team^.Clan^.Color); |
998 tmpDmg:= min(Damage, max(0,Gear^.Health-Gear^.Damage)); |
1002 tmpDmg:= min(Damage, max(0,Gear^.Health-Gear^.Damage)); |
999 if (Gear <> CurrentHedgehog^.Gear) and (CurrentHedgehog^.Gear <> nil) and (tmpDmg >= 1) then |
1003 if (Gear <> CurrentHedgehog^.Gear) and (CurrentHedgehog^.Gear <> nil) and (tmpDmg >= 1) then |
1000 begin |
1004 begin |
1026 begin // this cannot just use Damage or it interrupts shotgun and gets you called stupid |
1030 begin // this cannot just use Damage or it interrupts shotgun and gets you called stupid |
1027 inc(CurrentHedgehog^.Gear^.Karma, tmpDmg); |
1031 inc(CurrentHedgehog^.Gear^.Karma, tmpDmg); |
1028 spawnHealthTagForHH(CurrentHedgehog^.Gear, tmpDmg); |
1032 spawnHealthTagForHH(CurrentHedgehog^.Gear, tmpDmg); |
1029 end; |
1033 end; |
1030 end; |
1034 end; |
1031 end; |
1035 end else // not gtHedgehog |
|
1036 begin |
|
1037 AddFileLog('Assigning hedgehog ' + inttostr(LongInt(AttackerHog)) + ' to gear ' + inttostr(Gear^.uid)); |
|
1038 Gear^.Hedgehog:= AttackerHog; |
|
1039 end; |
1032 inc(Gear^.Damage, Damage); |
1040 inc(Gear^.Damage, Damage); |
1033 ScriptCall('onGearDamage', Gear^.UID, Damage); |
1041 ScriptCall('onGearDamage', Gear^.UID, Damage); |
1034 end; |
1042 end; |
1035 |
1043 |
1036 procedure SetAllToActive; |
1044 procedure SetAllToActive; |
1089 var i: LongInt; |
1097 var i: LongInt; |
1090 Gear: PGear; |
1098 Gear: PGear; |
1091 begin |
1099 begin |
1092 AddGear(0, 0, gtATStartGame, 0, _0, _0, 2000); |
1100 AddGear(0, 0, gtATStartGame, 0, _0, _0, 2000); |
1093 |
1101 |
1094 for i:= 0 to Pred(cLandMines) do |
1102 i:= 0; |
|
1103 Gear:= PGear(1); |
|
1104 while (i < cLandMines) {and (Gear <> nil)} do // disable this check until better solution found |
1095 begin |
1105 begin |
1096 Gear:= AddGear(0, 0, gtMine, 0, _0, _0, 0); |
1106 Gear:= AddGear(0, 0, gtMine, 0, _0, _0, 0); |
1097 FindPlace(Gear, false, 0, LAND_WIDTH); |
1107 FindPlace(Gear, false, 0, LAND_WIDTH); |
1098 end; |
1108 inc(i) |
1099 for i:= 0 to Pred(cExplosives) do |
1109 end; |
|
1110 |
|
1111 i:= 0; |
|
1112 Gear:= PGear(1); |
|
1113 while (i < cExplosives){ and (Gear <> nil)} do |
1100 begin |
1114 begin |
1101 Gear:= AddGear(0, 0, gtExplosives, 0, _0, _0, 0); |
1115 Gear:= AddGear(0, 0, gtExplosives, 0, _0, _0, 0); |
1102 FindPlace(Gear, false, 0, LAND_WIDTH); |
1116 FindPlace(Gear, false, 0, LAND_WIDTH); |
|
1117 inc(i) |
1103 end; |
1118 end; |
1104 |
1119 |
1105 if (GameFlags and gfLowGravity) <> 0 then |
1120 if (GameFlags and gfLowGravity) <> 0 then |
1106 begin |
1121 begin |
1107 cGravity:= cMaxWindSpeed; |
1122 cGravity:= cMaxWindSpeed; |
1131 AddGear(GetRandom(LAND_WIDTH+1024)-512, LAND_HEIGHT - GetRandom(LAND_HEIGHT div 2), gtFlake, 0, _0, _0, 0); |
1146 AddGear(GetRandom(LAND_WIDTH+1024)-512, LAND_HEIGHT - GetRandom(LAND_HEIGHT div 2), gtFlake, 0, _0, _0, 0); |
1132 disableLandBack:= true |
1147 disableLandBack:= true |
1133 end |
1148 end |
1134 end; |
1149 end; |
1135 |
1150 |
1136 procedure doMakeExplosion(X, Y, Radius: LongInt; Mask: LongWord); |
1151 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord); |
1137 begin |
|
1138 doMakeExplosion(X, Y, Radius, Mask, $FFFFFFFF); |
|
1139 end; |
|
1140 |
|
1141 procedure doMakeExplosion(X, Y, Radius: LongInt; Mask, Tint: LongWord); |
|
1142 var Gear: PGear; |
1152 var Gear: PGear; |
1143 dmg, dmgRadius, dmgBase: LongInt; |
1153 dmg, dmgRadius, dmgBase: LongInt; |
1144 fX, fY: hwFloat; |
1154 fX, fY: hwFloat; |
1145 vg: PVisualGear; |
1155 vg: PVisualGear; |
1146 i, cnt: LongInt; |
1156 i, cnt: LongInt; |
1190 dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); |
1200 dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); |
1191 //{$IFDEF DEBUGFILE}AddFileLog('Damage: ' + inttostr(dmg));{$ENDIF} |
1201 //{$IFDEF DEBUGFILE}AddFileLog('Damage: ' + inttostr(dmg));{$ENDIF} |
1192 if (Mask and EXPLNoDamage) = 0 then |
1202 if (Mask and EXPLNoDamage) = 0 then |
1193 begin |
1203 begin |
1194 if not Gear^.Invulnerable then |
1204 if not Gear^.Invulnerable then |
1195 ApplyDamage(Gear, dmg, dsExplosion) |
1205 ApplyDamage(Gear, AttackingHog, dmg, dsExplosion) |
1196 else |
1206 else |
1197 Gear^.State:= Gear^.State or gstWinner; |
1207 Gear^.State:= Gear^.State or gstWinner; |
1198 end; |
1208 end; |
1199 if ((Mask and EXPLDoNotTouchAny) = 0) and (((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog)) then |
1209 if ((Mask and EXPLDoNotTouchAny) = 0) and (((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog)) then |
1200 begin |
1210 begin |
1256 gtSMine, |
1266 gtSMine, |
1257 gtCase, |
1267 gtCase, |
1258 gtTarget, |
1268 gtTarget, |
1259 gtExplosives: begin |
1269 gtExplosives: begin |
1260 if (not t^.Invulnerable) then |
1270 if (not t^.Invulnerable) then |
1261 ApplyDamage(t, dmg, dsBullet) |
1271 ApplyDamage(t, Gear^.Hedgehog, dmg, dsBullet) |
1262 else |
1272 else |
1263 Gear^.State:= Gear^.State or gstWinner; |
1273 Gear^.State:= Gear^.State or gstWinner; |
1264 |
1274 |
1265 DeleteCI(t); |
1275 DeleteCI(t); |
1266 t^.dX:= t^.dX + Gear^.dX * dmg * _0_01 + SignAs(cHHKick, Gear^.dX); |
1276 t^.dX:= t^.dX + Gear^.dX * dmg * _0_01 + SignAs(cHHKick, Gear^.dX); |
1303 dec(i); |
1313 dec(i); |
1304 Gear:= t^.ar[i]; |
1314 Gear:= t^.ar[i]; |
1305 tmpDmg:= ModifyDamage(Damage, Gear); |
1315 tmpDmg:= ModifyDamage(Damage, Gear); |
1306 if (Gear^.State and gstNoDamage) = 0 then |
1316 if (Gear^.State and gstNoDamage) = 0 then |
1307 begin |
1317 begin |
1308 |
1318 |
1309 if (Ammo^.Kind = gtDEagleShot) or (Ammo^.Kind = gtSniperRifleShot) then |
1319 if (Ammo^.Kind = gtDEagleShot) or (Ammo^.Kind = gtSniperRifleShot) then |
1310 begin |
1320 begin |
1311 VGear := AddVisualGear(hwround(Ammo^.X), hwround(Ammo^.Y), vgtBulletHit); |
1321 VGear := AddVisualGear(hwround(Ammo^.X), hwround(Ammo^.Y), vgtBulletHit); |
1312 if VGear <> nil then VGear^.Angle := DxDy2Angle(-Ammo^.dX, Ammo^.dY); |
1322 if VGear <> nil then VGear^.Angle := DxDy2Angle(-Ammo^.dX, Ammo^.dY); |
1313 end; |
1323 end; |
1314 |
1324 |
1315 if (Gear^.Kind = gtHedgehog) and (Ammo^.State and gsttmpFlag <> 0) and (Ammo^.Kind = gtShover) then Gear^.FlightTime:= 1; |
1325 if (Gear^.Kind = gtHedgehog) and (Ammo^.State and gsttmpFlag <> 0) and (Ammo^.Kind = gtShover) then Gear^.FlightTime:= 1; |
1316 |
1326 |
1317 case Gear^.Kind of |
1327 case Gear^.Kind of |
1318 gtHedgehog, |
1328 gtHedgehog, |
1319 gtMine, |
1329 gtMine, |
1321 gtTarget, |
1331 gtTarget, |
1322 gtCase, |
1332 gtCase, |
1323 gtExplosives: begin |
1333 gtExplosives: begin |
1324 if (Ammo^.Kind = gtDrill) then begin Ammo^.Timer:= 0; exit; end; |
1334 if (Ammo^.Kind = gtDrill) then begin Ammo^.Timer:= 0; exit; end; |
1325 if (not Gear^.Invulnerable) then |
1335 if (not Gear^.Invulnerable) then |
1326 ApplyDamage(Gear, tmpDmg, dsShove) |
1336 ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg, dsShove) |
1327 else |
1337 else |
1328 Gear^.State:= Gear^.State or gstWinner; |
1338 Gear^.State:= Gear^.State or gstWinner; |
1329 if (Gear^.Kind = gtExplosives) and (Ammo^.Kind = gtBlowtorch) then ApplyDamage(Gear, tmpDmg * 100, dsUnknown); // crank up damage for explosives + blowtorch |
1339 if (Gear^.Kind = gtExplosives) and (Ammo^.Kind = gtBlowtorch) then ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg * 100, dsUnknown); // crank up damage for explosives + blowtorch |
1330 |
1340 |
1331 DeleteCI(Gear); |
1341 DeleteCI(Gear); |
1332 if (Gear^.Kind = gtHedgehog) and Gear^.Hedgehog^.King then |
1342 if (Gear^.Kind = gtHedgehog) and Gear^.Hedgehog^.King then |
1333 begin |
1343 begin |
1334 Gear^.dX:= Ammo^.dX * Power * _0_005; |
1344 Gear^.dX:= Ammo^.dX * Power * _0_005; |
1426 |
1436 |
1427 function GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): TPGearArray; |
1437 function GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): TPGearArray; |
1428 var |
1438 var |
1429 t: PGear; |
1439 t: PGear; |
1430 begin |
1440 begin |
|
1441 r:= r*r; |
1431 GearsNear := nil; |
1442 GearsNear := nil; |
1432 t := GearsList; |
1443 t := GearsList; |
1433 while t <> nil do begin |
1444 while t <> nil do begin |
1434 if (t^.Kind = Kind) then begin |
1445 if (t^.Kind = Kind) then begin |
1435 if (X - t^.X)*(X - t^.X) + (Y - t^.Y)*(Y-t^.Y) < |
1446 if (X - t^.X)*(X - t^.X) + (Y - t^.Y)*(Y-t^.Y) < |
1436 int2hwFloat(r)*int2hwFloat(r) then |
1447 int2hwFloat(r) then |
1437 begin |
1448 begin |
1438 SetLength(GearsNear, Length(GearsNear)+1); |
1449 SetLength(GearsNear, Length(GearsNear)+1); |
1439 GearsNear[High(GearsNear)] := t; |
1450 GearsNear[High(GearsNear)] := t; |
1440 end; |
1451 end; |
1441 end; |
1452 end; |
1515 var tempTeam : PTeam; |
1526 var tempTeam : PTeam; |
1516 begin |
1527 begin |
1517 gear^.dX := _0; |
1528 gear^.dX := _0; |
1518 gear^.dY := _0; |
1529 gear^.dY := _0; |
1519 gear^.State := gstWait; |
1530 gear^.State := gstWait; |
1520 uStats.HedgehogDamaged(gear); |
|
1521 gear^.Damage := 0; |
1531 gear^.Damage := 0; |
1522 gear^.Health := gear^.Hedgehog^.InitialHealth; |
1532 gear^.Health := gear^.Hedgehog^.InitialHealth; |
1523 gear^.Hedgehog^.Effects[hePoisoned] := false; |
1533 gear^.Hedgehog^.Effects[hePoisoned] := false; |
1524 if not CurrentHedgehog^.Effects[heResurrectable] then |
1534 if not CurrentHedgehog^.Effects[heResurrectable] then |
1525 with CurrentHedgehog^ do |
1535 with CurrentHedgehog^ do |