summaryrefslogtreecommitdiff
path: root/sourcemod/scripting/gokz-core/map/end.sp
diff options
context:
space:
mode:
Diffstat (limited to 'sourcemod/scripting/gokz-core/map/end.sp')
-rw-r--r--sourcemod/scripting/gokz-core/map/end.sp155
1 files changed, 155 insertions, 0 deletions
diff --git a/sourcemod/scripting/gokz-core/map/end.sp b/sourcemod/scripting/gokz-core/map/end.sp
new file mode 100644
index 0000000..d119084
--- /dev/null
+++ b/sourcemod/scripting/gokz-core/map/end.sp
@@ -0,0 +1,155 @@
+/*
+ Hooks between specifically named end destinations and GOKZ
+*/
+
+
+
+static Regex RE_BonusEndButton;
+static Regex RE_BonusEndZone;
+static CourseTimerType endType[GOKZ_MAX_COURSES];
+static float endOrigin[GOKZ_MAX_COURSES][3];
+static float endAngles[GOKZ_MAX_COURSES][3];
+
+
+
+// =====[ EVENTS ]=====
+
+void OnPluginStart_MapEnd()
+{
+ RE_BonusEndButton = CompileRegex(GOKZ_BONUS_END_BUTTON_NAME_REGEX);
+ RE_BonusEndZone = CompileRegex(GOKZ_BONUS_END_ZONE_NAME_REGEX);
+}
+
+void OnEntitySpawnedPost_MapEnd(int entity)
+{
+ char buffer[32];
+
+ GetEntityClassname(entity, buffer, sizeof(buffer));
+
+ if (StrEqual("trigger_multiple", buffer, false))
+ {
+ bool isEndZone;
+ if (GetEntityName(entity, buffer, sizeof(buffer)) != 0)
+ {
+ if (StrEqual(GOKZ_END_ZONE_NAME, buffer, false))
+ {
+ isEndZone = true;
+ StoreEnd(0, entity, CourseTimerType_ZoneNew);
+ }
+ else if (GetEndZoneBonusNumber(entity) != -1)
+ {
+ int course = GetEndZoneBonusNumber(entity);
+ if (GOKZ_IsValidCourse(course, true))
+ {
+ isEndZone = true;
+ StoreEnd(course, entity, CourseTimerType_ZoneNew);
+ }
+ }
+ }
+ if (!isEndZone)
+ {
+ TimerButtonTrigger trigger;
+ if (IsTimerButtonTrigger(entity, trigger) && !trigger.isStartTimer)
+ {
+ StoreEnd(trigger.course, entity, CourseTimerType_ZoneLegacy);
+ }
+ }
+ }
+ else if (StrEqual("func_button", buffer, false))
+ {
+ bool isEndButton;
+ if (GetEntityName(entity, buffer, sizeof(buffer)) != 0)
+ {
+ if (StrEqual(GOKZ_END_BUTTON_NAME, buffer, false))
+ {
+ isEndButton = true;
+ StoreEnd(0, entity, CourseTimerType_Button);
+ }
+ else
+ {
+ int course = GetEndButtonBonusNumber(entity);
+ if (GOKZ_IsValidCourse(course, true))
+ {
+ isEndButton = true;
+ StoreEnd(course, entity, CourseTimerType_Button);
+ }
+ }
+ }
+ if (!isEndButton)
+ {
+ TimerButtonTrigger trigger;
+ if (IsTimerButtonTrigger(entity, trigger) && !trigger.isStartTimer)
+ {
+ StoreEnd(trigger.course, entity, CourseTimerType_Button);
+ }
+ }
+ }
+}
+
+void OnMapStart_MapEnd()
+{
+ for (int course = 0; course < GOKZ_MAX_COURSES; course++)
+ {
+ endType[course] = CourseTimerType_None;
+ }
+}
+
+bool GetMapEndPosition(int course, float origin[3], float angles[3])
+{
+ if (endType[course] == CourseTimerType_None)
+ {
+ return false;
+ }
+
+ origin = endOrigin[course];
+ angles = endAngles[course];
+
+ return true;
+}
+
+
+
+// =====[ PRIVATE ]=====
+
+static void StoreEnd(int course, int entity, CourseTimerType type)
+{
+ // If StoreEnd is called, then there is at least an end position (even though it might not be a valid one)
+ if (endType[course] < CourseTimerType_Default)
+ {
+ endType[course] = CourseTimerType_Default;
+ }
+
+ // Real zone is always better than "fake" zones which are better than buttons
+ // as the buttons found in a map with fake zones aren't meant to be visible.
+ if (endType[course] >= type)
+ {
+ return;
+ }
+
+ float origin[3], distFromCenter[3];
+ GetEntityPositions(entity, origin, endOrigin[course], endAngles[course], distFromCenter);
+
+ // If it is a button or the center of the center of the zone is invalid
+ if (type == CourseTimerType_Button || !IsSpawnValid(endOrigin[course]))
+ {
+ // Attempt with various positions around the entity, pick the first valid one.
+ if (!FindValidPositionAroundTimerEntity(entity, endOrigin[course], endAngles[course], type == CourseTimerType_Button))
+ {
+ endOrigin[course][2] -= 64.0; // Move the origin down so the eye position is directly on top of the button/zone.
+ return;
+ }
+ }
+
+ // Only update the CourseTimerType if a valid position is found.
+ endType[course] = type;
+}
+
+static int GetEndButtonBonusNumber(int entity)
+{
+ return GOKZ_MatchIntFromEntityName(entity, RE_BonusEndButton, 1);
+}
+
+static int GetEndZoneBonusNumber(int entity)
+{
+ return GOKZ_MatchIntFromEntityName(entity, RE_BonusEndZone, 1);
+}