diff --git a/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt b/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt index 66d2d59..1d3682b 100644 --- a/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt +++ b/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt @@ -219,7 +219,7 @@ "Classes random assignment" { "#format" "{1:s}" - "en" "You have randomly been assigned to the @green\"{1}\" @defaultclass." + "en" "You have randomly been assigned to the @green\"{1}\"@default class." } // Center Text/HUD @@ -433,7 +433,7 @@ "Infect command infect successful" { "#format" "{1:s}" - "en" "Player @green{1} @defaulthas been successfully infected." + "en" "Successfully infected @green{1}@default." } "Infect command infect successful public" @@ -445,7 +445,7 @@ "Infect command infect mother successful" { "#format" "{1:s}" - "en" "Player @green{1} @defaulthas been successfully infected as the mother zombie." + "en" "Successfully infected @green{1}@default as the mother zombie." } "Infect command infect mother successful public" @@ -457,25 +457,25 @@ "Infect command infect unsuccessful" { "#format" "{1:s}" - "en" "Player @green{1} @defaultis already a zombie." + "en" "Could not infect @green{1}@default." } "Infect command human successful" { "#format" "{1:s}" - "en" "Player @green{1} @defaulthas been successfully brought back as a human." + "en" "Successfully brought back @green{1}@default to life." } "Infect command human successful public" { "#format" "{1:s},{2:s}" - "en" "@lgreen{1}@default has brought back @green{2}@default as a human." + "en" "@lgreen{1}@default has brought back @green{2}@default to life." } "Infect command human unsuccessful" { "#format" "{1:s}" - "en" "Player @green{1} @defaultis already a human." + "en" "Could not bring back @green{1}@default to life." } // =========================== @@ -550,67 +550,67 @@ "Restrict weapon" { "#format" "{1:s}" - "en" "Weapon @green\"{1}\" @defaulthas been restricted." + "en" "Weapon @green\"{1}\"@default has been restricted." } "Unrestrict weapon" { "#format" "{1:s}" - "en" "Weapon @green\"{1}\" @defaulthas been unrestricted." + "en" "Weapon @green\"{1}\"@default has been unrestricted." } "Restrict weapon stopped" { "#format" "{1:s}" - "en" "Weapon @green\"{1}\" @defaultis already restricted." + "en" "Weapon @green\"{1}\"@default is already restricted." } "Unrestrict weapon stopped" { "#format" "{1:s}" - "en" "Weapon @green\"{1}\" @default has no restrictions set." + "en" "Weapon @green\"{1}\"@default has no restrictions set." } "Restrict weapon type" { "#format" "{1:s}" - "en" "Weapons of type @green\"{1}\" @defaulthave been restricted." + "en" "Weapons of type @green\"{1}\"@default have been restricted." } "Unrestrict weapon type" { "#format" "{1:s}" - "en" "Weapons of type @green\"{1}\" @defaulthave been unrestricted." + "en" "Weapons of type @green\"{1}\"@default have been unrestricted." } "Restrict weapon type stopped" { "#format" "{1:s}" - "en" "Weapons of type @green\"{1}\" @defaultare all already restricted." + "en" "Weapons of type @green\"{1}\"@default are all already restricted." } "Unrestrict weapon type stopped" { "#format" "{1:s}" - "en" "Weapons of type @green\"{1}\" @defaulthave no restrictions set." + "en" "Weapons of type @green\"{1}\"@default have no restrictions set." } "Restrict weapon untoggleable" { "#format" "{1:s}" - "en" "Weapon @green\"{1}\" @defaultmay not have its restrictions toggled." + "en" "Weapon @green\"{1}\"@default may not have its restrictions toggled." } "Weapon invalid" { "#format" "{1:s}" - "en" "Weapon @green\"{1}\" @defaultis an invalid weapon (type) name." + "en" "Weapon @green\"{1}\"@default is an invalid weapon (type) name." } "Weapon is restricted" { "#format" "{1:s}" - "en" "Weapon @green{1} @defaultis restricted." + "en" "Weapon @green{1}@default is restricted." } // ZMarket @@ -623,13 +623,13 @@ "Weapons zmarket purchase" { "#format" "{1:s}" - "en" "You have purchased weapon @green{1}. @defaultSelect item again to buy ammo if you are low." + "en" "You have purchased weapon @green{1}.@default Select item again to buy ammo if you are low." } "Weapons zmarket purchase max" { "#format" "{1:s},{2:d}" - "en" "Weapon @green{1} @defaulthas a purchase limit of @green{2}@default. Wait until you respawn to try again." + "en" "Weapon @green{1}@default has a purchase limit of @green{2}@default. Wait until you respawn to try again." } "Weapons zmarket grenade max" @@ -1030,19 +1030,19 @@ "ZSpawn command force successful" { "#format" "{1:s}" - "en" "Player {1} was successfully spawned." + "en" "Successfully spawned @lgreen{1}@default." } "ZSpawn command force successful public" { "#format" "{1:s},{2:s},{3:s}" - "en" "@lgreen{1}@default has spawned @green{2}@default as a @lgreen{3}@default." + "en" "@lgreen{1}@default has spawned @green{2}@default as @lgreen{3}@default." } "ZSpawn command force unsuccessful" { "#format" "{1:s}" - "en" "Player {1} couldn't be spawned." + "en" "Could not zspawn @lgreen{1}@default." } // =========================== @@ -1110,13 +1110,13 @@ "ZTele command force successful" { "#format" "{1:s}" - "en" "Player {1} was successfully teleported." + "en" "Successfully teleported @lgreen{1}@default." } "ZTele command force unsuccessful" { "#format" "{1:s}" - "en" "Player {1} couldn't be teleported." + "en" "Could not teleport @lgreen{1}@default." } // =========================== diff --git a/env/include/sourcetvmanager.inc b/env/include/sourcetvmanager.inc new file mode 100644 index 0000000..4a0bf02 --- /dev/null +++ b/env/include/sourcetvmanager.inc @@ -0,0 +1,543 @@ +#if defined _stvmngr_included + #endinput +#endif +#define _stvmngr_included + +// Some guidelines from the SDK about director camera shot durations +#define MIN_SHOT_LENGTH 4.0 // minimum time of a cut (seconds) +#define MAX_SHOT_LENGTH 8.0 // maximum time of a cut (seconds) +#define DEF_SHOT_LENGTH 6.0 // average time of a cut (seconds) + +enum SourceTVBroadcastTarget { + // Send message to all spectators including proxies. + BTarget_Everyone = 0, + // Send message only to locally connected spectators. + BTarget_OnlyLocal +}; + +/** + * Get the current amount of running SourceTV instances. + * Can usually only be 1 at max except for CSGO, which can have 2. + * + * @return SourceTV instance number count. + */ +native int SourceTV_GetServerInstanceCount(); + +/** + * Select a SourceTV instance to operate the rest of the natives on. + * The first SourceTV to connect will always be selected by default. + * Most games only have 1 instance, so this might only be useful in CS:GO, + * which can have 2 instances running. + * + * @param instance The SourceTV instance number. + * @error Invalid SourceTV instance number. + */ +native void SourceTV_SelectServerInstance(int instance); + +/** + * Get the index of the currently selected SourceTV server instance. + * + * @return Index of the selected SourceTV instance number or -1 if no SourceTV enabled. + */ +native int SourceTV_GetSelectedServerInstance(); + +/** + * Called when a SourceTV is initialized. + * + * @param instance The SourceTV instance number. + */ +forward void SourceTV_OnServerStart(int instance); + + /** + * Called when a SourceTV server instance is shutdown. + * + * @param instance The SourceTV instance number. + */ +forward void SourceTV_OnServerShutdown(int instance); + +/** + * Returns whether this SourceTV instance is currently broadcasting. + * + * @return True if SourceTV instance is broadcasting, false otherwise. + */ +native bool SourceTV_IsActive(); + +/** + * Returns whether this SourceTV instance is a master proxy or relay. + * + * @return True if SourceTV instance is master proxy, false otherwise. + */ +native bool SourceTV_IsMasterProxy(); + +/** + * Get the local ip of the SourceTV server. + * + * @param ip Buffer to save IP in. + * @param maxlen Maximum length of the buffer. + * @return True if IP written, false otherwise. + */ +native bool SourceTV_GetServerIP(char[] ip, int maxlen); + +/** + * Get the UDP port of the SourceTV server. + * This is the port clients use to connect. + * + * @return SourceTV server UDP port. + */ +native int SourceTV_GetServerPort(); + +/** + * Get the client index of the SourceTV bot. + * + * @return Client index of SourceTV bot. + */ +native int SourceTV_GetBotIndex(); + +/** + * Get stats of the local SourceTV instance. + * Returns only the stats of this server, don't include relays. + * + * You have to subtract the proxy count from the spectator count to + * get the real spectator count, because the proxies take one spectator slot + * on the SourceTV server. + * + * @param proxies Number of SourceTV proxies connected to this server. + * @param slots Number of maximal available SourceTV spectator slots. + * @param specs Number of currently connected SourceTV spectators. + * @return True if stats were retrieved, false otherwise. + */ +native bool SourceTV_GetLocalStats(int &proxies, int &slots, int &specs); + +/** + * Get stats of this SourceTV network. + * Only the current Master Proxy can give accurate numbers. + * Relay proxies only get updates from the master from time to time. + * + * You have to subtract the proxy count from the spectator count to + * get the real spectator count, because the proxies take one spectator slot + * on the SourceTV server. + * + * @param proxies Number of SourceTV proxies connected to all servers. + * @param slots Number of maximal available SourceTV spectator slots on all servers. + * @param specs Number of currently connected SourceTV spectators on all servers. + * @return True if stats were retrieved, false otherwise. + */ +native bool SourceTV_GetGlobalStats(int &proxies, int &slots, int &specs); + +/** + * Current broadcasted tick. Can be lower than the actual server tick, + * due to delay. + * + * @return Current broadcast tick from director. + */ +native int SourceTV_GetBroadcastTick(); + +/** + * Returns current delay in seconds. (tv_delay) + * + * @return Current delay in seconds. + */ +native float SourceTV_GetDelay(); + +/** + * Print a center message to all SourceTV spectators for ~2 seconds. + * Like the tv_msg command. + * + * @param target Send only to directly connected spectators or proxies as well? + * @param format The format string. + * @param ... Variable number of format string arguments. + * @return True if message was sent, false otherwise. + */ +native bool SourceTV_BroadcastScreenMessage(SourceTVBroadcastTarget target, const char[] format, any ...); + +/** + * Prints text to the console of all connected SourceTV spectators. + * + * @param format The format string. + * @param ... Variable number of format string arguments. + * @return True if message was sent, false otherwise. + */ +native bool SourceTV_BroadcastConsoleMessage(const char[] format, any ...); + +/** + * Print a chat message to all SourceTV spectators. + * + * @param target Send only to directly connected spectators or proxies as well? + * @param format The format string. + * @param ... Variable number of format string arguments. + * @return True if message was sent, false otherwise. + */ +native bool SourceTV_BroadcastChatMessage(SourceTVBroadcastTarget target, const char[] format, any ...); + + +/******************************************************************************** + * SourceTV Director control + ********************************************************************************/ + +/** + * Get entity index of current view entity (PVS) of the + * auto director. Check the view origin, if this returns 0. + * @see SourceTV_GetViewOrigin + * + * @return Current view entity index, 0 if coords are used. + */ +native int SourceTV_GetViewEntity(); + +/** + * Get origin of current view point if view entity is 0. + * + * @param view Vector to store view position in. + */ +native void SourceTV_GetViewOrigin(float view[3]); + +/** + * Force the auto director to show a certain camera angle. + * + * @param pos The camera position. + * @param angle The camera angles (roll is unused). + * @param iTarget Target entity to keep the camera pointed towards or 0 to use the angle. + * @param fow Field of view of the camera. + * @param fDuration Length of the shot in seconds. + * @return True if shot was created, false otherwise. + * @error Invalid target entity. + */ +native bool SourceTV_ForceFixedCameraShot(float[] pos, float[] angle, int iTarget, float fov, float fDuration = DEF_SHOT_LENGTH); + +/** + * Force the auto director to show a player. + * + * @param iTarget1 The target player to follow. + * @param iTarget2 The other player to keep the camera centered on or 0 to follow target1's view. + * @param distance Distance of camera behind the player. + * @param phi Up/down offset of view point. + * @param theta Left/right offset of view point. + * @param bInEye Show as in-eye camera of the target. Ignores all the other third-person settings. + * @param fDuration Length of the shot in seconds. + * @return True if shot was created, false otherwise. + * @error Invalid target1 or target2 entity + */ +native bool SourceTV_ForceChaseCameraShot(int iTarget1, int iTarget2, int distance, int phi, int theta, bool bInEye, float fDuration = DEF_SHOT_LENGTH); + + + + +/******************************************************************************** + * SourceTV demo recording + ********************************************************************************/ + +/** + * Starts recording a SourceTV demo into the specified file. + * Only the master proxy can record demos. + * + * @param sFilename Filename of the demo file. + * @return True if recording started, false otherwise. + */ +native bool SourceTV_StartRecording(const char[] sFilename); + +/** + * Stops recording a SourceTV demo. + * + * @return True if recording stopped, false otherwise. + */ +native bool SourceTV_StopRecording(); + +/** + * Returns whether the SourceTV server is currently recording a demo. + * + * @return True if currently recording a SourceTV demo, false otherwise. + */ +native bool SourceTV_IsRecording(); + +/** + * Get the filename of the currently recorded demo. + * + * @param sFilename Buffer to store the filename in. + * @param maxlen Maximal length of the buffer. + * @return True if filename was written, false otherwise. + */ +native bool SourceTV_GetDemoFileName(char[] sFilename, int maxlen); + +/** + * Get current tick in the demofile. + * + * @return Current recording tick in the demofle. + */ +native int SourceTV_GetRecordingTick(); + +/** + * Print text to the demo console. + * This will show up when playing the demo back in the client console later. + * + * @param format The format string. + * @param ... Variable number of format string arguments. + * + * @return True if message was printed, false otherwise. + */ +native bool SourceTV_PrintToDemoConsole(const char[] format, any ...); + +/** + * Called when a SourceTV demo starts being recorded. + * @see SourceTV_SelectServerInstance + * + * @param instance The SourceTV instance of server recording. + * @param filename The filename of the demo. + */ +forward void SourceTV_OnStartRecording(int instance, const char[] filename); + +/** + * Called when a SourceTV demo stops being recorded. + * @see SourceTV_SelectServerInstance + * + * @param instance The SourceTV instance of server recording. + * @param filename The filename of the demo. + * @param recordingtick The tick length of the demo. + */ +forward void SourceTV_OnStopRecording(int instance, const char[] filename, int recordingtick); + + + + +/******************************************************************************** + * SourceTV spectator client handling + ********************************************************************************/ + +/** + * Get currently connected SourcetV spectator count. + * + * @return SourceTV spectator count. + */ +native int SourceTV_GetSpectatorCount(); + +/** + * Get the current client limit. + * + * @return Maximal possible spectator count. + */ +native int SourceTV_GetMaxClients(); + +/** + * Get number of client slots (used & unused) + * Client slots are only allocated when they're needed. + * Use this when iterating spectators. + * + * @return Number of client slots (used & unused) + */ +native int SourceTV_GetClientCount(); + +/** + * Returns if the spectator is connected. + * + * @param client The spectator client index. + * @return True if client is connected, false otherwise. + * @error Invalid client index. + */ +native bool SourceTV_IsClientConnected(int client); + +/** + * Returns if the spectator is a relay proxy. + * + * @param client The spectator client index. + * @return True if client is a proxy, false otherwise. + * @error Invalid client index. + */ +native bool SourceTV_IsClientProxy(int client); + +/** + * Get the name of a SourceTV spectator client. + * + * @param client The spectator client index. + * @param name Buffer for the client name. + * @param maxlen Maximal length of the buffer. + * @error Invalid client index or not connected. + */ +native void SourceTV_GetClientName(int client, char[] name, int maxlen); + +/** + * Get the IP of a SourceTV spectator client. + * + * @param client The spectator client index. + * @param name Buffer for the client ip. + * @param maxlen Maximal length of the buffer. + * @error Invalid client index or not connected. + */ +native void SourceTV_GetClientIP(int client, char[] ip, int maxlen); + +/** + * Get the password of a SourceTV spectator client. + * The password the client tried to connect with. + * Ignores changes from the SourceTV_OnSpectatorPreConnect forward. + * + * @param client The spectator client index. + * @param name Buffer for the client ip. + * @param maxlen Maximal length of the buffer. + * @error Invalid client index or not connected. + */ +native void SourceTV_GetClientPassword(int client, char[] password, int maxlen); + +/** + * Kick a SourceTV spectator client. + * + * @param client The spectator client index. + * @param sReason The kick reason. + * @error Invalid client index or not connected. + */ +native void SourceTV_KickClient(int client, const char[] sReason); + +/** + * Print a message to a single client's chat. + * + * @param client The spectator client index. + * @param format The format string. + * @param ... Variable number of format string arguments. + * @error Invalid client index or not connected. + */ +native void SourceTV_PrintToChat(int client, const char[] format, any ...); + +/** + * Print a message to a single client's console. + * + * @param client The spectator client index. + * @param format The format string. + * @param ... Variable number of format string arguments. + * @error Invalid client index or not connected. + */ +native void SourceTV_PrintToConsole(int client, const char[] format, any ...); + +/** + * Change the stream title only for one spectator. + * This is like tv_title but for a single client. + * Gets overwritten when tv_title gets changed. + * + * @param client The spectator client index. + * @param format The format string. + * @param ... Variable number of format string arguments. + * @error Invalid client index or not connected. + */ +native void SourceTV_SetClientTVTitle(int client, const char[] format, any ...); + +/** + * Called when a spectator wants to connect to the SourceTV server. + * This is called before any other validation has happened. + * Similar to the OnClientPreConnectEx forward in the Connect extension by asherkin. + * + * @param name The player name. + * @param password The password the client used to connect. Can be overwritten. + * @param ip The ip address of the client. + * @param rejectReason Buffer to write the reject reason to, if you want to reject the client from connecting. + * @return True to allow the client to connect, false to reject him with the given reason. + */ +forward bool SourceTV_OnSpectatorPreConnect(const char[] name, char password[255], const char[] ip, char rejectReason[255]); + +/** + * Called when a spectator client connected to the SourceTV server. + * + * @param client The spectator client index. + */ +forward void SourceTV_OnSpectatorConnected(int client); + +/** + * Called when a spectator client is about to disconnect. + * + * @param client The spectator client index. + * @param reason The reason for the disconnect. Can be overwritten. + */ +forward void SourceTV_OnSpectatorDisconnect(int client, char reason[255]); + +/** + * Called after a spectator client disconnected. + * + * @param client The spectator client index. + * @param reason The reason for the disconnect. + */ +forward void SourceTV_OnSpectatorDisconnected(int client, const char reason[255]); + +/** + * Called when a spectator client is entering the game. + * + * @param client The spectator client index. + */ +forward void SourceTV_OnSpectatorPutInServer(int client); + +/** + * Called before a spectator's chat message is sent. + * The message and chat group can be changed. + * Only called for directly connected clients - no proxies. + * + * @param client The spectator client index. + * @param message The message the client typed. + * @param chatgroup The chatgroup this message is sent to (tv_chatgroup). + * @return >= Plugin_Handled to block the message, Plugin_Continue to let it through. + */ +forward Action SourceTV_OnSpectatorChatMessage(int client, char message[255], char chatgroup[255]); + +/** + * Called after a spectator wrote a chat message. + * Only called for directly connected clients - no proxies. + * + * @param client The spectator client index. + * @param message The message the client typed. + * @param chatgroup The chatgroup this message is sent to (tv_chatgroup). + */ +forward void SourceTV_OnSpectatorChatMessage_Post(int client, const char[] message, const char[] chatgroup); + +/** + * Do not edit below this line! + */ +public Extension __ext_stvmngr = +{ + name = "SourceTV Manager", + file = "sourcetvmanager.ext", +#if defined AUTOLOAD_EXTENSIONS + autoload = 1, +#else + autoload = 0, +#endif +#if defined REQUIRE_EXTENSIONS + required = 1, +#else + required = 0, +#endif +}; + +#if !defined REQUIRE_EXTENSIONS +public void __ext_stvmngr_SetNTVOptional() +{ + MarkNativeAsOptional("SourceTV_GetServerInstanceCount"); + MarkNativeAsOptional("SourceTV_SelectServerInstance"); + MarkNativeAsOptional("SourceTV_GetSelectedServerInstance"); + MarkNativeAsOptional("SourceTV_IsActive"); + MarkNativeAsOptional("SourceTV_IsMasterProxy"); + MarkNativeAsOptional("SourceTV_GetServerIP"); + MarkNativeAsOptional("SourceTV_GetServerPort"); + MarkNativeAsOptional("SourceTV_GetBotIndex"); + MarkNativeAsOptional("SourceTV_GetLocalStats"); + MarkNativeAsOptional("SourceTV_GetGlobalStats"); + MarkNativeAsOptional("SourceTV_GetBroadcastTick"); + MarkNativeAsOptional("SourceTV_GetDelay"); + MarkNativeAsOptional("SourceTV_BroadcastScreenMessage"); + MarkNativeAsOptional("SourceTV_BroadcastConsoleMessage"); + MarkNativeAsOptional("SourceTV_BroadcastChatMessage"); + MarkNativeAsOptional("SourceTV_GetViewEntity"); + MarkNativeAsOptional("SourceTV_GetViewOrigin"); + MarkNativeAsOptional("SourceTV_ForceFixedCameraShot"); + MarkNativeAsOptional("SourceTV_ForceChaseCameraShot"); + MarkNativeAsOptional("SourceTV_StartRecording"); + MarkNativeAsOptional("SourceTV_StopRecording"); + MarkNativeAsOptional("SourceTV_IsRecording"); + MarkNativeAsOptional("SourceTV_GetDemoFileName"); + MarkNativeAsOptional("SourceTV_GetRecordingTick"); + MarkNativeAsOptional("SourceTV_PrintToDemoConsole"); + MarkNativeAsOptional("SourceTV_GetSpectatorCount"); + MarkNativeAsOptional("SourceTV_GetMaxClients"); + MarkNativeAsOptional("SourceTV_GetClientCount"); + MarkNativeAsOptional("SourceTV_IsClientConnected"); + MarkNativeAsOptional("SourceTV_IsClientProxy"); + MarkNativeAsOptional("SourceTV_GetClientName"); + MarkNativeAsOptional("SourceTV_GetClientIP"); + MarkNativeAsOptional("SourceTV_GetClientPassword"); + MarkNativeAsOptional("SourceTV_KickClient"); + MarkNativeAsOptional("SourceTV_PrintToChat"); + MarkNativeAsOptional("SourceTV_PrintToConsole"); + MarkNativeAsOptional("SourceTV_SetClientTVTitle"); +} +#endif diff --git a/src/zombiereloaded.sp b/src/zombiereloaded.sp index 9a4c639..b5eb9d4 100644 --- a/src/zombiereloaded.sp +++ b/src/zombiereloaded.sp @@ -168,6 +168,7 @@ public OnPluginStart() public OnAllPluginsLoaded() { // Forward event to modules. + RoundEndOnAllPluginsLoaded(); WeaponsOnAllPluginsLoaded(); ConfigOnAllPluginsLoaded(); } @@ -252,8 +253,12 @@ public OnConfigsExecuted() ConfigOnModulesLoaded(); ClassOnModulesLoaded(); + // Fake roundstart + EventRoundStart(INVALID_HANDLE, "", false); + if(g_bLate) { + new bool:bZombieSpawned = false; for(new client = 1; client <= MaxClients; client++) { if(!IsClientConnected(client)) @@ -265,12 +270,24 @@ public OnConfigsExecuted() { OnClientPutInServer(client); + if(AreClientCookiesCached(client)) + OnClientCookiesCached(client); + if(IsClientAuthorized(client)) OnClientPostAdminCheck(client); - } - if(AreClientCookiesCached(client)) - OnClientCookiesCached(client); + if(IsPlayerAlive(client) && GetClientTeam(client) == CS_TEAM_T) + { + InfectHumanToZombie(client); + bZombieSpawned = true; + } + } + } + + if(bZombieSpawned) + { + // Zombies have been infected. + g_bZombieSpawned = true; } g_bLate = false; diff --git a/src/zr/infect.inc b/src/zr/infect.inc index d48c728..c13d20a 100644 --- a/src/zr/infect.inc +++ b/src/zr/infect.inc @@ -464,9 +464,6 @@ public Action:InfectMotherZombie(Handle:timer) return; } - // Prune list of immune clients. - //eligibleclients = InfectRemoveImmuneClients(arrayEligibleClients); - // Move all clients to CT. InfectMoveAllToCT(); @@ -1187,6 +1184,8 @@ stock InfectManualInfect(client, targets[], count, bool:respawnoverride = false, else strcopy(adminname, sizeof(adminname), "Console"); + new bool:success = false; + // x = Client index. for (new x = 0; x < count; x++) { @@ -1196,13 +1195,6 @@ stock InfectManualInfect(client, targets[], count, bool:respawnoverride = false, // Check if client is a human before turning into zombie. if (!InfectIsClientHuman(targets[x])) { - // If there was only 1 player targetted, then let admin know the command was unsuccessful. - if (count == 1) - { - // Tell admin command was unsuccessful. - TranslationReplyToCommand(client, "Infect command infect unsuccessful", targetname); - } - continue; } @@ -1211,29 +1203,42 @@ stock InfectManualInfect(client, targets[], count, bool:respawnoverride = false, { // Turn client into a mother zombie. InfectHumanToZombie(targets[x], _, true, respawnoverride, respawn); - LogAction(client, targets[x], "\"%L\" turned \"%L\" into a mother zombie", client, targets[x]); - TranslationPrintToChatAll(false, false, "Infect command infect mother successful public", adminname, targetname); - // If there was only 1 player targetted, then let admin know the outcome of the command. - if (count == 1) - { - TranslationReplyToCommand(client, "Infect command infect mother successful", targetname); - } + // Log action to game events. + LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Infect, "Manual Infect", "\"%L\" turned \"%L\" into a mother zombie", client, targets[x]); + success = true; continue; } // Turn client into a zombie. InfectHumanToZombie(targets[x], _, false, respawnoverride, respawn); - LogAction(client, targets[x], "\"%L\" turned \"%L\" into a zombie", client, targets[x]); - TranslationPrintToChatAll(false, false, "Infect command infect successful public", adminname, targetname); - // If there was only 1 player targetted, then let admin know the outcome of the command. - if (count == 1) + // Log action to game events. + LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Infect, "Manual Infect", "\"%L\" turned \"%L\" into a zombie", client, targets[x]); + + success = true; + } + + // Tell admin the outcome of the command. + if(success) + { + if (!zombiespawned) + { + TranslationReplyToCommand(client, "Infect command infect mother successful", targetname); + TranslationPrintToChatAllExcept(false, false, client, "Infect command infect mother successful public", adminname, targetname); + } + else { TranslationReplyToCommand(client, "Infect command infect successful", targetname); + TranslationPrintToChatAllExcept(false, false, client, "Infect command infect successful public", adminname, targetname); } } + else + { + // Tell admin command was unsuccessful. + TranslationReplyToCommand(client, "Infect command infect unsuccessful", targetname); + } } /** @@ -1256,6 +1261,8 @@ stock InfectManualHuman(client, targets[], count, bool:respawn = false, bool:pro else strcopy(adminname, sizeof(adminname), "Console"); + new bool:success = false; + // x = Client index. for (new x = 0; x < count; x++) { @@ -1267,26 +1274,24 @@ stock InfectManualHuman(client, targets[], count, bool:respawn = false, bool:pro { // Turn client into a zombie. InfectZombieToHuman(targets[x], respawn, protect); - LogAction(client, targets[x], "\"%L\" turned \"%L\" into a human", client, targets[x]); - TranslationPrintToChatAll(false, false, "Infect command human successful public", adminname, targetname); - // If there was only 1 player targetted, then let admin know the outcome of the command. - if (count == 1) - { - // Tell admin command was successful. - TranslationReplyToCommand(client, "Infect command human successful", targetname); - } - } - else - { - // If there was only 1 player targetted, then let admin know the command was unsuccessful. - if (count == 1) - { - // Tell admin command was unsuccessful. - TranslationReplyToCommand(client, "Infect command human unsuccessful", targetname); - } + // Log action to game events. + LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Infect, "Manual Human", "\"%L\" turned \"%L\" into a human", client, targets[x]); + + success = true; } } + + // Tell admin the outcome of the command. + if (success) + { + TranslationReplyToCommand(client, "Infect command human successful", targetname); + TranslationPrintToChatAllExcept(false, false, client, "Infect command human successful public", adminname, targetname); + } + else + { + TranslationReplyToCommand(client, "Infect command human unsuccessful", targetname); + } } /** diff --git a/src/zr/playerclasses/playerclasses.inc b/src/zr/playerclasses/playerclasses.inc index f6280e7..178a33e 100644 --- a/src/zr/playerclasses/playerclasses.inc +++ b/src/zr/playerclasses/playerclasses.inc @@ -1202,8 +1202,11 @@ ClassClientSetDefaultIndexes(client = -1) ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = humanindex; ClassSelected[client][ZR_CLASS_TEAM_ADMINS] = adminindex; - // Copy human class data to player cache. - ClassReloadPlayerCache(client, humanindex); + // Copy class data to player cache. + if (InfectIsClientInfected(client)) + ClassReloadPlayerCache(client, zombieindex); + else + ClassReloadPlayerCache(client, humanindex); // Save indexes in cookies if enabled, and not already saved. if (saveclasses) diff --git a/src/zr/roundend.inc b/src/zr/roundend.inc index 04896e8..5827724 100644 --- a/src/zr/roundend.inc +++ b/src/zr/roundend.inc @@ -25,6 +25,22 @@ * ============================================================================ */ +/* Decide whether topmenus should be required */ +#if !defined REQUIRE_PLUGIN + #if defined REQUIRE_EXTENSIONS + #define TEMP_REQUIRE_EXTENSIONS + #undef REQUIRE_EXTENSIONS + #endif +#endif + +#tryinclude "sourcetvmanager.inc" + +/* Restore old REQUIRE_EXTENSIONS value if necessary */ +#if defined TEMP_REQUIRE_EXTENSIONS + #define REQUIRE_EXTENSIONS + #undef TEMP_REQUIRE_EXTENSIONS +#endif + /** * @section All round end reasons. */ @@ -69,6 +85,19 @@ enum RoundEndOutcome */ new Handle:g_tRoundEnd = INVALID_HANDLE; +new bool:g_SourceTVManagerLoaded = false; + +/** + * All plugins have finished loading. + */ +RoundEndOnAllPluginsLoaded() +{ + #if defined _stvmngr_included + g_SourceTVManagerLoaded = LibraryExists("sourcetvmanager"); + LogMessage("SourceTV Manager: %s", (g_SourceTVManagerLoaded ? "loaded" : "not loaded")); + #endif +} + /** * Map is starting. */ @@ -239,6 +268,14 @@ RoundEndDisplayStats() PrintToConsole(client, "# %8s %40s %24s %5s %6s", sPlayerID, sPlayerName, sPlayerAuth, sPlayerState, sPlayerTeam); } + + #if defined _stvmngr_included + if(g_SourceTVManagerLoaded) + { + SourceTV_PrintToDemoConsole("# %8s %40s %24s %5s %6s", + sPlayerID, sPlayerName, sPlayerAuth, sPlayerState, sPlayerTeam); + } + #endif } } diff --git a/src/zr/translation.inc b/src/zr/translation.inc index c46490e..3499dac 100644 --- a/src/zr/translation.inc +++ b/src/zr/translation.inc @@ -179,6 +179,67 @@ stock TranslationPrintToChatAll(bool:server, bool:admin, any:...) } } +/** + * Format the string to the plugin's style. + * + * @param server True to also print text to server console, false just to clients. + * @param admin True to only print text to admins, false to print to everyone. + * @param ... Translation formatting parameters. + */ +stock TranslationPrintToChatAllExcept(bool:server, bool:admin, client, any:...) +{ + decl String:translation[TRANSLATION_MAX_LENGTH_CHAT]; + + if (server) + { + // Set translation target + SetGlobalTransTarget(LANG_SERVER); + + // Translate phrase. + VFormat(translation, sizeof(translation), "%t", 4); + + // Format string to create plugin style. + TranslationPluginFormatString(translation, sizeof(translation), false); + + // Print phrase to server. + PrintToServer(translation); + } + + // x = client index. + for (new x = 1; x <= MaxClients; x++) + { + // Ignore this client + if (x == client) + { + continue; + } + + // If client isn't in-game, then stop. + if (!IsClientInGame(x)) + { + continue; + } + + // If client isn't an admin, and we're only printing to admins, then stop. + if (admin && !ZRIsClientAdmin(x)) + { + continue; + } + + // Set translation target to client. + SetGlobalTransTarget(x); + + // Translate phrase. + VFormat(translation, sizeof(translation), "%t", 4); + + // Format string to create plugin style. + TranslationPluginFormatString(translation, sizeof(translation)); + + // Print translated phrase to client. + PrintToChat(x, translation); + } +} + /** * Print console text to client. (with style) * diff --git a/src/zr/zspawn.inc b/src/zr/zspawn.inc index 3870022..c1acfbb 100644 --- a/src/zr/zspawn.inc +++ b/src/zr/zspawn.inc @@ -329,17 +329,26 @@ public ZSpawnForceHandle(Handle:menu_zspawn_force, MenuAction:action, client, sl } // Get the target's name for future use. - decl String:targetname[MAX_NAME_LENGTH]; + decl String:targetname[MAX_NAME_LENGTH], String:adminname[MAX_NAME_LENGTH]; GetClientName(target, targetname, sizeof(targetname)); + // Get admin's name for future use. + if(client > 0) + GetClientName(client, adminname, sizeof(adminname)); + else + strcopy(adminname, sizeof(adminname), "Console"); + // Force ZSpawn on the target. new bool:success = ZSpawnClient(target, true); // Tell admin the outcome of the action. if (success) { - LogAction(client, target, "\"%L\" forced a ZSpawn on \"%L\"", client, target); + // Log action to game events. + LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_ZSpawn, "Force ZSpawn", "\"%L\" force zspawned \"%L\" as human", client, target); + TranslationReplyToCommand(client, "ZSpawn command force successful", targetname); + TranslationPrintToChatAllExcept(false, false, client, "ZSpawn command force successful public", adminname, targetname, "human"); } else { @@ -441,35 +450,31 @@ public Action:ZSpawnForceCommand(client, argc) // Copy value of second (optional) parameter to 'zombie'. // It will be false if the parameter wasn't specified. new bool:zombie = bool:StringToInt(strZombie); + new bool:success = false; // x = Client index. for (new x = 0; x < result; x++) { - // Give client the item. - new bool:success = ZSpawnClient(targets[x], true, zombie); - - if(success) + // Spawn client + if (ZSpawnClient(targets[x], true, zombie)) { - LogAction(client, targets[x], "\"%L\" forced a ZSpawn on \"%L\"%s", client, targets[x], zombie ? " and made them zombie" : ""); - TranslationPrintToChatAll(false, false, "ZSpawn command force successful public", adminname, targetname, zombie ? "zombie" : "human"); - } + // Log action to game events. + LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_ZSpawn, "Force ZSpawn", "\"%L\" force zspawned \"%L\" as %s", client, targets[x], zombie ? "zombie" : "human"); - // Tell admin the outcome of the command if only 1 client was targetted. - if (result == 1) - { - if (success) - { - TranslationReplyToCommand(client, "ZSpawn command force successful", targetname); - } - else - { - TranslationReplyToCommand(client, "ZSpawn command force unsuccessful", targetname); - } + success = true; } } - // Log action to game events. - //LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_ZSpawn, "Force ZSpawn", "Admin \"%L\" forced player(s) to spawn. (zr_zspawn_force)", client); + // Tell admin the outcome of the command. + if (success) + { + TranslationReplyToCommand(client, "ZSpawn command force successful", targetname); + TranslationPrintToChatAllExcept(false, false, client, "ZSpawn command force successful public", adminname, targetname, zombie ? "zombie" : "human"); + } + else + { + TranslationReplyToCommand(client, "ZSpawn command force unsuccessful", targetname); + } return Plugin_Handled; } diff --git a/src/zr/ztele/ztele.inc b/src/zr/ztele/ztele.inc index 6d0e991..4310c2a 100644 --- a/src/zr/ztele/ztele.inc +++ b/src/zr/ztele/ztele.inc @@ -34,7 +34,7 @@ /** * Array to store client's spawn location. */ -float g_vecZTeleSpawn[MAXPLAYERS + 1][3]; +float g_vecZTeleSpawn[MAXPLAYERS + 1][2][3]; /** * Array to store client's current location. @@ -56,7 +56,7 @@ Handle tZTele[MAXPLAYERS + 1]; */ int g_iZTeleTimeLeft[MAXPLAYERS + 1]; -float g_vecZTeleSpawnPoints[MAX_PLAYER_SPAWNS][3]; +float g_vecZTeleSpawnPoints[MAX_PLAYER_SPAWNS][2][3]; int g_iZTeleSpawnPointsCount = 0; /** @@ -82,7 +82,8 @@ void ZTeleOnRoundStart() GetEntityClassname(entity, classname, sizeof(classname)); if (StrEqual(classname, "info_player_terrorist", true) || StrEqual(classname, "info_player_counterterrorist", true)) { - GetEntPropVector(entity, Prop_Send, "m_vecOrigin", g_vecZTeleSpawnPoints[g_iZTeleSpawnPointsCount]); + GetEntPropVector(entity, Prop_Send, "m_vecOrigin", g_vecZTeleSpawnPoints[g_iZTeleSpawnPointsCount][0]); + GetEntPropVector(entity, Prop_Send, "m_angRotation", g_vecZTeleSpawnPoints[g_iZTeleSpawnPointsCount][1]); g_iZTeleSpawnPointsCount++; if (g_iZTeleSpawnPointsCount >= MAX_PLAYER_SPAWNS) @@ -114,7 +115,8 @@ void ZTele_OnClientSpawn(int client) g_iZTeleCount[client] = 0; // Get spawn location. - GetClientAbsOrigin(client, g_vecZTeleSpawn[client]); + GetClientAbsOrigin(client, g_vecZTeleSpawn[client][0]); + GetClientAbsAngles(client, g_vecZTeleSpawn[client][1]); ZTele_StopTimer(client); } @@ -245,11 +247,11 @@ void ZTele_TeleportClient(int client) if (ZTele_IsRandomSpawnEnabled() && g_iZTeleSpawnPointsCount) { int select = Math_GetRandomInt(0, g_iZTeleSpawnPointsCount - 1); - TeleportEntity(client, g_vecZTeleSpawnPoints[select], NULL_VECTOR, view_as({0.0, 0.0, 0.0})); + TeleportEntity(client, g_vecZTeleSpawnPoints[select][0], g_vecZTeleSpawnPoints[select][1], NULL_VECTOR); } else { - TeleportEntity(client, g_vecZTeleSpawn[client], NULL_VECTOR, view_as({0.0, 0.0, 0.0})); + TeleportEntity(client, g_vecZTeleSpawn[client][0], g_vecZTeleSpawn[client][1], NULL_VECTOR); } } @@ -445,7 +447,7 @@ public Action ZTele_Timer(Handle timer, int client) if (g_iZTeleTimeLeft[client] <= 0) { // Teleport client. - TeleportEntity(client, g_vecZTeleSpawn[client], NULL_VECTOR, NULL_VECTOR); + TeleportEntity(client, g_vecZTeleSpawn[client][0], g_vecZTeleSpawn[client][1], NULL_VECTOR); // Increment teleport count. g_iZTeleCount[client]++;