Ejemplo n.º 1
0
/*
==================
BotMatch_Harvest
==================
*/
void BotMatch_Harvest(bot_state_t *bs, bot_match_t *match) {
	char netname[MAX_MESSAGE_SIZE];
	int playernum;

	if (gametype == GT_HARVESTER) {
		if (!neutralobelisk.areanum || !redobelisk.areanum || !blueobelisk.areanum)
			return;
	}
	else {
		return;
	}
	//if not addressed to this bot
	if (!BotAddressedToBot(bs, match)) return;
	//
	BotMatchVariable(match, NETNAME, netname, sizeof(netname));
	//
	playernum = FindPlayerByName(netname);
	//
	bs->decisionmaker = playernum;
	bs->ordered = qtrue;
	bs->order_time = FloatTime();
	//set the time to send a message to the team mates
	bs->teammessage_time = FloatTime() + 2 * random();
	//set the ltg type
	bs->ltgtype = LTG_HARVEST;
	//set the team goal time
	bs->teamgoal_time = FloatTime() + TEAM_HARVEST_TIME;
	bs->harvestaway_time = 0;
	//
	BotSetTeamStatus(bs);
	// remember last ordered task
	BotRememberLastOrderedTask(bs);
	BotPrintTeamGoal(bs);
}
Ejemplo n.º 2
0
/*
==================
BotMatch_ReturnFlag
==================
*/
void BotMatch_ReturnFlag(bot_state_t *bs, bot_match_t *match) {
	char netname[MAX_MESSAGE_SIZE];
	int playernum;

	//if not in CTF mode
	if (
		gametype != GT_CTF
#ifdef MISSIONPACK
		&& gametype != GT_1FCTF
#endif
		)
		return;
	//if not addressed to this bot
	if (!BotAddressedToBot(bs, match))
		return;
	//
	BotMatchVariable(match, NETNAME, netname, sizeof(netname));
	//
	playernum = FindPlayerByName(netname);
	//
	bs->decisionmaker = playernum;
	bs->ordered = qtrue;
	bs->order_time = FloatTime();
	//set the time to send a message to the team mates
	bs->teammessage_time = FloatTime() + 2 * random();
	//set the ltg type
	bs->ltgtype = LTG_RETURNFLAG;
	//set the team goal time
	bs->teamgoal_time = FloatTime() + CTF_RETURNFLAG_TIME;
	bs->rushbaseaway_time = 0;
	//
	BotSetTeamStatus(bs);
	BotPrintTeamGoal(bs);
}
Ejemplo n.º 3
0
/*
==================
BotMatch_Patrol
==================
*/
void BotMatch_Patrol(bot_state_t *bs, bot_match_t *match) {
	char netname[MAX_MESSAGE_SIZE];
	int playernum;

	if (!TeamPlayIsOn()) return;
	//if not addressed to this bot
	if (!BotAddressedToBot(bs, match)) return;
	//get the patrol waypoints
	if (!BotGetPatrolWaypoints(bs, match)) return;
	//
	BotMatchVariable(match, NETNAME, netname, sizeof(netname));
	//
	playernum = FindPlayerByName(netname);
	//
	bs->decisionmaker = playernum;
	bs->ordered = qtrue;
	bs->order_time = FloatTime();
	//set the time to send a message to the team mates
	bs->teammessage_time = FloatTime() + 2 * random();
	//set the ltg type
	bs->ltgtype = LTG_PATROL;
	//get the team goal time
	bs->teamgoal_time = BotGetTime(match);
	//set the team goal time if not set already
	if (!bs->teamgoal_time) bs->teamgoal_time = FloatTime() + TEAM_PATROL_TIME;
	//
	BotSetTeamStatus(bs);
	// remember last ordered task
	BotRememberLastOrderedTask(bs);
	BotPrintTeamGoal(bs);
}
Ejemplo n.º 4
0
void BotMatch_NewLeader(bot_state_t *bs, bot_match_t *match) {
	int playernum;
	char netname[MAX_NETNAME];

	BotMatchVariable(match, NETNAME, netname, sizeof(netname));
	playernum = FindPlayerByName(netname);
	if (!BotSameTeam(bs, playernum))
		return;
	Q_strncpyz(bs->teamleader, netname, sizeof(bs->teamleader));
}
Ejemplo n.º 5
0
/*
==================
BotMatch_StopTeamLeaderShip
==================
*/
void BotMatch_StopTeamLeaderShip(bot_state_t *bs, bot_match_t *match) {
	int playernum;
	char teammate[MAX_MESSAGE_SIZE];
	char netname[MAX_MESSAGE_SIZE];

	if (!TeamPlayIsOn()) return;
	//get the team mate that stops being the team leader
	BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate));
	//if chats for him or herself
	if (match->subtype & ST_I) {
		BotMatchVariable(match, NETNAME, netname, sizeof(netname));
		playernum = FindPlayerByName(netname);
	}
	//chats for someone else
	else {
		playernum = FindPlayerByName(teammate);
	} //end else
	if (playernum >= 0) {
		if (!Q_stricmp(bs->teamleader, PlayerName(playernum, netname, sizeof(netname)))) {
			bs->teamleader[0] = '\0';
			notleader[playernum] = qtrue;
		}
	}
}
Ejemplo n.º 6
0
void BotMatch_EnterGame(bot_state_t *bs, bot_match_t *match) {
	int playernum;
	char netname[MAX_NETNAME];
	//char buf[MAX_SAY_TEXT];

	BotMatchVariable(match, NETNAME, netname, sizeof(netname));
	playernum = FindPlayerByName(netname);
	if (playernum >= 0) {
		notleader[playernum] = qfalse;
	}
	//NOTE: eliza chats will catch this
	//if (playernum != bs->playernum) {
	//	Com_sprintf(buf, sizeof(buf), "heya %s", netname);
	//	EA_Say(bs->playernum, buf);
	//}
}
Ejemplo n.º 7
0
/*
==================
BotMatch_GetFlag
==================
*/
void BotMatch_GetFlag(bot_state_t *bs, bot_match_t *match) {
	char netname[MAX_MESSAGE_SIZE];
	int playernum;

	if (gametype == GT_CTF) {
		if (!ctf_redflag.areanum || !ctf_blueflag.areanum)
			return;
	}
#ifdef MISSIONPACK
	else if (gametype == GT_1FCTF) {
		if (!ctf_neutralflag.areanum || !ctf_redflag.areanum || !ctf_blueflag.areanum)
			return;
	}
#endif
	else {
		return;
	}
	//if not addressed to this bot
	if (!BotAddressedToBot(bs, match)) return;
	//
	BotMatchVariable(match, NETNAME, netname, sizeof(netname));
	//
	playernum = FindPlayerByName(netname);
	//
	bs->decisionmaker = playernum;
	bs->ordered = qtrue;
	bs->order_time = FloatTime();
	//set the time to send a message to the team mates
	bs->teammessage_time = FloatTime() + 2 * random();
	//set the ltg type
	bs->ltgtype = LTG_GETFLAG;
	//set the team goal time
	bs->teamgoal_time = FloatTime() + CTF_GETFLAG_TIME;
	// get an alternate route in ctf
	if (gametype == GT_CTF) {
		//get an alternative route goal towards the enemy base
		BotGetAlternateRouteGoal(bs, BotOppositeTeam(bs));
	}
	//
	BotSetTeamStatus(bs);
	// remember last ordered task
	BotRememberLastOrderedTask(bs);
	BotPrintTeamGoal(bs);
}
Ejemplo n.º 8
0
/*
==================
BotMatch_StartTeamLeaderShip
==================
*/
void BotMatch_StartTeamLeaderShip(bot_state_t *bs, bot_match_t *match) {
	int playernum;
	char teammate[MAX_MESSAGE_SIZE];

	if (!TeamPlayIsOn()) return;
	//if chats for him or herself
	if (match->subtype & ST_I) {
		//get the team mate that will be the team leader
		BotMatchVariable(match, NETNAME, teammate, sizeof(teammate));
		strncpy(bs->teamleader, teammate, sizeof(bs->teamleader));
		bs->teamleader[sizeof(bs->teamleader)-1] = '\0';
	}
	//chats for someone else
	else {
		//get the team mate that will be the team leader
		BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate));
		playernum = FindPlayerByName(teammate);
		if (playernum >= 0) PlayerName(playernum, bs->teamleader, sizeof(bs->teamleader));
	}
}
Ejemplo n.º 9
0
/*
==================
BotMatch_AttackEnemyBase
==================
*/
void BotMatch_AttackEnemyBase(bot_state_t *bs, bot_match_t *match) {
	char netname[MAX_MESSAGE_SIZE];
	int playernum;

	if (gametype == GT_CTF) {
		BotMatch_GetFlag(bs, match);
	}
#ifdef MISSIONPACK
	else if (gametype == GT_1FCTF || gametype == GT_OBELISK || gametype == GT_HARVESTER) {
		if (!redobelisk.areanum || !blueobelisk.areanum)
			return;
	}
#endif
	else {
		return;
	}
	//if not addressed to this bot
	if (!BotAddressedToBot(bs, match)) return;
	//
	BotMatchVariable(match, NETNAME, netname, sizeof(netname));
	//
	playernum = FindPlayerByName(netname);
	//
	bs->decisionmaker = playernum;
	bs->ordered = qtrue;
	bs->order_time = FloatTime();
	//set the time to send a message to the team mates
	bs->teammessage_time = FloatTime() + 2 * random();
	//set the ltg type
	bs->ltgtype = LTG_ATTACKENEMYBASE;
	//set the team goal time
	bs->teamgoal_time = FloatTime() + TEAM_ATTACKENEMYBASE_TIME;
	bs->attackaway_time = 0;
	//
	BotSetTeamStatus(bs);
	// remember last ordered task
	BotRememberLastOrderedTask(bs);
	BotPrintTeamGoal(bs);
}
Ejemplo n.º 10
0
/*
==================
BotMatch_RushBase
==================
*/
void BotMatch_RushBase(bot_state_t *bs, bot_match_t *match) {
	char netname[MAX_MESSAGE_SIZE];
	int playernum;

	if (gametype == GT_CTF) {
		if (!ctf_redflag.areanum || !ctf_blueflag.areanum)
			return;
	}
#ifdef MISSIONPACK
	else if (gametype == GT_1FCTF || gametype == GT_HARVESTER) {
		if (!redobelisk.areanum || !blueobelisk.areanum)
			return;
	}
#endif
	else {
		return;
	}
	//if not addressed to this bot
	if (!BotAddressedToBot(bs, match)) return;
	//
	BotMatchVariable(match, NETNAME, netname, sizeof(netname));
	//
	playernum = FindPlayerByName(netname);
	//
	bs->decisionmaker = playernum;
	bs->ordered = qtrue;
	bs->order_time = FloatTime();
	//set the time to send a message to the team mates
	bs->teammessage_time = FloatTime() + 2 * random();
	//set the ltg type
	bs->ltgtype = LTG_RUSHBASE;
	//set the team goal time
	bs->teamgoal_time = FloatTime() + CTF_RUSHBASE_TIME;
	bs->rushbaseaway_time = 0;
	//
	BotSetTeamStatus(bs);
	BotPrintTeamGoal(bs);
}
Ejemplo n.º 11
0
/*
 * CommandGetPlayer: "getplayer" command
 */
void CommandGetPlayer(char *args)
{
   ID player;
   char temp[MAXAMOUNT + 1];

   if (*args == 0)
      return;

   player = FindPlayerByName(args);
   if (player == 0)
   {
      GameMessage(GetString(hInst, IDS_NOPLAYERNAME));
      return;
   }

   if (player == INVALID_ID)
   {
      GameMessage(GetString(hInst, IDS_DUPLICATEPLAYERNAME));
      return;
   }

   sprintf(temp, "%d", player);
   RequestDMCommand(DM_GET_PLAYER, temp);
}
Ejemplo n.º 12
0
/*
 * GetPlayerName:  Parse str, and return a pointer to the start of the first
 *   player name in it, or NULL if there is none in str.
 *   If next is non-NULL and we find a player name, fill next with 
 *   a pointer to the position in str just after the end of the first player name.
 *   str and *next can be identical.
 *   Modifies str by null terminating player name.
 */
char *GetPlayerName(char *str, char **next)
{
   char *ptr, *retval, *last_ptr;
   Bool quoted = False;
   Bool ambiguous = False;

   if (str == NULL)
      return NULL;

   // Skip separators
   while (*str == ' ' || *str == ',')
      str++;

   if (*str == 0)
      return NULL;

   // See if name is quoted
   if (*str == '\"')
   {
      quoted = True;
      retval = str + 1;
   }
   else retval = str;

   ptr = retval;
   last_ptr = NULL;

   // Skip to end of name and null terminate
   do
   {
      if (quoted)
      {
	 while (*ptr != '\"' && *ptr != 0)
	    ptr++;
      }
      else
      {
	 while (*ptr != ' ' && *ptr != ',' && *ptr != 0)
	    ptr++;
      }
      
      if (*ptr == '\0')
      {
	 if (next != NULL)
	    *next = NULL;
	 break;
      }
      else
      {
	 if (next != NULL)
   	    *next = ptr + 1;

	 // Null terminate player name
	 *ptr = '\0';
      }

      if (!quoted)
      {
	 // if we're not quoted
	 //
	 Bool wasambiguous = ambiguous;
	 ambiguous = (INVALID_ID == FindPlayerByName(retval));
	 if (ambiguous)
	 {
	    // restore player name and try again by appending next word
	    last_ptr = ptr;
	    *ptr++ = ' ';
	 }
	 else if (wasambiguous)
	 {
	    // String was ambiguous but now it's not.
	    break;
	 }
      }

   } while (ambiguous);

   // If we ran out of words before resolving ambiguity, remove the last word;
   // the caller may need it.
   if (ambiguous)
   {
      if (last_ptr == NULL)
	 debug(("GetPlayerName found ambiguous name in bad case\n"));
      else 
      {
	 *last_ptr = 0;
	 if (next != NULL)
	    *next = last_ptr + 1;
      }
   }

   return retval;
}
Ejemplo n.º 13
0
/*
==================
BotMatch_Camp
==================
*/
void BotMatch_Camp(bot_state_t *bs, bot_match_t *match) {
	int playernum, areanum;
	char netname[MAX_MESSAGE_SIZE];
	char itemname[MAX_MESSAGE_SIZE];
	aas_entityinfo_t entinfo;

	if (!TeamPlayIsOn()) return;
	//if not addressed to this bot
	if (!BotAddressedToBot(bs, match)) return;
	//
	BotMatchVariable(match, NETNAME, netname, sizeof(netname));
	//asked for someone else
	playernum = FindPlayerByName(netname);
	//if there's no valid player with this name
	if (playernum < 0) {
		BotAI_BotInitialChat(bs, "whois", netname, NULL);
		BotEnterChat(bs->cs, bs->playernum, CHAT_TEAM);
		return;
	}
	//get the match variable
	BotMatchVariable(match, KEYAREA, itemname, sizeof(itemname));
	//in CTF it could be the base
	if (match->subtype & ST_THERE) {
		//camp at the spot the bot is currently standing
		bs->teamgoal.entitynum = bs->entitynum;
		bs->teamgoal.areanum = bs->areanum;
		VectorCopy(bs->origin, bs->teamgoal.origin);
		VectorSet(bs->teamgoal.mins, -8, -8, -8);
		VectorSet(bs->teamgoal.maxs, 8, 8, 8);
	}
	else if (match->subtype & ST_HERE) {
		//if this is the bot self
		if (playernum == bs->playernum) return;
		//
		bs->teamgoal.entitynum = -1;
		BotEntityInfo(playernum, &entinfo);
		//if info is valid (in PVS)
		if (entinfo.valid) {
			areanum = BotPointAreaNum(entinfo.origin);
			if (areanum) {// && trap_AAS_AreaReachability(areanum)) {
				//NOTE: just assume the bot knows where the person is
				//if (BotEntityVisible(bs->entitynum, bs->eye, bs->viewangles, 360, playernum)) {
					bs->teamgoal.entitynum = playernum;
					bs->teamgoal.areanum = areanum;
					VectorCopy(entinfo.origin, bs->teamgoal.origin);
					VectorSet(bs->teamgoal.mins, -8, -8, -8);
					VectorSet(bs->teamgoal.maxs, 8, 8, 8);
				//}
			}
		}
		//if the other is not visible
		if (bs->teamgoal.entitynum < 0) {
			BotAI_BotInitialChat(bs, "whereareyou", netname, NULL);
			playernum = PlayerFromName(netname);
			BotEnterChat(bs->cs, playernum, CHAT_TELL);
			return;
		}
	}
	else if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) {
		//BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL);
		//playernum = PlayerFromName(netname);
		//BotEnterChat(bs->cs, playernum, CHAT_TELL);
		return;
	}
	//
	bs->decisionmaker = playernum;
	bs->ordered = qtrue;
	bs->order_time = FloatTime();
	//set the time to send a message to the team mates
	bs->teammessage_time = FloatTime() + 2 * random();
	//set the ltg type
	bs->ltgtype = LTG_CAMPORDER;
	//get the team goal time
	bs->teamgoal_time = BotGetTime(match);
	//set the team goal time
	if (!bs->teamgoal_time) bs->teamgoal_time = FloatTime() + TEAM_CAMP_TIME;
	//not arrived yet
	bs->arrive_time = 0;
	//
	BotSetTeamStatus(bs);
	// remember last ordered task
	BotRememberLastOrderedTask(bs);
	BotPrintTeamGoal(bs);
}
Ejemplo n.º 14
0
/*
==================
BotMatch_HelpAccompany
==================
*/
void BotMatch_HelpAccompany(bot_state_t *bs, bot_match_t *match) {
	int playernum, other, areanum;
	char teammate[MAX_MESSAGE_SIZE];
	char netname[MAX_MESSAGE_SIZE];
	char itemname[MAX_MESSAGE_SIZE];
	bot_match_t teammatematch;
	aas_entityinfo_t entinfo;

	if (!TeamPlayIsOn()) return;
	//if not addressed to this bot
	if (!BotAddressedToBot(bs, match)) return;
	//get the team mate name
	BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate));
	//get the player to help
	if (BotFindMatch(teammate, &teammatematch, MTCONTEXT_TEAMMATE) &&
			//if someone asks for him or herself
			teammatematch.type == MSG_ME) {
		//get the netname
		BotMatchVariable(match, NETNAME, netname, sizeof(netname));
		playernum = PlayerFromName(netname);
		other = qfalse;
	}
	else {
		//asked for someone else
		playernum = FindPlayerByName(teammate);
		//if this is the bot self
		if (playernum == bs->playernum) {
			other = qfalse;
		}
		else if (!BotSameTeam(bs, playernum)) {
			//FIXME: say "I don't help the enemy"
			return;
		}
		else {
			other = qtrue;
		}
	}
	//if the bot doesn't know who to help (FindPlayerByName returned -1)
	if (playernum < 0) {
		if (other) BotAI_BotInitialChat(bs, "whois", teammate, NULL);
		else BotAI_BotInitialChat(bs, "whois", netname, NULL);
		playernum = PlayerFromName(netname);
		BotEnterChat(bs->cs, playernum, CHAT_TELL);
		return;
	}
	//don't help or accompany yourself
	if (playernum == bs->playernum) {
		return;
	}
	//
	bs->teamgoal.entitynum = -1;
	BotEntityInfo(playernum, &entinfo);
	//if info is valid (in PVS)
	if (entinfo.valid) {
		areanum = BotPointAreaNum(entinfo.origin);
		if (areanum) {// && trap_AAS_AreaReachability(areanum)) {
			bs->teamgoal.entitynum = playernum;
			bs->teamgoal.areanum = areanum;
			VectorCopy(entinfo.origin, bs->teamgoal.origin);
			VectorSet(bs->teamgoal.mins, -8, -8, -8);
			VectorSet(bs->teamgoal.maxs, 8, 8, 8);
		}
	}
	//if no teamgoal yet
	if (bs->teamgoal.entitynum < 0) {
		//if near an item
		if (match->subtype & ST_NEARITEM) {
			//get the match variable
			BotMatchVariable(match, ITEM, itemname, sizeof(itemname));
			//
			if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) {
				//BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL);
				//BotEnterChat(bs->cs, bs->playernum, CHAT_TEAM);
				return;
			}
		}
	}
	//
	if (bs->teamgoal.entitynum < 0) {
		if (other) BotAI_BotInitialChat(bs, "whereis", teammate, NULL);
		else BotAI_BotInitialChat(bs, "whereareyou", netname, NULL);
		playernum = PlayerFromName(netname);
		BotEnterChat(bs->cs, playernum, CHAT_TEAM);
		return;
	}
	//the team mate
	bs->teammate = playernum;
	//
	BotMatchVariable(match, NETNAME, netname, sizeof(netname));
	//
	playernum = PlayerFromName(netname);
	//the team mate who ordered
	bs->decisionmaker = playernum;
	bs->ordered = qtrue;
	bs->order_time = FloatTime();
	//last time the team mate was assumed visible
	bs->teammatevisible_time = FloatTime();
	//set the time to send a message to the team mates
	bs->teammessage_time = FloatTime() + 2 * random();
	//get the team goal time
	bs->teamgoal_time = BotGetTime(match);
	//set the ltg type
	if (match->type == MSG_HELP) {
		bs->ltgtype = LTG_TEAMHELP;
		if (!bs->teamgoal_time) bs->teamgoal_time = FloatTime() + TEAM_HELP_TIME;
	}
	else {
		bs->ltgtype = LTG_TEAMACCOMPANY;
		if (!bs->teamgoal_time) bs->teamgoal_time = FloatTime() + TEAM_ACCOMPANY_TIME;
		bs->formation_dist = 128;
		bs->arrive_time = 0;
		//
		BotSetTeamStatus(bs);
		// remember last ordered task
		BotRememberLastOrderedTask(bs);
	}
	BotPrintTeamGoal(bs);
}
Ejemplo n.º 15
0
/*
==================
BotMatch_LeadTheWay
==================
*/
void BotMatch_LeadTheWay(bot_state_t *bs, bot_match_t *match) {
	aas_entityinfo_t entinfo;
	char netname[MAX_MESSAGE_SIZE], teammate[MAX_MESSAGE_SIZE];
	int playernum, areanum, other;

	if (!TeamPlayIsOn()) return;
	//if not addressed to this bot
	if (!BotAddressedToBot(bs, match)) return;
	//if someone asks for someone else
	if (match->subtype & ST_SOMEONE) {
		//get the team mate name
		BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate));
		playernum = FindPlayerByName(teammate);
		//if this is the bot self
		if (playernum == bs->playernum) {
			other = qfalse;
		}
		else if (!BotSameTeam(bs, playernum)) {
			//FIXME: say "I don't help the enemy"
			return;
		}
		else {
			other = qtrue;
		}
	}
	else {
		//get the netname
		BotMatchVariable(match, NETNAME, netname, sizeof(netname));
		playernum = PlayerFromName(netname);
		other = qfalse;
	}
	//if the bot doesn't know who to help (FindPlayerByName returned -1)
	if (playernum < 0) {
		BotAI_BotInitialChat(bs, "whois", netname, NULL);
		BotEnterChat(bs->cs, bs->playernum, CHAT_TEAM);
		return;
	}
	//
	bs->lead_teamgoal.entitynum = -1;
	BotEntityInfo(playernum, &entinfo);
	//if info is valid (in PVS)
	if (entinfo.valid) {
		areanum = BotPointAreaNum(entinfo.origin);
		if (areanum) { // && trap_AAS_AreaReachability(areanum)) {
			bs->lead_teamgoal.entitynum = playernum;
			bs->lead_teamgoal.areanum = areanum;
			VectorCopy(entinfo.origin, bs->lead_teamgoal.origin);
			VectorSet(bs->lead_teamgoal.mins, -8, -8, -8);
			VectorSet(bs->lead_teamgoal.maxs, 8, 8, 8);
		}
	}

	if (bs->teamgoal.entitynum < 0) {
		if (other) BotAI_BotInitialChat(bs, "whereis", teammate, NULL);
		else BotAI_BotInitialChat(bs, "whereareyou", netname, NULL);
		BotEnterChat(bs->cs, bs->playernum, CHAT_TEAM);
		return;
	}
	bs->lead_teammate = playernum;
	bs->lead_time = FloatTime() + TEAM_LEAD_TIME;
	bs->leadvisible_time = 0;
	bs->leadmessage_time = -(FloatTime() + 2 * random());
}