Hot Ice: Add option for multiple rounds

liquid_container
Lukas Werling 2016-03-09 00:07:47 +01:00
parent 21cbf97562
commit d2836bb70a
6 changed files with 195 additions and 0 deletions

View File

@ -7,10 +7,15 @@
static g_player_spawn_positions;
static g_map_width;
static g_seed;
// Called be the engine: draw the complete map here.
public func InitializeMap(proplist map)
{
// Reloading the scenario section also resets the RNG. Call Random() a few times to get a new map each round.
var i = g_seed++;
while (i--) Random(2);
// Map type 0: One big island; more small islands above
// Map type 1: Only many small islands
var t = SCENPAR_MapType;

View File

@ -33,3 +33,31 @@ Default=0
Name=$WeaponsExplosive$
Description=$DescWeaponsExplosive$
Value=1
[ParameterDef]
Name=$Rounds$
Description=$DescRounds$
ID=Rounds
Default=1
[Options]
[Option]
Name=1
Value=1
[Option]
Name=2
Value=2
[Option]
Name=3
Value=3
[Option]
Name=5
Value=5
[Option]
Name=7
Value=7

View File

@ -1,7 +1,51 @@
/* Hot ice */
static g_remaining_rounds, g_winners, g_check_victory_effect;
func Initialize()
{
g_remaining_rounds = SCENPAR_Rounds;
g_winners = [];
InitializeRound();
}
// Resets the scenario, redrawing the map.
func ResetRound()
{
// Retrieve all Clonks.
var clonks = FindObjects(Find_OCF(OCF_CrewMember));
for (var clonk in clonks)
{
var container = clonk->Contained();
if (container)
{
clonk->Exit();
container->RemoveObject();
}
clonk->SetObjectStatus(C4OS_INACTIVE);
}
// Clear and redraw the map.
LoadScenarioSection("Empty");
LoadScenarioSection("main");
InitializeRound();
// Re-enable the players.
for (var clonk in clonks)
{
clonk->SetObjectStatus(C4OS_NORMAL);
SetCursor(clonk->GetOwner(), clonk);
// Select the first item. This fixes item ordering.
clonk->SetHandItemPos(0, 0);
InitializePlayer(clonk->GetOwner());
}
}
func InitializeRound()
{
// Checking for victory: Only active after a Clonk dies.
g_check_victory_effect = AddEffect("CheckVictory", nil, 1, 0);
g_player_spawn_index = 0;
ShuffleArray(g_player_spawn_positions);
// Materials: Chests
var i,pos;
var ls_wdt = LandscapeWidth(), ls_hgt = LandscapeHeight();
@ -93,6 +137,110 @@ func InitializePlayer(int plr)
return true;
}
func OnClonkDeath(object clonk)
{
var plr = clonk->GetOwner();
// Skip eliminated players, NO_OWNER, etc.
if (!GetPlayerName(plr))
return true;
var crew = CreateObject(Clonk, 0, 0, plr);
crew->MakeCrewMember(plr);
var relaunch = CreateObject(RelaunchContainer, LandscapeWidth() / 2, LandscapeHeight() / 2, plr);
// We just use the relaunch object as a dumb container.
crew->Enter(relaunch);
// Check for victory after three seconds to allow stalemates.
g_check_victory_effect.Interval = 36 * 3;
}
// Returns a list of colored player names, for example "Sven2, Maikel, Luchs"
global func GetTeamPlayerNames(int team)
{
var str = "";
for (var i = 0; i < GetPlayerCount(); i++)
{
var plr = GetPlayerByIndex(i);
if (GetPlayerTeam(plr) == team)
{
var comma = "";
if (str != "") comma = ", ";
str = Format("%s%s<c %x>%s</c>", str, comma, GetPlayerColor(plr), GetPlayerName(plr));
}
}
return str;
}
global func FxCheckVictoryTimer(_, proplist effect)
{
var find_living = Find_And(Find_OCF(OCF_CrewMember), Find_NoContainer());
var clonk = FindObject(find_living);
if (!clonk)
{
// Stalemate!
Log("$Stalemate$");
GameCall("ResetRound");
}
else if (!FindObject(find_living, Find_Hostile(clonk->GetOwner())))
{
// We have a winner!
var team = GetPlayerTeam(clonk->GetOwner());
PushBack(g_winners, team);
// Announce the winning team.
Log("$WinningTeam$", GetTeamPlayerNames(team));
if (--g_remaining_rounds > 0 || GetLeadingTeam() == nil)
{
if (g_remaining_rounds == 1)
Log("$LastRound$");
else if (g_remaining_rounds > 1)
Log("$RemainingRounds$", g_remaining_rounds);
else
Log("$Tiebreak$");
GameCall("ResetRound");
}
else
{
GameCall("EliminateLosers");
}
}
// Go to sleep again.
effect.Interval = 0;
return FX_OK;
}
// Returns the team which won the most rounds, or nil if there is a tie.
global func GetLeadingTeam()
{
var teams = [], winning_team = g_winners[0];
for (var w in g_winners)
{
teams[w] += 1;
if (teams[w] > teams[winning_team])
winning_team = w;
}
// Detect a tie.
for (var i = 0; i < GetLength(teams); i++)
{
if (i != winning_team && teams[i] == teams[winning_team])
return nil;
}
return winning_team;
}
func EliminateLosers()
{
// Determine the winning team.
var winning_team = GetLeadingTeam();
// Eliminate everybody who isn't on the winning team.
for (var i = 0; i < GetPlayerCount(); i++)
{
var plr = GetPlayerByIndex(i);
if (GetPlayerTeam(plr) != winning_team)
EliminatePlayer(plr);
}
// The scenario goal will end the scenario.
}
/* Called periodically in grenade launcher */
func ReplenishLauncherAmmo()
{

View File

@ -10,3 +10,10 @@ WeaponsClassic=Klassisch
DescWeaponsClassic=Bögen, Speere, Keulen und einige Feuersteine
WeaponsExplosive=Explosiv
DescWeaponsExplosive=Nur Granatwerfer mit Endlosmunition
Rounds=Rundenzahl
DescRounds=Mehrere Runden spielen
Stalemate=Unentschieden!
WinningTeam=Gewinner: %s
RemainingRounds=Noch %d Runden.
LastRound=Letzte Runde!
Tiebreak=Entscheidende Runde!

View File

@ -10,3 +10,10 @@ WeaponsClassic=Classic
DescWeaponsClassic=Bows, spears and clubs available in chests
WeaponsExplosive=Explosive
DescWeaponsExplosive=Only grenade lauchers and wind bags available
Rounds=Number of rounds
DescRounds=Play for multiple rounds
Stalemate=Stalemate!
WinningTeam=Winning team: %s
RemainingRounds=%d rounds remaining.
LastRound=Last round!
Tiebreak=Tiebreak!