# HG changeset patch # User nemo # Date 1342322349 14400 # Node ID 15c3fb4882dfc8727d4bf6248329b4382f843f98 # Parent 92535bc7e9288d2246a02c770e9878d435ebd6b0 Sorry about the slight delay in pickup. You can blame a few lame cheaters. This is to make their cheating a bit harder. diff -r 92535bc7e928 -r 15c3fb4882df hedgewars/GSHandlers.inc --- 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; diff -r 92535bc7e928 -r 15c3fb4882df hedgewars/uCommandHandlers.pas --- 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; diff -r 92535bc7e928 -r 15c3fb4882df hedgewars/uGears.pas --- 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; diff -r 92535bc7e928 -r 15c3fb4882df hedgewars/uGearsHedgehog.pas --- 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); diff -r 92535bc7e928 -r 15c3fb4882df hedgewars/uGearsList.pas --- 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 diff -r 92535bc7e928 -r 15c3fb4882df hedgewars/uGearsRender.pas --- 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); diff -r 92535bc7e928 -r 15c3fb4882df hedgewars/uGearsUtils.pas --- 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; diff -r 92535bc7e928 -r 15c3fb4882df hedgewars/uRandom.pas --- 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 diff -r 92535bc7e928 -r 15c3fb4882df hedgewars/uTypes.pas --- 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; diff -r 92535bc7e928 -r 15c3fb4882df hedgewars/uVariables.pas --- 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;