Sorry about the slight delay in pickup. You can blame a few lame cheaters. This is to make their cheating a bit harder.
--- a/hedgewars/GSHandlers.inc Fri Jul 13 13:21:52 2012 +0400
+++ b/hedgewars/GSHandlers.inc Sat Jul 14 23:19:09 2012 -0400
@@ -5532,3 +5532,37 @@
end
end;
end;
+
+procedure doStepAddAmmo(Gear: PGear);
+var a: TAmmoType;
+ gi: PGear;
+begin
+if Gear^.Timer > 0 then dec(Gear^.Timer)
+else
+ begin
+ if Gear^.Pos = posCaseUtility then
+ a:= GetUtility(Gear^.Hedgehog)
+ else
+ a:= GetAmmo(Gear^.Hedgehog);
+ CheckSum:= CheckSum xor GameTicks;
+ gi := GearsList;
+ while gi <> nil do
+ begin
+ with gi^ do CheckSum:= CheckSum xor X.round xor X.frac xor dX.round xor dX.frac xor Y.round xor Y.frac xor dY.round xor dY.frac;
+ AddRandomness(CheckSum);
+ gi := gi^.NextGear
+ end;
+ AddPickup(Gear^.Hedgehog^, a, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y));
+ DeleteGear(Gear)
+ end;
+end;
+
+procedure doStepGenericFaller(Gear: PGear);
+begin
+if Gear^.Timer > 0 then
+ begin
+ doStepFallingGear(Gear);
+ dec(Gear^.Timer)
+ end
+else DeleteGear(Gear)
+end;
--- a/hedgewars/uCommandHandlers.pas Fri Jul 13 13:21:52 2012 +0400
+++ b/hedgewars/uCommandHandlers.pas Sat Jul 14 23:19:09 2012 -0400
@@ -412,18 +412,19 @@
end;
procedure chNextTurn(var s: shortstring);
-var checksum: Longword;
+var i: Longword;
gi: PGear;
begin
s:= s; // avoid compiler hint
TryDo(AllInactive, '/nextturn called when not all gears are inactive', true);
- checksum:= GameTicks;
+ CheckSum:= CheckSum xor GameTicks;
gi := GearsList;
while gi <> nil do
begin
- with gi^ do checksum:= checksum xor X.round xor X.frac xor dX.round xor dX.frac xor Y.round xor Y.frac xor dY.round xor dY.frac;
+ with gi^ do CheckSum:= CheckSum xor X.round xor X.frac xor dX.round xor dX.frac xor Y.round xor Y.frac xor dY.round xor dY.frac;
+ AddRandomness(CheckSum);
gi := gi^.NextGear
end;
@@ -431,11 +432,11 @@
begin
s[0]:= #5;
s[1]:= 'N';
- SDLNet_Write32(checksum, @s[2]);
+ SDLNet_Write32(CheckSum, @s[2]);
SendIPC(s)
end
else
- TryDo(checksum = lastTurnChecksum, 'Desync detected', true);
+ TryDo(CheckSum = lastTurnChecksum, 'Desync detected', true);
AddFileLog('Next turn: time '+inttostr(GameTicks));
end;
--- a/hedgewars/uGears.pas Fri Jul 13 13:21:52 2012 +0400
+++ b/hedgewars/uGears.pas Sat Jul 14 23:19:09 2012 -0400
@@ -1313,7 +1313,9 @@
@doStepStructure,
@doStepLandGun,
@doStepTardis,
- @doStepIceGun);
+ @doStepIceGun,
+ @doStepAddAmmo,
+ @doStepGenericFaller);
begin
doStepHandlers:= handlers;
--- a/hedgewars/uGearsHedgehog.pas Fri Jul 13 13:21:52 2012 +0400
+++ b/hedgewars/uGearsHedgehog.pas Sat Jul 14 23:19:09 2012 -0400
@@ -28,6 +28,7 @@
procedure doStepHedgehogMoving(Gear: PGear);
procedure HedgehogChAngle(HHGear: PGear);
procedure PickUp(HH, Gear: PGear);
+procedure AddPickup(HH: THedgehog; ammo: TAmmoType; cnt, X, Y: LongWord);
implementation
uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions,
@@ -565,15 +566,41 @@
end
end;
+procedure AddPickup(HH: THedgehog; ammo: TAmmoType; cnt, X, Y: LongWord);
+var s: shortstring;
+ vga: PVisualGear;
+begin
+ PlaySound(sndShotgunReload);
+ if cnt <> 0 then AddAmmo(HH, ammo, cnt)
+ else AddAmmo(HH, ammo);
+
+ if (not (HH.Team^.ExtDriven
+ or (HH.BotLevel > 0)))
+ or (HH.Team^.Clan^.ClanIndex = LocalClan)
+ or (GameType = gmtDemo) then
+ begin
+ if cnt <> 0 then
+ s:= trammo[Ammoz[ammo].NameId] + ' (+' + IntToStr(cnt) + ')'
+ else
+ s:= trammo[Ammoz[ammo].NameId] + ' (+' + IntToStr(Ammoz[ammo].NumberInCase) + ')';
+ AddCaption(s, HH.Team^.Clan^.Color, capgrpAmmoinfo);
+
+ // show ammo icon
+ vga:= AddVisualGear(X, Y, vgtAmmo);
+ if vga <> nil then
+ vga^.Frame:= Longword(ammo);
+ end;
+end;
+
////////////////////////////////////////////////////////////////////////////////
procedure PickUp(HH, Gear: PGear);
var s: shortstring;
a: TAmmoType;
i: LongInt;
vga: PVisualGear;
+ ag: PGear;
begin
Gear^.Message:= gmDestroy;
-PlaySound(sndShotgunReload);
if (Gear^.Pos and posCaseExplode) <> 0 then
if (Gear^.Pos and posCasePoison) <> 0 then
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, HH^.Hedgehog, EXPLAutoSound + EXPLPoisoned)
@@ -585,39 +612,24 @@
case Gear^.Pos of
posCaseUtility,
posCaseAmmo: begin
- if Gear^.AmmoType <> amNothing then a:= Gear^.AmmoType
+ if Gear^.AmmoType <> amNothing then
+ begin
+ AddPickup(HH^.Hedgehog^, Gear^.AmmoType, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y));
+ end
else
begin
- for i:= 0 to GameTicks and $7F do
- GetRandom(2); // Burn some random numbers
- if Gear^.Pos = posCaseUtility then
- a:= GetUtility(HH^.Hedgehog)
- else
- a:= GetAmmo(HH^.Hedgehog)
+// Add spawning here...
+ AddRandomness(CheckSum xor GameTicks);
+ for i:= 0 to GetRandom(50)+50 do
+ AddGear(GetRandom(rightX-leftX)+leftX, GetRandom(LAND_HEIGHT-topY)+topY, gtGenericFaller,
+ gstInvisible, _90-(GetRandomf*_360), _90-(GetRandomf*_360), GetRandom(500));
+ ag:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAddAmmo, gstInvisible, _0, _0, GetRandom(200)+100);
+ ag^.Pos:= Gear^.Pos;
+ ag^.Power:= Gear^.Power
end;
- if Gear^.Power <> 0 then AddAmmo(HH^.Hedgehog^, a, Gear^.Power)
- else AddAmmo(HH^.Hedgehog^, a);
-// Possibly needs to check shared clan ammo game flag once added.
-// On the other hand, no obvious reason that clan members shouldn't know what ammo another clan member picked up
- if (not (HH^.Hedgehog^.Team^.ExtDriven
- or (HH^.Hedgehog^.BotLevel > 0)))
- or (HH^.Hedgehog^.Team^.Clan^.ClanIndex = LocalClan)
- or (GameType = gmtDemo) then
- begin
- if Gear^.Power <> 0 then
- s:= trammo[Ammoz[a].NameId] + ' (+' + IntToStr(Gear^.Power) + ')'
- else
- s:= trammo[Ammoz[a].NameId] + ' (+' + IntToStr(Ammoz[a].NumberInCase) + ')';
- AddCaption(s, HH^.Hedgehog^.Team^.Clan^.Color, capgrpAmmoinfo);
-
- // show ammo icon
- vga:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtAmmo);
- if vga <> nil then
- vga^.Frame:= Longword(a);
- end;
-
end;
posCaseHealth: begin
+ PlaySound(sndShotgunReload);
inc(HH^.Health, Gear^.Health);
HH^.Hedgehog^.Effects[hePoisoned] := 0;
str(Gear^.Health, s);
@@ -1224,6 +1236,7 @@
land: Word; *)
var slope: hwFloat;
begin
+CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel;
if (Gear^.Message and gmDestroy) <> 0 then
begin
DeleteGear(Gear);
--- a/hedgewars/uGearsList.pas Fri Jul 13 13:21:52 2012 +0400
+++ b/hedgewars/uGearsList.pas Sat Jul 14 23:19:09 2012 -0400
@@ -460,6 +460,13 @@
gear^.Pos:= 1;
end;
gtIceGun: gear^.Health:= 1000;
+gtGenericFaller:begin
+ gear^.AdvBounce:= 1;
+ gear^.Radius:= 1;
+ gear^.Elasticity:= _0_9;
+ gear^.Friction:= _0_995;
+ gear^.Density:= _1;
+ end;
end;
InsertGearToList(gear);
@@ -557,8 +564,10 @@
end
end;
with Gear^ do
+ begin
AddFileLog('Delete: #' + inttostr(uid) + ' (' + inttostr(hwRound(x)) + ',' + inttostr(hwRound(y)) + '), d(' + floattostr(dX) + ',' + floattostr(dY) + ') type = ' + EnumToStr(Kind));
-
+ AddRandomness(X.round xor X.frac xor dX.round xor dX.frac xor Y.round xor Y.frac xor dY.round xor dY.frac)
+ end;
if CurAmmoGear = Gear then
CurAmmoGear:= nil;
if FollowGear = Gear then
--- a/hedgewars/uGearsRender.pas Fri Jul 13 13:21:52 2012 +0400
+++ b/hedgewars/uGearsRender.pas Sat Jul 14 23:19:09 2012 -0400
@@ -21,7 +21,7 @@
unit uGearsRender;
interface
-uses uTypes, uConsts, GLunit, uFloat, SDLh;
+uses uTypes, uConsts, GLunit, uFloat, SDLh, uRandom;
procedure RenderGear(Gear: PGear; x, y: LongInt);
@@ -287,6 +287,7 @@
dy:= -Cos(Gear^.Angle * pi / cMaxAngle);
if cLaserSighting then
begin
+ GetRandom(2); // no, this does not prevent it, just makes things harder
lx:= GetLaunchX(HH^.CurAmmoType, sign * m, Gear^.Angle);
ly:= GetLaunchY(HH^.CurAmmoType, Gear^.Angle);
@@ -1213,9 +1214,8 @@
else DrawLine(hwRound(HHGear^.X), hwRound(HHGear^.Y), hwRound(Gear^.X), hwRound(Gear^.Y), 4.0, i, i, $FF, $40);
end
end
- end
-
-
+ end;
+ gtGenericFaller: DrawCircle(x, y, 3, 3, $FF, $00, $00, $FF); // debug
end;
if Gear^.RenderTimer and (Gear^.Tex <> nil) then
DrawTextureCentered(x + 8, y + 8, Gear^.Tex);
--- a/hedgewars/uGearsUtils.pas Fri Jul 13 13:21:52 2012 +0400
+++ b/hedgewars/uGearsUtils.pas Sat Jul 14 23:19:09 2012 -0400
@@ -343,6 +343,11 @@
Y:= hwRound(Gear^.Y);
if cWaterLine < Y + Gear^.Radius then
begin
+ if Gear^.State and gstInvisible <> 0 then
+ begin
+ DeleteGear(Gear);
+ exit
+ end;
isSubmersible:= (Gear = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) and (CurAmmoGear^.AmmoType = amJetpack);
skipSpeed := _0_25;
skipAngle := _1_9;
--- a/hedgewars/uRandom.pas Fri Jul 13 13:21:52 2012 +0400
+++ b/hedgewars/uRandom.pas Sat Jul 14 23:19:09 2012 -0400
@@ -35,15 +35,23 @@
procedure SetRandomSeed(Seed: shortstring); // Sets the seed that should be used for generating pseudo-random values.
function GetRandomf: hwFloat; overload; // Returns a pseudo-random hwFloat.
-function GetRandom(m: LongWord): LongWord; overload; // Returns a positive pseudo-random integer smaller than m.
+function GetRandom(m: LongWord): LongWord; overload; inline; // Returns a positive pseudo-random integer smaller than m.
+procedure AddRandomness(r: LongWord); inline;
function rndSign(num: hwFloat): hwFloat; // Returns num with a random chance of having a inverted sign.
+
implementation
var cirbuf: array[0..63] of Longword;
n: byte;
-function GetNext: Longword;
+procedure AddRandomness(r: LongWord); inline;
+begin
+n:= (n + 1) and $3F;
+cirbuf[n]:= cirbuf[n] xor r
+end;
+
+function GetNext: Longword; inline;
begin
n:= (n + 1) and $3F;
cirbuf[n]:=
@@ -79,7 +87,7 @@
GetRandomf.QWordValue:= GetNext
end;
-function GetRandom(m: LongWord): LongWord;
+function GetRandom(m: LongWord): LongWord; inline;
begin
GetNext;
GetRandom:= GetNext mod m
--- a/hedgewars/uTypes.pas Fri Jul 13 13:21:52 2012 +0400
+++ b/hedgewars/uTypes.pas Sat Jul 14 23:19:09 2012 -0400
@@ -102,7 +102,7 @@
gtSniperRifleShot, gtJetpack, gtMolotov, gtBirdy, // 44
gtEgg, gtPortal, gtPiano, gtGasBomb, gtSineGunShot, gtFlamethrower, // 50
gtSMine, gtPoisonCloud, gtHammer, gtHammerHit, gtResurrector, // 55
- gtNapalmBomb, gtSnowball, gtFlake, gtStructure, gtLandGun, gtTardis, gtIceGun); // 62
+ gtNapalmBomb, gtSnowball, gtFlake, gtStructure, gtLandGun, gtTardis, gtIceGun, gtAddAmmo, gtGenericFaller); // 62
// Gears that are _only_ of visual nature (e.g. background stuff, visual effects, speechbubbles, etc.)
TVisualGearType = (vgtFlake, vgtCloud, vgtExplPart, vgtExplPart2, vgtFire,
@@ -340,6 +340,8 @@
HatTex: PTexture;
Ammo: PHHAmmo;
CurAmmoType: TAmmoType;
+ PickUpType: LongWord;
+ PickUpDelay: LongInt;
AmmoStore: Longword;
Team: PTeam;
MultiShootAttacks: Longword;
--- a/hedgewars/uVariables.pas Fri Jul 13 13:21:52 2012 +0400
+++ b/hedgewars/uVariables.pas Sat Jul 14 23:19:09 2012 -0400
@@ -64,6 +64,7 @@
fastUntilLag : boolean;
autoCameraOn : boolean;
+ CheckSum : LongWord;
GameTicks : LongWord;
GameState : TGameState;
GameType : TGameType;
@@ -2368,6 +2369,8 @@
(* gtLandGun *) , amLandGun
(* gtTardis *) , amTardis
(* gtIceGun *) , amIceGun
+(* gtAddAmmo *) , amNothing
+(* gtGenericFaller *) , amNothing
);
var
@@ -2530,6 +2533,7 @@
CursorMovementX := 0;
CursorMovementY := 0;
GameTicks := 0;
+ CheckSum := 0;
cWaterLine := LAND_HEIGHT;
cGearScrEdgesDist := 240;