# HG changeset patch # User Medo # Date 1346082016 -7200 # Node ID ce6ead3327b260dcf6dc7e598f16f145caf3b742 # Parent 0be267033fb3b76dfc2f6a758ea73140f8071ea9# Parent 047c6692a2e7c93089c99a2ce4dceea19eb65d56 Merge diff -r 0be267033fb3 -r ce6ead3327b2 INSTALL --- a/INSTALL Thu Aug 23 19:47:38 2012 +0200 +++ b/INSTALL Mon Aug 27 17:40:16 2012 +0200 @@ -18,9 +18,9 @@ $ cmake . or $ cmake -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX="install_prefix" \ --DDATA_INSTALL_DIR="data_dir" . +-DDATA_INSTALL_DIR="data_dir" -DNOSERVER=1 . -add -DWITH_SERVER=1 to compile net server; if you have Qt installed but it is +add -DNOSERVER=0 to compile net server; if you have Qt installed but it is not found you can set it up with -DQT_QMAKE_EXECUTABLE="path_to_qmake" 2. Compile: diff -r 0be267033fb3 -r ce6ead3327b2 QTfrontend/net/tcpBase.cpp --- a/QTfrontend/net/tcpBase.cpp Thu Aug 23 19:47:38 2012 +0200 +++ b/QTfrontend/net/tcpBase.cpp Mon Aug 27 17:40:16 2012 +0200 @@ -107,6 +107,8 @@ QMessageBox::critical(0, tr("Error"), tr("Unable to run engine: %1 (") .arg(error) + bindir->absolutePath() + "/hwengine)"); + + ClientDisconnect(); } void TCPBase::tcpServerReady() diff -r 0be267033fb3 -r ce6ead3327b2 gameServer/Actions.hs --- a/gameServer/Actions.hs Thu Aug 23 19:47:38 2012 +0200 +++ b/gameServer/Actions.hs Mon Aug 27 17:40:16 2012 +0200 @@ -541,8 +541,8 @@ when (pq > 0) $ do withStateT (\as -> as{clientIndex = Just ci}) $ processAction (ByeClient "Ping timeout") - when (pq > 1) $ - processAction $ DeleteClient ci -- smth went wrong with client io threads, issue DeleteClient here +-- when (pq > 1) $ +-- processAction $ DeleteClient ci -- smth went wrong with client io threads, issue DeleteClient here processAction StatsAction = do diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/CMakeLists.txt --- a/hedgewars/CMakeLists.txt Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/CMakeLists.txt Mon Aug 27 17:40:16 2012 +0200 @@ -33,7 +33,9 @@ uGame.pas uGears.pas uGearsHandlers.pas + uGearsHandlersRope.pas uGearsRender.pas + uGearsUtils.pas uIO.pas uInputHandler.pas uLand.pas diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/GSHandlers.inc Mon Aug 27 17:40:16 2012 +0200 @@ -140,28 +140,6 @@ ScriptCall('onHogRestore', HH^.Gear^.Uid) end; -//////////////////////////////////////////////////////////////////////////////// -procedure CheckCollision(Gear: PGear); inline; -begin - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0) then - Gear^.State := Gear^.State or gstCollision - else - Gear^.State := Gear^.State and (not gstCollision) -end; - -procedure CheckCollisionWithLand(Gear: PGear); inline; -begin - if TestCollisionX(Gear, hwSign(Gear^.dX)) - or TestCollisionY(Gear, hwSign(Gear^.dY)) then - Gear^.State := Gear^.State or gstCollision - else - Gear^.State := Gear^.State and (not gstCollision) -end; - - -//////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// procedure doStepDrowningGear(Gear: PGear); @@ -923,7 +901,13 @@ Gear^.State := Gear^.State or gstAnimation end; exit - end + end else + if(Gear^.Hedgehog^.Gear = nil) or ((Gear^.Hedgehog^.Gear^.State and gstMoving) <> 0) then + begin + DeleteGear(Gear); + AfterAttack; + exit + end else inc(Gear^.Timer); @@ -1400,436 +1384,6 @@ end; //////////////////////////////////////////////////////////////////////////////// - -procedure doStepRope(Gear: PGear); -forward; - -procedure doStepRopeAfterAttack(Gear: PGear); -var - HHGear: PGear; -begin - HHGear := Gear^.Hedgehog^.Gear; - if ((HHGear^.State and gstHHDriven) = 0) - or (CheckGearDrowning(HHGear)) - or (TestCollisionYwithGear(HHGear, 1) <> 0) then - begin - DeleteGear(Gear); - isCursorVisible := false; - ApplyAmmoChanges(HHGear^.Hedgehog^); - exit - end; - - HedgehogChAngle(HHGear); - - if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then - SetLittle(HHGear^.dX); - - if HHGear^.dY.isNegative and (TestCollisionYwithGear(HHGear, -1) <> 0) then - HHGear^.dY := _0; - HHGear^.X := HHGear^.X + HHGear^.dX; - HHGear^.Y := HHGear^.Y + HHGear^.dY; - HHGear^.dY := HHGear^.dY + cGravity; - - if (GameFlags and gfMoreWind) <> 0 then - HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density; - - if (Gear^.Message and gmAttack) <> 0 then - begin - Gear^.X := HHGear^.X; - Gear^.Y := HHGear^.Y; - - ApplyAngleBounds(Gear^.Hedgehog^, amRope); - - Gear^.dX := SignAs(AngleSin(HHGear^.Angle), HHGear^.dX); - Gear^.dY := -AngleCos(HHGear^.Angle); - Gear^.Friction := _4_5 * cRopePercent; - Gear^.Elasticity := _0; - Gear^.State := Gear^.State and (not gsttmpflag); - Gear^.doStep := @doStepRope; - end -end; - -procedure RopeDeleteMe(Gear, HHGear: PGear); -begin - with HHGear^ do - begin - Message := Message and (not gmAttack); - State := (State or gstMoving) and (not gstWinner); - end; - DeleteGear(Gear) -end; - -procedure RopeWaitCollision(Gear, HHGear: PGear); -begin - with HHGear^ do - begin - Message := Message and (not gmAttack); - State := State or gstMoving; - end; - RopePoints.Count := 0; - Gear^.Elasticity := _0; - Gear^.doStep := @doStepRopeAfterAttack -end; - -procedure doStepRopeWork(Gear: PGear); -var - HHGear: PGear; - len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat; - lx, ly, cd: LongInt; - haveCollision, - haveDivided: boolean; - -begin - HHGear := Gear^.Hedgehog^.Gear; - - if ((HHGear^.State and gstHHDriven) = 0) - or (CheckGearDrowning(HHGear)) or (Gear^.PortalCounter <> 0) then - begin - PlaySound(sndRopeRelease); - RopeDeleteMe(Gear, HHGear); - exit - end; - - if (Gear^.Message and gmLeft <> 0) and (not TestCollisionXwithGear(HHGear, -1)) then - HHGear^.dX := HHGear^.dX - _0_0002; - - if (Gear^.Message and gmRight <> 0) and (not TestCollisionXwithGear(HHGear, 1)) then - HHGear^.dX := HHGear^.dX + _0_0002; - - // vector between hedgehog and rope attaching point - ropeDx := HHGear^.X - Gear^.X; - ropeDy := HHGear^.Y - Gear^.Y; - - if TestCollisionYwithGear(HHGear, 1) = 0 then - begin - - // depending on the rope vector we know which X-side to check for collision - // in order to find out if the hog can still be moved by gravity - if ropeDx.isNegative = RopeDy.IsNegative then - cd:= -1 - else - cd:= 1; - - // apply gravity if there is no obstacle - if not TestCollisionXwithGear(HHGear, cd) then - HHGear^.dY := HHGear^.dY + cGravity; - - if (GameFlags and gfMoreWind) <> 0 then - // apply wind if there's no obstacle - if not TestCollisionXwithGear(HHGear, hwSign(cWindSpeed)) then - HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density; - end; - - mdX := ropeDx + HHGear^.dX; - mdY := ropeDy + HHGear^.dY; - len := _1 / Distance(mdX, mdY); - // rope vector plus hedgehog direction vector normalized - mdX := mdX * len; - mdY := mdY * len; - - // for visual purposes only - Gear^.dX := mdX; - Gear^.dY := mdY; - - ///// - tx := HHGear^.X; - ty := HHGear^.Y; - - if ((Gear^.Message and gmDown) <> 0) and (Gear^.Elasticity < Gear^.Friction) then - if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx)) - or (TestCollisionYwithGear(HHGear, hwSign(ropeDy)) <> 0)) then - Gear^.Elasticity := Gear^.Elasticity + _0_3; - - if ((Gear^.Message and gmUp) <> 0) and (Gear^.Elasticity > _30) then - if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx)) - or (TestCollisionYwithGear(HHGear, -hwSign(ropeDy)) <> 0)) then - Gear^.Elasticity := Gear^.Elasticity - _0_3; - - HHGear^.X := Gear^.X + mdX * Gear^.Elasticity; - HHGear^.Y := Gear^.Y + mdY * Gear^.Elasticity; - - HHGear^.dX := HHGear^.X - tx; - HHGear^.dY := HHGear^.Y - ty; - //// - - - haveDivided := false; - // check whether rope needs dividing - - len := Gear^.Elasticity - _5; - nx := Gear^.X + mdX * len; - ny := Gear^.Y + mdY * len; - tx := mdX * _0_3; // should be the same as increase step - ty := mdY * _0_3; - - while len > _3 do - begin - lx := hwRound(nx); - ly := hwRound(ny); - if ((ly and LAND_HEIGHT_MASK) = 0) and ((lx and LAND_WIDTH_MASK) = 0) and ((Land[ly, lx] and $FF00) <> 0) then - begin - ny := _1 / Distance(ropeDx, ropeDy); - // old rope pos - nx := ropeDx * ny; - ny := ropeDy * ny; - - with RopePoints.ar[RopePoints.Count] do - begin - X := Gear^.X; - Y := Gear^.Y; - if RopePoints.Count = 0 then - RopePoints.HookAngle := DxDy2Angle(Gear^.dY, Gear^.dX); - b := (nx * HHGear^.dY) > (ny * HHGear^.dX); - dLen := len - end; - - with RopePoints.rounded[RopePoints.Count] do - begin - X := hwRound(Gear^.X); - Y := hwRound(Gear^.Y); - end; - - Gear^.X := Gear^.X + nx * len; - Gear^.Y := Gear^.Y + ny * len; - inc(RopePoints.Count); - TryDo(RopePoints.Count <= MAXROPEPOINTS, 'Rope points overflow', true); - Gear^.Elasticity := Gear^.Elasticity - len; - Gear^.Friction := Gear^.Friction - len; - haveDivided := true; - break - end; - nx := nx - tx; - ny := ny - ty; - - // len := len - _0_3 // should be the same as increase step - len.QWordValue := len.QWordValue - _0_3.QWordValue; - end; - - if not haveDivided then - if RopePoints.Count > 0 then // check whether the last dividing point could be removed - begin - tx := RopePoints.ar[Pred(RopePoints.Count)].X; - ty := RopePoints.ar[Pred(RopePoints.Count)].Y; - mdX := tx - Gear^.X; - mdY := ty - Gear^.Y; - if RopePoints.ar[Pred(RopePoints.Count)].b xor (mdX * (ty - HHGear^.Y) > (tx - HHGear^.X) * mdY) then - begin - dec(RopePoints.Count); - Gear^.X := RopePoints.ar[RopePoints.Count].X; - Gear^.Y := RopePoints.ar[RopePoints.Count].Y; - Gear^.Elasticity := Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen; - Gear^.Friction := Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen; - - // restore hog position - len := _1 / Distance(mdX, mdY); - mdX := mdX * len; - mdY := mdY * len; - - HHGear^.X := Gear^.X - mdX * Gear^.Elasticity; - HHGear^.Y := Gear^.Y - mdY * Gear^.Elasticity; - end - end; - - haveCollision := false; - if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then - begin - HHGear^.dX := -_0_6 * HHGear^.dX; - haveCollision := true - end; - if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) <> 0 then - begin - HHGear^.dY := -_0_6 * HHGear^.dY; - haveCollision := true - end; - - if haveCollision and (Gear^.Message and (gmLeft or gmRight) <> 0) and (Gear^.Message and (gmUp or gmDown) <> 0) then - begin - HHGear^.dX := SignAs(hwAbs(HHGear^.dX) + _0_2, HHGear^.dX); - HHGear^.dY := SignAs(hwAbs(HHGear^.dY) + _0_2, HHGear^.dY) - end; - - len := hwSqr(HHGear^.dX) + hwSqr(HHGear^.dY); - if len > _0_64 then - begin - len := _0_8 / hwSqrt(len); - HHGear^.dX := HHGear^.dX * len; - HHGear^.dY := HHGear^.dY * len; - end; - - haveCollision:= ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) and ((Land[hwRound(Gear^.Y), hwRound(Gear^.X)]) <> 0); - - if not haveCollision then - begin - // backup gear location - tx:= Gear^.X; - ty:= Gear^.Y; - - if RopePoints.Count > 0 then - begin - // set gear location to the remote end of the rope, the attachment point - Gear^.X:= RopePoints.ar[0].X; - Gear^.Y:= RopePoints.ar[0].Y; - end; - - CheckCollision(Gear); - // if we haven't found any collision yet then check the other side too - if (Gear^.State and gstCollision) = 0 then - begin - Gear^.dX.isNegative:= not Gear^.dX.isNegative; - Gear^.dY.isNegative:= not Gear^.dY.isNegative; - CheckCollision(Gear); - Gear^.dX.isNegative:= not Gear^.dX.isNegative; - Gear^.dY.isNegative:= not Gear^.dY.isNegative; - end; - - haveCollision:= (Gear^.State and gstCollision) <> 0; - - // restore gear location - Gear^.X:= tx; - Gear^.Y:= ty; - end; - - // if the attack key is pressed, lose rope contact as well - if (Gear^.Message and gmAttack) <> 0 then - haveCollision:= false; - - if not haveCollision then - begin - if (Gear^.State and gsttmpFlag) <> 0 then - begin - PlaySound(sndRopeRelease); - if Gear^.Hedgehog^.CurAmmoType <> amParachute then - RopeWaitCollision(Gear, HHGear) - else - RopeDeleteMe(Gear, HHGear) - end - end - else - if (Gear^.State and gsttmpFlag) = 0 then - Gear^.State := Gear^.State or gsttmpFlag; -end; - -procedure RopeRemoveFromAmmo(Gear, HHGear: PGear); -begin - if (Gear^.State and gstAttacked) = 0 then - begin - OnUsedAmmo(HHGear^.Hedgehog^); - Gear^.State := Gear^.State or gstAttacked - end; - ApplyAmmoChanges(HHGear^.Hedgehog^) -end; - -procedure doStepRopeAttach(Gear: PGear); -var - HHGear: PGear; - tx, ty, tt: hwFloat; -begin - Gear^.X := Gear^.X - Gear^.dX; - Gear^.Y := Gear^.Y - Gear^.dY; - Gear^.Elasticity := Gear^.Elasticity + _1; - - HHGear := Gear^.Hedgehog^.Gear; - DeleteCI(HHGear); - - if (HHGear^.State and gstMoving) <> 0 then - begin - if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then - SetLittle(HHGear^.dX); - if HHGear^.dY.isNegative and (TestCollisionYwithGear(HHGear, -1) <> 0) then - HHGear^.dY := _0; - - HHGear^.X := HHGear^.X + HHGear^.dX; - Gear^.X := Gear^.X + HHGear^.dX; - - if TestCollisionYwithGear(HHGear, 1) <> 0 then - begin - CheckHHDamage(HHGear); - HHGear^.dY := _0 - //HHGear^.State:= HHGear^.State and (not (gstHHJumping or gstHHHJump)); - end - else - begin - HHGear^.Y := HHGear^.Y + HHGear^.dY; - Gear^.Y := Gear^.Y + HHGear^.dY; - HHGear^.dY := HHGear^.dY + cGravity; - if (GameFlags and gfMoreWind) <> 0 then - HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density - end; - - tt := Gear^.Elasticity; - tx := _0; - ty := _0; - while tt > _20 do - begin - if ((hwRound(Gear^.Y+ty) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X+tx) and LAND_WIDTH_MASK) = 0) and ((Land[hwRound(Gear^.Y+ty), hwRound(Gear^.X+tx)] and $FF00) <> 0) then - begin - Gear^.X := Gear^.X + tx; - Gear^.Y := Gear^.Y + ty; - Gear^.Elasticity := tt; - Gear^.doStep := @doStepRopeWork; - PlaySound(sndRopeAttach); - with HHGear^ do - begin - State := State and (not (gstAttacking or gstHHJumping or gstHHHJump)); - Message := Message and (not gmAttack) - end; - - RopeRemoveFromAmmo(Gear, HHGear); - - tt := _0; - exit - end; - tx := tx + Gear^.dX + Gear^.dX; - ty := ty + Gear^.dY + Gear^.dY; - tt := tt - _2; - end; - end; - - CheckCollision(Gear); - - if (Gear^.State and gstCollision) <> 0 then - if Gear^.Elasticity < _10 then - Gear^.Elasticity := _10000 - else - begin - Gear^.doStep := @doStepRopeWork; - PlaySound(sndRopeAttach); - with HHGear^ do - begin - State := State and (not (gstAttacking or gstHHJumping or gstHHHJump)); - Message := Message and (not gmAttack) - end; - - RopeRemoveFromAmmo(Gear, HHGear); - - exit - end; - - if (Gear^.Elasticity > Gear^.Friction) - or ((Gear^.Message and gmAttack) = 0) - or ((HHGear^.State and gstHHDriven) = 0) - or (HHGear^.Damage > 0) then - begin - with Gear^.Hedgehog^.Gear^ do - begin - State := State and (not gstAttacking); - Message := Message and (not gmAttack) - end; - DeleteGear(Gear); - exit; - end; - if CheckGearDrowning(HHGear) then DeleteGear(Gear) -end; - -procedure doStepRope(Gear: PGear); -begin - Gear^.dX := - Gear^.dX; - Gear^.dY := - Gear^.dY; - Gear^.doStep := @doStepRopeAttach; - PlaySound(sndRopeShot) -end; - -//////////////////////////////////////////////////////////////////////////////// procedure doStepMine(Gear: PGear); var vg: PVisualGear; begin @@ -4035,7 +3589,7 @@ break; // don't port portals or other gear that wouldn't make sense - if (iterator^.Kind in [gtPortal, gtRope]) + if (iterator^.Kind in [gtPortal, gtRope, gtAirAttack]) or (iterator^.PortalCounter > 32) then continue; @@ -4317,23 +3871,6 @@ iterator^.Friction := iterator^.Y; end; - // This jiggles gears, to ensure a portal connection just placed under a gear takes effect. - iterator:= GearsList; - while iterator <> nil do - begin - if (iterator^.Kind <> gtPortal) and ((iterator^.Hedgehog <> CurrentHedgehog) - or ((iterator^.Message and gmAllStoppable) = 0)) then - begin - iterator^.Active:= true; - if iterator^.dY.QWordValue = _0.QWordValue then - iterator^.dY.isNegative:= false; - iterator^.State:= iterator^.State or gstMoving; - DeleteCI(iterator); - //inc(iterator^.dY.QWordValue,10); - end; - iterator:= iterator^.NextGear - end; - if Gear^.Health > 1 then dec(Gear^.Health); end; @@ -4462,7 +3999,7 @@ iterator := GearsList; while iterator <> nil do - begin + begin if (iterator^.Kind = gtPortal) then if (iterator <> newPortal) and (iterator^.Timer > 0) and (iterator^.Hedgehog = CurrentHedgehog) then begin @@ -4480,7 +4017,27 @@ end; iterator^.PortalCounter:= 0; iterator := iterator^.NextGear - end; + end; + + if newPortal^.LinkedGear <> nil then + begin + // This jiggles gears, to ensure a portal connection just placed under a gear takes effect. + iterator:= GearsList; + while iterator <> nil do + begin + if not (iterator^.Kind in [gtPortal, gtAirAttack]) and ((iterator^.Hedgehog <> CurrentHedgehog) + or ((iterator^.Message and gmAllStoppable) = 0)) then + begin + iterator^.Active:= true; + if iterator^.dY.QWordValue = _0.QWordValue then + iterator^.dY.isNegative:= false; + iterator^.State:= iterator^.State or gstMoving; + DeleteCI(iterator); + //inc(iterator^.dY.QWordValue,10); + end; + iterator:= iterator^.NextGear + end + end end; newPortal^.State := newPortal^.State and (not gstCollision); newPortal^.State := newPortal^.State or gstMoving; diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/hwengine.pas Mon Aug 27 17:40:16 2012 +0200 @@ -30,7 +30,7 @@ {$ENDIF} uses SDLh, uMisc, uConsole, uGame, uConsts, uLand, uAmmos, uVisualGears, uGears, uStore, uWorld, uInputHandler, uSound, - uScript, uTeams, uStats, uIO, uLocale, uChat, uAI, uAIMisc, uRandom, uLandTexture, uCollisions, + uScript, uTeams, uStats, uIO, uLocale, uChat, uAI, uAIMisc, uLandTexture, uCollisions, SysUtils, uTypes, uVariables, uCommands, uUtils, uCaptions, uDebug, uCommandHandlers, uLandPainted {$IFDEF SDL13}, uTouch{$ENDIF}{$IFDEF ANDROID}, GLUnit{$ENDIF}, uAILandMarks; @@ -416,7 +416,6 @@ //uLandObjects does not need initialization //uLandTemplates does not need initialization //uLocale does not need initialization - uRandom.initModule; uScript.initModule; uSound.initModule; uStats.initModule; @@ -444,7 +443,7 @@ uStats.freeModule; //stub uSound.freeModule; uScript.freeModule; - uRandom.freeModule; //stub + //uRandom does not need to be freed //uLocale does not need to be freed //uLandTemplates does not need to be freed uLandTexture.freeModule; diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/uFloat.pas --- a/hedgewars/uFloat.pas Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/uFloat.pas Mon Aug 27 17:40:16 2012 +0200 @@ -119,6 +119,7 @@ _0_005: hwFloat = (isNegative: false; QWordValue: 21474836); _0_008: hwFloat = (isNegative: false; QWordValue: 34359738); _0_01: hwFloat = (isNegative: false; QWordValue: 42949673); + _0_0128: hwFloat = (isNegative: false; QWordValue: 54975581); _0_02: hwFloat = (isNegative: false; QWordValue: 85899345); _0_03: hwFloat = (isNegative: false; QWordValue: 128849018); _0_07: hwFloat = (isNegative: false; QWordValue: 300647710); @@ -149,14 +150,18 @@ _0: hwFloat = (isNegative: false; QWordValue: 0); _1: hwFloat = (isNegative: false; QWordValue: 4294967296); _1_5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3 div 2); + _1_6: hwFloat = (isNegative: false; QWordValue: 4294967296 * 8 div 5); _1_9: hwFloat = (isNegative: false; QWordValue: 8160437862); _2: hwFloat = (isNegative: false; QWordValue: 4294967296 * 2); + _2_4: hwFloat = (isNegative: false; QWordValue: 4294967296 * 12 div 5); _3: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3); _PI: hwFloat = (isNegative: false; QWordValue: 13493037704); _4: hwFloat = (isNegative: false; QWordValue: 4294967296 * 4); _4_5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 9 div 2); _5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 5); _6: hwFloat = (isNegative: false; QWordValue: 4294967296 * 6); + _6_4: hwFloat = (isNegative: false; QWordValue: 3435973837 * 8); + _7: hwFloat = (isNegative: false; QWordValue: 4294967296 * 7); _10: hwFloat = (isNegative: false; QWordValue: 4294967296 * 10); _12: hwFloat = (isNegative: false; QWordValue: 4294967296 * 12); _16: hwFloat = (isNegative: false; QWordValue: 4294967296 * 16); @@ -165,6 +170,8 @@ _25: hwFloat = (isNegative: false; QWordValue: 4294967296 * 25); _30: hwFloat = (isNegative: false; QWordValue: 4294967296 * 30); _40: hwFloat = (isNegative: false; QWordValue: 4294967296 * 40); + _41: hwFloat = (isNegative: false; QWordValue: 4294967296 * 41); + _49: hwFloat = (isNegative: false; QWordValue: 4294967296 * 49); _50: hwFloat = (isNegative: false; QWordValue: 4294967296 * 50); _70: hwFloat = (isNegative: false; QWordValue: 4294967296 * 70); _90: hwFloat = (isNegative: false; QWordValue: 4294967296 * 90); diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/uGears.pas --- a/hedgewars/uGears.pas Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/uGears.pas Mon Aug 27 17:40:16 2012 +0200 @@ -59,7 +59,7 @@ uses uStore, uSound, uTeams, uRandom, uCollisions, uIO, uLandGraphics, uLocale, uAI, uAmmos, uStats, uVisualGears, uScript, GLunit, uMobile, uVariables, uCommands, uUtils, uTextures, uRenderUtils, uGearsRender, uCaptions, uDebug, uLandTexture, - uGearsHedgehog, uGearsUtils, uGearsList, uGearsHandlers; + uGearsHedgehog, uGearsUtils, uGearsList, uGearsHandlers, uGearsHandlersRope; var skipFlag: boolean; @@ -641,7 +641,8 @@ if (GameFlags and gfArtillery) <> 0 then cArtillery:= true; for i:= GetRandom(10)+30 downto 0 do - begin rx:= GetRandom(rightX-leftX)+leftX; + begin + rx:= GetRandom(rightX-leftX)+leftX; ry:= GetRandom(LAND_HEIGHT-topY)+topY; rdx:= _90-(GetRandomf*_360); rdy:= _90-(GetRandomf*_360); diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/uGearsHandlersRope.pas --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hedgewars/uGearsHandlersRope.pas Mon Aug 27 17:40:16 2012 +0200 @@ -0,0 +1,589 @@ +(* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + *) + +{$INCLUDE "options.inc"} +unit uGearsHandlersRope; +interface + +uses uTypes; + +procedure doStepRope(Gear: PGear); + +implementation +uses uConsts, uFloat, uCollisions, uVariables, uGearsList, uSound, uGearsUtils, + uAmmos, uDebug, uUtils, uGearsHedgehog, uGearsRender; + +procedure doStepRopeAfterAttack(Gear: PGear); +var + HHGear: PGear; +begin + HHGear := Gear^.Hedgehog^.Gear; + if ((HHGear^.State and gstHHDriven) = 0) + or (CheckGearDrowning(HHGear)) + or (TestCollisionYwithGear(HHGear, 1) <> 0) then + begin + DeleteGear(Gear); + isCursorVisible := false; + ApplyAmmoChanges(HHGear^.Hedgehog^); + exit + end; + + HedgehogChAngle(HHGear); + + if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then + SetLittle(HHGear^.dX); + + if HHGear^.dY.isNegative and (TestCollisionYwithGear(HHGear, -1) <> 0) then + HHGear^.dY := _0; + HHGear^.X := HHGear^.X + HHGear^.dX; + HHGear^.Y := HHGear^.Y + HHGear^.dY; + HHGear^.dY := HHGear^.dY + cGravity; + + if (GameFlags and gfMoreWind) <> 0 then + HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density; + + if (Gear^.Message and gmAttack) <> 0 then + begin + Gear^.X := HHGear^.X; + Gear^.Y := HHGear^.Y; + + ApplyAngleBounds(Gear^.Hedgehog^, amRope); + + Gear^.dX := SignAs(AngleSin(HHGear^.Angle), HHGear^.dX); + Gear^.dY := -AngleCos(HHGear^.Angle); + Gear^.Friction := _4_5 * cRopePercent; + Gear^.Elasticity := _0; + Gear^.State := Gear^.State and (not gsttmpflag); + Gear^.doStep := @doStepRope; + end +end; + +procedure unstickHog(Gear, HHGear: PGear); +var i: LongInt; + stuck: Boolean; +begin + if (TestCollisionYwithGear(HHGear, 1) <> 0) and (TestCollisionYwithGear(HHGear, -1) = 0) then + begin + i:= 1; + repeat + begin + inc(i); + stuck:= TestCollisionYwithGear(HHGear, 1) <> 0; + if stuck then HHGear^.Y:= HHGear^.Y-_1 + end + until (i = 8) or (not stuck); + HHGear^.Y:= HHGear^.Y+_1; + // experiment in simulating something the shoppa players apparently expect + if Gear^.Message and gmDown <> 0 then + begin + //HHGear^.dY:= HHGear^.dY / 16; + //HHGear^.dY.QWordValue:= 0; + HHGear^.dY:= -_0_1; + HHGear^.dX:= HHGear^.dX * _1_5; + end; + if Gear^.Message and gmRight <> 0 then + HHGear^.dX.isNegative:= false + else if Gear^.Message and gmLeft <> 0 then + HHGear^.dX.isNegative:= true + end + else if (TestCollisionYwithGear(HHGear, -1) <> 0) and (TestCollisionYwithGear(HHGear, 1) = 0) then + begin + i:= 1; + repeat + begin + inc(i); + stuck:= TestCollisionYwithGear(HHGear, -1) <> 0; + if stuck then HHGear^.Y:= HHGear^.Y+_1 + end + until (i = 8) or (not stuck); + HHGear^.Y:= HHGear^.Y-_1; + if Gear^.Message and gmDown <> 0 then + begin + //HHGear^.dY:= HHGear^.dY / 16; + //HHGear^.dY.QWordValue:= 0; + HHGear^.dY:= _0_1; + HHGear^.dX:= HHGear^.dX * _1_5; + end; + if Gear^.Message and gmRight <> 0 then + HHGear^.dX.isNegative:= true + else if Gear^.Message and gmLeft <> 0 then + HHGear^.dX.isNegative:= false + end; + if TestCollisionXwithGear(HHGear, 1) and (not TestCollisionXwithGear(HHGear, -1)) then + begin + i:= 1; + repeat + begin + inc(i); + stuck:= TestCollisionXwithGear(HHGear, 1); + if stuck then HHGear^.X:= HHGear^.X-_1 + end + until (i = 8) or (not stuck); + HHGear^.X:= HHGear^.X+_1; + if Gear^.Message and gmDown <> 0 then + begin + //HHGear^.dX:= HHGear^.dX / 16; + //HHGear^.dX.QWordValue:= 0; + HHGear^.dX:= -_0_1; + HHGear^.dY:= HHGear^.dY * _1_5; + end; + if Gear^.Message and gmRight <> 0 then + HHGear^.dY.isNegative:= true + else if Gear^.Message and gmLeft <> 0 then + HHGear^.dY.isNegative:= false + end + else if TestCollisionXwithGear(HHGear, -1) and (not TestCollisionXwithGear(HHGear, 1)) then + begin + i:= 1; + repeat + begin + inc(i); + stuck:= TestCollisionXwithGear(HHGear, -1); + if stuck then HHGear^.X:= HHGear^.X+_1 + end + until (i = 8) or (not stuck); + HHGear^.X:= HHGear^.X-_1; + if Gear^.Message and gmDown <> 0 then + begin + //HHGear^.dX:= HHGear^.dX / 16; + //HHGear^.dX.QWordValue:= 0; + HHGear^.dX:= _0_1; + HHGear^.dY:= HHGear^.dY * _1_5; + end; + if Gear^.Message and gmRight <> 0 then + HHGear^.dY.isNegative:= false + else if Gear^.Message and gmLeft <> 0 then + HHGear^.dY.isNegative:= true + end +end; + +procedure RopeDeleteMe(Gear, HHGear: PGear); +begin + PlaySound(sndRopeRelease); + HHGear^.dX.QWordValue:= HHGear^.dX.QWordValue div Gear^.stepFreq; + HHGear^.dY.QWordValue:= HHGear^.dY.QWordValue div Gear^.stepFreq; + with HHGear^ do + begin + Message := Message and (not gmAttack); + State := (State or gstMoving) and (not gstWinner); + end; + unstickHog(Gear, HHGear); + DeleteGear(Gear) +end; + +procedure RopeWaitCollision(Gear, HHGear: PGear); +begin + PlaySound(sndRopeRelease); + with HHGear^ do + begin + Message := Message and (not gmAttack); + State := State or gstMoving; + end; + unstickHog(Gear, HHGear); + RopePoints.Count := 0; + Gear^.Elasticity := _0; + Gear^.doStep := @doStepRopeAfterAttack; + HHGear^.dX.QWordValue:= HHGear^.dX.QWordValue div Gear^.stepFreq; + HHGear^.dY.QWordValue:= HHGear^.dY.QWordValue div Gear^.stepFreq; + Gear^.stepFreq := 1 +end; + +procedure doStepRopeWork(Gear: PGear); +var + HHGear: PGear; + len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY, t: hwFloat; + lx, ly, cd, i: LongInt; + haveCollision, + haveDivided: boolean; + +begin + if GameTicks mod 8 <> 0 then exit; + + HHGear := Gear^.Hedgehog^.Gear; + haveCollision:= false; + if (Gear^.Message and gmLeft <> 0) and (not TestCollisionXwithGear(HHGear, -1)) then + HHGear^.dX := HHGear^.dX - _0_0128 + else haveCollision:= true; + + if (Gear^.Message and gmRight <> 0) and (not TestCollisionXwithGear(HHGear, 1)) then + HHGear^.dX := HHGear^.dX + _0_0128 + else haveCollision:= true; + + + if ((HHGear^.State and gstHHDriven) = 0) + or (CheckGearDrowning(HHGear)) or (Gear^.PortalCounter <> 0) then + begin + RopeDeleteMe(Gear, HHGear); + exit + end; + + // vector between hedgehog and rope attaching point + ropeDx := HHGear^.X - Gear^.X; + ropeDy := HHGear^.Y - Gear^.Y; + + if TestCollisionYwithGear(HHGear, 1) = 0 then + begin + + // depending on the rope vector we know which X-side to check for collision + // in order to find out if the hog can still be moved by gravity + if ropeDx.isNegative = RopeDy.IsNegative then + cd:= -1 + else + cd:= 1; + + // apply gravity if there is no obstacle + if not TestCollisionXwithGear(HHGear, cd) then + HHGear^.dY := HHGear^.dY + cGravity * 64; + + if (GameFlags and gfMoreWind) <> 0 then + // apply wind if there's no obstacle + if not TestCollisionXwithGear(HHGear, hwSign(cWindSpeed)) then + HHGear^.dX := HHGear^.dX + cWindSpeed * 64 / HHGear^.Density; + end + else haveCollision:= true; + + if ((Gear^.Message and gmDown) <> 0) and (Gear^.Elasticity < Gear^.Friction) then + if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx)) + or (TestCollisionYwithGear(HHGear, hwSign(ropeDy)) <> 0)) then + Gear^.Elasticity := Gear^.Elasticity + _2_4 + else haveCollision:= true; + + if ((Gear^.Message and gmUp) <> 0) and (Gear^.Elasticity > _30) then + if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx)) + or (TestCollisionYwithGear(HHGear, -hwSign(ropeDy)) <> 0)) then + Gear^.Elasticity := Gear^.Elasticity - _2_4 + else haveCollision:= true; + +(* +I am not so sure this is useful. Disabling + if haveCollision then + begin + if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) and not TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then + HHGear^.dX.isNegative:= not HHGear^.dX.isNegative; + if (TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) <> 0) and (TestCollisionYwithGear(HHGear, -hwSign(HHGear^.dY)) = 0) then + HHGear^.dY.isNegative:= not HHGear^.dY.isNegative; + end; +*) + + mdX := ropeDx + HHGear^.dX; + mdY := ropeDy + HHGear^.dY; + len := _1 / Distance(mdX, mdY); + // rope vector plus hedgehog direction vector normalized + mdX := mdX * len; + mdY := mdY * len; + + // for visual purposes only + Gear^.dX := mdX; + Gear^.dY := mdY; + + ///// + tx := HHGear^.X; + ty := HHGear^.Y; + + HHGear^.X := Gear^.X + mdX * Gear^.Elasticity; + HHGear^.Y := Gear^.Y + mdY * Gear^.Elasticity; + + HHGear^.dX := HHGear^.X - tx; + HHGear^.dY := HHGear^.Y - ty; + //// + + + haveDivided := false; + // check whether rope needs dividing + + len := Gear^.Elasticity - _5; + nx := Gear^.X + mdX * len; + ny := Gear^.Y + mdY * len; + tx := mdX * _2_4; // should be the same as increase step + ty := mdY * _2_4; + + while len > _3 do + begin + lx := hwRound(nx); + ly := hwRound(ny); + if ((ly and LAND_HEIGHT_MASK) = 0) and ((lx and LAND_WIDTH_MASK) = 0) and ((Land[ly, lx] and $FF00) <> 0) then + begin + ny := _1 / Distance(ropeDx, ropeDy); + // old rope pos + nx := ropeDx * ny; + ny := ropeDy * ny; + + with RopePoints.ar[RopePoints.Count] do + begin + X := Gear^.X; + Y := Gear^.Y; + if RopePoints.Count = 0 then + RopePoints.HookAngle := DxDy2Angle(Gear^.dY, Gear^.dX); + b := (nx * HHGear^.dY) > (ny * HHGear^.dX); + dLen := len + end; + + with RopePoints.rounded[RopePoints.Count] do + begin + X := hwRound(Gear^.X); + Y := hwRound(Gear^.Y); + end; + + Gear^.X := Gear^.X + nx * len; + Gear^.Y := Gear^.Y + ny * len; + inc(RopePoints.Count); + TryDo(RopePoints.Count <= MAXROPEPOINTS, 'Rope points overflow', true); + Gear^.Elasticity := Gear^.Elasticity - len; + Gear^.Friction := Gear^.Friction - len; + haveDivided := true; + break + end; + nx := nx - tx; + ny := ny - ty; + + // len := len - _2_4 // should be the same as increase step + len.QWordValue := len.QWordValue - _2_4.QWordValue; + end; + + if not haveDivided then + if RopePoints.Count > 0 then // check whether the last dividing point could be removed + begin + tx := RopePoints.ar[Pred(RopePoints.Count)].X; + ty := RopePoints.ar[Pred(RopePoints.Count)].Y; + mdX := tx - Gear^.X; + mdY := ty - Gear^.Y; + if RopePoints.ar[Pred(RopePoints.Count)].b xor (mdX * (ty - HHGear^.Y) > (tx - HHGear^.X) * mdY) then + begin + dec(RopePoints.Count); + Gear^.X := RopePoints.ar[RopePoints.Count].X; + Gear^.Y := RopePoints.ar[RopePoints.Count].Y; + Gear^.Elasticity := Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen; + Gear^.Friction := Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen; + + // restore hog position + len := _1 / Distance(mdX, mdY); + mdX := mdX * len; + mdY := mdY * len; + + HHGear^.X := Gear^.X - mdX * Gear^.Elasticity; + HHGear^.Y := Gear^.Y - mdY * Gear^.Elasticity; + end + end; + + haveCollision := false; + if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then + begin + HHGear^.dX := -_0_6 * HHGear^.dX; + haveCollision := true + end; + if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) <> 0 then + begin + HHGear^.dY := -_0_6 * HHGear^.dY; + haveCollision := true + end; + + if haveCollision and (Gear^.Message and (gmLeft or gmRight) <> 0) and (Gear^.Message and (gmUp or gmDown) <> 0) then + begin + HHGear^.dX := SignAs(hwAbs(HHGear^.dX) + _1_6, HHGear^.dX); + HHGear^.dY := SignAs(hwAbs(HHGear^.dY) + _1_6, HHGear^.dY) + end; + + len := hwSqr(HHGear^.dX) + hwSqr(HHGear^.dY); + if len > _49 then + begin + len := _7 / hwSqrt(len); + HHGear^.dX := HHGear^.dX * len; + HHGear^.dY := HHGear^.dY * len; + end; + + haveCollision:= ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) and ((Land[hwRound(Gear^.Y), hwRound(Gear^.X)]) <> 0); + + if not haveCollision then + begin + // backup gear location + tx:= Gear^.X; + ty:= Gear^.Y; + + if RopePoints.Count > 0 then + begin + // set gear location to the remote end of the rope, the attachment point + Gear^.X:= RopePoints.ar[0].X; + Gear^.Y:= RopePoints.ar[0].Y; + end; + + CheckCollision(Gear); + // if we haven't found any collision yet then check the other side too + if (Gear^.State and gstCollision) = 0 then + begin + Gear^.dX.isNegative:= not Gear^.dX.isNegative; + Gear^.dY.isNegative:= not Gear^.dY.isNegative; + CheckCollision(Gear); + Gear^.dX.isNegative:= not Gear^.dX.isNegative; + Gear^.dY.isNegative:= not Gear^.dY.isNegative; + end; + + haveCollision:= (Gear^.State and gstCollision) <> 0; + + // restore gear location + Gear^.X:= tx; + Gear^.Y:= ty; + end; + + // if the attack key is pressed, lose rope contact as well + if (Gear^.Message and gmAttack) <> 0 then + haveCollision:= false; + + if not haveCollision then + begin + if (Gear^.State and gsttmpFlag) <> 0 then + begin + if Gear^.Hedgehog^.CurAmmoType <> amParachute then + RopeWaitCollision(Gear, HHGear) + else + RopeDeleteMe(Gear, HHGear) + end + end + else + if (Gear^.State and gsttmpFlag) = 0 then + Gear^.State := Gear^.State or gsttmpFlag; +end; + +procedure RopeRemoveFromAmmo(Gear, HHGear: PGear); +begin + if (Gear^.State and gstAttacked) = 0 then + begin + OnUsedAmmo(HHGear^.Hedgehog^); + Gear^.State := Gear^.State or gstAttacked + end; + ApplyAmmoChanges(HHGear^.Hedgehog^) +end; + +procedure doStepRopeAttach(Gear: PGear); +var + HHGear: PGear; + tx, ty, tt: hwFloat; +begin + Gear^.X := Gear^.X - Gear^.dX; + Gear^.Y := Gear^.Y - Gear^.dY; + Gear^.Elasticity := Gear^.Elasticity + _1; + + HHGear := Gear^.Hedgehog^.Gear; + DeleteCI(HHGear); + + if (HHGear^.State and gstMoving) <> 0 then + begin + if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then + SetLittle(HHGear^.dX); + if HHGear^.dY.isNegative and (TestCollisionYwithGear(HHGear, -1) <> 0) then + HHGear^.dY := _0; + + HHGear^.X := HHGear^.X + HHGear^.dX; + Gear^.X := Gear^.X + HHGear^.dX; + + if TestCollisionYwithGear(HHGear, 1) <> 0 then + begin + CheckHHDamage(HHGear); + HHGear^.dY := _0 + //HHGear^.State:= HHGear^.State and (not (gstHHJumping or gstHHHJump)); + end + else + begin + HHGear^.Y := HHGear^.Y + HHGear^.dY; + Gear^.Y := Gear^.Y + HHGear^.dY; + HHGear^.dY := HHGear^.dY + cGravity; + if (GameFlags and gfMoreWind) <> 0 then + HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density + end; + + tt := Gear^.Elasticity; + tx := _0; + ty := _0; + while tt > _20 do + begin + if ((hwRound(Gear^.Y+ty) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X+tx) and LAND_WIDTH_MASK) = 0) and ((Land[hwRound(Gear^.Y+ty), hwRound(Gear^.X+tx)] and $FF00) <> 0) then + begin + Gear^.X := Gear^.X + tx; + Gear^.Y := Gear^.Y + ty; + Gear^.Elasticity := tt; + Gear^.doStep := @doStepRopeWork; + Gear^.stepFreq:= 8; + PlaySound(sndRopeAttach); + with HHGear^ do + begin + dX.QWordValue:= dX.QWordValue shl 3; + dY.QWordValue:= dY.QWordValue shl 3; + State := State and (not (gstAttacking or gstHHJumping or gstHHHJump)); + Message := Message and (not gmAttack) + end; + + RopeRemoveFromAmmo(Gear, HHGear); + + tt := _0; + exit + end; + tx := tx + Gear^.dX + Gear^.dX; + ty := ty + Gear^.dY + Gear^.dY; + tt := tt - _2; + end; + end; + + if Gear^.Elasticity < _20 then Gear^.CollisionMask:= $FF00 + else Gear^.CollisionMask:= $FF7F; + CheckCollision(Gear); + + if (Gear^.State and gstCollision) <> 0 then + if Gear^.Elasticity < _10 then + Gear^.Elasticity := _10000 + else + begin + Gear^.doStep := @doStepRopeWork; + Gear^.stepFreq:= 8; + PlaySound(sndRopeAttach); + with HHGear^ do + begin + dX.QWordValue:= dX.QWordValue shl 3; + dY.QWordValue:= dY.QWordValue shl 3; + State := State and (not (gstAttacking or gstHHJumping or gstHHHJump)); + Message := Message and (not gmAttack) + end; + + RopeRemoveFromAmmo(Gear, HHGear); + + exit + end; + + if (Gear^.Elasticity > Gear^.Friction) + or ((Gear^.Message and gmAttack) = 0) + or ((HHGear^.State and gstHHDriven) = 0) + or (HHGear^.Damage > 0) then + begin + with Gear^.Hedgehog^.Gear^ do + begin + State := State and (not gstAttacking); + Message := Message and (not gmAttack) + end; + DeleteGear(Gear); + exit; + end; + if CheckGearDrowning(HHGear) then DeleteGear(Gear) +end; + +procedure doStepRope(Gear: PGear); +begin + Gear^.dX := - Gear^.dX; + Gear^.dY := - Gear^.dY; + Gear^.doStep := @doStepRopeAttach; + PlaySound(sndRopeShot) +end; + +end. diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/uGearsHedgehog.pas --- a/hedgewars/uGearsHedgehog.pas Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/uGearsHedgehog.pas Mon Aug 27 17:40:16 2012 +0200 @@ -234,9 +234,9 @@ and ((Gear^.Message and gmLJump) <> 0) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then begin - newDx:= dX / _2; - newDy:= dY / _2; - altUse:= true; + newDx:= dX / CurAmmoGear^.stepFreq; + newDy:= dY / CurAmmoGear^.stepFreq; + altUse:= true end else begin @@ -260,10 +260,7 @@ amPickHammer: newGear:= AddGear(hwRound(lx), hwRound(ly) + cHHRadius, gtPickHammer, 0, _0, _0, 0); amSkip: ParseCommand('/skip', true); amRope: newGear:= AddGear(hwRound(lx), hwRound(ly), gtRope, 0, xx, yy, 0); - amMine: if altUse then - newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, newDx, newDy, 3000) - else - newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, SignAs(_0_02, dX), _0, 3000); + amMine: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, SignAs(_0_02, dX), _0, 3000); amSMine: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSMine, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); amDEagle: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtDEagleShot, 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); @@ -360,6 +357,11 @@ amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000); amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0); end; + if altUse then + begin + newGear^.dX:= newDx / newGear^.Density; + newGear^.dY:= newDY / newGear^.Density + end; case CurAmmoType of amGrenade, amMolotov, @@ -572,7 +574,6 @@ var s: shortstring; vga: PVisualGear; begin - PlaySound(sndShotgunReload); if cnt <> 0 then AddAmmo(HH, ammo, cnt) else AddAmmo(HH, ammo); @@ -614,6 +615,7 @@ case Gear^.Pos of posCaseUtility, posCaseAmmo: begin + PlaySound(sndShotgunReload); if Gear^.AmmoType <> amNothing then begin AddPickup(HH^.Hedgehog^, Gear^.AmmoType, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y)); @@ -636,7 +638,7 @@ end; gi := gi^.NextGear end; - ag:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAddAmmo, gstInvisible, _0, _0, GetRandom(200)+100); + ag:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAddAmmo, gstInvisible, _0, _0, GetRandom(125)+25); ag^.Pos:= Gear^.Pos; ag^.Power:= Gear^.Power end; diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/uGearsList.pas --- a/hedgewars/uGearsList.pas Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/uGearsList.pas Mon Aug 27 17:40:16 2012 +0200 @@ -105,6 +105,7 @@ // Define ammo association, if any. gear^.AmmoType:= GearKindAmmoTypeMap[Kind]; gear^.CollisionMask:= $FFFF; +gear^.stepFreq:= 1; if CurrentHedgehog <> nil then gear^.Hedgehog:= CurrentHedgehog; @@ -230,7 +231,7 @@ gear^.Radius:= 2; gear^.Elasticity:= _0_55; gear^.Friction:= _0_995; - gear^.Density:= _0_9; + gear^.Density:= _1; if cMinesTime < 0 then gear^.Timer:= getrandom(51)*100 else @@ -242,7 +243,7 @@ gear^.Radius:= 2; gear^.Elasticity:= _0_55; gear^.Friction:= _0_995; - gear^.Density:= _0_9; + gear^.Density:= _1_6; gear^.Timer:= 500; end; gtCase: begin diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/uGearsUtils.pas --- a/hedgewars/uGearsUtils.pas Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/uGearsUtils.pas Mon Aug 27 17:40:16 2012 +0200 @@ -38,6 +38,8 @@ function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear; function CheckGearDrowning(Gear: PGear): boolean; +procedure CheckCollision(Gear: PGear); inline; +procedure CheckCollisionWithLand(Gear: PGear); inline; var doStepHandlers: array[TGearType] of TGearStepProcedure; @@ -603,7 +605,7 @@ inc(cnt) end; - inc(y, 45) + inc(y, 10) end; if cnt > 0 then @@ -663,4 +665,22 @@ CheckGearNear:= nil end; +procedure CheckCollision(Gear: PGear); inline; +begin + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) + or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0) then + Gear^.State := Gear^.State or gstCollision + else + Gear^.State := Gear^.State and (not gstCollision) +end; + +procedure CheckCollisionWithLand(Gear: PGear); inline; +begin + if TestCollisionX(Gear, hwSign(Gear^.dX)) + or TestCollisionY(Gear, hwSign(Gear^.dY)) then + Gear^.State := Gear^.State or gstCollision + else + Gear^.State := Gear^.State and (not gstCollision) +end; + end. diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/uLand.pas --- a/hedgewars/uLand.pas Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/uLand.pas Mon Aug 27 17:40:16 2012 +0200 @@ -286,6 +286,11 @@ 3: SelectTemplate:= LargeTemplates[getrandom(Succ(High(LargeTemplates)))]; 4: SelectTemplate:= CavernTemplates[getrandom(Succ(High(CavernTemplates)))]; 5: SelectTemplate:= WackyTemplates[getrandom(Succ(High(WackyTemplates)))]; +// For lua only! + 6: begin + SelectTemplate:= min(LuaTemplateNumber,High(EdgeTemplates)); + GetRandom(2) // burn 1 + end; end; WriteLnToConsole('Selected template #'+inttostr(SelectTemplate)+' using filter #'+inttostr(cTemplateFilter)); @@ -610,7 +615,7 @@ if Land[y, x] <> 0 then begin inc(c); - if c > 200 then // avoid accidental triggering + if c > 1000 then // avoid accidental triggering begin hasBorder:= true; break; diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/uLandPainted.pas --- a/hedgewars/uLandPainted.pas Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/uLandPainted.pas Mon Aug 27 17:40:16 2012 +0200 @@ -58,9 +58,9 @@ rec.X:= SDLNet_Read16(@rec.X); rec.Y:= SDLNet_Read16(@rec.Y); if rec.X < -318 then rec.X:= -318; - if rec.X > LAND_WIDTH+318 then rec.X:= LAND_WIDTH+318; + if rec.X > 4096+318 then rec.X:= 4096+318; if rec.Y < -318 then rec.Y:= -318; - if rec.Y > LAND_HEIGHT+318 then rec.Y:= LAND_HEIGHT+318; + if rec.Y > 2048+318 then rec.Y:= 2048+318; new(pe); if pointsListLast = nil then diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/uLandTemplates.pas --- a/hedgewars/uLandTemplates.pas Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/uLandTemplates.pas Mon Aug 27 17:40:16 2012 +0200 @@ -1459,92 +1459,92 @@ // Many islands const Template41Points: array[0..86] of TSDL_Rect = ( - (x: 95; y: 500; w: 1; h: 1), - (x: 100; y: 275; w: 25; h: 100), - (x: 325; y: 275; w: 25; h: 100), - (x: 330; y: 500; w: 1; h: 1), + (x: 95; y: 500; w: 26; h: 26), + (x: 100; y: 275; w: 50; h: 125), + (x: 325; y: 275; w: 50; h: 125), + (x: 330; y: 500; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 725; y: 125; w: 1; h: 1), - (x: 725; y: 25; w: 5; h: 25), - (x: 825; y: 35; w: 5; h: 10), - (x: 825; y: 135; w: 1; h: 1), + (x: 725; y: 125; w: 26; h: 26), + (x: 725; y: 25; w: 30; h: 50), + (x: 825; y: 35; w: 30; h: 35), + (x: 825; y: 135; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 1150; y: 550; w: 25; h: 50), - (x: 1250; y: 300; w: 25; h: 50), - (x: 1350; y: 300; w: 25; h: 50), - (x: 1400; y: 575; w: 25; h: 50), + (x: 1150; y: 550; w: 50; h: 75), + (x: 1250; y: 300; w: 50; h: 75), + (x: 1350; y: 300; w: 50; h: 75), + (x: 1400; y: 575; w: 50; h: 75), (x: NTPX; y: 0; w: 1; h: 1), - (x: 525; y:1050; w: 50; h: 50), - (x: 700; y: 800; w: 100; h: 150), - (x: 950; y: 900; w: 100; h: 150), - (x: 1100; y:1100; w: 50; h: 50), + (x: 525; y:1050; w: 75; h: 75), + (x: 700; y: 800; w: 125; h: 175), + (x: 950; y: 900; w: 125; h: 175), + (x: 1100; y:1100; w: 75; h: 75), (x: NTPX; y: 0; w: 1; h: 1), - (x: 175; y:1500; w: 1; h: 1), - (x: 210; y:1400; w: 5; h: 25), - (x: 240; y:1400; w: 5; h: 25), - (x: 275; y:1510; w: 1; h: 1), + (x: 175; y:1500; w: 26; h: 26), + (x: 210; y:1400; w: 30; h: 50), + (x: 240; y:1400; w: 30; h: 50), + (x: 275; y:1510; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 450; y:1800; w: 100; h: 100), - (x: 600; y:1750; w: 100; h: 100), - (x: 750; y:1750; w: 100; h: 100), - (x: 950; y:1850; w: 100; h: 100), + (x: 450; y:1800; w: 125; h: 125), + (x: 600; y:1750; w: 125; h: 125), + (x: 750; y:1750; w: 125; h: 125), + (x: 950; y:1850; w: 125; h: 125), (x: NTPX; y: 0; w: 1; h: 1), - (x: 1075; y:1450; w: 1; h: 1), - (x: 1110; y:1300; w: 5; h: 25), - (x: 1140; y:1300; w: 5; h: 25), - (x: 1175; y:1430; w: 1; h: 1), + (x: 1075; y:1450; w: 26; h: 26), + (x: 1110; y:1300; w: 30; h: 50), + (x: 1140; y:1300; w: 30; h: 50), + (x: 1175; y:1430; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 1600; y:1250; w: 25; h: 100), - (x: 1700; y:1150; w: 25; h: 100), - (x: 1850; y: 500; w: 50; h: 100), - (x: 1950; y: 550; w: 50; h: 150), - (x: 2250; y:1150; w: 25; h: 100), - (x: 2350; y:1250; w: 25; h: 100), + (x: 1600; y:1250; w: 50; h: 125), + (x: 1700; y:1150; w: 50; h: 125), + (x: 1850; y: 500; w: 75; h: 125), + (x: 1950; y: 550; w: 75; h: 175), + (x: 2250; y:1150; w: 50; h: 125), + (x: 2350; y:1250; w: 50; h: 125), (x: NTPX; y: 0; w: 1; h: 1), - (x: 1750; y:2010; w: 1; h: 1), - (x: 1900; y:1870; w: 50; h: 50), - (x: 2050; y:1870; w: 50; h: 50), - (x: 2175; y:2010; w: 1; h: 1), + (x: 1750; y:2010; w: 26; h: 26), + (x: 1900; y:1870; w: 75; h: 75), + (x: 2050; y:1870; w: 75; h: 75), + (x: 2175; y:2010; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 2500; y:1700; w: 1; h: 1), - (x: 2575; y:1500; w: 10; h: 50), - (x: 2650; y:1500; w: 10; h: 50), - (x: 2700; y:1690; w: 1; h: 1), + (x: 2500; y:1700; w: 26; h: 26), + (x: 2575; y:1500; w: 35; h: 75), + (x: 2650; y:1500; w: 35; h: 75), + (x: 2700; y:1690; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 2000; y: 125; w: 1; h: 1), - (x: 2050; y: 50; w: 25; h: 25), - (x: 2100; y: 50; w: 25; h: 25), - (x: 2150; y: 150; w: 1; h: 1), + (x: 2000; y: 125; w: 26; h: 26), + (x: 2050; y: 50; w: 50; h: 50), + (x: 2100; y: 50; w: 50; h: 50), + (x: 2150; y: 150; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 2600; y: 250; w: 25; h: 100), - (x: 2750; y: 400; w: 50; h: 50), - (x: 2900; y: 525; w: 50; h: 50), - (x: 3150; y: 550; w: 50; h: 100), + (x: 2600; y: 250; w: 50; h: 125), + (x: 2750; y: 400; w: 75; h: 75), + (x: 2900; y: 525; w: 75; h: 75), + (x: 3150; y: 550; w: 75; h: 125), (x: NTPX; y: 0; w: 1; h: 1), - (x: 2800; y:1150; w: 1; h: 1), - (x: 2840; y: 950; w: 25; h: 25), - (x: 2880; y: 950; w: 25; h: 25), - (x: 2900; y:1150; w: 1; h: 1), + (x: 2800; y:1150; w: 26; h: 26), + (x: 2840; y: 950; w: 50; h: 50), + (x: 2880; y: 950; w: 50; h: 50), + (x: 2900; y:1150; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 3075; y:1985; w: 1; h: 1), - (x: 3325; y:1700; w: 50; h: 100), - (x: 3475; y:1700; w: 50; h: 100), - (x: 3625; y:1985; w: 1; h: 1), + (x: 3075; y:1985; w: 26; h: 26), + (x: 3325; y:1700; w: 75; h: 125), + (x: 3475; y:1700; w: 75; h: 125), + (x: 3625; y:1985; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 3200; y:1450; w: 1; h: 1), - (x: 3240; y:1350; w: 25; h: 25), - (x: 3280; y:1350; w: 25; h: 25), - (x: 3300; y:1450; w: 1; h: 1), + (x: 3200; y:1450; w: 26; h: 26), + (x: 3240; y:1350; w: 50; h: 50), + (x: 3280; y:1350; w: 50; h: 50), + (x: 3300; y:1450; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 3500; y:1050; w: 25; h: 50), - (x: 3650; y: 600; w: 50; h: 100), - (x: 3800; y: 600; w: 50; h: 100), - (x: 3900; y:1000; w: 25; h: 50), + (x: 3500; y:1050; w: 50; h: 75), + (x: 3650; y: 600; w: 75; h: 125), + (x: 3800; y: 600; w: 75; h: 125), + (x: 3900; y:1000; w: 50; h: 75), (x: NTPX; y: 0; w: 1; h: 1), - (x: 3800; y: 200; w: 25; h: 50), - (x: 3875; y: 100; w: 50; h: 50), - (x: 3925; y: 50; w: 50; h: 25), - (x: 4050; y: 125; w: 25; h: 50), + (x: 3800; y: 200; w: 50; h: 75), + (x: 3875; y: 100; w: 75; h: 75), + (x: 3925; y: 50; w: 75; h: 50), + (x: 4050; y: 125; w: 50; h: 75), (x: NTPX; y: 0; w: 1; h: 1) ); Template41FPoints: array[0..0] of TPoint = @@ -1576,179 +1576,179 @@ // Many islands const Template43Points: array[0..173] of TSDL_Rect = ( - (x: 95; y: 500; w: 1; h: 1), - (x: 100; y: 275; w: 25; h: 100), - (x: 325; y: 275; w: 25; h: 100), - (x: 330; y: 500; w: 1; h: 1), + (x: 95; y: 500; w: 26; h: 26), + (x: 100; y: 275; w: 50; h: 125), + (x: 325; y: 275; w: 50; h: 125), + (x: 330; y: 500; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 725; y: 125; w: 1; h: 1), - (x: 725; y: 25; w: 5; h: 25), - (x: 825; y: 35; w: 5; h: 10), - (x: 825; y: 135; w: 1; h: 1), + (x: 725; y: 125; w: 26; h: 26), + (x: 725; y: 25; w: 30; h: 50), + (x: 825; y: 35; w: 30; h: 35), + (x: 825; y: 135; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 1150; y: 550; w: 25; h: 50), - (x: 1250; y: 300; w: 25; h: 50), - (x: 1350; y: 300; w: 25; h: 50), - (x: 1400; y: 575; w: 25; h: 50), + (x: 1150; y: 550; w: 50; h: 75), + (x: 1250; y: 300; w: 50; h: 75), + (x: 1350; y: 300; w: 50; h: 75), + (x: 1400; y: 575; w: 50; h: 75), (x: NTPX; y: 0; w: 1; h: 1), - (x: 525; y:1050; w: 50; h: 50), - (x: 700; y: 800; w: 100; h: 150), - (x: 950; y: 900; w: 100; h: 150), - (x: 1100; y:1100; w: 50; h: 50), + (x: 525; y:1050; w: 75; h: 75), + (x: 700; y: 800; w: 125; h: 175), + (x: 950; y: 900; w: 125; h: 175), + (x: 1100; y:1100; w: 75; h: 75), (x: NTPX; y: 0; w: 1; h: 1), - (x: 175; y:1500; w: 1; h: 1), - (x: 210; y:1400; w: 5; h: 25), - (x: 240; y:1400; w: 5; h: 25), - (x: 275; y:1510; w: 1; h: 1), + (x: 175; y:1500; w: 26; h: 26), + (x: 210; y:1400; w: 30; h: 50), + (x: 240; y:1400; w: 30; h: 50), + (x: 275; y:1510; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 450; y:1800; w: 100; h: 100), - (x: 600; y:1750; w: 100; h: 100), - (x: 750; y:1750; w: 100; h: 100), - (x: 950; y:1850; w: 100; h: 100), + (x: 450; y:1800; w: 125; h: 125), + (x: 600; y:1750; w: 125; h: 125), + (x: 750; y:1750; w: 125; h: 125), + (x: 950; y:1850; w: 125; h: 125), (x: NTPX; y: 0; w: 1; h: 1), - (x: 1075; y:1450; w: 1; h: 1), - (x: 1110; y:1300; w: 5; h: 25), - (x: 1140; y:1300; w: 5; h: 25), - (x: 1175; y:1430; w: 1; h: 1), + (x: 1075; y:1450; w: 26; h: 26), + (x: 1110; y:1300; w: 30; h: 50), + (x: 1140; y:1300; w: 30; h: 50), + (x: 1175; y:1430; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 1600; y:1250; w: 25; h: 100), - (x: 1700; y:1150; w: 25; h: 100), - (x: 1850; y: 500; w: 50; h: 100), - (x: 1950; y: 550; w: 50; h: 150), - (x: 2250; y:1150; w: 25; h: 100), - (x: 2350; y:1250; w: 25; h: 100), + (x: 1600; y:1250; w: 50; h: 125), + (x: 1700; y:1150; w: 50; h: 125), + (x: 1850; y: 500; w: 75; h: 125), + (x: 1950; y: 550; w: 75; h: 175), + (x: 2250; y:1150; w: 50; h: 125), + (x: 2350; y:1250; w: 50; h: 125), (x: NTPX; y: 0; w: 1; h: 1), - (x: 1750; y:2010; w: 1; h: 1), - (x: 1900; y:1870; w: 50; h: 50), - (x: 2050; y:1870; w: 50; h: 50), - (x: 2175; y:2010; w: 1; h: 1), + (x: 1750; y:2010; w: 26; h: 26), + (x: 1900; y:1870; w: 75; h: 75), + (x: 2050; y:1870; w: 75; h: 75), + (x: 2175; y:2010; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 2500; y:1700; w: 1; h: 1), - (x: 2575; y:1500; w: 10; h: 50), - (x: 2650; y:1500; w: 10; h: 50), - (x: 2700; y:1690; w: 1; h: 1), + (x: 2500; y:1700; w: 26; h: 26), + (x: 2575; y:1500; w: 35; h: 75), + (x: 2650; y:1500; w: 35; h: 75), + (x: 2700; y:1690; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 2000; y: 125; w: 1; h: 1), - (x: 2050; y: 50; w: 25; h: 25), - (x: 2100; y: 50; w: 25; h: 25), - (x: 2150; y: 150; w: 1; h: 1), + (x: 2000; y: 125; w: 26; h: 26), + (x: 2050; y: 50; w: 50; h: 50), + (x: 2100; y: 50; w: 50; h: 50), + (x: 2150; y: 150; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 2600; y: 250; w: 25; h: 100), - (x: 2750; y: 400; w: 50; h: 50), - (x: 2900; y: 525; w: 50; h: 50), - (x: 3150; y: 550; w: 50; h: 100), + (x: 2600; y: 250; w: 50; h: 125), + (x: 2750; y: 400; w: 75; h: 75), + (x: 2900; y: 525; w: 75; h: 75), + (x: 3150; y: 550; w: 75; h: 125), (x: NTPX; y: 0; w: 1; h: 1), - (x: 2800; y:1150; w: 1; h: 1), - (x: 2840; y: 950; w: 25; h: 25), - (x: 2880; y: 950; w: 25; h: 25), - (x: 2900; y:1150; w: 1; h: 1), + (x: 2800; y:1150; w: 26; h: 26), + (x: 2840; y: 950; w: 50; h: 50), + (x: 2880; y: 950; w: 50; h: 50), + (x: 2900; y:1150; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 3075; y:1985; w: 1; h: 1), - (x: 3325; y:1700; w: 50; h: 100), - (x: 3475; y:1700; w: 50; h: 100), - (x: 3625; y:1985; w: 1; h: 1), + (x: 3075; y:1985; w: 26; h: 26), + (x: 3325; y:1700; w: 75; h: 125), + (x: 3475; y:1700; w: 75; h: 125), + (x: 3625; y:1985; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 3200; y:1450; w: 1; h: 1), - (x: 3240; y:1350; w: 25; h: 25), - (x: 3280; y:1350; w: 25; h: 25), - (x: 3300; y:1450; w: 1; h: 1), + (x: 3200; y:1450; w: 26; h: 26), + (x: 3240; y:1350; w: 50; h: 50), + (x: 3280; y:1350; w: 50; h: 50), + (x: 3300; y:1450; w: 26; h: 26), (x: NTPX; y: 0; w: 1; h: 1), - (x: 3500; y:1050; w: 25; h: 50), - (x: 3650; y: 600; w: 50; h: 100), - (x: 3800; y: 600; w: 50; h: 100), - (x: 3900; y:1000; w: 25; h: 50), + (x: 3500; y:1050; w: 50; h: 75), + (x: 3650; y: 600; w: 75; h: 125), + (x: 3800; y: 600; w: 75; h: 125), + (x: 3900; y:1000; w: 50; h: 75), (x: NTPX; y: 0; w: 1; h: 1), - (x: 3800; y: 200; w: 25; h: 50), - (x: 3875; y: 100; w: 50; h: 50), - (x: 3925; y: 50; w: 50; h: 25), - (x: 4050; y: 125; w: 25; h: 50), + (x: 3800; y: 200; w: 50; h: 75), + (x: 3875; y: 100; w: 75; h: 75), + (x: 3925; y: 50; w: 75; h: 50), + (x: 4050; y: 125; w: 50; h: 75), (x: NTPX; y: 0; w: 1; h: 1), - (x: 95; y:2548; w: 1; h: 1), - (x: 100; y:2323; w: 25; h: 100), - (x: 325; y:2323; w: 25; h: 100), - (x: 330; y:2548; w: 1; h: 1), + (x: 95; y:2548; w: 26; h: 26), + (x: 100; y:2323; w: 50; h: 125), + (x: 325; y:2323; w: 50; h: 125), + (x: 330; y:2548; w: 26; h: 26), (x: NTPX; y:2048; w: 1; h: 1), - (x: 725; y:2173; w: 1; h: 1), - (x: 725; y:2073; w: 5; h: 25), - (x: 825; y:2083; w: 5; h: 10), - (x: 825; y:2183; w: 1; h: 1), + (x: 725; y:2173; w: 26; h: 26), + (x: 725; y:2073; w: 30; h: 50), + (x: 825; y:2083; w: 30; h: 35), + (x: 825; y:2183; w: 26; h: 26), (x: NTPX; y:2048; w: 1; h: 1), - (x: 1150; y:2598; w: 25; h: 50), - (x: 1250; y:2348; w: 25; h: 50), - (x: 1350; y:2348; w: 25; h: 50), - (x: 1400; y:2623; w: 25; h: 50), + (x: 1150; y:2598; w: 50; h: 75), + (x: 1250; y:2348; w: 50; h: 75), + (x: 1350; y:2348; w: 50; h: 75), + (x: 1400; y:2623; w: 50; h: 75), (x: NTPX; y:2048; w: 1; h: 1), - (x: 525; y:3098; w: 50; h: 50), - (x: 700; y:2848; w: 100; h: 150), - (x: 950; y:2948; w: 100; h: 150), - (x: 1100; y:3148; w: 50; h: 50), + (x: 525; y:3098; w: 75; h: 75), + (x: 700; y:2848; w: 125; h: 175), + (x: 950; y:2948; w: 125; h: 175), + (x: 1100; y:3148; w: 75; h: 75), (x: NTPX; y:2048; w: 1; h: 1), - (x: 175; y:3548; w: 1; h: 1), - (x: 210; y:3448; w: 5; h: 25), - (x: 240; y:3448; w: 5; h: 25), - (x: 275; y:3558; w: 1; h: 1), + (x: 175; y:3548; w: 26; h: 26), + (x: 210; y:3448; w: 30; h: 50), + (x: 240; y:3448; w: 30; h: 50), + (x: 275; y:3558; w: 26; h: 26), (x: NTPX; y:2048; w: 1; h: 1), - (x: 450; y:3848; w: 100; h: 100), - (x: 600; y:3798; w: 100; h: 100), - (x: 750; y:3798; w: 100; h: 100), - (x: 950; y:3898; w: 100; h: 100), + (x: 450; y:3848; w: 125; h: 125), + (x: 600; y:3798; w: 125; h: 125), + (x: 750; y:3798; w: 125; h: 125), + (x: 950; y:3898; w: 125; h: 125), (x: NTPX; y:2048; w: 1; h: 1), - (x: 1075; y:3498; w: 1; h: 1), - (x: 1110; y:3348; w: 5; h: 25), - (x: 1140; y:3348; w: 5; h: 25), - (x: 1175; y:3478; w: 1; h: 1), + (x: 1075; y:3498; w: 26; h: 26), + (x: 1110; y:3348; w: 30; h: 50), + (x: 1140; y:3348; w: 30; h: 50), + (x: 1175; y:3478; w: 26; h: 26), (x: NTPX; y:2048; w: 1; h: 1), - (x: 1600; y:3298; w: 25; h: 100), - (x: 1700; y:3198; w: 25; h: 100), - (x: 1850; y:2548; w: 50; h: 100), - (x: 1950; y:2598; w: 50; h: 150), - (x: 2250; y:3198; w: 25; h: 100), - (x: 2350; y:3298; w: 25; h: 100), + (x: 1600; y:3298; w: 50; h: 125), + (x: 1700; y:3198; w: 50; h: 125), + (x: 1850; y:2548; w: 75; h: 125), + (x: 1950; y:2598; w: 75; h: 175), + (x: 2250; y:3198; w: 50; h: 125), + (x: 2350; y:3298; w: 50; h: 125), (x: NTPX; y:2048; w: 1; h: 1), - (x: 1750; y:4058; w: 1; h: 1), - (x: 1900; y:3918; w: 50; h: 50), - (x: 2050; y:3918; w: 50; h: 50), - (x: 2175; y:4058; w: 1; h: 1), + (x: 1750; y:4058; w: 26; h: 26), + (x: 1900; y:3918; w: 75; h: 75), + (x: 2050; y:3918; w: 75; h: 75), + (x: 2175; y:4058; w: 26; h: 26), (x: NTPX; y:2048; w: 1; h: 1), - (x: 2500; y:3748; w: 1; h: 1), - (x: 2575; y:3548; w: 10; h: 50), - (x: 2650; y:3548; w: 10; h: 50), - (x: 2700; y:3738; w: 1; h: 1), + (x: 2500; y:3748; w: 26; h: 26), + (x: 2575; y:3548; w: 35; h: 75), + (x: 2650; y:3548; w: 35; h: 75), + (x: 2700; y:3738; w: 26; h: 26), (x: NTPX; y:2048; w: 1; h: 1), - (x: 2000; y:2173; w: 1; h: 1), - (x: 2050; y:2098; w: 25; h: 25), - (x: 2100; y:2098; w: 25; h: 25), - (x: 2150; y:2198; w: 1; h: 1), + (x: 2000; y:2173; w: 26; h: 26), + (x: 2050; y:2098; w: 50; h: 50), + (x: 2100; y:2098; w: 50; h: 50), + (x: 2150; y:2198; w: 26; h: 26), (x: NTPX; y:2048; w: 1; h: 1), - (x: 2600; y:2298; w: 25; h: 100), - (x: 2750; y:2448; w: 50; h: 50), - (x: 2900; y:2573; w: 50; h: 50), - (x: 3150; y:2598; w: 50; h: 100), + (x: 2600; y:2298; w: 50; h: 125), + (x: 2750; y:2448; w: 75; h: 75), + (x: 2900; y:2573; w: 75; h: 75), + (x: 3150; y:2598; w: 75; h: 125), (x: NTPX; y:2048; w: 1; h: 1), - (x: 2800; y:3198; w: 1; h: 1), - (x: 2840; y:2998; w: 25; h: 25), - (x: 2880; y:2998; w: 25; h: 25), - (x: 2900; y:3198; w: 1; h: 1), + (x: 2800; y:3198; w: 26; h: 26), + (x: 2840; y:2998; w: 50; h: 50), + (x: 2880; y:2998; w: 50; h: 50), + (x: 2900; y:3198; w: 26; h: 26), (x: NTPX; y:2048; w: 1; h: 1), - (x: 3075; y:4033; w: 1; h: 1), - (x: 3325; y:3748; w: 50; h: 100), - (x: 3475; y:3748; w: 50; h: 100), - (x: 3625; y:4033; w: 1; h: 1), + (x: 3075; y:4033; w: 26; h: 26), + (x: 3325; y:3748; w: 75; h: 125), + (x: 3475; y:3748; w: 75; h: 125), + (x: 3625; y:4033; w: 26; h: 26), (x: NTPX; y:2048; w: 1; h: 1), - (x: 3200; y:3498; w: 1; h: 1), - (x: 3240; y:3398; w: 25; h: 25), - (x: 3280; y:3398; w: 25; h: 25), - (x: 3300; y:3498; w: 1; h: 1), + (x: 3200; y:3498; w: 26; h: 26), + (x: 3240; y:3398; w: 50; h: 50), + (x: 3280; y:3398; w: 50; h: 50), + (x: 3300; y:3498; w: 26; h: 26), (x: NTPX; y:2048; w: 1; h: 1), - (x: 3500; y:3098; w: 25; h: 50), - (x: 3650; y:2648; w: 50; h: 100), - (x: 3800; y:2648; w: 50; h: 100), - (x: 3900; y:3048; w: 25; h: 50), + (x: 3500; y:3098; w: 50; h: 75), + (x: 3650; y:2648; w: 75; h: 125), + (x: 3800; y:2648; w: 75; h: 125), + (x: 3900; y:3048; w: 50; h: 75), (x: NTPX; y:2048; w: 1; h: 1), - (x: 3800; y:2248; w: 25; h: 50), - (x: 3875; y:2148; w: 50; h: 50), - (x: 3925; y:2098; w: 50; h: 25), - (x: 4050; y:2173; w: 25; h: 50), + (x: 3800; y:2248; w: 50; h: 75), + (x: 3875; y:2148; w: 75; h: 75), + (x: 3925; y:2098; w: 75; h: 50), + (x: 4050; y:2173; w: 50; h: 75), (x: NTPX; y:2048; w: 1; h: 1) ); Template43FPoints: array[0..0] of TPoint = @@ -2214,8 +2214,8 @@ BasePointsCount: Succ(High(Template41Points)); FillPoints: @Template41FPoints; FillPointsCount: Succ(High(Template41FPoints)); - BezierizeCount: 3; - RandPassesCount: 5; + BezierizeCount: 2; + RandPassesCount: 9; TemplateHeight: 2048; TemplateWidth: 4096; canMirror: true; canFlip: true; isNegative: false; canInvert: false; hasGirders: true; @@ -2236,8 +2236,8 @@ BasePointsCount: Succ(High(Template43Points)); FillPoints: @Template43FPoints; FillPointsCount: Succ(High(Template43FPoints)); - BezierizeCount: 3; - RandPassesCount: 5; + BezierizeCount: 2; + RandPassesCount: 9; TemplateHeight: 4096; TemplateWidth: 4096; canMirror: true; canFlip: true; isNegative: false; canInvert: false; hasGirders: true; diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/uRandom.pas --- a/hedgewars/uRandom.pas Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/uRandom.pas Mon Aug 27 17:40:16 2012 +0200 @@ -30,9 +30,6 @@ interface uses uFloat; -procedure initModule; -procedure freeModule; - 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; inline; // Returns a positive pseudo-random integer smaller than m. @@ -99,15 +96,4 @@ rndSign:= num end; -procedure initModule; -begin - n:= 54; - FillChar(cirbuf, 64*sizeof(Longword), 0); -end; - -procedure freeModule; -begin - -end; - end. diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/uScript.pas --- a/hedgewars/uScript.pas Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/uScript.pas Mon Aug 27 17:40:16 2012 +0200 @@ -980,10 +980,13 @@ if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) and (CurrentHedgehog <> nil) then begin prevgear := CurrentHedgehog^.Gear; - prevgear^.Active := false; - prevgear^.State:= prevgear^.State and (not gstHHDriven); - prevgear^.Z := cHHZ; - prevgear^.Message:= prevgear^.Message or gmRemoveFromList or gmAddToList; + if prevgear <> nil then + begin + prevgear^.Active := false; + prevgear^.State:= prevgear^.State and (not gstHHDriven); + prevgear^.Z := cHHZ; + prevgear^.Message:= prevgear^.Message or gmRemoveFromList or gmAddToList; + end; SwitchCurrentHedgehog(gear^.Hedgehog); CurrentTeam:= CurrentHedgehog^.Team; @@ -1745,6 +1748,7 @@ ScriptSetInteger('GameFlags', GameFlags); ScriptSetString('Seed', cSeed); ScriptSetInteger('TemplateFilter', cTemplateFilter); +ScriptSetInteger('TemplateNumber', LuaTemplateNumber); ScriptSetInteger('MapGen', cMapGen); ScriptSetInteger('ScreenHeight', cScreenHeight); ScriptSetInteger('ScreenWidth', cScreenWidth); @@ -1773,6 +1777,7 @@ // pop game variables ParseCommand('seed ' + ScriptGetString('Seed'), true); cTemplateFilter := ScriptGetInteger('TemplateFilter'); +LuaTemplateNumber:= ScriptGetInteger('TemplateNumber'); cMapGen := ScriptGetInteger('MapGen'); GameFlags := ScriptGetInteger('GameFlags'); cHedgehogTurnTime:= ScriptGetInteger('TurnTime'); diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/uTypes.pas --- a/hedgewars/uTypes.pas Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/uTypes.pas Mon Aug 27 17:40:16 2012 +0200 @@ -235,6 +235,7 @@ Kind: TGearType; Pos: Longword; doStep: TGearStepProcedure; + stepFreq: Longword; Radius: LongInt; Angle, Power : Longword; DirAngle: real; diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/uVariables.pas --- a/hedgewars/uVariables.pas Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/uVariables.pas Mon Aug 27 17:40:16 2012 +0200 @@ -183,6 +183,8 @@ LuaGoals : shortstring; + LuaTemplateNumber : LongWord; + VoiceList : array[0..7] of TVoice = ( ( snd: sndNone; voicepack: nil), ( snd: sndNone; voicepack: nil), @@ -2623,6 +2625,8 @@ SDWaterOpacity:= $80; LuaGoals:= ''; + + LuaTemplateNumber:= 0; end; procedure freeModule; diff -r 0be267033fb3 -r ce6ead3327b2 hedgewars/uVisualGears.pas --- a/hedgewars/uVisualGears.pas Thu Aug 23 19:47:38 2012 +0200 +++ b/hedgewars/uVisualGears.pas Mon Aug 27 17:40:16 2012 +0200 @@ -284,8 +284,9 @@ begin dx:= 0.005 * (random(15) + 10); dy:= 0.001 * (random(40) + 20); - if random(2) = 0 then - dx := -dx; + if random(2) = 0 then dx := -dx; + if random(2) = 0 then Tag:= 1 + else Tag:= -1; Frame:= 7 - random(2); FrameTicks:= random(20) + 15; end; @@ -642,9 +643,9 @@ vgtSmoke: DrawTextureF(SpritesData[sprSmoke].Texture, Gear^.scale, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 7 - Gear^.Frame, 1, SpritesData[sprSmoke].Width, SpritesData[sprSmoke].Height); vgtSmokeWhite: DrawSprite(sprSmokeWhite, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame); vgtDust: if Gear^.State = 1 then - DrawSpriteRotatedF(sprSnowDust, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame, 1, Gear^.Angle) + DrawSpriteRotatedF(sprSnowDust, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame, Gear^.Tag, Gear^.Angle) else - DrawSprite(sprDust, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame); + DrawSpriteRotatedF(sprDust, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame, Gear^.Tag, Gear^.Angle); vgtFire: if (Gear^.State and gstTmpFlag) = 0 then DrawSprite(sprFlame, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy, (RealTicks shr 6 + Gear^.Frame) mod 8) else