-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lua: Allow setting number of players, and placing HQs. Then fix the mission on map "The snake" #1683
base: master
Are you sure you want to change the base?
Lua: Allow setting number of players, and placing HQs. Then fix the mission on map "The snake" #1683
Changes from all commits
7625b14
d2e885c
dbd105d
47b869f
9ea584a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
#include "WineLoader.h" | ||
#include "addons/const_addons.h" | ||
#include "buildings/noBuildingSite.h" | ||
#include "buildings/nobHQ.h" | ||
#include "buildings/nobHarborBuilding.h" | ||
#include "buildings/nobMilitary.h" | ||
#include "buildings/nobUsual.h" | ||
|
@@ -411,6 +412,19 @@ void GamePlayer::RemoveBuildingSite(noBuildingSite* bldSite) | |
buildings.Remove(bldSite); | ||
} | ||
|
||
bool GamePlayer::IsHQTent() const | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the reason for adding this here? It isn't used (yet) |
||
{ | ||
if(const nobHQ* hq = GetHQ()) | ||
return hq->IsTent(); | ||
return false; | ||
} | ||
|
||
void GamePlayer::SetHQIsTent(bool isTent) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This and I'm thinking about the case where there are multiple HQs (e.g. the S2 cheats had it) and one might want to specify which HQ to change. Putting the code in the caller uses the world to get a specific HQ and changes that. Although we already have |
||
{ | ||
if(nobHQ* hq = const_cast<nobHQ*>(GetHQ())) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I missed that If you make |
||
hq->SetIsTent(isTent); | ||
} | ||
|
||
void GamePlayer::AddBuilding(noBuilding* bld, BuildingType bldType) | ||
{ | ||
RTTR_Assert(bld->GetPlayer() == GetPlayerId()); | ||
|
@@ -1400,6 +1414,12 @@ void GamePlayer::TestDefeat() | |
Surrender(); | ||
} | ||
|
||
const nobHQ* GamePlayer::GetHQ() const | ||
{ | ||
const MapPoint& hqPos = GetHQPos(); | ||
return hqPos.isValid() ? GetGameWorld().GetSpecObj<nobHQ>(hqPos) : nullptr; | ||
} | ||
|
||
void GamePlayer::Surrender() | ||
{ | ||
if(isDefeated) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,7 @@ | |
#include "ingameWindows/iwMsgbox.h" | ||
#include "lua/LuaInterfaceSettings.h" | ||
#include "network/GameClient.h" | ||
#include "network/GameServer.h" | ||
#include "ogl/FontStyle.h" | ||
#include "gameData/GameConsts.h" | ||
#include "gameData/const_gui_ids.h" | ||
|
@@ -102,6 +103,13 @@ dskGameLobby::dskGameLobby(ServerType serverType, std::shared_ptr<GameLobby> gam | |
RTTR_Assert(gameLobby_->isHost()); | ||
LOG.write(_("Lua was disabled by the script itself\n")); | ||
lua.reset(); | ||
} else | ||
{ | ||
if(const auto num = lua->GetNumPlayersFromScript()) | ||
{ | ||
GAMESERVER.SetNumPlayers(num); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This won't work for savegames, will it? Because I think for a savegame the player needs to be already initialized. |
||
gameLobby_->setNumPlayers(num); | ||
} | ||
} | ||
if(!lua && gameLobby_->isHost()) | ||
lobbyController->RemoveLuaScript(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -247,3 +247,13 @@ bool LuaInterfaceSettings::IsMapPreviewEnabled() | |
} | ||
return true; | ||
} | ||
|
||
unsigned LuaInterfaceSettings::GetNumPlayersFromScript() | ||
{ | ||
kaguya::LuaRef func = lua["getNumPlayers"]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add documentation for this new function. |
||
if(func.type() == LUA_TFUNCTION) | ||
{ | ||
return func.call<unsigned>(); | ||
} | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -36,6 +36,7 @@ class LuaInterfaceSettings : public LuaInterfaceGameBase | |||||||
/// Get addons that are allowed to be changed | ||||||||
std::vector<AddonId> GetAllowedAddons(); | ||||||||
bool IsMapPreviewEnabled(); | ||||||||
unsigned GetNumPlayersFromScript(); | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Or maybe returning an optional is more clear and disallow zero for lua files. |
||||||||
|
||||||||
private: | ||||||||
IGameLobbyController& lobbyServerController_; | ||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -9,6 +9,7 @@ | |||||||||||||||||
#include "ai/AIPlayer.h" | ||||||||||||||||||
#include "buildings/nobBaseWarehouse.h" | ||||||||||||||||||
#include "buildings/nobHQ.h" | ||||||||||||||||||
#include "factories/BuildingFactory.h" | ||||||||||||||||||
#include "helpers/EnumRange.h" | ||||||||||||||||||
#include "helpers/toString.h" | ||||||||||||||||||
#include "lua/LuaHelpers.h" | ||||||||||||||||||
|
@@ -46,6 +47,7 @@ void LuaPlayer::Register(kaguya::State& state) | |||||||||||||||||
.addFunction("GetNumPeople", &LuaPlayer::GetNumPeople) | ||||||||||||||||||
.addFunction("GetStatisticsValue", &LuaPlayer::GetStatisticsValue) | ||||||||||||||||||
.addFunction("AIConstructionOrder", &LuaPlayer::AIConstructionOrder) | ||||||||||||||||||
.addFunction("PlaceHQ", &LuaPlayer::PlaceHQ) | ||||||||||||||||||
.addFunction("ModifyHQ", &LuaPlayer::ModifyHQ) | ||||||||||||||||||
.addFunction("GetHQPos", &LuaPlayer::GetHQPos) | ||||||||||||||||||
.addFunction("IsDefeated", &LuaPlayer::IsDefeated) | ||||||||||||||||||
|
@@ -259,15 +261,22 @@ bool LuaPlayer::AIConstructionOrder(unsigned x, unsigned y, lua::SafeEnum<Buildi | |||||||||||||||||
return true; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
void LuaPlayer::PlaceHQ(MapCoord x, MapCoord y) | ||||||||||||||||||
{ | ||||||||||||||||||
// Ignore if there is an HQ set in the map file. | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't actually care about the map file directly. A script might (attempt to) set the HQ multiple times. Or re-add it if destroyed.
Suggested change
|
||||||||||||||||||
if(player.GetHQPos().isValid()) | ||||||||||||||||||
return; | ||||||||||||||||||
|
||||||||||||||||||
GameWorld& world = player.GetGameWorld(); | ||||||||||||||||||
const MapPoint mp{x, y}; | ||||||||||||||||||
constexpr auto checkExists = false; | ||||||||||||||||||
world.DestroyNO(mp, checkExists); | ||||||||||||||||||
BuildingFactory::CreateBuilding(world, BuildingType::Headquarters, mp, player.GetPlayerId(), player.nation); | ||||||||||||||||||
Comment on lines
+271
to
+274
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Better use
Suggested change
|
||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
void LuaPlayer::ModifyHQ(bool isTent) | ||||||||||||||||||
{ | ||||||||||||||||||
const MapPoint hqPos = player.GetHQPos(); | ||||||||||||||||||
if(hqPos.isValid()) | ||||||||||||||||||
{ | ||||||||||||||||||
auto* hq = player.GetGameWorld().GetSpecObj<nobHQ>(hqPos); | ||||||||||||||||||
if(hq) | ||||||||||||||||||
hq->SetIsTent(isTent); | ||||||||||||||||||
} | ||||||||||||||||||
player.SetHQIsTent(isTent); | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
bool LuaPlayer::IsDefeated() const | ||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -323,8 +323,10 @@ void GameClient::StartGame(const unsigned random_init) | |||||||||||||||||||
gameWorld.GetPlayer(i).MakeStartPacts(); | ||||||||||||||||||||
|
||||||||||||||||||||
MapLoader loader(gameWorld); | ||||||||||||||||||||
if(!loader.Load(mapinfo.filepath) | ||||||||||||||||||||
|| (!mapinfo.luaFilepath.empty() && !loader.LoadLuaScript(*game, *this, mapinfo.luaFilepath))) | ||||||||||||||||||||
if((!mapinfo.luaFilepath.empty() && !loader.LoadLuaScript(*game, *this, mapinfo.luaFilepath)) | ||||||||||||||||||||
|| !loader.Load(mapinfo.filepath)) // Do not reorder: load lua first, load map second. | ||||||||||||||||||||
// If the map is loaded first and it does not have a player HQ set, it | ||||||||||||||||||||
// will not load correctly, even though the HQ may be set using LUA. | ||||||||||||||||||||
Comment on lines
+326
to
+329
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still find it hard to understand why it will "not load correctly" and what loading the script first changes. What about:
Suggested change
|
||||||||||||||||||||
{ | ||||||||||||||||||||
OnError(ClientError::InvalidMap); | ||||||||||||||||||||
return; | ||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -526,6 +526,11 @@ bool GameServer::assignPlayersOfRandomTeams(std::vector<JoinPlayerInfo>& playerI | |||||||||||||
return playerWasAssigned; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
void GameServer::SetNumPlayers(unsigned num) | ||||||||||||||
{ | ||||||||||||||
playerInfos.resize(num); | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should add a check
Suggested change
Not sure about the 2nd check as the value is likely from a lua script. So maybe rather return false here and abort the game in the caller. |
||||||||||||||
} | ||||||||||||||
|
||||||||||||||
/** | ||||||||||||||
* startet das Spiel. | ||||||||||||||
*/ | ||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -52,6 +52,8 @@ class GameServer : | |||||||
/// Assign players that do not have a fixed team, return true if any player was assigned. | ||||||||
static bool assignPlayersOfRandomTeams(std::vector<JoinPlayerInfo>& playerInfos); | ||||||||
|
||||||||
void SetNumPlayers(unsigned num); | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe document as something like:
Suggested change
|
||||||||
|
||||||||
private: | ||||||||
bool StartGame(); | ||||||||
|
||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -409,8 +409,9 @@ bool MapLoader::PlaceHQs(GameWorldBase& world, std::vector<MapPoint> hqPositions | |
// Does the HQ have a position? | ||
if(i >= hqPositions.size() || !hqPositions[i].isValid()) | ||
{ | ||
LOG.write(_("Player %u does not have a valid start position!")) % i; | ||
return false; | ||
LOG.write(_("Player %u does not have a valid start position!\n")) % i; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs an update to the translations. I used a quick regex-search-replace in that repo. Please update the submodule external/languages to the current master (revision fa7f546) |
||
if(!world.HasLua()) // HQ can be placed in the script, so don't signal error | ||
return false; | ||
} | ||
|
||
BuildingFactory::CreateBuilding(world, BuildingType::Headquarters, hqPositions[i], i, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See below.
Maybe even remove the part in the parentheses