# HG changeset patch # User unc0rr # Date 1136501745 0 # Node ID c1ec4b15d70ec1137a3710d282e7577f2fd51733 # Parent 2b7f2a43b999d269d1c1298ea83cfcc033f336bc Better Desert Eagle and Shotgun diff -r 2b7f2a43b999 -r c1ec4b15d70e hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Thu Jan 05 15:54:22 2006 +0000 +++ b/hedgewars/GSHandlers.inc Thu Jan 05 22:55:45 2006 +0000 @@ -53,7 +53,7 @@ procedure CheckHHDamage(Gear: PGear); begin -if Gear.dY > 0.35 then Gear.Damage:= Gear.Damage + round(25 * (abs(Gear.dY) - 0.35)); +if Gear.dY > 0.35 then Gear.Damage:= Gear.Damage + round(75 * (abs(Gear.dY) - 0.35)); end; //////////////////////////////////////////////////////////////////////////////// @@ -131,7 +131,6 @@ begin doMakeExplosion(round(Gear.X), round(Gear.Y), 50, EXPLAutoSound); DeleteGear(Gear); - SetAllToActive; exit end; CalcRotationDirAngle(Gear); @@ -148,7 +147,6 @@ begin doMakeExplosion(round(Gear.X), round(Gear.Y), 50, EXPLAutoSound); DeleteGear(Gear); - SetAllToActive; exit end; if (GameTicks and $3F) = 0 then @@ -209,7 +207,6 @@ begin doMakeExplosion(round(Gear.X), round(Gear.Y), 50, EXPLAutoSound); DeleteGear(Gear); - SetAllToActive end; end; @@ -224,7 +221,6 @@ begin doMakeExplosion(round(Gear.X), round(Gear.Y), 50, EXPLAutoSound); DeleteGear(Gear); - SetAllToActive; exit end; dec(Gear.Timer); @@ -238,6 +234,7 @@ //////////////////////////////////////////////////////////////////////////////// procedure doStepShotgunShot(Gear: PGear); var i: LongWord; + t: PGear; begin AllInactive:= false; if Gear.Timer > 0 then @@ -253,9 +250,12 @@ CheckCollision(Gear); if (Gear.State and gstCollision) <> 0 then begin - doMakeExplosion(round(Gear.X), round(Gear.Y), 25, EXPLAllDamageInRadius); + t:= CheckGearsCollision(Gear, Sign(Gear.dX), true); + if t = nil then t:= CheckGearsCollision(Gear, Sign(Gear.dY), false); + if t <> nil then + AmmoShove(Gear, t, 25); + doMakeExplosion(round(Gear.X), round(Gear.Y), 25, EXPLNoDamage); DeleteGear(Gear); - SetAllToActive; exit end; dec(i) @@ -265,23 +265,38 @@ end; //////////////////////////////////////////////////////////////////////////////// -procedure doStepDEagleShot(Gear: PGear); // сама идея такова, что должна как то образовываться выбоина от выстрела :) -var i: LongWord; // пуля и в африке пуля.. и демаж совсем другой.. и эксплоза никакого, можно даже -begin // навылет сделать, типа через одного пролетела и в другого попала... опять же -AllInactive:= false; // дальше летишь меньше урон.. ой скока сразу мыслей то :)) +procedure doStepDEagleShot(Gear: PGear); +var i, x, y: LongWord; + oX, oY: real; + t: PGear; +begin +AllInactive:= false; i:= 80; +oX:= Gear.X; +oY:= Gear.Y; repeat -Gear.X:= Gear.X + Gear.dX; -Gear.Y:= Gear.Y + Gear.dY; -CheckCollision(Gear); -if (Gear.State and gstCollision) <> 0 then + Gear.X:= Gear.X + Gear.dX; + Gear.Y:= Gear.Y + Gear.dY; + x:= round(Gear.X); + y:= round(Gear.Y); + if ((y and $FFFFFC00) = 0) and ((x and $FFFFF800) = 0) + and (Land[y, x] <> 0) then inc(Gear.Damage); + t:= CheckGearsCollision(Gear, Sign(Gear.dX), true); + if t = nil then t:= CheckGearsCollision(Gear, Sign(Gear.dY), false); + if t <> nil then + begin + AmmoShove(Gear, t, 12); + if t.CollIndex < High(Longword) then DeleteCR(t) + end; + dec(i) +until (i = 0) or (Gear.Damage > Gear.Health); +if Gear.Damage > 0 then begin - inc(Gear.Damage); - doMakeExplosion(round(Gear.X), round(Gear.Y), 2, EXPLAllDamageInRadius); + DrawTunnel(oX, oY, Gear.dX, Gear.dY, 82 - i, 1); + dec(Gear.Health, Gear.Damage); + Gear.Damage:= 0 end; -dec(i) -until i = 0; -if (Gear.Damage > 20) or (Gear.X < 0) or (Gear.Y < 0) or (Gear.X > 2048) or (Gear.Y > 1024) then +if (Gear.Health <= 0) or (Gear.X < 0) or (Gear.Y < 0) or (Gear.X > 2048) or (Gear.Y > 1024) then DeleteGear(Gear) end; @@ -319,7 +334,6 @@ begin DeleteGear(Gear); AfterAttack; - SetAllToActive; exit end; HHGear:= PHedgehog(Gear.Hedgehog).Gear; @@ -332,7 +346,6 @@ doMakeExplosion(i, round(Gear.Y) + 3, 3, 0); inc(i, 1) end; - SetAllToActive; Gear.X:= Gear.X + Gear.dX; Gear.Y:= Gear.Y + 1.9 end; @@ -373,7 +386,7 @@ inc(y, 2); inc(i) end; -DrawLineExplosions(@ar, 3, round(Gear.Y) - cHHHalfHeight*2, 2, Pred(i)); +DrawHLineExplosions(@ar, 3, round(Gear.Y) - cHHHalfHeight*2, 2, Pred(i)); Gear.dY:= PHedgehog(Gear.Hedgehog).Gear.dY; doStepPickHammerWork(Gear); Gear.doStep:= doStepPickHammerWork @@ -618,7 +631,6 @@ if Gear.Timer = 0 then begin doMakeExplosion(round(Gear.X), round(Gear.Y), 50, EXPLAutoSound); - SetAllToActive; DeleteGear(Gear) end; dec(Gear.Timer); diff -r 2b7f2a43b999 -r c1ec4b15d70e hedgewars/HHHandlers.inc --- a/hedgewars/HHHandlers.inc Thu Jan 05 15:54:22 2006 +0000 +++ b/hedgewars/HHHandlers.inc Thu Jan 05 22:55:45 2006 +0000 @@ -126,10 +126,10 @@ amUFO: FollowGear:= AddGear(round(X), round(Y), gtUFO, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor); amShotgun: begin PlaySound(sndShotgunReload); - FollowGear:= AddGear(round(X + xx*20), round(Y + yy*20), gtShotgunShot, 0, xx * 0.5, 0.5 * yy); + FollowGear:= AddGear(round(X), round(Y), gtShotgunShot, 0, xx * 0.5, yy * 0.5); end; amDEagle: begin - FollowGear:= AddGear(round(X + xx*20), round(Y + yy*20), gtDEagleShot, 0, xx * 0.5, 0.5 * yy); + FollowGear:= AddGear(round(X), round(Y), gtDEagleShot, 0, xx * 0.5, yy * 0.5); end; amSkip: TurnTimeLeft:= 0; amPickHammer: CurAmmoGear:= AddGear(round(Gear.X), round(Gear.Y) + cHHHalfHeight, gtPickHammer, 0); @@ -209,7 +209,8 @@ Gear.State:= Gear.State or gstAttacking; if Gear.Power = cMaxPower then Gear.Message:= Gear.Message and not gm_Attack else - if (Ammo[CurSlot, CurAmmo].Propz and ammoprop_Power) = 0 then Attack(Gear) + if (Ammo[CurSlot, CurAmmo].Propz and ammoprop_Power) = 0 then + Gear.Message:= Gear.Message and not gm_Attack else begin if Gear.Power = 0 then begin @@ -225,6 +226,7 @@ begin RemoveIntersectorsCR(Gear); Attack(Gear); + StepTicks:= 40 end; if (Gear.State and gstFalling) <> 0 then @@ -355,7 +357,6 @@ //////////////////////////////////////////////////////////////////////////////// procedure doStepHedgehogFree(Gear: PGear); begin -if Gear.CollIndex < High(Longword) then DeleteCR(Gear); if not HHTestCollisionYwithGear(Gear, 1) then begin if (Gear.dY < 0) and HHTestCollisionYwithGear(Gear, -1) then Gear.dY:= 0; @@ -370,6 +371,8 @@ if ((Gear.State and gstMoving) <> 0) then Gear.dX:= Gear.dX * Gear.Friction end; +if (Gear.State <> 0) and (Gear.CollIndex < High(Longword)) then DeleteCR(Gear); + if (Gear.State and gstMoving) <> 0 then if TestCollisionXwithGear(Gear, Sign(Gear.dX)) then diff -r 2b7f2a43b999 -r c1ec4b15d70e hedgewars/tunsetborder.inc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hedgewars/tunsetborder.inc Thu Jan 05 22:55:45 2006 +0000 @@ -0,0 +1,17 @@ + begin + X:= X + dX; + Y:= Y + dY; + tx:= round(X); + ty:= round(Y); + if ((ty and $FFFFFC00) = 0) and ((tx and $FFFFF800) = 0)and (Land[ty, tx] <> 0) then + case LandSurface.format.BytesPerPixel of + 1: ; + 2: PWord(p + LandSurface.pitch * ty + tx * 2)^:= cExplosionBorderColor; + 3: begin + PByte(p + LandSurface.pitch * ty + tx * 3 + 0)^:= cExplosionBorderColor and $FF; + PByte(p + LandSurface.pitch * ty + tx * 3 + 1)^:= (cExplosionBorderColor shr 8) and $FF; + PByte(p + LandSurface.pitch * ty + tx * 3 + 2)^:= (cExplosionBorderColor shr 16); + end; + 4: PLongword(p + LandSurface.pitch * ty + tx * 4)^:= cExplosionBorderColor; + end + end; \ No newline at end of file diff -r 2b7f2a43b999 -r c1ec4b15d70e hedgewars/uCollisions.pas --- a/hedgewars/uCollisions.pas Thu Jan 05 15:54:22 2006 +0000 +++ b/hedgewars/uCollisions.pas Thu Jan 05 22:55:45 2006 +0000 @@ -44,7 +44,7 @@ procedure AddGearCR(Gear: PGear); procedure UpdateCR(NewX, NewY: integer; Index: Longword); procedure DeleteCR(Gear: PGear); -function CheckGearsCollision(Gear: PGear; Dir: integer; forX: boolean): boolean; +function CheckGearsCollision(Gear: PGear; Dir: integer; forX: boolean): PGear; function HHTestCollisionYwithGear(Gear: PGear; Dir: integer): boolean; function TestCollisionXwithGear(Gear: PGear; Dir: integer): boolean; function TestCollisionYwithGear(Gear: PGear; Dir: integer): boolean; @@ -94,11 +94,11 @@ dec(Count) end; -function CheckGearsCollision(Gear: PGear; Dir: integer; forX: boolean): boolean; +function CheckGearsCollision(Gear: PGear; Dir: integer; forX: boolean): PGear; var x1, x2, y1, y2: integer; i: Longword; begin -Result:= false; +Result:= nil; if Count = 0 then exit; x1:= round(Gear.X); y1:= round(Gear.Y); @@ -125,7 +125,7 @@ and (y1 <= Y + HHeight) and (y2 >= Y - HHeight) then begin - Result:= true; + Result:= crects[i].cGear; exit end; end; @@ -159,7 +159,7 @@ until (x > i) or Result; if Result then exit; - Result:= CheckGearsCollision(Gear, Dir, false) + Result:= CheckGearsCollision(Gear, Dir, false) <> nil end end; @@ -179,7 +179,7 @@ inc(y) until (y > i) or Result; if Result then exit; - Result:= CheckGearsCollision(Gear, Dir, true) + Result:= CheckGearsCollision(Gear, Dir, true) <> nil end end; @@ -208,7 +208,7 @@ inc(x) until (x > i) or Result; if Result then exit; - Result:= CheckGearsCollision(Gear, Dir, false); + Result:= CheckGearsCollision(Gear, Dir, false) <> nil; end end; diff -r 2b7f2a43b999 -r c1ec4b15d70e hedgewars/uGears.pas --- a/hedgewars/uGears.pas Thu Jan 05 15:54:22 2006 +0000 +++ b/hedgewars/uGears.pas Thu Jan 05 22:55:45 2006 +0000 @@ -57,7 +57,7 @@ Friction : Real; Message : Longword; Hedgehog: pointer; - Health, Damage: LongWord; + Health, Damage: integer; CollIndex: Longword; Tag: integer; end; @@ -88,6 +88,7 @@ procedure DeleteGear(Gear: PGear); forward; procedure doMakeExplosion(X, Y, Radius: integer; Mask: LongWord); forward; +procedure AmmoShove(Ammo, Gear: PGear; Power: Longword); forward; function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: integer): PGear; forward; procedure SpawnBoxOfSmth; forward; procedure AfterAttack; forward; @@ -205,7 +206,8 @@ end; gtDEagleShot: begin Result.HalfWidth:= 1; - Result.HalfHeight:= 1 + Result.HalfHeight:= 1; + Result.Health:= 50 end; end; if GearsList = nil then GearsList:= Result @@ -541,6 +543,7 @@ inc(Gear.Damage, dmg); Gear.dX:= Gear.dX + dmg / 200 * sign(Gear.X - X); Gear.dY:= Gear.dY + dmg / 200 * sign(Gear.Y - Y); + Gear.Active:= true; FollowGear:= Gear end; gtGrave: Gear.dY:= - dmg / 250; @@ -550,6 +553,19 @@ end end; +procedure AmmoShove(Ammo, Gear: PGear; Power: Longword); +begin +case Gear.Kind of + gtHedgehog: begin + inc(Gear.Damage, Power); + Gear.dX:= Ammo.dX * Power * 0.01; + Gear.dY:= Ammo.dY * Power * 0.01; + Gear.Active:= true; + FollowGear:= Gear + end; + end; +end; + procedure AssignHHCoords; var Gear: PGear; pX, pY: integer; diff -r 2b7f2a43b999 -r c1ec4b15d70e hedgewars/uStore.pas --- a/hedgewars/uStore.pas Thu Jan 05 15:54:22 2006 +0000 +++ b/hedgewars/uStore.pas Thu Jan 05 22:55:45 2006 +0000 @@ -52,7 +52,8 @@ procedure DrawCaption(X, Y: integer; Rect: TSDL_Rect; Surface: PSDL_Surface; const fromTempSurf: boolean = false); procedure DrawHedgehog(X, Y: integer; Dir: integer; Pos, Step: LongWord; Surface: PSDL_Surface); procedure DrawExplosion(X, Y, Radius: integer); -procedure DrawLineExplosions(ar: PRangeArray; Radius: Longword; y, dY: integer; Count: Byte); +procedure DrawHLineExplosions(ar: PRangeArray; Radius: Longword; y, dY: integer; Count: Byte); +procedure DrawTunnel(X, Y, dX, dY: real; ticks, HalfWidth: integer); procedure RenderHealth(var Hedgehog: THedgehog); function RenderString(var s: shortstring; Color, Pos: integer): TSDL_Rect; procedure AddProgress; @@ -69,8 +70,7 @@ HHSurface: PSDL_Surface; procedure DrawExplosion(X, Y, Radius: integer); -var ty, tx: integer; - p: integer; +var ty, tx, p: integer; begin for ty:= max(-Radius, -y) to min(radius, 1023 - y) do for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do @@ -79,7 +79,7 @@ if SDL_MustLock(LandSurface) then SDLTry(SDL_LockSurface(LandSurface) >= 0, true); -p:= Longword(LandSurface.pixels); +p:= integer(LandSurface.pixels); case LandSurface.format.BytesPerPixel of 1: ;// not supported 2: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do @@ -103,21 +103,19 @@ 1: ;// not supported 2: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do - if PWord(p + LandSurface.pitch*(y + ty) + tx * 2)^ <> 0 then + if Land[y + ty, tx] <> 0 then PWord(p + LandSurface.pitch*(y + ty) + tx * 2)^:= cExplosionBorderColor; 3: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do - if (PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 0)^ <> 0) - or (PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 1)^ <> 0) - or (PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 2)^ <> 0) - then begin + if Land[y + ty, tx] <> 0 then + begin PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 0)^:= cExplosionBorderColor and $FF; PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 1)^:= (cExplosionBorderColor shr 8) and $FF; PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 2)^:= (cExplosionBorderColor shr 16); end; 4: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do - if PLongword(p + LandSurface.pitch*(y + ty) + tx * 4)^ <> 0 then + if Land[y + ty, tx] <> 0 then PLongword(p + LandSurface.pitch*(y + ty) + tx * 4)^:= cExplosionBorderColor; end; @@ -127,13 +125,13 @@ SDL_UpdateRect(LandSurface, X - Radius, Y - Radius, Radius * 2, Radius * 2) end; -procedure DrawLineExplosions(ar: PRangeArray; Radius: Longword; y, dY: integer; Count: Byte); +procedure DrawHLineExplosions(ar: PRangeArray; Radius: Longword; y, dY: integer; Count: Byte); var tx, ty, i, p: integer; begin if SDL_MustLock(LandSurface) then SDL_LockSurface(LandSurface); -p:= Longword(LandSurface.pixels); +p:= integer(LandSurface.pixels); for i:= 0 to Pred(Count) do begin case LandSurface.format.BytesPerPixel of @@ -164,21 +162,19 @@ 1: ; 2: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do for tx:= max(0, round(ar[i].Left - radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(ar[i].Right + radius*sqrt(1-sqr(ty/radius)))) do - if PWord(p + LandSurface.pitch*(y + ty) + tx * 2)^ <> 0 then + if Land[y + ty, tx] <> 0 then PWord(p + LandSurface.pitch*(y + ty) + tx * 2)^:= cExplosionBorderColor; 3: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do for tx:= max(0, round(ar[i].Left - radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(ar[i].Right + radius*sqrt(1-sqr(ty/radius)))) do - if (PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 0)^ <> 0) - or (PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 1)^ <> 0) - or (PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 2)^ <> 0) - then begin + if Land[y + ty, tx] <> 0 then + begin PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 0)^:= cExplosionBorderColor and $FF; PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 1)^:= (cExplosionBorderColor shr 8) and $FF; PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 2)^:= (cExplosionBorderColor shr 16); end; 4: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do for tx:= max(0, round(ar[i].Left - radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(ar[i].Right + radius*sqrt(1-sqr(ty/radius)))) do - if PLongword(p + LandSurface.pitch*(y + ty) + tx * 4)^ <> 0 then + if Land[y + ty, tx] <> 0 then PLongword(p + LandSurface.pitch*(y + ty) + tx * 4)^:= cExplosionBorderColor; end; inc(y, dY) @@ -188,6 +184,79 @@ SDL_UnlockSurface(LandSurface); end; +// +// - (dX, dY) - direction, vector of length = 0.5 +// +procedure DrawTunnel(X, Y, dX, dY: real; ticks, HalfWidth: integer); +var nx, ny: real; + i, t, tx, ty, p: integer; +begin // (-dY, dX) is (dX, dY) turned by PI/2 +if SDL_MustLock(LandSurface) then + SDL_LockSurface(LandSurface); + +nx:= X + dY * (HalfWidth + 8); +ny:= Y - dX * (HalfWidth + 8); +p:= integer(LandSurface.pixels); + +for i:= 0 to 7 do + begin + X:= nx - 8 * dX; + Y:= ny - 8 * dY; + for t:= -8 to ticks + 8 do + {$include tunsetborder.inc} + nx:= nx - dY; + ny:= ny + dX; + end; + +for i:= -HalfWidth to HalfWidth do + begin + X:= nx - dX * 8; + Y:= ny - dY * 8; + for t:= 0 to 7 do + {$include tunsetborder.inc} + X:= nx; + Y:= ny; + for t:= 0 to ticks do + begin + X:= X + dX; + Y:= Y + dY; + tx:= round(X); + ty:= round(Y); + if ((ty and $FFFFFC00) = 0) and ((tx and $FFFFF800) = 0) then + begin + Land[ty, tx]:= 0; + case LandSurface.format.BytesPerPixel of + 1: ; + 2: PWord(p + LandSurface.pitch * ty + tx * 2)^:= 0; + 3: begin + PByte(p + LandSurface.pitch * ty + tx * 3 + 0)^:= 0; + PByte(p + LandSurface.pitch * ty + tx * 3 + 1)^:= 0; + PByte(p + LandSurface.pitch * ty + tx * 3 + 2)^:= 0; + end; + 4: PLongword(p + LandSurface.pitch * ty + tx * 4)^:= 0; + end + end + end; + for t:= 0 to 7 do + {$include tunsetborder.inc} + nx:= nx - dY; + ny:= ny + dX; + end; + +for i:= 0 to 7 do + begin + X:= nx - 8 * dX; + Y:= ny - 8 * dY; + for t:= -8 to ticks + 8 do + {$include tunsetborder.inc} + nx:= nx - dY; + ny:= ny + dX; + end; + +if SDL_MustLock(LandSurface) then + SDL_UnlockSurface(LandSurface) +end; + procedure StoreInit; begin StoreSurface := SDL_CreateRGBSurface(SDL_HWSURFACE, 576, 1024, cBits, PixelFormat.RMask, PixelFormat.GMask, PixelFormat.BMask, 0);