forked from Mirrors/openclonk
Parkour(some bugfixes and new features).
parent
a74e1d2c06
commit
184b463a39
|
@ -1,9 +1,8 @@
|
|||
[DefCore]
|
||||
id=MELE
|
||||
id=Core_Goal_Melee
|
||||
Version=4,10,0,0
|
||||
Category=C4D_StaticBack|C4D_Goal
|
||||
MaxUserSelect=1
|
||||
Width=1
|
||||
Height=1
|
||||
Value=100
|
||||
Picture=0,0,64,64
|
||||
|
|
|
@ -50,7 +50,7 @@ public func IsFulfilled()
|
|||
return true;
|
||||
}
|
||||
|
||||
protected func Activate(int byplr)
|
||||
public func Activate(int byplr)
|
||||
{
|
||||
// Count enemy players.
|
||||
var hostile_count;
|
||||
|
@ -71,6 +71,11 @@ protected func Activate(int byplr)
|
|||
return;
|
||||
}
|
||||
|
||||
public func GetShortDescription(int plr)
|
||||
{
|
||||
return ""; // TODO
|
||||
}
|
||||
|
||||
func Definition(def) {
|
||||
SetProperty("Name", "$Name$", def);
|
||||
}
|
|
@ -20,42 +20,42 @@ static const RACE_CP_Check = 8;
|
|||
static const RACE_CP_Ordered = 16;
|
||||
static const RACE_CP_Bonus = 32;
|
||||
|
||||
public func SetCPMode(int iMode)
|
||||
public func SetCPMode(int mode)
|
||||
{
|
||||
if (iMode & RACE_CP_Start) // Start always occurs alone.
|
||||
iMode = RACE_CP_Start;
|
||||
if (iMode & RACE_CP_Finish) // Start always occurs alone.
|
||||
iMode = RACE_CP_Finish;
|
||||
if (iMode & RACE_CP_Ordered) // Ordered checkpoints must have RACE_CP_Check.
|
||||
if (mode & RACE_CP_Start) // Start always occurs alone.
|
||||
mode = RACE_CP_Start;
|
||||
if (mode & RACE_CP_Finish) // Start always occurs alone.
|
||||
mode = RACE_CP_Finish;
|
||||
if (mode & RACE_CP_Ordered) // Ordered checkpoints must have RACE_CP_Check.
|
||||
{
|
||||
iMode = iMode | RACE_CP_Check;
|
||||
mode = mode | RACE_CP_Check;
|
||||
// Set CP number.
|
||||
SetCPNumber(ObjectCount(Find_ID(GetID()), Find_Func("GetCPNumber")) + 1);
|
||||
}
|
||||
CP_Mode = iMode;
|
||||
CP_Mode = mode;
|
||||
UpdateGraphics();
|
||||
return;
|
||||
}
|
||||
|
||||
public func GetCPMode() { return CP_Mode; }
|
||||
|
||||
public func FindCPMode(int iMode) { return CP_Mode & iMode; }
|
||||
public func FindCPMode(int mode) { return CP_Mode & mode; }
|
||||
|
||||
/*-- Checkpoint controller --*/
|
||||
local CP_Con;
|
||||
|
||||
public func SetCPController(object pCon)
|
||||
public func SetCPController(object con)
|
||||
{
|
||||
CP_Con = pCon;
|
||||
CP_Con = con;
|
||||
return;
|
||||
}
|
||||
|
||||
/*-- Checkpoint number --*/
|
||||
local CP_Num;
|
||||
|
||||
public func SetCPNumber(int iNum)
|
||||
public func SetCPNumber(int num)
|
||||
{
|
||||
CP_Num = iNum;
|
||||
CP_Num = num;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -78,23 +78,24 @@ protected func Initialize()
|
|||
|
||||
/*-- Checkpoint status --*/
|
||||
|
||||
public func ClearedByPlr(int iPlr)
|
||||
public func ClearedByPlr(int plr)
|
||||
{
|
||||
return aDoneByPlr[iPlr];
|
||||
var plrid = GetPlayerID(plr);
|
||||
return aDoneByPlr[plrid];
|
||||
}
|
||||
|
||||
public func ClearedByTeam(int iTeam)
|
||||
public func ClearedByTeam(int team)
|
||||
{
|
||||
return aDoneByTeam[iTeam];
|
||||
return aDoneByTeam[team];
|
||||
}
|
||||
|
||||
public func IsActiveForPlr(int iPlr)
|
||||
public func IsActiveForPlr(int plr)
|
||||
{
|
||||
if (CP_Mode & RACE_CP_Finish) // Check all checkpoints.
|
||||
{
|
||||
for (var cp in FindObjects(Find_ID(GetID())))
|
||||
if (cp->GetCPMode() & RACE_CP_Check)
|
||||
if (!cp->ClearedByPlr(iPlr))
|
||||
if (!cp->ClearedByPlr(plr))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -104,19 +105,19 @@ public func IsActiveForPlr(int iPlr)
|
|||
return true;
|
||||
for (var cp in FindObjects(Find_ID(GetID()), Find_Func("GetCPNumber")))
|
||||
if (cp->GetCPNumber() + 1 == GetCPNumber())
|
||||
if (cp->ClearedByPlr(iPlr))
|
||||
if (cp->ClearedByPlr(plr))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public func IsActiveForTeam(int iTeam)
|
||||
public func IsActiveForTeam(int team)
|
||||
{
|
||||
if (!iTeam)
|
||||
if (!team)
|
||||
return false;
|
||||
for (var i = 0; i < GetPlayerCount(); i++)
|
||||
if (GetPlayerTeam(GetPlayerByIndex(i)) == iTeam)
|
||||
if (GetPlayerTeam(GetPlayerByIndex(i)) == team)
|
||||
if (IsActiveForPlr(GetPlayerByIndex(i)))
|
||||
return true;
|
||||
return false;
|
||||
|
@ -135,49 +136,49 @@ protected func CheckForClonks()
|
|||
// Loop through all clonks inside the checkpoint.
|
||||
for (var pClonk in FindObjects(Find_OCF(OCF_CrewMember), Find_Distance(20)))
|
||||
{
|
||||
var iPlr = pClonk->GetOwner();
|
||||
var iTeam = GetPlayerTeam(iPlr);
|
||||
// Check whether this CP is already activated for iPlr or its team.
|
||||
if (!IsActiveForPlr(iPlr))
|
||||
if (!IsActiveForTeam(iTeam))
|
||||
var plr = pClonk->GetOwner();
|
||||
var team = GetPlayerTeam(plr);
|
||||
var plrid = GetPlayerID(plr);
|
||||
// Check whether this CP is already activated for player or its team.
|
||||
if (!IsActiveForPlr(plr) && !IsActiveForTeam(team))
|
||||
continue;
|
||||
// Check respawn status.
|
||||
if (CP_Mode & RACE_CP_Respawn)
|
||||
if (CP_Con)
|
||||
CP_Con->SetPlrRespawnCP(iPlr, this); // Notify race goal.
|
||||
CP_Con->SetPlrRespawnCP(plr, this); // Notify race goal.
|
||||
// If already done by player -> continue.
|
||||
if (aDoneByPlr[iPlr])
|
||||
if (aDoneByPlr[plrid])
|
||||
continue;
|
||||
// Check checkpoint status.
|
||||
if (CP_Mode & RACE_CP_Check)
|
||||
{
|
||||
aDoneByPlr[iPlr] = true;
|
||||
Sound("Cleared", false, nil, iPlr);
|
||||
if (!iTeam)
|
||||
aDoneByPlr[plrid] = true;
|
||||
Sound("Cleared", false, nil, plr);
|
||||
if (!team)
|
||||
if (CP_Con)
|
||||
CP_Con->AddPlrClearedCP(iPlr); // Notify race goal.
|
||||
if (iTeam && !aDoneByTeam[iTeam])
|
||||
CP_Con->AddPlrClearedCP(plr); // Notify race goal.
|
||||
if (team && !aDoneByTeam[team])
|
||||
{
|
||||
aDoneByTeam[iTeam] = true;
|
||||
aDoneByTeam[team] = true;
|
||||
if (CP_Con)
|
||||
CP_Con->AddPlrClearedCP(iPlr); // Notify race goal.
|
||||
CP_Con->AddPlrClearedCP(plr); // Notify race goal.
|
||||
}
|
||||
UpdateColor();
|
||||
}
|
||||
// Check finish status.
|
||||
if (CP_Mode & RACE_CP_Finish)
|
||||
{
|
||||
Sound("Cleared", false, nil, iPlr);
|
||||
aDoneByPlr[iPlr] = true;
|
||||
if (iTeam)
|
||||
aDoneByTeam[iTeam] = true;
|
||||
Sound("Cleared", false, nil, plr);
|
||||
aDoneByPlr[plrid] = true;
|
||||
if (team)
|
||||
aDoneByTeam[team] = true;
|
||||
if (CP_Con)
|
||||
CP_Con->PlayerHasReachedFinish(iPlr); // Notify race goal.
|
||||
CP_Con->PlrReachedFinishCP(plr); // Notify race goal.
|
||||
UpdateColor();
|
||||
}
|
||||
// Check bonus.
|
||||
if (CP_Mode & RACE_CP_Bonus)
|
||||
GameCall("GivePlrBonus", iPlr, this);
|
||||
GameCall("GivePlrBonus", plr, this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -208,11 +209,18 @@ protected func UpdateGraphics()
|
|||
SetGraphics("Check", GetID(), 3, GFXOV_MODE_Base);
|
||||
SetObjDrawTransform(1000, 0, 6000, 0, 1000, -3000, 3);
|
||||
}
|
||||
// Ordered.
|
||||
// Ordered, display numbers up to 99.
|
||||
if (CP_Mode & RACE_CP_Ordered)
|
||||
{
|
||||
SetGraphics(Format("%d", GetCPNumber()), NUMB, 4, GFXOV_MODE_Base);
|
||||
SetObjDrawTransform(200, 0, 0, 0, 200, 9000, 4);
|
||||
if (GetCPNumber() >= 10)
|
||||
{
|
||||
SetGraphics(Format("%d", GetCPNumber()/10), NUMB, 5, GFXOV_MODE_Base);
|
||||
SetObjDrawTransform(200, 0, -2500, 0, 200, 9000, 5);
|
||||
SetClrModulation(RGBa(255, 255, 255, 128) , 5);
|
||||
}
|
||||
SetGraphics(Format("%d", GetCPNumber()%10), NUMB, 4, GFXOV_MODE_Base);
|
||||
SetObjDrawTransform(200, 0, 2500, 0, 200, 9000, 4);
|
||||
SetClrModulation(RGBa(255, 255, 255, 128) , 4);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -230,18 +238,20 @@ protected func UpdateColor()
|
|||
for (var i = 0; i < GetLength(aDoneByPlr); i++)
|
||||
{
|
||||
if (aDoneByPlr[i])
|
||||
{
|
||||
SetGraphics("Ring8", GetID(), 5 + i, GFXOV_MODE_Base);
|
||||
SetClrModulation(GetPlrColor(i), 5 + i);
|
||||
{ // Does not work with TeamColors=1.
|
||||
SetGraphics("Ring8", GetID(), 6 + i, GFXOV_MODE_Base);
|
||||
SetClrModulation(GetPlrColor(GetPlayerByIndex(ringsec)), 6 + i); //WRONG.
|
||||
var angle = ringsec * 45;
|
||||
var s = Sin(angle, 1000), c = Cos(angle, 1000);
|
||||
SetObjDrawTransform(c, s, 0, -s, c, 0, 5 + i);
|
||||
SetObjDrawTransform(c, s, 0, -s, c, 0, 6 + i);
|
||||
ringsec++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*-- Proplist --*/
|
||||
|
||||
func Definition(def) {
|
||||
SetProperty("Name", "$Name$", def);
|
||||
}
|
||||
|
|
|
@ -8,17 +8,26 @@
|
|||
* Check: On/Off - The clonk must pass through these checkpoints before being able to finish.
|
||||
* Ordered: On/Off - The checkpoints mussed be passed in the order specified.
|
||||
* The start and finish are also checkpoints.
|
||||
ToDo: Scoreboard, Teams, Color update CP, relative distance to next CP in scoreboard.
|
||||
ToDo:
|
||||
* Scoreboard with teams -> commented away, since bugs.
|
||||
* Update CP Graphics.
|
||||
* Relative distance to next CP in scoreboard -> done.
|
||||
* Arrow showing direction to next CP -> partially done.
|
||||
* maybe update array access to plrID -> done.
|
||||
* Add evaluation data.
|
||||
*/
|
||||
|
||||
#include GOAL
|
||||
|
||||
local fFinished; // Whether the goal has been reached by some player.
|
||||
local aCheckpoints; // List of checkpoints.
|
||||
local nrCheckpoints; // Nr. of checkpoints.
|
||||
local nrCheckpoints; // Number of checkpoints.
|
||||
local aRespawnCP; // List of last reached respawn CP per player.
|
||||
local aPlrCP; // Number of checkpoints the player completed.
|
||||
local aTeamCP; // Number of checkpoints the team completed.
|
||||
local szBestTimeString; // String for best time storage in player file.
|
||||
|
||||
/*-- General --*/
|
||||
|
||||
protected func Initialize()
|
||||
{
|
||||
|
@ -28,44 +37,48 @@ protected func Initialize()
|
|||
aRespawnCP = [];
|
||||
aPlrCP = [];
|
||||
aTeamCP = [];
|
||||
// Best time tracking.
|
||||
szBestTimeString = Format("PARK_%s_BestTime", GetScenTitle());
|
||||
AddEffect("IntBestTime", this, 100, 1, this);
|
||||
// Activate restart rule, if there isn't any.
|
||||
if (!FindObject(Find_ID(Core_Rule_Restart)))
|
||||
CreateObject(Core_Rule_Restart, 0, 0, NO_OWNER);
|
||||
|
||||
// Scoreboard distance display.
|
||||
InitScoreboard();
|
||||
AddEffect("IntSBDistance", this, 100, 35, this);
|
||||
return _inherited(...);
|
||||
}
|
||||
|
||||
/*-- Checkpoint creation --*/
|
||||
|
||||
public func SetStartpoint(int iX, int iY)
|
||||
public func SetStartpoint(int x, int y)
|
||||
{
|
||||
var cp = CreateObject(Core_Goal_Checkpoint, iX, iY, NO_OWNER);
|
||||
cp->SetPosition(iX, iY);
|
||||
var cp = CreateObject(Core_Goal_Checkpoint, x, y, NO_OWNER);
|
||||
cp->SetPosition(x, y);
|
||||
cp->SetCPMode(RACE_CP_Start);
|
||||
cp->SetCPController(this);
|
||||
aCheckpoints[0] = cp;
|
||||
return;
|
||||
}
|
||||
|
||||
public func SetFinishpoint(int iX, int iY)
|
||||
public func SetFinishpoint(int x, int y)
|
||||
{
|
||||
var cp = CreateObject(Core_Goal_Checkpoint, iX, iY, NO_OWNER);
|
||||
cp->SetPosition(iX, iY);
|
||||
var cp = CreateObject(Core_Goal_Checkpoint, x, y, NO_OWNER);
|
||||
cp->SetPosition(x, y);
|
||||
cp->SetCPMode(RACE_CP_Finish);
|
||||
cp->SetCPController(this);
|
||||
aCheckpoints[nrCheckpoints + 1] = cp;
|
||||
return;
|
||||
}
|
||||
|
||||
public func AddCheckpoint(int iX, int iY, int iMode)
|
||||
public func AddCheckpoint(int x, int y, int mode)
|
||||
{
|
||||
var cp = CreateObject(Core_Goal_Checkpoint, iX, iY, NO_OWNER);
|
||||
cp->SetPosition(iX, iY);
|
||||
cp->SetCPMode(iMode);
|
||||
var cp = CreateObject(Core_Goal_Checkpoint, x, y, NO_OWNER);
|
||||
cp->SetPosition(x, y);
|
||||
cp->SetCPMode(mode);
|
||||
cp->SetCPController(this);
|
||||
if (iMode & RACE_CP_Check || iMode & RACE_CP_Ordered)
|
||||
if (mode & RACE_CP_Check || mode & RACE_CP_Ordered)
|
||||
{
|
||||
nrCheckpoints++;
|
||||
aCheckpoints[nrCheckpoints + 1] = aCheckpoints[nrCheckpoints]; // Finish 1 place further.
|
||||
|
@ -76,53 +89,58 @@ public func AddCheckpoint(int iX, int iY, int iMode)
|
|||
|
||||
/*-- Checkpoint interaction --*/
|
||||
|
||||
// Called from a finish CP to indicate that iPlr has reached it.
|
||||
public func PlayerHasReachedFinish(int iPlr)
|
||||
// Called from a finish CP to indicate that plr has reached it.
|
||||
public func PlrReachedFinishCP(int plr)
|
||||
{
|
||||
aPlrCP[iPlr]++;
|
||||
if (GetPlayerTeam(iPlr))
|
||||
aTeamCP[GetPlayerTeam(iPlr)]++;
|
||||
UpdateScoreboard(iPlr);
|
||||
EliminatePlayers(iPlr);
|
||||
var plrid = GetPlayerID(plr);
|
||||
aPlrCP[plrid]++;
|
||||
if (GetPlayerTeam(plr))
|
||||
aTeamCP[GetPlayerTeam(plr)]++;
|
||||
UpdateScoreboard(plr);
|
||||
DoBestTime(plr);
|
||||
SetEvalData(plr);
|
||||
EliminatePlayers(plr);
|
||||
fFinished = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Called from a respawn CP to indicate that iPlr has reached it.
|
||||
public func SetPlrRespawnCP(int iPlr, object cp)
|
||||
// Called from a respawn CP to indicate that plr has reached it.
|
||||
public func SetPlrRespawnCP(int plr, object cp)
|
||||
{
|
||||
if (aRespawnCP[iPlr] == cp)
|
||||
if (aRespawnCP[plr] == cp)
|
||||
return;
|
||||
aRespawnCP[iPlr] = cp;
|
||||
PlrMessage(Translate("MsgNewRespawn"), iPlr);
|
||||
aRespawnCP[plr] = cp;
|
||||
PlrMessage(Translate("MsgNewRespawn"), plr);
|
||||
return;
|
||||
}
|
||||
|
||||
// Called from a check CP to indicate that iPlr has cleared it.
|
||||
public func AddPlrClearedCP(int iPlr)
|
||||
// Called from a check CP to indicate that plr has cleared it.
|
||||
public func AddPlrClearedCP(int plr)
|
||||
{
|
||||
aPlrCP[iPlr]++;
|
||||
if (GetPlayerTeam(iPlr))
|
||||
aTeamCP[GetPlayerTeam(iPlr)]++;
|
||||
UpdateScoreboard(iPlr);
|
||||
var plrid = GetPlayerID(plr);
|
||||
var team = GetPlayerTeam(plr);
|
||||
aPlrCP[plrid]++;
|
||||
if (team)
|
||||
aTeamCP[team]++;
|
||||
UpdateScoreboard(plr);
|
||||
return;
|
||||
}
|
||||
|
||||
/*-- Goal checking --*/
|
||||
/*-- Goal interface --*/
|
||||
|
||||
// Eliminate all players apart from iWinner and his team.
|
||||
private func EliminatePlayers(int iWinner)
|
||||
// Eliminates all players apart from the winner and his team.
|
||||
private func EliminatePlayers(int winner)
|
||||
{
|
||||
var iWinTeam = GetPlayerTeam(iWinner);
|
||||
var winteam = GetPlayerTeam(winner);
|
||||
for (var i = 0; i < GetPlayerCount(); i++)
|
||||
{
|
||||
var iPlr = GetPlayerByIndex(i);
|
||||
var iTeam = GetPlayerTeam(iPlr);
|
||||
if (iPlr == iWinner) // The winner self.
|
||||
var plr = GetPlayerByIndex(i);
|
||||
var team = GetPlayerTeam(plr);
|
||||
if (plr == winner) // The winner self.
|
||||
continue;
|
||||
if (iTeam && iTeam == iWinTeam) // In the same team as the winner.
|
||||
if (team && team == winteam) // In the same team as the winner.
|
||||
continue;
|
||||
EliminatePlayer(iPlr);
|
||||
EliminatePlayer(plr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -132,139 +150,131 @@ public func IsFulfilled()
|
|||
return fFinished;
|
||||
}
|
||||
|
||||
public func Activate(int iPlr)
|
||||
public func Activate(int plr)
|
||||
{
|
||||
var iTeam = GetPlayerTeam(iPlr);
|
||||
var szMessage = "";
|
||||
var team = GetPlayerTeam(plr);
|
||||
var msg;
|
||||
if (fFinished)
|
||||
{
|
||||
if (iTeam)
|
||||
if (team)
|
||||
{
|
||||
if (IsWinner(iPlr))
|
||||
szMessage = Format(Translate("MsgRaceWonTeam"));
|
||||
if (IsWinner(plr))
|
||||
msg = Format(Translate("MsgRaceWonTeam"));
|
||||
else
|
||||
szMessage = Format(Translate("MsgRaceLostTeam"));
|
||||
msg = Format(Translate("MsgRaceLostTeam"));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsWinner(iPlr))
|
||||
szMessage = Format(Translate("MsgRaceWon"));
|
||||
if (IsWinner(plr))
|
||||
msg = Format(Translate("MsgRaceWon"));
|
||||
else
|
||||
szMessage = Format(Translate("MsgRaceLost"));
|
||||
msg = Format(Translate("MsgRaceLost"));
|
||||
}
|
||||
}
|
||||
else
|
||||
szMessage = Format(Translate("MsgRace"), nrCheckpoints + 1);
|
||||
msg = Format(Translate("MsgRace"), nrCheckpoints + 1);
|
||||
// Show goal message.
|
||||
MessageWindow(szMessage, iPlr);
|
||||
MessageWindow(msg, plr);
|
||||
return;
|
||||
}
|
||||
|
||||
private func IsWinner(int iPlr)
|
||||
public func GetShortDescription(int plr)
|
||||
{
|
||||
var iTeam = GetPlayerTeam(iPlr);
|
||||
return Translate("MsgDesc");
|
||||
}
|
||||
|
||||
private func IsWinner(int plr)
|
||||
{
|
||||
var team = GetPlayerTeam(plr);
|
||||
var finish = FindObject(Find_ID(Core_Goal_Checkpoint), Find_Func("FindCPMode", RACE_CP_Finish));
|
||||
if (!finish)
|
||||
return false;
|
||||
if (iTeam)
|
||||
if (team)
|
||||
{
|
||||
if (finish->ClearedByTeam(iTeam))
|
||||
if (finish->ClearedByTeam(team))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (finish->ClearedByPlr(iPlr))
|
||||
if (finish->ClearedByPlr(plr))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*-- Player section --*/
|
||||
|
||||
protected func InitializePlayer(int iPlr, int iX, int iY, object pBase, int iTeam)
|
||||
protected func InitializePlayer(int plr, int x, int y, object base, int team)
|
||||
{
|
||||
// If the race is already finished, then immediately eliminate player.
|
||||
if (fFinished)
|
||||
return EliminatePlayer(iPlr);
|
||||
return EliminatePlayer(plr);
|
||||
// Remove all hostilities.
|
||||
for (var i = 0; i < GetPlayerCount(); i++)
|
||||
{
|
||||
SetHostility(iPlr, GetPlayerByIndex(i), 0, 1);
|
||||
SetHostility(GetPlayerByIndex(i), iPlr, 0, 1);
|
||||
SetHostility(plr, GetPlayerByIndex(i), false, true);
|
||||
SetHostility(GetPlayerByIndex(i), plr, false, true);
|
||||
}
|
||||
// Init Respawn CP to start CP.
|
||||
aRespawnCP[iPlr] = aCheckpoints[0];
|
||||
aPlrCP[iPlr] = 0;
|
||||
if (iTeam)
|
||||
if (!aPlrCP[iTeam])
|
||||
aPlrCP[iTeam] = 0;
|
||||
UpdateScoreboard(iPlr);
|
||||
DoScoreboardShow(1, iPlr + 1);
|
||||
JoinPlayer(iPlr);
|
||||
var plrid = GetPlayerID(plr);
|
||||
aRespawnCP[plr] = aCheckpoints[0];
|
||||
aPlrCP[plrid] = 0;
|
||||
if (team)
|
||||
if (!aTeamCP[team])
|
||||
aTeamCP[team] = 0;
|
||||
// Scoreboard.
|
||||
InitScoreboard();
|
||||
UpdateScoreboard(plr);
|
||||
DoScoreboardShow(1, plr + 1);
|
||||
JoinPlayer(plr);
|
||||
// Scenario script callback.
|
||||
GameCall("PlrHasRespawned", iPlr, aRespawnCP[iPlr]);
|
||||
GameCall("PlrHasRespawned", plr, aRespawnCP[plr]);
|
||||
return;
|
||||
}
|
||||
|
||||
protected func OnClonkDeath(object clonk)
|
||||
protected func RelaunchPlayer(int plr)
|
||||
{
|
||||
var iPlr = clonk->GetOwner();
|
||||
var nclonk = CreateObject(CLNK, 0, 0, iPlr);
|
||||
nclonk->MakeCrewMember(iPlr);
|
||||
nclonk->GrabObjectInfo(clonk);
|
||||
SetCursor(iPlr, nclonk);
|
||||
SelectCrew(iPlr, nclonk, true);
|
||||
JoinPlayer(iPlr);
|
||||
var clonk = CreateObject(CLNK, 0, 0, plr);
|
||||
clonk->MakeCrewMember(plr);
|
||||
SetCursor(plr, clonk);
|
||||
SelectCrew(plr, clonk, true);
|
||||
JoinPlayer(plr);
|
||||
// Scenario script callback.
|
||||
GameCall("PlrHasRespawned", iPlr, aRespawnCP[iPlr]);
|
||||
GameCall("PlrHasRespawned", plr, aRespawnCP[plr]);
|
||||
// Log message.
|
||||
Log(RndRespawnMsg(), GetPlayerName(iPlr));
|
||||
}
|
||||
|
||||
/*
|
||||
protected func RelaunchPlayer(int iPlr)
|
||||
{
|
||||
var clonk = CreateObject(CLNK, 0, 0, iPlr);
|
||||
clonk->MakeCrewMember(iPlr);
|
||||
SetCursor(iPlr, clonk);
|
||||
SelectCrew(iPlr, clonk, true);
|
||||
JoinPlayer(iPlr);
|
||||
// Scenario script callback.
|
||||
GameCall("PlrHasRespawned", iPlr, aRespawnCP[iPlr]);
|
||||
// Log message.
|
||||
Log(RndRespawnMsg(), GetPlayerName(iPlr));
|
||||
Log(RndRespawnMsg(), GetPlayerName(plr));
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
private func RndRespawnMsg()
|
||||
{
|
||||
return Translate(Format("MsgRespawn%d", Random(4)));
|
||||
}
|
||||
|
||||
protected func JoinPlayer(int iPlr)
|
||||
protected func JoinPlayer(int plr)
|
||||
{
|
||||
var clonk = GetCrew(iPlr);
|
||||
var clonk = GetCrew(plr);
|
||||
clonk->DoEnergy(100000);
|
||||
var x, y;
|
||||
FindRespawnPos(iPlr, x, y);
|
||||
FindRespawnPos(plr, x, y);
|
||||
clonk->SetPosition(x, y);
|
||||
AddEffect("IntDirNextCP", clonk, 100, 10, this);
|
||||
return;
|
||||
}
|
||||
|
||||
private func FindRespawnPos(int iPlr, int &iX, int &iY)
|
||||
private func FindRespawnPos(int plr, int &x, int &y)
|
||||
{
|
||||
iX = aRespawnCP[iPlr]->GetX();
|
||||
iY = aRespawnCP[iPlr]->GetY();
|
||||
x = aRespawnCP[plr]->GetX();
|
||||
y = aRespawnCP[plr]->GetY();
|
||||
return;
|
||||
}
|
||||
|
||||
protected func RemovePlayer(int iPlr)
|
||||
protected func RemovePlayer(int plr)
|
||||
{
|
||||
// TODO
|
||||
|
||||
if (!fFinished)
|
||||
AddEvalData(plr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -279,40 +289,64 @@ protected func FxIntSBDistanceTimer()
|
|||
|
||||
static const SBRD_Checkpoints = 0;
|
||||
static const SBRD_Distance = 1;
|
||||
static const SBRD_BestTime = 2;
|
||||
|
||||
private func UpdateScoreboard(int iPlr)
|
||||
private func InitScoreboard()
|
||||
{
|
||||
// TODO
|
||||
var szCaption = Format("Race over %d checkpoints", nrCheckpoints + 1);
|
||||
SetScoreboardData(SBRD_Caption, SBRD_Caption, szCaption, SBRD_Caption);
|
||||
if (nrCheckpoints > 0)
|
||||
var caption = Format(Translate("MsgCaptionX"), nrCheckpoints + 1);
|
||||
else
|
||||
var caption = Translate("MsgCaptionNone");
|
||||
// The above row.
|
||||
SetScoreboardData(SBRD_Caption, SBRD_Caption, caption, SBRD_Caption);
|
||||
SetScoreboardData(SBRD_Caption, SBRD_Checkpoints, Format("{{%i}}", Core_Goal_Checkpoint), SBRD_Caption);
|
||||
SetScoreboardData(SBRD_Caption, SBRD_Distance, Format("->{{%i}}", Core_Goal_Checkpoint), SBRD_Caption);
|
||||
SetScoreboardData(iPlr, SBRD_Caption, GetTaggedPlayerName(iPlr), SBRD_Caption);
|
||||
SetScoreboardData(iPlr, SBRD_Checkpoints, Format("%d", aPlrCP[iPlr]), aPlrCP[iPlr]);
|
||||
SetScoreboardData(iPlr, SBRD_Distance, Format("%d%", GetDistToCP(iPlr)), GetDistToCP(iPlr));
|
||||
SetScoreboardData(SBRD_Caption, SBRD_BestTime, "T", SBRD_Caption);
|
||||
return;
|
||||
}
|
||||
|
||||
// Returns the number of players in a team
|
||||
private func GetTeamPlrCount(int iTeam)
|
||||
private func UpdateScoreboard(int plr)
|
||||
{
|
||||
var cnt = 0;
|
||||
for(var i = 0; i < GetPlayerCount(); i++)
|
||||
if(GetPlayerTeam(GetPlayerByIndex(i)) == iTeam)
|
||||
cnt++;
|
||||
return cnt;
|
||||
var plrid = GetPlayerID(plr);
|
||||
// The player name.
|
||||
SetScoreboardData(plrid, SBRD_Caption, GetTaggedPlayerName(plr), SBRD_Caption);
|
||||
// The player scores.
|
||||
SetScoreboardData(plrid, SBRD_Checkpoints, Format("%d", aPlrCP[plrid]), aPlrCP[plrid]);
|
||||
SetScoreboardData(plrid, SBRD_Distance, Format("%d%", GetDistToCP(plr)), GetDistToCP(plr));
|
||||
SetScoreboardData(plrid, SBRD_BestTime, TimeToString(GetPlrExtraData(plr, szBestTimeString)), SBRD_Caption);
|
||||
// Sort.
|
||||
SortScoreboard(SBRD_Distance, false);
|
||||
SortScoreboard(SBRD_Checkpoints, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Only works for ordered CPs
|
||||
private func GetDistToCP(int iPlr)
|
||||
/*-- Direction & distance indication --*/
|
||||
|
||||
// Returns the last cleared CP for plr.
|
||||
private func FindLastCP(int plr)
|
||||
{
|
||||
// Get last finished ordered CP.
|
||||
var lastcp;
|
||||
for (var cp in FindObjects(Find_ID(Core_Goal_Checkpoint), Find_Func("FindCPMode", RACE_CP_Ordered), Find_Func("ClearedByPlr", iPlr)))
|
||||
for (var cp in FindObjects(Find_ID(Core_Goal_Checkpoint), Find_Func("FindCPMode", RACE_CP_Ordered), Find_Func("ClearedByPlr", plr)))
|
||||
if (!lastcp || lastcp->~GetCPNumber() < cp->~GetCPNumber())
|
||||
lastcp = cp;
|
||||
if (!lastcp)
|
||||
lastcp = FindObject(Find_ID(Core_Goal_Checkpoint), Find_Func("FindCPMode", RACE_CP_Start));
|
||||
return lastcp;
|
||||
}
|
||||
|
||||
// Returns the next CP for plr.
|
||||
private func FindNextCP(int plr)
|
||||
{
|
||||
var nextcp;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Only works for ordered CPs
|
||||
private func GetDistToCP(int plr)
|
||||
{
|
||||
// Get last finished ordered CP.
|
||||
var lastcp = FindLastCP(plr);
|
||||
if (!lastcp)
|
||||
return 0;
|
||||
// Get next ordered CP.
|
||||
|
@ -324,21 +358,20 @@ private func GetDistToCP(int iPlr)
|
|||
nextcp = FindObject(Find_ID(Core_Goal_Checkpoint), Find_Func("FindCPMode", RACE_CP_Finish));
|
||||
if (!nextcp)
|
||||
return 0;
|
||||
var dist = ObjectDistance(GetCrew(iPlr), nextcp);
|
||||
var dist = ObjectDistance(GetCrew(plr), nextcp);
|
||||
dist = (100 * dist) / ObjectDistance(lastcp, nextcp);
|
||||
dist = BoundBy(dist, 0, 100);
|
||||
return dist;
|
||||
}
|
||||
|
||||
/*-- Direction indication --*/
|
||||
|
||||
// Effect for direction indication for the clonk.
|
||||
protected func FxIntDirNextCPTimer(object pTarget, int iEffectNumber, int iEffectTime)
|
||||
{
|
||||
var plr = pTarget->GetOwner();
|
||||
// Find nearest CP.
|
||||
var nextcp;
|
||||
for (var cp in FindObjects(Find_ID(Core_Goal_Checkpoint), Find_Func("FindCPMode", RACE_CP_Check | RACE_CP_Finish), Sort_Distance(pTarget->GetX()-GetX(), pTarget->GetY()-GetY())))
|
||||
if (!cp->ClearedByPlr(plr) && (cp->IsActiveForPlr(plr) || cp->IsActiveForPlr(GetPlayerTeam(plr))))
|
||||
if (!cp->ClearedByPlr(plr) && (cp->IsActiveForPlr(plr) || cp->IsActiveForTeam(GetPlayerTeam(plr))))
|
||||
{
|
||||
nextcp = cp;
|
||||
break;
|
||||
|
@ -347,11 +380,83 @@ protected func FxIntDirNextCPTimer(object pTarget, int iEffectNumber, int iEffec
|
|||
return;
|
||||
// Calculate angle.
|
||||
var angle = Angle(pTarget->GetX(), pTarget->GetY(), nextcp->GetX(), nextcp->GetY());
|
||||
// Effect.
|
||||
// Effect, should be replaced with an arrow.
|
||||
CreateParticle("DebugReticle", pTarget->GetX()+Sin(angle, 20)-GetX(), pTarget->GetY()-Cos(angle,20)-GetY(), 0, 0, 30, RGB(255,0,0));
|
||||
return FX_OK;
|
||||
}
|
||||
|
||||
/*-- Time tracker --*/
|
||||
|
||||
private func DoBestTime(int plr)
|
||||
{
|
||||
var effect = GetEffect("IntBestTime", this);
|
||||
var time = EffectVar(0, this, effect);
|
||||
var rectime = GetPlrExtraData(plr, szBestTimeString);
|
||||
if (time != 0 && (!rectime || time < rectime))
|
||||
{
|
||||
SetPlrExtraData(plr, szBestTimeString, time);
|
||||
Log(Format(Translate("MsgBestTime"), GetPlayerName(plr), TimeToString(time)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Starts at goal initialization, should be equivalent to gamestart.
|
||||
protected func FxIntBestTimeTimer(object pTarget, int iEffectNumber, int iEffectTime)
|
||||
{
|
||||
EffectVar(0, pTarget, iEffectNumber) = iEffectTime;
|
||||
return FX_OK;
|
||||
}
|
||||
|
||||
// Returns a best time string.
|
||||
private func TimeToString(int time)
|
||||
{
|
||||
if (!time) // No time.
|
||||
return "N/A";
|
||||
if (time > 36*60*60) // Longer than an hour.
|
||||
return Format("%d:%.2d:%.2d.%.1d", (time/60/60/36)%24, (time/60/36)%60, (time/36)%60, (10*time/36)%10);
|
||||
if (time > 36*60) // Longer than a minute.
|
||||
return Format("%d:%.2d.%.1d", (time/60/36)%60, (time/36)%60, (10*time/36)%10);
|
||||
else // Only seconds.
|
||||
return Format("%d.%.1d", (time/36)%60, (10*time/36)%10);
|
||||
}
|
||||
|
||||
/*-- Evaluation data --*/
|
||||
|
||||
private func SetEvalData(int winner)
|
||||
{
|
||||
var winteam = GetPlayerTeam(winner);
|
||||
var effect = GetEffect("IntBestTime", this);
|
||||
var time = EffectVar(0, this, effect);
|
||||
var msg;
|
||||
// General data.
|
||||
if (winteam)
|
||||
msg = Format(Translate("MsgEvalTeamWon"), GetTeamName(winteam), TimeToString(time));
|
||||
else
|
||||
msg = Format(Translate("MsgEvalPlrWon"), GetPlayerName(winner), TimeToString(time));
|
||||
AddEvaluationData(msg, 0);
|
||||
// Individual data.
|
||||
for (var i = 0; i < GetPlayerCount(); i++)
|
||||
AddEvalData(GetPlayerByIndex(i));
|
||||
// Obviously get rid of settlement score.*/
|
||||
HideSettlementScoreInEvaluation(true);
|
||||
return;
|
||||
}
|
||||
|
||||
private func AddEvalData(int plr)
|
||||
{
|
||||
var plrid = GetPlayerID(plr);
|
||||
var cps = aPlrCP[plrid];
|
||||
var msg;
|
||||
if (cps == nrCheckpoints)
|
||||
msg = Translate("MsgEvalPlayerAll");
|
||||
else
|
||||
msg = Format(Translate("MsgEvalPlayerX"), cps);
|
||||
AddEvaluationData(msg, plrid);
|
||||
return;
|
||||
}
|
||||
|
||||
/*-- Proplist --*/
|
||||
|
||||
func Definition(def) {
|
||||
SetProperty("Name", "$Name$", def);
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
NameRace=Wettrennen
|
||||
Name=Parkour
|
||||
|
||||
#Race
|
||||
#Goal window
|
||||
MsgRace=This is race over %d checkpoints, check the scoreboard for the number of completed checkpoints per team/player.
|
||||
MsgRaceWon=Congratulations, you have won the race!
|
||||
MsgRaceWonTeam=Congratulations, your team has won the race!
|
||||
|
@ -8,8 +8,24 @@ MsgRaceLost=You have lost the race.
|
|||
MsgRaceLostTeam=Your team has lost the race.
|
||||
|
||||
#Respawn
|
||||
MsgRespawn0=%s tries it again.
|
||||
MsgRespawn1=%s is dead.
|
||||
MsgRespawn0=%s tries again.
|
||||
MsgRespawn1=%s has died.
|
||||
MsgRespawn2=Haha, %s!
|
||||
MsgRespawn3=We're mourning %s.
|
||||
MsgNewRespawn=You'll now respawn here.
|
||||
|
||||
#Description
|
||||
MsgDesc=You are in a race.
|
||||
|
||||
#Scoreboard
|
||||
MsgCaptionX=Race over %d checkpoints.
|
||||
MsgCaptionNone=Race without checkpoints.
|
||||
|
||||
#Best time
|
||||
MsgBestTime=%s has set a new personal best time of %s.
|
||||
|
||||
#Evaluation data
|
||||
MsgEvalPlrWon=%s has won the parkour in %s.
|
||||
MsgEvalTeamWon=The team %s has won the parkour in %s.
|
||||
MsgEvalPlayerX=You have cleared %d checkpoints.
|
||||
MsgEvalPlayerAll=You have cleared all checkpoints.
|
|
@ -1,6 +1,6 @@
|
|||
Name=Race
|
||||
Name=Parkour
|
||||
|
||||
#Race
|
||||
#Goal window
|
||||
MsgRace=This is race over %d checkpoints, check the scoreboard for the number of completed checkpoints per team/player.
|
||||
MsgRaceWon=Congratulations, you have won the race!
|
||||
MsgRaceWonTeam=Congratulations, your team has won the race!
|
||||
|
@ -8,8 +8,24 @@ MsgRaceLost=You have lost the race.
|
|||
MsgRaceLostTeam=Your team has lost the race.
|
||||
|
||||
#Respawn
|
||||
MsgRespawn0=%s tries it again.
|
||||
MsgRespawn1=%s is dead.
|
||||
MsgRespawn0=%s tries again.
|
||||
MsgRespawn1=%s has died.
|
||||
MsgRespawn2=Haha, %s!
|
||||
MsgRespawn3=We're mourning %s.
|
||||
MsgNewRespawn=You'll now respawn here.
|
||||
|
||||
#Description
|
||||
MsgDesc=You are in a race.
|
||||
|
||||
#Scoreboard
|
||||
MsgCaptionX=Race over %d checkpoints.
|
||||
MsgCaptionNone=Race without checkpoints.
|
||||
|
||||
#Best time
|
||||
MsgBestTime=%s has set a new personal best time of %s.
|
||||
|
||||
#Evaluation data
|
||||
MsgEvalPlrWon=%s has won the parkour in %s.
|
||||
MsgEvalTeamWon=The team %s has won the parkour in %s.
|
||||
MsgEvalPlayerX=You have cleared %d checkpoints.
|
||||
MsgEvalPlayerAll=You have cleared all checkpoints.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[Head]
|
||||
Icon=26
|
||||
Title=TheCavern
|
||||
Title=Cavern
|
||||
Version=4,10,0,0
|
||||
MaxPlayer=12
|
||||
|
||||
|
@ -8,25 +8,21 @@ MaxPlayer=12
|
|||
Definition1=Objects.c4d
|
||||
|
||||
[Player1]
|
||||
Wealth=50,0,0,250
|
||||
Crew=CLNK=1
|
||||
|
||||
[Player2]
|
||||
Wealth=50,0,0,250
|
||||
Crew=CLNK=1
|
||||
|
||||
[Player3]
|
||||
Wealth=50,0,0,250
|
||||
Crew=CLNK=1
|
||||
|
||||
[Player4]
|
||||
Wealth=50,0,0,250
|
||||
Crew=CLNK=1
|
||||
|
||||
[Landscape]
|
||||
InEarth=ROCK=1;GOLD=1;DYNA=3;LOAM=3
|
||||
InEarthLevel=80,0,0,100
|
||||
Sky=Clouds2
|
||||
Sky=Clouds1
|
||||
MapWidth=100,0,64,10000
|
||||
MapHeight=250,0,40,10000
|
||||
SkyScrollMode=2
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*-- The Summit --*/
|
||||
/*-- The Cavern --*/
|
||||
|
||||
protected func Initialize()
|
||||
{
|
||||
|
@ -11,10 +11,10 @@ protected func Initialize()
|
|||
d += 10;
|
||||
pGoal->SetStartpoint(x, y);
|
||||
// Set some checkpoints.
|
||||
for (var i = 0; d < LandscapeHeight()-400; i++)
|
||||
for (var i = 0; d < LandscapeHeight()-350; i++)
|
||||
{
|
||||
var mode = RACE_CP_Check;
|
||||
d += RandomX(150,300);
|
||||
d += RandomX(150,250);
|
||||
if (!FindPosInMat(x, y, "Tunnel", 0, LandscapeHeight()-d-80, LandscapeWidth(), 80, 20) || !Random(3))
|
||||
FindPosInMat(x, y, "Sky", 0, LandscapeHeight()-d-80, LandscapeWidth(), 80, 20);
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue