Files
linguist/samples/AngelScript/payload.as
Codecat 44048c9ba8 Add Angelscript language (#3844)
* Add AngelScript scriping language

* Add AngelScript sample

* Initial implementation of Angelscript

* Update Angelscript tm_scope and ace_mode

* Move Angelscript after ANTLR

* Updated grammar list

* Alphabetical sorting for Angelscript

* Angelscript grammar license is unlicense

* Add ActionScript samples

* Added a heuristic for .as files

* Whitelist sublime-angelscript license hash

* Added heuristic test for Angelscript and Actionscript

* Remove .acs from Angelscript file extensions
2017-10-14 17:34:12 +01:00

397 lines
8.7 KiB
ActionScript

// Sample script.
// Source: https://github.com/codecat/ssbd-payload
array<WorldScript::PayloadBeginTrigger@> g_payloadBeginTriggers;
array<WorldScript::PayloadTeamForcefield@> g_teamForceFields;
[GameMode]
class Payload : TeamVersusGameMode
{
[Editable]
UnitFeed PayloadUnit;
[Editable]
UnitFeed FirstNode;
[Editable default=10]
int PrepareTime;
[Editable default=300]
int TimeLimit;
[Editable default=90]
int TimeAddCheckpoint;
[Editable default=2]
float TimeOvertime;
[Editable default=1000]
int TimePayloadHeal;
[Editable default=1]
int PayloadHeal;
PayloadBehavior@ m_payload;
int m_tmStarting;
int m_tmStarted;
int m_tmLimitCustom;
int m_tmOvertime;
int m_tmInOvertime;
PayloadHUD@ m_payloadHUD;
PayloadClassSwitchWindow@ m_switchClass;
array<SValue@>@ m_switchedSidesData;
Payload(Scene@ scene)
{
super(scene);
m_tmRespawnCountdown = 5000;
@m_payloadHUD = PayloadHUD(m_guiBuilder);
@m_switchTeam = PayloadTeamSwitchWindow(m_guiBuilder);
@m_switchClass = PayloadClassSwitchWindow(m_guiBuilder);
}
void UpdateFrame(int ms, GameInput& gameInput, MenuInput& menuInput) override
{
TeamVersusGameMode::UpdateFrame(ms, gameInput, menuInput);
m_payloadHUD.Update(ms);
if (Network::IsServer())
{
uint64 tmNow = CurrPlaytimeLevel();
if (m_tmStarting == 0)
{
if (GetPlayersInTeam(0) > 0 && GetPlayersInTeam(1) > 0)
{
m_tmStarting = tmNow;
(Network::Message("GameStarting") << m_tmStarting).SendToAll();
}
}
if (m_tmStarting > 0 && m_tmStarted == 0 && tmNow - m_tmStarting > PrepareTime * 1000)
{
m_tmStarted = tmNow;
(Network::Message("GameStarted") << m_tmStarted).SendToAll();
for (uint i = 0; i < g_payloadBeginTriggers.length(); i++)
{
WorldScript@ ws = WorldScript::GetWorldScript(g_scene, g_payloadBeginTriggers[i]);
ws.Execute();
}
}
}
if (!m_ended && m_tmStarted > 0)
CheckTimeReached(ms);
}
string NameForTeam(int index) override
{
if (index == 0)
return "Defenders";
else if (index == 1)
return "Attackers";
return "Unknown";
}
void CheckTimeReached(int dt)
{
// Check if time limit is not reached yet
if (m_tmLimitCustom - (CurrPlaytimeLevel() - m_tmStarted) > 0)
{
// Don't need to continue checking
m_tmOvertime = 0;
m_tmInOvertime = 0;
return;
}
// Count how long we're in overtime for later time limit fixing when we reach a checkpoint
if (m_tmOvertime > 0)
m_tmInOvertime += dt;
// Check if there are any attackers still inside
if (m_payload.AttackersInside() > 0)
{
// We have overtime
m_tmOvertime = int(TimeOvertime * 1000);
return;
}
// If we have overtime
if (m_tmOvertime > 0)
{
// Decrease timer
m_tmOvertime -= dt;
if (m_tmOvertime <= 0)
{
// Overtime countdown reached, time limit reached
TimeReached();
}
}
else
{
// No overtime, so time limit is reached
TimeReached();
}
}
void TimeReached()
{
if (!Network::IsServer())
return;
(Network::Message("TimeReached")).SendToAll();
SetWinner(false);
}
bool ShouldFreezeControls() override
{
return m_switchClass.m_visible
|| TeamVersusGameMode::ShouldFreezeControls();
}
bool ShouldDisplayCursor() override
{
return m_switchClass.m_visible
|| TeamVersusGameMode::ShouldDisplayCursor();
}
bool CanSwitchTeams() override
{
return m_tmStarted == 0;
}
PlayerRecord@ CreatePlayerRecord() override
{
return PayloadPlayerRecord();
}
int GetPlayerClassCount(PlayerClass playerClass, TeamVersusScore@ team)
{
if (team is null)
return 0;
int ret = 0;
for (uint i = 0; i < team.m_players.length(); i++)
{
if (team.m_players[i].peer == 255)
continue;
auto record = cast<PayloadPlayerRecord>(team.m_players[i]);
if (record.playerClass == playerClass)
ret++;
}
return ret;
}
void PlayerClassesUpdated()
{
m_switchClass.PlayerClassesUpdated();
}
void SetWinner(bool attackers)
{
if (attackers)
print("Attackers win!");
else
print("Defenders win!");
m_payloadHUD.Winner(attackers);
EndMatch();
}
void DisplayPlayerName(int idt, SpriteBatch& sb, PlayerRecord@ record, PlayerHusk@ plr, vec2 pos) override
{
TeamVersusGameMode::DisplayPlayerName(idt, sb, record, plr, pos);
m_payloadHUD.DisplayPlayerName(idt, sb, cast<PayloadPlayerRecord>(record), plr, pos);
}
void RenderFrame(int idt, SpriteBatch& sb) override
{
Player@ player = GetLocalPlayer();
if (player !is null)
{
PlayerHealgun@ healgun = cast<PlayerHealgun>(player.m_currWeapon);
if (healgun !is null)
healgun.RenderMarkers(idt, sb);
}
TeamVersusGameMode::RenderFrame(idt, sb);
}
void RenderWidgets(PlayerRecord@ player, int idt, SpriteBatch& sb) override
{
m_payloadHUD.Draw(sb, idt);
TeamVersusGameMode::RenderWidgets(player, idt, sb);
m_switchClass.Draw(sb, idt);
}
void GoNextMap() override
{
if (m_switchedSidesData !is null)
{
TeamVersusGameMode::GoNextMap();
return;
}
ChangeLevel(GetCurrentLevelFilename());
}
void SpawnPlayers() override
{
if (m_switchedSidesData is null)
{
TeamVersusGameMode::SpawnPlayers();
return;
}
if (Network::IsServer())
{
for (uint i = 0; i < m_switchedSidesData.length(); i += 2)
{
uint peer = uint(m_switchedSidesData[i].GetInteger());
uint team = uint(m_switchedSidesData[i + 1].GetInteger());
TeamVersusScore@ joinScore = FindTeamScore(team);
if (joinScore is m_teamScores[0])
@joinScore = m_teamScores[1];
else
@joinScore = m_teamScores[0];
for (uint j = 0; j < g_players.length(); j++)
{
if (g_players[j].peer != peer)
continue;
SpawnPlayer(j, vec2(), 0, joinScore.m_team);
break;
}
}
}
}
void Save(SValueBuilder& builder) override
{
if (m_switchedSidesData is null)
{
builder.PushArray("teams");
for (uint i = 0; i < g_players.length(); i++)
{
if (g_players[i].peer == 255)
continue;
builder.PushInteger(g_players[i].peer);
builder.PushInteger(g_players[i].team);
}
builder.PopArray();
}
TeamVersusGameMode::Save(builder);
}
void Start(uint8 peer, SValue@ save, StartMode sMode) override
{
if (save !is null)
@m_switchedSidesData = GetParamArray(UnitPtr(), save, "teams", false);
TeamVersusGameMode::Start(peer, save, sMode);
m_tmLimit = 0; // infinite time limit as far as VersusGameMode is concerned
m_tmLimitCustom = TimeLimit * 1000; // 5 minutes by default
@m_payload = cast<PayloadBehavior>(PayloadUnit.FetchFirst().GetScriptBehavior());
if (m_payload is null)
PrintError("PayloadUnit is not a PayloadBehavior!");
UnitPtr unitFirstNode = FirstNode.FetchFirst();
if (unitFirstNode.IsValid())
{
auto node = cast<WorldScript::PayloadNode>(unitFirstNode.GetScriptBehavior());
if (node !is null)
@m_payload.m_targetNode = node;
else
PrintError("First target node is not a PayloadNode script!");
}
else
PrintError("First target node was not set!");
WorldScript::PayloadNode@ prevNode;
float totalDistance = 0.0f;
UnitPtr unitNode = unitFirstNode;
while (unitNode.IsValid())
{
auto node = cast<WorldScript::PayloadNode>(unitNode.GetScriptBehavior());
if (node is null)
break;
unitNode = node.NextNode.FetchFirst();
@node.m_prevNode = prevNode;
@node.m_nextNode = cast<WorldScript::PayloadNode>(unitNode.GetScriptBehavior());
if (prevNode !is null)
totalDistance += dist(prevNode.Position, node.Position);
@prevNode = node;
}
float currDistance = 0.0f;
auto distNode = cast<WorldScript::PayloadNode>(unitFirstNode.GetScriptBehavior());
while (distNode !is null)
{
if (distNode.m_prevNode is null)
distNode.m_locationFactor = 0.0f;
else
{
currDistance += dist(distNode.m_prevNode.Position, distNode.Position);
distNode.m_locationFactor = currDistance / totalDistance;
}
@distNode = distNode.m_nextNode;
}
m_payloadHUD.AddCheckpoints();
}
void SpawnPlayer(int i, vec2 pos = vec2(), int unitId = 0, uint team = 0) override
{
TeamVersusGameMode::SpawnPlayer(i, pos, unitId, team);
PayloadPlayerRecord@ record = cast<PayloadPlayerRecord>(g_players[i]);
record.HandlePlayerClass();
if (g_players[i].local)
{
//TODO: This doesn't work well
bool localAttackers = (team == HashString("player_1"));
for (uint j = 0; j < g_teamForceFields.length(); j++)
{
bool hasCollision = (localAttackers != g_teamForceFields[j].Attackers);
auto units = g_teamForceFields[j].Units.FetchAll();
for (uint k = 0; k < units.length(); k++)
{
PhysicsBody@ body = units[k].GetPhysicsBody();
if (body is null)
{
PrintError("PhysicsBody for unit " + units[k].GetDebugName() + "is null");
continue;
}
body.SetActive(hasCollision);
}
}
}
}
}