Custom Server time
#1

Hello,

I've been trying to edit the standard gl_realtime script in such a way that the time will increase with every second, much like in San Andreas Multiplayer (1 second in real = 1 minute server time). But I've been unsuccessful so far.
I've been wondering what changes one needs to make in order for this to work. Can you perhaps help me?
The script I am using:

Код:
//
// Keeps the in game time synced to the server's time and
// draws the current time on the player's hud using a textdraw/
// (1 minute = 1 minute real world time)
//
//  © 2009-2014 SA-MP Team

#include <a_samp>
#pragma tabsize 0

#include "../include/gl_common.inc"

//--------------------------------------------------

// Used to override the time in this script
new worldtime_override = 0;
new worldtime_overridehour = 0;
new worldtime_overridemin  = 0;

new Text:txtTimeDisp;
new hour, minute;
new timestr[32];

forward UpdateTimeAndWeather();

//--------------------------------------------------

new fine_weather_ids[] = {1,2,3,4,5,6,7,12,13,14,15,17,18,24,25,26,27,28,29,30,40};
new foggy_weather_ids[] = {9,19,20,31,32};
new wet_weather_ids[] = {8};

stock UpdateWorldWeather()
{
	new next_weather_prob = random(100);
	if(next_weather_prob < 70) 		SetWeather(fine_weather_ids[random(sizeof(fine_weather_ids))]);
	else if(next_weather_prob < 95) SetWeather(foggy_weather_ids[random(sizeof(foggy_weather_ids))]);
	else							SetWeather(wet_weather_ids[random(sizeof(wet_weather_ids))]);
}

//--------------------------------------------------

//new last_weather_update=0;

public UpdateTimeAndWeather()
{
	// Update time
	if(!worldtime_override) {
    	gettime(hour, minute);
	} else {
		hour = worldtime_overridehour;
		minute = worldtime_overridemin;
	}

   	format(timestr,32,"%02d:%02d",hour,minute);
   	TextDrawSetString(txtTimeDisp,timestr);
   	SetWorldTime(hour);
   	
	new x=0;
	while(x!=MAX_PLAYERS) {
	    if(IsPlayerConnected(x) && GetPlayerState(x) != PLAYER_STATE_NONE) {
	        SetPlayerTime(x,hour,minute);
		 }
		 x++;
	}

	/* Update weather every hour
	if(last_weather_update == 0) {
	    UpdateWorldWeather();
	}
	last_weather_update++;
	if(last_weather_update == 60) {
	    last_weather_update = 0;
	}*/
}

//--------------------------------------------------

public OnGameModeInit()
{
	// Init our text display
	txtTimeDisp = TextDrawCreate(605.0,25.0,"00:00");
	TextDrawUseBox(txtTimeDisp, 0);
	TextDrawFont(txtTimeDisp, 3);
	TextDrawSetShadow(txtTimeDisp,0); // no shadow
    TextDrawSetOutline(txtTimeDisp,2); // thickness 1
    TextDrawBackgroundColor(txtTimeDisp,0x000000FF);
    TextDrawColor(txtTimeDisp,0xFFFFFFFF);
    TextDrawAlignment(txtTimeDisp,3);
	TextDrawLetterSize(txtTimeDisp,0.5,1.5);
	
	UpdateTimeAndWeather();
	SetTimer("UpdateTimeAndWeather",1000 * 60,1);

	return 1;
}

//--------------------------------------------------

public OnPlayerSpawn(playerid)
{
	TextDrawShowForPlayer(playerid,txtTimeDisp);
	
	// Update time
	if(!worldtime_override) {
    	gettime(hour, minute);
	} else {
		hour = worldtime_overridehour;
		minute = worldtime_overridemin;
	}
	
	SetPlayerTime(playerid,hour,minute);
	
	return 1;
}

//--------------------------------------------------

public OnPlayerDeath(playerid, killerid, reason)
{
    TextDrawHideForPlayer(playerid,txtTimeDisp);
 	return 1;
}

//--------------------------------------------------

public OnPlayerConnect(playerid)
{
    gettime(hour, minute);
    SetPlayerTime(playerid,hour,minute);
    return 1;
}

//--------------------------------------------------

public OnPlayerCommandText(playerid, cmdtext[])
{
	new cmd[256+1];
	new idx;
	cmd = strtok(cmdtext, idx);
	
	if(!IsPlayerAdmin(playerid)) return 0; // this is an admin only script

	if(strcmp(cmd, "/sethour", true) == 0) {
	    new tmp[256+1];
		tmp = strtok(cmdtext,idx);
        worldtime_override = 1;
        worldtime_overridehour = strval(tmp);
        UpdateTimeAndWeather();
		return 1;
	}
	
	if(strcmp(cmd, "/setminute", true) == 0) {
	    new tmp[256+1];
		tmp = strtok(cmdtext,idx);
        worldtime_override = 1;
        worldtime_overridemin = strval(tmp);
        UpdateTimeAndWeather();
		return 1;
	}
	
	return 0;
}
Reply
#2

That would be the easy answer, but the time won't be synced with other players. I've already checked that.
Reply
#3

Could you be more specific?
Reply
#4

Use https://sampwiki.blast.hk/wiki/SetPlayerTime

That is synced.

Just use a global variable and increase the minutes and hours
Reply
#5

I already know this exists, my question is how to increase this? a simple minute+1 doesn't work
Reply
#6

bump
Reply
#7

1. Declare two variables - one to store the current hour and one to store the current minute.
2. Set a repeating one second timer to increase the current minute. If the current minute reaches 60, set it to 0 and increase the current hour. If the current hour reaches 24, set it to 0.
3. Set a player's time when the spawn or perhaps periodically (once a minute?) to keep players' time in sync.

Note that with TogglePlayerClock enabled, if a player pauses, their clock will pause for the duration they are paused. So perhaps also sync the time when a player unpauses (when no longer paused, detected using OnPlayerUpdate).

Hope this was helpful, unless you are attempting to do something different from this?
Reply
#8

Quote:
Originally Posted by MP2
Посмотреть сообщение
1. Declare two variables - one to store the current hour and one to store the current minute.
2. Set a repeating one second timer to increase the current minute. If the current minute reaches 60, set it to 0 and increase the current hour. If the current hour reaches 24, set it to 0.
3. Set a player's time when the spawn or perhaps periodically (once a minute?) to keep players' time in sync.

Note that with TogglePlayerClock enabled, if a player pauses, their clock will pause for the duration they are paused. So perhaps also sync the time when a player unpauses (when no longer paused, detected using OnPlayerUpdate).

Hope this was helpful, unless you are attempting to do something different from this?
If you want it to be accurate - which is better if you use the ingame clock since timers aren't perfectly accurate - use the unix timestamp and modulo it by 1440 (24 minutes). Then convert the result to hours and minutes.
This will also have the nice side-effect that the ingame time will be an exactly 60x sped up equivalent to the real time, meaning every real life day at 18:54 server time it will be 6:00 ingame with a stable pattern.

Using timers you'll occassionally notice the ingame time getting out of sync and it will never be the same ingame time at the same time of RL day because of the inaccuracy (which becomes very noticable after a while, even with timerfix).

Код:
new tstamp = gettime() % 1440,
    hour = tstamp / 60,
    min = tstamp % 60;
It's technically even easier to code.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)