summaryrefslogtreecommitdiff
path: root/sourcemod/scripting/gokz-core/map
diff options
context:
space:
mode:
Diffstat (limited to 'sourcemod/scripting/gokz-core/map')
-rw-r--r--sourcemod/scripting/gokz-core/map/buttons.sp138
-rw-r--r--sourcemod/scripting/gokz-core/map/end.sp155
-rw-r--r--sourcemod/scripting/gokz-core/map/mapfile.sp502
-rw-r--r--sourcemod/scripting/gokz-core/map/prefix.sp48
-rw-r--r--sourcemod/scripting/gokz-core/map/starts.sp219
-rw-r--r--sourcemod/scripting/gokz-core/map/triggers.sp855
-rw-r--r--sourcemod/scripting/gokz-core/map/zones.sp183
7 files changed, 0 insertions, 2100 deletions
diff --git a/sourcemod/scripting/gokz-core/map/buttons.sp b/sourcemod/scripting/gokz-core/map/buttons.sp
deleted file mode 100644
index 8923fbd..0000000
--- a/sourcemod/scripting/gokz-core/map/buttons.sp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- Hooks between specifically named func_buttons and GOKZ.
-*/
-
-
-
-static Regex RE_BonusStartButton;
-static Regex RE_BonusEndButton;
-
-
-
-// =====[ EVENTS ]=====
-
-void OnPluginStart_MapButtons()
-{
- RE_BonusStartButton = CompileRegex(GOKZ_BONUS_START_BUTTON_NAME_REGEX);
- RE_BonusEndButton = CompileRegex(GOKZ_BONUS_END_BUTTON_NAME_REGEX);
-}
-
-void OnEntitySpawned_MapButtons(int entity)
-{
- char buffer[32];
-
- GetEntityClassname(entity, buffer, sizeof(buffer));
- if (!StrEqual("func_button", buffer, false))
- {
- return;
- }
-
- if (GetEntityName(entity, buffer, sizeof(buffer)) == 0)
- {
- return;
- }
-
- int course = 0;
- if (StrEqual(GOKZ_START_BUTTON_NAME, buffer, false))
- {
- HookSingleEntityOutput(entity, "OnPressed", OnStartButtonPress);
- RegisterCourseStart(course);
- }
- else if (StrEqual(GOKZ_END_BUTTON_NAME, buffer, false))
- {
- HookSingleEntityOutput(entity, "OnPressed", OnEndButtonPress);
- RegisterCourseEnd(course);
- }
- else if ((course = GetStartButtonBonusNumber(entity)) != -1)
- {
- HookSingleEntityOutput(entity, "OnPressed", OnBonusStartButtonPress);
- RegisterCourseStart(course);
- }
- else if ((course = GetEndButtonBonusNumber(entity)) != -1)
- {
- HookSingleEntityOutput(entity, "OnPressed", OnBonusEndButtonPress);
- RegisterCourseEnd(course);
- }
-}
-
-public void OnStartButtonPress(const char[] name, int caller, int activator, float delay)
-{
- if (!IsValidEntity(caller) || !IsValidClient(activator))
- {
- return;
- }
-
- ProcessStartButtonPress(activator, 0);
-}
-
-public void OnEndButtonPress(const char[] name, int caller, int activator, float delay)
-{
- if (!IsValidEntity(caller) || !IsValidClient(activator))
- {
- return;
- }
-
- ProcessEndButtonPress(activator, 0);
-}
-
-public void OnBonusStartButtonPress(const char[] name, int caller, int activator, float delay)
-{
- if (!IsValidEntity(caller) || !IsValidClient(activator))
- {
- return;
- }
-
- int course = GetStartButtonBonusNumber(caller);
- if (!GOKZ_IsValidCourse(course, true))
- {
- return;
- }
-
- ProcessStartButtonPress(activator, course);
-}
-
-public void OnBonusEndButtonPress(const char[] name, int caller, int activator, float delay)
-{
- if (!IsValidEntity(caller) || !IsValidClient(activator))
- {
- return;
- }
-
- int course = GetEndButtonBonusNumber(caller);
- if (!GOKZ_IsValidCourse(course, true))
- {
- return;
- }
-
- ProcessEndButtonPress(activator, course);
-}
-
-
-
-// =====[ PRIVATE ]=====
-
-static void ProcessStartButtonPress(int client, int course)
-{
- if (GOKZ_StartTimer(client, course))
- {
- // Only calling on success is intended behaviour (and prevents virtual button exploits)
- OnStartButtonPress_Teleports(client, course);
- OnStartButtonPress_VirtualButtons(client, course);
- }
-}
-
-static void ProcessEndButtonPress(int client, int course)
-{
- GOKZ_EndTimer(client, course);
- OnEndButtonPress_VirtualButtons(client, course);
-}
-
-static int GetStartButtonBonusNumber(int entity)
-{
- return GOKZ_MatchIntFromEntityName(entity, RE_BonusStartButton, 1);
-}
-
-static int GetEndButtonBonusNumber(int entity)
-{
- return GOKZ_MatchIntFromEntityName(entity, RE_BonusEndButton, 1);
-} \ No newline at end of file
diff --git a/sourcemod/scripting/gokz-core/map/end.sp b/sourcemod/scripting/gokz-core/map/end.sp
deleted file mode 100644
index d119084..0000000
--- a/sourcemod/scripting/gokz-core/map/end.sp
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- 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);
-}
diff --git a/sourcemod/scripting/gokz-core/map/mapfile.sp b/sourcemod/scripting/gokz-core/map/mapfile.sp
deleted file mode 100644
index db60e7e..0000000
--- a/sourcemod/scripting/gokz-core/map/mapfile.sp
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- Mapping API
-
- Reads data from the current map file.
-*/
-
-static Regex RE_BonusStartButton;
-static Regex RE_BonusEndButton;
-
-// NOTE: 4 megabyte array for entity lump reading.
-static char gEntityLump[4194304];
-
-// =====[ PUBLIC ]=====
-
-void EntlumpParse(StringMap antiBhopTriggers, StringMap teleportTriggers, StringMap timerButtonTriggers, int &mappingApiVersion)
-{
- char mapPath[512];
- GetCurrentMap(mapPath, sizeof(mapPath));
- Format(mapPath, sizeof(mapPath), "maps/%s.bsp", mapPath);
-
- // https://developer.valvesoftware.com/wiki/Source_BSP_File_Format
-
- File file = OpenFile(mapPath, "rb");
- if (file != INVALID_HANDLE)
- {
- int identifier;
- file.ReadInt32(identifier);
-
- if (identifier == GOKZ_BSP_HEADER_IDENTIFIER)
- {
- // skip version number
- file.Seek(4, SEEK_CUR);
-
- // the entity lump info is the first lump in the array, so we don't need to seek any further.
- int offset;
- int length;
- file.ReadInt32(offset);
- file.ReadInt32(length);
-
- // jump to the start of the entity lump
- file.Seek(offset, SEEK_SET);
-
- int charactersRead = file.ReadString(gEntityLump, sizeof(gEntityLump), length);
- delete file;
- if (charactersRead >= sizeof(gEntityLump) - 1)
- {
- PushMappingApiError("ERROR: Entity lump: The map's entity lump is too big! Reduce the amount of entities in your map.");
- return;
- }
- gEntityLump[length] = '\0';
-
- int index = 0;
-
- StringMap entity = new StringMap();
- bool gotWorldSpawn = false;
- while (EntlumpParseEntity(entity, gEntityLump, index))
- {
- char classname[128];
- char targetName[GOKZ_ENTLUMP_MAX_VALUE];
- entity.GetString("classname", classname, sizeof(classname));
-
- if (!gotWorldSpawn && StrEqual("worldspawn", classname, false))
- {
- gotWorldSpawn = true;
- char versionString[32];
- if (entity.GetString("climb_mapping_api_version", versionString, sizeof(versionString)))
- {
- if (StringToIntEx(versionString, mappingApiVersion) == 0)
- {
- PushMappingApiError("ERROR: Entity lump: Couldn't parse Mapping API version from map properties: \"%s\".", versionString);
- mappingApiVersion = GOKZ_MAPPING_API_VERSION_NONE;
- }
- }
- else
- {
- // map doesn't have a mapping api version.
- mappingApiVersion = GOKZ_MAPPING_API_VERSION_NONE;
- }
- }
- else if (StrEqual("trigger_multiple", classname, false))
- {
- TriggerType triggerType;
- if (!gotWorldSpawn || mappingApiVersion != GOKZ_MAPPING_API_VERSION_NONE)
- {
- if (entity.GetString("targetname", targetName, sizeof(targetName)))
- {
- // get trigger properties if applicable
- triggerType = GetTriggerType(targetName);
- if (triggerType == TriggerType_Antibhop)
- {
- AntiBhopTrigger trigger;
- if (GetAntiBhopTriggerEntityProperties(trigger, entity))
- {
- char key[32];
- IntToString(trigger.hammerID, key, sizeof(key));
- antiBhopTriggers.SetArray(key, trigger, sizeof(trigger));
- }
- }
- else if (triggerType == TriggerType_Teleport)
- {
- TeleportTrigger trigger;
- if (GetTeleportTriggerEntityProperties(trigger, entity))
- {
- char key[32];
- IntToString(trigger.hammerID, key, sizeof(key));
- teleportTriggers.SetArray(key, trigger, sizeof(trigger));
- }
- }
- }
- }
-
- // Tracking legacy timer triggers that press the timer buttons upon triggered.
- if (triggerType == TriggerType_Invalid)
- {
- char touchOutput[128];
- ArrayList value;
-
- if (entity.GetString("OnStartTouch", touchOutput, sizeof(touchOutput)))
- {
- TimerButtonTriggerCheck(touchOutput, sizeof(touchOutput), entity, timerButtonTriggers);
- }
- else if (entity.GetValue("OnStartTouch", value)) // If there are multiple outputs, we have to check for all of them.
- {
- for (int i = 0; i < value.Length; i++)
- {
- value.GetString(i, touchOutput, sizeof(touchOutput));
- TimerButtonTriggerCheck(touchOutput, sizeof(touchOutput), entity, timerButtonTriggers);
- }
- }
- }
- }
- else if (StrEqual("func_button", classname, false))
- {
- char pressOutput[128];
- ArrayList value;
-
- if (entity.GetString("OnPressed", pressOutput, sizeof(pressOutput)))
- {
- TimerButtonTriggerCheck(pressOutput, sizeof(pressOutput), entity, timerButtonTriggers);
- }
- else if (entity.GetValue("OnPressed", value)) // If there are multiple outputs, we have to check for all of them.
- {
- for (int i = 0; i < value.Length; i++)
- {
- value.GetString(i, pressOutput, sizeof(pressOutput));
- TimerButtonTriggerCheck(pressOutput, sizeof(pressOutput), entity, timerButtonTriggers);
- }
- }
- }
- // clear for next loop
- entity.Clear();
- }
- delete entity;
- }
- delete file;
- }
- else
- {
- // TODO: do something more elegant
- SetFailState("Catastrophic extreme hyperfailure! Mapping API Couldn't open the map file for reading! %s. The map file might be gone or another program is using it.", mapPath);
- }
-}
-
-
-// =====[ EVENTS ]=====
-
-void OnPluginStart_MapFile()
-{
- char buffer[64];
- char press[8];
- FormatEx(press, sizeof(press), "%s%s", CHAR_ESCAPE, "Press");
-
- buffer = GOKZ_BONUS_START_BUTTON_NAME_REGEX;
- ReplaceStringEx(buffer, sizeof(buffer), "$", "");
- StrCat(buffer, sizeof(buffer), press);
- RE_BonusStartButton = CompileRegex(buffer);
-
- buffer = GOKZ_BONUS_END_BUTTON_NAME_REGEX;
- ReplaceStringEx(buffer, sizeof(buffer), "$", "");
- StrCat(buffer, sizeof(buffer), press);
- RE_BonusEndButton = CompileRegex(buffer);
-}
-
-
-// =====[ PRIVATE ]=====
-
-static void EntlumpSkipAllWhiteSpace(char[] entityLump, int &index)
-{
- while (IsCharSpace(entityLump[index]) && entityLump[index] != '\0')
- {
- index++;
- }
-}
-
-static int EntlumpGetString(char[] result, int maxLength, int copyCount, char[] entityLump, int entlumpIndex)
-{
- int finalLength;
- for (int i = 0; i < maxLength - 1 && i < copyCount; i++)
- {
- if (entityLump[entlumpIndex + i] == '\0')
- {
- break;
- }
- result[i] = entityLump[entlumpIndex + i];
- finalLength++;
- }
-
- result[finalLength] = '\0';
- return finalLength;
-}
-
-static EntlumpToken EntlumpGetToken(char[] entityLump, int &entlumpIndex)
-{
- EntlumpToken result;
-
- EntlumpSkipAllWhiteSpace(entityLump, entlumpIndex);
-
- switch (entityLump[entlumpIndex])
- {
- case '{':
- {
- result.type = EntlumpTokenType_OpenBrace;
- EntlumpGetString(result.string, sizeof(result.string), 1, entityLump, entlumpIndex);
- entlumpIndex++;
- }
- case '}':
- {
- result.type = EntlumpTokenType_CloseBrace;
- EntlumpGetString(result.string, sizeof(result.string), 1, entityLump, entlumpIndex);
- entlumpIndex++;
- }
- case '\0':
- {
- result.type = EntlumpTokenType_EndOfStream;
- EntlumpGetString(result.string, sizeof(result.string), 1, entityLump, entlumpIndex);
- entlumpIndex++;
- }
- case '\"':
- {
- result.type = EntlumpTokenType_Identifier;
- int identifierLen;
- entlumpIndex++;
- for (int i = 0; i < sizeof(result.string) - 1; i++)
- {
- // NOTE: Unterminated strings can probably never happen, since the map has to be
- // loaded by the game first and the engine will fail the load before we get to it.
- if (entityLump[entlumpIndex + i] == '\0')
- {
- result.type = EntlumpTokenType_Unknown;
- break;
- }
- if (entityLump[entlumpIndex + i] == '\"')
- {
- break;
- }
- result.string[i] = entityLump[entlumpIndex + i];
- identifierLen++;
- }
-
- entlumpIndex += identifierLen + 1; // +1 to skip over last quotation mark
- result.string[identifierLen] = '\0';
- }
- default:
- {
- result.type = EntlumpTokenType_Unknown;
- result.string[0] = entityLump[entlumpIndex];
- result.string[1] = '\0';
- }
- }
-
- return result;
-}
-
-static bool EntlumpParseEntity(StringMap result, char[] entityLump, int &entlumpIndex)
-{
- EntlumpToken token;
- token = EntlumpGetToken(entityLump, entlumpIndex);
- if (token.type == EntlumpTokenType_EndOfStream)
- {
- return false;
- }
-
- // NOTE: The following errors will very very likely never happen, since the entity lump has to be
- // loaded by the game first and the engine will fail the load before we get to it.
- // But if there's an obscure bug in this code, then we'll know!!!
- for (;;)
- {
- token = EntlumpGetToken(entityLump, entlumpIndex);
- switch (token.type)
- {
- case EntlumpTokenType_OpenBrace:
- {
- continue;
- }
- case EntlumpTokenType_Identifier:
- {
- EntlumpToken valueToken;
- valueToken = EntlumpGetToken(entityLump, entlumpIndex);
- if (valueToken.type == EntlumpTokenType_Identifier)
- {
- char tempString[GOKZ_ENTLUMP_MAX_VALUE];
- ArrayList values;
- if (result.GetString(token.string, tempString, sizeof(tempString)))
- {
- result.Remove(token.string);
- values = new ArrayList(ByteCountToCells(GOKZ_ENTLUMP_MAX_VALUE));
- values.PushString(tempString);
- values.PushString(valueToken.string);
- result.SetValue(token.string, values);
- }
- else if (result.GetValue(token.string, values))
- {
- values.PushString(valueToken.string);
- }
- else
- {
- result.SetString(token.string, valueToken.string);
- }
- }
- else
- {
- PushMappingApiError("ERROR: Entity lump: Unexpected token \"%s\".", valueToken.string);
- return false;
- }
- }
- case EntlumpTokenType_CloseBrace:
- {
- break;
- }
- case EntlumpTokenType_EndOfStream:
- {
- PushMappingApiError("ERROR: Entity lump: Unexpected end of entity lump! Entity lump parsing failed.");
- return false;
- }
- default:
- {
- PushMappingApiError("ERROR: Entity lump: Invalid token \"%s\". Entity lump parsing failed.", token.string);
- return false;
- }
- }
- }
-
- return true;
-}
-
-static bool GetHammerIDFromEntityStringMap(int &result, StringMap entity)
-{
- char hammerID[32];
- if (!entity.GetString("hammerid", hammerID, sizeof(hammerID))
- || StringToIntEx(hammerID, result) == 0)
- {
- // if we don't have the hammer id, then we can't match the entity to an existing one!
- char origin[64];
- entity.GetString("origin", origin, sizeof(origin));
- PushMappingApiError("ERROR: Failed to parse \"hammerid\" keyvalue on trigger! \"%i\" origin: %s.", result, origin);
- return false;
- }
- return true;
-}
-
-static bool GetAntiBhopTriggerEntityProperties(AntiBhopTrigger result, StringMap entity)
-{
- if (!GetHammerIDFromEntityStringMap(result.hammerID, entity))
- {
- return false;
- }
-
- char time[32];
- if (!entity.GetString("climb_anti_bhop_time", time, sizeof(time))
- || StringToFloatEx(time, result.time) == 0)
- {
- result.time = GOKZ_ANTI_BHOP_TRIGGER_DEFAULT_DELAY;
- }
-
- return true;
-}
-
-static bool GetTeleportTriggerEntityProperties(TeleportTrigger result, StringMap entity)
-{
- if (!GetHammerIDFromEntityStringMap(result.hammerID, entity))
- {
- return false;
- }
-
- char buffer[64];
- if (!entity.GetString("climb_teleport_type", buffer, sizeof(buffer))
- || StringToIntEx(buffer, view_as<int>(result.type)) == 0)
- {
- result.type = GOKZ_TELEPORT_TRIGGER_DEFAULT_TYPE;
- }
-
- if (!entity.GetString("climb_teleport_destination", result.tpDestination, sizeof(result.tpDestination)))
- {
- // We don't want triggers without destinations dangling about, so we need to tell everyone about it!!!
- PushMappingApiError("ERROR: Could not find \"climb_teleport_destination\" keyvalue on a climb_teleport trigger! hammer id \"%i\".",
- result.hammerID);
- return false;
- }
-
- if (!entity.GetString("climb_teleport_delay", buffer, sizeof(buffer))
- || StringToFloatEx(buffer, result.delay) == 0)
- {
- result.delay = GOKZ_TELEPORT_TRIGGER_DEFAULT_DELAY;
- }
-
- if (!entity.GetString("climb_teleport_use_dest_angles", buffer, sizeof(buffer))
- || StringToIntEx(buffer, result.useDestAngles) == 0)
- {
- result.useDestAngles = GOKZ_TELEPORT_TRIGGER_DEFAULT_USE_DEST_ANGLES;
- }
-
- if (!entity.GetString("climb_teleport_reset_speed", buffer, sizeof(buffer))
- || StringToIntEx(buffer, result.resetSpeed) == 0)
- {
- result.resetSpeed = GOKZ_TELEPORT_TRIGGER_DEFAULT_RESET_SPEED;
- }
-
- if (!entity.GetString("climb_teleport_reorient_player", buffer, sizeof(buffer))
- || StringToIntEx(buffer, result.reorientPlayer) == 0)
- {
- result.reorientPlayer = GOKZ_TELEPORT_TRIGGER_DEFAULT_REORIENT_PLAYER;
- }
-
- if (!entity.GetString("climb_teleport_relative", buffer, sizeof(buffer))
- || StringToIntEx(buffer, result.relativeDestination) == 0)
- {
- result.relativeDestination = GOKZ_TELEPORT_TRIGGER_DEFAULT_RELATIVE_DESTINATION;
- }
-
- // NOTE: Clamping
- if (IsBhopTrigger(result.type))
- {
- result.delay = FloatMax(result.delay, GOKZ_TELEPORT_TRIGGER_BHOP_MIN_DELAY);
- }
- else
- {
- result.delay = FloatMax(result.delay, 0.0);
- }
-
- return true;
-}
-
-static void TimerButtonTriggerCheck(char[] touchOutput, int size, StringMap entity, StringMap timerButtonTriggers)
-{
- int course = 0;
- char startOutput[128];
- char endOutput[128];
- FormatEx(startOutput, sizeof(startOutput), "%s%s%s", GOKZ_START_BUTTON_NAME, CHAR_ESCAPE, "Press");
- FormatEx(endOutput, sizeof(endOutput), "%s%s%s", GOKZ_END_BUTTON_NAME, CHAR_ESCAPE, "Press");
- if (StrContains(touchOutput, startOutput, false) != -1)
- {
- TimerButtonTrigger trigger;
- if (GetHammerIDFromEntityStringMap(trigger.hammerID, entity))
- {
- trigger.course = 0;
- trigger.isStartTimer = true;
- }
- char key[32];
- IntToString(trigger.hammerID, key, sizeof(key));
- timerButtonTriggers.SetArray(key, trigger, sizeof(trigger));
- }
- else if (StrContains(touchOutput, endOutput, false) != -1)
- {
- TimerButtonTrigger trigger;
- if (GetHammerIDFromEntityStringMap(trigger.hammerID, entity))
- {
- trigger.course = 0;
- trigger.isStartTimer = false;
- }
- char key[32];
- IntToString(trigger.hammerID, key, sizeof(key));
- timerButtonTriggers.SetArray(key, trigger, sizeof(trigger));
- }
- else if (RE_BonusStartButton.Match(touchOutput) > 0)
- {
- RE_BonusStartButton.GetSubString(1, touchOutput, sizeof(size));
- course = StringToInt(touchOutput);
- TimerButtonTrigger trigger;
- if (GetHammerIDFromEntityStringMap(trigger.hammerID, entity))
- {
- trigger.course = course;
- trigger.isStartTimer = true;
- }
- char key[32];
- IntToString(trigger.hammerID, key, sizeof(key));
- timerButtonTriggers.SetArray(key, trigger, sizeof(trigger));
- }
- else if (RE_BonusEndButton.Match(touchOutput) > 0)
- {
- RE_BonusEndButton.GetSubString(1, touchOutput, sizeof(size));
- course = StringToInt(touchOutput);
- TimerButtonTrigger trigger;
- if (GetHammerIDFromEntityStringMap(trigger.hammerID, entity))
- {
- trigger.course = course;
- trigger.isStartTimer = false;
- }
- char key[32];
- IntToString(trigger.hammerID, key, sizeof(key));
- timerButtonTriggers.SetArray(key, trigger, sizeof(trigger));
- }
-} \ No newline at end of file
diff --git a/sourcemod/scripting/gokz-core/map/prefix.sp b/sourcemod/scripting/gokz-core/map/prefix.sp
deleted file mode 100644
index 3ecbf89..0000000
--- a/sourcemod/scripting/gokz-core/map/prefix.sp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- Mapping API - Prefix
-
- Detects the map's prefix.
-*/
-
-
-
-static int currentMapPrefix;
-
-
-
-// =====[ PUBLIC ]=====
-
-int GetCurrentMapPrefix()
-{
- return currentMapPrefix;
-}
-
-
-
-// =====[ LISTENERS ]=====
-
-void OnMapStart_Prefix()
-{
- char map[PLATFORM_MAX_PATH], mapPrefix[PLATFORM_MAX_PATH];
- GetCurrentMapDisplayName(map, sizeof(map));
-
- // Get all characters before the first '_' character
- for (int i = 0; i < sizeof(mapPrefix); i++)
- {
- if (map[i] == '\0' || map[i] == '_')
- {
- break;
- }
-
- mapPrefix[i] = map[i];
- }
-
- if (StrEqual(mapPrefix[0], "kzpro", false))
- {
- currentMapPrefix = MapPrefix_KZPro;
- }
- else
- {
- currentMapPrefix = MapPrefix_Other;
- }
-} \ No newline at end of file
diff --git a/sourcemod/scripting/gokz-core/map/starts.sp b/sourcemod/scripting/gokz-core/map/starts.sp
deleted file mode 100644
index 94d5b33..0000000
--- a/sourcemod/scripting/gokz-core/map/starts.sp
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- Hooks between start destinations and GOKZ.
-*/
-
-
-
-static Regex RE_BonusStart;
-static bool startExists[GOKZ_MAX_COURSES];
-static float startOrigin[GOKZ_MAX_COURSES][3];
-static float startAngles[GOKZ_MAX_COURSES][3];
-
-// Used for SearchStart
-static Regex RE_BonusStartButton;
-static Regex RE_BonusStartZone;
-static CourseTimerType startType[GOKZ_MAX_COURSES];
-static float searchStartOrigin[GOKZ_MAX_COURSES][3];
-static float searchStartAngles[GOKZ_MAX_COURSES][3];
-
-// =====[ EVENTS ]=====
-
-void OnPluginStart_MapStarts()
-{
- RE_BonusStart = CompileRegex(GOKZ_BONUS_START_NAME_REGEX);
- RE_BonusStartButton = CompileRegex(GOKZ_BONUS_START_BUTTON_NAME_REGEX);
- RE_BonusStartZone = CompileRegex(GOKZ_BONUS_START_ZONE_NAME_REGEX);
-}
-
-void OnEntitySpawned_MapStarts(int entity)
-{
- char buffer[32];
-
- GetEntityClassname(entity, buffer, sizeof(buffer));
- if (!StrEqual("info_teleport_destination", buffer, false))
- {
- return;
- }
-
- if (GetEntityName(entity, buffer, sizeof(buffer)) == 0)
- {
- return;
- }
-
- if (StrEqual(GOKZ_START_NAME, buffer, false))
- {
- StoreStart(0, entity);
- }
- else
- {
- int course = GetStartBonusNumber(entity);
- if (GOKZ_IsValidCourse(course, true))
- {
- StoreStart(course, entity);
- }
- }
-}
-
-void OnEntitySpawnedPost_MapStarts(int entity)
-{
- char buffer[32];
- GetEntityClassname(entity, buffer, sizeof(buffer));
-
- if (StrEqual("trigger_multiple", buffer, false))
- {
- bool isStartZone;
- if (GetEntityName(entity, buffer, sizeof(buffer)) != 0)
- {
- if (StrEqual(GOKZ_START_ZONE_NAME, buffer, false))
- {
- isStartZone = true;
- StoreSearchStart(0, entity, CourseTimerType_ZoneNew);
- }
- else if (GetStartZoneBonusNumber(entity) != -1)
- {
- int course = GetStartZoneBonusNumber(entity);
- if (GOKZ_IsValidCourse(course, true))
- {
- isStartZone = true;
- StoreSearchStart(course, entity, CourseTimerType_ZoneNew);
- }
- }
- }
- if (!isStartZone)
- {
- TimerButtonTrigger trigger;
- if (IsTimerButtonTrigger(entity, trigger) && trigger.isStartTimer)
- {
- StoreSearchStart(trigger.course, entity, CourseTimerType_ZoneLegacy);
- }
- }
-
- }
- else if (StrEqual("func_button", buffer, false))
- {
- bool isStartButton;
- if (GetEntityName(entity, buffer, sizeof(buffer)) != 0)
- {
- if (StrEqual(GOKZ_START_BUTTON_NAME, buffer, false))
- {
- isStartButton = true;
- StoreSearchStart(0, entity, CourseTimerType_Button);
- }
- else
- {
- int course = GetStartButtonBonusNumber(entity);
- if (GOKZ_IsValidCourse(course, true))
- {
- isStartButton = true;
- StoreSearchStart(course, entity, CourseTimerType_Button);
- }
- }
- }
- if (!isStartButton)
- {
- TimerButtonTrigger trigger;
- if (IsTimerButtonTrigger(entity, trigger) && trigger.isStartTimer)
- {
- StoreSearchStart(trigger.course, entity, CourseTimerType_Button);
- }
- }
- }
-}
-
-void OnMapStart_MapStarts()
-{
- for (int course = 0; course < GOKZ_MAX_COURSES; course++)
- {
- startExists[course] = false;
- startType[course] = CourseTimerType_None;
- }
-}
-
-bool GetMapStartPosition(int course, float origin[3], float angles[3])
-{
- if (!startExists[course])
- {
- return false;
- }
-
- origin = startOrigin[course];
- angles = startAngles[course];
-
- return true;
-}
-
-bool GetSearchStartPosition(int course, float origin[3], float angles[3])
-{
- if (startType[course] == CourseTimerType_None)
- {
- return false;
- }
-
- origin = searchStartOrigin[course];
- angles = searchStartAngles[course];
-
- return true;
-}
-
-// =====[ PRIVATE ]=====
-
-static void StoreStart(int course, int entity)
-{
- float origin[3], angles[3];
- GetEntPropVector(entity, Prop_Send, "m_vecOrigin", origin);
- GetEntPropVector(entity, Prop_Data, "m_angRotation", angles);
- angles[2] = 0.0; // Roll should always be 0.0
-
- startExists[course] = true;
- startOrigin[course] = origin;
- startAngles[course] = angles;
-}
-
-static void StoreSearchStart(int course, int entity, CourseTimerType type)
-{
- // If StoreSearchStart is called, then there is at least an end position (even though it might not be a valid one)
- if (startType[course] < CourseTimerType_Default)
- {
- startType[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 (startType[course] >= type)
- {
- return;
- }
-
- float origin[3], distFromCenter[3];
- GetEntityPositions(entity, origin, searchStartOrigin[course], searchStartAngles[course], distFromCenter);
-
- // If it is a button or the center of the center of the zone is invalid
- if (type == CourseTimerType_Button || !IsSpawnValid(searchStartOrigin[course]))
- {
- // Attempt with various positions around the entity, pick the first valid one.
- if (!FindValidPositionAroundTimerEntity(entity, searchStartOrigin[course], searchStartAngles[course], type == CourseTimerType_Button))
- {
- searchStartOrigin[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.
- startType[course] = type;
-}
-
-
-static int GetStartBonusNumber(int entity)
-{
- return GOKZ_MatchIntFromEntityName(entity, RE_BonusStart, 1);
-}
-
-static int GetStartButtonBonusNumber(int entity)
-{
- return GOKZ_MatchIntFromEntityName(entity, RE_BonusStartButton, 1);
-}
-
-static int GetStartZoneBonusNumber(int entity)
-{
- return GOKZ_MatchIntFromEntityName(entity, RE_BonusStartZone, 1);
-} \ No newline at end of file
diff --git a/sourcemod/scripting/gokz-core/map/triggers.sp b/sourcemod/scripting/gokz-core/map/triggers.sp
deleted file mode 100644
index 2444493..0000000
--- a/sourcemod/scripting/gokz-core/map/triggers.sp
+++ /dev/null
@@ -1,855 +0,0 @@
-/*
- Mapping API - Triggers
-
- Implements trigger related features.
-*/
-
-
-
-static float lastTrigMultiTouchTime[MAXPLAYERS + 1];
-static float lastTrigTeleTouchTime[MAXPLAYERS + 1];
-static float lastTouchGroundOrLadderTime[MAXPLAYERS + 1];
-static int lastTouchSingleBhopEntRef[MAXPLAYERS + 1];
-static ArrayList lastTouchSequentialBhopEntRefs[MAXPLAYERS + 1];
-static int triggerTouchCount[MAXPLAYERS + 1];
-static int antiCpTriggerTouchCount[MAXPLAYERS + 1];
-static int antiPauseTriggerTouchCount[MAXPLAYERS + 1];
-static int antiJumpstatTriggerTouchCount[MAXPLAYERS + 1];
-static int mapMappingApiVersion = GOKZ_MAPPING_API_VERSION_NONE;
-static int bhopTouchCount[MAXPLAYERS + 1];
-static bool jumpedThisTick[MAXPLAYERS + 1];
-static float jumpOrigin[MAXPLAYERS + 1][3];
-static float jumpVelocity[MAXPLAYERS + 1][3];
-static ArrayList triggerTouchList[MAXPLAYERS + 1]; // arraylist of TouchedTrigger that the player is currently touching. this array won't ever get long (unless the mapper does something weird).
-static StringMap triggerTouchCounts[MAXPLAYERS + 1]; // stringmap of int touch counts with key being a string of the entity reference.
-static StringMap antiBhopTriggers; // stringmap of AntiBhopTrigger with key being a string of the m_iHammerID entprop.
-static StringMap teleportTriggers; // stringmap of TeleportTrigger with key being a string of the m_iHammerID entprop.
-static StringMap timerButtonTriggers; // stringmap of legacy timer zone triggers with key being a string of the m_iHammerID entprop.
-static ArrayList parseErrorStrings;
-
-
-
-// =====[ PUBLIC ]=====
-
-bool BhopTriggersJustTouched(int client)
-{
- // NOTE: This is slightly incorrect since we touch triggers in the air, but
- // it doesn't matter since we can't checkpoint in the air.
- if (bhopTouchCount[client] > 0)
- {
- return true;
- }
- // GetEngineTime return changes between calls. We only call it once at the beginning.
- float engineTime = GetEngineTime();
- // If the player touches a teleport trigger, increase the delay required
- if (engineTime - lastTouchGroundOrLadderTime[client] < GOKZ_MULT_NO_CHECKPOINT_TIME // Just touched ground or ladder
- && engineTime - lastTrigMultiTouchTime[client] < GOKZ_MULT_NO_CHECKPOINT_TIME // Just touched trigger_multiple
- || engineTime - lastTrigTeleTouchTime[client] < GOKZ_BHOP_NO_CHECKPOINT_TIME) // Just touched trigger_teleport
- {
- return true;
- }
-
- return Movement_GetMovetype(client) == MOVETYPE_LADDER
- && triggerTouchCount[client] > 0
- && engineTime - lastTrigTeleTouchTime[client] < GOKZ_LADDER_NO_CHECKPOINT_TIME;
-}
-
-bool AntiCpTriggerIsTouched(int client)
-{
- return antiCpTriggerTouchCount[client] > 0;
-}
-
-bool AntiPauseTriggerIsTouched(int client)
-{
- return antiPauseTriggerTouchCount[client] > 0;
-}
-
-void PushMappingApiError(char[] format, any ...)
-{
- char error[GOKZ_MAX_MAPTRIGGERS_ERROR_LENGTH];
- VFormat(error, sizeof(error), format, 2);
- parseErrorStrings.PushString(error);
-}
-
-TriggerType GetTriggerType(char[] targetName)
-{
- TriggerType result = TriggerType_Invalid;
-
- if (StrEqual(targetName, GOKZ_ANTI_BHOP_TRIGGER_NAME))
- {
- result = TriggerType_Antibhop;
- }
- else if (StrEqual(targetName, GOKZ_TELEPORT_TRIGGER_NAME))
- {
- result = TriggerType_Teleport;
- }
-
- return result;
-}
-
-bool IsBhopTrigger(TeleportType type)
-{
- return type == TeleportType_MultiBhop
- || type == TeleportType_SingleBhop
- || type == TeleportType_SequentialBhop;
-}
-
-bool IsTimerButtonTrigger(int entity, TimerButtonTrigger trigger)
-{
- char hammerID[32];
- bool gotHammerID = GetEntityHammerIDString(entity, hammerID, sizeof(hammerID));
- if (gotHammerID && timerButtonTriggers.GetArray(hammerID, trigger, sizeof(trigger)))
- {
- return true;
- }
- return false;
-}
-
-// =====[ EVENTS ]=====
-
-void OnPluginStart_MapTriggers()
-{
- parseErrorStrings = new ArrayList(ByteCountToCells(GOKZ_MAX_MAPTRIGGERS_ERROR_LENGTH));
- antiBhopTriggers = new StringMap();
- teleportTriggers = new StringMap();
- timerButtonTriggers = new StringMap();
-}
-
-void OnMapStart_MapTriggers()
-{
- parseErrorStrings.Clear();
- antiBhopTriggers.Clear();
- teleportTriggers.Clear();
- timerButtonTriggers.Clear();
- mapMappingApiVersion = GOKZ_MAPPING_API_VERSION_NONE;
- EntlumpParse(antiBhopTriggers, teleportTriggers, timerButtonTriggers, mapMappingApiVersion);
-
- if (mapMappingApiVersion > GOKZ_MAPPING_API_VERSION)
- {
- SetFailState("Map's mapping api version is too big! Maximum supported version is %i, but map has %i. If you're not on the latest GOKZ version, then update!",
- GOKZ_MAPPING_API_VERSION, mapMappingApiVersion);
- }
-}
-
-void OnClientPutInServer_MapTriggers(int client)
-{
- triggerTouchCount[client] = 0;
- antiCpTriggerTouchCount[client] = 0;
- antiPauseTriggerTouchCount[client] = 0;
- antiJumpstatTriggerTouchCount[client] = 0;
-
- if (triggerTouchList[client] == null)
- {
- triggerTouchList[client] = new ArrayList(sizeof(TouchedTrigger));
- }
- else
- {
- triggerTouchList[client].Clear();
- }
-
- if (triggerTouchCounts[client] == null)
- {
- triggerTouchCounts[client] = new StringMap();
- }
- else
- {
- triggerTouchCounts[client].Clear();
- }
-
- bhopTouchCount[client] = 0;
-
- if (lastTouchSequentialBhopEntRefs[client] == null)
- {
- lastTouchSequentialBhopEntRefs[client] = new ArrayList();
- }
- else
- {
- lastTouchSequentialBhopEntRefs[client].Clear();
- }
-}
-
-void OnPlayerRunCmd_MapTriggers(int client, int &buttons)
-{
- int flags = GetEntityFlags(client);
- MoveType moveType = GetEntityMoveType(client);
-
- // if the player isn't touching any bhop triggers on ground/a ladder, then
- // reset the singlebhop and sequential bhop state.
- if ((flags & FL_ONGROUND || moveType == MOVETYPE_LADDER)
- && bhopTouchCount[client] == 0)
- {
- ResetBhopState(client);
- }
-
- if (antiJumpstatTriggerTouchCount[client] > 0)
- {
- if (GetFeatureStatus(FeatureType_Native, "GOKZ_JS_InvalidateJump") == FeatureStatus_Available)
- {
- GOKZ_JS_InvalidateJump(client);
- }
- }
-
- // Check if we're touching any triggers and act accordingly.
- // NOTE: Read through the touch list in reverse order, so some
- // trigger behaviours will be better. Trust me!
- int triggerTouchListLength = triggerTouchList[client].Length;
- for (int i = triggerTouchListLength - 1; i >= 0; i--)
- {
- TouchedTrigger touched;
- triggerTouchList[client].GetArray(i, touched);
-
- if (touched.triggerType == TriggerType_Antibhop)
- {
- TouchAntibhopTrigger(client, touched, buttons, flags);
- }
- else if (touched.triggerType == TriggerType_Teleport)
- {
- // Sometimes due to lag or whatever, the player can be
- // teleported twice by the same trigger. This fixes that.
- if (TouchTeleportTrigger(client, touched, flags))
- {
- RemoveTriggerFromTouchList(client, EntRefToEntIndex(touched.entRef));
- i--;
- triggerTouchListLength--;
- }
- }
- }
- jumpedThisTick[client] = false;
-}
-
-void OnPlayerSpawn_MapTriggers(int client)
-{
- // Print trigger errors every time a player spawns so that
- // mappers and testers can very easily spot mistakes in names
- // and get them fixed asap.
- if (parseErrorStrings.Length > 0)
- {
- char errStart[] = "ERROR: Errors detected when trying to load triggers!";
- CPrintToChat(client, "{red}%s", errStart);
- PrintToConsole(client, "\n%s", errStart);
-
- int length = parseErrorStrings.Length;
- for (int err = 0; err < length; err++)
- {
- char error[GOKZ_MAX_MAPTRIGGERS_ERROR_LENGTH];
- parseErrorStrings.GetString(err, error, sizeof(error));
- CPrintToChat(client, "{red}%s", error);
- PrintToConsole(client, error);
- }
- CPrintToChat(client, "{red}If the errors get clipped off in the chat, then look in your developer console!\n");
- }
-}
-
-public void OnPlayerJump_Triggers(int client)
-{
- jumpedThisTick[client] = true;
- GetClientAbsOrigin(client, jumpOrigin[client]);
- Movement_GetVelocity(client, jumpVelocity[client]);
-}
-
-void OnEntitySpawned_MapTriggers(int entity)
-{
- char classname[32];
- GetEntityClassname(entity, classname, sizeof(classname));
- char name[64];
- GetEntityName(entity, name, sizeof(name));
-
- bool triggerMultiple = StrEqual("trigger_multiple", classname);
- if (triggerMultiple)
- {
- char hammerID[32];
- bool gotHammerID = GetEntityHammerIDString(entity, hammerID, sizeof(hammerID));
-
- if (StrEqual(GOKZ_TELEPORT_TRIGGER_NAME, name))
- {
- TeleportTrigger teleportTrigger;
- if (gotHammerID && teleportTriggers.GetArray(hammerID, teleportTrigger, sizeof(teleportTrigger)))
- {
- HookSingleEntityOutput(entity, "OnStartTouch", OnTeleportTrigTouchStart_MapTriggers);
- HookSingleEntityOutput(entity, "OnEndTouch", OnTeleportTrigTouchEnd_MapTriggers);
- }
- else
- {
- PushMappingApiError("ERROR: Couldn't match teleport trigger's Hammer ID %s with any Hammer ID from the map.", hammerID);
- }
- }
- else if (StrEqual(GOKZ_ANTI_BHOP_TRIGGER_NAME, name))
- {
- AntiBhopTrigger antiBhopTrigger;
- if (gotHammerID && antiBhopTriggers.GetArray(hammerID, antiBhopTrigger, sizeof(antiBhopTrigger)))
- {
- HookSingleEntityOutput(entity, "OnStartTouch", OnAntiBhopTrigTouchStart_MapTriggers);
- HookSingleEntityOutput(entity, "OnEndTouch", OnAntiBhopTrigTouchEnd_MapTriggers);
- }
- else
- {
- PushMappingApiError("ERROR: Couldn't match antibhop trigger's Hammer ID %s with any Hammer ID from the map.", hammerID);
- }
- }
- else if (StrEqual(GOKZ_BHOP_RESET_TRIGGER_NAME, name))
- {
- HookSingleEntityOutput(entity, "OnStartTouch", OnBhopResetTouchStart_MapTriggers);
- }
- else if (StrEqual(GOKZ_ANTI_CP_TRIGGER_NAME, name, false))
- {
- HookSingleEntityOutput(entity, "OnStartTouch", OnAntiCpTrigTouchStart_MapTriggers);
- HookSingleEntityOutput(entity, "OnEndTouch", OnAntiCpTrigTouchEnd_MapTriggers);
- }
- else if (StrEqual(GOKZ_ANTI_PAUSE_TRIGGER_NAME, name, false))
- {
- HookSingleEntityOutput(entity, "OnStartTouch", OnAntiPauseTrigTouchStart_MapTriggers);
- HookSingleEntityOutput(entity, "OnEndTouch", OnAntiPauseTrigTouchEnd_MapTriggers);
- }
- else if (StrEqual(GOKZ_ANTI_JUMPSTAT_TRIGGER_NAME, name, false))
- {
- HookSingleEntityOutput(entity, "OnStartTouch", OnAntiJumpstatTrigTouchStart_MapTriggers);
- HookSingleEntityOutput(entity, "OnEndTouch", OnAntiJumpstatTrigTouchEnd_MapTriggers);
- }
- else
- {
- // NOTE: SDKHook touch hooks bypass trigger filters. We want that only with
- // non mapping api triggers because it prevents checkpointing on bhop blocks.
- SDKHook(entity, SDKHook_StartTouchPost, OnTrigMultTouchStart_MapTriggers);
- SDKHook(entity, SDKHook_EndTouchPost, OnTrigMultTouchEnd_MapTriggers);
- }
- }
- else if (StrEqual("trigger_teleport", classname))
- {
- SDKHook(entity, SDKHook_StartTouchPost, OnTrigTeleTouchStart_MapTriggers);
- SDKHook(entity, SDKHook_EndTouchPost, OnTrigTeleTouchEnd_MapTriggers);
- }
-}
-
-public void OnAntiBhopTrigTouchStart_MapTriggers(const char[] output, int entity, int other, float delay)
-{
- if (!IsValidClient(other))
- {
- return;
- }
-
- int touchCount = IncrementTriggerTouchCount(other, entity);
- if (touchCount <= 0)
- {
- // The trigger has fired a matching endtouch output before
- // the starttouch output, so ignore it.
- return;
- }
-
- if (jumpedThisTick[other])
- {
- TeleportEntity(other, jumpOrigin[other], NULL_VECTOR, jumpVelocity[other]);
- }
-
- AddTriggerToTouchList(other, entity, TriggerType_Antibhop);
-}
-
-public void OnAntiBhopTrigTouchEnd_MapTriggers(const char[] output, int entity, int other, float delay)
-{
- if (!IsValidClient(other))
- {
- return;
- }
-
- DecrementTriggerTouchCount(other, entity);
- RemoveTriggerFromTouchList(other, entity);
-}
-
-public void OnTeleportTrigTouchStart_MapTriggers(const char[] output, int entity, int other, float delay)
-{
- if (!IsValidClient(other))
- {
- return;
- }
-
- int touchCount = IncrementTriggerTouchCount(other, entity);
- if (touchCount <= 0)
- {
- // The trigger has fired a matching endtouch output before
- // the starttouch output, so ignore it.
- return;
- }
-
- char key[32];
- GetEntityHammerIDString(entity, key, sizeof(key));
- TeleportTrigger trigger;
- if (teleportTriggers.GetArray(key, trigger, sizeof(trigger))
- && IsBhopTrigger(trigger.type))
- {
- bhopTouchCount[other]++;
- }
-
- AddTriggerToTouchList(other, entity, TriggerType_Teleport);
-}
-
-public void OnTeleportTrigTouchEnd_MapTriggers(const char[] output, int entity, int other, float delay)
-{
- if (!IsValidClient(other))
- {
- return;
- }
-
- DecrementTriggerTouchCount(other, entity);
-
- char key[32];
- GetEntityHammerIDString(entity, key, sizeof(key));
- TeleportTrigger trigger;
- if (teleportTriggers.GetArray(key, trigger, sizeof(trigger))
- && IsBhopTrigger(trigger.type))
- {
- bhopTouchCount[other]--;
- }
-
- RemoveTriggerFromTouchList(other, entity);
-}
-
-public void OnBhopResetTouchStart_MapTriggers(const char[] output, int entity, int other, float delay)
-{
- if (!IsValidClient(other))
- {
- return;
- }
-
- ResetBhopState(other);
-}
-
-public void OnAntiCpTrigTouchStart_MapTriggers(const char[] output, int entity, int other, float delay)
-{
- if (!IsValidClient(other))
- {
- return;
- }
-
- antiCpTriggerTouchCount[other]++;
-}
-
-public void OnAntiCpTrigTouchEnd_MapTriggers(const char[] output, int entity, int other, float delay)
-{
- if (!IsValidClient(other))
- {
- return;
- }
-
- antiCpTriggerTouchCount[other]--;
-}
-
-public void OnAntiPauseTrigTouchStart_MapTriggers(const char[] output, int entity, int other, float delay)
-{
- if (!IsValidClient(other))
- {
- return;
- }
-
- antiPauseTriggerTouchCount[other]++;
-}
-
-public void OnAntiPauseTrigTouchEnd_MapTriggers(const char[] output, int entity, int other, float delay)
-{
- if (!IsValidClient(other))
- {
- return;
- }
-
- antiPauseTriggerTouchCount[other]--;
-}
-
-public void OnAntiJumpstatTrigTouchStart_MapTriggers(const char[] output, int entity, int other, float delay)
-{
- if (!IsValidClient(other))
- {
- return;
- }
-
- antiJumpstatTriggerTouchCount[other]++;
-}
-
-public void OnAntiJumpstatTrigTouchEnd_MapTriggers(const char[] output, int entity, int other, float delay)
-{
- if (!IsValidClient(other))
- {
- return;
- }
-
- antiJumpstatTriggerTouchCount[other]--;
-}
-
-public void OnTrigMultTouchStart_MapTriggers(int entity, int other)
-{
- if (!IsValidClient(other))
- {
- return;
- }
-
- lastTrigMultiTouchTime[other] = GetEngineTime();
- triggerTouchCount[other]++;
-}
-
-public void OnTrigMultTouchEnd_MapTriggers(int entity, int other)
-{
- if (!IsValidClient(other))
- {
- return;
- }
-
- triggerTouchCount[other]--;
-}
-
-public void OnTrigTeleTouchStart_MapTriggers(int entity, int other)
-{
- if (!IsValidClient(other))
- {
- return;
- }
-
- lastTrigTeleTouchTime[other] = GetEngineTime();
- triggerTouchCount[other]++;
-}
-
-public void OnTrigTeleTouchEnd_MapTriggers(int entity, int other)
-{
- if (!IsValidClient(other))
- {
- return;
- }
-
- triggerTouchCount[other]--;
-}
-
-void OnStartTouchGround_MapTriggers(int client)
-{
- lastTouchGroundOrLadderTime[client] = GetEngineTime();
-
- for (int i = 0; i < triggerTouchList[client].Length; i++)
- {
- TouchedTrigger touched;
- triggerTouchList[client].GetArray(i, touched);
- // set the touched tick to the tick that the player touches the ground.
- touched.groundTouchTick = gI_TickCount[client];
- triggerTouchList[client].SetArray(i, touched);
- }
-}
-
-void OnStopTouchGround_MapTriggers(int client)
-{
- for (int i = 0; i < triggerTouchList[client].Length; i++)
- {
- TouchedTrigger touched;
- triggerTouchList[client].GetArray(i, touched);
-
- if (touched.triggerType == TriggerType_Teleport)
- {
- char key[32];
- GetEntityHammerIDString(touched.entRef, key, sizeof(key));
- TeleportTrigger trigger;
- // set last touched triggers for single and sequential bhop.
- if (teleportTriggers.GetArray(key, trigger, sizeof(trigger))
- && IsBhopTrigger(trigger.type))
- {
- if (trigger.type == TeleportType_SequentialBhop)
- {
- lastTouchSequentialBhopEntRefs[client].Push(touched.entRef);
- }
- // NOTE: For singlebhops, we don't care which type of bhop we last touched, because
- // otherwise jumping back and forth between a multibhop and a singlebhop wouldn't work.
- if (i == 0 && IsBhopTrigger(trigger.type))
- {
- // We only want to set this once in this loop.
- lastTouchSingleBhopEntRef[client] = touched.entRef;
- }
- }
- }
- }
-}
-
-void OnChangeMovetype_MapTriggers(int client, MoveType newMovetype)
-{
- if (newMovetype == MOVETYPE_LADDER)
- {
- lastTouchGroundOrLadderTime[client] = GetEngineTime();
- }
-}
-
-
-
-// =====[ PRIVATE ]=====
-
-static void AddTriggerToTouchList(int client, int trigger, TriggerType triggerType)
-{
- int triggerEntRef = EntIndexToEntRef(trigger);
-
- TouchedTrigger touched;
- touched.triggerType = triggerType;
- touched.entRef = triggerEntRef;
- touched.startTouchTick = gI_TickCount[client];
- touched.groundTouchTick = -1;
- if (GetEntityFlags(client) & FL_ONGROUND)
- {
- touched.groundTouchTick = gI_TickCount[client];
- }
-
- triggerTouchList[client].PushArray(touched);
-}
-
-static void RemoveTriggerFromTouchList(int client, int trigger)
-{
- int triggerEntRef = EntIndexToEntRef(trigger);
- for (int i = 0; i < triggerTouchList[client].Length; i++)
- {
- TouchedTrigger touched;
- triggerTouchList[client].GetArray(i, touched);
- if (touched.entRef == triggerEntRef)
- {
- triggerTouchList[client].Erase(i);
- break;
- }
- }
-}
-
-static int IncrementTriggerTouchCount(int client, int trigger)
-{
- int entref = EntIndexToEntRef(trigger);
- char szEntref[64];
- FormatEx(szEntref, sizeof(szEntref), "%i", entref);
-
- int value = 0;
- triggerTouchCounts[client].GetValue(szEntref, value);
-
- value += 1;
- triggerTouchCounts[client].SetValue(szEntref, value);
-
- return value;
-}
-
-static void DecrementTriggerTouchCount(int client, int trigger)
-{
- int entref = EntIndexToEntRef(trigger);
- char szEntref[64];
- FormatEx(szEntref, sizeof(szEntref), "%i", entref);
-
- int value = 0;
- triggerTouchCounts[client].GetValue(szEntref, value);
-
- value -= 1;
- triggerTouchCounts[client].SetValue(szEntref, value);
-}
-
-static void TouchAntibhopTrigger(int client, TouchedTrigger touched, int &newButtons, int flags)
-{
- if (!(flags & FL_ONGROUND))
- {
- // Disable jump when the player is in the air.
- // This is a very simple way to fix jumpbugging antibhop triggers.
- newButtons &= ~IN_JUMP;
- return;
- }
-
- if (touched.groundTouchTick == -1)
- {
- // The player hasn't touched the ground inside this trigger yet.
- return;
- }
-
- char key[32];
- GetEntityHammerIDString(touched.entRef, key, sizeof(key));
- AntiBhopTrigger trigger;
- if (antiBhopTriggers.GetArray(key, trigger, sizeof(trigger)))
- {
- float touchTime = CalculateGroundTouchTime(client, touched);
- if (trigger.time == 0.0 || touchTime <= trigger.time)
- {
- // disable jump
- newButtons &= ~IN_JUMP;
- }
- }
-}
-
-static bool TouchTeleportTrigger(int client, TouchedTrigger touched, int flags)
-{
- bool shouldTeleport = false;
-
- char key[32];
- GetEntityHammerIDString(touched.entRef, key, sizeof(key));
- TeleportTrigger trigger;
- if (!teleportTriggers.GetArray(key, trigger, sizeof(trigger)))
- {
- // Couldn't get the teleport trigger from the trigger array for some reason.
- return shouldTeleport;
- }
-
- bool isBhopTrigger = IsBhopTrigger(trigger.type);
- // NOTE: Player hasn't touched the ground inside this trigger yet.
- if (touched.groundTouchTick == -1 && isBhopTrigger)
- {
- return shouldTeleport;
- }
-
- float destOrigin[3];
- float destAngles[3];
- bool gotDestOrigin;
- bool gotDestAngles;
- int destinationEnt = GetTeleportDestinationAndOrientation(trigger.tpDestination, destOrigin, destAngles, gotDestOrigin, gotDestAngles);
-
- float triggerOrigin[3];
- bool gotTriggerOrigin = GetEntityAbsOrigin(touched.entRef, triggerOrigin);
-
- // NOTE: We only use the trigger's origin if we're using a relative destination, so if
- // we're not using a relative destination and don't have it, then it's fine.
- if (!IsValidEntity(destinationEnt) || !gotDestOrigin
- || (!gotTriggerOrigin && trigger.relativeDestination))
- {
- PrintToConsole(client, "[KZ] Invalid teleport destination \"%s\" on trigger with hammerID %i.", trigger.tpDestination, trigger.hammerID);
- return shouldTeleport;
- }
-
- // NOTE: Find out if we should actually teleport.
- if (isBhopTrigger && (flags & FL_ONGROUND))
- {
- float touchTime = CalculateGroundTouchTime(client, touched);
- if (touchTime > trigger.delay)
- {
- shouldTeleport = true;
- }
- else if (trigger.type == TeleportType_SingleBhop)
- {
- shouldTeleport = lastTouchSingleBhopEntRef[client] == touched.entRef;
- }
- else if (trigger.type == TeleportType_SequentialBhop)
- {
- int length = lastTouchSequentialBhopEntRefs[client].Length;
- for (int j = 0; j < length; j++)
- {
- int entRef = lastTouchSequentialBhopEntRefs[client].Get(j);
- if (entRef == touched.entRef)
- {
- shouldTeleport = true;
- break;
- }
- }
- }
- }
- else if (trigger.type == TeleportType_Normal)
- {
- float touchTime = CalculateStartTouchTime(client, touched);
- shouldTeleport = touchTime > trigger.delay || (trigger.delay == 0.0);
- }
-
- if (!shouldTeleport)
- {
- return shouldTeleport;
- }
-
- bool shouldReorientPlayer = trigger.reorientPlayer
- && gotDestAngles && (destAngles[1] != 0.0);
-
- float zAxis[3];
- zAxis = view_as<float>({0.0, 0.0, 1.0});
-
- // NOTE: Work out finalOrigin.
- float finalOrigin[3];
- if (trigger.relativeDestination)
- {
- float playerOrigin[3];
- Movement_GetOrigin(client, playerOrigin);
-
- float playerOffsetFromTrigger[3];
- SubtractVectors(playerOrigin, triggerOrigin, playerOffsetFromTrigger);
-
- if (shouldReorientPlayer)
- {
- // NOTE: rotate player offset by the destination trigger's yaw.
- RotateVectorAxis(playerOffsetFromTrigger, zAxis, DegToRad(destAngles[1]), playerOffsetFromTrigger);
- }
-
- AddVectors(destOrigin, playerOffsetFromTrigger, finalOrigin);
- }
- else
- {
- finalOrigin = destOrigin;
- }
-
- // NOTE: Work out finalPlayerAngles.
- float finalPlayerAngles[3];
- Movement_GetEyeAngles(client, finalPlayerAngles);
- if (shouldReorientPlayer)
- {
- finalPlayerAngles[1] -= destAngles[1];
-
- float velocity[3];
- Movement_GetVelocity(client, velocity);
-
- // NOTE: rotate velocity by the destination trigger's yaw.
- RotateVectorAxis(velocity, zAxis, DegToRad(destAngles[1]), velocity);
- Movement_SetVelocity(client, velocity);
- }
- else if (!trigger.reorientPlayer && trigger.useDestAngles)
- {
- finalPlayerAngles = destAngles;
- }
-
- if (shouldTeleport)
- {
- TeleportPlayer(client, finalOrigin, finalPlayerAngles, gotDestAngles && trigger.useDestAngles, trigger.resetSpeed);
- }
-
- return shouldTeleport;
-}
-
-static float CalculateGroundTouchTime(int client, TouchedTrigger touched)
-{
- float result = float(gI_TickCount[client] - touched.groundTouchTick) * GetTickInterval();
- return result;
-}
-
-static float CalculateStartTouchTime(int client, TouchedTrigger touched)
-{
- float result = float(gI_TickCount[client] - touched.startTouchTick) * GetTickInterval();
- return result;
-}
-
-static void ResetBhopState(int client)
-{
- lastTouchSingleBhopEntRef[client] = INVALID_ENT_REFERENCE;
- lastTouchSequentialBhopEntRefs[client].Clear();
-}
-
-static bool GetEntityHammerIDString(int entity, char[] buffer, int maxLength)
-{
- if (!IsValidEntity(entity))
- {
- return false;
- }
-
- if (!HasEntProp(entity, Prop_Data, "m_iHammerID"))
- {
- return false;
- }
-
- int hammerID = GetEntProp(entity, Prop_Data, "m_iHammerID");
- IntToString(hammerID, buffer, maxLength);
-
- return true;
-}
-
-// NOTE: returns an entity reference (possibly invalid).
-static int GetTeleportDestinationAndOrientation(char[] targetName, float origin[3], float angles[3] = NULL_VECTOR, bool &gotOrigin = false, bool &gotAngles = false)
-{
- // NOTE: We're not caching the teleport destination because it could change.
- int destination = GOKZFindEntityByName(targetName, .ignorePlayers = true);
- if (!IsValidEntity(destination))
- {
- return destination;
- }
-
- gotOrigin = GetEntityAbsOrigin(destination, origin);
-
- if (HasEntProp(destination, Prop_Data, "m_angAbsRotation"))
- {
- GetEntPropVector(destination, Prop_Data, "m_angAbsRotation", angles);
- gotAngles = true;
- }
- else
- {
- gotAngles = false;
- }
-
- return destination;
-} \ No newline at end of file
diff --git a/sourcemod/scripting/gokz-core/map/zones.sp b/sourcemod/scripting/gokz-core/map/zones.sp
deleted file mode 100644
index 684e42d..0000000
--- a/sourcemod/scripting/gokz-core/map/zones.sp
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- Hooks between specifically named trigger_multiples and GOKZ.
-*/
-
-
-
-static Regex RE_BonusStartZone;
-static Regex RE_BonusEndZone;
-static bool touchedGroundSinceTouchingStartZone[MAXPLAYERS + 1];
-
-
-
-// =====[ EVENTS ]=====
-
-void OnPluginStart_MapZones()
-{
- RE_BonusStartZone = CompileRegex(GOKZ_BONUS_START_ZONE_NAME_REGEX);
- RE_BonusEndZone = CompileRegex(GOKZ_BONUS_END_ZONE_NAME_REGEX);
-}
-
-void OnStartTouchGround_MapZones(int client)
-{
- touchedGroundSinceTouchingStartZone[client] = true;
-}
-
-void OnEntitySpawned_MapZones(int entity)
-{
- char buffer[32];
-
- GetEntityClassname(entity, buffer, sizeof(buffer));
- if (!StrEqual("trigger_multiple", buffer, false))
- {
- return;
- }
-
- if (GetEntityName(entity, buffer, sizeof(buffer)) == 0)
- {
- return;
- }
-
- int course = 0;
- if (StrEqual(GOKZ_START_ZONE_NAME, buffer, false))
- {
- HookSingleEntityOutput(entity, "OnStartTouch", OnStartZoneStartTouch);
- HookSingleEntityOutput(entity, "OnEndTouch", OnStartZoneEndTouch);
- RegisterCourseStart(course);
- }
- else if (StrEqual(GOKZ_END_ZONE_NAME, buffer, false))
- {
- HookSingleEntityOutput(entity, "OnStartTouch", OnEndZoneStartTouch);
- RegisterCourseEnd(course);
- }
- else if ((course = GetStartZoneBonusNumber(entity)) != -1)
- {
- HookSingleEntityOutput(entity, "OnStartTouch", OnBonusStartZoneStartTouch);
- HookSingleEntityOutput(entity, "OnEndTouch", OnBonusStartZoneEndTouch);
- RegisterCourseStart(course);
- }
- else if ((course = GetEndZoneBonusNumber(entity)) != -1)
- {
- HookSingleEntityOutput(entity, "OnStartTouch", OnBonusEndZoneStartTouch);
- RegisterCourseEnd(course);
- }
-}
-
-public void OnStartZoneStartTouch(const char[] name, int caller, int activator, float delay)
-{
- if (!IsValidEntity(caller) || !IsValidClient(activator))
- {
- return;
- }
-
- ProcessStartZoneStartTouch(activator, 0);
-}
-
-public void OnStartZoneEndTouch(const char[] name, int caller, int activator, float delay)
-{
- if (!IsValidEntity(caller) || !IsValidClient(activator))
- {
- return;
- }
-
- ProcessStartZoneEndTouch(activator, 0);
-}
-
-public void OnEndZoneStartTouch(const char[] name, int caller, int activator, float delay)
-{
- if (!IsValidEntity(caller) || !IsValidClient(activator))
- {
- return;
- }
-
- ProcessEndZoneStartTouch(activator, 0);
-}
-
-public void OnBonusStartZoneStartTouch(const char[] name, int caller, int activator, float delay)
-{
- if (!IsValidEntity(caller) || !IsValidClient(activator))
- {
- return;
- }
-
- int course = GetStartZoneBonusNumber(caller);
- if (!GOKZ_IsValidCourse(course, true))
- {
- return;
- }
-
- ProcessStartZoneStartTouch(activator, course);
-}
-
-public void OnBonusStartZoneEndTouch(const char[] name, int caller, int activator, float delay)
-{
- if (!IsValidEntity(caller) || !IsValidClient(activator))
- {
- return;
- }
-
- int course = GetStartZoneBonusNumber(caller);
- if (!GOKZ_IsValidCourse(course, true))
- {
- return;
- }
-
- ProcessStartZoneEndTouch(activator, course);
-}
-
-public void OnBonusEndZoneStartTouch(const char[] name, int caller, int activator, float delay)
-{
- if (!IsValidEntity(caller) || !IsValidClient(activator))
- {
- return;
- }
-
- int course = GetEndZoneBonusNumber(caller);
- if (!GOKZ_IsValidCourse(course, true))
- {
- return;
- }
-
- ProcessEndZoneStartTouch(activator, course);
-}
-
-
-
-// =====[ PRIVATE ]=====
-
-static void ProcessStartZoneStartTouch(int client, int course)
-{
- touchedGroundSinceTouchingStartZone[client] = Movement_GetOnGround(client);
-
- GOKZ_StopTimer(client, false);
- SetCurrentCourse(client, course);
-
- OnStartZoneStartTouch_Teleports(client, course);
-}
-
-static void ProcessStartZoneEndTouch(int client, int course)
-{
- if (!touchedGroundSinceTouchingStartZone[client])
- {
- return;
- }
-
- GOKZ_StartTimer(client, course, true);
- GOKZ_ResetVirtualButtonPosition(client, true);
-}
-
-static void ProcessEndZoneStartTouch(int client, int course)
-{
- GOKZ_EndTimer(client, course);
- GOKZ_ResetVirtualButtonPosition(client, false);
-}
-
-static int GetStartZoneBonusNumber(int entity)
-{
- return GOKZ_MatchIntFromEntityName(entity, RE_BonusStartZone, 1);
-}
-
-static int GetEndZoneBonusNumber(int entity)
-{
- return GOKZ_MatchIntFromEntityName(entity, RE_BonusEndZone, 1);
-} \ No newline at end of file