New Weapon: Resurrector (TODO: ammo icon + sprites)
authorTobias Neumann <mail@tobias-neumann.eu>
Mon, 11 Oct 2010 20:34:21 +0200
changeset 3963 6090d2a2472e
parent 3962 e9ee2bd51e08
child 3964 6aadae28b3df
New Weapon: Resurrector (TODO: ammo icon + sprites)
QTfrontend/hwconsts.cpp.in
hedgewars/GSHandlers.inc
hedgewars/GearDrawing.inc
hedgewars/HHHandlers.inc
hedgewars/uAIAmmoTests.pas
hedgewars/uConsts.pas
hedgewars/uGears.pas
hedgewars/uLocale.pas
hedgewars/uStore.pas
share/hedgewars/Data/Locale/en.txt
--- a/QTfrontend/hwconsts.cpp.in	Mon Oct 11 21:41:24 2010 +0400
+++ b/QTfrontend/hwconsts.cpp.in	Mon Oct 11 20:34:21 2010 +0200
@@ -36,10 +36,10 @@
 int cMaxTeams = 6;
 
 QString * cDefaultAmmoStore = new QString(
-        "939192942219912103223511100120100000021111010101"
-        "040504054160065554655446477657666666615551010111"
-        "000000000000020550000004000700400000000020000000"
-        "131111031211111112311411111111111111121111110111"
+        "9391929422199121032235111001201000000211110101011"
+        "0405040541600655546554464776576666666155510101117"
+        "0000000000000205500000040007004000000000200000000"
+        "1311110312111111123114111111111111111211111101111"
 		);
 int cAmmoNumber = cDefaultAmmoStore->size() / 4;
 
@@ -47,30 +47,30 @@
 	QList< QPair<QString, QString> >()
 	<< qMakePair(QString("Default"), *cDefaultAmmoStore)
 	<< qMakePair(QString("Crazy"),     QString(
-        "999999999999999999299999999999999929999999990999" // TODO: Remove Piano's unlimited uses!
-        "111111011111111111111111111111111111111111110111"
-        "000000000000000000000000000000000000000000000000"
-        "131111031211111112311411111111111111121111010111"))
+        "9999999999999999992999999999999999299999999909999" // TODO: Remove Piano's unlimited uses!
+        "1111110111111111111111111111111111111111111101111"
+        "0000000000000000000000000000000000000000000000000"
+        "1311110312111111123114111111111111111211110101111"))
 	<< qMakePair(QString("Pro mode"),  QString(
-        "909000900000000000000900000000000000000000000000"
-        "000000000000000000000000000000000000000000000000"
-        "000000000000020550000004000700400000000020000000"
-        "111111111111111111111111111111111111111110010111"))
+        "9090009000000000000009000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000"
+        "0000000000000205500000040007004000000000200000000"
+        "1111111111111111111111111111111111111111100101111"))
 	<< qMakePair(QString("Shoppa"),    QString(
-        "000000990000000000000000000000000000000000000000"
-        "444441004424440221011212122242200000000200040001"
-        "000000000000000000000000000000000000000000000000"
-        "111111111111111111111111111111111111111110110111"))
+        "0000009900000000000000000000000000000000000000000"
+        "4444410044244402210112121222422000000002000400010"
+        "0000000000000000000000000000000000000000000000000"
+        "1111111111111111111111111111111111111111101101111"))
 	<< qMakePair(QString("Basketball"),QString(
-		"000000900000090000000000000000000000000000000000"
-		"000000000000000000000000000000000000000000000000"
-		"000000000000000550000004000700400000000020000000"
-		"111111111111111111111111111111111111111111110111"))
+		"0000009000000900000000000000000000000000000000000"
+		"0000000000000000000000000000000000000000000000000"
+		"0000000000000005500000040007004000000000200000000"
+		"1111111111111111111111111111111111111111111101111"))
 	<< qMakePair(QString("Minefield"), QString(
-		"000000990009000000030000000000000000000000000000"
-		"000000000000000000000000000000000000000000000000"
-		"000000000000020550000004000700400000000020000000"
-		"111111111111111111111111111111111111111111110111"))
+		"0000009900090000000300000000000000000000000000000"
+		"0000000000000000000000000000000000000000000000000"
+		"0000000000000205500000040007004000000000200000000"
+		"1111111111111111111111111111111111111111111101111"))
 	;
 
 QColor *colors[] = {
--- a/hedgewars/GSHandlers.inc	Mon Oct 11 21:41:24 2010 +0400
+++ b/hedgewars/GSHandlers.inc	Mon Oct 11 20:34:21 2010 +0200
@@ -4084,3 +4084,80 @@
     doStepHammerHitWork(Gear);
     Gear^.doStep := @doStepHammerHitWork
 end;
+
+
+procedure doStepResurrectorWork(Gear: PGear);
+var
+    graves: TPGearArray;
+    resgear: PGear;
+    hh: PHedgehog;
+    i: LongInt;
+begin
+    AllInactive := false;
+    hh := PHedgehog(Gear^.Hedgehog);
+    RenderHealth(hh^);
+    DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy -
+            cHHRadius - 14 - hh^.HealthTagTex^.h, hh^.HealthTagTex);
+    DrawCircle(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Radius, 1.5, 0, 0, $FF,
+            $FF);
+
+    if ((Gear^.Message and gmUp) <> 0) then begin
+        if (GameTicks and $F) <> 0 then exit;
+    end else begin
+        if (GameTicks and $1FF) <> 0 then exit;
+    end;
+
+    graves := GearsNear(hh^.Gear, gtGrave, Gear^.Radius);
+
+    if ((Gear^.Message and gmAttack) <> 0) and (hh^.Gear^.Health > 0) then begin
+        i := getRandom(Length(graves));
+        writeln(i);
+        dec(hh^.Gear^.Health);
+        inc(graves[i]^.Health);
+{-for i:= 0 to High(graves) do begin
+            if hh^.Gear^.Health > 0 then begin
+                dec(hh^.Gear^.Health);
+                inc(graves[i]^.Health);
+            end;
+        end; -}
+    end else begin
+        // now really resurrect the hogs with the hp saved in the graves
+        for i:= 0 to High(graves) do begin
+            if graves[i]^.Health > 0 then begin
+                resgear := AddGear(hwRound(graves[i]^.X), hwRound(graves[i]^.Y),
+                        gtHedgehog, gstWait, _0, _0, 0);
+                resgear^.Hedgehog := graves[i]^.Hedgehog;
+                resgear^.Health := graves[i]^.Health;
+                PHedgehog(graves[i]^.Hedgehog)^.Gear := resgear;
+                DeleteGear(graves[i]);
+                RenderHealth(PHedgehog(resgear^.Hedgehog)^);
+                RecountTeamHealth(Phedgehog(resgear^.Hedgehog)^.Team);
+            end;
+        end;
+        Gear^.Timer := 250;
+        Gear^.doStep := @doStepIdle;
+    end;
+end;
+
+procedure doStepResurrector(Gear: PGear);
+var
+    graves: TPGearArray;
+    hh: PHedgehog;
+    i: LongInt;
+begin
+    AllInactive := false;
+    hh := PHedgehog(Gear^.Hedgehog);
+    graves := GearsNear(hh^.Gear, gtGrave, Gear^.Radius);
+
+    if Length(graves) > 0 then begin
+        for i:= 0 to High(graves) do begin
+            PHedgehog(graves[i]^.Hedgehog)^.Gear := nil;
+            graves[i]^.Health := 0;
+        end;
+        Gear^.doStep := @doStepResurrectorWork;
+    end else begin
+        Gear^.Timer := 250;
+        Gear^.doStep := @doStepIdle;
+    end;
+end;
+
--- a/hedgewars/GearDrawing.inc	Mon Oct 11 21:41:24 2010 +0400
+++ b/hedgewars/GearDrawing.inc	Mon Oct 11 20:34:21 2010 +0200
@@ -277,6 +277,9 @@
                         0);
                 defaultPos:= false
                 end;
+            gtResurrector: begin
+                // yet to come?
+            end;
             gtKamikaze: begin
                 if CurAmmoGear^.Pos = 0 then
                     DrawHedgehog(sx, sy,
@@ -431,6 +434,10 @@
                 end;
             amBee: DrawRotatedF(sprHandBee, hx, hy, (RealTicks div 125) mod 4, hwSign(Gear^.dX), aangle);
             amFlamethrower: DrawRotatedF(sprHandFlamethrower, hx, hy, (RealTicks div 125) mod 4, hwSign(Gear^.dX), aangle);
+            amResurrector: begin
+                DrawCircle(hwRound(Gear^.X), hwRound(Gear^.y), 100, 1.5, 0, 0,
+                        $FF, $FF); // I'd rather not like to hardcore 100 here
+            end;
         end;
 
         case amt of
--- a/hedgewars/HHHandlers.inc	Mon Oct 11 21:41:24 2010 +0400
+++ b/hedgewars/HHHandlers.inc	Mon Oct 11 20:34:21 2010 +0200
@@ -268,6 +268,9 @@
                                PauseMusic
                                end;
                       amFlamethrower: CurAmmoGear:= AddGear(hwRound(X), hwRound(Y), gtFlamethrower,  0, xx * _0_5, yy * _0_5, 0);
+                    amResurrector: CurAmmoGear:= AddGear(hwRound(lx),
+                                           hwRound(ly), gtResurrector, 0, _0,
+                                           _0, 0);
                   end;
 
         uStats.AmmoUsed(CurAmmoType);
--- a/hedgewars/uAIAmmoTests.pas	Mon Oct 11 21:41:24 2010 +0400
+++ b/hedgewars/uAIAmmoTests.pas	Mon Oct 11 20:34:21 2010 +0200
@@ -100,7 +100,8 @@
             (proc: @TestShotgun;     flags: 0), // amSineGun
             (proc: nil;              flags: 0), // amFlamethrower
             (proc: @TestGrenade;     flags: 0), // amSMine
-            (proc: @TestFirePunch;   flags: 0)  // amHammer
+            (proc: @TestFirePunch;   flags: 0), // amHammer
+            (proc: nil;              flags: 0) // amResurrector
             );
 
 const BadTurn = Low(LongInt) div 4;
--- a/hedgewars/uConsts.pas	Mon Oct 11 21:41:24 2010 +0400
+++ b/hedgewars/uConsts.pas	Mon Oct 11 20:34:21 2010 +0200
@@ -74,7 +74,7 @@
             sprBigExplosion, sprSmokeRing, sprBeeTrace, sprEgg, sprTargetBee, sprHandBee,
             sprFeather, sprPiano, sprHandSineGun, sprPortalGun, sprPortal,
             sprCheese, sprHandCheese, sprHandFlamethrower, sprChunk, sprNote,
-            sprSMineOff, sprSMineOn, sprHandSMine, sprHammer
+            sprSMineOff, sprSMineOn, sprHandSMine, sprHammer, sprResurrector
             );
 
     // Gears that interact with other Gears and/or Land
@@ -88,7 +88,7 @@
             gtHellishBomb, gtWaterUp, gtDrill, gtBallGun, gtBall, gtRCPlane, // 40
             gtSniperRifleShot, gtJetpack, gtMolotov, gtExplosives, gtBirdy, // 45
             gtEgg, gtPortal, gtPiano, gtGasBomb, gtSineGunShot, gtFlamethrower, // 51
-            gtSMine, gtPoisonCloud, gtHammer, gtHammerHit);
+            gtSMine, gtPoisonCloud, gtHammer, gtHammerHit, gtResurrector);
 
     // Gears that are _only_ of visual nature (e.g. background stuff, visual effects, speechbubbles, etc.)
     TVisualGearType = (vgtFlake, vgtCloud, vgtExplPart, vgtExplPart2, vgtFire,
@@ -132,7 +132,8 @@
             amSeduction, amWatermelon, amHellishBomb, amNapalm, amDrill, amBallgun, // 30
             amRCPlane, amLowGravity, amExtraDamage, amInvulnerable, amExtraTime, // 35
             amLaserSight, amVampiric, amSniperRifle, amJetpack, amMolotov, amBirdy, amPortalGun, // 42
-            amPiano, amGasBomb, amSineGun, amFlamethrower, amSMine, amHammer); // 48
+            amPiano, amGasBomb, amSineGun, amFlamethrower, amSMine, amHammer, // 48
+            amResurrector);
 
     TCrateType = (HealthCrate, AmmoCrate, UtilityCrate);
 
@@ -815,7 +816,11 @@
             (FileName:   'amSMine'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
             Width:  64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprHandSMine
             (FileName:  'amHammer'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
-            Width: 128; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true) // sprWhip
+            Width: 128; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true), // sprWhip
+            (FileName: 'amResurrector'; Path: ptHedgehog; AltPath: ptNone;
+                Texture: nil; Surface: nil; Width: 128; Height: 64;
+                imageWidth: 0; imageHeight: 0; saveSurf: false; priority:
+                tpMedium; getDimensions: false; getImageDimensions: true) 
             );
 
     Wavez: array [TWave] of record
@@ -2169,8 +2174,31 @@
             PosCount: 1;
             PosSprite: sprWater;
             ejectX: 0;
+            ejectY: 0),
+
+        (NameId: sidResurrector;
+            NameTex: nil;
+            Probability: 0;
+            NumberInCase: 1;
+            Ammo: (Propz: ammoprop_NoCrosshair;
+                Count: 1;
+                NumPerTurn: 0;
+                Timer: 0;
+                Pos: 0;
+                AmmoType: amResurrector;
+                AttackVoice: sndNone);
+            Slot: 8;
+            TimeAfterTurn: 3000;
+            minAngle: 0;
+            maxAngle: 0;
+            isDamaging: true;
+            SkipTurns: 0;
+            PosCount: 1;
+            PosSprite: sprWater;
+            ejectX: 0;
             ejectY: 0)
-            );
+        );
+
 
 
     conversionFormat: TSDL_PixelFormat = (
--- a/hedgewars/uGears.pas	Mon Oct 11 21:41:24 2010 +0400
+++ b/hedgewars/uGears.pas	Mon Oct 11 20:34:21 2010 +0200
@@ -62,6 +62,7 @@
             SoundChannel: LongInt;
             PortalCounter: LongWord  // Hopefully temporary, but avoids infinite portal loops in a guaranteed fashion.
         end;
+    TPGearArray = Array of PGear;
 
 var AllInactive: boolean;
     PrvInactive: boolean;
@@ -120,6 +121,7 @@
 procedure doMakeExplosion(X, Y, Radius: LongInt; Mask, Tint: LongWord); forward;
 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); forward;
 //procedure AmmoFlameWork(Ammo: PGear); forward;
+function GearsNear(Gear: PGear; Kind: TGearType; r: LongInt): TPGearArray; forward;
 function  CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear; forward;
 procedure SpawnBoxOfSmth; forward;
 procedure AfterAttack; forward;
@@ -206,7 +208,8 @@
             @doStepSMine,
             @doStepPoisonCloud,
             @doStepHammer,
-            @doStepHammerHit
+            @doStepHammerHit,
+            @doStepResurrector
             );
 
 procedure InsertGearToList(Gear: PGear);
@@ -533,7 +536,11 @@
                 gear^.Timer:= 5000;
                 gear^.dY:= int2hwfloat((-4 + getRandom(8))) / 1000;
                 end;
-     end;
+ gtResurrector: begin
+                gear^.Radius := 100;
+                end;
+    end;
+
 InsertGearToList(gear);
 AddGear:= gear;
 
@@ -1512,6 +1519,25 @@
     end
 end;
 
+function GearsNear(Gear: PGear; Kind: TGearType; r: LongInt): TPGearArray;
+var
+    t: PGear;
+begin
+    GearsNear := nil;
+    t := GearsList;
+    while t <> nil do begin
+        if (t <> Gear) and (t^.Kind = Kind) then begin
+            if (Gear^.X - t^.X)*(Gear^.X - t^.X) + (Gear^.Y -
+                   t^.Y)*(Gear^.Y-t^.Y) < int2hwFloat(r)*int2hwFloat(r) then
+            begin
+                SetLength(GearsNear, Length(GearsNear)+1);
+                GearsNear[High(GearsNear)] := t;
+            end;
+        end;
+        t := t^.NextGear;
+    end;
+end;
+
 function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
 var t: PGear;
 begin
--- a/hedgewars/uLocale.pas	Mon Oct 11 21:41:24 2010 +0400
+++ b/hedgewars/uLocale.pas	Mon Oct 11 20:34:21 2010 +0200
@@ -30,7 +30,7 @@
             sidLowGravity, sidExtraDamage, sidInvulnerable, sidExtraTime,
             sidLaserSight, sidVampiric, sidSniperRifle, sidJetpack,
             sidMolotov, sidBirdy, sidPortalGun, sidPiano, sidGasBomb, sidSineGun, sidFlamethrower,
-            sidSMine, sidHammer);
+            sidSMine, sidHammer, sidResurrector);
 
     TMsgStrId = (sidStartFight, sidDraw, sidWinner, sidVolume, sidPaused,
             sidConfirm, sidSuddenDeath, sidRemaining, sidFuel, sidSync,
--- a/hedgewars/uStore.pas	Mon Oct 11 21:41:24 2010 +0400
+++ b/hedgewars/uStore.pas	Mon Oct 11 20:34:21 2010 +0200
@@ -20,7 +20,7 @@
 
 unit uStore;
 interface
-uses sysutils, uConsts, uTeams, SDLh, GLunit;
+uses sysutils, uConsts, uTeams, SDLh, GLunit, uWorld;
 
 
 var PixelFormat: PSDL_PixelFormat;
@@ -58,6 +58,7 @@
 procedure DrawFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
 procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real);
 procedure DrawFillRect(r: TSDL_Rect);
+procedure DrawCircle(X, Y, Radius: LongInt; Width: Single; r, g, b, a: Byte); 
 procedure DrawRoundRect(rect: PSDL_Rect; BorderColor, FillColor: Longword; Surface: PSDL_Surface; Clear: boolean);
 function  CheckCJKFont(s: ansistring; font: THWFont): THWFont;
 function  RenderStringTex(s: ansistring; Color: Longword; font: THWFont): PTexture;
@@ -819,6 +820,29 @@
 glEnable(GL_TEXTURE_2D)
 end;
 
+procedure DrawCircle(X, Y, Radius: LongInt; Width: Single; r, g, b, a: Byte); 
+var
+    i: LongInt;
+    CircleVertex: array [0..359] of TVertex2f;
+begin
+    for i := 0 to 359 do begin
+        CircleVertex[i].X := X + Radius*cos(i*pi/180);
+        CircleVertex[i].Y := Y + Radius*sin(i*pi/180);
+    end;
+    glDisable(GL_TEXTURE_2D);
+    glEnable(GL_LINE_SMOOTH);
+    glPushMatrix;
+    glTranslatef(WorldDx, WorldDy, 0);
+    glLineWidth(Width);
+    Tint(r, g, b, a);
+    glVertexPointer(2, GL_FLOAT, 0, @CircleVertex[0]);
+    glDrawArrays(GL_LINE_LOOP, 0, 360);
+    Tint($FF, $FF, $FF, $FF);
+    glPopMatrix;
+    glEnable(GL_TEXTURE_2D);
+    glDisable(GL_LINE_SMOOTH);
+end;
+
 procedure StoreRelease;
 var ii: TSprite;
 begin
--- a/share/hedgewars/Data/Locale/en.txt	Mon Oct 11 21:41:24 2010 +0400
+++ b/share/hedgewars/Data/Locale/en.txt	Mon Oct 11 20:34:21 2010 +0200
@@ -49,6 +49,7 @@
 00:46=Flamethrower
 00:47=Sticky Mine
 00:48=Hammer
+00:49=Resurrector
 
 01:00=Let's fight!
 01:01=Round draw