Esempio n. 1
0
void PrintMenuHead()
{
	printf("\x1B[J\n\n");
	if(started)
		CenterPrint("PAUSED");
	else
		CenterPrint("MENU");
	printf("\n\n");
}
Esempio n. 2
0
//=========================================================================
// Think function for the timer which checks the distance between the 
// Engineer and the building he's using
void CheckDistance(  )
{
    vec3_t dist;
    gedict_t *owner, *enemy;

    owner = PROG_TO_EDICT( self->s.v.owner );
    enemy = PROG_TO_EDICT( self->s.v.enemy );
    // Check to see if the Engineer's spanner'ed a different building 
    // without leaving the area of this one.
    if ( owner->building != enemy )
    {
	dremove( self );
	return;
    }

    VectorSubtract( enemy->s.v.origin, owner->s.v.origin, dist );
    if ( vlen( dist ) > 64 )
    {
	CenterPrint( owner, "\n" );
	owner->menu_count = MENU_REFRESH_RATE;
	owner->current_menu = MENU_DEFAULT;
	owner->building = world;
	dremove( self );
	return;
    }
    self->s.v.nextthink = g_globalvars.time + 0.3;
}
Esempio n. 3
0
//=========================================================================
// Dispenser Touch function. Allows players to get stuff from the Dispenser.
void T_Dispenser(  )
{
    gedict_t *dist_checker;

    if ( strneq( other->s.v.classname, "player" ) )
	return;

    if ( other->team_no && !TeamFortress_isTeamsAllied (other->team_no , self->team_no) )
	CenterPrint( self->real_owner, "Enemies are using your dispenser!\n" );

    // Ignore any engineer working on this dispenser	
    if ( ( !other->building || other->building == world ) && other->building_wait < g_globalvars.time )
    {
        // Pop up the menu
	other->current_menu = MENU_DISPENSER;
	other->menu_count = MENU_REFRESH_RATE;

	other->building = self;

        // Start a Distance checker, which removes the menu if the player
	// gets too far away from the Dispenser.
	dist_checker = spawn(  );
	dist_checker->s.v.classname = "timer";
	dist_checker->s.v.owner = EDICT_TO_PROG( other );
	dist_checker->s.v.enemy = EDICT_TO_PROG( self );
	dist_checker->s.v.think = ( func_t ) CheckDistance;
	dist_checker->s.v.nextthink = g_globalvars.time + 0.3;
    }
}
Esempio n. 4
0
// Message handler for text messages
// displays a string, looking them up from the titles.txt file, which can be localised
// parameters:
//   byte:   message direction  ( HUD_PRINTCONSOLE, HUD_PRINTNOTIFY, HUD_PRINTCENTER, HUD_PRINTTALK )
//   string: message
// optional parameters:
//   string: message parameter 1
//   string: message parameter 2
//   string: message parameter 3
//   string: message parameter 4
// any string that starts with the character '#' is a message name, and is used to look up the real message in titles.txt
// the next (optional) one to four strings are parameters for that string (which can also be message names if they begin with '#')
int CHudTextMessage::MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf )
{
	int destination;
	StringList message;
	NetMsg_TextMsg( pbuf, iSize, destination, message );
 
	if ( gViewPort && gViewPort->AllowedToPrintText() == FALSE )
		return 1;

	while( message.size() < 5 )
	{ message.push_back( string("") ); }
	char psz[1024];

	char* origin = psz;
	if( destination == HUD_PRINTNOTIFY )
	{ 
		psz[0] = 1;
		origin = psz + 1;
	}

	// Ensure that message[0] does not contain exessive %'s, max 4x%s, all other %'s removed.
	size_t lastpos = 0; size_t pos; int count = 0;
	while(true)
	{
		pos = message[0].find("%", lastpos);

		if (pos == string::npos)
			break;

		if ((message[0].substr(pos + 1, 1) == "s") && (count < 4))
			count++;
		else
			message[0].replace(pos, 1, " ");

		lastpos = pos + 1;
	}

	sprintf( origin, message[0].c_str(), message[1].c_str(), message[2].c_str(), message[3].c_str(), message[4].c_str() );
	ConvertCRtoNL(psz);

	switch ( destination )
	{
	case HUD_PRINTNOTIFY:
	case HUD_PRINTCONSOLE:
		ConsolePrint(psz);
		break;
	case HUD_PRINTCENTER:
		CenterPrint(psz);
		break;
	case HUD_PRINTTALK:
		gHUD.m_SayText.SayTextPrint(psz, 1024);
		break;
	}

	return 1;
}
Esempio n. 5
0
// Message handler for text messages
// displays a string, looking them up from the titles.txt file, which can be localised
// parameters:
//   byte:   message direction  ( HUD_PRINTCONSOLE, HUD_PRINTNOTIFY, HUD_PRINTCENTER, HUD_PRINTTALK )
//   string: message
// optional parameters:
//   string: message parameter 1
//   string: message parameter 2
//   string: message parameter 3
//   string: message parameter 4
// any string that starts with the character '#' is a message name, and is used to look up the real message in titles.txt
// the next (optional) one to four strings are parameters for that string (which can also be message names if they begin with '#')
int CHudTextMessage::MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf )
{
	BEGIN_READ( pbuf, iSize );

	int msg_dest = READ_BYTE();

#define MSG_BUF_SIZE 128
	static char szBuf[6][MSG_BUF_SIZE];
	char *msg_text = LookupString( READ_STRING(), &msg_dest );
	msg_text = safe_strcpy( szBuf[0], msg_text , MSG_BUF_SIZE);

	// keep reading strings and using C format strings for subsituting the strings into the localised text string
	char *sstr1 = LookupString( READ_STRING() );
	sstr1 = safe_strcpy( szBuf[1], sstr1 , MSG_BUF_SIZE);
	StripEndNewlineFromString( sstr1 );  // these strings are meant for subsitution into the main strings, so cull the automatic end newlines
	char *sstr2 = LookupString( READ_STRING() );
	sstr2 = safe_strcpy( szBuf[2], sstr2 , MSG_BUF_SIZE);
	StripEndNewlineFromString( sstr2 );
	char *sstr3 = LookupString( READ_STRING() );
	sstr3 = safe_strcpy( szBuf[3], sstr3 , MSG_BUF_SIZE);
	StripEndNewlineFromString( sstr3 );
	char *sstr4 = LookupString( READ_STRING() );
	sstr4 = safe_strcpy( szBuf[4], sstr4 , MSG_BUF_SIZE);
	StripEndNewlineFromString( sstr4 );
	char *psz = szBuf[5];

	if ( gViewPort && gViewPort->AllowedToPrintText() == FALSE )
		return 1;

	switch ( msg_dest )
	{
	case HUD_PRINTCENTER:
		safe_sprintf( psz, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 );
		CenterPrint( ConvertCRtoNL( psz ) );
		break;

	case HUD_PRINTNOTIFY:
		psz[0] = 1;  // mark this message to go into the notify buffer
		safe_sprintf( psz+1, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 );
		ConsolePrint( ConvertCRtoNL( psz ) );
		break;

	case HUD_PRINTTALK:
		safe_sprintf( psz, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 );
		gHUD.m_SayText.SayTextPrint( ConvertCRtoNL( psz ), 128 );
		break;

	case HUD_PRINTCONSOLE:
		safe_sprintf( psz, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 );
		ConsolePrint( ConvertCRtoNL( psz ) );
		break;
	}

	return 1;
}
Esempio n. 6
0
void Bot::Kick (void)
{
   // this function kick off one bot from the server.

   ServerCommand ("kick #%d", GETPLAYERUSERID (GetEntity ()));
   CenterPrint ("Bot '%s' kicked", STRING (pev->netname));

   // balances quota
   if (g_botManager->GetBotsNum () - 1 < yb_quota.GetInt ())
      yb_quota.SetInt (g_botManager->GetBotsNum () - 1);
}
Esempio n. 7
0
void BotControl::FillServer (int selection, int personality, int skill, int numToAdd)
{
   // this function fill server with bots, with specified team & personality

   if (GetBotsNum () >= engine->GetMaxClients () - GetHumansNum ())
      return;

   if (selection == 1 || selection == 2)
   {
      CVAR_SET_STRING ("mp_limitteams", "0");
      CVAR_SET_STRING ("mp_autoteambalance", "0");
   }
   else
      selection = 5;

   char teamDescs[6][12] =
   {
      "",
      {"Terrorists"},
      {"CTs"},
      "",
      "",
      {"Random"},
   };

   int toAdd = numToAdd == -1 ? engine->GetMaxClients () - (GetHumansNum () + GetBotsNum ()) : numToAdd;

   for (int i = 0; i <= toAdd; i++)
   {
      // since we got constant skill from menu (since creation process call automatic), we need to manually
      // randomize skill here, on given skill there.
      int randomizedSkill = 0;

      if (skill >= 0 && skill <= 20)
         randomizedSkill = engine->RandomInt (0, 20);
      else if (skill >= 20 && skill <= 40)
         randomizedSkill = engine->RandomInt (20, 40);
      else if (skill >= 40 && skill <= 60)
         randomizedSkill = engine->RandomInt (40, 60);
      else if (skill >= 60 && skill <= 80)
         randomizedSkill = engine->RandomInt (60, 80);
      else if (skill >= 80 && skill <= 99)
         randomizedSkill = engine->RandomInt (80, 99);
      else if (skill == 100)
         randomizedSkill = skill;

      AddBot ("", randomizedSkill, personality, selection, -1);
   }

   yb_quota.SetInt (toAdd);
   CenterPrint ("Fill Server with %s bots...", &teamDescs[selection][0]);
}
Esempio n. 8
0
void BotControl::SetWeaponMode (int selection)
{
   // this function sets bots weapon mode

   int tabMapStandart[7][Const_NumWeapons] =
   {
      {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // Knife only
      {-1,-1,-1, 2, 2, 0, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // Pistols only
      {-1,-1,-1,-1,-1,-1,-1, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // Shotgun only
      {-1,-1,-1,-1,-1,-1,-1,-1,-1, 2, 1, 2, 0, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 2,-1}, // Machine Guns only
      {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 1, 0, 1, 1,-1,-1,-1,-1,-1,-1}, // Rifles only
      {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 2, 2, 0, 1,-1,-1}, // Snipers only
      {-1,-1,-1, 2, 2, 0, 1, 2, 2, 2, 1, 2, 0, 2, 0, 0, 1, 0, 1, 1, 2, 2, 0, 1, 2, 1}  // Standard
   };

   int tabMapAS[7][Const_NumWeapons] =
   {
      {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // Knife only
      {-1,-1,-1, 2, 2, 0, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // Pistols only
      {-1,-1,-1,-1,-1,-1,-1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // Shotgun only
      {-1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 0, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1}, // Machine Guns only
      {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0,-1, 1, 0, 1, 1,-1,-1,-1,-1,-1,-1}, // Rifles only
      {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0,-1, 1,-1,-1}, // Snipers only
      {-1,-1,-1, 2, 2, 0, 1, 1, 1, 1, 1, 1, 0, 2, 0,-1, 1, 0, 1, 1, 0, 0,-1, 1, 1, 1}  // Standard
   };

   char modeName[7][12] =
   {
      {"Knife"},
      {"Pistol"},
      {"Shotgun"},
      {"Machine Gun"},
      {"Rifle"},
      {"Sniper"},
      {"Standard"}
   };
   selection--;

   for (int i = 0; i < Const_NumWeapons; i++)
   {
      g_weaponSelect[i].teamStandard = tabMapStandart[selection][i];
      g_weaponSelect[i].teamAS = tabMapAS[selection][i];
   }

   if (selection == 0)
      yb_knifemode.SetInt (1);
   else
      yb_knifemode.SetInt (0);

   CenterPrint ("%s weapon mode selected", &modeName[selection][0]);
}
Esempio n. 9
0
void BotControl::KillAll (int team)
{
   // this function kills all bots on server (only this dll controlled bots)

   for (int i = 0; i < engine->GetMaxClients (); i++)
   {
      if (m_bots[i] != null)
      {
         if (team != -1 && team != GetTeam (m_bots[i]->GetEntity ()))
            continue;

         m_bots[i]->Kill ();
      }
   }
   CenterPrint ("All bots are killed.");
}
Esempio n. 10
0
void BotControl::RemoveAll (void)
{
   // this function drops all bot clients from server (this function removes only yapb's)`q

   CenterPrint ("Bots are removed from server.");

   for (int i = 0; i < engine->GetMaxClients (); i++)
   {
      if (m_bots[i] != null)  // is this slot used?
         m_bots[i]->Kick ();
   }
   m_creationTab.RemoveAll ();

   // reset cvars
   yb_quota.SetInt (0);
   yb_autovacate.SetInt (0);
}
Esempio n. 11
0
//=========================================================================
// Function handling the Engineer's build impulse
void TeamFortress_EngineerBuild(  )
{
    gedict_t *te;

/*    if ( !( ( int ) self->s.v.flags & FL_ONGROUND ) )
    {
	CenterPrint( self, "You can't build in the air!\n\n" );
	return;
    }*/
    // Pop up the menu
    if ( !self->is_building )
    {
        if(!tg_data.tg_enabled)
        {
        	if ( self->s.v.ammo_cells < 100 && !self->has_dispenser && !self->has_sentry )
        	{
        	    CenterPrint( self, "You don't have enough metal to \nbuild anything.\n\n" );
        	    return;
        	}
        }
	self->current_menu = MENU_ENGINEER;
	self->menu_count = MENU_REFRESH_RATE;
    } else
    {
//	if ( self->is_building == 1 )
//	{
	    G_sprint( self, 2, "You stop building.\n" );
	    self->tfstate = self->tfstate - ( self->tfstate & TFSTATE_CANT_MOVE );
	    TeamFortress_SetSpeed( self );
	    // Remove the timer
	    for ( te = world; (te = trap_find( te, FOFS( s.v.netname ), "build_timer" )); )
	    {
		if ( te->s.v.owner == EDICT_TO_PROG( self ) )
		{
		    dremove( te );
		    break;
		}
	    }
	    self->is_building = 0;
	    self->current_weapon = self->s.v.weapon;
	    W_SetCurrentAmmo(  );
//	}
    }
}
Esempio n. 12
0
void DestroyBuilding( gedict_t * eng, char *bld )
{
    gedict_t *te;
    gedict_t *oldself;
    float pos;

    for ( te = world; (te = trap_find( te, FOFS( s.v.classname ), bld )); )
    {
	if ( te->real_owner == eng )
	{
	    pos = trap_pointcontents( PASSVEC3( te->s.v.origin ) );
	    if ( pos == CONTENT_SOLID || pos == CONTENT_SKY )
	    {
		oldself = self;
		self = eng;
		self->s.v.ammo_cells = self->s.v.ammo_cells + 100;
		bound_other_ammo( self );
		W_SetCurrentAmmo(  );
		self = oldself;
	    }
	    if ( te->real_owner->building == te )
	    {
		if ( !te->real_owner->StatusBarSize )
		    CenterPrint( te->real_owner, "\n" );
		else
		    te->real_owner->StatusRefreshTime = g_globalvars.time + 0.1;
		te->real_owner->menu_count = MENU_REFRESH_RATE;
		te->real_owner->current_menu = MENU_DEFAULT;
		te->real_owner->building = world;
	    }
          if( tg_data.tg_enabled )
	    	te->has_sentry = 0;
	    TF_T_Damage( te, world, world, 500, 0, 0 );
	}
    }
}
Esempio n. 13
0
int BotControl::CreateBot (String name, int skill, int personality, int team, int member)
{
   // this function completely prepares bot entity (edict) for creation, creates team, skill, sets name etc, and
   // then sends result to bot constructor

   edict_t *bot = null;
   char outputName[33];

   if (g_numWaypoints < 1) // don't allow creating bots with no waypoints loaded
   {
      CenterPrint ("Map not waypointed. Can't Create Bot");
      return 0;
   }
   else if (g_waypointsChanged) // don't allow creating bots with changed waypoints (distance tables are messed up)
   {
      CenterPrint ("Waypoints has been changed. Load waypoints again...");
      return 0;
   }


   if (skill < 0 || skill > 100)
      skill = engine->RandomInt (yb_minskill.GetInt (), yb_maxskill.GetInt ());

   if (skill > 100 || skill < 0)
      skill = engine->RandomInt (0, 100);

   if (personality < 0 || personality > 2)
   {
      int randomPrecent = engine->RandomInt (0, 100);

      if (randomPrecent < 50)
         personality = PERSONALITY_NORMAL;
      else
      {
         if (engine->RandomInt (0, randomPrecent) < randomPrecent * 0.5)
            personality = PERSONALITY_CAREFUL;
         else
            personality = PERSONALITY_RUSHER;
      }
   }

   // setup name
   if (name.IsEmpty ())
   {
      if (!g_botNames.IsEmpty ())
      {
         bool nameFound = false;

         for (int i = 0; i < 8; i++)
         {
            if (nameFound)
               break;

            NameItem &botName = g_botNames.GetRandomElement ();

            if (botName.isUsed)
               continue;

            botName.isUsed = nameFound = true;
            strcpy (outputName, botName.name);
         }
      }
      else
         sprintf (outputName, "bot%i", engine->RandomInt (0, 100)); // just pick ugly random name
   }
   else
      strncpy (outputName, name, 21);

   if (!IsNullString (yb_nameprefix.GetString ()) || yb_skilltags.GetBool ())
   {
      char prefixedName[33]; // temp buffer for storing modified name

      if (!IsNullString (yb_nameprefix.GetString ()))
         sprintf (prefixedName, "%s %s", yb_nameprefix.GetString (), outputName);

      else if (yb_skilltags.GetBool ())
         sprintf  (prefixedName, "%s (%d)", outputName, skill);

      else if (!IsNullString (yb_nameprefix.GetString ()) && yb_skilltags.GetBool ())
         sprintf  (prefixedName, "%s %s (%d)", yb_nameprefix.GetString (), outputName, skill);

      // buffer has been modified, copy to real name
      if (!IsNullString (prefixedName))
         sprintf (outputName, prefixedName);
   }

   if (FNullEnt ((bot = (*g_engfuncs.pfnCreateFakeClient) (outputName))))
   {
      CenterPrint ("Maximum players reached (%d/%d). Unable to create Bot.", engine->GetMaxClients (), engine->GetMaxClients ());
      return 2;
   }

   int index = ENTINDEX (bot) - 1;

   InternalAssert (index >= 0 && index <= 32); // check index
   InternalAssert (m_bots[index] == null); // check bot slot

   m_bots[index] = new Bot (bot, skill, personality, team, member);
 
   if (m_bots == null)
      TerminateOnMalloc ();

   if (engine->GetDeveloperLevel () > 0)
      ServerPrint ("Connecting '%s'... (Skill %d)", STRING (bot->v.netname), skill);
   else
      ServerPrint ("Connecting YaPB... (Skill %d)", skill);

   return 1;
}
Esempio n. 14
0
void CBaseDelay :: SUB_UseTargets( CBaseEntity *pActivator, USE_TYPE useType, float value )
{
	//
	// exit immediatly if we don't have a target or kill target or message
	//
	if (FStringNull(pev->target) && FStringNull(m_iszKillTarget) && FStringNull(pev->message))
		return;

	//
	// check for a delay
	//
	if (m_flDelay != 0)
	{
		// create a temp object to fire at a later time
		CBaseDelay *pTemp = GetClassPtr( (CBaseDelay *)NULL);
		pTemp->pev->classname = MAKE_STRING("DelayedUse");

		pTemp->pev->nextthink = gpGlobals->time + m_flDelay;

		pTemp->SetThink( &CBaseDelay::DelayThink );
		
		// Save the useType
		pTemp->pev->button = (int)useType;
		pTemp->m_iszKillTarget = m_iszKillTarget;
		pTemp->m_flDelay = 0; // prevent "recursion"
		pTemp->pev->target = pev->target;
		pTemp->m_hActivator = pActivator;

		return;
	}

	//
	// print the message
	//
	if (pActivator->IsPlayer() && !FStringNull( pev->message ))
	{
		CenterPrint( pActivator->pev, STRING( pev->message ));

		if(FStringNull( pev->noise ))
			EMIT_SOUND(ENT(pActivator->pev), CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
	}

	//
	// kill the killtargets
	//
	if ( m_iszKillTarget )
	{
		edict_t *pentKillTarget = NULL;

		ALERT( at_aiconsole, "KillTarget: %s\n", STRING(m_iszKillTarget) );
		pentKillTarget = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_iszKillTarget) );
		while ( !FNullEnt(pentKillTarget) )
		{
			UTIL_Remove( CBaseEntity::Instance(pentKillTarget) );

			ALERT( at_aiconsole, "killing %s\n", STRING( pentKillTarget->v.classname ) );
			pentKillTarget = FIND_ENTITY_BY_TARGETNAME( pentKillTarget, STRING(m_iszKillTarget) );
		}
	}
	
	//
	// fire targets
	//
	if (!FStringNull(pev->target))
	{
		FireTargets( STRING(pev->target), pActivator, this, useType, value );
	}
}
Esempio n. 15
0
void TeamFortress_Build( int objtobuild )
{
    float btime;

//      gedict_t *te;
    vec3_t tmp1;
    vec3_t tmp2;

    newmis = spawn(  );
    g_globalvars.newmis = EDICT_TO_PROG( newmis );

    // get an origin
    makevectors( self->s.v.v_angle );
    g_globalvars.v_forward[2] = 0;
    VectorNormalize( g_globalvars.v_forward );
    VectorScale( g_globalvars.v_forward, 64, g_globalvars.v_forward );
    VectorAdd( self->s.v.origin, g_globalvars.v_forward, newmis->s.v.origin );

    if ( objtobuild == BUILD_DISPENSER )
    {
        if( self->has_dispenser && !tg_data.tg_enabled)
	{
	    G_sprint( self, 2, "You can only have one dispenser.\nTry dismantling your old one.\n" );
	    return;
	}
	SetVector( tmp1, -8, -8, 0 );
	SetVector( tmp2, 8, 8, 24 );
//	newmis->mdl = "progs/disp.mdl";
	newmis->mdl = "progs/dispencr.mdl";		// megatf disp!
	newmis->s.v.netname = "dispenser";
	btime = g_globalvars.time + BUILD_TIME_DISPENSER;
	if( tg_data.tg_enabled )
		btime = g_globalvars.time;
    } else
    {
	if ( objtobuild == BUILD_SENTRYGUN )
	{
           if( self->has_sentry && !tg_data.tg_enabled)
	    {
		G_sprint( self, 2, "You can only have one sentry gun.\nTry dismantling your old one.\n" );
		return;
	    }
	    SetVector( tmp1, -16, -16, 0 );
	    SetVector( tmp2, 16, 16, 48 );
	    newmis->mdl = "progs/turrbase.mdl";
	    newmis->s.v.netname = "sentrygun";
	    btime = g_globalvars.time + BUILD_TIME_SENTRYGUN;
	    if( tg_data.tg_enabled )
	    	btime = g_globalvars.time;
	}else
	{
		G_Error("Unknown objtobuild in TeamFortress_Build\n");
		return;
	}

    }
    VectorCopy(tmp1,newmis->s.v.mins);
    VectorCopy(tmp2,newmis->s.v.maxs);
    // before we start building it, check it out
    // check for validity of point
    if ( !CheckArea( newmis, self ) )
    {
	G_sprint( self, 2, "Not enough room to build here\n" );
	dremove( newmis );
	return;
    }

    if ( !( ( int ) self->s.v.flags & FL_ONGROUND ) )
    {
	CenterPrint( self, "You can't build in the air!\n\n" );
	return;
    }
    self->is_building = 1;
    self->tfstate = self->tfstate | TFSTATE_CANT_MOVE;
    // Save the current weapon and remove it
    self->s.v.weapon = self->current_weapon;
    self->current_weapon = 0;
    self->s.v.weaponmodel = "";
    self->s.v.weaponframe = 0;

    TeamFortress_SetSpeed( self );
    newmis->s.v.owner = EDICT_TO_PROG( self );
    newmis->s.v.classname = "timer";
    newmis->s.v.netname = "build_timer";
    newmis->s.v.nextthink = btime;
    newmis->s.v.think = ( func_t ) TeamFortress_FinishedBuilding;
    newmis->s.v.colormap = self->s.v.colormap;
    newmis->s.v.weapon = objtobuild;
    newmis->s.v.angles[1] = anglemod( self->s.v.angles[1] + 180 );
    SetVector( newmis->s.v.velocity, 0, 0, 8 );
    newmis->s.v.movetype = MOVETYPE_TOSS;
    newmis->s.v.solid = SOLID_BBOX;
    setmodel( newmis, newmis->mdl );
    setsize( newmis, PASSVEC3( tmp1 ), PASSVEC3( tmp2 ) );
    setorigin( newmis, PASSVEC3( newmis->s.v.origin ) );
    newmis->s.v.flags = ( int ) newmis->s.v.flags - ( ( int ) newmis->s.v.flags & FL_ONGROUND );
}