From 699dd2ff1540c2fcda2b9f8cf9765e94c86ce6ba Mon Sep 17 00:00:00 2001 From: feber <> Date: Sun, 24 Oct 2004 06:49:11 +0000 Subject: [PATCH] New Lua map format: map presentation. --- doc/ChangeLog.html | 5 +- doc/scripts/index.html | 8 +- doc/scripts/mappresentation.html | 50 ++++---- src/editor/editloop.cpp | 42 +++---- src/game/campaign.cpp | 3 +- src/game/game.cpp | 18 ++- src/game/savegame.cpp | 2 +- src/include/map.h | 4 +- src/include/menus.h | 1 - src/include/pud.h | 2 +- src/map/map.cpp | 6 +- src/map/map_save.cpp | 2 +- src/map/script_map.cpp | 49 ++++++-- src/network/commands.cpp | 2 +- src/network/netconnect.cpp | 40 +++---- src/stratagus/pud.cpp | 44 +++---- src/stratagus/stratagus.cpp | 8 +- src/ui/menus.cpp | 198 ++++++++++++++++--------------- src/ui/script_ui.cpp | 35 ++++++ 19 files changed, 306 insertions(+), 213 deletions(-) diff --git a/doc/ChangeLog.html b/doc/ChangeLog.html index a73b9740a..2193022b4 100644 --- a/doc/ChangeLog.html +++ b/doc/ChangeLog.html @@ -34,9 +34,10 @@ <ul> <p><li>2.2 Released<p> <ul> + <li>New Lua map format: map presentation (from Fran�ois Beerten). <li>Fixed bug #1048426: [Bos] Segfault with a map. Bug with die sequence for unit without corpse (from Joris Dauphin). - <li>Fixed crash where cursors were not initialized to 0, introduced in recent cleaups (from Russell Smith). - <li>Removed Speed attribute for UnitType(its only effect was to show the value). (from Joris Dauphin) + <li>Fixed crash where cursors were not initialized to 0, introduced in recent cleanups (from Russell Smith). + <li>Removed Speed attribute for UnitType (its only effect was to show the value). (from Joris Dauphin) <li>Fixed bug #1043210: [editor] several units on the same tiles (from Russell Smith). <li>Make InfoPanel more configurable. (from Joris Dauphin). <li>Added support for transparent UI graphics, allowing for non-rectangular map areas (from Jimmy Salmon). diff --git a/doc/scripts/index.html b/doc/scripts/index.html index 0f7813a5a..406173b26 100644 --- a/doc/scripts/index.html +++ b/doc/scripts/index.html @@ -134,8 +134,6 @@ <dd></dd> <dt><a href="research.html#CheckDependency">CheckDependency</a></dt> <dd></dd> -<dt><a href="mappresentation.html#CreateMap">CreateMap</a></dt> -<dd></dd> <dt><a href="game.html#CreateUnit">CreateUnit</a></dt> <dd></dd> <dt><a href="game.html#Credits">Credits</a></dt> @@ -212,6 +210,10 @@ <dd></dd> <dt><a href="research.html#DefineModifier">DefineModifier</a></dt> <dd></dd> +<dt><a href="ui.html#DefinePanel">DefinePanel</a></dt> +<dd></dd> +<dt><a href="mappresentation.html#DefinePlayerTypes">DefinePlayerTypes</a></dt> +<dd></dd> <dt><a href="game.html#DefineRaceNames">DefineRaceNames</a></dt> <dd></dd> <dt><a href="game.html#DefineRanks">DefineRanks</a></dt> @@ -320,6 +322,8 @@ <dd></dd> <dt><a href="game.html#Player">Player</a></dt> <dd></dd> +<dt><a href="mappresentation.html#PresentMap">PresentMap</a></dt> +<dd></dd> <dt><a href="ui.html#ProcessMenu">ProcessMenu</a></dt> <dd></dd> <dt><a href="game.html#RemoveObjective">RemoveObjective</a></dt> diff --git a/doc/scripts/mappresentation.html b/doc/scripts/mappresentation.html index c1d34b0a9..55c24a678 100644 --- a/doc/scripts/mappresentation.html +++ b/doc/scripts/mappresentation.html @@ -36,13 +36,14 @@ <p><b>(C) Copyright 1998-2004 by The Stratagus Project. Distributed under the <a href="../gpl.html">"GNU General Public License"</a></b> <hr> -<a href="../index.html">Stratagus</a> -<a href="../faq.html">FAQ</a> -<a href="magic.html">PREV</a> +<a href="../index.html">Stratagus</a> +<a href="../faq.html">FAQ</a> +<a href="magic.html">PREV</a> <a href="mapsetup.html">NEXT</a> <a href="index.html">LUA Index</a> <hr> <a href="#PresentMap">PresentMap</a> +<a href="#DefinePlayerTypes">DefinePlayerTypes</a> <a href="#SetMapMiniImage">SetMapMiniImage</a> <a href="#DefineMapSetup">DefineMapSetup</a> <a href="#GetMapOption">GetMapOption</a> @@ -64,16 +65,14 @@ the needed tilesets and the whole map are loaded into the engine.</li> This page documents map presentation functions. <p> -Note: This is for the new map format. Not implented yet. +Note: This is for the new map format. Not implented yet. <h2>Functions</h2> -<a name="CreateMap"></a> -<h3>PresentMap(name, description, numplayers, mapwidth, mapheight)</h3> +<a name="PresentMap"></a> +<h3>PresentMap(description, numplayers, mapwidth, mapheight)</h3> <dl> -<dt>Name</dt> -<dd>Name of the map as displayed to the user.</dd> <dt>Description</dt> <dd>A textual description of the map that can be displayed to the user.</dd> <dt>numplayers</dt> @@ -82,16 +81,10 @@ Note: This is for the new map format. Not implented yet. <dd>The sizes of the map.</dd> </dl> -<p> -Note: This is for the new map format. Not implented yet. - <h4>Example</h4> <pre> - PresentMap("Doom World", - "As you enter hell, you encounter the home of Doom monster. " + - "Be careful for the worst of them all: John Carmack.", - 4, 64, 64) + PresentMap("Doom World", 4, 64, 64) </pre> <a name="SetMapMiniImage"></a> @@ -106,7 +99,7 @@ Path to the file with the graphic. </dd></dl> <p> -Note: This is for the new map format. Not implented yet. +Note: This is for the new map format. Not implented yet. <h4>Example</h4> @@ -114,15 +107,30 @@ Note: This is for the new map format. Not implented yet. SetMiniImage("doomworld/doomworld.png") </pre> +<a name="DefinePlayerTypes"></a> +<h3>DefinePlayerType(player1, player2, ...)</h3> + +Define the number of players and their type on the map. Possible values for player type are: +<ul> +<li>"neutral"</li> +<li>"nobody"</li> +<li>"computer"</li> +<li>"person"</li> +<li>"rescue-passive"</li> +<li>"rescue-active"</li> +</ul> + +<h4>Example</h4> + +<pre> + DefinePlayerTypes("person", "person") +</pre> + <a name="DefineMapSetup"></a> <h3>DefineMapSetup(luafile)</h3> Define the map setup file that will be loaded if the player starts a game with this map. -<p> -Note: This is for the new map format. Not implented yet. - - <h4>Example</h4> <pre> @@ -139,7 +147,7 @@ A map can define configuration options. A player can modify those options just before starting a game. For example: the tileset to use, your race, game type, number of opponents or the amount of resources on the map. <p> -Note: This is for the new map format. Not implented yet. +Note: This is for the new map format. Not implented yet. <h4>Example</h4> diff --git a/src/editor/editloop.cpp b/src/editor/editloop.cpp index e726a1dab..b3e684844 100644 --- a/src/editor/editloop.cpp +++ b/src/editor/editloop.cpp @@ -533,14 +533,14 @@ static void DrawUnitIcons(void) if (i == PlayerMax / 2) { y += 20; } - if (i == CursorPlayer && TheMap.Info->PlayerType[i] != PlayerNobody) { + if (i == CursorPlayer && TheMap.Info.PlayerType[i] != PlayerNobody) { VideoDrawRectangle(ColorWhite, x + i % 8 * 20, y, 20, 20); } VideoDrawRectangle( - i == CursorPlayer && TheMap.Info->PlayerType[i] != PlayerNobody ? + i == CursorPlayer && TheMap.Info.PlayerType[i] != PlayerNobody ? ColorWhite : ColorGray, x + i % 8 * 20, y, 19, 19); - if (TheMap.Info->PlayerType[i] != PlayerNobody) { + if (TheMap.Info.PlayerType[i] != PlayerNobody) { VideoFillRectangle(Players[i].Color, x + 1 + i % 8 * 20, y + 1, 17, 17); } @@ -555,10 +555,10 @@ static void DrawUnitIcons(void) y += 18 * 1 + 4; if (SelectedPlayer != -1) { i = sprintf(buf,"Plyr %d %s ", SelectedPlayer, - PlayerRaces.Name[TheMap. Info->PlayerSide[SelectedPlayer]]); + PlayerRaces.Name[TheMap. Info.PlayerSide[SelectedPlayer]]); // Players[SelectedPlayer].RaceName); - switch (TheMap.Info->PlayerType[SelectedPlayer]) { + switch (TheMap.Info.PlayerType[SelectedPlayer]) { case PlayerNeutral: strcat(buf, "Neutral"); break; @@ -1134,7 +1134,7 @@ static void EditorCallbackButtonDown(unsigned button __attribute__ ((unused))) } // Cursor on player icons if (CursorPlayer != -1) { - if (TheMap.Info->PlayerType[CursorPlayer] != PlayerNobody) { + if (TheMap.Info.PlayerType[CursorPlayer] != PlayerNobody) { SelectedPlayer = CursorPlayer; ThisPlayer = Players + SelectedPlayer; } @@ -1588,7 +1588,7 @@ static void EditorCallbackMouse(int x, int y) by += 20; } if (bx < x && x < bx + 20 && by < y && y < by + 20) { - if (TheMap.Info->PlayerType[i] != PlayerNobody) { + if (TheMap.Info.PlayerType[i] != PlayerNobody) { sprintf(buf,"Select player #%d",i); SetStatusLine(buf); } else { @@ -1819,35 +1819,35 @@ static void CreateEditor(void) // // Inititialize TheMap / Players. // - TheMap.Info->MapTerrainName = - strdup(Tilesets[TheMap.Info->MapTerrain]->Ident); + TheMap.Info.MapTerrainName = + strdup(Tilesets[TheMap.Info.MapTerrain]->Ident); InitPlayers(); for (i = 0; i < PlayerMax; ++i) { int j; if (i == PlayerNumNeutral) { CreatePlayer(PlayerNeutral); - TheMap.Info->PlayerType[i] = PlayerNeutral; - TheMap.Info->PlayerSide[i] = Players[i].Race = PlayerRaceNeutral; + TheMap.Info.PlayerType[i] = PlayerNeutral; + TheMap.Info.PlayerSide[i] = Players[i].Race = PlayerRaceNeutral; } else { CreatePlayer(PlayerNobody); - TheMap.Info->PlayerType[i] = PlayerNobody; + TheMap.Info.PlayerType[i] = PlayerNobody; } for (j = 1; j < MaxCosts; ++j) { - TheMap.Info->PlayerResources[i][j] = Players[i].Resources[j]; + TheMap.Info.PlayerResources[i][j] = Players[i].Resources[j]; } } - strncpy(TheMap.Description, TheMap.Info->Description, 32); - TheMap.Width = TheMap.Info->MapWidth; - TheMap.Height = TheMap.Info->MapHeight; + strncpy(TheMap.Description, TheMap.Info.Description, 32); + TheMap.Width = TheMap.Info.MapWidth; + TheMap.Height = TheMap.Info.MapHeight; TheMap.Fields = calloc(TheMap.Width * TheMap.Height, sizeof(MapField)); TheMap.Visible[0] = calloc(TheMap.Width * TheMap.Height / 8, 1); InitUnitCache(); - TheMap.Terrain = TheMap.Info->MapTerrain; - TheMap.TerrainName = strdup(Tilesets[TheMap.Info->MapTerrain]->Ident); - TheMap.Tileset = Tilesets[TheMap.Info->MapTerrain]; + TheMap.Terrain = TheMap.Info.MapTerrain; + TheMap.TerrainName = strdup(Tilesets[TheMap.Info.MapTerrain]->Ident); + TheMap.Tileset = Tilesets[TheMap.Info.MapTerrain]; LoadTileset(); for (i = 0; i < TheMap.Width * TheMap.Height; ++i) { @@ -1870,14 +1870,14 @@ static void CreateEditor(void) // Place the start points, which the loader discarded. // for (i = 0; i < PlayerMax; ++i) { - if (TheMap.Info->PlayerType[i] != PlayerNobody) { + if (TheMap.Info.PlayerType[i] != PlayerNobody) { // Set SelectedPlayer to a valid player if (SelectedPlayer == 15) { SelectedPlayer = i; } #if 0 // FIXME: must support more races - switch (TheMap.Info->PlayerSide[i]) { + switch (TheMap.Info.PlayerSide[i]) { case PlayerRaceHuman: MakeUnitAndPlace(Players[i].StartX, Players[i].StartY, UnitTypeByWcNum(WC_StartLocationHuman), diff --git a/src/game/campaign.cpp b/src/game/campaign.cpp index 686e1a0c7..81ea8aca6 100644 --- a/src/game/campaign.cpp +++ b/src/game/campaign.cpp @@ -168,7 +168,8 @@ void PlayCampaign(const char* name) SkipCurrentChapter = 1; GameResult = GameNoResult; - strcpy(CurrentMapPath, filename); + FreeMapInfo(&TheMap.Info); + sprintf(CurrentMapPath, "%s/%s", StratagusLibPath, filename); } /** diff --git a/src/game/game.cpp b/src/game/game.cpp index a2fbf23a4..e9546f03c 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -122,7 +122,7 @@ static void LoadStratagusMap(const char* mapname, fprintf(stderr, "%s: invalid Stratagus map\n", mapname); ExitFatal(-1); } - TheMap.Info->Filename = strdup(mapname); + TheMap.Info.Filename = strdup(mapname); } /** @@ -133,7 +133,7 @@ static void LoadStratagusMap(const char* mapname, */ static void LoadMap(const char* filename, WorldMap* map) { - const char* tmp; + char* tmp; tmp = strrchr(filename, '.'); if (tmp) { @@ -149,6 +149,15 @@ static void LoadMap(const char* filename, WorldMap* map) } } #endif + if (!strcmp(tmp, ".smp")) { + if (!TheMap.Info.Filename) { + // The map info hasn't been loaded yet => do it now + LuaLoadFile(filename); + } + Assert(TheMap.Info.Filename); + LoadStratagusMap(TheMap.Info.Filename, map); + return; + } if (!strcmp(tmp, ".cm") #ifdef USE_ZLIB || !strcmp(tmp, ".cm.gz") @@ -164,8 +173,11 @@ static void LoadMap(const char* filename, WorldMap* map) // ARI: This bombs out, if no pud, so will be safe. if (strcasestr(filename, ".pud")) { LoadPud(filename, map); - map->Info->Filename = strdup(filename); + map->Info.Filename = strdup(filename); + return; } + + printf("Unrecognized map format\n"); } /*---------------------------------------------------------------------------- diff --git a/src/game/savegame.cpp b/src/game/savegame.cpp index cab8a1749..3c0335ef8 100644 --- a/src/game/savegame.cpp +++ b/src/game/savegame.cpp @@ -257,7 +257,7 @@ void SaveGame(const char* filename) StratagusMajorVersion, StratagusMinorVersion, StratagusPatchLevel); CLprintf(file, " SyncHash = %d, \n", SyncHash); CLprintf(file, " SyncRandSeed = %d, \n", SyncRandSeed); - CLprintf(file, " SaveFile = \"%s\"\n", TheMap.Info->Filename); + CLprintf(file, " SaveFile = \"%s\"\n", CurrentMapPath); CLprintf(file, "\n--- \"preview\", \"%s.pam\",\n", filename); CLprintf(file, "} )\n\n"); diff --git a/src/include/map.h b/src/include/map.h index 61cf76e82..13508704e 100644 --- a/src/include/map.h +++ b/src/include/map.h @@ -291,8 +291,8 @@ typedef struct _world_map_ { char Description[32];///< map description short - MapInfo* Info; ///< descriptive information - // TODO: (MapInfo* Info DUPLICATES!) + MapInfo Info; ///< descriptive information + // TODO: (remove MapInfo Info DUPLICATES!) } WorldMap; /*---------------------------------------------------------------------------- diff --git a/src/include/menus.h b/src/include/menus.h index 02b8575c9..de93370bf 100644 --- a/src/include/menus.h +++ b/src/include/menus.h @@ -299,7 +299,6 @@ extern Menu* CurrentMenu; ///< Current menu extern struct _graphic_* MenuButtonGraphics[];///< Menu button graphics extern struct _graphic_* MenuButtonG; ///< Current menu button graphics -extern struct _map_info_* MenuMapInfo; ///< MapInfo of map used in gui menus extern char MenuMapFullPath[1024]; ///< Full path to currently selected map extern int nKeyStrokeHelps; ///< Number of loaded keystroke helps diff --git a/src/include/pud.h b/src/include/pud.h index 147149b2c..6ea609060 100644 --- a/src/include/pud.h +++ b/src/include/pud.h @@ -93,7 +93,7 @@ struct _world_map_; ----------------------------------------------------------------------------*/ /// Return info for pud -extern MapInfo* GetPudInfo(const char* pud); +extern MapInfo* GetPudInfo(const char* pud, MapInfo* info); /// Load a pud file extern void LoadPud(const char* pud, struct _world_map_* map); diff --git a/src/map/map.cpp b/src/map/map.cpp index 784f6db3e..e333db010 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -10,7 +10,7 @@ // /**@name map.c - The map. */ // -// (c) Copyright 1998-2004 by Lutz Sammer and Vladi Shabanski +// (c) Copyright 1998-2004 by Lutz Sammer, Vladi Shabanski and Fran�ois Beerten // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -414,7 +414,7 @@ void FreeMapInfo(MapInfo* info) if (info->Filename) { free(info->Filename); } - free(info); + memset(info, 0, sizeof(MapInfo)); } } @@ -429,7 +429,7 @@ void CleanMap(void) // Tileset freed by Tileset? - FreeMapInfo(TheMap.Info); + FreeMapInfo(&TheMap.Info); memset(&TheMap, 0, sizeof(TheMap)); FlagRevealMap = 0; ReplayRevealMap = 0; diff --git a/src/map/map_save.cpp b/src/map/map_save.cpp index 839141c63..17a0d2b6f 100644 --- a/src/map/map_save.cpp +++ b/src/map/map_save.cpp @@ -85,7 +85,7 @@ void SaveMap(CLFile* file) CLprintf(file, " \"size\", {%d, %d},\n", TheMap.Width, TheMap.Height); CLprintf(file, " \"%s\",\n", TheMap.NoFogOfWar ? "no-fog-of-war" : "fog-of-war"); - CLprintf(file, " \"filename\", \"%s\",\n", TheMap.Info->Filename); + CLprintf(file, " \"filename\", \"%s\",\n", TheMap.Info.Filename); CLprintf(file, " \"map-fields\", {\n"); for (h = 0; h < TheMap.Height; ++h) { diff --git a/src/map/script_map.cpp b/src/map/script_map.cpp index dee984710..86e24d693 100644 --- a/src/map/script_map.cpp +++ b/src/map/script_map.cpp @@ -71,10 +71,6 @@ static int CclStratagusMap(lua_State* l) // Parse the list: (still everything could be changed!) // - if (!TheMap.Info) { - TheMap.Info = calloc(1, sizeof(MapInfo)); - } - args = lua_gettop(l); for (j = 0; j < args; ++j) { value = LuaToString(l, j + 1); @@ -89,11 +85,11 @@ static int CclStratagusMap(lua_State* l) fprintf(stderr, "Warning not saved with this version.\n"); } } else if (!strcmp(value, "uid")) { - TheMap.Info->MapUID = LuaToNumber(l, j + 1); + TheMap.Info.MapUID = LuaToNumber(l, j + 1); } else if (!strcmp(value, "description")) { value = LuaToString(l, j + 1); strncpy(TheMap.Description, value, sizeof(TheMap.Description)); - TheMap.Info->Description = strdup(value); + TheMap.Info.Description = strdup(value); } else if (!strcmp(value, "the-map")) { if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); @@ -154,7 +150,7 @@ static int CclStratagusMap(lua_State* l) --k; } else if (!strcmp(value, "filename")) { lua_rawgeti(l, j + 1, k + 1); - TheMap.Info->Filename = strdup(LuaToString(l, -1)); + TheMap.Info.Filename = strdup(LuaToString(l, -1)); lua_pop(l, 1); } else if (!strcmp(value, "map-fields")) { int i; @@ -445,6 +441,43 @@ static int CclSetFogOfWarGraphics(lua_State* l) return 0; } +/** +** Define the type of each player available for the map +** +** @param l Lua state. +*/ +static int CclDefinePlayerTypes(lua_State* l) +{ + const char* type; + int numplayers; + int i; + + numplayers = lua_gettop(l); /* Number of players == number of arguments */ + if (numplayers < 2) { + LuaError(l, "Not enough players"); + } + + for (i = 0; i < numplayers; i++) { + type = LuaToString(l, i + 1); + if (!strcmp(type, "neutral")) { + TheMap.Info.PlayerType[i] = PlayerNeutral; + } else if (!strcmp(type, "nobody")) { + TheMap.Info.PlayerType[i] = PlayerNobody; + } else if (!strcmp(type, "computer")) { + TheMap.Info.PlayerType[i] = PlayerComputer; + } else if (!strcmp(type, "person")) { + TheMap.Info.PlayerType[i] = PlayerPerson; + } else if (!strcmp(type, "rescue-passive")) { + TheMap.Info.PlayerType[i] = PlayerRescuePassive; + } else if (!strcmp(type, "rescue-active")) { + TheMap.Info.PlayerType[i] = PlayerRescueActive; + } else { + LuaError(l, "Unsupported tag: %s" _C_ type); + } + } + return 0; +} + /** ** Register CCL features for map. */ @@ -463,6 +496,8 @@ void MapCclRegister(void) lua_register(Lua, "SetFogOfWarOpacity", CclSetFogOfWarOpacity); lua_register(Lua, "SetForestRegeneration",CclSetForestRegeneration); + + lua_register(Lua, "DefinePlayerTypes", CclDefinePlayerTypes); } //@} diff --git a/src/network/commands.cpp b/src/network/commands.cpp index d5e77b1eb..204cef2bc 100644 --- a/src/network/commands.cpp +++ b/src/network/commands.cpp @@ -195,7 +195,7 @@ static FullReplay* StartReplay(void) replay->Date = strdup(s); replay->Map = strdup(TheMap.Description); - replay->MapId = (signed int)TheMap.Info->MapUID; + replay->MapId = (signed int)TheMap.Info.MapUID; replay->MapPath = strdup(CurrentMapPath); replay->Resource = GameSettings.Resources; replay->NumUnits = GameSettings.NumUnits; diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index 672677371..b4e8292af 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -353,7 +353,7 @@ void NetworkServerStartGame(void) // Make a list of the available player slots. for (h = i = 0; i < PlayerMax; ++i) { - if (MenuMapInfo->PlayerType[i] == PlayerPerson) { + if (TheMap.Info.PlayerType[i] == PlayerPerson) { rev[i] = h; num[h++] = i; DebugPrint("Slot %d is available for an interactive player (%d)\n" _C_ @@ -363,7 +363,7 @@ void NetworkServerStartGame(void) // Make a list of the available computer slots. n = h; for (i = 0; i < PlayerMax; ++i) { - if (MenuMapInfo->PlayerType[i] == PlayerComputer) { + if (TheMap.Info.PlayerType[i] == PlayerComputer) { rev[i] = n++; DebugPrint("Slot %d is available for an ai computer player (%d)\n" _C_ i _C_ rev[i]); @@ -371,8 +371,8 @@ void NetworkServerStartGame(void) } // Make a list of the remaining slots. for (i = 0; i < PlayerMax; ++i) { - if (MenuMapInfo->PlayerType[i] != PlayerPerson && - MenuMapInfo->PlayerType[i] != PlayerComputer) { + if (TheMap.Info.PlayerType[i] != PlayerPerson && + TheMap.Info.PlayerType[i] != PlayerComputer) { rev[i] = n++; // PlayerNobody - not available to anything.. } @@ -435,7 +435,7 @@ void NetworkServerStartGame(void) j = h; if (NoRandomPlacementMultiplayer == 1) { for (i = 0; i < PlayerMax; ++i) { - if (MenuMapInfo->PlayerType[i] != PlayerComputer) { + if (TheMap.Info.PlayerType[i] != PlayerComputer) { org[i] = Hosts[i].PlyNr; } } @@ -506,7 +506,7 @@ void NetworkServerStartGame(void) message.Type = MessageInitReply; message.SubType = ICMConfig; message.HostsCount = NetPlayers; - message.MapUID = htonl(MenuMapInfo->MapUID); + message.MapUID = htonl(TheMap.Info.MapUID); for (i = 0; i < NetPlayers; ++i) { message.u.Hosts[i].Host = Hosts[i].Host; message.u.Hosts[i].Port = Hosts[i].Port; @@ -519,7 +519,7 @@ void NetworkServerStartGame(void) statemsg.SubType = ICMState; statemsg.HostsCount = NetPlayers; statemsg.u.State = ServerSetupState; - statemsg.MapUID = htonl(MenuMapInfo->MapUID); + statemsg.MapUID = htonl(TheMap.Info.MapUID); msg = (InitMessage*)buf; DebugPrint("Ready, sending InitConfig to %d host(s)\n" _C_ HostsCount); @@ -705,7 +705,7 @@ changed: message.Type = MessageInitHello; message.SubType = ICMState; message.u.State = LocalSetupState; - message.MapUID = htonl(MenuMapInfo->MapUID); + message.MapUID = htonl(TheMap.Info.MapUID); NetworkSendRateLimitedClientMessage(&message, 450); } else { NetLocalState = ccs_unreachable; @@ -725,10 +725,10 @@ changed: } break; case ccs_mapinfo: - if (NetStateMsgCnt < 20 && MenuMapInfo != NULL) { // 20 retries + if (NetStateMsgCnt < 20) { // 20 retries message.Type = MessageInitHello; message.SubType = ICMMap; // ICMMapAck.. - message.MapUID = htonl(MenuMapInfo->MapUID); + message.MapUID = htonl(TheMap.Info.MapUID); NetworkSendRateLimitedClientMessage(&message, 650); } else { NetLocalState = ccs_unreachable; @@ -739,11 +739,7 @@ changed: if (NetStateMsgCnt < 20) { // 20 retries message.Type = MessageInitHello; message.SubType = ICMMapUidMismatch; - if (MenuMapInfo) { - message.MapUID = htonl(MenuMapInfo->MapUID); // MAP Uid doesn't match - } else { - message.MapUID = 0L; // Map not found - } + message.MapUID = htonl(TheMap.Info.MapUID); // MAP Uid doesn't match NetworkSendRateLimitedClientMessage(&message, 650); } else { NetLocalState = ccs_unreachable; @@ -813,7 +809,7 @@ void NetworkProcessServerRequest(void) unsigned long fcd; InitMessage message; - if (MenuMapInfo == NULL) { + if (GameRunning) { return; // Game already started... } @@ -965,10 +961,10 @@ static void ClientParseConnected(const InitMessage* msg) NetLocalState = ccs_badmap; break; } - if (ntohl(msg->MapUID) != MenuMapInfo->MapUID) { + if (ntohl(msg->MapUID) != TheMap.Info.MapUID) { NetLocalState = ccs_badmap; fprintf(stderr, "Stratagus maps do not match (0x%08x) <-> (0x%08x)\n", - (unsigned int)MenuMapInfo->MapUID, + (unsigned int)TheMap.Info.MapUID, (unsigned int)ntohl(msg->MapUID)); break; } @@ -1343,7 +1339,7 @@ static void ServerParseWaiting(const int h) message.SubType = ICMMap; // Send Map info to the client pathlen = strlen(StratagusLibPath) + 1; memcpy(message.u.MapPath, MenuMapFullPath + pathlen, 256); - message.MapUID = htonl(MenuMapInfo->MapUID); + message.MapUID = htonl(TheMap.Info.MapUID); n = NetworkSendICMessage(NetLastHost, NetLastPort, &message); DebugPrint("Sending InitReply Message Map: (%d) to %d.%d.%d.%d:%d\n" _C_ n _C_ NIPQUAD(ntohl(NetLastHost)) _C_ ntohs(NetLastPort)); @@ -1377,7 +1373,7 @@ static void ServerParseWaiting(const int h) message.Type = MessageInitReply; message.SubType = ICMState; // Send new state info to the client message.u.State = ServerSetupState; - message.MapUID = htonl(MenuMapInfo->MapUID); + message.MapUID = htonl(TheMap.Info.MapUID); n = NetworkSendICMessage(NetLastHost, NetLastPort, &message); DebugPrint("Sending InitReply Message State: (%d) to %d.%d.%d.%d:%d\n" _C_ n _C_ NIPQUAD(ntohl(NetLastHost)) _C_ ntohs(NetLastPort)); @@ -1418,7 +1414,7 @@ static void ServerParseMap(const int h) message.Type = MessageInitReply; message.SubType = ICMState; // Send State info to the client message.u.State = ServerSetupState; - message.MapUID = htonl(MenuMapInfo->MapUID); + message.MapUID = htonl(TheMap.Info.MapUID); n = NetworkSendICMessage(NetLastHost, NetLastPort, &message); DebugPrint("Sending InitReply Message State: (%d) to %d.%d.%d.%d:%d\n" _C_ n _C_ NIPQUAD(ntohl(NetLastHost)) _C_ ntohs(NetLastPort)); @@ -1475,7 +1471,7 @@ static void ServerParseState(const int h, const InitMessage* msg) message.Type = MessageInitReply; message.SubType = ICMState; // Send new state info to the client message.u.State = ServerSetupState; - message.MapUID = htonl(MenuMapInfo->MapUID); + message.MapUID = htonl(TheMap.Info.MapUID); n = NetworkSendICMessage(NetLastHost, NetLastPort, &message); DebugPrint("Sending InitReply Message State: (%d) to %d.%d.%d.%d:%d\n" _C_ n _C_ NIPQUAD(ntohl(NetLastHost)) _C_ ntohs(NetLastPort)); diff --git a/src/stratagus/pud.cpp b/src/stratagus/pud.cpp index 90e694d6f..8a3688161 100644 --- a/src/stratagus/pud.cpp +++ b/src/stratagus/pud.cpp @@ -353,13 +353,12 @@ static int PudReadByte(CLFile* input) /** ** Get the info for a pud. */ -MapInfo* GetPudInfo(const char* pud) +MapInfo* GetPudInfo(const char* pud, MapInfo* info) { CLFile* input; uint32_t length; char header[5]; char buf[1024]; - MapInfo* info; unsigned short temp_short; // FIXME: Reuse the temporary alloca buffer... @@ -387,10 +386,7 @@ MapInfo* GetPudInfo(const char* pud) return NULL; } - info=calloc(1, sizeof(MapInfo)); // clears with 0 - if (!info) { - return NULL; - } + memset(info, 0, sizeof(MapInfo)); // clears with 0 info->Filename = strdup(pud); @@ -813,9 +809,7 @@ void LoadPud(const char* pud,WorldMap* map) strcat(pudfull, "/"); strcat(pudfull, pud); - if (!map->Info) { - map->Info = GetPudInfo(pudfull); - } + GetPudInfo(pudfull, &map->Info); if( !(input=CLopen(pudfull,CL_OPEN_READ)) ) { fprintf(stderr,"Try ./path/name\n"); fprintf(stderr,"pud: CLopen(%s): %s\n", pud, strerror(errno)); @@ -1577,10 +1571,10 @@ int SavePud(const char* pud,const WorldMap* map) buf[0x9]=0x00; buf[0xA]=0x0A; buf[0xB]=0xFF; - buf[0xC]=map->Info->MapUID >> 0; - buf[0xD]=map->Info->MapUID >> 8; - buf[0xE]=map->Info->MapUID >> 16; - buf[0xF]=map->Info->MapUID >> 24; + buf[0xC]=map->Info.MapUID >> 0; + buf[0xD]=map->Info.MapUID >> 8; + buf[0xE]=map->Info.MapUID >> 16; + buf[0xF]=map->Info.MapUID >> 24; gzwrite(f,buf,16); PudWriteHeader(f,"VER ",2); @@ -1590,18 +1584,18 @@ int SavePud(const char* pud,const WorldMap* map) PudWriteHeader(f,"DESC",32); memset(buf,0,32); - strncpy(buf,map->Info->Description,32); + strncpy(buf,map->Info.Description,32); gzwrite(f,buf,32); PudWriteHeader(f,"OWNR",16); for( i=0; i<16; ++i ) { - buf[i]=map->Info->PlayerType[i]; + buf[i]=map->Info.PlayerType[i]; } gzwrite(f,buf,16); PudWriteHeader(f,"ERAX",2); - buf[0]=map->Info->MapTerrain >> 0; - buf[1]=map->Info->MapTerrain >> 8; + buf[0]=map->Info.MapTerrain >> 0; + buf[1]=map->Info.MapTerrain >> 8; gzwrite(f,buf,2); PudWriteHeader(f,"DIM ",4); @@ -1633,34 +1627,34 @@ int SavePud(const char* pud,const WorldMap* map) PudWriteHeader(f,"SIDE",16); for( i=0; i<16; ++i ) { - buf[i]=map->Info->PlayerSide[i]; + buf[i]=map->Info.PlayerSide[i]; } gzwrite(f,buf,16); PudWriteHeader(f,"SGLD",32); for( i=0; i<16; ++i ) { - buf[i*2+0]=map->Info->PlayerResources[i][GoldCost] >> 0; - buf[i*2+1]=map->Info->PlayerResources[i][GoldCost] >> 8; + buf[i*2+0]=map->Info.PlayerResources[i][GoldCost] >> 0; + buf[i*2+1]=map->Info.PlayerResources[i][GoldCost] >> 8; } gzwrite(f,buf,32); PudWriteHeader(f,"SLBR",32); for( i=0; i<16; ++i ) { - buf[i*2+0]=map->Info->PlayerResources[i][WoodCost] >> 0; - buf[i*2+1]=map->Info->PlayerResources[i][WoodCost] >> 8; + buf[i*2+0]=map->Info.PlayerResources[i][WoodCost] >> 0; + buf[i*2+1]=map->Info.PlayerResources[i][WoodCost] >> 8; } gzwrite(f,buf,32); PudWriteHeader(f,"SOIL",32); for( i=0; i<16; ++i ) { - buf[i*2+0]=map->Info->PlayerResources[i][OilCost] >> 0; - buf[i*2+1]=map->Info->PlayerResources[i][OilCost] >> 8; + buf[i*2+0]=map->Info.PlayerResources[i][OilCost] >> 0; + buf[i*2+1]=map->Info.PlayerResources[i][OilCost] >> 8; } gzwrite(f,buf,32); PudWriteHeader(f,"AIPL",16); for( i=0; i<16; ++i ) { - buf[i]=map->Info->PlayerAi[i]; + buf[i]=map->Info.PlayerAi[i]; } gzwrite(f,buf,16); diff --git a/src/stratagus/stratagus.cpp b/src/stratagus/stratagus.cpp index 49bc89705..42f481164 100644 --- a/src/stratagus/stratagus.cpp +++ b/src/stratagus/stratagus.cpp @@ -669,8 +669,7 @@ void MenuLoop(char* filename, WorldMap* map) // - FIXME: not the ideal place for this.. // DebugPrint("Freeing map info, wrong place\n"); - FreeMapInfo(map->Info); - map->Info = NULL; + FreeMapInfo(&map->Info); // // No filename given, choose with the menus @@ -730,6 +729,7 @@ void MenuLoop(char* filename, WorldMap* map) // // Create the game. // + DebugPrint("Creating game with map: %s\n" _C_ filename); CreateGame(filename, map); SetStatusLine(NameLine); @@ -750,7 +750,9 @@ void MenuLoop(char* filename, WorldMap* map) PreMenuSetup(); filename = NextChapter(); - DebugPrint("Next chapter %s\n" _C_ filename); + sprintf(CurrentMapPath, "%s/%s", StratagusLibPath, filename); + filename = CurrentMapPath; + DebugPrint("Next chapter %s\n" _C_ CurrentMapPath); } } diff --git a/src/ui/menus.cpp b/src/ui/menus.cpp index b52484d41..b50d317b1 100644 --- a/src/ui/menus.cpp +++ b/src/ui/menus.cpp @@ -428,7 +428,6 @@ static char ScenSelectPath[1024]; ///< Scenario selector path static char ScenSelectDisplayPath[1024]; ///< Displayed selector path static char ScenSelectFileName[128]; ///< Scenario selector name -MapInfo *MenuMapInfo; ///< Selected map info char MenuMapFullPath[1024]; ///< Selected map path+name static char *SaveDir; ///< Save game directory @@ -2485,9 +2484,6 @@ static void GetInfoFromSelectPath(void) { int i; - FreeMapInfo(MenuMapInfo); - MenuMapInfo = NULL; - if (ScenSelectPath[0]) { i = strlen(ScenSelectPath); strcat(ScenSelectPath, "/"); @@ -2496,10 +2492,10 @@ static void GetInfoFromSelectPath(void) } strcat(ScenSelectPath, ScenSelectFileName); // Final map name with path if (strcasestr(ScenSelectFileName, ".pud")) { - MenuMapInfo = GetPudInfo(ScenSelectPath); + GetPudInfo(ScenSelectPath, &TheMap.Info); strcpy(MenuMapFullPath, ScenSelectPath); - } else { - // FIXME: GetCmInfo(); + } else if(strcasestr(ScenSelectFileName, ".smp")) { + LuaLoadFile(ScenSelectPath); } ScenSelectPath[i] = '\0'; // Remove appended part } @@ -2519,21 +2515,15 @@ static void ScenSelectMenu(void) GetInfoFromSelectPath(); menu = FindMenu("menu-custom-game"); - // FIXME: This check is only needed until GetCmInfo works - if (!MenuMapInfo) { - menu->Items[12].D.Pulldown.noptions = PlayerMax-1; + for (n = j = 0; j < PlayerMax; ++j) { + t = TheMap.Info.PlayerType[j]; + if (t == PlayerPerson || t == PlayerComputer) { + n++; + } + } + menu->Items[12].D.Pulldown.noptions = n; + if (menu->Items[12].D.Pulldown.curopt >= n) { menu->Items[12].D.Pulldown.curopt = 0; - } else { - for (n = j = 0; j < PlayerMax; ++j) { - t = MenuMapInfo->PlayerType[j]; - if (t == PlayerPerson || t == PlayerComputer) { - n++; - } - } - menu->Items[12].D.Pulldown.noptions = n; - if (menu->Items[12].D.Pulldown.curopt >= n) { - menu->Items[12].D.Pulldown.curopt = 0; - } } } @@ -3008,6 +2998,28 @@ static void MultiPlayerInternetGame(void) } } +/** +** Allocate and deep copy a MapInfo structure +*/ +static MapInfo* DuplicateMapInfo(MapInfo *orig) +{ + MapInfo* dest; + + dest = malloc(sizeof(MapInfo)); + memcpy(dest, orig, sizeof(MapInfo)); + if (orig->Description) { + dest->Description = strdup(orig->Description); + } + if (dest->MapTerrainName) { + dest->MapTerrainName = strdup(orig->MapTerrainName); + } + if (dest->Filename) { + dest->Filename = strdup(orig->Filename); + } + + return dest; +} + /** ** Free map info data */ @@ -3018,6 +3030,7 @@ static void FreeMapInfos(FileList *fl, int n) for (i = 0; i < n; i++) { if (fl[i].type && fl[i].xdata) { FreeMapInfo(fl[i].xdata); + free(fl[i].xdata); fl[i].xdata = NULL; } free(fl[i].name); @@ -3092,7 +3105,7 @@ static int ScenSelectRDFilter(char *pathbuf, FileList *fl) curopt = menu->Items[6].D.Pulldown.curopt; if (curopt == 0) { - suf[0] = ".cm"; + suf[0] = ".smp"; suf[1] = NULL; } else if (curopt == 1) { suf[0] = ".pud"; @@ -3141,20 +3154,22 @@ static int ScenSelectRDFilter(char *pathbuf, FileList *fl) #endif if (*cp == 0) { if (curopt == 0) { - // info = GetCmInfo(pathbuf); info = NULL; fl->type = 1; fl->name = strdup(np); - fl->xdata = info; + FreeMapInfo(&TheMap.Info); + LuaLoadFile(pathbuf); + fl->xdata = DuplicateMapInfo(&TheMap.Info); return 1; } else if (curopt == 1) { - info = GetPudInfo(pathbuf); + FreeMapInfo(&TheMap.Info); + info = GetPudInfo(pathbuf, &TheMap.Info); if (info) { sz = szl[menu->Items[8].D.Pulldown.curopt]; if (sz < 0 || (info->MapWidth == sz && info->MapHeight == sz)) { fl->type = 1; fl->name = strdup(np); - fl->xdata = info; + fl->xdata = DuplicateMapInfo(info); return 1; } else { FreeMapInfo(info); @@ -3474,8 +3489,6 @@ static void ScenSelectCancel(void) */ static void GameCancel(void) { - FreeMapInfo(MenuMapInfo); - MenuMapInfo = NULL; EndMenu(); } @@ -3487,9 +3500,6 @@ static void CustomGameStart(void) int i; char *p; - FreeMapInfo(MenuMapInfo); - MenuMapInfo = NULL; - if (ScenSelectPath[0]) { strcat(ScenSelectPath, "/"); strcat(ScenSelectPath, ScenSelectFileName); // Final map name with path @@ -3551,21 +3561,15 @@ static void GameSetupInit(Menuitem* mi __attribute__ ((unused))) GetInfoFromSelectPath(); menu = FindMenu("menu-custom-game"); - // FIXME: This check is only needed until GetCmInfo works - if (!MenuMapInfo) { - menu->Items[12].D.Pulldown.noptions = PlayerMax-1; + for (n = j = 0; j < PlayerMax; ++j) { + t = TheMap.Info.PlayerType[j]; + if (t == PlayerPerson || t == PlayerComputer) { + n++; + } + } + menu->Items[12].D.Pulldown.noptions = n; + if (menu->Items[12].D.Pulldown.curopt >= n) { menu->Items[12].D.Pulldown.curopt = 0; - } else { - for (n = j = 0; j < PlayerMax; ++j) { - t = MenuMapInfo->PlayerType[j]; - if (t == PlayerPerson || t == PlayerComputer) { - n++; - } - } - menu->Items[12].D.Pulldown.noptions = n; - if (menu->Items[12].D.Pulldown.curopt >= n) { - menu->Items[12].D.Pulldown.curopt = 0; - } } } @@ -3584,13 +3588,12 @@ static void GameDrawFunc(Menuitem* mi __attribute__((unused))) l = VideoTextLength(GameFont, "Scenario:"); VideoDrawText(TheUI.Offset640X + 16, TheUI.Offset480Y + 360, GameFont, "Scenario:"); VideoDrawText(TheUI.Offset640X + 16, TheUI.Offset480Y + 360 + 24 , GameFont, ScenSelectFileName); - if (MenuMapInfo) { - if (MenuMapInfo->Description) { - VideoDrawText(TheUI.Offset640X + 16 + l + 8, TheUI.Offset480Y + 360, GameFont, MenuMapInfo->Description); - } - sprintf(buffer, " (%d x %d)", MenuMapInfo->MapWidth, MenuMapInfo->MapHeight); - VideoDrawText(TheUI.Offset640X + 16 + l + 8 + VideoTextLength(GameFont, ScenSelectFileName), TheUI.Offset480Y + 360 + 24, GameFont, buffer); + if (TheMap.Info.Description) { + VideoDrawText(TheUI.Offset640X + 16 + l + 8, TheUI.Offset480Y + 360, GameFont, TheMap.Info.Description); } + sprintf(buffer, " (%d x %d)", TheMap.Info.MapWidth, TheMap.Info.MapHeight); + VideoDrawText(TheUI.Offset640X + 16 + l + 8 + VideoTextLength(GameFont, ScenSelectFileName), TheUI.Offset480Y + 360 + 24, GameFont, buffer); + #if 0 for (n = j = 0; j < PlayerMax; j++) { if (info->PlayerType[j] == PlayerPerson) { @@ -3803,8 +3806,6 @@ static void NetworkGamePrepareGameSettings(void) int x; int v; - Assert(MenuMapInfo); - DebugPrint("NetPlayers = %d\n" _C_ NetPlayers); GameSettings.NetGameType=SettingsMultiPlayerGame; @@ -3825,10 +3826,10 @@ static void NetworkGamePrepareGameSettings(void) // Make a list of the available player slots. for (c = h = i = 0; i < PlayerMax; i++) { - if (MenuMapInfo->PlayerType[i] == PlayerPerson) { + if (TheMap.Info.PlayerType[i] == PlayerPerson) { num[h++] = i; } - if (MenuMapInfo->PlayerType[i] == PlayerComputer) { + if (TheMap.Info.PlayerType[i] == PlayerComputer) { comp[c++] = i; // available computer player slots } } @@ -3902,10 +3903,10 @@ static void MultiGamePlayerSelectorsUpdate(int initial) // Calculate available slots from pudinfo for (c = h = i = 0; i < PlayerMax; i++) { - if (MenuMapInfo->PlayerType[i] == PlayerPerson) { + if (TheMap.Info.PlayerType[i] == PlayerPerson) { h++; // available interactive player slots } - if (MenuMapInfo->PlayerType[i] == PlayerComputer) { + if (TheMap.Info.PlayerType[i] == PlayerComputer) { c++; // available computer player slots } } @@ -4039,10 +4040,10 @@ static void MultiClientUpdate(int initial) // Calculate available slots from pudinfo for (c = h = i = 0; i < PlayerMax; i++) { - if (MenuMapInfo->PlayerType[i] == PlayerPerson) { + if (TheMap.Info.PlayerType[i] == PlayerPerson) { h++; // available interactive player slots } - if (MenuMapInfo->PlayerType[i] == PlayerComputer) { + if (TheMap.Info.PlayerType[i] == PlayerComputer) { c++; // available computer player slots } } @@ -4134,7 +4135,7 @@ static void MultiGameSetupInit(Menuitem* mi) memset(&ServerSetupState, 0, sizeof(ServerSetup)); // Calculate available slots from pudinfo for (h = i = 0; i < PlayerMax; i++) { - if (MenuMapInfo->PlayerType[i] == PlayerPerson) { + if (TheMap.Info.PlayerType[i] == PlayerPerson) { h++; // available interactive player slots } } @@ -4369,9 +4370,6 @@ int NetClientSelectScenario(void) { char *cp; - FreeMapInfo(MenuMapInfo); - MenuMapInfo = NULL; - cp = strrchr(MenuMapFullPath, '/'); if (cp) { strcpy(ScenSelectFileName, cp + 1); @@ -4383,12 +4381,13 @@ int NetClientSelectScenario(void) ScenSelectPath[0] = 0; } + FreeMapInfo(&TheMap.Info); if (strcasestr(ScenSelectFileName, ".pud")) { - MenuMapInfo = GetPudInfo(MenuMapFullPath); + GetPudInfo(MenuMapFullPath, &TheMap.Info); } else { - // FIXME: GetCmInfo(); + LuaLoadFile(MenuMapFullPath); } - return MenuMapInfo == NULL; + return 1; } /** @@ -4520,12 +4519,11 @@ static void EditorNewMap(void) return; } - TheMap.Info = calloc(1, sizeof(MapInfo)); description[strlen(description) - 3] = '\0'; - TheMap.Info->Description = strdup(description); - TheMap.Info->MapTerrain = menu->Items[7].D.Pulldown.curopt; - TheMap.Info->MapWidth = atoi(width); - TheMap.Info->MapHeight = atoi(height); + TheMap.Info.Description = strdup(description); + TheMap.Info.MapTerrain = menu->Items[7].D.Pulldown.curopt; + TheMap.Info.MapWidth = atoi(width); + TheMap.Info.MapHeight = atoi(height); VideoClearScreen(); @@ -4761,13 +4759,21 @@ static int EditorMainLoadRDFilter(char *pathbuf, FileList *fl) #endif if (*cp == 0) { if (strcasestr(np, ".pud")) { - info = GetPudInfo(pathbuf); + info = GetPudInfo(pathbuf, &TheMap.Info); if (info) { fl->type = 1; fl->name = strdup(np); - fl->xdata = info; + fl->xdata = DuplicateMapInfo(info); return 1; } + } else { + info = NULL; + fl->type = 1; + fl->name = strdup(np); + FreeMapInfo(&TheMap.Info); + LuaLoadFile(pathbuf); + fl->xdata = DuplicateMapInfo(&TheMap.Info); + return 1; } } } @@ -5074,7 +5080,7 @@ static void EditorMapPropertiesMenu(void) menu = FindMenu("menu-editor-map-properties"); menu->Items[2].D.Input.buffer = description; - strcpy(description, TheMap.Info->Description); + strcpy(description, TheMap.Info.Description); strcat(description, "~!_"); menu->Items[2].D.Input.nch = strlen(description) - 3; menu->Items[2].D.Input.maxch = 31; @@ -5114,19 +5120,19 @@ static void EditorMapPropertiesOk(void) description = menu->Items[2].D.Input.buffer; description[strlen(description)-3] = '\0'; - free(TheMap.Info->Description); - TheMap.Info->Description = strdup(description); + free(TheMap.Info.Description); + TheMap.Info.Description = strdup(description); // Change the terrain - old = TheMap.Info->MapTerrain; + old = TheMap.Info.MapTerrain; if (old != menu->Items[6].D.Pulldown.curopt) { - TheMap.Info->MapTerrain = menu->Items[6].D.Pulldown.curopt; - free(TheMap.Info->MapTerrainName); - TheMap.Info->MapTerrainName = strdup(TilesetWcNames[TheMap.Info->MapTerrain]); - TheMap.Terrain = TheMap.Info->MapTerrain; + TheMap.Info.MapTerrain = menu->Items[6].D.Pulldown.curopt; + free(TheMap.Info.MapTerrainName); + TheMap.Info.MapTerrainName = strdup(TilesetWcNames[TheMap.Info.MapTerrain]); + TheMap.Terrain = TheMap.Info.MapTerrain; free(TheMap.TerrainName); - TheMap.TerrainName = strdup(TilesetWcNames[TheMap.Info->MapTerrain]); - TheMap.Tileset = Tilesets[TheMap.Info->MapTerrain]; + TheMap.TerrainName = strdup(TilesetWcNames[TheMap.Info.MapTerrain]); + TheMap.Tileset = Tilesets[TheMap.Info.MapTerrain]; LoadTileset(); ChangeTilesetPud(old, &TheMap); @@ -5244,12 +5250,12 @@ static void EditorPlayerPropertiesMenu(void) #define OIL_POSITION 106 for (i = 0; i < PlayerMax; ++i) { - menu->Items[RACE_POSITION + i].D.Pulldown.defopt = TheMap.Info->PlayerSide[i]; - menu->Items[TYPE_POSITION + i].D.Pulldown.defopt = PlayerTypesFcToMenu[TheMap.Info->PlayerType[i]]; - menu->Items[AI_POSITION + i].D.Pulldown.defopt = PlayerAiFcToMenu(TheMap.Info->PlayerAi[i]); - sprintf(gold[i], "%d~!_", TheMap.Info->PlayerResources[i][GoldCost]); - sprintf(lumber[i], "%d~!_", TheMap.Info->PlayerResources[i][WoodCost]); - sprintf(oil[i], "%d~!_", TheMap.Info->PlayerResources[i][OilCost]); + menu->Items[RACE_POSITION + i].D.Pulldown.defopt = TheMap.Info.PlayerSide[i]; + menu->Items[TYPE_POSITION + i].D.Pulldown.defopt = PlayerTypesFcToMenu[TheMap.Info.PlayerType[i]]; + menu->Items[AI_POSITION + i].D.Pulldown.defopt = PlayerAiFcToMenu(TheMap.Info.PlayerAi[i]); + sprintf(gold[i], "%d~!_", TheMap.Info.PlayerResources[i][GoldCost]); + sprintf(lumber[i], "%d~!_", TheMap.Info.PlayerResources[i][WoodCost]); + sprintf(oil[i], "%d~!_", TheMap.Info.PlayerResources[i][OilCost]); menu->Items[GOLD_POSITION + i].D.Input.buffer = gold[i]; menu->Items[GOLD_POSITION + i].D.Input.nch = strlen(gold[i]) - 3; menu->Items[GOLD_POSITION + i].D.Input.maxch = 7; @@ -5264,12 +5270,12 @@ static void EditorPlayerPropertiesMenu(void) ProcessMenu("menu-editor-player-properties", 1); for (i = 0; i < PlayerMax; ++i) { - TheMap.Info->PlayerSide[i] = menu->Items[RACE_POSITION + i].D.Pulldown.curopt; - TheMap.Info->PlayerType[i] = PlayerTypesMenuToFc[menu->Items[TYPE_POSITION + i].D.Pulldown.curopt]; - TheMap.Info->PlayerAi[i] = PlayerAiMenuToFc(menu->Items[AI_POSITION + i].D.Pulldown.curopt); - TheMap.Info->PlayerResources[i][GoldCost] = atoi(gold[i]); - TheMap.Info->PlayerResources[i][WoodCost] = atoi(lumber[i]); - TheMap.Info->PlayerResources[i][OilCost] = atoi(oil[i]); + TheMap.Info.PlayerSide[i] = menu->Items[RACE_POSITION + i].D.Pulldown.curopt; + TheMap.Info.PlayerType[i] = PlayerTypesMenuToFc[menu->Items[TYPE_POSITION + i].D.Pulldown.curopt]; + TheMap.Info.PlayerAi[i] = PlayerAiMenuToFc(menu->Items[AI_POSITION + i].D.Pulldown.curopt); + TheMap.Info.PlayerResources[i][GoldCost] = atoi(gold[i]); + TheMap.Info.PlayerResources[i][WoodCost] = atoi(lumber[i]); + TheMap.Info.PlayerResources[i][OilCost] = atoi(oil[i]); } } @@ -6414,7 +6420,7 @@ static void ChangeGameServer(void) freespots = 0; players = 0; for (i = 0; i < PlayerMax - 1; ++i) { - if (MenuMapInfo->PlayerType[i] == PlayerPerson) { + if (TheMap.Info.PlayerType[i] == PlayerPerson) { ++players; } if (ServerSetupState.CompOpt[i] == 0) { diff --git a/src/ui/script_ui.cpp b/src/ui/script_ui.cpp index 2e4b77ff8..d9e2d6cc2 100644 --- a/src/ui/script_ui.cpp +++ b/src/ui/script_ui.cpp @@ -4437,6 +4437,38 @@ static int CclSetGroupKeys(lua_State* l) return 0; } +/** +** Set basic map caracteristics. +** +** @param l Lua state. +*/ +static int CclPresentMap(lua_State* l) +{ + if (lua_gettop(l) != 4) { + LuaError(l, "incorrect argument"); + } + TheMap.Info.Description = strdup(LuaToString(l, 1)); + // Number of players in LuaToNumber(l, 3); // Not used yet. + TheMap.Info.MapWidth = LuaToNumber(l, 3); + TheMap.Info.MapHeight = LuaToNumber(l, 4); + + return 0; +} + +/** +** Define the lua file that will be build the map +** +** @param l Lua state. +*/ +static int CclDefineMapSetup(lua_State* l) +{ + if (lua_gettop(l) != 1) { + LuaError(l, "incorrect argument"); + } + TheMap.Info.Filename = strdup(LuaToString(l, 1)); + return 0; +} + /** ** Add a keystroke help ** @@ -4523,6 +4555,9 @@ void UserInterfaceCclRegister(void) lua_register(Lua, "DefineMenu", CclDefineMenu); lua_register(Lua, "DefineMenuGraphics", CclDefineMenuGraphics); + lua_register(Lua, "PresentMap", CclPresentMap); + lua_register(Lua, "DefineMapSetup", CclDefineMapSetup); + // // Color cycling //