forked from Mirrors/openclonk
194 lines
4.1 KiB
C
194 lines
4.1 KiB
C
/*--
|
|
Capture The Flag
|
|
Author: Maikel
|
|
|
|
Capture the flag of the opposing team and bring it to your base to gain points.
|
|
--*/
|
|
|
|
|
|
#include Library_Goal
|
|
|
|
local score_list;
|
|
|
|
func ScoreboardTeamID(int team)
|
|
{
|
|
return team + 1000;
|
|
}
|
|
|
|
protected func Initialize()
|
|
{
|
|
score_list = [];
|
|
|
|
// init scoreboard
|
|
Scoreboard->Init(
|
|
[
|
|
{key = "title", title = "Teams"},
|
|
{key = "ctf", title = Goal_CaptureTheFlag, sorted = true, desc = true, default = 0, priority = 80}
|
|
]
|
|
);
|
|
Scoreboard->SetTitle("Capture the Flag");
|
|
|
|
return _inherited(...);
|
|
}
|
|
|
|
private func GetScoreGoal()
|
|
{
|
|
var flag_cnt = GameCall("CaptureFlagCount");
|
|
if (flag_cnt != nil)
|
|
return Max(1, flag_cnt);
|
|
return 1;
|
|
}
|
|
|
|
public func SetFlagBase(int team, float x, float y)
|
|
{
|
|
var base = CreateObject(Goal_FlagBase, x, y, NO_OWNER);
|
|
base->SetTeam(team);
|
|
var flag = CreateObject(Goal_Flag, x, y, NO_OWNER);
|
|
flag->SetAction("AttachBase", base);
|
|
flag->SetTeam(team);
|
|
return;
|
|
}
|
|
|
|
public func AddTeamScore(int team)
|
|
{
|
|
score_list[team]++;
|
|
|
|
Scoreboard->SetData(ScoreboardTeamID(team), "ctf", score_list[team]);
|
|
|
|
if (score_list[team] >= GetScoreGoal())
|
|
EliminateOthers(team);
|
|
return;
|
|
}
|
|
|
|
private func EliminateOthers(int win_team)
|
|
{
|
|
for (var i = 0; i < GetPlayerCount(); i++)
|
|
{
|
|
var plr = GetPlayerByIndex(i);
|
|
var team = GetPlayerTeam(plr);
|
|
if (team != win_team)
|
|
EliminatePlayer(plr);
|
|
}
|
|
return;
|
|
}
|
|
|
|
protected func InitializePlayer(int plr, num x, num y, object base, int team)
|
|
{
|
|
// Join new clonk.
|
|
JoinPlayer(plr);
|
|
|
|
// make scoreboard entry for team
|
|
Scoreboard->NewEntry(ScoreboardTeamID(team), GetTaggedTeamName(team));
|
|
|
|
// Broadcast to scenario.
|
|
GameCall("OnPlayerRelaunch", plr);
|
|
return _inherited(plr, ...);
|
|
}
|
|
|
|
protected func RelaunchPlayer(int plr)
|
|
{
|
|
// New clonk.
|
|
var clonk = CreateObject(Clonk, 0, 0, plr);
|
|
clonk->MakeCrewMember(plr);
|
|
SetCursor(plr, clonk);
|
|
// Join new clonk.
|
|
JoinPlayer(plr);
|
|
// Broadcast to scenario.
|
|
GameCall("OnPlayerRelaunch", plr);
|
|
return _inherited(plr, ...);
|
|
}
|
|
|
|
private func JoinPlayer(int plr)
|
|
{
|
|
var clonk = GetCrew(plr);
|
|
clonk->DoEnergy(100000);
|
|
var team = GetPlayerTeam(plr);
|
|
var base = FindObject(Find_ID(Goal_FlagBase), Find_Func("FindTeam", team));
|
|
if (base)
|
|
clonk->SetPosition(base->GetX(), base->GetY() - 10);
|
|
return;
|
|
}
|
|
|
|
protected func RemovePlayer(int plr)
|
|
{
|
|
|
|
return _inherited(plr, ...);
|
|
}
|
|
|
|
protected func RejectTeamSwitch(int player, int new_team)
|
|
{
|
|
// Prevent team switching in any case.
|
|
return true;
|
|
}
|
|
|
|
/*-- Goal interface --*/
|
|
|
|
public func IsFulfilled()
|
|
{
|
|
// If Teams.txt-Teams still need to be chosen, the goal cannot be fulfilled.
|
|
for (var i = 0; i < GetPlayerCount(); i++)
|
|
if (GetPlayerTeam(GetPlayerByIndex(i)) == -1)
|
|
return false;
|
|
// If only one team is left, the goal is fulfilled.
|
|
var teamcnt = 0;
|
|
for (var i = 0; i < GetTeamCount(); i++)
|
|
if (GetPlayerInTeamCount(GetTeamByIndex(i)))
|
|
teamcnt++;
|
|
if (teamcnt < 2)
|
|
return true;
|
|
// If one team has reached the score limit, the goal is fulfilled.
|
|
for (var i = 0; i < GetTeamCount(); i++)
|
|
{
|
|
var team = GetTeamByIndex(i);
|
|
if (score_list[team] >= GetScoreGoal())
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public func Activate(int byplr)
|
|
{
|
|
var flags = GetScoreGoal() - score_list[GetPlayerTeam(byplr)];
|
|
if (IsFulfilled())
|
|
MessageWindow("$MsgGoalFulfilled$", byplr);
|
|
else
|
|
{
|
|
var msg = "$MsgGoalCaptureTheFlag$";
|
|
if (flags == 1)
|
|
msg = Format("%s %s", msg, "$MsgGoalUnfulfilled1$");
|
|
else
|
|
msg = Format("%s %s", msg, Format("$MsgGoalUnfulfilledX$", flags));
|
|
|
|
MessageWindow(msg, byplr);
|
|
}
|
|
return;
|
|
}
|
|
|
|
public func GetShortDescription(int plr)
|
|
{
|
|
var team = GetPlayerTeam(plr);
|
|
var flag = FindObject(Find_ID(Goal_Flag), Find_Func("FindTeam", team));
|
|
var at_base = flag->IsAtBase();
|
|
if (!at_base)
|
|
return "$MsgShortCaptured$";
|
|
|
|
var cursor = GetCursor(plr);
|
|
flag = FindObject(Find_ID(Goal_Flag), Find_Not(Find_Func("FindTeam", team)), Find_Container(cursor));
|
|
if (flag)
|
|
return "$MsgShortReturn$";
|
|
|
|
return "$MsgShortSteal$";
|
|
}
|
|
|
|
// Returns the number of players in a specific team.
|
|
private func GetPlayerInTeamCount(int team)
|
|
{
|
|
var cnt = 0;
|
|
for (var i = 0; i < GetPlayerCount(); i++)
|
|
if (GetPlayerTeam(GetPlayerByIndex(i)) == team)
|
|
cnt++;
|
|
return cnt;
|
|
}
|
|
|
|
local Name = "$Name$";
|