# HG changeset patch # User sheepluva # Date 1446443888 -3600 # Node ID b14de8b741837b7025413c92015d1a0732dcea84 # Parent db1d14179b6cd37908aa8af5218a7172b498b187# Parent 4c4f22cc3fa4e6c1e5cd6cce35350dd93478415f merge default diff -r db1d14179b6c -r b14de8b74183 .hgtags --- a/.hgtags Mon Nov 02 06:23:46 2015 +0100 +++ b/.hgtags Mon Nov 02 06:58:08 2015 +0100 @@ -64,3 +64,6 @@ 7e55468ffe384a3065524c483eb5e3cdb1658fd5 0.9.21-release 7e55468ffe384a3065524c483eb5e3cdb1658fd5 fab746a3597e 0f5961910e2712582b162abd08ae3eed330cc978 Nice one +d9622394ec9c2974a84b9b4d9e6c0ac26c4060ff 0.9.22-RC +0f5961910e2712582b162abd08ae3eed330cc978 Nice one +0000000000000000000000000000000000000000 Nice one diff -r db1d14179b6c -r b14de8b74183 CMakeLists.txt --- a/CMakeLists.txt Mon Nov 02 06:23:46 2015 +0100 +++ b/CMakeLists.txt Mon Nov 02 06:58:08 2015 +0100 @@ -55,7 +55,7 @@ set(CPACK_PACKAGE_VERSION_MAJOR 0) set(CPACK_PACKAGE_VERSION_MINOR 9) set(CPACK_PACKAGE_VERSION_PATCH 22) -set(HEDGEWARS_PROTO_VER 50) +set(HEDGEWARS_PROTO_VER 51) set(HEDGEWARS_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") include(${CMAKE_MODULE_PATH}/revinfo.cmake) diff -r db1d14179b6c -r b14de8b74183 ChangeLog.txt --- a/ChangeLog.txt Mon Nov 02 06:23:46 2015 +0100 +++ b/ChangeLog.txt Mon Nov 02 06:58:08 2015 +0100 @@ -2,10 +2,11 @@ * bugfixes 0.9.21 -> 0.9.22 + + New Weapon / Map object: AirMine (floating mine that will follow nearby hedgehogs) + Extensive changes to TechRacer: Variable terrain types, enhanced parameters, hwmap interpreter, fuel limiter, etc. + Map previews can now take script parameters into account and preview waypoints in TechRacer + Added a couple new flags - + Small improvements to the interface and in-game chat + + Various tweaks to the interface and in-game chat + Divided teams options will now just be ignored when more/less than 2 teams, instead of displaying a fatal error + Added 6 TechRacer maps to TechMaps + Added 3 SpeedShoppa Challenges: Shoppa Love, Ropes and Crates, The Customer is King @@ -13,10 +14,20 @@ + Improved "Art" theme. * Generated bridges/girders are now connected better to the land mass * Fixed rubberband sprite + * Fixed Wind-Indicator being wrong in certain situations + * Melon Bomb Pieces now bounce on Rubberband + * Reduced menu music volume * The game will now fallback to default voicepack if a team's voicepack is not locally installed. (Instead of rendering team voiceless) * Hammer now does more damage when the Extra-Damage utility is used * Many other bug fixes +Lua-API: + + New map parameter: MapFeatureSize -- numeric representation of detail slider below map preview; use within onGameInit()/onPreviewInit() + + New function: SetMaxBuildDistance([ distInPx ]) -- specify how many pixels away a hedgehog can still place girders/etc. set to 0 for no limit; call with no param to reset to default + + New hook: onSuddenDeath() -- called by engine when sudden death begins + * Previously missing gear states are now available (gstSubmersible, gstFrozen and gstNoGravity) + * Fixed OnHogAttack giving the incorrect AmmoType (amNothing) under certain conditions + 0.9.20 -> 0.9.21: + New type of randomly generated maps: Perlin Maps. + Old Random generated maps are more diverse now. diff -r db1d14179b6c -r b14de8b74183 gameServer/Actions.hs --- a/gameServer/Actions.hs Mon Nov 02 06:23:46 2015 +0100 +++ b/gameServer/Actions.hs Mon Nov 02 06:58:08 2015 +0100 @@ -757,15 +757,15 @@ processAction (CheckFailed msg) = do - Just (CheckInfo fileName _) <- client's checkInfo + Just (CheckInfo fileName _ _) <- client's checkInfo io $ moveFailedRecord fileName processAction (CheckSuccess info) = do - Just (CheckInfo fileName teams) <- client's checkInfo + Just (CheckInfo fileName teams script) <- client's checkInfo p <- client's clientProto si <- gets serverInfo - io $ writeChan (dbQueries si) $ StoreAchievements p (B.pack fileName) (map toPair teams) info + io $ writeChan (dbQueries si) $ StoreAchievements p (B.pack fileName) (map toPair teams) script info io $ moveCheckedRecord fileName where toPair t = (teamname t, teamowner t) diff -r db1d14179b6c -r b14de8b74183 gameServer/CoreTypes.hs --- a/gameServer/CoreTypes.hs Mon Nov 02 06:23:46 2015 +0100 +++ b/gameServer/CoreTypes.hs Mon Nov 02 06:58:08 2015 +0100 @@ -119,7 +119,8 @@ CheckInfo { recordFileName :: String, - recordTeams :: [TeamInfo] + recordTeams :: [TeamInfo], + recordScript :: B.ByteString } data ClientInfo = @@ -345,7 +346,7 @@ CheckAccount ClientIndex Int B.ByteString B.ByteString | ClearCache | SendStats Int Int - | StoreAchievements Word16 B.ByteString [(B.ByteString, B.ByteString)] [B.ByteString] + | StoreAchievements Word16 B.ByteString [(B.ByteString, B.ByteString)] B.ByteString [B.ByteString] | GetReplayName ClientIndex Int B.ByteString deriving (Show, Read) diff -r db1d14179b6c -r b14de8b74183 gameServer/EngineInteraction.hs --- a/gameServer/EngineInteraction.hs Mon Nov 02 06:23:46 2015 +0100 +++ b/gameServer/EngineInteraction.hs Mon Nov 02 06:58:08 2015 +0100 @@ -100,8 +100,8 @@ -> Map.Map B.ByteString B.ByteString -> Map.Map B.ByteString [B.ByteString] -> [B.ByteString] - -> [B.ByteString] -replayToDemo ti mParams prms msgs = if not sane then [] else concat [ + -> ([B.ByteString], [B.ByteString]) +replayToDemo ti mParams prms msgs = if not sane then ([], []) else ([scriptName], concat [ [em "TD"] , maybeScript , maybeMap @@ -117,7 +117,7 @@ , concatMap teamSetup ti , msgs , [em "!"] - ] + ]) where keys1, keys2 :: Set.Set B.ByteString keys1 = Set.fromList ["FEATURE_SIZE", "MAP", "MAPGEN", "MAZE_SIZE", "SEED", "TEMPLATE"] @@ -127,7 +127,8 @@ && (not . null . drop 41 $ scheme) && (not . null . tail $ prms Map.! "AMMO") mapGenTypes = ["+rnd+", "+maze+", "+drawn+", "+perlin+"] - maybeScript = let s = head . fromMaybe ["Normal"] $ Map.lookup "SCRIPT" prms in if s == "Normal" then [] else [eml ["escript Scripts/Multiplayer/", s, ".lua"]] + scriptName = head . fromMaybe ["Normal"] $ Map.lookup "SCRIPT" prms + maybeScript = let s = scriptName in if s == "Normal" then [] else [eml ["escript Scripts/Multiplayer/", s, ".lua"]] maybeMap = let m = mParams Map.! "MAP" in if m `elem` mapGenTypes then [] else [eml ["emap ", m]] scheme = tail $ prms Map.! "SCHEME" mapgen = mParams Map.! "MAPGEN" diff -r db1d14179b6c -r b14de8b74183 gameServer/OfficialServer/GameReplayStore.hs --- a/gameServer/OfficialServer/GameReplayStore.hs Mon Nov 02 06:23:46 2015 +0100 +++ b/gameServer/OfficialServer/GameReplayStore.hs Mon Nov 02 06:58:08 2015 +0100 @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. \-} -{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE ScopedTypeVariables, OverloadedStrings #-} module OfficialServer.GameReplayStore where import Data.Time @@ -70,11 +70,12 @@ where loadFile :: String -> IO (Maybe CheckInfo, [B.ByteString]) loadFile fileName = E.handle (\(e :: SomeException) -> - warningM "REPLAYS" ("Problems reading " ++ fileName ++ ": " ++ show e) >> return (Just $ CheckInfo fileName [], [])) $ do + warningM "REPLAYS" ("Problems reading " ++ fileName ++ ": " ++ show e) >> return (Just $ CheckInfo fileName [] "", [])) $ do (teams, params1, params2, roundMsgs) <- liftM read $ readFile fileName - return $ ( - Just (CheckInfo fileName teams) - , let d = replayToDemo teams (Map.fromList params1) (Map.fromList params2) (reverse roundMsgs) in d `deepseq` d + let d = replayToDemo teams (Map.fromList params1) (Map.fromList params2) (reverse roundMsgs) + d `deepseq` return $ ( + Just (CheckInfo fileName teams (head $ fst d)) + , snd d ) moveFailedRecord :: String -> IO () diff -r db1d14179b6c -r b14de8b74183 gameServer/OfficialServer/extdbinterface.hs --- a/gameServer/OfficialServer/extdbinterface.hs Mon Nov 02 06:23:46 2015 +0100 +++ b/gameServer/OfficialServer/extdbinterface.hs Mon Nov 02 06:58:08 2015 +0100 @@ -50,6 +50,9 @@ \ VALUES (?, (SELECT id FROM achievement_types WHERE name = ?), (SELECT uid FROM users WHERE name = ?), \ \ ?, ?, ?, ?)" +dbQueryGamesHistory = + "? ? ?" + dbQueryReplayFilename = "SELECT filename FROM achievements WHERE id = ?" @@ -83,8 +86,8 @@ SendStats clients rooms -> void $ execute dbConn dbQueryStats (clients, rooms) - StoreAchievements p fileName teams info -> - mapM_ (execute dbConn dbQueryAchievement) $ (parseStats p fileName teams) info + StoreAchievements p fileName teams script info -> + mapM_ (uncurry (execute dbConn)) $ parseStats p fileName teams script info --readTime = read . B.unpack . B.take 19 . B.drop 8 @@ -94,15 +97,16 @@ Word16 -> B.ByteString -> [(B.ByteString, B.ByteString)] - -> [B.ByteString] - -> [(B.ByteString, B.ByteString, B.ByteString, Int, B.ByteString, B.ByteString, Int)] -parseStats p fileName teams = ps + -> B.ByteString + -> [B.ByteString] + -> [(Query, (B.ByteString, B.ByteString, B.ByteString, Int, B.ByteString, B.ByteString, Int))] +parseStats p fileName teams script = ps where time = readTime fileName ps [] = [] ps ("DRAW" : bs) = ps bs ps ("WINNERS" : n : bs) = ps $ drop (readInt_ n) bs - ps ("ACHIEVEMENT" : typ : teamname : location : value : bs) = + ps ("ACHIEVEMENT" : typ : teamname : location : value : bs) = (dbQueryAchievement, ( time , typ , fromMaybe "" (lookup teamname teams) @@ -110,7 +114,7 @@ , fileName , location , fromIntegral p - ) : ps bs + )) : ps bs ps (b:bs) = ps bs diff -r db1d14179b6c -r b14de8b74183 hedgewars/uGears.pas --- a/hedgewars/uGears.pas Mon Nov 02 06:23:46 2015 +0100 +++ b/hedgewars/uGears.pas Mon Nov 02 06:58:08 2015 +0100 @@ -320,6 +320,7 @@ Ammoz[amTardis].Probability:= 0; end; AddCaption(trmsg[sidSuddenDeath], cWhiteColor, capgrpGameState); + ScriptCall('onSuddenDeath'); playSound(sndSuddenDeath); StopMusic; if SDMusicFN <> '' then PlayMusic diff -r db1d14179b6c -r b14de8b74183 hedgewars/uGearsHandlersMess.pas --- a/hedgewars/uGearsHandlersMess.pas Mon Nov 02 06:23:46 2015 +0100 +++ b/hedgewars/uGearsHandlersMess.pas Mon Nov 02 06:58:08 2015 +0100 @@ -2675,7 +2675,7 @@ //4: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtWaterMelon, 0, cBombsSpeed * // Gear^.Tag, _0, 5000); end; - Gear^.dX := Gear^.dX + int2hwFloat(30 * Gear^.Tag); + Gear^.dX := Gear^.dX + int2hwFloat(Gear^.Damage * Gear^.Tag); if CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y)) then FollowGear^.State:= FollowGear^.State or gstSubmersible; StopSoundChan(Gear^.SoundChannel, 4000); @@ -2708,7 +2708,7 @@ end; Gear^.Y := int2hwFloat(topY-300); - Gear^.dX := int2hwFloat(Gear^.Target.X - 5 * Gear^.Tag * 15); + Gear^.dX := int2hwFloat(Gear^.Target.X) - int2hwFloat(Gear^.Tag * Gear^.Health * Gear^.Damage) / 2; // calcs for Napalm Strike, so that it will hit the target (without wind at least :P) if (Gear^.State = 2) then @@ -2718,7 +2718,6 @@ Gear^.dX := Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(Gear^.Target.Y) - Gear^.Y) * 2 / cGravity) * Gear^.Tag; - Gear^.Health := 6; Gear^.doStep := @doStepAirAttackWork; Gear^.SoundChannel := LoopSound(sndPlane, 4000); @@ -5198,7 +5197,9 @@ //////////////////////////////////////////////////////////////////////////////// procedure doStepPoisonCloud(Gear: PGear); begin - WorldWrap(Gear); + // don't bounce + if WorldEdge <> weBounce then + WorldWrap(Gear); if Gear^.Timer = 0 then begin DeleteGear(Gear); @@ -5430,7 +5431,7 @@ for i:= 0 to graves.size - 1 do if graves.ar^[i]^.Health > 0 then begin - resgear := AddGear(hwRound(graves.ar^[i]^.X), hwRound(graves.ar^[i]^.Y), gtHedgehog, gstWait, _0, _0, 0); + resgear := AddGear(hwRound(graves.ar^[i]^.X), hwRound(graves.ar^[i]^.Y), gtHedgehog, gstWait, _0, _0, 0,graves.ar^[i]^.Pos); resgear^.Hedgehog := graves.ar^[i]^.Hedgehog; resgear^.Health := graves.ar^[i]^.Health; PHedgehog(graves.ar^[i]^.Hedgehog)^.Gear := resgear; @@ -5792,9 +5793,16 @@ All these effects assume the ray's angle is not changed and that the target type was unchanged over a number of ticks. This is a simplifying assumption for "gun was applying freezing effect to the same target". * When fired at water a layer of ice textured land is added above the water. * When fired at non-ice land (land and lfLandMask and not lfIce) the land is overlaid with a thin layer of ice textured land around that point (say, 1 or 2px into land, 1px above). For attractiveness, a slope would probably be needed. - * When fired at a hog (land and $00FF <> 0), while the hog is targetted, the hog's state is set to frozen. As long as the gun is on the hog, a frozen hog sprite creeps up from the feet to the head. If the effect is interrupted before reaching the top, the freezing state is cleared. -A frozen hog will animate differently. To be decided, but possibly in a similar fashion to a grave when it comes to explosions. The hog might (possibly) not be damaged by explosions. This might make freezing potentially useful for friendlies in a bad position. It might be better to allow damage though. -A frozen hog stays frozen for a certain number of turns. Each turn the frozen overlay becomes fainter, until it fades and the hog animates normally again. + * When fired at a hog (land and $00FF <> 0), while the hog is targetted, the hog's state is set to frozen. + As long as the gun is on the hog, a frozen hog sprite creeps up from the feet to the head. + If the effect is interrupted before reaching the top, the freezing state is cleared. +A frozen hog will animate differently. + To be decided, but possibly in a similar fashion to a grave when it comes to explosions. + The hog might (possibly) not be damaged by explosions. + This might make freezing potentially useful for friendlies in a bad position. + It might be better to allow damage though. +A frozen hog stays frozen for a certain number of turns. + Each turn the frozen overlay becomes fainter, until it fades and the hog animates normally again. *) diff -r db1d14179b6c -r b14de8b74183 hedgewars/uGearsHandlersRope.pas --- a/hedgewars/uGearsHandlersRope.pas Mon Nov 02 06:23:46 2015 +0100 +++ b/hedgewars/uGearsHandlersRope.pas Mon Nov 02 06:58:08 2015 +0100 @@ -42,7 +42,8 @@ OutError('ERROR: doStepRopeAfterAttack called while HHGear = nil', IsNilHHFatal); DeleteGear(Gear); exit() - end; + end + else if not CurrentTeam^.ExtDriven then FollowGear := HHGear; tX:= HHGear^.X; if WorldWrap(HHGear) and (WorldEdge = weWrap) and @@ -137,7 +138,8 @@ OutError('ERROR: doStepRopeWork called while HHGear = nil', IsNilHHFatal); DeleteGear(Gear); exit() - end; + end + else if not CurrentTeam^.ExtDriven then FollowGear := HHGear; if ((HHGear^.State and gstHHDriven) = 0) or (CheckGearDrowning(HHGear)) or (Gear^.PortalCounter <> 0) then @@ -425,6 +427,7 @@ HHGear: PGear; tx, ty, tt: hwFloat; begin + Gear^.X := Gear^.X - Gear^.dX; Gear^.Y := Gear^.Y - Gear^.dY; Gear^.Elasticity := Gear^.Elasticity + _1; @@ -435,7 +438,8 @@ OutError('ERROR: doStepRopeAttach called while HHGear = nil', IsNilHHFatal); DeleteGear(Gear); exit() - end; + end + else if not CurrentTeam^.ExtDriven then FollowGear := HHGear; DeleteCI(HHGear); diff -r db1d14179b6c -r b14de8b74183 hedgewars/uGearsHedgehog.pas --- a/hedgewars/uGearsHedgehog.pas Mon Nov 02 06:23:46 2015 +0100 +++ b/hedgewars/uGearsHedgehog.pas Mon Nov 02 06:58:08 2015 +0100 @@ -451,7 +451,7 @@ if CurAmmoType = amAirMine then newGear^.Hedgehog:= nil; if ((CurAmmoType = amMine) or (CurAmmoType = amSMine) or (CurAmmoType = amAirMine)) and (GameFlags and gfInfAttack <> 0) then - newGear^.FlightTime:= GameTicks + 1000 + newGear^.FlightTime:= GameTicks + min(TurnTimeLeft,1000) else if CurAmmoType = amDrill then newGear^.FlightTime:= GameTicks + 250; if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then @@ -572,6 +572,7 @@ procedure doStepHedgehogDead(Gear: PGear); const frametime = 200; timertime = frametime * 6; +var grave: PGear; begin if Gear^.Hedgehog^.Unplaced then exit; @@ -587,7 +588,10 @@ Gear^.Hedgehog^.Effects[heFrozen]:= 0; Gear^.State:= Gear^.State or gstNoDamage; doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, CurrentHedgehog, EXPLAutoSound); - AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtGrave, 0, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog; + grave:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtGrave, 0, _0, _0, 0); + grave^.Hedgehog:= Gear^.Hedgehog; + grave^.Pos:= Gear^.uid; + DeleteGear(Gear); SetAllToActive end diff -r db1d14179b6c -r b14de8b74183 hedgewars/uGearsList.pas --- a/hedgewars/uGearsList.pas Mon Nov 02 06:23:46 2015 +0100 +++ b/hedgewars/uGearsList.pas Mon Nov 02 06:58:08 2015 +0100 @@ -23,6 +23,7 @@ uses uFloat, uTypes, SDLh; function AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear; +function AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer, newUid: LongWord): PGear; procedure DeleteGear(Gear: PGear); procedure InsertGearToList(Gear: PGear); procedure RemoveGearFromList(Gear: PGear); @@ -164,11 +165,16 @@ function AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear; +begin +AddGear:= AddGear(X, Y, Kind, State, dX, dY, Timer, 0); +end; +function AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer, newUid: LongWord): PGear; var gear: PGear; //c: byte; cakeData: PCakeData; begin -inc(GCounter); +if newUid = 0 then + inc(GCounter); AddFileLog('AddGear: #' + inttostr(GCounter) + ' (' + inttostr(x) + ',' + inttostr(y) + '), d(' + floattostr(dX) + ',' + floattostr(dY) + ') type = ' + EnumToStr(Kind)); @@ -186,7 +192,9 @@ gear^.doStep:= doStepHandlers[Kind]; gear^.CollisionIndex:= -1; gear^.Timer:= Timer; -gear^.uid:= GCounter; +if newUid = 0 then + gear^.uid:= GCounter +else gear^.uid:= newUid; gear^.SoundChannel:= -1; gear^.ImpactSound:= sndNone; gear^.Density:= _1; @@ -466,6 +474,8 @@ gear^.Tag:= Y end; gtAirAttack: begin + gear^.Health:= 6; + gear^.Damage:= 30; gear^.Z:= cHHZ+2; gear^.Tint:= gear^.Hedgehog^.Team^.Clan^.Color shl 8 or $FF end; diff -r db1d14179b6c -r b14de8b74183 hedgewars/uGearsRender.pas --- a/hedgewars/uGearsRender.pas Mon Nov 02 06:23:46 2015 +0100 +++ b/hedgewars/uGearsRender.pas Mon Nov 02 06:58:08 2015 +0100 @@ -728,7 +728,7 @@ amHellishBomb: DrawSpriteRotated(sprHandHellish, hx, hy, sign, aangle); amGasBomb: DrawSpriteRotated(sprHandCheese, hx, hy, sign, aangle); amMine: DrawSpriteRotated(sprHandMine, hx, hy, sign, aangle); - amAirMine: DrawSpriteRotated(sprHandMine, hx, hy, sign, aangle); + amAirMine: DrawSpriteRotated(sprHandAirMine, hx, hy, sign, aangle); amSMine: DrawSpriteRotated(sprHandSMine, hx, hy, sign, aangle); amKnife: DrawSpriteRotatedF(sprHandKnife, hx, hy, 0, sign, aangle); amSeduction: begin diff -r db1d14179b6c -r b14de8b74183 hedgewars/uGearsUtils.pas --- a/hedgewars/uGearsUtils.pas Mon Nov 02 06:23:46 2015 +0100 +++ b/hedgewars/uGearsUtils.pas Mon Nov 02 06:58:08 2015 +0100 @@ -829,7 +829,7 @@ procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean); var x: LongInt; - y, sy: LongInt; + y, sy, dir: LongInt; ar: array[0..1023] of TPoint; ar2: array[0..2047] of TPoint; temp: TPoint; @@ -850,9 +850,10 @@ delta:= LAND_WIDTH div 16; cnt2:= 0; repeat - x:= Left + max(LAND_WIDTH div 2048, LongInt(GetRandom(Delta))); + if GetRandom(2) = 0 then dir:= -1 else dir:= 1; + x:= max(LAND_WIDTH div 2048, LongInt(GetRandom(Delta))); + if dir = 1 then x:= Left + x else x:= Right - x; repeat - inc(x, Delta); cnt:= 0; y:= min(1024, topY) - Gear^.Radius shl 1; while y < cWaterLine do @@ -901,9 +902,10 @@ ar2[cnt2].x:= x; ar2[cnt2].y:= y; inc(cnt2) - end - end - until (x + Delta > Right); + end; + end; + inc(x, Delta*dir) + until ((dir = 1) and (x > Right)) or ((dir = -1) and (x < Left)); dec(Delta, 60) until (cnt2 > 0) or (Delta < 70); diff -r db1d14179b6c -r b14de8b74183 hedgewars/uScript.pas --- a/hedgewars/uScript.pas Mon Nov 02 06:23:46 2015 +0100 +++ b/hedgewars/uScript.pas Mon Nov 02 06:58:08 2015 +0100 @@ -629,7 +629,9 @@ begin gear := SpawnFakeCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), HealthCrate, lua_toboolean(L, 3), lua_toboolean(L, 4)); - lua_pushinteger(L, gear^.uid); + if gear <> nil then + lua_pushinteger(L, gear^.uid) + else lua_pushnil(L) end else lua_pushnil(L); @@ -643,7 +645,9 @@ begin gear := SpawnFakeCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), AmmoCrate, lua_toboolean(L, 3), lua_toboolean(L, 4)); - lua_pushinteger(L, gear^.uid); + if gear <> nil then + lua_pushinteger(L, gear^.uid) + else lua_pushnil(L) end else lua_pushnil(L); @@ -657,7 +661,9 @@ begin gear := SpawnFakeCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), UtilityCrate, lua_toboolean(L, 3), lua_toboolean(L, 4)); - lua_pushinteger(L, gear^.uid); + if gear <> nil then + lua_pushinteger(L, gear^.uid) + else lua_pushnil(L) end else lua_pushnil(L); @@ -676,9 +682,8 @@ health:= cHealthCaseAmount; gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), HealthCrate, health, 0); if gear <> nil then - lua_pushinteger(L, gear^.uid) - else - lua_pushnil(L); + lua_pushinteger(L, gear^.uid) + else lua_pushnil(L); end else lua_pushnil(L); @@ -695,9 +700,8 @@ gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), AmmoCrate, lua_tointeger(L, 3), 0) else gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), AmmoCrate, lua_tointeger(L, 3), lua_tointeger(L, 4)); if gear <> nil then - lua_pushinteger(L, gear^.uid) - else - lua_pushnil(L); + lua_pushinteger(L, gear^.uid) + else lua_pushnil(L); end else lua_pushnil(L); @@ -714,9 +718,8 @@ gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), UtilityCrate, lua_tointeger(L, 3), 0) else gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), UtilityCrate, lua_tointeger(L, 3), lua_tointeger(L, 4)); if gear <> nil then - lua_pushinteger(L, gear^.uid) - else - lua_pushnil(L); + lua_pushinteger(L, gear^.uid) + else lua_pushnil(L); end else lua_pushnil(L); @@ -918,29 +921,30 @@ lua_pushinteger(L, gear^.AdvBounce); lua_pushinteger(L, Integer(gear^.ImpactSound)); lua_pushinteger(L, gear^.nImpactSounds); - lua_pushinteger(L, gear^.Tint) + lua_pushinteger(L, gear^.Tint); + lua_pushinteger(L, gear^.Damage) 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) 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) end; - lc_getgearvalues:= 11 + lc_getgearvalues:= 12 end; function lc_setgearvalues(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin -// Currently allows 1-12 params -// if CheckLuaParamCount(L, 12, 'SetGearValues', 'gearUid, Angle, Power, WDTimer, Radius, Density, Karma, DirAngle, AdvBounce, ImpactSound, # ImpactSounds, Tint') then +// Currently allows 1-13 params +// if CheckLuaParamCount(L, 13, 'SetGearValues', 'gearUid, Angle, Power, WDTimer, Radius, Density, Karma, DirAngle, AdvBounce, ImpactSound, # ImpactSounds, Tint, Damage') then // begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then @@ -966,7 +970,9 @@ if not lua_isnoneornil(L, 11) then gear^.nImpactSounds := lua_tointeger(L, 11); if not lua_isnoneornil(L, 12) then - gear^.Tint := lua_tointeger(L, 12) + gear^.Tint := lua_tointeger(L, 12); + if not lua_isnoneornil(L, 13) then + gear^.Damage := lua_tointeger(L, 13); end; // end // else @@ -2907,6 +2913,12 @@ procedure GetGlobals; begin +// TODO +// Use setters instead, because globals should be read-only! +// Otherwise globals might be changed by Lua, but then unexpectatly overwritten by engine when a ScriptCall is triggered by whatever Lua is doing! +// Sure, one could work around that in engine (e.g. by setting writable globals in SetGlobals only when their engine-side value has actually changed since SetGlobals was called the last time...), but things just get messier and messier then. +// It is inconsistent anyway to have some globals be read-only and others not with no indication whatsoever. +// -- sheepluva TurnTimeLeft:= ScriptGetInteger('TurnTimeLeft'); end; diff -r db1d14179b6c -r b14de8b74183 hedgewars/uTeams.pas --- a/hedgewars/uTeams.pas Mon Nov 02 06:23:46 2015 +0100 +++ b/hedgewars/uTeams.pas Mon Nov 02 06:58:08 2015 +0100 @@ -604,7 +604,6 @@ SplitBySpace(s, cs); SplitBySpace(cs, ts); Color:= StrToInt(cs); - TryDo(Color <> 0, 'Error: black team color', true); // color is always little endian so the mask must be constant also in big endian archs Color:= Color or $FF000000; diff -r db1d14179b6c -r b14de8b74183 hedgewars/uTypes.pas --- a/hedgewars/uTypes.pas Mon Nov 02 06:23:46 2015 +0100 +++ b/hedgewars/uTypes.pas Mon Nov 02 06:58:08 2015 +0100 @@ -88,7 +88,7 @@ sprBulletHit, sprSnowball, sprHandSnowball, sprSnow, sprSDFlake, sprSDWater, sprSDCloud, sprSDSplash, sprSDDroplet, sprTardis, sprSlider, sprBotlevels, sprHandKnife, sprKnife, sprStar, sprIceTexture, sprIceGun, - sprFrozenHog, sprAmRubber, sprBoing, sprCustom1, sprCustom2, sprAirMine + sprFrozenHog, sprAmRubber, sprBoing, sprCustom1, sprCustom2, sprAirMine, sprHandAirMine ); // Gears that interact with other Gears and/or Land diff -r db1d14179b6c -r b14de8b74183 hedgewars/uVariables.pas --- a/hedgewars/uVariables.pas Mon Nov 02 06:23:46 2015 +0100 +++ b/hedgewars/uVariables.pas Mon Nov 02 06:58:08 2015 +0100 @@ -722,7 +722,9 @@ (FileName: 'custom2'; Path: ptCurrTheme;AltPath: ptGraphics; Texture: nil; Surface: nil; Width: 0; Height: 0; imageWidth: 0; imageHeight: 0; saveSurf: true; priority: tpLow; getDimensions: true; getImageDimensions: true), // sprCustom2 (FileName: 'AirMine'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil; - Width: 32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHighest; getDimensions: false; getImageDimensions: true)// sprAirMine + Width: 32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHighest; getDimensions: false; getImageDimensions: true), // sprAirMine + (FileName: 'amAirMine'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil; + Width: 64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true) // sprHandAirMine ); const diff -r db1d14179b6c -r b14de8b74183 share/hedgewars/Data/Graphics/Hedgehog/amAirMine.png Binary file share/hedgewars/Data/Graphics/Hedgehog/amAirMine.png has changed diff -r db1d14179b6c -r b14de8b74183 share/hedgewars/Data/Locale/tips_en.xml --- a/share/hedgewars/Data/Locale/tips_en.xml Mon Nov 02 06:23:46 2015 +0100 +++ b/share/hedgewars/Data/Locale/tips_en.xml Mon Nov 02 06:58:08 2015 +0100 @@ -11,7 +11,7 @@ <tip>You're bored of default gameplay? Try one of the missions — they'll offer different gameplay depending on the one you picked.</tip> <tip>By default the game will always record the last game played as a demo. Select “Local Game” and pick the “Demos” button on the lower right corner to play or manage them.</tip> <tip>Hedgewars is free software (Open Source) we create in our spare time. If you’ve got problems, ask on our forums or visit our IRC room!</tip> - <tip>Hedgewars is free software (Open Source) we create in our spare time. If you like it, help us with a small donation or contribute your own work!</tip> + <tip>Hedgewars is free software (Open Source) we create in our spare time. If you like it, feel free to help us with a small donation or contribute your own work!</tip> <tip>Hedgewars is free software (Open Source) we create in our spare time. Share it with your family and friends as you like!</tip> <tip>Hedgewars is free software (Open Source) we create in our spare time, just for fun! Meet the devs in <a href="irc://irc.freenode.net/hedgewars">#hedgewars</a>!</tip> <tip>From time to time there will be official tournaments. Upcoming events will be announced at <a href="http://www.hedgewars.org/">http://www.hedgewars.org/</a> some days in advance.</tip> @@ -19,14 +19,13 @@ <tip>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and GNU/Linux.</tip> <tip>Always remember you’re able to set up your own games in local and network/online play. You’re not restricted to the “Simple Game” option.</tip> <tip>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</tip> - <tip>Create an account on <a href="http://www.hedgewars.org/">http://www.hedgewars.org/</a> to keep others from using your most favourite nickname while playing on the official server.</tip> - <tip>While playing you should give yourself a short break at least once an hour.</tip> + <tip>Consider giving yourself a short break at least once an hour to guard against strain from playing.</tip> <tip>If your graphics card isn’t able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</tip> <tip>If your graphics card isn’t able to provide hardware accelerated OpenGL, try to update the associated drivers.</tip> <tip>We’re open to suggestions and constructive feedback. If you don’t like something or got a great idea, let us know!</tip> - <tip>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</tip> + <tip>For your own benefit we'd like you to be polite and friendly while playing on our server. Also please keep in mind that some players are minors!</tip> <tip>Special game modes such as “Vampirism” or “Karma” allow you to develop completely new tactics. Try them in a custom game!</tip> - <tip>You should never install Hedgewars on computers you don’t own (school, university, work, etc.). Please ask the responsible person instead!</tip> + <tip>Please don't install Hedgewars on computers you don’t own (school, university, work, etc.) unless you got permission. We don't want you to get into any trouble.</tip> <tip>Hedgewars can be perfect for short games during breaks. Just ensure you don’t add too many hedgehogs or use an huge map. Reducing time and health might help as well.</tip> <tip>No hedgehogs were harmed in making this game.</tip> <tip>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</tip> diff -r db1d14179b6c -r b14de8b74183 share/hedgewars/Data/Maps/Basketball/map.lua --- a/share/hedgewars/Data/Maps/Basketball/map.lua Mon Nov 02 06:23:46 2015 +0100 +++ b/share/hedgewars/Data/Maps/Basketball/map.lua Mon Nov 02 06:58:08 2015 +0100 @@ -54,3 +54,7 @@ end end end + +function onNewTurn() + SetWeapon(amBaseballBat) +end diff -r db1d14179b6c -r b14de8b74183 share/hedgewars/Data/Maps/Knockball/map.lua --- a/share/hedgewars/Data/Maps/Knockball/map.lua Mon Nov 02 06:23:46 2015 +0100 +++ b/share/hedgewars/Data/Maps/Knockball/map.lua Mon Nov 02 06:58:08 2015 +0100 @@ -68,3 +68,7 @@ end end end + +function onNewTurn() + SetWeapon(amBaseballBat) +end diff -r db1d14179b6c -r b14de8b74183 share/hedgewars/Data/Maps/TrophyRace/map.lua --- a/share/hedgewars/Data/Maps/TrophyRace/map.lua Mon Nov 02 06:23:46 2015 +0100 +++ b/share/hedgewars/Data/Maps/TrophyRace/map.lua Mon Nov 02 06:58:08 2015 +0100 @@ -33,6 +33,7 @@ local worsthog = nil local besthog = nil +local besthogname = '' -- best time local besttime = maxtime + 1 @@ -78,7 +79,8 @@ SetHealth(CurrentHedgehog, 0) SetEffect(CurrentHedgehog, heInvulnerable, 0) x, y = GetGearPosition(CurrentHedgehog) - AddGear(x, y, gtShell, 0, 0, 0, 0) + AddGear(x, y-2, gtGrenade, 0, 0, 0, 2) + SetGearVelocity(CurrentHedgehog, 0, 0) worsttime = 99999 worsthog = nil lasthog = nil @@ -141,6 +143,7 @@ if ttime < besttime then besttime = ttime besthog = CurrentHedgehog + besthogname = GetHogName(besthog) hscore = hscore .. loc("NEW fastest lap: ") else hscore = hscore .. loc("Fastest lap: ") @@ -149,7 +152,7 @@ worsttime = ttime worsthog = CurrentHedgehog end - hscore = hscore .. GetHogName(besthog) .. " - " .. (besttime / 1000) .. " s | |" .. loc("Best laps per team: ") + hscore = hscore .. besthogname .. " - " .. (besttime / 1000) .. " s | |" .. loc("Best laps per team: ") if clan == ClansCount -1 then -- Time for elimination - worst hog is out and the worst hog vars are reset.