/**************************************** * MapType for Athletics Game Mode * * Author: steeffeen * * Contact: schteffens@gmail.com * ****************************************/ #RequireContext CSmMapType #Include "TextLib" as TextLib #Include "Libs/Nadeo/Anchor.Script.txt" as Anchor #Const Version "0.6 (2013-04-25)" #Const C_LobbyName "Lobby" #Const C_DisciplineTypes [1 => "LongJump", 2 => "HighJump", 3 => "Run", 4 => "Rounds"] declare Integer[Text] G_Disciplines; declare Integer[Text] G_Rounds; // Initializes all anchors to default Void InitAnchors() { foreach (Anchor in AnchorData) { Anchor.Tag = Anchor.DefaultTag; Anchor.Order = Anchor.DefaultOrder; } } // Check validity of discipline name Boolean CheckDisciplineNameIsValid(Text _Name) { // Check name length if (TextLib::Length(_Name) <= 0) { return False; } // Check for invalid chars for (Index, 0, TextLib::Length(_Name)-1) { switch (TextLib::SubString(_Name, Index, 1)) { case ":": { return False; } case "\\": { return False; } case "\"": { return False; } } } return True; } // Extracts discipline of a goal tag Text GetDisciplineFromGoalTag(Text _Tag) { for (Index, 0, TextLib::Length(_Tag)-1) { if (TextLib::SubString(_Tag, Index, 1) == ":") { return TextLib::SubString(_Tag, 0, Index); } } return ""; } // Extracts goal type of a tag Text GetGoalTypeFromTag(Text _Tag) { for (Index, 0, TextLib::Length(_Tag)-1) { if (TextLib::SubString(_Tag, Index, 1) == ":") { return TextLib::SubString(_Tag, Index+2, TextLib::Length(_Tag)-2-Index); } } return ""; } // Assigns order for extra information to all goal anchors of a discipline Void AssignExtraOrder(Text _Discipline, Integer _Order) { foreach (Anchor in AnchorData) { if ((Anchor.DefaultTag == "Goal" || Anchor.DefaultTag == "Checkpoint") && _Discipline == GetDisciplineFromGoalTag(Anchor.Tag)) { if ("Goal" == GetGoalTypeFromTag(Anchor.Tag)) { Anchor.Order = _Order; } else { Anchor.Order = 0; } } } } // Get created disciplines of the map Void GatherDisciplines() { G_Disciplines.clear(); // Clear old disciplines foreach (Anchor in AnchorData) { switch (Anchor.DefaultTag) { // Disciplines are defined by spawns case "Spawn": { // Ignore default spawns and check name validity if (Anchor.Tag != "Spawn" && Anchor.Tag != C_LobbyName && CheckDisciplineNameIsValid(Anchor.Tag)) { if (!G_Disciplines.existskey(Anchor.Tag)) { // New discipline found - Save name and type G_Disciplines[Anchor.Tag] = Anchor.Order; } } } } } } // Counts goals of a discipline Integer NumberOfDisciplineGoals(Text _Discipline, Text _GoalType) { declare NbGoals = 0; foreach (Anchor in AnchorData) { if (Anchor.DefaultTag == "Goal" || Anchor.DefaultTag == "Checkpoint") { // Only check goals if (TextLib::SubString(Anchor.Tag, 0, TextLib::Length(_Discipline)) == _Discipline) { // Goal belongs to the discipline if (TextLib::SubString(Anchor.Tag, TextLib::Length(Anchor.Tag)-4, 4) == _GoalType) { // Goal is a discipline goal NbGoals += 1; } } } } return NbGoals; } // Check if the map is valid Void UpdateValidability() { ValidationStatus = CSmMapType::ValidationStatus::NotValidable; GatherDisciplines(); Anchor::UpdateAnchorCounts(); // Check for unused spawns if (Anchor::HasAtLeastOneAnchor("Spawn", 0, "")) { ValidabilityRequirementsMessage = "You have at least one unused Spawn!"; ValidationStatus = CSmMapType::ValidationStatus::NotValidable; return; } // Check for unused goals if (Anchor::HasAtLeastOneAnchor("Goal", 0, "")) { ValidabilityRequirementsMessage = "You have at least one unused Goal!"; ValidationStatus = CSmMapType::ValidationStatus::NotValidable; return; } // Check lobby if (!Anchor::HasExactlyOneAnchor(C_LobbyName, 0, """You must place exactly one {{{C_LobbyName}}}!""")) return; // Check disciplines foreach (Name => Type in G_Disciplines) { // Check for ports if (NumberOfDisciplineGoals(Name, "Port") != 1) { // Missing port ValidabilityRequirementsMessage = """You must place at exactly one {{{Name}}} port!"""; ValidationStatus = CSmMapType::ValidationStatus::NotValidable; return; } // Check for goals switch (Type) { case 3: { // Run if (NumberOfDisciplineGoals(Name, "Goal") < 1) { // Missing finish ValidabilityRequirementsMessage = """You must place at least one {{{Name}}} goal!"""; ValidationStatus = CSmMapType::ValidationStatus::NotValidable; return; } } case 4: { // Rounds if (NumberOfDisciplineGoals(Name, "Goal") < 2) { // Missing checkpoints ValidabilityRequirementsMessage = """You must place at least two {{{Name}}} checkpoints (goals)!"""; ValidationStatus = CSmMapType::ValidationStatus::NotValidable; return; } // Check if rounds count is set declare RoundsSet = True; foreach (Anchor in AnchorData) { if (Name == GetDisciplineFromGoalTag(Anchor.Tag) && "Spawn" != Anchor.DefaultTag && "Goal" == GetGoalTypeFromTag(Anchor.Tag)) { if (Anchor.Order <= 0) { RoundsSet = False; } } } if (!RoundsSet) { // Rounds are not set! ValidabilityRequirementsMessage = """You must set the amount of rounds for {{{Name}}}!"""; ValidationStatus = CSmMapType::ValidationStatus::NotValidable; return; } } } } ValidabilityRequirementsMessage = ""; ValidationStatus = CSmMapType::ValidationStatus::Validated; } // Return the manialink for spawn anchor edition Text EditSpawnAnchorManialink(Ident _AnchorId) { declare Manialink = """