# HG changeset patch # User unc0rr # Date 1451664932 -10800 # Node ID caa1e84c3ac29faa6efdd7e7b673da6cc3b5bda6 # Parent b0c34402038c3078ca314e73106b089db6fd93cc# Parent 846a3b3a3d1ce991db12592babdbb9298eb43737 merge default diff -r b0c34402038c -r caa1e84c3ac2 QTfrontend/net/newnetclient.cpp --- a/QTfrontend/net/newnetclient.cpp Fri Jan 01 19:14:59 2016 +0300 +++ b/QTfrontend/net/newnetclient.cpp Fri Jan 01 19:15:32 2016 +0300 @@ -183,7 +183,7 @@ void HWNewNet::RawSendNet(const QByteArray & buf) { - qDebug() << "Client: " << QString(buf).split("\n"); + qDebug() << "Client: " << QString(QString::fromUtf8(buf)).split("\n"); NetSocket.write(buf); NetSocket.write("\n\n", 2); } @@ -552,7 +552,7 @@ } netClientState = InLobby; - RawSendNet(QString("LIST")); + //RawSendNet(QString("LIST")); //deprecated emit connected(); } @@ -945,7 +945,7 @@ qWarning("Illegal try to get rooms list!"); return; } - RawSendNet(QString("LIST")); + //RawSendNet(QString("LIST")); //deprecated } HWNewNet::ClientState HWNewNet::clientState() diff -r b0c34402038c -r caa1e84c3ac2 QTfrontend/sdlkeys.h --- a/QTfrontend/sdlkeys.h Fri Jan 01 19:14:59 2016 +0300 +++ b/QTfrontend/sdlkeys.h Fri Jan 01 19:15:32 2016 +0300 @@ -118,8 +118,8 @@ {"insert", QT_TRANSLATE_NOOP("binds (keys)", "Insert")}, {"home", QT_TRANSLATE_NOOP("binds (keys)", "Home")}, {"end", QT_TRANSLATE_NOOP("binds (keys)", "End")}, - {"page up", QT_TRANSLATE_NOOP("binds (keys)", "Page up")}, - {"page down", QT_TRANSLATE_NOOP("binds (keys)", "Page down")}, + {"page_up", QT_TRANSLATE_NOOP("binds (keys)", "Page up")}, + {"page_down", QT_TRANSLATE_NOOP("binds (keys)", "Page down")}, {"f1", "F1"}, {"f2", "F2"}, {"f3", "F3"}, diff -r b0c34402038c -r caa1e84c3ac2 gameServer/Actions.hs --- a/gameServer/Actions.hs Fri Jan 01 19:14:59 2016 +0300 +++ b/gameServer/Actions.hs Fri Jan 01 19:15:32 2016 +0300 @@ -466,12 +466,15 @@ processAction (ProcessAccountInfo info) = do + si <- gets serverInfo case info of HasAccount passwd isAdmin isContr -> do b <- isBanned c <- client's isChecker when (not b) $ (if c then checkerLogin else playerLogin) passwd isAdmin isContr - Guest -> do + Guest | isRegisteredUsersOnly si -> do + processAction $ ByeClient "Registered users only" + | otherwise -> do b <- isBanned c <- client's isChecker when (not b) $ @@ -508,6 +511,7 @@ chan <- client's sendChan rnc <- gets roomsClients clientNick <- client's nick + clProto <- client's clientProto isAuthenticated <- liftM (not . B.null) $ client's webPassword isAdmin <- client's isAdministrator isContr <- client's isContributor @@ -521,6 +525,13 @@ >>= filterM (liftM ((/=) lobbyId) . clientRoomM rnc) >>= mapM (client'sM rnc nick) let clFlags = B.concat . L.concat $ [["u" | isAuthenticated], ["a" | isAdmin], ["c" | isContr]] + + roomsInfoList <- io $ do + rooms <- roomsM rnc + mapM (\r -> (if isNothing $ masterID r then return "" else client'sM rnc nick (fromJust $ masterID r)) + >>= \cn -> return $ roomInfo clProto cn r) + $ filter (\r -> (roomProto r == clProto)) rooms + mapM_ processAction . concat $ [ [AnswerClients clientsChans ["LOBBY:JOINED", clientNick]] , [AnswerClients [chan] ("LOBBY:JOINED" : clientNick : lobbyNicks)] @@ -531,6 +542,7 @@ , [AnswerClients (chan : clientsChans) ["CLIENT_FLAGS", B.concat["+" , clFlags], clientNick] | not $ B.null clFlags] , [ModifyClient (\cl -> cl{logonPassed = True, isVisible = True})] , [SendServerMessage] + , [AnswerClients [chan] ("ROOMS" : concat roomsInfoList)] ] diff -r b0c34402038c -r caa1e84c3ac2 gameServer/CoreTypes.hs --- a/gameServer/CoreTypes.hs Fri Jan 01 19:14:59 2016 +0300 +++ b/gameServer/CoreTypes.hs Fri Jan 01 19:15:32 2016 +0300 @@ -126,32 +126,35 @@ data ClientInfo = ClientInfo { - clUID :: Unique, - sendChan :: ClientChan, - clientSocket :: Socket, - host :: B.ByteString, - connectTime :: UTCTime, - nick :: B.ByteString, - webPassword :: B.ByteString, - serverSalt :: B.ByteString, - logonPassed :: Bool, - isVisible :: Bool, + clUID :: !Unique, + sendChan :: !ClientChan, + clientSocket :: !Socket, + host :: !B.ByteString, + connectTime :: !UTCTime, + nick :: !B.ByteString, + webPassword :: !B.ByteString, + serverSalt :: !B.ByteString, + logonPassed :: !Bool, + isVisible :: !Bool, clientProto :: !Word16, pingsQueue :: !Word, - isMaster :: Bool, + isMaster :: !Bool, isReady :: !Bool, - isInGame :: Bool, - isAdministrator :: Bool, - isChecker :: Bool, - isContributor :: Bool, - isKickedFromServer :: Bool, - isJoinedMidGame :: Bool, + isInGame :: !Bool, + isAdministrator :: !Bool, + hasSuperPower :: !Bool, + isChecker :: !Bool, + isContributor :: !Bool, + isKickedFromServer :: !Bool, + isJoinedMidGame :: !Bool, + hasAskedList :: !Bool, clientClan :: !(Maybe B.ByteString), - checkInfo :: Maybe CheckInfo, + checkInfo :: !(Maybe CheckInfo), eiLobbyChat, eiEM, - eiJoin :: EventsInfo, - teamsInGame :: Word + eiJoin :: !EventsInfo, + teamsInGame :: !Word, + pendingActions :: ![Action] } instance Eq ClientInfo where @@ -164,17 +167,17 @@ data TeamInfo = TeamInfo { - teamowner :: B.ByteString, - teamname :: B.ByteString, - teamcolor :: B.ByteString, - teamgrave :: B.ByteString, - teamfort :: B.ByteString, - teamvoicepack :: B.ByteString, - teamflag :: B.ByteString, - isOwnerRegistered :: Bool, - difficulty :: Int, - hhnum :: Int, - hedgehogs :: [HedgehogInfo] + teamowner :: !B.ByteString, + teamname :: !B.ByteString, + teamcolor :: !B.ByteString, + teamgrave :: !B.ByteString, + teamfort :: !B.ByteString, + teamvoicepack :: !B.ByteString, + teamflag :: !B.ByteString, + isOwnerRegistered :: !Bool, + difficulty :: !Int, + hhnum :: !Int, + hedgehogs :: ![HedgehogInfo] } deriving (Show, Read) @@ -214,26 +217,26 @@ data RoomInfo = RoomInfo { - masterID :: Maybe ClientIndex, - name :: B.ByteString, - password :: B.ByteString, - roomProto :: Word16, - teams :: [TeamInfo], - gameInfo :: Maybe GameInfo, + masterID :: !(Maybe ClientIndex), + name :: !B.ByteString, + password :: !B.ByteString, + roomProto :: !Word16, + teams :: ![TeamInfo], + gameInfo :: !(Maybe GameInfo), playersIn :: !Int, readyPlayers :: !Int, - isRestrictedJoins :: Bool, - isRestrictedTeams :: Bool, - isRegisteredOnly :: Bool, - isSpecial :: Bool, - defaultHedgehogsNumber :: Int, - teamsNumberLimit :: Int, - greeting :: B.ByteString, - voting :: Maybe Voting, + isRestrictedJoins :: !Bool, + isRestrictedTeams :: !Bool, + isRegisteredOnly :: !Bool, + isSpecial :: !Bool, + defaultHedgehogsNumber :: !Int, + teamsNumberLimit :: !Int, + greeting :: !B.ByteString, + voting :: !(Maybe Voting), roomBansList :: ![B.ByteString], - mapParams :: Map.Map B.ByteString B.ByteString, - params :: Map.Map B.ByteString [B.ByteString], - roomSaves :: Map.Map B.ByteString (Map.Map B.ByteString B.ByteString, Map.Map B.ByteString [B.ByteString]) + mapParams :: !(Map.Map B.ByteString B.ByteString), + params :: !(Map.Map B.ByteString [B.ByteString]), + roomSaves :: !(Map.Map B.ByteString (Map.Map B.ByteString B.ByteString, Map.Map B.ByteString [B.ByteString])) } newRoom :: RoomInfo @@ -280,6 +283,7 @@ ServerInfo { isDedicated :: Bool, + isRegisteredUsersOnly :: Bool, serverMessage :: B.ByteString, serverMessageForOldVersions :: B.ByteString, latestReleaseVersion :: Word16, @@ -303,6 +307,7 @@ newServerInfo = ServerInfo True + False "

http://www.hedgewars.org/

" "

Hedgewars 0.9.22 is out! Please update.

Download page here" 51 -- latestReleaseVersion diff -r b0c34402038c -r caa1e84c3ac2 gameServer/FloodDetection.hs --- a/gameServer/FloodDetection.hs Fri Jan 01 19:14:59 2016 +0300 +++ b/gameServer/FloodDetection.hs Fri Jan 01 19:15:32 2016 +0300 @@ -49,7 +49,7 @@ chat1 = [Warning $ loc "Warning! Chat flood protection activated"] chat2 = [ByeClient $ loc "Excess flood"] em1 = [Warning $ loc "Game messages flood detected - 1"] - em2 = [Warning $ loc "Game messages flood detected - 2"] + em2 = [ByeClient $ loc "Excess flood"] join1 = [Warning $ loc "Warning! Joins flood protection activated"] join2 = [ByeClient $ loc "Excess flood"] @@ -69,7 +69,9 @@ else [] - return $ (ModifyClient . transformField e . const $ (numPerEntry, curTime) : nei) : actions + return $ [ModifyClient . transformField e . const $ (numPerEntry, curTime) : nei + , ModifyClient (\c -> c{pendingActions = actions}) -- append? prepend? just replacing for now + ] updateInfo = return [ ModifyClient $ transformField e diff -r b0c34402038c -r caa1e84c3ac2 gameServer/HWProtoCore.hs --- a/gameServer/HWProtoCore.hs Fri Jan 01 19:14:59 2016 +0300 +++ b/gameServer/HWProtoCore.hs Fri Jan 01 19:15:32 2016 +0300 @@ -75,11 +75,10 @@ h "QUIT" m | not $ B.null m = handleCmd ["QUIT", m] | otherwise = handleCmd ["QUIT"] h "RND" p = handleCmd ("RND" : B.words p) - h "GLOBAL" p = do - cl <- thisClient + h "GLOBAL" p = serverAdminOnly $ do rnc <- liftM snd ask let chans = map (sendChan . client rnc) $ allClients rnc - return [AnswerClients chans ["CHAT", "[global notice]", p] | isAdministrator cl] + return [AnswerClients chans ["CHAT", "[global notice]", p]] h "WATCH" f = return [QueryReplay f] h "FIX" _ = handleCmd ["FIX"] h "UNFIX" _ = handleCmd ["UNFIX"] @@ -92,6 +91,13 @@ h "MAXTEAMS" n | not $ B.null n = handleCmd ["MAXTEAMS", n] h "INFO" n | not $ B.null n = handleCmd ["INFO", n] h "RESTART_SERVER" "YES" = handleCmd ["RESTART_SERVER"] + h "REGISTERED_ONLY" _ = serverAdminOnly $ do + cl <- thisClient + return + [ModifyServerInfo(\s -> s{isRegisteredUsersOnly = not $ isRegisteredUsersOnly s}) + , AnswerClients [sendChan cl] ["CHAT", "[server]", "'Registered only' state toggled"] + ] + h "SUPER_POWER" _ = serverAdminOnly $ return [ModifyClient (\c -> c{hasSuperPower = True})] h c p = return [Warning $ B.concat ["Unknown cmd: /", c, " ", p]] extractParameters p = let (a, b) = B.break (== ' ') p in (upperCase a, B.dropWhile (== ' ') b) diff -r b0c34402038c -r caa1e84c3ac2 gameServer/HWProtoLobbyState.hs --- a/gameServer/HWProtoLobbyState.hs Fri Jan 01 19:14:59 2016 +0300 +++ b/gameServer/HWProtoLobbyState.hs Fri Jan 01 19:15:32 2016 +0300 @@ -39,7 +39,9 @@ let cl = irnc `client` ci rooms <- allRoomInfos let roomsInfoList = concatMap (\r -> roomInfo (clientProto cl) (maybeNick . liftM (client irnc) $ masterID r) r) . filter (\r -> (roomProto r == clientProto cl)) - return [AnswerClients [sendChan cl] ("ROOMS" : roomsInfoList rooms)] + return $ if hasAskedList cl then [] else + [ ModifyClient (\c -> c{hasAskedList = True}) + , AnswerClients [sendChan cl] ("ROOMS" : roomsInfoList rooms)] handleCmd_lobby ["CHAT", msg] = do n <- clientNick @@ -91,13 +93,13 @@ [Warning $ loc "No such room"] else if (not sameProto) && (not $ isAdministrator cl) then [Warning $ loc "Room version incompatible to your hedgewars version"] - else if isRestrictedJoins jRoom then + else if isRestrictedJoins jRoom && not (hasSuperPower cl) then [Warning $ loc "Joining restricted"] else if isRegisteredOnly jRoom && (B.null . webPassword $ cl) && not (isAdministrator cl) then [Warning $ loc "Registered users only"] else if isBanned then [Warning $ loc "You are banned in this room"] - else if roomPassword /= password jRoom then + else if roomPassword /= password jRoom && not (hasSuperPower cl) then [NoticeMessage WrongPassword] else ( diff -r b0c34402038c -r caa1e84c3ac2 gameServer/NetRoutines.hs --- a/gameServer/NetRoutines.hs Fri Jan 01 19:14:59 2016 +0300 +++ b/gameServer/NetRoutines.hs Fri Jan 01 19:15:32 2016 +0300 @@ -72,12 +72,15 @@ False False False + False + False Nothing Nothing newEventsInfo newEventsInfo newEventsInfo 0 + [] ) writeChan chan $ Accept newClient diff -r b0c34402038c -r caa1e84c3ac2 gameServer/ServerCore.hs --- a/gameServer/ServerCore.hs Fri Jan 01 19:14:59 2016 +0300 +++ b/gameServer/ServerCore.hs Fri Jan 01 19:15:32 2016 +0300 @@ -23,7 +23,7 @@ import System.Log.Logger import Control.Monad.Reader import Control.Monad.State.Strict -import Data.Set as Set +import Data.Set as Set hiding (null) import Data.Unique import Data.Maybe -------------------------------------- @@ -55,6 +55,10 @@ unless (ci `Set.member` removed) $ do modify (\s -> s{clientIndex = Just ci}) processAction $ ReactCmd cmd + pa <- client's pendingActions + when (not $ null pa) $ do + mapM_ processAction pa + processAction $ ModifyClient $ \c -> c{pendingActions = []} Remove ci -> processAction (DeleteClient ci) diff -r b0c34402038c -r caa1e84c3ac2 hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Fri Jan 01 19:14:59 2016 +0300 +++ b/hedgewars/hwengine.pas Fri Jan 01 19:15:32 2016 +0300 @@ -70,9 +70,9 @@ AddClouds; AddFlakes; SetRandomSeed(cSeed, false); + StoreLoad(false); AssignHHCoords; AddMiscGears; - StoreLoad(false); InitWorld; ResetKbd; if GameType = gmtSave then diff -r b0c34402038c -r caa1e84c3ac2 hedgewars/uAI.pas --- a/hedgewars/uAI.pas Fri Jan 01 19:14:59 2016 +0300 +++ b/hedgewars/uAI.pas Fri Jan 01 19:15:32 2016 +0300 @@ -166,6 +166,11 @@ AddAction(BestActions, aia_Weapon, Longword(a), 300 + random(400), 0, 0); + if (Ammoz[a].Ammo.Propz and ammoprop_NeedTarget) <> 0 then + begin + AddAction(BestActions, aia_Put, 0, 8, ap.AttackPutX, ap.AttackPutY) + end; + if (ap.Angle > 0) then AddAction(BestActions, aia_LookRight, 0, 200, 0, 0) else if (ap.Angle < 0) then @@ -189,11 +194,6 @@ end end; - if (Ammoz[a].Ammo.Propz and ammoprop_NeedTarget) <> 0 then - begin - AddAction(BestActions, aia_Put, 0, 1, ap.AttackPutX, ap.AttackPutY) - end; - if (Ammoz[a].Ammo.Propz and ammoprop_OscAim) <> 0 then begin AddAction(BestActions, aia_attack, aim_push, 350 + random(200), 0, 0); diff -r b0c34402038c -r caa1e84c3ac2 hedgewars/uAIAmmoTests.pas --- a/hedgewars/uAIAmmoTests.pas Fri Jan 01 19:14:59 2016 +0300 +++ b/hedgewars/uAIAmmoTests.pas Fri Jan 01 19:15:32 2016 +0300 @@ -36,6 +36,7 @@ end; function TestBazooka(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; +function TestBee(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; function TestSnowball(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; function TestGrenade(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; function TestMolotov(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; @@ -68,7 +69,7 @@ (proc: @TestGrenade; flags: 0), // amGrenade (proc: @TestClusterBomb; flags: 0), // amClusterBomb (proc: @TestBazooka; flags: 0), // amBazooka - (proc: nil; flags: 0), // amBee + (proc: @TestBee; flags: amtest_Rare), // amBee (proc: @TestShotgun; flags: 0), // amShotgun (proc: nil; flags: 0), // amPickHammer (proc: nil; flags: 0), // amSkip @@ -176,7 +177,9 @@ value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand) else value:= RateExplosion(Me, EX, EY, 101); if (value = 0) and (Targ.Kind = gtHedgehog) and (Targ.Score > 0) then - value:= 1024 - Metric(Targ.Point.X, Targ.Point.Y, EX, EY) div 64; + if GameFlags and gfSolidLand = 0 then + value := 1024 - Metric(Targ.Point.X, Targ.Point.Y, EX, EY) div 64 + else value := BadTurn; if valueResult <= value then begin ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random((Level - 1) * 9)); @@ -192,6 +195,113 @@ TestBazooka:= valueResult end; +function calcBeeFlight(Me: PGear; x, y, dx, dy, tX, tY: real; var eX, eY: LongInt): LongInt; +var t: Longword; + f: boolean; + speed, d: real; +begin + // parabola flight before activation + t:= 500; + repeat + x:= x + dx; + y:= y + dy; + dy:= dy + cGravityf; + f:= ((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or + ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5)); + dec(t) + until (t = 0) or (y >= cWaterLine) or f; + + if f then + begin + eX:= trunc(x); + eY:= trunc(y); + exit(RateExplosion(Me, eX, eY, 101, afTrackFall or afErasesLand)); + end; + + + // activated + t:= 5000; + speed:= sqrt(sqr(dx) + sqr(dy)); + + repeat + if (t and $F) = 0 then + begin + dx:= dx + 0.000064 * (tX - x); + dy:= dy + 0.000064 * (tY - y); + d := speed / sqrt(sqr(dx) + sqr(dy)); + dx:= dx * d; + dy:= dy * d; + end; + + x:= x + dx; + y:= y + dy; + f:= ((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or + ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5)); + dec(t) + until (t = 0) or f; + + if f then + begin + eX:= trunc(x); + eY:= trunc(y); + exit(RateExplosion(Me, eX, eY, 101, afTrackFall or afErasesLand)); + end + else + calcBeeFlight:= BadTurn +end; + +function TestBee(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; +var i, j: LongInt; + valueResult, v, a, p: LongInt; + mX, mY, dX: real; + eX, eY: LongInt; +begin + if Level > 1 then + exit(BadTurn); + + eX:= 0; + eY:= 0; + mX:= hwFloat2Float(Me^.X); + mY:= hwFloat2Float(Me^.Y); + valueResult:= BadTurn; + for i:= 0 to 8 do + for j:= 0 to 1 do + begin + a:= i * 120; + p:= random(cMaxPower - 200) + 180; + + if j = 0 then + a:= -a; + + v:= calcBeeFlight(Me + , mX + , mY + , sin(a * pi / 2048) * p / cPowerDivisor + , -cos(a * pi / 2048) * p / cPowerDivisor + , Targ.Point.X + , Targ.Point.Y + , eX + , eY); + + if v > valueResult then + begin + ap.ExplR:= 100; + ap.ExplX:= eX; + ap.ExplY:= eY; + ap.Angle:= a; + ap.Power:= p; + valueResult:= v + end + end; + + ap.AttackPutX:= Targ.Point.X; + ap.AttackPutY:= Targ.Point.Y; + + if valueResult > 0 then + TestBee:= valueResult - 5000 + else + TestBee:= BadTurn // no digging +end; function TestDrillRocket(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; var Vx, Vy, r, mX, mY: real; @@ -668,7 +778,11 @@ valueResult:= RateShotgun(Me, vX, vY, rx, ry); if (valueResult = 0) and (Targ.Kind = gtHedgehog) and (Targ.Score > 0) then - valueResult:= 1024 - Metric(Targ.Point.X, Targ.Point.Y, rx, ry) div 64 + begin + if GameFlags and gfSolidLand = 0 then + valueResult:= 1024 - Metric(Targ.Point.X, Targ.Point.Y, rx, ry) div 64 + else valueResult := BadTurn + end else dec(valueResult, Level * 4000); // 27/20 is reuse bonus diff -r b0c34402038c -r caa1e84c3ac2 hedgewars/uChat.pas --- a/hedgewars/uChat.pas Fri Jan 01 19:14:59 2016 +0300 +++ b/hedgewars/uChat.pas Fri Jan 01 19:15:32 2016 +0300 @@ -196,7 +196,7 @@ // create and blit text strSurface:= TTF_RenderUTF8_Blended(Fontz[font].Handle, Str2PChar(str), cl.color); //SDL_UpperBlit(strSurface, nil, resSurface, @dstrect); -if strSurface <> nil then copyTOXY(strSurface, resSurface, Padding, Padding); +if strSurface <> nil then copyToXY(strSurface, resSurface, Padding, Padding); SDL_FreeSurface(strSurface); cl.Tex:= Surface2Tex(resSurface, false); diff -r b0c34402038c -r caa1e84c3ac2 hedgewars/uGears.pas --- a/hedgewars/uGears.pas Fri Jan 01 19:14:59 2016 +0300 +++ b/hedgewars/uGears.pas Fri Jan 01 19:15:32 2016 +0300 @@ -168,7 +168,9 @@ i, AliveCount: LongInt; s: ansistring; prevtime: LongWord; + stirFallers: boolean; begin +stirFallers:= false; prevtime:= TurnTimeLeft; ScriptCall('onGameTick'); if GameTicks mod 20 = 0 then ScriptCall('onGameTick20'); @@ -199,6 +201,8 @@ begin curHandledGear:= t; t:= curHandledGear^.NextGear; + if (GameTicks and $1FFF = 0) and (curHandledGear^.Kind = gtCase) and (curHandledGear^.Pos <> posCaseHealth) then + stirFallers := true; if curHandledGear^.Message and gmDelete <> 0 then DeleteGear(curHandledGear) @@ -224,6 +228,23 @@ end end end; +if stirFallers then + begin + t := GearsList; + while t <> nil do + begin + if t^.Kind = gtGenericFaller then + begin + t^.Active:= true; + t^.X:= int2hwFloat(GetRandom(rightX-leftX)+leftX); + t^.Y:= int2hwFloat(GetRandom(LAND_HEIGHT-topY)+topY); + t^.dX:= _90-(GetRandomf*_360); + t^.dY:= _90-(GetRandomf*_360) + end; + t := t^.NextGear + end + end; + curHandledGear:= nil; if AllInactive then @@ -749,7 +770,8 @@ end; t:= LAND_WIDTH div 2 end - end else // mix hedgehogs + end +else // mix hedgehogs begin Count:= 0; for p:= 0 to Pred(TeamsCount) do @@ -778,7 +800,30 @@ ar[i]:= ar[Count - 1]; dec(Count) end - end + end; +for p:= 0 to Pred(TeamsCount) do + with TeamsArray[p]^ do + for i:= 0 to cMaxHHIndex do + with Hedgehogs[i] do + if (Gear <> nil) and (Gear^.State and gsttmpFlag <> 0) then + begin + DrawExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50); + AddFileLog('Carved a hole for hog at coordinates (' + inttostr(hwRound(Gear^.X)) + ',' + inttostr(hwRound(Gear^.Y)) + ')') + end; +// place flowers after in case holes overlap (we shrink search distance if we are failing to place) +for p:= 0 to Pred(TeamsCount) do + with TeamsArray[p]^ do + for i:= 0 to cMaxHHIndex do + with Hedgehogs[i] do + if (Gear <> nil) and (Gear^.State and gsttmpFlag <> 0) then + begin + ForcePlaceOnLand(hwRound(Gear^.X) - SpritesData[sprTargetBee].Width div 2, + hwRound(Gear^.Y) - SpritesData[sprTargetBee].Height div 2, + sprTargetBee, 0, lfBasic, $FFFFFFFF, false, false, false); + Gear^.Y:= int2hwFloat(hwRound(Gear^.Y) - 16 - Gear^.Radius); + Gear^.State:= Gear^.State and not gsttmpFlag; + AddFileLog('Carved a hole for hog at coordinates (' + inttostr(hwRound(Gear^.X)) + ',' + inttostr(hwRound(Gear^.Y)) + ')') + end end; diff -r b0c34402038c -r caa1e84c3ac2 hedgewars/uGearsHandlersMess.pas --- a/hedgewars/uGearsHandlersMess.pas Fri Jan 01 19:14:59 2016 +0300 +++ b/hedgewars/uGearsHandlersMess.pas Fri Jan 01 19:15:32 2016 +0300 @@ -128,7 +128,7 @@ procedure doStepResurrectorWork(Gear: PGear); procedure doStepResurrector(Gear: PGear); procedure doStepNapalmBomb(Gear: PGear); -procedure doStepStructure(Gear: PGear); +//procedure doStepStructure(Gear: PGear); procedure doStepTardisWarp(Gear: PGear); procedure doStepTardis(Gear: PGear); procedure updateFuel(Gear: PGear); @@ -136,7 +136,7 @@ procedure doStepIceGun(Gear: PGear); procedure doStepAddAmmo(Gear: PGear); procedure doStepGenericFaller(Gear: PGear); -procedure doStepCreeper(Gear: PGear); +//procedure doStepCreeper(Gear: PGear); procedure doStepKnife(Gear: PGear); var @@ -513,10 +513,10 @@ dec(Gear^.Timer); if Gear^.Timer = 1000 then // might need adjustments case Gear^.Kind of - gtGrenade: makeHogsWorry(Gear^.X, Gear^.Y, 50); - gtClusterBomb: makeHogsWorry(Gear^.X, Gear^.Y, 20); - gtWatermelon: makeHogsWorry(Gear^.X, Gear^.Y, 75); - gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, 90); + gtGrenade, + gtClusterBomb, + gtWatermelon, + gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, Gear^.Boom); gtGasBomb: makeHogsWorry(Gear^.X, Gear^.Y, 50); end; @@ -524,7 +524,7 @@ begin CheckCollision(Gear); if (Gear^.State and gstCollision) <> 0 then - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLDontDraw or EXPLNoGfx); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLDontDraw or EXPLNoGfx); end; if (Gear^.Kind = gtGasBomb) and ((GameTicks mod 200) = 0) then @@ -537,14 +537,14 @@ if Gear^.Timer = 0 then begin case Gear^.Kind of - gtGrenade: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); - gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 40, Gear^.Hedgehog, EXPLAutoSound); + gtGrenade: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); + gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); gtClusterBomb: begin x := hwRound(Gear^.X); y := hwRound(Gear^.Y); gdX:= Gear^.dX; - doMakeExplosion(x, y, 20, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(x, y, Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); for i:= 0 to 4 do begin dX := rndSign(GetRandomf * _0_1) + gdX / 5; @@ -557,7 +557,7 @@ x := hwRound(Gear^.X); y := hwRound(Gear^.Y); gdX:= Gear^.dX; - doMakeExplosion(x, y, 75, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(x, y, Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); for i:= 0 to 5 do begin dX := rndSign(GetRandomf * _0_1) + gdX / 5; @@ -570,7 +570,7 @@ begin x := hwRound(Gear^.X); y := hwRound(Gear^.Y); - doMakeExplosion(x, y, 90, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(x, y, Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); for i:= 0 to 127 do begin @@ -590,7 +590,7 @@ end; gtGasBomb: begin - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); for i:= 0 to 2 do begin x:= GetRandom(60); @@ -699,13 +699,12 @@ doStepFallingGear(Gear); if (Gear^.State and gstCollision) <> 0 then begin - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Timer, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); DeleteGear(Gear); exit end; - if (Gear^.Kind = gtMelonPiece) - or (Gear^.Kind = gtBall) then + if (Gear^.Kind = gtMelonPiece) then CalcRotationDirAngle(Gear) else if (GameTicks and $1F) = 0 then AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); @@ -720,7 +719,7 @@ doStepFallingGear(Gear); if (Gear^.State and gstCollision) <> 0 then begin - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); DeleteGear(Gear); exit end; @@ -743,7 +742,7 @@ CalcRotationDirAngle(Gear); if (Gear^.State and gstCollision) <> 0 then begin - kick:= hwRound((hwAbs(gdX)+hwAbs(gdY)) * _20); + kick:= hwRound((hwAbs(gdX)+hwAbs(gdY)) * Gear^.Boom / 10000); Gear^.dX:= gdX; Gear^.dY:= gdY; AmmoShove(Gear, 0, kick); @@ -1029,13 +1028,13 @@ end else begin - if (GameTicks and $F) = 0 then + if (Gear^.Timer and $F) = 0 then begin - if (GameTicks and $30) = 0 then + if (Gear^.Timer and $3F) = 0 then AddVisualGear(gX, gY, vgtBeeTrace); - Gear^.dX := Gear^.Elasticity * (Gear^.dX + _0_000064 * (Gear^.Target.X - gX)); - Gear^.dY := Gear^.Elasticity * (Gear^.dY + _0_000064 * (Gear^.Target.Y - gY)); + Gear^.dX := Gear^.dX + _0_000064 * (Gear^.Target.X - gX); + Gear^.dY := Gear^.dY + _0_000064 * (Gear^.Target.Y - gY); // make sure new speed isn't higher than original one (which we stored in Friction variable) t := Gear^.Friction / Distance(Gear^.dX, Gear^.dY); Gear^.dX := Gear^.dX * t; @@ -1052,7 +1051,7 @@ if ((Gear^.State and gstCollision) <> 0) then begin StopSoundChan(Gear^.SoundChannel); - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); for i:= 0 to 31 do begin flower:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtStraightShot); @@ -1098,7 +1097,7 @@ CheckCollision(Gear); if (Gear^.State and gstCollision) <> 0 then begin - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); DeleteGear(Gear); exit end; @@ -1280,9 +1279,9 @@ if Gear^.Damage > 5 then begin if Gear^.AmmoType = amDEagle then - AmmoShove(Gear, 7, 20) + AmmoShove(Gear, Gear^.Boom, 20) else - AmmoShove(Gear, Gear^.Timer, 20); + AmmoShove(Gear, Gear^.Timer * Gear^.Boom div 100000, 20); end; CheckGearDrowning(Gear); dec(i) @@ -1471,7 +1470,7 @@ if (Gear^.Timer mod 33) = 0 then begin HHGear^.State := HHGear^.State or gstNoDamage; - doMakeExplosion(x, y + 7, 6, Gear^.Hedgehog, EXPLDontDraw); + doMakeExplosion(x, y + 7, Gear^.Boom, Gear^.Hedgehog, EXPLDontDraw); HHGear^.State := HHGear^.State and (not gstNoDamage) end; @@ -1646,7 +1645,7 @@ Gear^.Y := HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC); end; HHGear^.State := HHGear^.State or gstNoDamage; - AmmoShove(Gear, 2, 15); + AmmoShove(Gear, Gear^.Boom, 15); HHGear^.State := HHGear^.State and (not gstNoDamage) end; end; @@ -1731,7 +1730,7 @@ if (Gear^.Damage > 35) then begin - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); DeleteGear(Gear); exit end @@ -1755,7 +1754,7 @@ or (cMineDudPercent = 0) or (getRandom(100) > cMineDudPercent) then begin - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); DeleteGear(Gear) end else @@ -1779,12 +1778,6 @@ Gear^.State := Gear^.State or gsttmpFlag; end; -(* -Just keeping track for my own benefit. -Every second, locate new target. Clear if target radius has been set to 0 or no target in range. -Every... 16 milliseconds? Update vector to target. -*) - procedure doStepAirMine(Gear: PGear); var i,t,targDist,tmpDist: LongWord; targ, tmpG: PGear; @@ -1983,7 +1976,8 @@ if ((Gear^.State and gstAttacking) = 0) then begin if ((GameTicks and $1F) = 0) then - if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then +// FIXME - values taken from mine. use a gear val and set both to same + if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then Gear^.State := Gear^.State or gstAttacking end else // gstAttacking <> 0 @@ -1991,7 +1985,7 @@ AllInactive := false; if Gear^.Timer = 0 then begin - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); DeleteGear(Gear); exit end @@ -2018,7 +2012,7 @@ makeHogsWorry(Gear^.X, Gear^.Y, 75); if Gear^.Timer = 0 then begin - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); DeleteGear(Gear); exit end; @@ -2137,13 +2131,13 @@ if k = gtCase then begin - doMakeExplosion(x, y, 25, hog, EXPLAutoSound); + doMakeExplosion(x, y, Gear^.Boom, hog, EXPLAutoSound); for i:= 0 to 63 do AddGear(x, y, gtFlame, 0, _0, _0, 0); end else if k = gtExplosives then begin - doMakeExplosion(x, y, 75, hog, EXPLAutoSound); + doMakeExplosion(x, y, Gear^.Boom, hog, EXPLAutoSound); for i:= 0 to 31 do begin dX := AngleCos(i * 64) * _0_5 * (getrandomf + _1); @@ -2175,23 +2169,6 @@ end else begin - if (Gear^.Pos <> posCaseHealth) and (GameTicks and $1FFF = 0) then // stir 'em up periodically - begin - gi := GearsList; - while gi <> nil do - begin - if gi^.Kind = gtGenericFaller then - begin - gi^.Active:= true; - gi^.X:= int2hwFloat(GetRandom(rightX-leftX)+leftX); - gi^.Y:= int2hwFloat(GetRandom(LAND_HEIGHT-topY)+topY); - gi^.dX:= _90-(GetRandomf*_360); - gi^.dY:= _90-(GetRandomf*_360) - end; - gi := gi^.NextGear - end - end; - if Gear^.Timer = 500 then begin (* Can't make sparkles team coloured without working out what the next team is going to be. This should be solved, really, since it also screws up @@ -2312,7 +2289,7 @@ HHGear^.State := HHGear^.State or gstNoDamage; DeleteCI(HHGear); - AmmoShove(Gear, 30, 115); + AmmoShove(Gear, Gear^.Boom, 115); HHGear^.State := (HHGear^.State and (not gstNoDamage)) or gstMoving; Gear^.Timer := 250; @@ -2332,7 +2309,7 @@ for i:= 0 to 3 do begin AddVisualGear(hwRound(Gear^.X) + hwSign(Gear^.dX) * (10 + 6 * i), hwRound(Gear^.Y) + 12 + Random(6), vgtDust); - AmmoShove(Gear, 30, 25); + AmmoShove(Gear, Gear^.Boom, 25); Gear^.X := Gear^.X + Gear^.dX * 5 end; @@ -2370,7 +2347,7 @@ Gear^.dY.QWordValue:= 429496730; Gear^.dX.isNegative:= getrandom(2)<>1; Gear^.dY.isNegative:= true; - AmmoShove(Gear, 2, 125); + AmmoShove(Gear, Gear^.Boom, 125); Gear^.dX:= tdX; Gear^.dY:= tdY; Gear^.Radius := 1 @@ -2449,7 +2426,7 @@ Gear^.dY.QWordValue:= 429496730; Gear^.dX.isNegative:= getrandom(2)<>1; Gear^.dY.isNegative:= true; - AmmoShove(Gear, 2, 125); + AmmoShove(Gear, Gear^.Boom, 125); Gear^.dX:= tdX; Gear^.dY:= tdY; Gear^.Radius := 1 @@ -2475,13 +2452,13 @@ Gear^.dY.QWordValue:= 429496730; Gear^.dX.isNegative:= getrandom(2)<>1; Gear^.dY.isNegative:= true; - AmmoShove(Gear, 6, 100); + AmmoShove(Gear, Gear^.Boom * 3, 100); Gear^.dX:= tdX; Gear^.dY:= tdY; Gear^.Radius := 1; end else if ((GameTicks and $3) = 3) then - doMakeExplosion(gX, gY, 8, Gear^.Hedgehog, 0);//, EXPLNoDamage); + doMakeExplosion(gX, gY, Gear^.Boom * 4, Gear^.Hedgehog, 0);//, EXPLNoDamage); //DrawExplosion(gX, gY, 4); if ((GameTicks and $7) = 0) and (Random(2) = 0) then @@ -2548,7 +2525,7 @@ DrawTunnel(HHGear^.X - int2hwFloat(cHHRadius), HHGear^.Y - _1, _0_5, _0, cHHRadius * 4+2, 2); HHGear^.State := HHGear^.State or gstNoDamage; Gear^.Y := HHGear^.Y; - AmmoShove(Gear, 30, 40); + AmmoShove(Gear, Gear^.Boom, 40); HHGear^.State := HHGear^.State and (not gstNoDamage) end; @@ -2734,7 +2711,7 @@ doStepFallingGear(Gear); if (Gear^.State and gstCollision) <> 0 then begin - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); DeleteGear(Gear); {$IFNDEF PAS2C} with mobileRecord do @@ -3009,7 +2986,7 @@ doStepFallingGear(Gear); if (Gear^.State and gstCollision) <> 0 then begin - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); gdX.isNegative := not gdX.isNegative; gdY.isNegative := not gdY.isNegative; gdX:= gdX*_0_2; @@ -3101,7 +3078,7 @@ Gear^.Pos := 2; end; - AmmoShove(Gear, 30, 40); + AmmoShove(Gear, Gear^.Boom, 40); DrawTunnel(HHGear^.X - HHGear^.dX * 10, HHGear^.Y - _2 - HHGear^.dY * 10 + hwAbs(HHGear^.dY) * 2, @@ -3115,7 +3092,7 @@ if Gear^.Health < Gear^.Damage then begin - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); if hasWishes then for i:= 0 to 31 do begin @@ -3186,7 +3163,7 @@ if Gear^.Tag < 2250 then exit; - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), cakeDmg, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); AfterAttack; DeleteGear(Gear) end; @@ -3510,10 +3487,7 @@ begin //out of time or exited ground StopSoundChan(Gear^.SoundChannel); - if (Gear^.State and gsttmpFlag) <> 0 then - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound) - else - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); DeleteGear(Gear); exit end @@ -3573,10 +3547,7 @@ else if (t <> nil) then begin //explode right on contact with HH - if (Gear^.State and gsttmpFlag) <> 0 then - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound) - else - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); DeleteGear(Gear); exit; end; @@ -3596,7 +3567,7 @@ dec(Gear^.Timer) else begin - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); DeleteGear(Gear); end end; @@ -3764,7 +3735,7 @@ if ((Gear^.State and gstCollision) <> 0) then begin - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, Gear^.Hedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound); for i:= 0 to 15 do begin dX := AngleCos(i * 64) * _0_5 * (GetRandomf + _1); @@ -4185,7 +4156,7 @@ if (Gear^.State and gstCollision) <> 0 then begin - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, Gear^.Hedgehog, EXPLPoisoned, $C0E0FFE0); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLPoisoned, $C0E0FFE0); PlaySound(sndEggBreak); AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEgg); vg := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEgg); @@ -4795,11 +4766,11 @@ end else if (Gear^.State and gstCollision) <> 0 then begin - r0 := GetRandom(21); - r1 := GetRandom(21); - doMakeExplosion(hwRound(Gear^.X) - 30 - r0, hwRound(Gear^.Y) + 40, 40 + r1, Gear^.Hedgehog, 0); - doMakeExplosion(hwRound(Gear^.X) + 30 + r1, hwRound(Gear^.Y) + 40, 40 + r0, Gear^.Hedgehog, 0); - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 80 + r0, Gear^.Hedgehog, EXPLAutoSound); + r0 := GetRandom(Gear^.Boom div 4 + 1); + r1 := GetRandom(Gear^.Boom div 4 + 1); + doMakeExplosion(hwRound(Gear^.X) - 30 - r0, hwRound(Gear^.Y) + 40, Gear^.Boom div 2 + r1, Gear^.Hedgehog, 0); + doMakeExplosion(hwRound(Gear^.X) + 30 + r1, hwRound(Gear^.Y) + 40, Gear^.Boom div 2 + r0, Gear^.Hedgehog, 0); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom + r0, Gear^.Hedgehog, EXPLAutoSound); for r0:= 0 to 4 do AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote); Gear^.dY := cGravity * 2 - odY; @@ -4933,7 +4904,7 @@ end; // kick nearby hogs - AmmoShove(Gear, 35, 50); + AmmoShove(Gear, Gear^.Boom, 50); dec(Gear^.Health, Gear^.Damage); @@ -5214,7 +5185,7 @@ Gear^.dX := Gear^.dX + cWindSpeed / 4; Gear^.dY := Gear^.dY + cGravity / 100; if (GameTicks and $FF) = 0 then - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLDontDraw or EXPLNoGfx or EXPLNoDamage or EXPLDoNotTouchAny or EXPLPoisoned); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLDontDraw or EXPLNoGfx or EXPLNoDamage or EXPLDoNotTouchAny or EXPLPoisoned); if Gear^.State and gstTmpFlag = 0 then AllInactive:= false; end; @@ -5253,18 +5224,13 @@ dmg:= (tmp^.Health - tmp^.Damage); if dmg > 0 then begin - // do 1/2 current hp worth of damage if extra damage is enabled (1/3 damage if not) - if cDamageModifier > _1 then - d:= 2 - else - d:= 3; - // always rounding down - dmg:= dmg div d; + dmg:= dmg div Gear^.Boom; if dmg > 0 then ApplyDamage(tmp, CurrentHedgehog, dmg, dsUnknown); end; + tmp^.dY:= _0_03 * Gear^.Boom end; if (tmp^.Kind <> gtHedgehog) or (dmg > 0) or (tmp^.Health > tmp^.Damage) then @@ -5534,6 +5500,7 @@ dec(Gear^.Timer) end; +(* //////////////////////////////////////////////////////////////////////////////// procedure doStepStructure(Gear: PGear); var @@ -5625,6 +5592,7 @@ doMakeExplosion(x, y, 50, CurrentHedgehog, EXPLAutoSound); end; end; +*) //////////////////////////////////////////////////////////////////////////////// (* @@ -6114,7 +6082,7 @@ end; end end; - +(* procedure doStepCreeper(Gear: PGear); var hogs: PGearArrayS; HHGear: PGear; @@ -6195,7 +6163,7 @@ end; end; end; - +*) //////////////////////////////////////////////////////////////////////////////// procedure doStepKnife(Gear: PGear); //var ox, oy: LongInt; @@ -6214,7 +6182,7 @@ DeleteCI(Gear); Gear^.Radius:= 7; // used for damage and impact calc. needs balancing I think - Gear^.Health:= hwRound(hwSqr((hwAbs(Gear^.dY)+hwAbs(Gear^.dX))*_4)); + Gear^.Health:= hwRound(hwSqr((hwAbs(Gear^.dY)+hwAbs(Gear^.dX))*Gear^.Boom/10000)); doStepFallingGear(Gear); AllInactive := false; a:= Gear^.DirAngle; diff -r b0c34402038c -r caa1e84c3ac2 hedgewars/uGearsHedgehog.pas --- a/hedgewars/uGearsHedgehog.pas Fri Jan 01 19:14:59 2016 +0300 +++ b/hedgewars/uGearsHedgehog.pas Fri Jan 01 19:15:32 2016 +0300 @@ -587,7 +587,7 @@ begin Gear^.Hedgehog^.Effects[heFrozen]:= 0; Gear^.State:= Gear^.State or gstNoDamage; - doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, CurrentHedgehog, EXPLAutoSound); + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, CurrentHedgehog, EXPLAutoSound); grave:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtGrave, 0, _0, _0, 0); grave^.Hedgehog:= Gear^.Hedgehog; grave^.Pos:= Gear^.uid; diff -r b0c34402038c -r caa1e84c3ac2 hedgewars/uGearsList.pas --- a/hedgewars/uGearsList.pas Fri Jan 01 19:14:59 2016 +0300 +++ b/hedgewars/uGearsList.pas Fri Jan 01 19:15:32 2016 +0300 @@ -215,6 +215,54 @@ gear^.Z:= cHHZ+1 else gear^.Z:= cUsualZ; +case Kind of + gtFlame: Gear^.Boom := 2; // some additional expl in there are x3, x4 this + gtHedgehog: Gear^.Boom := 30; + gtMine: Gear^.Boom := 50; + gtCase: Gear^.Boom := 25; + gtAirMine: Gear^.Boom := 25; + gtExplosives: Gear^.Boom := 75; + gtGrenade: Gear^.Boom := 50; + gtShell: Gear^.Boom := 50; + gtBee: Gear^.Boom := 50; + gtShotgunShot: Gear^.Boom := 25; + gtPickHammer: Gear^.Boom := 6; +// gtRope: Gear^.Boom := 2; could be funny to have rope attaching to hog deal small amount of dmg? + gtDEagleShot: Gear^.Boom := 7; + gtDynamite: Gear^.Boom := 75; + gtClusterBomb: Gear^.Boom := 20; + gtMelonPiece, + gtCluster: Gear^.Boom := Timer; + gtShover: Gear^.Boom := 30; + gtFirePunch: Gear^.Boom := 30; + gtAirBomb: Gear^.Boom := 30; + gtBlowTorch: Gear^.Boom := 2; + gtMortar: Gear^.Boom := 20; + gtWhip: Gear^.Boom := 30; + gtKamikaze: Gear^.Boom := 30; // both shove and explosion + gtCake: Gear^.Boom := cakeDmg; // why is cake damage a global constant + gtWatermelon: Gear^.Boom := 75; + gtHellishBomb: Gear^.Boom := 90; + gtDrill: if Gear^.State and gsttmpFlag = 0 then + Gear^.Boom := 50 + else Gear^.Boom := 30; + gtBall: Gear^.Boom := 40; + gtRCPlane: Gear^.Boom := 25; +// sniper rifle is distance linked, this Boom is just an arbitrary scaling factor applied to timer-based-damage +// because, eh, why not.. +gtSniperRifleShot: Gear^.Boom := 100000; + gtEgg: Gear^.Boom := 10; + gtPiano: Gear^.Boom := 80; + gtGasBomb: Gear^.Boom := 20; + gtSineGunShot: Gear^.Boom := 35; + gtSMine: Gear^.Boom := 30; + gtSnowball: Gear^.Boom := 200000; // arbitrary scaling for the shove + gtHammer: if cDamageModifier > _1 then // scale it based on cDamageModifier? + Gear^.Boom := 2 + else Gear^.Boom := 3; + gtPoisonCloud: Gear^.Boom := 20; + gtKnife: Gear^.Boom := 40000; // arbitrary scaling factor since impact-based + end; case Kind of gtGrenade, diff -r b0c34402038c -r caa1e84c3ac2 hedgewars/uGearsUtils.pas --- a/hedgewars/uGearsUtils.pas Fri Jan 01 19:14:59 2016 +0300 +++ b/hedgewars/uGearsUtils.pas Fri Jan 01 19:15:32 2016 +0300 @@ -927,13 +927,42 @@ AddFileLog('Assigned Gear coordinates (' + inttostr(x) + ',' + inttostr(y) + ')'); end end - else +else begin OutError('Can''t find place for Gear', false); if Gear^.Kind = gtHedgehog then - Gear^.Hedgehog^.Effects[heResurrectable] := 0; - DeleteGear(Gear); - Gear:= nil + begin + cnt:= 0; + if GameTicks = 0 then + begin + //AddFileLog('Trying to make a hole'); + while (cnt < 1000) do + begin + inc(cnt); + x:= leftX+GetRandom(rightX-leftX-32)+16; + y:= topY+GetRandom(LAND_HEIGHT-topY-64)+48; + if NoGearsToAvoid(x, y, 100 div max(1,cnt div 100), 100 div max(1,cnt div 100)) then + begin + Gear^.State:= Gear^.State or gsttmpFlag; + Gear^.X:= int2hwFloat(x); + Gear^.Y:= int2hwFloat(y); + AddFileLog('Picked a spot for hog at coordinates (' + inttostr(hwRound(Gear^.X)) + ',' + inttostr(hwRound(Gear^.Y)) + ')'); + cnt:= 2000 + end + end; + end; + if cnt < 2000 then + begin + Gear^.Hedgehog^.Effects[heResurrectable] := 0; + DeleteGear(Gear); + Gear:= nil + end + end + else + begin + DeleteGear(Gear); + Gear:= nil + end end end; @@ -1074,7 +1103,7 @@ if r-hwRound(dx+dy) > 0 then begin dist:= hwRound(Distance(dx, dy)); - dmg:= ModifyDamage(min(r - dist, 25), t); + dmg:= ModifyDamage(min(r - dist, Gear^.Boom), t); end; if dmg > 0 then begin @@ -1102,7 +1131,7 @@ if r-hwRound(dx+dy) > 0 then begin dist:= hwRound(Distance(dx, dy)); - dmg:= ModifyDamage(min(r - dist, 25), t); + dmg:= ModifyDamage(min(r - dist, Gear^.Boom), t); end; if dmg > 0 then begin diff -r b0c34402038c -r caa1e84c3ac2 hedgewars/uLand.pas --- a/hedgewars/uLand.pas Fri Jan 01 19:14:59 2016 +0300 +++ b/hedgewars/uLand.pas Fri Jan 01 19:15:32 2016 +0300 @@ -271,9 +271,9 @@ for x:= 0 to LAND_WIDTH - 1 do if Land[y, x] <> 0 then if (cReducedQuality and rqBlurryLand) = 0 then - LandPixels[y, x]:= p^[x] or AMask + LandPixels[y, x]:= p^[x]// or AMask else - LandPixels[y div 2, x div 2]:= p^[x] or AMask; + LandPixels[y div 2, x div 2]:= p^[x];// or AMask; p:= PLongwordArray(@(p^[Surface^.pitch div 4])); end; @@ -289,7 +289,7 @@ begin AddProgress(); - tmpsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, LAND_WIDTH, LAND_HEIGHT, 32, RMask, GMask, BMask, 0); + tmpsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, LAND_WIDTH, LAND_HEIGHT, 32, RMask, GMask, BMask, AMask); TryDo(tmpsurf <> nil, 'Error creating pre-land surface', true); ColorizeLand(tmpsurf); diff -r b0c34402038c -r caa1e84c3ac2 hedgewars/uScript.pas --- a/hedgewars/uScript.pas Fri Jan 01 19:14:59 2016 +0300 +++ b/hedgewars/uScript.pas Fri Jan 01 19:15:32 2016 +0300 @@ -921,29 +921,30 @@ lua_pushinteger(L, Integer(gear^.ImpactSound)); lua_pushinteger(L, gear^.nImpactSounds); lua_pushinteger(L, gear^.Tint); - lua_pushinteger(L, gear^.Damage) + lua_pushinteger(L, gear^.Damage); + lua_pushinteger(L, gear^.Boom) end else begin lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); - lua_pushnil(L); lua_pushnil(L) + lua_pushnil(L); lua_pushnil(L); lua_pushnil(L) end end else begin lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); - lua_pushnil(L); lua_pushnil(L) + lua_pushnil(L); lua_pushnil(L); lua_pushnil(L) end; - lc_getgearvalues:= 12 + lc_getgearvalues:= 13 end; function lc_setgearvalues(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin -// Currently allows 1-13 params -// if CheckLuaParamCount(L, 13, 'SetGearValues', 'gearUid, Angle, Power, WDTimer, Radius, Density, Karma, DirAngle, AdvBounce, ImpactSound, # ImpactSounds, Tint, Damage') then +// Currently allows 1-14 params +// if CheckLuaParamCount(L, 14, 'SetGearValues', 'gearUid, Angle, Power, WDTimer, Radius, Density, Karma, DirAngle, AdvBounce, ImpactSound, # ImpactSounds, Tint, Damage, Boom') then // begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then @@ -972,6 +973,8 @@ gear^.Tint := lua_tointeger(L, 12); if not lua_isnoneornil(L, 13) then gear^.Damage := lua_tointeger(L, 13); + if not lua_isnoneornil(L, 14) then + gear^.Boom := lua_tointeger(L, 14); end; // end // else diff -r b0c34402038c -r caa1e84c3ac2 hedgewars/uTeams.pas --- a/hedgewars/uTeams.pas Fri Jan 01 19:14:59 2016 +0300 +++ b/hedgewars/uTeams.pas Fri Jan 01 19:15:32 2016 +0300 @@ -127,7 +127,7 @@ if Gear <> nil then begin DeleteCI(Gear); - FindPlace(Gear, false, 0, LAND_WIDTH); + FindPlace(Gear, false, 0, LAND_WIDTH, true); if Gear <> nil then AddCI(Gear) end diff -r b0c34402038c -r caa1e84c3ac2 hedgewars/uTypes.pas --- a/hedgewars/uTypes.pas Fri Jan 01 19:14:59 2016 +0300 +++ b/hedgewars/uTypes.pas Fri Jan 01 19:15:32 2016 +0300 @@ -273,6 +273,7 @@ // DirAngle is a 'real' - if you do not need it for rotation of sprite in uGearsRender, you can use it for any visual-only value DirAngle: real; // These are frequently overridden to serve some other purpose + Boom: Longword; // amount of damage caused by the gear Pos: Longword; // Commonly overridden. Example use is posCase values in uConsts. Angle, Power : Longword; // Used for hog aiming/firing. Angle is rarely used as an Angle otherwise. Timer, WDTimer : LongWord; // Typically used for some sort of gear timer. Time to explosion, remaining fuel... diff -r b0c34402038c -r caa1e84c3ac2 hedgewars/uVariables.pas --- a/hedgewars/uVariables.pas Fri Jan 01 19:14:59 2016 +0300 +++ b/hedgewars/uVariables.pas Fri Jan 01 19:15:32 2016 +0300 @@ -621,7 +621,7 @@ (FileName: 'Egg'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil; Width: 16; Height: 16; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprEgg (FileName: 'TargetBee'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil; - Width: 32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprTargetBee + Width: 32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: true; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprTargetBee (FileName: 'amBee'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil; Width: 128; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprHandBee (FileName: 'Feather'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;