diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index 9bf2e148..dc6f0516 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -981,6 +981,20 @@ native int Shavit_ReloadReplays(bool restart); */ native void Shavit_StopChatSound(); +/** + * Marks a map as a KZ map. + * + * @noreturn + */ +native void Shavit_MarkKZMap(); + +/** + * Lets us know if the map was marked as a KZ map. + * + * @return Boolean value. + */ +native bool Shavit_IsKZMap(); + /** * Gets the map tier for a specified map. * Use the map's display name. @@ -1079,15 +1093,17 @@ public void __pl_shavit_SetNTVOptional() MarkNativeAsOptional("Shavit_GetWRTime"); MarkNativeAsOptional("Shavit_InsideZone"); MarkNativeAsOptional("Shavit_IsClientCreatingZone"); + MarkNativeAsOptional("Shavit_IsKZMap"); MarkNativeAsOptional("Shavit_IsPracticeMode"); MarkNativeAsOptional("Shavit_IsReplayDataLoaded"); MarkNativeAsOptional("Shavit_LoadSnapshot"); + MarkNativeAsOptional("Shavit_MarkKZMap"); MarkNativeAsOptional("Shavit_OpenStatsMenu"); MarkNativeAsOptional("Shavit_PauseTimer"); MarkNativeAsOptional("Shavit_PrintToChat"); - MarkNativeAsOptional("Shavit_RestartTimer"); MarkNativeAsOptional("Shavit_ReloadReplay"); MarkNativeAsOptional("Shavit_ReloadReplays"); + MarkNativeAsOptional("Shavit_RestartTimer"); MarkNativeAsOptional("Shavit_ResumeTimer"); MarkNativeAsOptional("Shavit_SaveSnapshot"); MarkNativeAsOptional("Shavit_SetPracticeMode"); diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 011cde61..56985b4d 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -133,6 +133,9 @@ char gS_ChatStrings[CHATSETTINGS_SIZE][128]; // misc cache bool gB_StopChatSound = false; +// kz support +bool gB_KZMap = false; + public Plugin myinfo = { name = "[shavit] Core", @@ -160,8 +163,10 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max CreateNative("Shavit_GetSync", Native_GetSync); CreateNative("Shavit_GetTimer", Native_GetTimer); CreateNative("Shavit_GetTimerStatus", Native_GetTimerStatus); + CreateNative("Shavit_IsKZMap", Native_IsKZMap); CreateNative("Shavit_IsPracticeMode", Native_IsPracticeMode); CreateNative("Shavit_LoadSnapshot", Native_LoadSnapshot); + CreateNative("Shavit_MarkKZMap", Native_MarkKZMap); CreateNative("Shavit_PauseTimer", Native_PauseTimer); CreateNative("Shavit_PrintToChat", Native_PrintToChat); CreateNative("Shavit_RestartTimer", Native_RestartTimer); @@ -417,6 +422,11 @@ public void OnMapStart() } } +public void OnMapEnd() +{ + gB_KZMap = false; +} + public Action Command_StartTimer(int client, int args) { if(!IsValidClient(client)) @@ -437,14 +447,17 @@ public Action Command_StartTimer(int client, int args) return Plugin_Handled; } - if(gB_AllowTimerWithoutZone || (gB_Zones && Shavit_ZoneExists(Zone_Start, Track_Main))) + if(gB_AllowTimerWithoutZone || (gB_Zones && (Shavit_ZoneExists(Zone_Start, Track_Main) || gB_KZMap))) { Call_StartForward(gH_Forwards_OnRestart); Call_PushCell(client); Call_PushCell(Track_Main); Call_Finish(); - StartTimer(client, Track_Main); + if(gB_AllowTimerWithoutZone) + { + StartTimer(client, Track_Main); + } } else @@ -475,14 +488,17 @@ public Action Command_StartTimer_Bonus(int client, int args) return Plugin_Handled; } - if(gB_AllowTimerWithoutZone || (gB_Zones && Shavit_ZoneExists(Zone_Start, Track_Bonus))) + if(gB_AllowTimerWithoutZone || (gB_Zones && (Shavit_ZoneExists(Zone_Start, Track_Bonus) || gB_KZMap))) { Call_StartForward(gH_Forwards_OnRestart); Call_PushCell(client); Call_PushCell(Track_Bonus); Call_Finish(); - StartTimer(client, Track_Bonus); + if(gB_AllowTimerWithoutZone) + { + StartTimer(client, Track_Bonus); + } } else @@ -943,6 +959,11 @@ public int Native_GetTimerStatus(Handle handler, int numParams) return GetTimerStatus(GetNativeCell(1)); } +public int Native_IsKZMap(Handle handler, int numParams) +{ + return view_as(gB_KZMap); +} + public int Native_StartTimer(Handle handler, int numParams) { StartTimer(GetNativeCell(1), GetNativeCell(2)); @@ -1171,6 +1192,11 @@ public int Native_LoadSnapshot(Handle handler, int numParams) gI_Track[client] = view_as(snapshot[iTimerTrack]); } +public int Native_MarkKZMap(Handle handler, int numParams) +{ + gB_KZMap = true; +} + int GetTimerStatus(int client) { if(!gB_TimerEnabled[client]) diff --git a/addons/sourcemod/scripting/shavit-zones.sp b/addons/sourcemod/scripting/shavit-zones.sp index 0a158118..8b0b5a36 100644 --- a/addons/sourcemod/scripting/shavit-zones.sp +++ b/addons/sourcemod/scripting/shavit-zones.sp @@ -76,7 +76,7 @@ int gI_GridSnap[MAXPLAYERS+1]; bool gB_SnapToWall[MAXPLAYERS+1]; bool gB_CursorTracing[MAXPLAYERS+1]; -// Cache. +// cache float gV_Point1[MAXPLAYERS+1][3]; float gV_Point2[MAXPLAYERS+1][3]; float gV_Teleport[MAXPLAYERS+1][3]; @@ -89,7 +89,7 @@ float gF_CustomSpawn[3]; int gI_ZoneTrack[MAXPLAYERS+1]; int gI_ZoneDatabaseID[MAXPLAYERS+1]; -// Zone cache. +// zone cache any gA_ZoneSettings[ZONETYPES_SIZE][TRACKS_SIZE][ZONESETTINGS_SIZE]; any gA_ZoneCache[MAX_ZONES][ZONECACHE_SIZE]; // Vectors will not be inside this array. int gI_MapZones = 0; @@ -107,7 +107,7 @@ int gI_HaloSprite = -1; // admin menu Handle gH_AdminMenu = INVALID_HANDLE; -// cache +// misc cache bool gB_Late = false; // cvars @@ -141,6 +141,10 @@ char gS_ChatStrings[CHATSETTINGS_SIZE][128]; Handle gH_Forwards_EnterZone = null; Handle gH_Forwards_LeaveZone = null; +// kz support +float gF_ClimbButtonCache[MAXPLAYERS+1][TRACKS_SIZE][2][3]; // 0 - location, 1 - angles +int gI_KZButtons[TRACKS_SIZE][2]; // 0 - start, 1 - end + public Plugin myinfo = { name = "[shavit] Map Zones", @@ -244,6 +248,14 @@ public void OnPluginStart() } } + for(int i = 1; i <= MaxClients; i++) + { + if(IsClientConnected(i) && IsClientInGame(i)) + { + OnClientPutInServer(i); + } + } + SQL_SetPrefix(); } @@ -533,6 +545,60 @@ public void OnMapEnd() delete gH_DrawEverything; } +public void OnEntityCreated(int entity, const char[] classname) +{ + if(!StrEqual(classname, "func_button", false)) + { + return; + } + + RequestFrame(Frame_HookButton, EntIndexToEntRef(entity)); +} + +public void Frame_HookButton(any data) +{ + int entity = EntRefToEntIndex(data); + + if(entity == INVALID_ENT_REFERENCE) + { + return; + } + + char[] sName = new char[32]; + GetEntPropString(entity, Prop_Data, "m_iName", sName, 32); + + if(StrContains(sName, "climb_") == -1) + { + return; + } + + int zone = -1; + int track = Track_Main; + + if(StrContains(sName, "startbutton") != -1) + { + zone = Zone_Start; + } + + else if(StrContains(sName, "endbutton") != -1) + { + zone = Zone_End; + } + + if(StrContains(sName, "bonus") != -1) + { + track = Track_Bonus; + } + + if(zone != -1) + { + gI_KZButtons[track][zone] = entity; + Shavit_MarkKZMap(); + + SDKHook(entity, SDKHook_UsePost, UsePost); + } +} + public void Shavit_OnChatConfigLoaded() { for(int i = 0; i < CHATSETTINGS_SIZE; i++) @@ -703,11 +769,17 @@ public void SQL_RefreshZones_Callback(Database db, DBResultSet results, const ch public void OnClientPutInServer(int client) { - for(int i = 0; i < ZONETYPES_SIZE; i++) + for(int i = 0; i < TRACKS_SIZE; i++) { - for(int j = 0; j < TRACKS_SIZE; j++) + for(int j = 0; j < ZONETYPES_SIZE; j++) { - gB_InsideZone[client][i][j] = false; + gB_InsideZone[client][j][i] = false; + } + + for(int j = 0; j < 3; j++) + { + gF_ClimbButtonCache[client][i][0][j] = 0.0; + gF_ClimbButtonCache[client][i][1][j] = 0.0; } } @@ -719,11 +791,6 @@ public void OnClientPutInServer(int client) Reset(client); } -public void OnClientDisconnect(int client) -{ - Reset(client); -} - public Action Command_Modifier(int client, int args) { if(!IsValidClient(client)) @@ -2138,13 +2205,18 @@ public void Shavit_OnRestart(int client, int track) { if(gB_TeleportToStart) { - Shavit_StartTimer(client, track); - if(track == Track_Main && !EmptyVector(gF_CustomSpawn)) { TeleportEntity(client, gF_CustomSpawn, NULL_VECTOR, view_as({0.0, 0.0, 0.0})); } + else if(Shavit_IsKZMap() && !EmptyVector(gF_ClimbButtonCache[client][track][0]) && !EmptyVector(gF_ClimbButtonCache[client][track][1])) + { + TeleportEntity(client, gF_ClimbButtonCache[client][track][0], gF_ClimbButtonCache[client][track][1], view_as({0.0, 0.0, 0.0})); + + return; + } + else { int index = GetZoneIndex(Zone_Start, track); @@ -2161,6 +2233,8 @@ public void Shavit_OnRestart(int client, int track) TeleportEntity(client, center, NULL_VECTOR, view_as({0.0, 0.0, 0.0})); } + + Shavit_StartTimer(client, track); } } @@ -2215,6 +2289,12 @@ public void Player_Spawn(Event event, const char[] name, bool dontBroadcast) public void Round_Start(Event event, const char[] name, bool dontBroadcast) { + for(int i = 0; i < TRACKS_SIZE; i++) + { + gI_KZButtons[i][0] = -1; + gI_KZButtons[i][1] = -1; + } + gB_ZonesCreated = false; RequestFrame(Frame_CreateZoneEntities); @@ -2432,3 +2512,41 @@ public void TouchPost(int entity, int other) } } } + +public void UsePost(int entity, int activator, int caller, UseType type, float value) +{ + if(activator < 1 || activator > MaxClients || IsFakeClient(activator) || GetEntPropEnt(activator, Prop_Send, "m_hGroundEntity") == -1) + { + return; + } + + int zone = -1; + int track = Track_Main; + + for(int i = 0; i < TRACKS_SIZE; i++) + { + for(int j = 0; j < 2; j++) + { + if(gI_KZButtons[i][j] == entity) + { + zone = j; + track = i; + + break; + } + } + } + + if(zone == Zone_Start) + { + GetClientAbsOrigin(activator, gF_ClimbButtonCache[activator][track][0]); + GetClientEyeAngles(activator, gF_ClimbButtonCache[activator][track][1]); + + Shavit_StartTimer(activator, track); + } + + if(zone == Zone_End) + { + Shavit_FinishMap(activator, track); + } +}