--- 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()
--- 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"},
--- 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)]
]
--- 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
"<h2><p align=center><a href=\"http://www.hedgewars.org/\">http://www.hedgewars.org/</a></p></h2>"
"<font color=yellow><h3 align=center>Hedgewars 0.9.22 is out! Please update.</h3><p align=center><a href=http://hedgewars.org/download.html>Download page here</a></font>"
51 -- latestReleaseVersion
--- 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
--- 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)
--- 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
(
--- 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
--- 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)
--- 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
--- 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);
--- 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
--- 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);
--- 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;
--- 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;
--- 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;
--- 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,
--- 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
--- 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);
--- 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
--- 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
--- 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...
--- 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;