--- a/hedgewars/uGears.pas Fri Mar 06 13:50:40 2009 +0000
+++ b/hedgewars/uGears.pas Sat Mar 07 17:42:54 2009 +0000
@@ -601,12 +601,19 @@
//Purpose, to reset all transient attributes toggled by a utility.
//If any of these are set as permanent toggles in the frontend, that needs to be checked and skipped here.
procedure ResetUtilities;
+var i: LongInt;
begin
cGravity:= cMaxWindSpeed;
cDamageModifier:= _1;
cLaserSighting:= false;
- if (CurrentHedgehog^.Gear <> nil) then
- CurrentHedgehog^.Gear^.Invulnerable:= false;
+ // have to sweep *all* current team hedgehogs since it is theoretically possible if you have enough invulnerabilities and switch turns to make your entire team invulnerable
+
+ if (CurrentTeam <> nil) then
+ with CurrentTeam^ do
+ for i:= 0 to cMaxHHIndex do
+ with Hedgehogs[i] do
+ if (Gear <> nil) then
+ Gear^.Invulnerable:= false;
end;
procedure SetAllToActive;
@@ -636,8 +643,8 @@
procedure DrawHH(Gear: PGear);
var t: LongInt;
amt: TAmmoType;
- hx, hy, cx, cy, tx, ty, m: LongInt;
- lx, ly, dx, dy, aAngle, dAngle: real;
+ hx, hy, cx, cy, tx, ty, sx, sy, m: LongInt; // hedgehog, crosshair, temp, sprite`
+ lx, ly, dx, dy, ax, ay, aAngle, dAngle: real; // laser, change
defaultPos, HatVisible: boolean;
begin
if (Gear^.State and gstHHDeath) <> 0 then
@@ -649,23 +656,34 @@
defaultPos:= true;
HatVisible:= false;
+sx:= hwRound(Gear^.X) + 1 + WorldDx;
+sy:= hwRound(Gear^.Y) - 3 + WorldDy;
if (Gear^.State and gstDrowning) <> 0 then
begin
- DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ DrawHedgehog(sx, sy,
hwSign(Gear^.dX),
1,
7,
- 0, Gear^.Invulnerable);
+ 0);
defaultPos:= false
end else
if (Gear^.State and gstWinner) <> 0 then
begin
- DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ DrawHedgehog(sx, sy,
hwSign(Gear^.dX),
2,
0,
- 0, Gear^.Invulnerable);
+ 0);
+ defaultPos:= false
+ end else
+if (Gear^.State and gstLoser) <> 0 then // for now using the jackhammer for its kind of bemused "oops" look
+ begin
+ DrawHedgehog(sx, sy,
+ hwSign(Gear^.dX),
+ 1,
+ 2,
+ 0);
defaultPos:= false
end else
@@ -701,37 +719,39 @@
dAngle:= 180;
m:= -1
end;
- DrawHedgehog(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy,
+ sx:= hwRound(Gear^.X) + WorldDx;
+ sy:= hwRound(Gear^.Y) + WorldDy;
+ DrawHedgehog(sx, sy,
m,
1,
0,
- DxDy2Angle(CurAmmoGear^.dY, CurAmmoGear^.dX) + dAngle, Gear^.Invulnerable);
+ DxDy2Angle(CurAmmoGear^.dY, CurAmmoGear^.dX) + dAngle);
defaultPos:= false
end;
gtBlowTorch: begin
DrawRotated(sprBlowTorch, hx, hy, hwSign(Gear^.dX), aangle);
- DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ DrawHedgehog(sx, sy,
hwSign(Gear^.dX),
3,
PHedgehog(Gear^.Hedgehog)^.visStepPos div 2,
- 0, Gear^.Invulnerable);
+ 0);
defaultPos:= false
end;
gtShover: DrawRotated(sprHandBaseball, hx, hy, hwSign(Gear^.dX), aangle + 180);
gtFirePunch: begin
- DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ DrawHedgehog(sx, sy,
hwSign(Gear^.dX),
1,
4,
- 0, Gear^.Invulnerable);
+ 0);
defaultPos:= false
end;
gtPickHammer,
gtTeleport: defaultPos:= false;
gtWhip: begin
DrawRotatedF(sprWhip,
- hwRound(Gear^.X) + 1 + WorldDx,
- hwRound(Gear^.Y) - 3 + WorldDy,
+ sx,
+ sy,
1,
hwSign(Gear^.dX),
0);
@@ -739,11 +759,11 @@
end;
gtKamikaze: begin
if CurAmmoGear^.Pos = 0 then
- DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ DrawHedgehog(sx, sy,
hwSign(Gear^.dX),
1,
6,
- 0, Gear^.Invulnerable)
+ 0)
else
DrawRotatedF(sprKamikaze,
hwRound(Gear^.X) + WorldDx,
@@ -751,16 +771,15 @@
CurAmmoGear^.Pos - 1,
1,
DxDy2Angle(Gear^.dY, Gear^.dX));
-
defaultPos:= false
end;
gtSeduction: begin
if CurAmmoGear^.Pos >= 6 then
- DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ DrawHedgehog(sx, sy,
hwSign(Gear^.dX),
2,
2,
- 0, Gear^.Invulnerable)
+ 0)
else
begin
DrawRotatedF(sprDress,
@@ -779,11 +798,11 @@
gtShotgunShot,
gtDEagleShot,
gtShover: begin
- DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ DrawHedgehog(sx, sy,
hwSign(Gear^.dX),
0,
4,
- 0, Gear^.Invulnerable);
+ 0);
defaultPos:= false
end
end
@@ -792,27 +811,27 @@
if ((Gear^.State and gstHHJumping) <> 0) then
begin
if ((Gear^.State and gstHHHJump) <> 0) then
- DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ DrawHedgehog(sx, sy,
- hwSign(Gear^.dX),
1,
1,
- 0, Gear^.Invulnerable)
+ 0)
else
- DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ DrawHedgehog(sx, sy,
hwSign(Gear^.dX),
1,
1,
- 0, Gear^.Invulnerable);
+ 0);
defaultPos:= false
end else
if (Gear^.Message and (gm_Left or gm_Right) <> 0) then
begin
- DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ DrawHedgehog(sx, sy,
hwSign(Gear^.dX),
0,
PHedgehog(Gear^.Hedgehog)^.visStepPos div 2,
- 0, Gear^.Invulnerable);
+ 0);
defaultPos:= false;
HatVisible:= true
end
@@ -821,8 +840,8 @@
if ((Gear^.State and gstAnimation) <> 0) then
begin
DrawRotatedF(Wavez[TWave(Gear^.Tag)].Sprite,
- hwRound(Gear^.X) + 1 + WorldDx,
- hwRound(Gear^.Y) - 3 + WorldDy,
+ sx,
+ sy,
Gear^.Pos,
hwSign(Gear^.dX),
0.0);
@@ -849,44 +868,43 @@
case amt of
amAirAttack,
- amMineStrike: DrawRotated(sprHandAirAttack, hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) + WorldDy, hwSign(Gear^.dX), 0);
- amPickHammer: DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ amMineStrike: DrawRotated(sprHandAirAttack, sx, hwRound(Gear^.Y) + WorldDy, hwSign(Gear^.dX), 0);
+ amPickHammer: DrawHedgehog(sx, sy,
hwSign(Gear^.dX),
1,
2,
- 0, Gear^.Invulnerable);
- amBlowTorch: DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ 0);
+ amBlowTorch: DrawHedgehog(sx, sy,
hwSign(Gear^.dX),
1,
3,
- 0, Gear^.Invulnerable);
- amTeleport: DrawRotatedF(sprTeleport, hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy, 0, hwSign(Gear^.dX), 0);
- amKamikaze: DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ 0);
+ amTeleport: DrawRotatedF(sprTeleport, sx, sy, 0, hwSign(Gear^.dX), 0);
+ amKamikaze: DrawHedgehog(sx, sy,
hwSign(Gear^.dX),
1,
5,
- 0, Gear^.Invulnerable);
+ 0);
amWhip: DrawRotatedF(sprWhip,
- hwRound(Gear^.X) + 1 + WorldDx,
- hwRound(Gear^.Y) - 3 + WorldDy,
+ sx,
+ sy,
0,
hwSign(Gear^.dX),
0);
else
- DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ DrawHedgehog(sx, sy,
hwSign(Gear^.dX),
0,
4,
- 0, Gear^.Invulnerable);
+ 0);
HatVisible:= true;
with PHedgehog(Gear^.Hedgehog)^ do
if (HatTex <> nil)
- and (HatVisibility > 0)
- and (not Gear^.Invulnerable) then
+ and (HatVisibility > 0) then
DrawTextureF(HatTex,
HatVisibility,
- hwRound(Gear^.X) + 1 + WorldDx,
+ sx,
hwRound(Gear^.Y) - 8 + WorldDy,
0,
hwSign(Gear^.dX),
@@ -906,28 +924,28 @@
if (Gear^.Damage > 0)
and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then
begin
- DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ DrawHedgehog(sx, sy,
hwSign(Gear^.dX),
2,
1,
- Gear^.DirAngle, Gear^.Invulnerable);
+ Gear^.DirAngle);
defaultPos:= false
end else
if ((Gear^.State and gstHHJumping) <> 0) then
begin
if ((Gear^.State and gstHHHJump) <> 0) then
- DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ DrawHedgehog(sx, sy,
- hwSign(Gear^.dX),
1,
1,
- 0, Gear^.Invulnerable)
+ 0)
else
- DrawHedgehog(hwRound(Gear^.X) + 1 + WorldDx, hwRound(Gear^.Y) - 3 + WorldDy,
+ DrawHedgehog(sx, sy,
hwSign(Gear^.dX),
1,
1,
- 0, Gear^.Invulnerable);
+ 0);
defaultPos:= false
end;
end;
@@ -937,8 +955,8 @@
if defaultPos then
begin
DrawRotatedF(sprHHIdle,
- hwRound(Gear^.X) + 1 + WorldDx,
- hwRound(Gear^.Y) - 3 + WorldDy,
+ sx,
+ sy,
(RealTicks div 128 + Gear^.Pos) mod 19,
hwSign(Gear^.dX),
0);
@@ -953,12 +971,12 @@
if HatVisibility > 0.0 then
HatVisibility:= HatVisibility - 0.2;
- if (HatTex <> nil) and (not Gear^.Invulnerable)
+ if (HatTex <> nil)
and (HatVisibility > 0) then
if DefaultPos then
DrawTextureF(HatTex,
HatVisibility,
- hwRound(Gear^.X) + 1 + WorldDx,
+ sx,
hwRound(Gear^.Y) - 8 + WorldDy,
(RealTicks div 128 + Gear^.Pos) mod 19,
hwSign(Gear^.dX),
@@ -966,7 +984,7 @@
else
DrawTextureF(HatTex,
HatVisibility,
- hwRound(Gear^.X) + 1 + WorldDx,
+ sx,
hwRound(Gear^.Y) - 8 + WorldDy,
0,
hwSign(Gear^.dX),
@@ -1011,22 +1029,21 @@
(* These calculations are a little complex for a few reasons:
1: I need to draw the laser from weapon origin to nearest land
2: I need to start the beam outside the hedgie for attractiveness.
- I can't do the calc from there, or it accumulates more error visible in a deagle shot.
3: I need to extend the beam beyond land.
This routine perhaps should be pushed into uStore or somesuch instead of continuuing the increase in size of this function.
- Additionally, using crosshairs, amusingly, makes the laser imprecise to about 0.05% of a deagle shot. This means that if you are firing across an entire 4096px map your laser will be a few pixels off of the the deagle shot. This is still a lot more accurate than real laser sights - feel free to change if it bothers you.
*)
+ if ((Gear^.State and gstHHHJump) <> 0) then m:= -1 else m:= 1;
+ dx:= hwSign(Gear^.dX) * m * Sin(Gear^.Angle * pi / cMaxAngle);
+ dy:= - Cos(Gear^.Angle * pi / cMaxAngle);
if cLaserSighting then
begin
lx:= hwRound(Gear^.X);
ly:= hwRound(Gear^.Y);
- dx:= hwSign(Gear^.dX) * Sin(Gear^.Angle * pi / cMaxAngle);
- dy:= - Cos(Gear^.Angle * pi / cMaxAngle);
lx:= lx + dx * 16;
ly:= ly + dy * 16;
- dx:= dx * 4;
- dy:= dy * 4;
+ ax:= dx * 4;
+ ay:= dy * 4;
tx:= round(lx);
ty:= round(ly);
@@ -1036,16 +1053,16 @@
((tx and LAND_WIDTH_MASK) = 0) and
(Land[ty, tx] = 0) do
begin
- lx:= lx + dx;
- ly:= ly + dy;
+ lx:= lx + ax;
+ ly:= ly + ay;
tx:= round(lx);
ty:= round(ly)
end;
// reached edge of land. assume infinite beam. Extend it way out past camera
if ((ty and LAND_HEIGHT_MASK) <> 0) or ((tx and LAND_WIDTH_MASK) <> 0) then
begin
- tx:= round(lx + dx * (LAND_WIDTH div 4));
- ty:= round(ly + dy * (LAND_WIDTH div 4));
+ tx:= round(lx + ax * (LAND_WIDTH div 4));
+ ty:= round(ly + ay * (LAND_WIDTH div 4));
end;
//if (abs(lx-tx)>8) or (abs(ly-ty)>8) then
@@ -1062,16 +1079,20 @@
glDisable(GL_LINE_SMOOTH);
end;
end;
- // draw crossahair
- if ((Gear^.State and gstHHHJump) <> 0) then m:= -1 else m:= 1;
- cx:= Round(hwRound(Gear^.X) + hwSign(Gear^.dX) * m * Sin(Gear^.Angle*pi/cMaxAngle) * 80);
- cy:= Round(hwRound(Gear^.Y) - Cos(Gear^.Angle*pi/cMaxAngle) * 80);
+ // draw crosshair
+ cx:= Round(hwRound(Gear^.X) + dx * 80);
+ cy:= Round(hwRound(Gear^.Y) + dy * 80);
DrawRotatedTex(Team^.CrosshairTex,
- 12, 12, cx+WorldDx, cy+WorldDy, 0,
+ 12, 12, cx + WorldDx, cy + WorldDy, 0,
hwSign(Gear^.dX) * (Gear^.Angle * 180.0) / cMaxAngle);
end
end
- end
+ end;
+
+if Gear^.Invulnerable then
+ begin
+ DrawSprite(sprInvulnerable, sx - 24, sy - 24, 0);
+ end;
end;
procedure DrawGears;
@@ -1302,19 +1323,23 @@
//{$IFDEF DEBUGFILE}AddFileLog('Damage: ' + inttostr(dmg));{$ENDIF}
if (Mask and EXPLNoDamage) = 0 then
begin
- if not Gear^.Invulnerable then
- begin
+ if not Gear^.Invulnerable then
+ begin
inc(Gear^.Damage, dmg);
if Gear^.Kind = gtHedgehog then
AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), dmg, PHedgehog(Gear^.Hedgehog)^.Team^.Clan^.Color);
- end;
+ end
+ else
+ Gear^.State:= Gear^.State or gstWinner;
end;
if ((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog) then
begin
DeleteCI(Gear);
Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X - int2hwFloat(X));
Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, Gear^.Y - int2hwFloat(Y));
- Gear^.State:= (Gear^.State or gstMoving) and (not gstWinner);
+ Gear^.State:= Gear^.State or gstMoving;
+ if not Gear^.Invulnerable then
+ Gear^.State:= Gear^.State and (not gstWinner);
Gear^.Active:= true;
FollowGear:= Gear
end;
@@ -1354,7 +1379,9 @@
inc(t^.Damage, dmg);
if t^.Kind = gtHedgehog then
AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), dmg, PHedgehog(t^.Hedgehog)^.Team^.Clan^.Color);
- end;
+ end
+ else
+ Gear^.State:= Gear^.State or gstWinner;
DeleteCI(t);
t^.dX:= t^.dX + Gear^.dX * dmg * _0_01 + SignAs(cHHKick, Gear^.dX);
@@ -1398,7 +1425,9 @@
if (t^.ar[i]^.Kind = gtHedgehog) and (Damage > 0) then
AddDamageTag(hwRound(t^.ar[i]^.X), hwRound(t^.ar[i]^.Y), Damage, PHedgehog(t^.ar[i]^.Hedgehog)^.Team^.Clan^.Color);
- end;
+ end
+ else
+ t^.ar[i]^.State:= t^.ar[i]^.State or gstWinner;
DeleteCI(t^.ar[i]);
t^.ar[i]^.dX:= Ammo^.dX * Power * _0_01;
@@ -1559,9 +1588,9 @@
(CountGears(gtCase) >= 5) or
(getrandom(cCaseFactor) <> 0) then exit;
-FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0);
case getrandom(20) of
0..6: begin
+ FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0);
FollowGear^.Health:= 25;
FollowGear^.Pos:= posCaseHealth
end;
@@ -1570,42 +1599,54 @@
for i:= Low(TAmmoType) to High(TAmmoType) do
if (Ammoz[i].Ammo.Propz and ammoprop_Utility) = 0 then
inc(t, Ammoz[i].Probability);
- t:= GetRandom(t);
- i:= Low(TAmmoType);
- if (Ammoz[i].Ammo.Propz and ammoprop_Utility) = 0 then
- dec(t, Ammoz[i].Probability);
- while t >= 0 do
- begin
- inc(i);
- if (Ammoz[i].Ammo.Propz and ammoprop_Utility) = 0 then
- dec(t, Ammoz[i].Probability)
- end;
- PlaySound(sndReinforce, false, CurrentTeam^.voicepack);
- FollowGear^.Pos:= posCaseAmmo;
- FollowGear^.State:= Longword(i)
+ if (t > 0) then
+ begin
+ FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0);
+ t:= GetRandom(t);
+ i:= Low(TAmmoType);
+ if (Ammoz[i].Ammo.Propz and ammoprop_Utility) = 0 then
+ dec(t, Ammoz[i].Probability);
+ while t >= 0 do
+ begin
+ inc(i);
+ if (Ammoz[i].Ammo.Propz and ammoprop_Utility) = 0 then
+ dec(t, Ammoz[i].Probability)
+ end;
+ FollowGear^.Pos:= posCaseAmmo;
+ FollowGear^.State:= Longword(i)
+ end
end;
- 14..19: begin
+ 14..19: begin
t:= 0;
for i:= Low(TAmmoType) to High(TAmmoType) do
if (Ammoz[i].Ammo.Propz and ammoprop_Utility) <> 0 then
inc(t, Ammoz[i].Probability);
- t:= GetRandom(t);
- i:= Low(TAmmoType);
- if (Ammoz[i].Ammo.Propz and ammoprop_Utility) <> 0 then
- dec(t, Ammoz[i].Probability);
- while t >= 0 do
- begin
- inc(i);
- if (Ammoz[i].Ammo.Propz and ammoprop_Utility) <> 0 then
- dec(t, Ammoz[i].Probability)
- end;
- PlaySound(sndReinforce, false, CurrentTeam^.voicepack);
- FollowGear^.Pos:= posCaseUtility;
- FollowGear^.State:= Longword(i)
+ if (t > 0) then
+ begin
+ FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0);
+ t:= GetRandom(t);
+ i:= Low(TAmmoType);
+ if (Ammoz[i].Ammo.Propz and ammoprop_Utility) <> 0 then
+ dec(t, Ammoz[i].Probability);
+ while t >= 0 do
+ begin
+ inc(i);
+ if (Ammoz[i].Ammo.Propz and ammoprop_Utility) <> 0 then
+ dec(t, Ammoz[i].Probability)
+ end;
+ FollowGear^.Pos:= posCaseUtility;
+ FollowGear^.State:= Longword(i)
+ end
end;
end;
-
-FindPlace(FollowGear, true, 0, LAND_WIDTH)
+// handles case of no ammo or utility crates - considered also placing booleans in uAmmos and altering probabilities
+if (FollowGear <> nil) then
+ begin
+ FindPlace(FollowGear, true, 0, LAND_WIDTH);
+
+ if (FollowGear <> nil) then
+ PlaySound(sndReinforce, false, CurrentTeam^.voicepack)
+ end
end;
procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt);