PDA

View Full Version : [TF2] Get the time left in a round


DarthNinja
09-10-2010, 08:33
Here is a way to get exactly how much time is left in the round:
Code should be self explanatory.



#include <sourcemod>
#include <sdktools>
#include <tf2>
#include <tf2_stocks>


#define PLUGIN_VERSION "1.0.0"

new g_StartTime;
new g_AdditionalTime = 0;

public Plugin:myinfo =
{
name = "[DEV] Get Round Time Left",
author = "DarthNinja",
description = "This was a BITCH",
version = PLUGIN_VERSION,
url = "DarthNinja.com"
}

public OnPluginStart()
{
CreateConVar("sm_roundtime_version", PLUGIN_VERSION, "Version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FC VAR_NOTIFY);

RegConsoleCmd("sm_roundtime", Command_Debug);

HookEvent("teamplay_setup_finished", EventSetupEnd);
HookEvent("teamplay_timer_time_added", EventTimeAdded);
}

public Action:EventSetupEnd(Handle:event, const String:name[], bool:dontBroadcast)
{
g_StartTime = GetTime()
PrintToChatAll("RoundStart TimeStamp Logged: %i", g_StartTime)
g_AdditionalTime = 0;
}

public Action:EventTimeAdded(Handle:event, const String:name[], bool:dontBroadcast)
{
new iAddedTime = GetEventInt(event, "seconds_added")
g_AdditionalTime = g_AdditionalTime + iAddedTime;
PrintToChatAll("Time added: %i", iAddedTime)
}


public Action:Command_Debug(client, args)
{
PrintToChatAll("-----------------------------------------")

//Alright bitch, play tiemz ovar
new SecElapsed = GetTime() - g_StartTime;
PrintToChatAll("%i Seconds have elapsed since the round started", SecElapsed)

//Get round time that the round started with
new ent = FindEntityByClassname(MaxClients+1, "team_round_timer");
new Float:RoundStartLength = GetEntPropFloat(ent, Prop_Send, "m_flTimeRemaining");
PrintToChatAll("Float:RoundStartLength == %f", RoundStartLength)
new iRoundStartLength = RoundToZero(RoundStartLength)
PrintToChatAll("Int:iRoundStartLength == %i", iRoundStartLength)


//g_AdditionalTime = time added this round
PrintToChatAll("TimeAdded This Round: %i", g_AdditionalTime)

new TimeBuffer = iRoundStartLength + g_AdditionalTime;
new TimeLeft = TimeBuffer - SecElapsed;
PrintToChatAll("TimeLeft Sec: %i", TimeLeft)

PrintToChatAll("TimeLeft Min: %i~", TimeLeft/60)

new timeleftMIN = TimeLeft/60;
new Sec = TimeLeft-(timeleftMIN*60)
PrintToChatAll("<<EXACT TIME LEFT>> :: |||%i:%02i|||", TimeLeft/60,Sec)

PrintToChatAll("-----------------------------------------")
return Plugin_Handled;
}


This is a fully working plugin, you can use the command and it will output something like this:
http://img825.**************/img825/1599/1039538834.jpg
http://img825.**************/img825/8148/1039540104.jpg
http://img825.**************/img825/8113/1039546044.jpg

Note that this code only works correctly during rounds, not before or after.

asherkin
09-10-2010, 08:34
Nice work.

Doctor Noob
12-07-2010, 01:09
This approach does not seem to work properly on some maps, particularly KOTH, which has more than one round timer that must be checked. In NoobBalance (http://forums.alliedmods.net/showthread.php?t=144102), I used an approach like the following, which seemed to be quite reliable in my testing:

//Global variables
new bool:round_is_timed = false; //True if this is a timed round
new Float:round_end_time; //Contains the round end time (compare to GetGameTime()'s return value) if round_is_timed is true

public OnPluginStart()
{
HookEvent("teamplay_setup_finished", hook_setup_finished, EventHookMode_PostNoCopy);
HookEvent("teamplay_timer_time_added", hook_timer_time_added, EventHookMode_PostNoCopy);
}

stock GetRoundTimerInformation()
{
new round_timer = -1;
new Float:best_end_time = 1000000000000; //a very large "time"
new Float:timer_end_time;
new bool:found_valid_timer = false;
new bool:timer_is_disabled = true;
new bool:timer_is_paused = true;

while ( (round_timer = FindEntityByClassname(round_timer, "team_round_timer")) != -1) {
//Make sure this timer is enabled
timer_is_paused = bool:GetEntProp(round_timer, Prop_Send, "m_bTimerPaused");
timer_is_disabled = bool:GetEntProp(round_timer, Prop_Send, "m_bIsDisabled");

//End time is what we're interested in... fortunately, it works
// (getting the current time remaining does NOT work as of late November 2010)
timer_end_time = GetEntPropFloat(round_timer, Prop_Send, "m_flTimerEndTime");

if (!timer_is_paused && !timer_is_disabled && (timer_end_time <= best_end_time || !found_valid_timer)) {
best_end_time = timer_end_time;
found_valid_timer = true;
}
}

if (found_valid_timer) {
round_end_time = best_end_time;
round_is_timed = true;
} else {
round_is_timed = false;
}
}

public hook_timer_time_added(Handle:event, const String:name[], bool:dontBroadcast)
{
GetRoundTimerInformation();
}

public hook_setup_finished(Handle:event, const String:name[], bool:dontBroadcast)
{
GetRoundTimerInformation();
}

The above code is quite stripped down, and of course may contain bugs. It will only report correctly during the game, as I left out the sections that track the current game stage. The complete implementation I settled on is available in the source code to NoobBalance. I ended up just having to call GetRoundTimerInformation() regularly as I couldn't be bothered to chase down every possible event that could adjust the timers; doing it this way is a little more future-proof anyway.

crazydog
04-17-2011, 21:03
Sorry to necro this(ish), but I'm having trouble using your code Doctor Noob - could you provide an example of its use? I need to get the current round time when an event is fired, but I can't seem to get a proper reading with your above code. =/