#Extends "Modes/ShootMania/ModeBase.Script.txt"
#Const CompatibleMapTypes "MeleeArena"
#Const Version "1.0.0"
#Const ScriptName "Melee_Tuto.Script.txt"
#Include "Libs/Nadeo/Settings.Script.txt" as Settings
#Include "TextLib" as TextLib
#Include "MathLib" as MathLib
#Include "Libs/Nadeo/ShootMania/SM.Script.txt" as SM
#Include "Libs/Nadeo/ShootMania/Score.Script.txt" as Score
#Include "Libs/Nadeo/Message.Script.txt" as Message
#Include "Libs/Nadeo/Interface.Script.txt" as Interface
#Include "Libs/Nadeo/Layers.Script.txt" as Layers
// ---------------------------------- //
// Settings
// ---------------------------------- //
#Setting S_TimeLimit 600 as _("Time limit") ///< Time limit on a map
#Setting S_PointLimit 25 as _("Points limit") ///< Points limit on a map
declare Ident[] G_SpawnsList; ///< Id of all the BlockSpawns of the map
declare Ident G_LatestSpawnId; ///< Id of the last BlockSpawn used
***StartServer***
***
UseClans = False;
declare PointsLayerId = Layers::Create("PointsLayer", PointLayerLayerText());
declare Attached = Layers::Attach("PointsLayer", NullId);
ST2::SetStyle("LibST_SMBaseSolo");
ST2::SetTeamsMode(False);
ST2::SetTeamsScoresVisibility(False);
ST2::Build("SM");
***
***StartMap***
***
G_SpawnsList.clear();
G_LatestSpawnId = NullId;
// ---------------------------------- //
// Init bases
foreach (Base in Bases) {
Base.Clan = 0;
Base.IsActive = True;
}
// ---------------------------------- //
// Init scores
MB_Sleep(1); ///< Allow the scores array to be sorted
foreach (Score in Scores) {
declare Integer LastPoint for Score;
LastPoint = 0;
}
declare LeadId = NullId;
if (Scores.existskey(0)) LeadId = Scores[0].User.Id;
declare CurrentPointLimit = S_PointLimit;
// ---------------------------------- //
StartTime = Now;
EndTime = StartTime + (S_TimeLimit * 1000);
UIManager.UIAll.UISequence = CUIConfig::EUISequence::Playing;
***
***StartRound***
***
foreach(Player in Players){
declare UI <=> UIManager.GetUI(Player);
declare netwrite Integer Net_Points for UI;
Net_Points = 0;
}
***
***PlayLoop***
***
foreach (Event, PendingEvents) {
// ---------------------------------- //
// On armor empty
if (Event.Type == CSmModeEvent::EType::OnArmorEmpty) {
if (Event.Shooter == Null) {
Event.Victim.Score.Points -= 1;
} else {
Event.Shooter.Score.Points += 1;
declare UI <=> UIManager.GetUI(Event.Shooter);
declare netwrite Integer Net_Points for UI;
Net_Points = Event.Shooter.Score.Points;
}
XmlRpc::OnArmorEmpty(Event);
PassOn(Event);
}
// ---------------------------------- //
// On hit
else if (Event.Type == CSmModeEvent::EType::OnHit) {
if (Event.Shooter == Event.Victim) {
Discard(Event);
} else {
Event.Victim.Armor -= Event.Damage;
XmlRpc::OnHit(Event);
PassOn(Event);
}
}
// ---------------------------------- //
// On player request respawn
else if (Event.Type == CSmModeEvent::EType::OnPlayerRequestRespawn) {
Event.Player.Score.Points -= 1;
XmlRpc::OnPlayerRequestRespawn(Event);
PassOn(Event);
}
// ---------------------------------- //
// Others
else {
PassOn(Event);
}
}
// ---------------------------------- //
// Spawn players
foreach (Player in Players) {
if (Player.SpawnStatus == CSmPlayer::ESpawnStatus::NotSpawned && !Player.RequestsSpectate) {
MeleeSpawnPlayer(Player);
}
}
// ---------------------------------- //
// Play sound and notice if someone is taking the lead
if (Scores.existskey(0) && Scores[0].User.Id != LeadId) {
LeadId = Scores[0].User.Id;
Message::SendBigMessage(TextLib::Compose(_("$<%1$> takes the lead!"), Scores[0].User.Name), 3000, 1, CUIConfig::EUISound::PhaseChange, 1);
}
// ---------------------------------- //
// victory conditions
declare IsMatchOver = False;
if (Now > EndTime) IsMatchOver = True;
foreach (Player in Players) {
if (Player.Score != Null && Player.Score.RoundPoints >= S_PointLimit) IsMatchOver = True;
}
if (IsMatchOver) MB_StopMap = True;
***
***EndMap***
***
EndTime = -1;
Score::RoundEnd();
Score::MatchEnd(True);
// ---------------------------------- //
// End match sequence
declare CUser Winner <=> Null;
declare MaxPoints = 0;
foreach (Score in Scores) {
if (Score.Points > MaxPoints) {
MaxPoints = Score.Points;
Winner <=> Score.User;
} else if (Score.Points == MaxPoints) {
Winner <=> Null;
}
}
foreach (Player in Players) {
if (Player.User != Winner) UnspawnPlayer(Player);
Interface::UpdatePosition(Player);
}
MB_Sleep(1000);
Message::CleanBigMessages();
UIManager.UIAll.BigMessageSound = CUIConfig::EUISound::EndRound;
UIManager.UIAll.BigMessageSoundVariant = 0;
if (Winner != Null) {
UIManager.UIAll.BigMessage = TextLib::Compose(_("$<%1$> wins the match!"), Winner.Name);
} else {
UIManager.UIAll.BigMessage = _("|Match|Draw");
}
MB_Sleep(2000);
UIManager.UIAll.UISequence = CUIConfig::EUISequence::EndRound;
UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::ForcedVisible;
MB_Sleep(5000);
UIManager.UIAll.UISequence = CUIConfig::EUISequence::Podium;
while(!UIManager.UIAll.UISequenceIsCompleted) {
MB_Yield();
}
UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal;
UIManager.UIAll.BigMessage = "";
***
Void MeleeSpawnPlayer(CSmPlayer _Player) {
if (G_SpawnsList.count == 0) {
foreach (BlockSpawn in BlockSpawns) G_SpawnsList.add(BlockSpawn.Id);
}
declare SpawnId = NullId;
while (True) {
SpawnId = G_SpawnsList[MathLib::Rand(0, G_SpawnsList.count - 1)];
if (SpawnId != G_LatestSpawnId) break;
if (G_SpawnsList.count == 1) break;
}
G_LatestSpawnId = SpawnId;
SM::SpawnPlayer(_Player, 0, BlockSpawns[SpawnId]);
declare Removed = G_SpawnsList.remove(SpawnId);
}
Text PointLayerLayerText(){
declare Text MLText = """
""";
return MLText;
}