# 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 @@ You're bored of default gameplay? Try one of the missions — they'll offer different gameplay depending on the one you picked. 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. 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! - 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! + 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! Hedgewars is free software (Open Source) we create in our spare time. Share it with your family and friends as you like! Hedgewars is free software (Open Source) we create in our spare time, just for fun! Meet the devs in #hedgewars! From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance. @@ -19,14 +19,13 @@ Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and GNU/Linux. 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. Connect one or more gamepads before starting the game to be able to assign their controls to your teams. - Create an account on http://www.hedgewars.org/ to keep others from using your most favourite nickname while playing on the official server. - While playing you should give yourself a short break at least once an hour. + Consider giving yourself a short break at least once an hour to guard against strain from playing. If your graphics card isn’t able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance. If your graphics card isn’t able to provide hardware accelerated OpenGL, try to update the associated drivers. We’re open to suggestions and constructive feedback. If you don’t like something or got a great idea, let us know! - Especially while playing online be polite and always remember there might be some minors playing with or against you as well! + 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! Special game modes such as “Vampirism” or “Karma” allow you to develop completely new tactics. Try them in a custom game! - You should never install Hedgewars on computers you don’t own (school, university, work, etc.). Please ask the responsible person instead! + 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. 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. No hedgehogs were harmed in making this game. There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump. 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.