# HG changeset patch # User alfadur # Date 1517424172 18000 # Node ID 8a40ce061d94c9fa21e26f56288c876fbfe77e82 # Parent 856570ddd409bec11645c90b5a92fb79c5f2a4e1 Machinegun. also tweaked ignore diff -r 856570ddd409 -r 8a40ce061d94 .hgignore --- a/.hgignore Mon Jan 15 12:15:56 2018 -0500 +++ b/.hgignore Wed Jan 31 13:42:52 2018 -0500 @@ -5,8 +5,8 @@ .git CMakeCache.txt CMakeFiles -moc_*.cxx -qrc_*.cxx +moc_*.* +qrc_*.* *.o *.a *.qm diff -r 856570ddd409 -r 8a40ce061d94 QTfrontend/weapons.h --- a/QTfrontend/weapons.h Mon Jan 15 12:15:56 2018 -0500 +++ b/QTfrontend/weapons.h Wed Jan 31 13:42:52 2018 -0500 @@ -16,10 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#define AMMOLINE_EMPTY_QT "0000009000000000000000000000000000000000000000000000000000" -#define AMMOLINE_EMPTY_PROB "0000000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_EMPTY_DELAY "0000000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_EMPTY_CRATE "1311110312111111123114111111111111111211111111111111111111" +#define AMMOLINE_EMPTY_QT "00000090000000000000000000000000000000000000000000000000000" +#define AMMOLINE_EMPTY_PROB "00000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_EMPTY_DELAY "00000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_EMPTY_CRATE "13111103121111111231141111111111111112111111111111111111111" /* AmmoType lookup table (use monospace font / cursor movements) @@ -82,63 +82,64 @@ amRubber-------------------------------------------------------------------------------| amAirMine-------------------------------------------------------------------------------| amDuck-----------------------------------------------------------------------------------| + amMinigun---------------------------------------------------------------------------------| */ -#define AMMOLINE_DEFAULT_QT "9391929422199121032235111001200000000211100101011111000102" -#define AMMOLINE_DEFAULT_PROB "0405040541600655546554464776576666666155510101115411111114" -#define AMMOLINE_DEFAULT_DELAY "0000000000000205500000040007004000000000220000000600020000" -#define AMMOLINE_DEFAULT_CRATE "1311110312111111123114111111111111111211111111111111111111" +#define AMMOLINE_DEFAULT_QT "93919294221991210322351110012000000002111001010111110001021" +#define AMMOLINE_DEFAULT_PROB "04050405416006555465544647765766666661555101011154111111143" +#define AMMOLINE_DEFAULT_DELAY "00000000000002055000000400070040000000002200000006000200000" +#define AMMOLINE_DEFAULT_CRATE "13111103121111111231141111111111111112111111111111111111111" -#define AMMOLINE_CRAZY_QT "9999999999999999992999999999999999299999999999999992999199" -#define AMMOLINE_CRAZY_PROB "1111110111111111111111111111111111111111111111111111111111" -#define AMMOLINE_CRAZY_DELAY "0000000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_CRAZY_CRATE "1311110312111111123114111111111111111211111111111111111111" +#define AMMOLINE_CRAZY_QT "99999999999999999929999999999999992999999999999999929991999" +#define AMMOLINE_CRAZY_PROB "11111101111111111111111111111111111111111111111111111111111" +#define AMMOLINE_CRAZY_DELAY "00000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_CRAZY_CRATE "13111103121111111231141111111111111112111111111111111111111" -#define AMMOLINE_PROMODE_QT "9090009000000000000009000000000000000000000000000000000000" -#define AMMOLINE_PROMODE_PROB "0000000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_PROMODE_DELAY "0000000000000205500000040007004000000000200000000000020000" -#define AMMOLINE_PROMODE_CRATE "1111110111111111111111111111111111111111111111111111111111" +#define AMMOLINE_PROMODE_QT "90900090000000000000090000000000000000000000000000000000000" +#define AMMOLINE_PROMODE_PROB "00000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_PROMODE_DELAY "00000000000002055000000400070040000000002000000000000200000" +#define AMMOLINE_PROMODE_CRATE "11111101111111111111111111111111111111111111111111111111111" -#define AMMOLINE_SHOPPA_QT "0000009900000000000000000000000000000000000000000000000000" -#define AMMOLINE_SHOPPA_PROB "4444410044244402210112121222422000000002000400010011001011" -#define AMMOLINE_SHOPPA_DELAY "0000000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_SHOPPA_CRATE "1111110111111111111111111111111111111111111111111111111111" +#define AMMOLINE_SHOPPA_QT "00000099000000000000000000000000000000000000000000000000000" +#define AMMOLINE_SHOPPA_PROB "44444100442444022101121212224220000000020004000100110010111" +#define AMMOLINE_SHOPPA_DELAY "00000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_SHOPPA_CRATE "11111101111111111111111111111111111111111111111111111111111" -#define AMMOLINE_CLEAN_QT "1010009000010000011000000000000000000000000000001000000000" -#define AMMOLINE_CLEAN_PROB "0405040541600655546554464776576666666155510101115411121114" -#define AMMOLINE_CLEAN_DELAY "0000000000000000000000000000000000000000000000000000020000" -#define AMMOLINE_CLEAN_CRATE "1311110312111111123114111111111111111211111111111111111111" +#define AMMOLINE_CLEAN_QT "10100090000100000110000000000000000000000000000010000000000" +#define AMMOLINE_CLEAN_PROB "04050405416006555465544647765766666661555101011154111211144" +#define AMMOLINE_CLEAN_DELAY "00000000000000000000000000000000000000000000000000000200000" +#define AMMOLINE_CLEAN_CRATE "13111103121111111231141111111111111112111111111111111111111" -#define AMMOLINE_MINES_QT "0000009900090000000300000000000000000000000000000000000000" -#define AMMOLINE_MINES_PROB "0000000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_MINES_DELAY "0000000000000205500000040007004000000000200000000600020000" -#define AMMOLINE_MINES_CRATE "1111110111111111111111111111111111111111111111111111111111" +#define AMMOLINE_MINES_QT "00000099000900000003000000000000000000000000000000000000000" +#define AMMOLINE_MINES_PROB "00000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_MINES_DELAY "00000000000002055000000400070040000000002000000006000200000" +#define AMMOLINE_MINES_CRATE "11111101111111111111111111111111111111111111111111111111111" -#define AMMOLINE_PORTALS_QT "9000009002000000002100000000000000110000090000000000000000" -#define AMMOLINE_PORTALS_PROB "0405040541600655546554464776576666666155510101115411121112" -#define AMMOLINE_PORTALS_DELAY "0000000000000205500000040007004000000000200000000600020000" -#define AMMOLINE_PORTALS_CRATE "1311110312111111123114111111111111111211111111111111111111" +#define AMMOLINE_PORTALS_QT "90000090020000000021000000000000001100000900000000000000000" +#define AMMOLINE_PORTALS_PROB "04050405416006555465544647765766666661555101011154111211122" +#define AMMOLINE_PORTALS_DELAY "00000000000002055000000400070040000000002000000006000200000" +#define AMMOLINE_PORTALS_CRATE "13111103121111111231141111111111111112111111111111111111111" -#define AMMOLINE_ONEEVERY_QT "1111119111111111111111111111111111111111111111111111111111" -#define AMMOLINE_ONEEVERY_PROB "1111110111111111111111111111111111111111111111111111111111" -#define AMMOLINE_ONEEVERY_DELAY "0000000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_ONEEVERY_CRATE "1111110111111111111111111111111111111111111111111111111111" +#define AMMOLINE_ONEEVERY_QT "11111191111111111111111111111111111111111111111111111111111" +#define AMMOLINE_ONEEVERY_PROB "11111101111111111111111111111111111111111111111111111111111" +#define AMMOLINE_ONEEVERY_DELAY "00000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_ONEEVERY_CRATE "11111101111111111111111111111111111111111111111111111111111" -#define AMMOLINE_HIGHLANDER_QT "1111119111111111111101911111111110010111110111100100101111" -#define AMMOLINE_HIGHLANDER_PROB "0000000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_HIGHLANDER_DELAY "0000000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_HIGHLANDER_CRATE "0000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_HIGHLANDER_QT "11111191111111111111019111111111100101111101111001001011111" +#define AMMOLINE_HIGHLANDER_PROB "00000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_HIGHLANDER_DELAY "00000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_HIGHLANDER_CRATE "00000000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_CONSTRUCTION_QT "1100019000000010010000000000000000000000000000000000000000" -#define AMMOLINE_CONSTRUCTION_PROB "1111110111111111111111111111111111111111111111111111111111" -#define AMMOLINE_CONSTRUCTION_DELAY "0000000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_CONSTRUCTION_CRATE "1111110111111111111111111111111111111111111111111111111111" +#define AMMOLINE_CONSTRUCTION_QT "11000190000000100100000000000000000000000000000000000000000" +#define AMMOLINE_CONSTRUCTION_PROB "11111101111111111111111111111111111111111111111111111111111" +#define AMMOLINE_CONSTRUCTION_DELAY "00000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_CONSTRUCTION_CRATE "11111101111111111111111111111111111111111111111111111111111" -#define AMMOLINE_SHOPPAPRO_QT "0000009900000000000000000000000000000000000000000000000000" -#define AMMOLINE_SHOPPAPRO_PROB "4444400044044400000000000000400000000000000000000000000000" -#define AMMOLINE_SHOPPAPRO_DELAY "0000000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_SHOPPAPRO_CRATE "1111110111111111111111111111111111111111111111111111121111" +#define AMMOLINE_SHOPPAPRO_QT "00000099000000000000000000000000000000000000000000000000000" +#define AMMOLINE_SHOPPAPRO_PROB "44444000440444000000000000004000000000000000000000000000000" +#define AMMOLINE_SHOPPAPRO_DELAY "00000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_SHOPPAPRO_CRATE "11111101111111111111111111111111111111111111111111111211111" -#define AMMOLINE_HEDGEEDITOR_QT "0000009000000000000000000000000000000000000000000000000000" -#define AMMOLINE_HEDGEEDITOR_PROB "0000000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_HEDGEEDITOR_DELAY "0000000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_HEDGEEDITOR_CRATE "1111110111111111111111111111111111111111111111111111111111" +#define AMMOLINE_HEDGEEDITOR_QT "00000090000000000000000000000000000000000000000000000000000" +#define AMMOLINE_HEDGEEDITOR_PROB "00000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_HEDGEEDITOR_DELAY "00000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_HEDGEEDITOR_CRATE "11111101111111111111111111111111111111111111111111111111111" diff -r 856570ddd409 -r 8a40ce061d94 hedgewars/uAIAmmoTests.pas --- a/hedgewars/uAIAmmoTests.pas Mon Jan 15 12:15:56 2018 -0500 +++ b/hedgewars/uAIAmmoTests.pas Wed Jan 31 13:42:52 2018 -0500 @@ -125,7 +125,8 @@ (proc: nil; flags: 0), // amKnife (proc: nil; flags: 0), // amRubber (proc: nil; flags: 0), // amAirMine - (proc: nil; flags: 0) // amDuck + (proc: nil; flags: 0), // amDuck + (proc: @TestShotgun; flags: 0) // amMinigun ); implementation diff -r 856570ddd409 -r 8a40ce061d94 hedgewars/uCollisions.pas --- a/hedgewars/uCollisions.pas Mon Jan 15 12:15:56 2018 -0500 +++ b/hedgewars/uCollisions.pas Wed Jan 31 13:42:52 2018 -0500 @@ -20,16 +20,31 @@ unit uCollisions; interface -uses uFloat, uTypes; +uses uFloat, uTypes, uUtils; const cMaxGearArrayInd = 1023; +const cMaxGearHitOrderInd = 1023; type PGearArray = ^TGearArray; TGearArray = record ar: array[0..cMaxGearArrayInd] of PGear; + cX: array[0..cMaxGearArrayInd] of LongInt; + cY: array[0..cMaxGearArrayInd] of LongInt; Count: Longword end; +type PGearHitOrder = ^TGearHitOrder; + TGearHitOrder = record + ar: array[0..cMaxGearHitOrderInd] of PGear; + order: array[0..cMaxGearHitOrderInd] of LongInt; + Count: Longword + end; + +type TLineCollision = record + hasCollision: Boolean; + cX, cY: LongInt; //for visual effects only + end; + procedure initModule; procedure freeModule; @@ -37,6 +52,14 @@ procedure DeleteCI(Gear: PGear); function CheckGearsCollision(Gear: PGear): PGearArray; +function CheckAllGearsCollision(SourceGear: PGear): PGearArray; + +function CheckGearsLineCollision(Gear: PGear; oX, oY, tX, tY: hwFloat): PGearArray; +function CheckAllGearsLineCollision(SourceGear: PGear; oX, oY, tX, tY: hwFloat): PGearArray; + +function UpdateHitOrder(Gear: PGear; Order: LongInt): boolean; +procedure ClearHitOrderLeq(MinOrder: LongInt); +procedure ClearHitOrder(); function TestCollisionXwithGear(Gear: PGear; Dir: LongInt): Word; function TestCollisionYwithGear(Gear: PGear; Dir: LongInt): Word; @@ -73,6 +96,7 @@ var Count: Longword; cinfos: array[0..MAXRECTSINDEX] of TCollisionEntry; ga: TGearArray; + ordera: TGearHitOrder; procedure AddCI(Gear: PGear); begin @@ -130,10 +154,189 @@ (sqr(mx - x) + sqr(my - y) <= sqr(Radius + tr)) then begin ga.ar[ga.Count]:= cinfos[i].cGear; + ga.cX[ga.Count]:= hwround(Gear^.X); + ga.cY[ga.Count]:= hwround(Gear^.Y); inc(ga.Count) end end; +function CheckAllGearsCollision(SourceGear: PGear): PGearArray; +var mx, my, tr: LongInt; + Gear: PGear; +begin + CheckAllGearsCollision:= @ga; + ga.Count:= 0; + + mx:= hwRound(SourceGear^.X); + my:= hwRound(SourceGear^.Y); + + tr:= SourceGear^.Radius + 2; + + Gear:= GearsList; + + while Gear <> nil do + begin + if (Gear <> SourceGear) and + (sqr(mx - hwRound(Gear^.x)) + sqr(my - hwRound(Gear^.y)) <= sqr(Gear^.Radius + tr))then + begin + ga.ar[ga.Count]:= Gear; + ga.cX[ga.Count]:= hwround(SourceGear^.X); + ga.cY[ga.Count]:= hwround(SourceGear^.Y); + inc(ga.Count) + end; + + Gear := Gear^.NextGear + end; +end; + +function LineCollisionTest(oX, oY, dirX, dirY, dirNormSqr, dirNormBound: hwFloat; + width: LongInt; Gear: PGear): + TLineCollision; inline; +var toCenterX, toCenterY, r, + b, bSqr, c, desc, t: hwFloat; + realT: extended; +begin + LineCollisionTest.hasCollision:= false; + toCenterX:= (oX - Gear^.X); + toCenterY:= (oY - Gear^.Y); + r:= int2hwFloat(Gear^.Radius + width + 2); + // Early cull to avoid multiplying large numbers + if hwAbs(toCenterX) + hwAbs(toCenterY) > dirNormBound + r then + exit; + b:= dirX * toCenterX + dirY * toCenterY; + c:= hwSqr(toCenterX) + hwSqr(toCenterY) - hwSqr(r); + if (b > _0) and (c > _0) then + exit; + bSqr:= hwSqr(b); + desc:= bSqr - dirNormSqr * c; + if desc.isNegative then exit; + + t:= -b - hwSqrt(desc); + if t.isNegative then t:= _0; + if t < dirNormSqr then + with LineCollisionTest do + begin + hasCollision:= true; + realT := hwFloat2Float(t) / hwFloat2Float(dirNormSqr); + cX:= round(hwFloat2Float(oX) + realT * hwFloat2Float(dirX)); + cY:= round(hwFloat2Float(oY) + realT * hwFloat2Float(dirY)); + end; +end; + +function CheckGearsLineCollision(Gear: PGear; oX, oY, tX, tY: hwFloat): PGearArray; +var dirX, dirY, dirNormSqr, dirNormBound: hwFloat; + test: TLineCollision; + i: Longword; +begin + CheckGearsLineCollision:= @ga; + ga.Count:= 0; + if Count = 0 then + exit; + dirX:= (tX - oX); + dirY:= (tY - oY); + dirNormBound:= _1_5 * (hwAbs(dirX) + hwAbs(dirY)); + dirNormSqr:= hwSqr(dirX) + hwSqr(dirY); + if dirNormSqr.isNegative then + exit; + + for i:= 0 to Pred(Count) do + with cinfos[i] do if Gear <> cGear then + begin + test:= LineCollisionTest( + oX, oY, dirX, dirY, dirNormSqr, dirNormBound, Gear^.Radius, cGear); + if test.hasCollision then + begin + ga.ar[ga.Count] := cGear; + ga.cX[ga.Count] := test.cX; + ga.cY[ga.Count] := test.cY; + inc(ga.Count) + end + end +end; + +function CheckAllGearsLineCollision(SourceGear: PGear; oX, oY, tX, tY: hwFloat): PGearArray; +var dirX, dirY, dirNormSqr, dirNormBound: hwFloat; + test: TLineCollision; + Gear: PGear; +begin + CheckAllGearsLineCollision:= @ga; + ga.Count:= 0; + dirX:= (tX - oX); + dirY:= (tY - oY); + dirNormBound:= _1_5 * (hwAbs(dirX) + hwAbs(dirY)); + dirNormSqr:= hwSqr(dirX) + hwSqr(dirY); + if dirNormSqr.isNegative then + exit; + + Gear:= GearsList; + while Gear <> nil do + begin + if SourceGear <> Gear then + begin + test:= LineCollisionTest( + oX, oY, dirX, dirY, dirNormSqr, dirNormBound, SourceGear^.Radius, Gear); + if test.hasCollision then + begin + ga.ar[ga.Count] := Gear; + ga.cX[ga.Count] := test.cX; + ga.cY[ga.Count] := test.cY; + inc(ga.Count) + end + end; + Gear := Gear^.NextGear + end; +end; + +function UpdateHitOrder(Gear: PGear; Order: LongInt): boolean; +var i: LongInt; +begin +UpdateHitOrder:= true; +for i:= 0 to cMaxGearHitOrderInd do + if ordera.ar[i] = Gear then + begin + if Order <= ordera.order[i] then UpdateHitOrder:= false; + ordera.order[i]:= Max(ordera.order[i], order); + exit; + end; + +if ordera.Count > cMaxGearHitOrderInd then + UpdateHitOrder:= false +else + begin + ordera.ar[ordera.Count]:= Gear; + ordera.order[ordera.Count]:= Order; + Inc(ordera.Count); + end +end; + +procedure ClearHitOrderLeq(MinOrder: LongInt); +var i, freeIndex: LongInt; +begin; +freeIndex:= 0; +i:= 0; + +while i < ordera.Count do + begin + if ordera.order[i] <= MinOrder then + Dec(ordera.Count) + else + begin + if freeIndex < i then + begin + ordera.ar[freeIndex]:= ordera.ar[i]; + ordera.order[freeIndex]:= ordera.order[i]; + end; + Inc(freeIndex); + end; + Inc(i) + end +end; + +procedure ClearHitOrder(); +begin + ordera.Count:= 0; +end; + function TestCollisionXwithGear(Gear: PGear; Dir: LongInt): Word; var x, y, i: LongInt; begin diff -r 856570ddd409 -r 8a40ce061d94 hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Mon Jan 15 12:15:56 2018 -0500 +++ b/hedgewars/uConsts.pas Wed Jan 31 13:42:52 2018 -0500 @@ -277,7 +277,7 @@ cMaxSlotIndex = 10; cHiddenSlotIndex = cMaxSlotIndex; // slot for hidden ammo types, not visible and has no key - cMaxSlotAmmoIndex = 5; + cMaxSlotAmmoIndex = 6; // ai hints aihUsualProcessing = $00000000; diff -r 856570ddd409 -r 8a40ce061d94 hedgewars/uGears.pas --- a/hedgewars/uGears.pas Mon Jan 15 12:15:56 2018 -0500 +++ b/hedgewars/uGears.pas Wed Jan 31 13:42:52 2018 -0500 @@ -1250,7 +1250,9 @@ @doStepAddAmmo, @doStepGenericFaller, @doStepKnife, - @doStepDuck); + @doStepDuck, + @doStepMinigun, + @doStepMinigunBullet); begin doStepHandlers:= handlers; diff -r 856570ddd409 -r 8a40ce061d94 hedgewars/uGearsHandlersMess.pas --- a/hedgewars/uGearsHandlersMess.pas Mon Jan 15 12:15:56 2018 -0500 +++ b/hedgewars/uGearsHandlersMess.pas Wed Jan 31 13:42:52 2018 -0500 @@ -139,6 +139,9 @@ //procedure doStepCreeper(Gear: PGear); procedure doStepKnife(Gear: PGear); procedure doStepDuck(Gear: PGear); +procedure doStepMinigunWork(Gear: PGear); +procedure doStepMinigun(Gear: PGear); +procedure doStepMinigunBullet(Gear: PGear); var upd: Longword; @@ -1234,16 +1237,45 @@ end; end; +procedure LineShoveHelp(Gear: PGear; oX, oY, tX, tY, dX, dY: hwFloat; count: LongWord); +var dmg,power: LongInt; +begin + if ((Gear^.Kind = gtMinigunBullet) or (Gear^.Damage > 0)) + and (hwSqr(tX - oX) + hwSqr(tY - oY) > _0_25) then + begin + if (Gear^.AmmoType = amDEagle) or (Gear^.AmmoType = amMinigun) then + dmg:= Gear^.Boom + else + dmg:= Gear^.Timer * Gear^.Boom div 100000; + if (Gear^.AmmoType = amMinigun) then + power:= 10 + else + power:= 20; + AmmoShoveLine(Gear, dmg, power, oX, oY, tX, tY); + end; + if Gear^.Damage > 0 then + begin + DrawTunnel(oX, oY, dX, dY, count, 1); + dec(Gear^.Health, Gear^.Damage); + Gear^.Damage := 0 + end; +end; + procedure doStepBulletWork(Gear: PGear); var i, x, y, iInit: LongWord; oX, oY, tX, tY, tDx, tDy: hwFloat; VGear: PVisualGear; + LandFlags: Word; + isDigging: Boolean; + isDead: Boolean; begin AllInactive := false; inc(Gear^.Timer); - iInit := 80; + iInit := 100; i := iInit; + isDigging := false; + isDead := false; oX := Gear^.X; oY := Gear^.Y; repeat @@ -1255,7 +1287,7 @@ tDy:= Gear^.dY; if (Gear^.PortalCounter < 30) and WorldWrap(Gear) then begin - DrawTunnel(oX, oY, tDx, tDy, iInit + 2 - i, 1); + LineShoveHelp(Gear, oX, oY, tX, tY, tDx, tDy, iInit + 2 - i); SpawnBulletTrail(Gear, tX, tY); iInit:= i; oX:= Gear^.X; @@ -1268,38 +1300,45 @@ x := hwRound(Gear^.X); y := hwRound(Gear^.Y); - if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] <> 0) then - inc(Gear^.Damage); - // let's interrupt before a collision to give portals a chance to catch the bullet - if (Gear^.Damage = 1) and (Gear^.Tag = 0) and (not CheckLandValue(x, y, lfLandMask)) then + if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) then + begin + LandFlags:= Land[y, x]; + if LandFlags <> 0 then inc(Gear^.Damage); + isDigging:= (LandFlags and lfLandMask) <> 0; + end; + // let's interrupt before a collision with land to give portals a chance to catch the bullet + if isDigging and (Gear^.Tag = 0) then begin Gear^.Tag := 1; - Gear^.Damage := 0; + dec(Gear^.Damage); Gear^.X := Gear^.X - Gear^.dX; Gear^.Y := Gear^.Y - Gear^.dY; CheckGearDrowning(Gear); break; end - else + else if (not isDigging) then Gear^.Tag := 0; - if Gear^.Damage > 5 then - begin - if Gear^.AmmoType = amDEagle then - AmmoShove(Gear, Gear^.Boom, 20) - else - AmmoShove(Gear, Gear^.Timer * Gear^.Boom div 100000, 20); + //Shove static gears to remove the mask and stop damaging the bullet + if (not isDigging) and (Gear^.Damage > 5) and (Gear^.Kind <> gtMinigunBullet) then + begin + LineShoveHelp(Gear, oX, oY, tX, tY, tDx, tDy, iInit + 2 - i); + SpawnBulletTrail(Gear, tX, tY); + iInit:= i; + oX:= Gear^.X; + oY:= Gear^.Y; end; + CheckGearDrowning(Gear); + case Gear^.Kind of + gtMinigunBullet: isDead:= isDigging; + gtDEagleShot, gtSniperRifleShot: isDead:= Gear^.Damage >= Gear^.Health; + end; dec(i) - until (i = 0) or (Gear^.Damage > Gear^.Health) or ((Gear^.State and gstDrowning) <> 0); - - if Gear^.Damage > 0 then - begin - DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, iInit + 2 - i, 1); - dec(Gear^.Health, Gear^.Damage); - Gear^.Damage := 0 - end; + until (i = 0) or (isDead) or ((Gear^.State and gstDrowning) <> 0); + + LineShoveHelp(Gear, oX, oY, Gear^.X, Gear^.Y, + Gear^.dX, Gear^.dY, iInit + 2 - i); if ((Gear^.State and gstDrowning) <> 0) and (Gear^.Health > 0) then begin @@ -1318,7 +1357,7 @@ Gear^.Health:= 0; end; - if (Gear^.Health <= 0) + if (isDead) or (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then begin @@ -1330,7 +1369,15 @@ // Bullet Hit if ((Gear^.State and gstDrowning) = 0) and (hwRound(Gear^.X) and LAND_WIDTH_MASK = 0) and (hwRound(Gear^.Y) and LAND_HEIGHT_MASK = 0) then begin - VGear := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBulletHit); + if Gear^.Kind = gtMinigunBullet then + begin + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 5, + Gear^.Hedgehog, EXPLNoDamage{ or EXPLDontDraw or EXPLNoGfx}); + VGear := AddVisualGear(hwRound(Gear^.X + Gear^.dX * 5), hwRound(Gear^.Y + Gear^.dY * 5), vgtBulletHit); + end + else + VGear := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBulletHit); + if VGear <> nil then begin VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY); @@ -1338,6 +1385,8 @@ end; spawnBulletTrail(Gear, Gear^.X, Gear^.Y); + if Gear^.Kind = gtMinigunBullet then + ClearHitOrderLeq(Gear^.Tag); Gear^.doStep := @doStepShotIdle end; end; @@ -1357,8 +1406,7 @@ end; procedure doStepSniperRifleShot(Gear: PGear); -var - HHGear: PGear; +var HHGear: PGear; shell: PVisualGear; begin @@ -4454,7 +4502,7 @@ // Make duck go into “falling” mode again iterator^.Pos:= 0; - isbullet:= (iterator^.Kind in [gtShotgunShot, gtDEagleShot, gtSniperRifleShot, gtSineGunShot]); + isbullet:= (iterator^.Kind in [gtShotgunShot, gtDEagleShot, gtSniperRifleShot, gtSineGunShot, gtMinigunBullet]); r:= int2hwFloat(iterator^.Radius); @@ -4481,7 +4529,7 @@ continue; end; - if (iterator^.Kind = gtDEagleShot) or (iterator^.Kind = gtSniperRifleShot) then + if (iterator^.Kind in [gtDEagleShot, gtSniperRifleShot, gtMinigunBullet]) then begin // draw bullet trail spawnBulletTrail(iterator, iterator^.X, iterator^.Y); @@ -6564,6 +6612,95 @@ dec(Gear^.Timer); end; +//////////////////////////////////////////////////////////////////////////////// +procedure doStepMinigunWork(Gear: PGear); +var HHGear: PGear; + i: LongWord; + shell: PVisualGear; + bullet: PGear; + rx, ry: hwFloat; + gX, gY: LongInt; +begin + AllInactive:= false; + HHGear := Gear^.Hedgehog^.Gear; + if HHGear = nil then + begin + ClearHitOrder(); + DeleteGear(gear); + exit + end; + + HedgehogChAngle(HHGear); + + dec(Gear^.Timer); + if (Gear^.Timer mod 50) = 0 then + begin + Gear^.Tag := ((Gear^.Tag - 1) and 1) + 2; + + gX := hwRound(Gear^.X) + GetLaunchX(amMinigun, hwSign(HHGear^.dX), HHGear^.Angle); + gY := hwRound(Gear^.Y) + GetLaunchY(amMinigun, HHGear^.Angle); + rx := rndSign(getRandomf * _0_2); + ry := rndSign(getRandomf * _0_2); + + bullet:= AddGear(gx, gy, gtMinigunBullet, 0, SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx, AngleCos(HHGear^.Angle) * ( - _0_8) + ry, 0); + bullet^.CollisionMask:= lfNotCurrentMask; + bullet^.WDTimer := Gear^.WDTimer; + Inc(Gear^.WDTimer); + + shell := AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell); + if shell <> nil then + begin + shell^.dX := gear^.dX.QWordValue / -17179869184; + shell^.dY := gear^.dY.QWordValue / -17179869184; + shell^.Frame := 0 + end; + end; + + if (Gear^.Timer = 0) or ((HHGear^.State and gstHHDriven) = 0) then + begin + HHGear^.State := HHGear^.State and (not gstNotKickable); + ClearHitOrder(); + DeleteGear(Gear); + AfterAttack + end +end; + +procedure doStepMinigun(Gear: PGear); +var HHGear: PGear; +begin + dec(Gear^.Timer); + if (Gear^.Timer mod 100) = 0 then + Gear^.Tag := (Gear^.Tag + 1) and 1; + + if Gear^.Timer = 0 then + begin + Gear^.Tag := 2; + HHGear := Gear^.Hedgehog^.Gear; + HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown)); + HHGear^.State := HHGear^.State or gstNotKickable; + + Gear^.Timer := 3501; + Gear^.WDTimer := 0; // Order of the next bullet; + ClearHitOrder(); + Gear^.doStep := @doStepMinigunWork + end; +end; + +//////////////////////////////////////////////////////////////////////////////// + +procedure doStepMinigunBullet(Gear: PGear); +begin + Gear^.Data:= nil; + // remember who fired this + if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.Gear <> nil) then + Gear^.Data:= Pointer(Gear^.Hedgehog^.Gear); + + PlaySound(sndGun); + Gear^.X := Gear^.X + Gear^.dX * 2; + Gear^.Y := Gear^.Y + Gear^.dY * 2; + Gear^.doStep := @doStepBulletWork +end; + (* This didn't end up getting used, but, who knows, might be reasonable for javellin or something // Make the knife initial angle based on the hog attack angle, or is that too hard? diff -r 856570ddd409 -r 8a40ce061d94 hedgewars/uGearsHedgehog.pas --- a/hedgewars/uGearsHedgehog.pas Mon Jan 15 12:15:56 2018 -0500 +++ b/hedgewars/uGearsHedgehog.pas Wed Jan 31 13:42:52 2018 -0500 @@ -315,6 +315,7 @@ newGear^.Radius:= 4 // temporarily shrink so it doesn't instantly embed in the ground end; amDEagle: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtDEagleShot, 0, xx * _0_5, yy * _0_5, 0); + amMinigun: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtMinigun, 0, xx * _0_5, yy * _0_5, 0); amSineGun: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSineGunShot, 0, xx * _0_5, yy * _0_5, 0); amPortalGun: begin newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtPortal, 0, xx * _0_6, yy * _0_6, @@ -466,7 +467,8 @@ amFlamethrower, amLandGun, amResurrector, //amStructure, amTardis, amPiano, - amIceGun, amRubber: CurAmmoGear:= newGear; + amIceGun, amRubber, + amMinigun: CurAmmoGear:= newGear; end; if CurAmmoType = amCake then FollowGear:= newGear; if CurAmmoType = amAirMine then newGear^.Hedgehog:= nil; diff -r 856570ddd409 -r 8a40ce061d94 hedgewars/uGearsList.pas --- a/hedgewars/uGearsList.pas Mon Jan 15 12:15:56 2018 -0500 +++ b/hedgewars/uGearsList.pas Wed Jan 31 13:42:52 2018 -0500 @@ -106,6 +106,8 @@ (* gtGenericFaller *) , amNothing (* gtKnife *) , amKnife (* gtDuck *) , amDuck +(* gtMinigun *) , amMinigun +(* gtMinigunBullet *) , amMinigun ); @@ -265,6 +267,7 @@ gtPoisonCloud: Gear^.Boom := 20; gtKnife: Gear^.Boom := 40000; // arbitrary scaling factor since impact-based gtDuck: Gear^.Boom := 40; + gtMinigunBullet: Gear^.Boom := 2; end; case Kind of @@ -741,6 +744,13 @@ gear^.Density:= _0_5; gear^.AdvBounce:= 1; end; + gtMinigun: begin + if gear^.Timer = 0 then gear^.Timer:= 601; + end; + gtMinigunBullet: begin + gear^.Radius:= 1; + gear^.Health:= 2; + end; gtGenericFaller:begin gear^.AdvBounce:= 1; gear^.Radius:= 1; diff -r 856570ddd409 -r 8a40ce061d94 hedgewars/uGearsRender.pas --- a/hedgewars/uGearsRender.pas Mon Jan 15 12:15:56 2018 -0500 +++ b/hedgewars/uGearsRender.pas Wed Jan 31 13:42:52 2018 -0500 @@ -639,7 +639,7 @@ defaultPos:= false; HatVisible:= true end; - gtShover: + gtShover, gtMinigun: begin DrawHedgehog(sx, sy, sign, 0, 5, 0); defaultPos:= false; @@ -822,7 +822,7 @@ 0, sign, 0); - amBaseballBat: + amBaseballBat, amMinigun: begin HatVisible:= true; DrawHedgehog(sx, sy, @@ -852,12 +852,6 @@ 32); *) end; - case amt of - amBaseballBat: DrawSpritePivotedF(sprHandBaseball, - sx + 9 * sign, - sy + 2, 0, sign, -8, 1, aangle); - end; - defaultPos:= false end; @@ -1025,6 +1019,7 @@ end end end; + if (Gear^.State and gstHHDriven) <> 0 then begin (* if (CurAmmoGear = nil) then @@ -1036,15 +1031,17 @@ end; *) if (CurAmmoGear = nil) then begin - if ((Gear^.State and (gstAttacked or gstAnimation or gstHHJumping)) = 0) - and (Gear^.Message and (gmLeft or gmRight) = 0) then - begin + if ((Gear^.State and (gstAttacked or gstAnimation or gstHHJumping)) = 0) + and (Gear^.Message and (gmLeft or gmRight) = 0) then + begin amt:= CurrentHedgehog^.CurAmmoType; - case amt of - amBaseballBat: DrawSpritePivotedF(sprHandBaseball, - sx + 9 * sign, sy + 2, 0, sign, -8, 1, aangle); + case amt of + amBaseballBat: DrawSpritePivotedF(sprHandBaseball, + sx + 9 * sign, sy + 2, 0, sign, -8, 1, aangle); + amMinigun: DrawSpritePivotedF(sprMinigun, + sx + 20 * sign, sy + 4, 0, sign, -18, -2, aangle); + end; end; - end; end else begin @@ -1065,7 +1062,10 @@ DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex); DrawAltWeapon(Gear, sx, sy) end; - gtShover: DrawSpritePivotedF(sprHandBaseball, sx + 9 * sign, sy + 2, CurAmmoGear^.Tag, sign, -8, 1, aangle); + gtShover: DrawSpritePivotedF(sprHandBaseball, + sx + 9 * sign, sy + 2, CurAmmoGear^.Tag, sign, -8, 1, aangle); + gtMinigun: DrawSpritePivotedF(sprMinigun, + sx + 20 * sign, sy + 4, CurAmmoGear^.Tag, sign, -18, -2, aangle); end; end end; diff -r 856570ddd409 -r 8a40ce061d94 hedgewars/uGearsUtils.pas --- a/hedgewars/uGearsUtils.pas Mon Jan 15 12:15:56 2018 -0500 +++ b/hedgewars/uGearsUtils.pas Wed Jan 31 13:42:52 2018 -0500 @@ -44,6 +44,7 @@ procedure CheckCollisionWithLand(Gear: PGear); inline; procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); +procedure AmmoShoveLine(Ammo: PGear; Damage, Power: LongInt; oX, oY, tX, tY: hwFloat); function GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): PGearArrayS; procedure SpawnBoxOfSmth; procedure ShotgunShot(Gear: PGear); @@ -663,7 +664,8 @@ TurnTimeLeft := 0; Gear^.RenderTimer := false; if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot) - and (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot) then + and (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot) + and (Gear^.Kind <> gtMinigunBullet) then if Gear^.Kind = gtHedgehog then begin if Gear^.Hedgehog^.Effects[heResurrectable] <> 0 then @@ -1204,13 +1206,14 @@ CanUseTardis:= usable; end; -procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); +procedure AmmoShoveImpl(Ammo: PGear; Damage, Power: LongInt; collisions: PGearArray); var t: PGearArray; Gear: PGear; i, j, tmpDmg: LongInt; VGear: PVisualGear; begin -t:= CheckGearsCollision(Ammo); +t:= collisions; + // Just to avoid hogs on rope dodging fire. if (CurAmmoGear <> nil) and ((CurAmmoGear^.Kind = gtRope) or (CurAmmoGear^.Kind = gtJetpack) or (CurAmmoGear^.Kind = gtBirdy)) and (CurrentHedgehog^.Gear <> nil) and (CurrentHedgehog^.Gear^.CollisionIndex = -1) @@ -1228,18 +1231,21 @@ begin dec(i); Gear:= t^.ar[i]; - if (Ammo^.Data <> nil) and (Ammo^.Kind in [gtDEagleShot, gtSniperRifleShot]) and (PGear(Ammo^.Data) = Gear) then + if (Ammo^.Data <> nil) and (Ammo^.Kind in [gtDEagleShot, gtSniperRifleShot, gtMinigunBullet]) and (PGear(Ammo^.Data) = Gear) + or ((Ammo^.Kind = gtMinigunBullet) and (not UpdateHitOrder(Gear, Ammo^.WDTimer))) then continue; + if ((Ammo^.Kind = gtFlame) or (Ammo^.Kind = gtBlowTorch)) and - (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heFrozen] > 255) then + (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heFrozen] > 255) then Gear^.Hedgehog^.Effects[heFrozen]:= max(255,Gear^.Hedgehog^.Effects[heFrozen]-10000); tmpDmg:= ModifyDamage(Damage, Gear); if (Gear^.State and gstNoDamage) = 0 then begin - if (Ammo^.Kind = gtDEagleShot) or (Ammo^.Kind = gtSniperRifleShot) then + if (Ammo^.Kind = gtDEagleShot) or (Ammo^.Kind = gtSniperRifleShot) + or (Ammo^.Kind = gtMinigunBullet) then begin - VGear := AddVisualGear(hwround(Ammo^.X), hwround(Ammo^.Y), vgtBulletHit); + VGear := AddVisualGear(t^.cX[i], t^.cY[i], vgtBulletHit); if VGear <> nil then VGear^.Angle := DxDy2Angle(-Ammo^.dX, Ammo^.dY); end; @@ -1268,7 +1274,10 @@ if (Ammo^.Kind = gtKnife) and (tmpDmg > 0) then for j:= 1 to max(1,min(3,tmpDmg div 5)) do begin - VGear:= AddVisualGear(hwRound(Ammo^.X-((Ammo^.X-Gear^.X)/_2)), hwRound(Ammo^.Y-((Ammo^.Y-Gear^.Y)/_2)), vgtStraightShot); + VGear:= AddVisualGear( + t^.cX[i] - ((t^.cX[i] - hwround(Gear^.X)) div 2), + t^.cY[i] - ((t^.cY[i] - hwround(Gear^.Y)) div 2), + vgtStraightShot); if VGear <> nil then with VGear^ do begin @@ -1297,13 +1306,13 @@ if (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.King or (Gear^.Hedgehog^.Effects[heFrozen] > 0)) then begin - Gear^.dX:= Ammo^.dX * Power * _0_005; - Gear^.dY:= Ammo^.dY * Power * _0_005 + Gear^.dX:= Gear^.dX + Ammo^.dX * Power * _0_005; + Gear^.dY:= Gear^.dY + Ammo^.dY * Power * _0_005 end else if ((Ammo^.Kind <> gtFlame) or (Gear^.Kind = gtHedgehog)) and (Power <> 0) then begin - Gear^.dX:= Ammo^.dX * Power * _0_01; - Gear^.dY:= Ammo^.dY * Power * _0_01 + Gear^.dX:= Gear^.dX + Ammo^.dX * Power * _0_01; + Gear^.dY:= Gear^.dY + Ammo^.dY * Power * _0_01 end; if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then @@ -1338,6 +1347,22 @@ SetAllToActive end; +procedure AmmoShoveLine(Ammo: PGear; Damage, Power: LongInt; oX, oY, tX, tY: hwFloat); +var t: PGearArray; +begin + if Ammo^.Kind = gtMinigunBullet then + t:= CheckAllGearsLineCollision(Ammo, oX, oY, tX, tY) + else + t:= CheckGearsLineCollision(Ammo, oX, oY, tX, tY); + AmmoShoveImpl(Ammo, Damage, Power, t); +end; + +procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); +begin + AmmoShoveImpl(Ammo, Damage, Power, + CheckGearsCollision(Ammo)); +end; + function CountGears(Kind: TGearType): Longword; var t: PGear; @@ -1579,7 +1604,7 @@ (hwRound(Gear^.X) > LongInt(rightX)) then begin // bullets can now hurt the hog that fired them - if (WorldEdge <> weSea) and (Gear^.Kind in [gtDEagleShot, gtSniperRifleShot]) then + if (WorldEdge <> weSea) and (Gear^.Kind in [gtDEagleShot, gtSniperRifleShot, gtMinigunBullet]) then Gear^.Data:= nil; if WorldEdge = weWrap then begin diff -r 856570ddd409 -r 8a40ce061d94 hedgewars/uRender.pas --- a/hedgewars/uRender.pas Mon Jan 15 12:15:56 2018 -0500 +++ b/hedgewars/uRender.pas Wed Jan 31 13:42:52 2018 -0500 @@ -1148,7 +1148,7 @@ if Angle <> 0 then begin // Check the bounding circle - if isCircleOffscreen(X, Y, sqr(SpritesData[Sprite].Width) + sqr(SpritesData[Sprite].Height)) then + if isCircleOffscreen(X, Y, (sqr(SpritesData[Sprite].Width) + sqr(SpritesData[Sprite].Height)) div 4) then exit; end else diff -r 856570ddd409 -r 8a40ce061d94 hedgewars/uTypes.pas --- a/hedgewars/uTypes.pas Mon Jan 15 12:15:56 2018 -0500 +++ b/hedgewars/uTypes.pas Wed Jan 31 13:42:52 2018 -0500 @@ -91,7 +91,7 @@ sprSlider, sprBotlevels, sprHandKnife, sprKnife, sprStar, sprIceTexture, sprIceGun, sprFrozenHog, sprAmRubber, sprBoing, sprCustom1, sprCustom2, sprCustom3, sprCustom4, sprCustom5, sprCustom6, sprCustom7, sprCustom8, sprAirMine, sprHandAirMine, - sprFlakeL, sprSDFlakeL, sprCloudL, sprSDCloudL, sprDuck, sprHandDuck + sprFlakeL, sprSDFlakeL, sprCloudL, sprSDCloudL, sprDuck, sprHandDuck, sprMinigun ); // Gears that interact with other Gears and/or Land @@ -109,7 +109,7 @@ gtEgg, gtPortal, gtPiano, gtGasBomb, gtSineGunShot, gtFlamethrower, // 51 gtSMine, gtPoisonCloud, gtHammer, gtHammerHit, gtResurrector, // 56 gtNapalmBomb, gtSnowball, gtFlake, {gtStructure,} gtLandGun, gtTardis, // 61 - gtIceGun, gtAddAmmo, gtGenericFaller, gtKnife, gtDuck); // 66 + gtIceGun, gtAddAmmo, gtGenericFaller, gtKnife, gtDuck, gtMinigun, gtMinigunBullet); // 68 // Gears that are _only_ of visual nature (e.g. background stuff, visual effects, speechbubbles, etc.) TVisualGearType = (vgtFlake, vgtCloud, vgtExplPart, vgtExplPart2, vgtFire, @@ -163,7 +163,7 @@ amLaserSight, amVampiric, amSniperRifle, amJetpack, amMolotov, amBirdy, amPortalGun, // 42 amPiano, amGasBomb, amSineGun, amFlamethrower, amSMine, amHammer, // 48 amResurrector, amDrillStrike, amSnowball, amTardis, {amStructure,} amLandGun, // 53 - amIceGun, amKnife, amRubber, amAirMine, amDuck); // 58 + amIceGun, amKnife, amRubber, amAirMine, amDuck, amMinigun); // 59 // Different kind of crates that e.g. hedgehogs can pick up TCrateType = (HealthCrate, AmmoCrate, UtilityCrate); @@ -460,7 +460,7 @@ sidSineGun, sidFlamethrower,sidSMine, sidHammer, sidResurrector, sidDrillStrike, sidSnowball, sidNothing, sidTardis, {sidStructure,} sidLandGun, sidIceGun, sidKnife, sidRubber, sidAirMine, - sidDuck); + sidDuck, sidMinigun); TMsgStrId = (sidLoading, sidDraw, sidWinner, sidVolume, sidPaused, sidConfirm, sidSuddenDeath, sidRemaining, sidFuel, sidSync, diff -r 856570ddd409 -r 8a40ce061d94 hedgewars/uVariables.pas --- a/hedgewars/uVariables.pas Mon Jan 15 12:15:56 2018 -0500 +++ b/hedgewars/uVariables.pas Wed Jan 31 13:42:52 2018 -0500 @@ -702,7 +702,7 @@ Texture: nil; Surface: nil; Width: 32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true), - // sprNapalmBomb + // sprBulletHit (FileName: 'Snowball'; Path: ptCurrTheme; AltPath: ptGraphics; Texture: nil; Surface: nil; Width: 16; Height: 16; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprSnowball (FileName: 'amSnowball'; Path: ptCurrTheme; AltPath: ptHedgehog; Texture: nil; Surface: nil; @@ -772,7 +772,9 @@ (FileName: 'Duck'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil; Width: 32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprDuck (FileName: 'amDuck'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil; - Width: 64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true) // sprHandDuck + Width: 64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true), // sprHandDuck + (FileName: 'amMinigun'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil; + Width: 64; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true) // sprMinigun ); const @@ -2438,7 +2440,30 @@ PosCount: 1; PosSprite: sprWater; ejectX: 15; - ejectY: -7) + ejectY: -7), +// Minigun + (NameId: sidMinigun; + NameTex: nil; + Probability: 100; + NumberInCase: 1; + Ammo: (Propz: ammoprop_NeedUpDown; + Count: 1; + NumPerTurn: 0; + Timer: 0; + Pos: 0; + AmmoType: amMinigun; + AttackVoice: sndNone; + Bounciness: 1000); + Slot: 2; + TimeAfterTurn: 3000; + minAngle: cMaxAngle div 6; + maxAngle: 5 * cMaxAngle div 6; + isDamaging: true; + SkipTurns: 0; + PosCount: 1; + PosSprite: sprWater; + ejectX: 0; //23; + ejectY: 0) //-6; ); var diff -r 856570ddd409 -r 8a40ce061d94 share/hedgewars/Data/Graphics/AmmoMenu/Ammos_base.png Binary file share/hedgewars/Data/Graphics/AmmoMenu/Ammos_base.png has changed diff -r 856570ddd409 -r 8a40ce061d94 share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw_base.png Binary file share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw_base.png has changed diff -r 856570ddd409 -r 8a40ce061d94 share/hedgewars/Data/Graphics/amMinigun.png Binary file share/hedgewars/Data/Graphics/amMinigun.png has changed diff -r 856570ddd409 -r 8a40ce061d94 share/hedgewars/Data/Graphics/amMinigun.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Graphics/amMinigun.svg Wed Jan 31 13:42:52 2018 -0500 @@ -0,0 +1,340 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 856570ddd409 -r 8a40ce061d94 share/hedgewars/Data/Locale/en.txt --- a/share/hedgewars/Data/Locale/en.txt Mon Jan 15 12:15:56 2018 -0500 +++ b/share/hedgewars/Data/Locale/en.txt Wed Jan 31 13:42:52 2018 -0500 @@ -61,6 +61,7 @@ 00:57=Rubber 00:58=Air Mine 00:59=Rubber Duck +00:60=Minigun 01:00=Loading … 01:01=Round draw @@ -1194,6 +1195,7 @@ 03:57=Utility 03:58=Floating proximity bomb 03:59=Swimming bomb +03:60=The ultimate firearm ; Weapon Descriptions (use | as line breaks) 04:00=Attack your enemies using a simple grenade.|It will explode once its timer reaches zero.|1-5: Set grenade's timer|Precise + 1-5: Set bounce strength|Attack: Hold to throw with more power @@ -1256,6 +1258,7 @@ 04:57=Build a VERY elastic rubber band, from which|hedgehogs and other things bounce off|without taking fall damage.|Left/Right: Change rubber band orientation|Cursor: Place rubber band in a valid position 04:58=This proximity bomb will float freely in the air and follow|hedgehogs careless enouogh to come too close to it.|Its explosion is weaker than that of the land mine, however.|Attack: Hold to shoot with more power 04:59=Send those dirty hogs swimming! This cute little squeaky|rubber duck is able to swim on water and will go with the|wind once swimming. It explodes when it hits land, so|make sure to drop it from a cliff or another safe spot.|Attack: Drop the rubber duck +04:60=Unleash a rain of bullets upon your foes!|And they thought they were safe|behind a triple layer of girders.|Attack: Shoot at full power|Up/Down: Continue aiming ; Game goal strings 05:00=Game Modes