always missed a countdown timer for it so i made own of my own. Its based upon the old script but it can be altered to make it work with the new one.
It also works on EliteMaps aswell as anyother Maps.
Code: Select all
#RequireContext CSmMode
#Include "Libs/Nadeo/Mode.Script.txt"
#Include "Libs/Nadeo/ShootMania/SM.Script.txt" as SM
#Include "Libs/Nadeo/ShootMania/Score.Script.txt" as Score
#Include "MathLib" as MathLib
#Include "TextLib" as TextLib
#Const CompatibleMapTypes "EliteArena"
#Const Version "2012-08-31"
#Const ModeVer "v1.0"
#Const C_UITickInterval 200
#Setting TimeLimit 600 as "Time limit"
#Setting PointLimit 25 as "Point limit"
#Setting SwitchInt 20 as "Switch interval"
#Setting SelfElimCost 3 as "Self elimination mode cost"
declare Ident[] SpawnsList;
declare Ident LatestSpawnId;
Void FillSpawnsList() {
foreach (BlockSpawn in BlockSpawns) { SpawnsList.add(BlockSpawn.Id); }
}
Void SpawnPlayers(CSmPlayer _Player) {
if (SpawnsList.count == 0) FillSpawnsList();
declare SpawnId = NullId;
while (True) {
SpawnId = SpawnsList[MathLib::Rand(0, SpawnsList.count - 1)];
if (SpawnId != LatestSpawnId) break;
if (SpawnsList.count == 1) break;
}
SM::SpawnPlayer(_Player, 0, BlockSpawns[SpawnId]);
LatestSpawnId = SpawnId;
declare Tmp = SpawnsList.remove(SpawnId);
}
Text UpdateLayerInfos(CSmPlayer _Player) {
if (_Player.Score == Null) return "";
return """
<frame posn="150 -88">
<label posn="0 1" halign="left" valign="bottom" text="/{{{ Scores.count }}}"/>
<label posn="0 0" halign="right" valign="bottom" style="TextRaceChrono" text="{{{ Scores.keyof(_Player.Score) + 1 }}}"/>
</frame>
""";
}
/* ------------------------------------- */
/** Get the help manialink string.
*
* @return The manialink string
*/
Text UpdateLayerSpawnScreen() {
declare Text ML;
declare TempForI18n = _("Free for all\n- Survive as long as possible to score a maximum of points.\n- Bonus points are awarded for the pole capture and for each player hit.\n- If the pole is captured then the playing area will start to shrink. If a player leaves this area he is eliminated.\n- The first player to reach %1 points wins.");
ML = """
<script><!--
main () {
declare FrameRules <=> Page.GetFirstChild("FrameRules");
declare FrameShow <=> Page.GetFirstChild("FrameShow");
declare ShowRules = False;
while(True) {
if (ShowRules) {
FrameRules.Show();
FrameShow.Hide();
} else {
FrameRules.Hide();
FrameShow.Show();
}
yield;
// process events.
foreach (Event in PendingEvents) {
switch (Event.Type) {
case CMlEvent::Type::MouseClick :
{
if (Event.ControlId == "FrameRules") ShowRules = !ShowRules;
}
case CMlEvent::Type::KeyPress:
{
if (Event.CharPressed == "2424832") ShowRules = !ShowRules; // F1
}
}
}
}
}
--></script>
<frame posn="0 -70 0" id="FrameShow">
<quad posn="0 0 10" sizen="140 20" halign="center" valign="center" style="Bgs1InRace" substyle="BgTitle3_5" />
<label posn="0 0 11" scale="2" halign="center" valign="center" style="TextTitle3" text="{{{ _("Press F1 to show rules") }}}" />
</frame>
<frame posn="0 50 1" id="FrameRules">
<frame posn="0 0 5">
<quad posn="0 0 10" sizen="120 20" halign="center" valign="center" style="Bgs1InRace" substyle="BgTitle3_5" />
<label posn="0 0 11" scale="2" halign="center" valign="center" style="TextTitle3" text="$fffOscillation" />
</frame>
<frame posn="0 -10 5">
<quad posn="0 0 10" sizen="300 120" halign="center" bgcolor="222c" />
<label posn="-145 -5 11" sizen="192 5" scale="1.5" autonewline="1" style="TextCardSmallScores2" text="{{{"Modes:\n1. Normal Mode - This is standard melee.\n2. Self-eliminations cost __ points! - If you die from offzone or backspace, you lose __ points, where __ is a number.\n3. UNLIMITED! POWER!! - Gives everyone 10x weapon power gain for the mode's duration.\n4. Don't die! - If you die while this mode is active, you do not respawn until it changes.\n5. Spawn with 3 armor points! - If you spawn during this mode, you have 3 armor points.\n6. Spawn with Laser only! - If you spawn during this mode, you get the laser only. The other weapons do not work.\n7. Spawn with Nucleus only! - Same as mode 6, but with the Nucleus, not the Laser.\n8. DOULBE POINTS! - This mode doubles every hit's point worth (1 -> 2, 2 -> 4).\n9. It's a one-hit wonder! - Everyone's HP is set to 1 at the start of this mode.\n10. Health: Refilled! - Completley refills your health.\n\nThis is version 1.4"}}}" />
</frame>
</frame>
""";
return ML;
}
main() {
UseClans = False;
//SetNbFakePlayers(10,0);
declare LayerSpawnScreen <=> UIManager.UILayerCreate();
LayerSpawnScreen.Type = CUILayer::EUILayerType::ScreenIn3d;
while (!ServerShutdownRequested) {
LoadMap();
XmlRpc.SendCallback("beginMap",MapName);
SpawnsList.clear();
LatestSpawnId = NullId;
Score::MatchBegin();
Score::RoundBegin();
MatchEndRequested = False;
UIManager.ResetAll();
SM::SetupDefaultVisibility();
LayerSpawnScreen.ManialinkPage = UpdateLayerSpawnScreen();
UIManager.UIAll.UILayers.add(LayerSpawnScreen);
UIManager.UIAll.UISequence = CUIConfig::EUISequence::Intro;
UIManager.UIAll.BigMessage = _("New match");
wait(UIManager.UIAll.UISequenceIsCompleted);
sleep(2000);
UIManager.UIAll.BigMessage = "";
UIManager.UIAll.UISequence = CUIConfig::EUISequence::Playing;
declare LastUITick = 0;
StartTime = Now;
EndTime = StartTime + (TimeLimit * 1000);
declare Integer Mode = 0;
declare Integer PrevMode = -1;
declare Integer NextSwitch = Now;
declare WarningGiven = 1;
declare ModeCount = 1;
declare ShotsFired = 0;
while (!MatchEndRequested && !ServerShutdownRequested)
{
yield;
if (Now >= NextSwitch - 5000 && WarningGiven == 0) {
UIManager.UIAll.SendChat("""$fffOscillation #$0f0{{{ModeCount}}}$fff will start oscillating in $0f0five $fffseconds.""");
WarningGiven = 1;
}
if(Now == NextSwitch - 5000){
WarningGiven = 0;
UIManager.UIAll.BigMessage = "5";
WarningGiven = 1;
}
if(Now == NextSwitch - 4000){
WarningGiven = 0;
UIManager.UIAll.BigMessage = "4";
WarningGiven = 1;
}
if(Now == NextSwitch - 3000){
WarningGiven = 0;
UIManager.UIAll.BigMessage = "3";
WarningGiven = 1;
}
if(Now == NextSwitch - 2000){
WarningGiven = 0;
UIManager.UIAll.BigMessage = "2";
WarningGiven = 1;
}
if(Now == NextSwitch - 1000){
WarningGiven = 0;
UIManager.UIAll.BigMessage = "1";
WarningGiven = 1;
}
if (Now >= NextSwitch) {
WarningGiven = 0;
ModeCount += 1;
NextSwitch = Now + (SwitchInt * 1000);
while (Mode == PrevMode) {
Mode = MathLib::Rand(0,10);
}
PrevMode = Mode;
switch (Mode) {
case 0:
UIManager.UIAll.BigMessage = "Normal Mode";
case 1:
UIManager.UIAll.BigMessage = """Self-eliminations cost {{{SelfElimCost}}} points!""";
case 2:
UIManager.UIAll.BigMessage = "Spawn with 3 Armor Points!";
case 3:
UIManager.UIAll.BigMessage = "UNLIMITED! POWER!!";
case 4:
UIManager.UIAll.BigMessage = "Don't get eliminated!";
case 5:
UIManager.UIAll.BigMessage = "Spawn with Laser only!";
case 6:
UIManager.UIAll.BigMessage = "Spawn with Nucleus only!";
case 7:
UIManager.UIAll.BigMessage = "DOUBLE POINTS!";
case 8: {
UIManager.UIAll.BigMessage = "It's a one-hit wonder!";
foreach(Player in Players) {
Player.Armor = 100;
}
}
case 9: {
UIManager.UIAll.BigMessage = "Health: Refilled!";
foreach (Player in Players) {
Player.Armor = Player.ArmorMax;
}
}
}
}
foreach (Event, PendingEvents) {
if (Event.Type == CSmModeEvent::EType::OnArmorEmpty) {
if (Event.Shooter == Event.Victim || Event.Shooter == Null) {
if (Mode == 1) {
Score::RemovePoints(Event.Victim, SelfElimCost);
} else {
Score::RemovePoints(Event.Victim, 1);
}
}
XmlRpc.SendCallback("playerDeath", Event.Victim.Login);
PassOn(Event);
} else if (Event.Type == CSmModeEvent::EType::OnShoot) {
ShotsFired += 1;
PassOn(Event);
} else if (Event.Type == CSmModeEvent::EType::OnHit) {
if (Event.Shooter == Event.Victim) {
Discard(Event);
} else {
declare Points = Event.Damage / 100;
if (Mode == 7) {
Points = Points * 2;
}
XmlRpc.SendCallback("playerHit", "Victim:"^Event.Victim.Login^";Shooter:"^Event.Shooter.Login^";"^Points);
Score::AddPoints(Event.Shooter, Points);
PassOn(Event);
// Play sound and notice if someone is close to win
if (Event.Shooter != Null && Event.Shooter.Score != Null) {
declare Gap = PointLimit - Event.Shooter.Score.RoundPoints;
if (Gap <= 3 && Gap > 0) {
declare Variant = 3 - Gap;
declare Msg = "";
if (Gap > 1)
Msg = TextLib::Compose(_("$<%1$> is %2 points from victory!"), Event.Shooter.Name, TextLib::ToText(Gap));
else
Msg = TextLib::Compose(_("$<%1$> is 1 point from victory!"), Event.Shooter.Name);
UIManager.UIAll.SendNotice(
Msg,
CUIConfig::ENoticeLevel::PlayerInfo,
Null, CUIConfig::EAvatarVariant::Default,
CUIConfig::EUISound::TieBreakPoint, Variant
);
} else if (Gap <= 0) {
UIManager.UIAll.SendNotice(
TextLib::Compose(_("$<%1$> gets the final hit!"), Event.Shooter.Name),
CUIConfig::ENoticeLevel::PlayerInfo,
Null, CUIConfig::EAvatarVariant::Default,
CUIConfig::EUISound::VictoryPoint, 0
);
}
}
PassOn(Event);
}
} else if (Event.Type == CSmModeEvent::EType::OnPlayerRequestRespawn) {
if (Mode == 1) {
Score::RemovePoints(Event.Player, SelfElimCost);
} else if (Mode != 2 || Mode != 5 || Mode != 6) {
Score::RemovePoints(Event.Player, 1);
}
if (Mode == 2 || Mode == 5 || Mode == 6) {
Discard(Event);
} else {
PassOn(Event);
}
} else {
PassOn(Event);
}
}
foreach (Player in Players) {
//Other things
if (Mode == 3) {
Player.AmmoGain = 10.0;
} else {
Player.AmmoGain = 1.0;
}
// Spawn
if (Mode != 4) {
if (Player.SpawnStatus == CSmPlayer::ESpawnStatus::NotSpawned && !Player.RequestsSpectate) {
if (Mode == 2) {
Player.ArmorMax = 300;
} else {
Player.ArmorMax = 200;
}
if (Mode == 5) {
SetPlayerWeapon(Player, CSmMode::EWeapon::Laser, False);
} else if (Mode == 6) {
SetPlayerWeapon(Player, CSmMode::EWeapon::Nucleus, False);
} else {
SetPlayerWeapon(Player, CSmMode::EWeapon::Rocket, True);
}
SpawnPlayers(Player);
}
}
}
/* -------------------------------------- */
// Update UI
if (LastUITick + C_UITickInterval < Now) {
declare UsedLayers = Ident[];
// Add layer and create it if necessary
foreach (Player in Players) {
declare UI <=> UIManager.GetUI(Player);
if (UI == Null) continue;
declare CUILayer LayerInfos;
if (UI.UILayers.count != 1) {
LayerInfos <=> UIManager.UILayerCreate();
UI.UILayers.add(LayerInfos);
} else {
LayerInfos <=> UI.UILayers[0];
}
UsedLayers.add(LayerInfos.Id);
LayerInfos.ManialinkPage = UpdateLayerInfos(Player);
}
// Remove layers
declare LayersToRemove = Ident[];
foreach (Layer in UIManager.UILayers) {
if (!UsedLayers.exists(Layer.Id) && Layer != LayerSpawnScreen) {
LayersToRemove.add(Layer.Id);
}
}
foreach (LayerId in LayersToRemove) {
UIManager.UILayerDestroy(UIManager.UILayers[LayerId]);
}
LastUITick = Now;
}
////////////////////////////////////
// victory conditions
declare IsMatchOver = False;
if (Now > EndTime)
IsMatchOver = True;
foreach (Player in Players) {
if (Player.Score != Null && Player.Score.RoundPoints >= PointLimit)
IsMatchOver = True;
}
if (IsMatchOver)
break;
}
Score::RoundEnd();
XmlRpc.SendCallback("endRound",MapName);
Score::MatchEnd(True);
declare PlayerList = "";
foreach (Player in Players) {
PlayerList = PlayerList^(Player.Login^":"^Player.Score.Points^";");
}
foreach (Player in Spectators) {
PlayerList = PlayerList^(Player.Login^":"^Player.Score.Points^";");
}
XmlRpc.SendCallback("endMap",PlayerList);
////////////////////////////////////
// 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);
}
if (Winner != Null) {
UIManager.UIAll.BigMessage = TextLib::Compose(_("$<%1$> wins the match!"), Winner.Name);
} else {
UIManager.UIAll.BigMessage = _("|Match|Draw");
}
UIManager.UIAll.SendChat("""Fun fact: $0f0{{{ShotsFired}}}$fff shots were fired this match.""");
sleep(5000);
UIManager.UIAll.UISequence = CUIConfig::EUISequence::Podium;
UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::ForcedVisible;
wait(UIManager.UIAll.UISequenceIsCompleted);
UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal;
UIManager.UIAll.BigMessage = "";
UnloadMap();
}
UIManager.UILayerDestroy(LayerSpawnScreen);
}