HotIce: Fix initial player spawn

InitializePlayer() semantics differ in online and local games. In a
local game, InitializePlayers() is called before InitializePlayer(plr);
in an online game it's the other way around.

This also improves handling of players joining at runtime. Those
previously started at random positions.

Close GH-32
alut-include-path
Lukas Werling 2017-02-18 23:07:34 +01:00
parent a4492dd828
commit 16591ffe53
2 changed files with 33 additions and 9 deletions

View File

@ -30,6 +30,11 @@ public func InitializeMap(proplist map)
return true; return true;
} }
func SpawnPositionCount()
{
return Max(Max(GetStartupPlayerCount(), GetPlayerCount()), 2);
}
func DrawBigIslandMap(proplist map) func DrawBigIslandMap(proplist map)
{ {
var w = map.Wdt, h=map.Hgt; var w = map.Wdt, h=map.Hgt;
@ -49,7 +54,7 @@ func DrawBigIslandMap(proplist map)
map->Draw("^Ice-ice2", nil, [x,y,1,1]); map->Draw("^Ice-ice2", nil, [x,y,1,1]);
} }
// Player spawns simply in middle of big island // Player spawns simply in middle of big island
var plrcnt = Max(GetStartupPlayerCount(), 2); var plrcnt = SpawnPositionCount();
g_player_spawn_positions = CreateArray(plrcnt); g_player_spawn_positions = CreateArray(plrcnt);
for (var i = 0; i < plrcnt; ++i) for (var i = 0; i < plrcnt; ++i)
{ {
@ -78,7 +83,7 @@ func DrawSmallIslandsMap(proplist map)
if (SCENPAR_SpawnType == 1) if (SCENPAR_SpawnType == 1)
return true; return true;
// Starting islands for player spawns // Starting islands for player spawns
var spawn_island_count = Max(GetStartupPlayerCount(), 2); var spawn_island_count = SpawnPositionCount();
g_player_spawn_positions = CreateArray(spawn_island_count); g_player_spawn_positions = CreateArray(spawn_island_count);
for (var i = 0; i < spawn_island_count; ++i) for (var i = 0; i < spawn_island_count; ++i)
{ {

View File

@ -44,7 +44,7 @@ func ResetRound()
// Clear and redraw the map. // Clear and redraw the map.
LoadScenarioSection("main"); LoadScenarioSection("main");
InitializeRound(); InitializeRound();
InitializePlayers(); AssignHandicaps();
// Re-enable the players. // Re-enable the players.
for (var clonk in clonks) for (var clonk in clonks)
{ {
@ -124,12 +124,24 @@ func InitializePlayer(int plr)
Scoreboard->SetData(ScoreboardTeam(team), "team", "", ScoreboardTeam(team)); Scoreboard->SetData(ScoreboardTeam(team), "team", "", ScoreboardTeam(team));
Scoreboard->SetPlayerData(plr, "team", "", ScoreboardTeam(team) + 1); Scoreboard->SetPlayerData(plr, "team", "", ScoreboardTeam(team) + 1);
return InitPlayerRound(plr); // Players joining at runtime will participate in the following round.
PutInRelaunchContainer(GetCrew(plr));
// On non-network rounds, InitializePlayers is called before InitializePlayer. Thus, we have to
// join the players here.
// TODO: Maybe find a better way to detect this case.
if (!IsNetwork())
InitPlayerRound(plr);
} }
func InitializePlayers() func InitializePlayers()
{ {
AssignHandicaps(); AssignHandicaps();
for (var i = 0; i < GetPlayerCount(); i++)
{
var plr = GetPlayerByIndex(i);
InitPlayerRound(plr);
}
} }
func InitPlayerRound(int plr) func InitPlayerRound(int plr)
@ -142,6 +154,7 @@ func InitPlayerRound(int plr)
// Player positioning. // Player positioning.
var ls_wdt = LandscapeWidth(), ls_hgt = LandscapeHeight(); var ls_wdt = LandscapeWidth(), ls_hgt = LandscapeHeight();
var crew = GetCrew(plr), start_pos; var crew = GetCrew(plr), start_pos;
if (!crew) return;
// Position by map type? // Position by map type?
if (SCENPAR_SpawnType == 0) if (SCENPAR_SpawnType == 0)
{ {
@ -231,6 +244,16 @@ func OnCountdownFinished()
} }
} }
func PutInRelaunchContainer(object clonk)
{
var plr = clonk->GetOwner();
var relaunch = CreateObject(RelaunchContainer, LandscapeWidth() / 2, LandscapeHeight() / 2, plr);
// We just use the relaunch object as a dumb container.
clonk->Enter(relaunch);
// Allow scrolling around the landscape.
SetPlayerViewLock(plr, false);
}
func OnClonkDeath(object clonk) func OnClonkDeath(object clonk)
{ {
var plr = clonk->GetOwner(); var plr = clonk->GetOwner();
@ -241,11 +264,7 @@ func OnClonkDeath(object clonk)
{ {
var crew = CreateObject(Clonk, 0, 0, plr); var crew = CreateObject(Clonk, 0, 0, plr);
crew->MakeCrewMember(plr); crew->MakeCrewMember(plr);
var relaunch = CreateObject(RelaunchContainer, LandscapeWidth() / 2, LandscapeHeight() / 2, plr); PutInRelaunchContainer(crew);
// We just use the relaunch object as a dumb container.
crew->Enter(relaunch);
// Allow scrolling around the landscape.
SetPlayerViewLock(plr, false);
} }
// Check for victory after three seconds to allow stalemates. // Check for victory after three seconds to allow stalemates.