Ejemplo n.º 1
0
CGameRules *InstallGameRules( void )
{
	SERVER_COMMAND( "exec game.rc\n" );
	g_engfuncs.pfnServerExecute();

	ALERT( at_aiconsole, "InstallGameRules\n" );

	if ( !gpGlobals->deathmatch )
	{
		// generic half-life
		g_teamplay = 0;
		return new CHalfLifeRules;
	}
	else
	{
		if( CVAR_GET_FLOAT( "mp_teamplay" ) > 0 )
		{
			// teamplay

			g_teamplay = 1;
			return new CHalfLifeTeamplay;
		}
		if ((int)gpGlobals->deathmatch == 1)
		{
			// vanilla deathmatch
			g_teamplay = 0;
			return new CHalfLifeMultiplay;
		}
		else
		{
			// vanilla deathmatch??
			g_teamplay = 0;
			return new CHalfLifeMultiplay;
		}
	}
}
// sets the round state
// ben notes : bSkipAutoRoundThink will avoid calling the round think function
// ben notes : after updating the status
void CBaseRoundRules::SetRoundState(ROUND_STATE iRoundState, bool bSkipAutoRoundThink)
{
	// check validity of what we have been sent
	if((iRoundState < ROUND_NOTSTARTED) || (iRoundState > ROUND_NOPLAYERS))
	{
		// - report the error
		ALERT(at_console, "Bad Round State being set - (%i)\n", (int)iRoundState);
		UTIL_LogPrintf(ROUND_LOGGING, "World triggered \"Bad Round State\" (round_state \"%i\") (old_round_state \"%i\")\n", (int)iRoundState, (int)m_iRoundState);

		// - give the round state a dummy value to keep it going
		iRoundState = ROUND_WAITING_FOR_PLAYERS;
	}
	// - log the change
	UTIL_LogPrintf(ALL_LOGGING, "World triggered \"Round State Change\" (round_state \"%i\") (old_round_state \"%i\")\n", (int)iRoundState, (int)m_iRoundState);

	// - set the round state
	m_iRoundState = iRoundState;

	// - call round think to update the round progress.
	// ben notes : after set round state is called we should leave the round think
	// ben notes : function or wierd bugs could creep in
	if(GetRoundState() != ROUND_NOPLAYERS && bSkipAutoRoundThink == false)
		this->RoundThink();
}
Ejemplo n.º 3
0
//=========================================================
// ********** DeadGenericMonster SPAWN **********
//=========================================================
void CDeadGenericMonster :: Spawn( void )
{
	Precache();
	SET_MODEL(ENT(pev), STRING(pev->model));

	pev->effects		= 0;
	pev->yaw_speed		= 8; //LRC -- what?
	pev->sequence		= 0;

	if (pev->netname)
	{
		pev->sequence = LookupSequence( STRING(pev->netname) );

		if (pev->sequence == -1)
		{
			ALERT ( at_debug, "Invalid sequence name \"%s\" in monster_generic_dead\n", STRING(pev->netname) );
		}
	}
	else
	{
		pev->sequence = LookupActivity( pev->frags );
//		if (pev->sequence == -1)
//		{
//			ALERT ( at_error, "monster_generic_dead - specify a sequence name or choose a different death type: model \"%s\" has no available death sequences.\n", STRING(pev->model) );
//		}
		//...and if that doesn't work, forget it.
	}

	// Corpses have less health
	pev->health			= 8;

	MonsterInitDead();

	ResetSequenceInfo( );
	pev->frame = 255; // pose at the _end_ of its death sequence.
}
Ejemplo n.º 4
0
/* <cd466> ../cstrike/dlls/h_cycler.cpp:96 */
void CCycler::GenericCyclerSpawn(char *szModel, Vector vecMin, Vector vecMax)
{
	if (!szModel || !szModel[0])
	{
		ALERT(at_error, "cycler at %.0f %.0f %0.f missing modelname", pev->origin.x, pev->origin.y, pev->origin.z);
		REMOVE_ENTITY(ENT(pev));
		return;
	}

	if (pev->classname)
	{
		RemoveEntityHashValue(pev, STRING(pev->classname), CLASSNAME);
	}

	MAKE_STRING_CLASS("cycler", pev);
	AddEntityHashValue(pev, STRING(pev->classname), CLASSNAME);

	PRECACHE_MODEL(szModel);
	SET_MODEL(ENT(pev), szModel);

	CCycler::Spawn();

	UTIL_SetSize(pev, vecMin, vecMax);
}
Ejemplo n.º 5
0
void CGrappleHook::Killed(entvars_t *pev, int gib)
{
	ALERT( at_console, "^2HLU -> ^3weapon_grapple ^2-> Tongue was killed.\n");

	// Fograin92: Clear player
	myowner->pev->movetype = MOVETYPE_WALK; //Re-apply gravity
	myowner->m_afPhysicsFlags &= ~PFLAG_ON_GRAPPLE; //Remove "on grapple" flag
	myowner->m_iGrappleExists = 0;
	myowner->m_flNextAttack = UTIL_WeaponTimeBase() + 1.0;

	// Fograin92: Clear monster
	if( (m_iHitMonster == 2) && (myHitMonster->IsAlive()) )
		myHitMonster->pev->movetype = MOVETYPE_STEP;	// Re-apply gravity to the pulled monster, if it's alive
	
	// Fograin92: Clear tongue leftovers
	bPullBack = false;
	UTIL_Remove( m_pTongue );
	m_pTongue = NULL;

	m_iHitMonster = 0;
	SetThink(NULL);
	SetTouch(NULL);
	SUB_Remove( ); 
}
Ejemplo n.º 6
0
int R_AllocateCinematicTexture( unsigned int txFlags )
{
	int i = tr.num_cin_used;

	if( i >= MAX_MOVIE_TEXTURES )
	{
		ALERT( at_error, "R_AllocateCinematicTexture: cine textures limit exceeded!\n" );
		return 0; // disable
	}
	tr.num_cin_used++;

	if( !tr.cinTextures[i] )
	{
		char txName[16];

		Q_snprintf( txName, sizeof( txName ), "*cinematic%i", i );

		// create new cinematic texture
		// NOTE: dimension of texture is no matter because CIN_UPLOAD_FRAME will be rescale texture
		tr.cinTextures[i] = CREATE_TEXTURE( txName, 256, 256, NULL, txFlags ); 
	}

	return (i+1);
}
Ejemplo n.º 7
0
void eeReadAll()
{
  fill_file_index() ;

  if (!eeLoadGeneral() )
  {
    generalDefault();
    modelDefault(0);

    ALERT(STR_EEPROMWARN, STR_BADEEPROMDATA, AU_BAD_EEPROM);

    MESSAGE(STR_EEPROMWARN, STR_EEPROMFORMATTING, NULL, AU_EEPROM_FORMATTING);

    /* we remove all models */
    for (uint32_t i=0; i<MAX_MODELS; i++)
      eeDeleteModel(i);

    eeDirty(EE_GENERAL);
    eeDirty(EE_MODEL);
  }
  else {
    eeLoadModelHeaders() ;
  }

  // TODO common!
  stickMode = g_eeGeneral.stickMode;

#if defined(CPUARM)
  for (uint8_t i=0; languagePacks[i]!=NULL; i++) {
    if (!strncmp(g_eeGeneral.ttsLanguage, languagePacks[i]->id, 2)) {
      currentLanguagePackIdx = i;
      currentLanguagePack = languagePacks[i];
    }
  }
#endif
}
Ejemplo n.º 8
0
void DispatchSave( edict_t *pent, SAVERESTOREDATA *pSaveData )
{
	CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
	
	if( pEntity && pSaveData )
	{
		// ALERT( at_console, "DispatchSave( %s, %i )\n", STRING( pent->v.classname ), pent->serialnumber );
		ENTITYTABLE *pTable = &pSaveData->pTable[ pSaveData->currentIndex ];

		if( pTable->pent != pent )
			ALERT( at_error, "ENTITY TABLE OR INDEX IS WRONG!!!!\n" );

		if( pEntity->ObjectCaps() & FCAP_DONT_SAVE ) return;

		// These don't use ltime & nextthink as times really, but we'll fudge around it.
		if( pEntity->pev->movetype == MOVETYPE_PUSH )
		{
			float delta = gpGlobals->time - pEntity->pev->ltime;
			pEntity->pev->ltime += delta;
			pEntity->pev->nextthink += delta;
			pEntity->m_fPevNextThink = pEntity->pev->nextthink;
			pEntity->m_fNextThink += delta;
		}

		if( gpGlobals->changelevel )
			pEntity->ClearPointers();

		pTable->location = pSaveData->size;		// Remember entity position for file I/O
		pTable->classname = pEntity->pev->classname;	// Remember entity class for respawn

		CSave saveHelper( pSaveData );
		pEntity->Save( saveHelper );

		pTable->size = pSaveData->size - pTable->location;// Size of entity block is data size written to block
	}
}
Ejemplo n.º 9
0
static long
ioctl_unload_vmm(void)
{
    int i;
    int64_t ret;
    long status = BF_IOCTL_SUCCESS;

    ret = common_unload_vmm();
    if (ret != BF_SUCCESS)
    {
        ALERT("IOCTL_UNLOAD_VMM: failed to unload vmm: %lld\n", ret);
        status = BF_IOCTL_FAILURE;
    }

    for (i = 0; i < g_num_files; i++)
        platform_free(files[i], files_sizes[i]);

    g_num_files = 0;

    if (status == BF_IOCTL_SUCCESS)
        DEBUG("IOCTL_UNLOAD_VMM: succeeded\n");

    return status;
}
Ejemplo n.º 10
0
void CBigMomma::NodeStart( int iszNextNode )
{
	pev->netname = iszNextNode;

	CBaseEntity *pTarget = NULL;

	if ( pev->netname )
	{
		edict_t *pentTarget = FIND_ENTITY_BY_TARGETNAME ( NULL, STRING(pev->netname) );

		if ( !FNullEnt(pentTarget) )
			pTarget = Instance( pentTarget );
	}


	if ( !pTarget )
	{
		ALERT( at_aiconsole, "BM: Finished the path!!\n" );
		Remember( bits_MEMORY_PATH_FINISHED );
		return;
	}
	Remember( bits_MEMORY_ON_PATH );
	m_hTargetEnt = pTarget;
}
Ejemplo n.º 11
0
void CISlave :: CallForHelp( char *szClassname, float flDist, EHANDLE hEnemy, Vector &vecLocation )
{
	 ALERT( at_aiconsole, "help " );

	// skip ones not on my netname
	if ( FStringNull( pev->netname ))
		return;

	CBaseEntity *pEntity = NULL;

	while ((pEntity = UTIL_FindEntityByString( pEntity, "netname", STRING( pev->netname ))) != NULL)
	{
		float d = (pev->origin - pEntity->pev->origin).Length();
		if (d < flDist)
		{
			CBaseMonster *pMonster = pEntity->MyMonsterPointer( );
			if (pMonster)
			{
				pMonster->m_afMemory |= bits_MEMORY_PROVOKED;
				pMonster->PushEnemy( hEnemy, vecLocation );
			}
		}
	}
}
Ejemplo n.º 12
0
//=========================================================
// IAllocSound - moves a sound from the Free list to the 
// Active list returns the index of the alloc'd sound
//=========================================================
int CSoundEnt :: IAllocSound( void )
{
	int iNewSound;

	if ( m_iFreeSound == SOUNDLIST_EMPTY )
	{
		// no free sound!
		ALERT ( at_console, "Free Sound List is full!\n" );
		return SOUNDLIST_EMPTY;
	}

	// there is at least one sound available, so move it to the
	// Active sound list, and return its SoundPool index.
	
	iNewSound = m_iFreeSound;// copy the index of the next free sound

	m_iFreeSound = m_SoundPool[ m_iFreeSound ].m_iNext;// move the index down into the free list. 

	m_SoundPool[ iNewSound ].m_iNext = m_iActiveSound;// point the new sound at the top of the active list.

	m_iActiveSound = iNewSound;// now make the new sound the top of the active list. You're done.

	return iNewSound;
}
Ejemplo n.º 13
0
// Assumes this is ALWAYS enabled
CPathTrack *CPathTrack :: Nearest( Vector origin )
{
	int			deadCount;
	float		minDist, dist;
	Vector		delta;
	CPathTrack	*ppath, *pnearest;


	delta = origin - pev->origin;
	delta.z = 0;
	minDist = delta.Length();
	pnearest = this;
	ppath = GetNext();

	// Hey, I could use the old 2 racing pointers solution to this, but I'm lazy :)
	deadCount = 0;
	while ( ppath && ppath != this )
	{
		deadCount++;
		if ( deadCount > 9999 )
		{
			ALERT( at_error, "Bad sequence of path_tracks from %s", STRING(pev->targetname) );
			return NULL;
		}
		delta = origin - ppath->pev->origin;
		delta.z = 0;
		dist = delta.Length();
		if ( dist < minDist )
		{
			minDist = dist;
			pnearest = ppath;
		}
		ppath = ppath->GetNext();
	}
	return pnearest;
}
Ejemplo n.º 14
0
int snd_init(void)
{
    char info_buf[256];

    PaError p_err;
    if((p_err = Pa_Initialize()) != paNoError)
    {
        snprintf(info_buf, sizeof(info_buf),
				_("PortAudio init failed:\n%s\n"),
				Pa_GetErrorText(p_err));

        ALERT(info_buf);
        return 1;
    }

    srconv_stream.data_in = (float*)malloc(pa_frames*2 * sizeof(float));
    srconv_stream.data_out = (float*)malloc(pa_frames*2 * 10 * sizeof(float));
    srconv_record.data_in = (float*)malloc(pa_frames*2 * sizeof(float));
    srconv_record.data_out = (float*)malloc(pa_frames*2 * 10 * sizeof(float));

    reconnect = 0;
    buf_index = 0;
    return 0;
}
CHalfLifeMultiplay :: CHalfLifeMultiplay()
{
	g_VoiceGameMgr.Init(&g_GameMgrHelper, gpGlobals->maxClients);

	RefreshSkillData();
	m_flIntermissionEndTime = 0;
	g_flIntermissionStartTime = 0;
	
	// 11/8/98
	// Modified by YWB:  Server .cfg file is now a cvar, so that 
	//  server ops can run multiple game servers, with different server .cfg files,
	//  from a single installed directory.
	// Mapcyclefile is already a cvar.

	// 3/31/99
	// Added lservercfg file cvar, since listen and dedicated servers should not
	// share a single config file. (sjb)
	if ( IS_DEDICATED_SERVER() )
	{
		// this code has been moved into engine, to only run server.cfg once
	}
	else
	{
		// listen server
		char *lservercfgfile = (char *)CVAR_GET_STRING( "lservercfgfile" );

		if ( lservercfgfile && lservercfgfile[0] )
		{
			char szCommand[256];
			
			ALERT( at_console, "Executing listen server config file\n" );
			sprintf( szCommand, "exec %s\n", lservercfgfile );
			SERVER_COMMAND( szCommand );
		}
	}
}
Ejemplo n.º 16
0
int CFuncCollideWall :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType )
{
	ALERT ( at_notice, "TakeDamage()\n");

	TraceResult trace = UTIL_GetGlobalTrace( );

//== 1) //metal
//== 5) //wood
//== 5) //water
//== -1/0) //not defined (default concrete)

	float flVolume = RANDOM_FLOAT ( 0.7 , 1.0 );//random volume range
	BOOL	b_CanMakeParticles = TRUE;

	if ( CVAR_GET_FLOAT( "r_paintball" ) == 0 )
	if ( CVAR_GET_FLOAT( "cl_wallpuff" ) >= 1 )
	{			
		if (pev->frags == 1) //metal
		{								
			UTIL_Ricochet( trace.vecEndPos, 0.5 );

			switch ( RANDOM_LONG(0,2) )
			{
				case 0: UTIL_EmitAmbientSound(ENT(0), trace.vecEndPos, "weapons/bulletimpact/metal1.wav", flVolume, ATTN_NORM, 0, 100); break;
				case 1: UTIL_EmitAmbientSound(ENT(0), trace.vecEndPos, "weapons/bulletimpact/metal2.wav", flVolume, ATTN_NORM, 0, 100); break;
				case 2: UTIL_EmitAmbientSound(ENT(0), trace.vecEndPos, "weapons/bulletimpact/metal3.wav", flVolume, ATTN_NORM, 0, 100); break;
			}

			if (RANDOM_LONG( 0, 99 ) < 40)
			UTIL_WhiteSparks( trace.vecEndPos, trace.vecPlaneNormal, 0, 5, 500, 500 );//chispas

			UTIL_WhiteSparks( trace.vecEndPos, trace.vecPlaneNormal, 9, 5, 5, 100 );//puntos
			UTIL_WhiteSparks( trace.vecEndPos, trace.vecPlaneNormal, 0, 5, 500, 20 );//chispas
												
			b_CanMakeParticles = FALSE;
		}
		if (pev->frags == 5) //wood
		{
			switch ( RANDOM_LONG(0,2) )
			{
				case 0: UTIL_EmitAmbientSound(ENT(0), trace.vecEndPos, "weapons/bulletimpact/wood1.wav", flVolume, ATTN_NORM, 0, 100); break;
				case 1: UTIL_EmitAmbientSound(ENT(0), trace.vecEndPos, "weapons/bulletimpact/wood2.wav", flVolume, ATTN_NORM, 0, 100); break;
				case 2: UTIL_EmitAmbientSound(ENT(0), trace.vecEndPos, "weapons/bulletimpact/wood3.wav", flVolume, ATTN_NORM, 0, 100); break;
			}
		}
		else if (pev->frags == 6) //water
		{
			switch ( RANDOM_LONG(0,2) )
			{
				case 0: UTIL_EmitAmbientSound(ENT(0), trace.vecEndPos, "weapons/bulletimpact/water1.wav", flVolume, ATTN_NORM, 0, 100); break;
				case 1: UTIL_EmitAmbientSound(ENT(0), trace.vecEndPos, "weapons/bulletimpact/water2.wav", flVolume, ATTN_NORM, 0, 100); break;
				case 2: UTIL_EmitAmbientSound(ENT(0), trace.vecEndPos, "weapons/bulletimpact/water3.wav", flVolume, ATTN_NORM, 0, 100); break;
			}
		}
		else if (pev->frags == 7) //gas canister
		{
			switch ( RANDOM_LONG(0,1) )
			{
				case 0: UTIL_EmitAmbientSound(ENT(0), trace.vecEndPos, "weapons/bulletimpact/gascan1.wav", flVolume, ATTN_NORM, 0, 100); break;
				case 1: UTIL_EmitAmbientSound(ENT(0), trace.vecEndPos, "weapons/bulletimpact/gascan2.wav", flVolume, ATTN_NORM, 0, 100); break;
			}
		}

		else
		{
			switch ( RANDOM_LONG(0,2) )
			{
				case 0: UTIL_EmitAmbientSound(ENT(0), trace.vecEndPos, "weapons/bulletimpact/concrete1.wav", flVolume, ATTN_NORM, 0, 100); break;
				case 1: UTIL_EmitAmbientSound(ENT(0), trace.vecEndPos, "weapons/bulletimpact/concrete2.wav", flVolume, ATTN_NORM, 0, 100); break;
				case 2: UTIL_EmitAmbientSound(ENT(0), trace.vecEndPos, "weapons/bulletimpact/concrete3.wav", flVolume, ATTN_NORM, 0, 100); break;
			}
		}	
		
		if (b_CanMakeParticles)
		{
			if ( CVAR_GET_FLOAT("r_particles" ) != 0 )			
			{
				MESSAGE_BEGIN(MSG_ALL, gmsgParticles);
					WRITE_SHORT(0);
					WRITE_BYTE(0);
					WRITE_COORD( trace.vecEndPos.x );
					WRITE_COORD( trace.vecEndPos.y );
					WRITE_COORD( trace.vecEndPos.z );
					WRITE_COORD( 0 );
					WRITE_COORD( 0 );
					WRITE_COORD( 0 );
					if (pev->frags == 5) //wood
					WRITE_SHORT(iDefaultHitWood1);
					else if (pev->frags == 6) //water
					WRITE_SHORT(iDefaultWaterSplash);
					else if (pev->frags == 7) //gas canister
					WRITE_SHORT(iDefaultGasCanister);
					else
					WRITE_SHORT(iDefaultWallSmoke);
				MESSAGE_END();
			}
		}
	}//eo cvar check
	return 1;
}
Ejemplo n.º 17
0
void CCyclerSprite::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
	m_animate = !m_animate;
	ALERT( at_console, "Sprite: %s\n", STRING(pev->model) );
}
Ejemplo n.º 18
0
/*
==============
ChangeLevel

Server is changing to a new level, check mapcycle.txt for map name and setup info
==============
*/
void CHalfLifeMultiplay :: ChangeLevel( void )
{
	static char szPreviousMapCycleFile[ 256 ];
	static mapcycle_t mapcycle;

	char szNextMap[32];
	char szFirstMapInList[32];
	char szCommands[ 1500 ];
	char szRules[ 1500 ];
	int minplayers = 0, maxplayers = 0;
	strcpy( szFirstMapInList, "hldm1" );  // the absolute default level is hldm1

	int	curplayers;
	BOOL do_cycle = TRUE;

	// find the map to change to
	char *mapcfile = (char*)CVAR_GET_STRING( "mapcyclefile" );
	ASSERT( mapcfile != NULL );

	szCommands[ 0 ] = '\0';
	szRules[ 0 ] = '\0';

	curplayers = CountPlayers();

	// Has the map cycle filename changed?
	if ( stricmp( mapcfile, szPreviousMapCycleFile ) )
	{
		strcpy( szPreviousMapCycleFile, mapcfile );

		DestroyMapCycle( &mapcycle );

		if ( !ReloadMapCycleFile( mapcfile, &mapcycle ) || ( !mapcycle.items ) )
		{
			ALERT( at_console, "Unable to load map cycle file %s\n", mapcfile );
			do_cycle = FALSE;
		}
	}

	if ( do_cycle && mapcycle.items )
	{
		BOOL keeplooking = FALSE;
		BOOL found = FALSE;
		mapcycle_item_s *item;

		// Assume current map
		strcpy( szNextMap, STRING(gpGlobals->mapname) );
		strcpy( szFirstMapInList, STRING(gpGlobals->mapname) );

		// Traverse list
		for ( item = mapcycle.next_item; item->next != mapcycle.next_item; item = item->next )
		{
			keeplooking = FALSE;

			ASSERT( item != NULL );

			if ( item->minplayers != 0 )
			{
				if ( curplayers >= item->minplayers )
				{
					found = TRUE;
					minplayers = item->minplayers;
				}
				else
				{
					keeplooking = TRUE;
				}
			}

			if ( item->maxplayers != 0 )
			{
				if ( curplayers <= item->maxplayers )
				{
					found = TRUE;
					maxplayers = item->maxplayers;
				}
				else
				{
					keeplooking = TRUE;
				}
			}

			if ( keeplooking )
				continue;

			found = TRUE;
			break;
		}

		if ( !found )
		{
			item = mapcycle.next_item;
		}			
		
		// Increment next item pointer
		mapcycle.next_item = item->next;

		// Perform logic on current item
		strcpy( szNextMap, item->mapname );

		ExtractCommandString( item->rulebuffer, szCommands );
		strcpy( szRules, item->rulebuffer );
	}

	if ( !IS_MAP_VALID(szNextMap) )
	{
		strcpy( szNextMap, szFirstMapInList );
	}

	g_fGameOver = TRUE;

	ALERT( at_console, "CHANGE LEVEL: %s\n", szNextMap );
	if ( minplayers || maxplayers )
	{
		ALERT( at_console, "PLAYER COUNT:  min %i max %i current %i\n", minplayers, maxplayers, curplayers );
	}
	if ( strlen( szRules ) > 0 )
	{
		ALERT( at_console, "RULES:  %s\n", szRules );
	}
	
	CHANGE_LEVEL( szNextMap, NULL );
	if ( strlen( szCommands ) > 0 )
	{
		SERVER_COMMAND( szCommands );
	}
}
Ejemplo n.º 19
0
/*
==============
ReloadMapCycleFile


Parses mapcycle.txt file into mapcycle_t structure
==============
*/
int ReloadMapCycleFile( char *filename, mapcycle_t *cycle )
{
	char szBuffer[ MAX_RULE_BUFFER ];
	char szMap[ 32 ];
	int length;
	char *pFileList;
	char *aFileList = pFileList = (char*)LOAD_FILE_FOR_ME( filename, &length );
	int hasbuffer;
	mapcycle_item_s *item, *newlist = NULL, *next;

	if ( pFileList && length )
	{
		// the first map name in the file becomes the default
		while ( 1 )
		{
			hasbuffer = 0;
			memset( szBuffer, 0, MAX_RULE_BUFFER );

			pFileList = COM_Parse( pFileList );
			if ( strlen( com_token ) <= 0 )
				break;

			strcpy( szMap, com_token );

			// Any more tokens on this line?
			if ( COM_TokenWaiting( pFileList ) )
			{
				pFileList = COM_Parse( pFileList );
				if ( strlen( com_token ) > 0 )
				{
					hasbuffer = 1;
					strcpy( szBuffer, com_token );
				}
			}

			// Check map
			if ( IS_MAP_VALID( szMap ) )
			{
				// Create entry
				char *s;

				item = new mapcycle_item_s;

				strcpy( item->mapname, szMap );

				item->minplayers = 0;
				item->maxplayers = 0;

				memset( item->rulebuffer, 0, MAX_RULE_BUFFER );

				if ( hasbuffer )
				{
					s = g_engfuncs.pfnInfoKeyValue( szBuffer, "minplayers" );
					if ( s && s[0] )
					{
						item->minplayers = atoi( s );
						item->minplayers = max( item->minplayers, 0 );
						item->minplayers = min( item->minplayers, gpGlobals->maxClients );
					}
					s = g_engfuncs.pfnInfoKeyValue( szBuffer, "maxplayers" );
					if ( s && s[0] )
					{
						item->maxplayers = atoi( s );
						item->maxplayers = max( item->maxplayers, 0 );
						item->maxplayers = min( item->maxplayers, gpGlobals->maxClients );
					}

					// Remove keys
					//
					g_engfuncs.pfnInfo_RemoveKey( szBuffer, "minplayers" );
					g_engfuncs.pfnInfo_RemoveKey( szBuffer, "maxplayers" );

					strcpy( item->rulebuffer, szBuffer );
				}

				item->next = cycle->items;
				cycle->items = item;
			}
			else
			{
				ALERT( at_console, "Skipping %s from mapcycle, not a valid map\n", szMap );
			}


		}

		FREE_FILE( aFileList );
	}

	// Fixup circular list pointer
	item = cycle->items;

	// Reverse it to get original order
	while ( item )
	{
		next = item->next;
		item->next = newlist;
		newlist = item;
		item = next;
	}
	cycle->items = newlist;
	item = cycle->items;

	// Didn't parse anything
	if ( !item )
	{
		return 0;
	}

	while ( item->next )
	{
		item = item->next;
	}
	item->next = cycle->items;
	
	cycle->next_item = item->next;

	return 1;
}
Ejemplo n.º 20
0
// make the entity carry out the scripted sequence instructions, but without
// destroying the monster's state.
void CCineAI::PossessEntity(void)
{
	Schedule_t *pNewSchedule;

	CBaseEntity * pEntity = m_hTargetEnt;
	CBaseMonster *pTarget = NULL;
	if(pEntity)
		pTarget = pEntity->MyMonsterPointer();

	if(pTarget)
	{
		if(!pTarget->CanPlaySequence(FCanOverrideState(), SS_INTERRUPT_AI))
		{
			ALERT(at_aiconsole, "(AI)Can't possess entity %s\n", STRING(pTarget->pev->classname));
			return;
		}

		pTarget->m_pGoalEnt   = this;
		pTarget->m_pCine      = this;
		pTarget->m_hTargetEnt = this;

		m_saved_movetype = pTarget->pev->movetype;
		m_saved_solid    = pTarget->pev->solid;
		m_saved_effects  = pTarget->pev->effects;
		pTarget->pev->effects |= pev->effects;

		switch(m_fMoveTo)
		{
		case 0:
		case 5:
			pTarget->m_scriptState = SCRIPT_WAIT;
			break;

		case 1:
			pTarget->m_scriptState = SCRIPT_WALK_TO_MARK;
			break;

		case 2:
			pTarget->m_scriptState = SCRIPT_RUN_TO_MARK;
			break;

		case 4:
			// zap the monster instantly to the site of the script entity.
			UTIL_SetOrigin(pTarget->pev, pev->origin);
			pTarget->pev->ideal_yaw = pev->angles.y;
			pTarget->pev->avelocity = Vector(0, 0, 0);
			pTarget->pev->velocity  = Vector(0, 0, 0);
			pTarget->pev->effects |= EF_NOINTERP;
			pTarget->pev->angles.y = pev->angles.y;
			pTarget->m_scriptState = SCRIPT_WAIT;
			m_startTime            = gpGlobals->time + 1E6;
			// UNDONE: Add a flag to do this so people can fixup physics after teleporting monsters
			pTarget->pev->flags &= ~FL_ONGROUND;
			break;
		default:
			ALERT(at_aiconsole, "aiscript:  invalid Move To Position value!");
			break;
		}

		ALERT(at_aiconsole, "\"%s\" found and used\n", STRING(pTarget->pev->targetname));

		pTarget->m_IdealMonsterState = MONSTERSTATE_SCRIPT;

		/*
		if (m_iszIdle)
		{
			StartSequence( pTarget, m_iszIdle, FALSE );
			if (FStrEq( STRING(m_iszIdle), STRING(m_iszPlay)))
			{
				pTarget->pev->framerate = 0;
			}
		}
*/
		// Already in a scripted state?
		if(pTarget->m_MonsterState == MONSTERSTATE_SCRIPT)
		{
			pNewSchedule = pTarget->GetScheduleOfType(SCHED_AISCRIPT);
			pTarget->ChangeSchedule(pNewSchedule);
		}
	}
}
Ejemplo n.º 21
0
// make the entity enter a scripted sequence
void CCineMonster::PossessEntity(void)
{
	CBaseEntity * pEntity = m_hTargetEnt;
	CBaseMonster *pTarget = NULL;
	if(pEntity)
		pTarget = pEntity->MyMonsterPointer();

	if(pTarget)
	{
// FindEntity() just checked this!
#if 0
		if ( !pTarget->CanPlaySequence(  FCanOverrideState() ) )
		{
			ALERT( at_aiconsole, "Can't possess entity %s\n", STRING(pTarget->pev->classname) );
			return;
		}
#endif

		pTarget->m_pGoalEnt   = this;
		pTarget->m_pCine      = this;
		pTarget->m_hTargetEnt = this;

		m_saved_movetype = pTarget->pev->movetype;
		m_saved_solid    = pTarget->pev->solid;
		m_saved_effects  = pTarget->pev->effects;
		pTarget->pev->effects |= pev->effects;

		switch(m_fMoveTo)
		{
		case 0:
			pTarget->m_scriptState = SCRIPT_WAIT;
			break;

		case 1:
			pTarget->m_scriptState = SCRIPT_WALK_TO_MARK;
			DelayStart(1);
			break;

		case 2:
			pTarget->m_scriptState = SCRIPT_RUN_TO_MARK;
			DelayStart(1);
			break;

		case 4:
			UTIL_SetOrigin(pTarget->pev, pev->origin);
			pTarget->pev->ideal_yaw = pev->angles.y;
			pTarget->pev->avelocity = Vector(0, 0, 0);
			pTarget->pev->velocity  = Vector(0, 0, 0);
			pTarget->pev->effects |= EF_NOINTERP;
			pTarget->pev->angles.y = pev->angles.y;
			pTarget->m_scriptState = SCRIPT_WAIT;
			m_startTime            = gpGlobals->time + 1E6;
			// UNDONE: Add a flag to do this so people can fixup physics after teleporting monsters
			//			pTarget->pev->flags &= ~FL_ONGROUND;
			break;
		}
		//		ALERT( at_aiconsole, "\"%s\" found and used (INT: %s)\n", STRING( pTarget->pev->targetname ), FBitSet(pev->spawnflags, SF_SCRIPT_NOINTERRUPT)?"No":"Yes" );

		pTarget->m_IdealMonsterState = MONSTERSTATE_SCRIPT;
		if(m_iszIdle)
		{
			StartSequence(pTarget, m_iszIdle, FALSE);
			if(FStrEq(STRING(m_iszIdle), STRING(m_iszPlay)))
			{
				pTarget->pev->framerate = 0;
			}
		}
	}
}
Ejemplo n.º 22
0
// Used for context sensitive mouse and for processing right-click
// Must be shared, uses prediction code
// Fill in target index or target point, depending on type of order decided upon
AvHOrderType AvHGetDefaultOrderType(AvHTeamNumber inTeam, const vec3_t& inOrigin, const vec3_t& inNormRay, int& outTargetIndex, vec3_t& outTargetPoint, AvHUser3& outUser3, AvHOrderTargetType& outTargetType)
{
	vec3_t			theTraceStart;
	vec3_t			theTraceEnd;
	AvHOrderType	theOrderType = ORDERTYPE_UNDEFINED;

//	// Look for a player order
//	if(!AvHOrderTracePlayers(inTeam, inOrigin, inNormRay, theOrderType, outTargetIndex))
//	{
//		// If couldn't find one, create a non-player order if possible
//		//AvHOrderTraceNonPlayers(inTeam, inOrigin, inNormRay, theOrderType, outTargetIndex, outTargetPoint);
//	}

	
	// Offset a little so we don't hit the commander
	VectorMA(inOrigin, kSelectionStartRange, inNormRay, theTraceStart);
	VectorMA(inOrigin, kSelectionEndRange, inNormRay, theTraceEnd);
	int theFoundIndex = -1;
	vec3_t theFoundLocation;
	AvHTeamNumber theTeamOfThingHit;
	bool thePlayerHit = false;
	int theUserThree = 0;
	int theUserFour = 0;
	
	if(AvHSHUTraceTangible(theTraceStart, theTraceEnd, theFoundIndex, theFoundLocation, theTeamOfThingHit, thePlayerHit, theUserThree, theUserFour))
	{
		float theHealthPercentage=100.0f;
		float theArmorPercentage=100.0f;
		bool theSighted=false;
#ifdef AVH_SERVER
		CBaseEntity *theEntity=AvHSUGetEntityFromIndex(theFoundIndex);
		if ( theEntity ) 
		{
			theHealthPercentage=theEntity->pev->health/theEntity->pev->max_health;
		}
		else 
		{
			ALERT(at_console, "Not a buildable\n");
		}
		
        theArmorPercentage = theEntity->pev->armorvalue/AvHPlayerUpgrade::GetMaxArmorLevel(theEntity->pev->iuser4, (AvHUser3)theEntity->pev->iuser3);
		theSighted=GetHasUpgrade(theEntity->pev->iuser4, MASK_VIS_SIGHTED);
#endif

		// Did we hit an enemy?  If so, issue an attack order on him, then we're done, it's highest priority
		if(thePlayerHit ) 
		{
			// Did we hit a player on our team?  If so check for welding, if not guard
			if((theTeamOfThingHit == inTeam ) && (theTeamOfThingHit != TEAM_IND) )
			{
				theOrderType = ORDERTYPET_GUARD;
				if (  theArmorPercentage < 0.90f ) {
					theOrderType = ORDERTYPET_WELD;
					outTargetType = ORDERTARGETTYPE_TARGET;
				}
				outTargetIndex = theFoundIndex;
				outUser3 = (AvHUser3)theUserThree;
			}
		}
		// Something to pick up?
		if(!thePlayerHit ) 
		{
//			if ( ( theTeamOfThingHit ) != inTeam && (theTeamOfThingHit != TEAM_IND) && theSighted )
//			{
//				// Use it's center for the height
//				VectorCopy(theFoundLocation, outTargetPoint);
//				theOrderType = ORDERTYPET_ATTACK;
//				outTargetIndex = theFoundIndex;
//				outUser3 = (AvHUser3)theUserThree;
//				outTargetType = ORDERTARGETTYPE_LOCATION;
//			}
//			else 
			if ( theUserThree == AVH_USER3_MARINEITEM) 
			{
				// Use it's center for the height
				VectorCopy(theFoundLocation, outTargetPoint);
				outTargetIndex = theFoundIndex;
				outUser3 = (AvHUser3)theUserThree;
				
				// We're done
				theOrderType = ORDERTYPET_GET;
			}
			// Buildable?
			else if(GetHasUpgrade(theUserFour, MASK_BUILDABLE) && (theTeamOfThingHit == inTeam) && (theTeamOfThingHit != TEAM_IND))
			{
				// Use it's center for the height
				VectorCopy(theFoundLocation, outTargetPoint);
				outTargetIndex = theFoundIndex;
				outUser3 = (AvHUser3)theUserThree;
				
				// We're done
				theOrderType = ORDERTYPET_BUILD;
			}
			// Weldable?
			else if(theUserThree == AVH_USER3_WELD )
			{
				// Use it's center for the height
				VectorCopy(theFoundLocation, outTargetPoint);
				outTargetIndex = theFoundIndex;
				
				// We're done
				theOrderType = ORDERTYPET_WELD;
			}
			// Hit the ground?  Move to, we're done
			else if(theUserThree == AVH_USER3_WAYPOINT || (( theTeamOfThingHit != inTeam) && !theSighted ))
			{
				// Use it's center for the height
				VectorCopy(theFoundLocation, outTargetPoint);
			
				// We're done
				theOrderType = ORDERTYPEL_MOVE;
			}
			// Did we hit an entity on our team?  Repair/guard it, we're done
			else if((theTeamOfThingHit == inTeam) && (theTeamOfThingHit != TEAM_IND))
			{
				theOrderType = ORDERTYPET_GUARD;
				if (  theHealthPercentage < 0.90f ) {
					theOrderType = ORDERTYPET_WELD;
					VectorCopy(theFoundLocation, outTargetPoint);
					outTargetType = ORDERTARGETTYPE_LOCATION;
				}
				outTargetIndex = theFoundIndex;
				outUser3 = (AvHUser3)theUserThree;
			}
		}
//		else if(!thePlayerHit && (theUserThree == AVH_USER3_USEABLE))
//		{
//			// Use it's center for the height
//			VectorCopy(theFoundLocation, outTargetPoint);
//			outTargetIndex = theFoundIndex;
//			
//			// We're done
//			theOrderType = ORDERTYPEL_USE;
//		}
	}
	
	return theOrderType;
}
Ejemplo n.º 23
0
void CWorld :: Precache( void )
{
	g_pLastSpawn = NULL;
	
	CVAR_SET_STRING("sv_gravity", "800"); // 67ft/sec
	CVAR_SET_STRING("sv_stepsize", "18");
	CVAR_SET_STRING("room_type", "0"); // clear DSP

	// Create all the arenas
	for (int i = 0; i < MAX_ARENAS; i++)
	{
		g_pArenaList[i] = GetClassPtr( ( CDiscArena *)NULL );
		g_pArenaList[i]->Spawn();
	}

	// Set up game rules
	if (g_pGameRules)
	{
		delete g_pGameRules;
	}

	g_pGameRules = InstallGameRules( );

	//!!!UNDONE why is there so much Spawn code in the Precache function? I'll just keep it here 

	///!!!LATER - do we want a sound ent in deathmatch? (sjb)
	//pSoundEnt = CBaseEntity::Create( "soundent", g_vecZero, g_vecZero, edict() );
	pSoundEnt = GetClassPtr( ( CSoundEnt *)NULL );
	pSoundEnt->Spawn();

	if ( !pSoundEnt )
	{
		ALERT ( at_console, "**COULD NOT CREATE SOUNDENT**\n" );
	}

	InitBodyQue();
	
// init sentence group playback stuff from sentences.txt.
// ok to call this multiple times, calls after first are ignored.

	SENTENCEG_Init();

// init texture type array from materials.txt

	TEXTURETYPE_Init();


// the area based ambient sounds MUST be the first precache_sounds

// player precaches     
	W_Precache ();									// get weapon precaches

	ClientPrecache();

// sounds used from C physics code
	PRECACHE_SOUND("common/null.wav");				// clears sound channels

	PRECACHE_SOUND( "items/suitchargeok1.wav" );//!!! temporary sound for respawning weapons.
	PRECACHE_SOUND( "items/gunpickup2.wav" );// player picks up a gun.

	PRECACHE_SOUND( "common/bodydrop3.wav" );// dead bodies hitting the ground (animation events)
	PRECACHE_SOUND( "common/bodydrop4.wav" );

	PRECACHE_SOUND( "r_tele1.wav" );	// respawn sound
	PRECACHE_SOUND( "scream1.wav" );	// falling scream sound
	PRECACHE_SOUND( "scream2.wav" );	// falling scream sound
	PRECACHE_SOUND( "scream3.wav" );	// falling scream sound
	PRECACHE_SOUND( "decap.wav" );		// decapitation sound
	PRECACHE_SOUND( "shatter.wav" );	// freeze decapitation sound
	PRECACHE_MODEL( "models/head.mdl" ); // head
	
	g_Language = (int)CVAR_GET_FLOAT( "sv_language" );
	if ( g_Language == LANGUAGE_GERMAN )
	{
		PRECACHE_MODEL( "models/germangibs.mdl" );
	}
	else
	{
		PRECACHE_MODEL( "models/hgibs.mdl" );
		PRECACHE_MODEL( "models/agibs.mdl" );
	}

	PRECACHE_SOUND ("weapons/ric1.wav");
	PRECACHE_SOUND ("weapons/ric2.wav");
	PRECACHE_SOUND ("weapons/ric3.wav");
	PRECACHE_SOUND ("weapons/ric4.wav");
	PRECACHE_SOUND ("weapons/ric5.wav");
//
// Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
//

	// 0 normal
	LIGHT_STYLE(0, "m");
	
	// 1 FLICKER (first variety)
	LIGHT_STYLE(1, "mmnmmommommnonmmonqnmmo");
	
	// 2 SLOW STRONG PULSE
	LIGHT_STYLE(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
	
	// 3 CANDLE (first variety)
	LIGHT_STYLE(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
	
	// 4 FAST STROBE
	LIGHT_STYLE(4, "mamamamamama");
	
	// 5 GENTLE PULSE 1
	LIGHT_STYLE(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");
	
	// 6 FLICKER (second variety)
	LIGHT_STYLE(6, "nmonqnmomnmomomno");
	
	// 7 CANDLE (second variety)
	LIGHT_STYLE(7, "mmmaaaabcdefgmmmmaaaammmaamm");
	
	// 8 CANDLE (third variety)
	LIGHT_STYLE(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
	
	// 9 SLOW STROBE (fourth variety)
	LIGHT_STYLE(9, "aaaaaaaazzzzzzzz");
	
	// 10 FLUORESCENT FLICKER
	LIGHT_STYLE(10, "mmamammmmammamamaaamammma");

	// 11 SLOW PULSE NOT FADE TO BLACK
	LIGHT_STYLE(11, "abcdefghijklmnopqrrqponmlkjihgfedcba");
	
	// 12 UNDERWATER LIGHT MUTATION
	// this light only distorts the lightmap - no contribution
	// is made to the brightness of affected surfaces
	LIGHT_STYLE(12, "mmnnmmnnnmmnn");
	
	// styles 32-62 are assigned by the light program for switchable lights

	// 63 testing
	LIGHT_STYLE(63, "a");

	for ( i = 0; i < ARRAYSIZE(gDecals); i++ )
		gDecals[i].index = DECAL_INDEX( gDecals[i].name );

// init the WorldGraph.
	WorldGraph.InitGraph();

// make sure the .NOD file is newer than the .BSP file.
	if ( !WorldGraph.CheckNODFile ( ( char * )STRING( gpGlobals->mapname ) ) )
	{// NOD file is not present, or is older than the BSP file.
		WorldGraph.AllocNodes ();
	}
	else
	{// Load the node graph for this level
		if ( !WorldGraph.FLoadGraph ( (char *)STRING( gpGlobals->mapname ) ) )
		{// couldn't load, so alloc and prepare to build a graph.
			ALERT ( at_console, "*Error opening .NOD file\n" );
			WorldGraph.AllocNodes ();
		}
		else
		{
			ALERT ( at_console, "\n*Graph Loaded!\n" );
		}
	}

	if ( pev->speed > 0 )
		CVAR_SET_FLOAT( "sv_zmax", pev->speed );
	else
		CVAR_SET_FLOAT( "sv_zmax", 4096 );

	if ( pev->netname )
	{
		ALERT( at_aiconsole, "Chapter title: %s\n", STRING(pev->netname) );
		CBaseEntity *pEntity = CBaseEntity::Create( "env_message", g_vecZero, g_vecZero, NULL );
		if ( pEntity )
		{
			pEntity->SetThink( SUB_CallUseToggle );
			pEntity->pev->message = pev->netname;
			pev->netname = 0;
			pEntity->pev->nextthink = gpGlobals->time + 0.3;
			pEntity->pev->spawnflags = SF_MESSAGE_ONCE;
		}
	}

	if ( pev->spawnflags & SF_WORLD_DARK )
		CVAR_SET_FLOAT( "v_dark", 1.0 );
	else
		CVAR_SET_FLOAT( "v_dark", 0.0 );

	if ( pev->spawnflags & SF_WORLD_TITLE )
		gDisplayTitle = TRUE;		// display the game title if this key is set
	else
		gDisplayTitle = FALSE;

	if ( pev->spawnflags & SF_WORLD_FORCETEAM )
	{
		CVAR_SET_FLOAT( "mp_defaultteam", 1 );
	}
	else
	{
		CVAR_SET_FLOAT( "mp_defaultteam", 0 );
	}

	// Discwar
	if ( g_iPlayersPerTeam < 1 )
		g_iPlayersPerTeam = CVAR_GET_FLOAT("rc_playersperteam");
}
Ejemplo n.º 24
0
extern "C" void GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals )
#endif
{
	// get the engine functions from the engine...
	memcpy( &g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t) );
	// get the globals from the engine
	gpGlobals = pGlobals;

	// get the directory name of the currently running game or mod
	// this now returns just the mod directory's name: http://metamod.org/engine_notes.html#GetGameDir
	char szGameDir[256];
	char *szLibraryPath = "";
	GET_GAME_DIR(szGameDir);

	if( !strcmpi( szGameDir, "valve" ) )
	{
		mod_id = VALVE_DLL;

#ifndef __linux__
		szLibraryPath = "valve/dlls/hl.dll";
#else
		szLibraryPath = "valve/dlls/hl.so";
#endif

		if( !g_bIsMMPlugin )
		{
#ifndef __linux__
			h_Library = LoadLibrary( szLibraryPath );
#else
			h_Library = dlopen( szLibraryPath, RTLD_NOW );
#endif
		}
	}
	else if( !strcmpi( szGameDir, "bshift" ) )
	{
		mod_id = BSHIFT_DLL;

#ifndef __linux__
		szLibraryPath = "bshift/dlls/hl.dll";
#else
		szLibraryPath = "bshift/dlls/bshift.so";
#endif

		if( !g_bIsMMPlugin )
		{
#ifndef __linux__
			h_Library = LoadLibrary( szLibraryPath );
#else
			h_Library = dlopen( szLibraryPath, RTLD_NOW );
#endif
		}
	}
	else if( !strcmpi( szGameDir, "gearbox" ) )
	{
		mod_id = GEARBOX_DLL;

#ifndef __linux__
		szLibraryPath = "gearbox/dlls/opfor.dll";
#else
		szLibraryPath = "gearbox/dlls/opfor.so";
#endif

		if( !g_bIsMMPlugin )
		{
#ifndef __linux__
			h_Library = LoadLibrary( szLibraryPath );
#else
			h_Library = dlopen( szLibraryPath, RTLD_NOW );
#endif
		}
	}
	else if( !strcmpi( szGameDir, "decay" ) )
	{
		mod_id = DECAY_DLL;

#ifndef __linux__
		szLibraryPath = "decay/dlls/decay.dll";
#else
		szLibraryPath = "decay/dlls/decay_i386.so";
#endif

		if( !g_bIsMMPlugin )
		{
#ifndef __linux__
			h_Library = LoadLibrary( szLibraryPath );
#else
			h_Library = dlopen( szLibraryPath, RTLD_NOW );
#endif
		}
	}
	else if( !strcmpi( szGameDir, "cstrike" ) )
	{
		mod_id = CSTRIKE_DLL;

#ifndef __linux__
		szLibraryPath = "cstrike/dlls/mp.dll";
#else
		szLibraryPath = "cstrike/dlls/cs.so";
#endif

		if( !g_bIsMMPlugin )
		{
#ifndef __linux__
			h_Library = LoadLibrary( szLibraryPath );
#else
			h_Library = dlopen( szLibraryPath, RTLD_NOW );
#endif
		}
	}
	else if( !strcmpi( szGameDir, "czero" ) )
	{
		mod_id = CZERO_DLL;

#ifndef __linux__
		szLibraryPath = "czero/dlls/mp.dll";
#else
		szLibraryPath = "czero/dlls/cs.so";
#endif

		if( !g_bIsMMPlugin )
		{
#ifndef __linux__
			h_Library = LoadLibrary( szLibraryPath );
#else
			h_Library = dlopen( szLibraryPath, RTLD_NOW );
#endif
		}
	}
	else if( !strcmpi( szGameDir, "czeror" ) )
	{
		mod_id = CZEROR_DLL;

#ifndef __linux__
		szLibraryPath = "czeror/dlls/cz.dll";
#else
		szLibraryPath = "czeror/dlls/cz.so";
#endif

		if( !g_bIsMMPlugin )
		{
#ifndef __linux__
			h_Library = LoadLibrary( szLibraryPath );
#else
			h_Library = dlopen( szLibraryPath, RTLD_NOW );
#endif
		}
	}
	else if( !strcmpi( szGameDir, "dod" ) )
	{
		mod_id = DOD_DLL;

#ifndef __linux__
		szLibraryPath = "dod/dlls/dod.dll";
#else
		szLibraryPath = "dod/dlls/dod.so";
#endif

		if( !g_bIsMMPlugin )
		{
#ifndef __linux__
			h_Library = LoadLibrary( szLibraryPath );
#else
			h_Library = dlopen( szLibraryPath, RTLD_NOW );
#endif
		}
	}
	else if( !strcmpi( szGameDir, "tfc" ) )
	{
		mod_id = TFC_DLL;

#ifndef __linux__
		szLibraryPath = "tfc/dlls/tfc.dll";
#else
		szLibraryPath = "tfc/dlls/tfc.so";
#endif

		if( !g_bIsMMPlugin )
		{
#ifndef __linux__
			h_Library = LoadLibrary( szLibraryPath );
#else
			h_Library = dlopen( szLibraryPath, RTLD_NOW );
#endif
		}
	}
	else if( !strcmpi( szGameDir, "rewolf" ) )
	{
		mod_id = REWOLF_DLL;

#ifndef __linux__
		szLibraryPath = "rewolf/dlls/gunman.dll";
#else
		szLibraryPath = nullptr;
#endif

		if( !g_bIsMMPlugin )
		{
#ifndef __linux__
			h_Library = LoadLibrary( szLibraryPath );
#else
			h_Library = nullptr;
#endif
		}
	}
	else if( !strcmpi( szGameDir, "hunger" ) )
	{
		mod_id = HUNGER_DLL;

#ifndef __linux__
		szLibraryPath = "hunger/dlls/einar.dll";
#else
		szLibraryPath = nullptr;
#endif

		if( !g_bIsMMPlugin )
		{
#ifndef __linux__
			h_Library = LoadLibrary( szLibraryPath );
#else
			h_Library = nullptr;
#endif
		}
	}
	else if( !strcmpi( szGameDir , "ns") )
	{
		mod_id = NS_DLL;

#ifndef __linux__
		szLibraryPath = "ns/dlls/ns.dll";
#else
		szLibraryPath = "ns/dlls/ns_i386.so";
#endif

		if( !g_bIsMMPlugin )
		{
#ifndef __linux__
			h_Library = LoadLibrary( szLibraryPath );
#else
			h_Library = dlopen( szLibraryPath, RTLD_NOW );
#endif
		}
	}
	else if( strcmpi( szGameDir, "ship" ) )
	{
		mod_id = SHIP_DLL;

#ifndef __linux__
		szLibraryPath = "ship/dlls/ship.dll";
#else
		szLibraryPath = "ship/dlls/ship_i386.so";
#endif

		if( !g_bIsMMPlugin )
		{
#ifndef __linux__
			h_Library = LoadLibrary( szLibraryPath );
#else
			h_Library = dlopen( szLibraryPath, RTLD_NOW );
#endif
		}
	}

	strncpy( g_szLibraryPath, szLibraryPath, strlen( szLibraryPath ) );

	if( !g_bIsMMPlugin && h_Library == nullptr )
	{
		ALERT( at_error, "Library not found or not supported!\n" );
	}

	extern bot_player_t g_valveBots[];
	extern bot_player_t g_gearboxBots[];
	extern bot_player_t g_dodBots[];
	extern bot_player_t g_gunmanBots[];
	extern bot_player_t g_nsBots[];
	extern bot_player_t g_hungerBots[];
	extern bot_player_t g_shipBots[];

	if( mod_id == VALVE_DLL || mod_id == TFC_DLL )
	{
		pBotData = g_valveBots;
	}
	else if( mod_id == GEARBOX_DLL )
	{
		pBotData = g_gearboxBots;
	}
	else if( mod_id == DOD_DLL )
	{
		pBotData = g_dodBots;
	}
	else if( mod_id == REWOLF_DLL )
	{
		pBotData = g_gunmanBots;
	}
	else if( mod_id == NS_DLL )
	{
		pBotData = g_nsBots;
	}
	else if( mod_id == HUNGER_DLL )
	{
		pBotData = g_hungerBots;
	}
	else if( mod_id == SHIP_DLL )
	{
		pBotData = g_shipBots;
	}

	LoadExtraExports();

	if( g_bIsMMPlugin )
	{
		return;
	}

	GetEngineFunctions( pengfuncsFromEngine, nullptr );

	// give the engine functions to the other DLL...
	(*(GIVEFNPTRSTODLL)GetProcAddress( h_Library, "GiveFnptrsToDll" ))(pengfuncsFromEngine, pGlobals);

	// finished, interfacing from gamedll to engine complete
	return;
}
void CController :: Move ( float flInterval ) 
{
	float		flWaypointDist;
	float		flCheckDist;
	float		flDist;// how far the lookahead check got before hitting an object.
	float		flMoveDist;
	Vector		vecDir;
	Vector		vecApex;
	CBaseEntity	*pTargetEnt;

	// Don't move if no valid route
	if ( FRouteClear() )
	{
		ALERT( at_aiconsole, "Tried to move with no route!\n" );
		TaskFail();
		return;
	}
	
	if ( m_flMoveWaitFinished > gpGlobals->time )
		return;

// Debug, test movement code
#if 0
//	if ( CVAR_GET_FLOAT("stopmove" ) != 0 )
	{
		if ( m_movementGoal == MOVEGOAL_ENEMY )
			RouteSimplify( m_hEnemy );
		else
			RouteSimplify( m_hTargetEnt );
		FRefreshRoute();
		return;
	}
#else
// Debug, draw the route
//	DrawRoute( pev, m_Route, m_iRouteIndex, 0, 0, 255 );
#endif

	// if the monster is moving directly towards an entity (enemy for instance), we'll set this pointer
	// to that entity for the CheckLocalMove and Triangulate functions.
	pTargetEnt = NULL;

	if (m_flGroundSpeed == 0)
	{
		m_flGroundSpeed = 100;
		// TaskFail( );
		// return;
	}

	flMoveDist = m_flGroundSpeed * flInterval;

	do 
	{
		// local move to waypoint.
		vecDir = ( m_Route[ m_iRouteIndex ].vecLocation - pev->origin ).Normalize();
		flWaypointDist = ( m_Route[ m_iRouteIndex ].vecLocation - pev->origin ).Length();
		
		// MakeIdealYaw ( m_Route[ m_iRouteIndex ].vecLocation );
		// ChangeYaw ( pev->yaw_speed );

		// if the waypoint is closer than CheckDist, CheckDist is the dist to waypoint
		if ( flWaypointDist < DIST_TO_CHECK )
		{
			flCheckDist = flWaypointDist;
		}
		else
		{
			flCheckDist = DIST_TO_CHECK;
		}
		
		if ( (m_Route[ m_iRouteIndex ].iType & (~bits_MF_NOT_TO_MASK)) == bits_MF_TO_ENEMY )
		{
			// only on a PURE move to enemy ( i.e., ONLY MF_TO_ENEMY set, not MF_TO_ENEMY and DETOUR )
			pTargetEnt = m_hEnemy;
		}
		else if ( (m_Route[ m_iRouteIndex ].iType & ~bits_MF_NOT_TO_MASK) == bits_MF_TO_TARGETENT )
		{
			pTargetEnt = m_hTargetEnt;
		}

		// !!!BUGBUG - CheckDist should be derived from ground speed.
		// If this fails, it should be because of some dynamic entity blocking this guy.
		// We've already checked this path, so we should wait and time out if the entity doesn't move
		flDist = 0;
		if ( CheckLocalMove ( pev->origin, pev->origin + vecDir * flCheckDist, pTargetEnt, &flDist ) != LOCALMOVE_VALID )
		{
			CBaseEntity *pBlocker;

			// Can't move, stop
			Stop();
			// Blocking entity is in global trace_ent
			pBlocker = CBaseEntity::Instance( gpGlobals->trace_ent );
			if (pBlocker)
			{
				DispatchBlocked( edict(), pBlocker->edict() );
			}
			if ( pBlocker && m_moveWaitTime > 0 && pBlocker->IsMoving() && !pBlocker->IsPlayer() && (gpGlobals->time-m_flMoveWaitFinished) > 3.0 )
			{
				// Can we still move toward our target?
				if ( flDist < m_flGroundSpeed )
				{
					// Wait for a second
					m_flMoveWaitFinished = gpGlobals->time + m_moveWaitTime;
	//				ALERT( at_aiconsole, "Move %s!!!\n", STRING( pBlocker->pev->classname ) );
					return;
				}
			}
			else 
			{
				// try to triangulate around whatever is in the way.
				if ( FTriangulate( pev->origin, m_Route[ m_iRouteIndex ].vecLocation, flDist, pTargetEnt, &vecApex ) )
				{
					InsertWaypoint( vecApex, bits_MF_TO_DETOUR );
					RouteSimplify( pTargetEnt );
				}
				else
				{
	 			    ALERT ( at_aiconsole, "Couldn't Triangulate\n" );
					Stop();
					if ( m_moveWaitTime > 0 )
					{
						FRefreshRoute();
						m_flMoveWaitFinished = gpGlobals->time + m_moveWaitTime * 0.5;
					}
					else
					{
						TaskFail();
						ALERT( at_aiconsole, "Failed to move!\n" );
						//ALERT( at_aiconsole, "%f, %f, %f\n", pev->origin.z, (pev->origin + (vecDir * flCheckDist)).z, m_Route[m_iRouteIndex].vecLocation.z );
					}
					return;
				}
			}
		}

		// UNDONE: this is a hack to quit moving farther than it has looked ahead.
		if (flCheckDist < flMoveDist)
		{
			MoveExecute( pTargetEnt, vecDir, flCheckDist / m_flGroundSpeed );

			// ALERT( at_console, "%.02f\n", flInterval );
			AdvanceRoute( flWaypointDist );
			flMoveDist -= flCheckDist;
		}
		else
		{
			MoveExecute( pTargetEnt, vecDir, flMoveDist / m_flGroundSpeed );

			if ( ShouldAdvanceRoute( flWaypointDist - flMoveDist ) )
			{
				AdvanceRoute( flWaypointDist );
			}
			flMoveDist = 0;
		}

		if ( MovementIsComplete() )
		{
			Stop();
			RouteClear();
		}
	} while (flMoveDist > 0 && flCheckDist > 0);

	// cut corner?
	if (flWaypointDist < 128)
	{
		if ( m_movementGoal == MOVEGOAL_ENEMY )
			RouteSimplify( m_hEnemy );
		else
			RouteSimplify( m_hTargetEnt );
		FRefreshRoute();

		if (m_flGroundSpeed > 100)
			m_flGroundSpeed -= 40;
	}
	else
	{
		if (m_flGroundSpeed < 400)
			m_flGroundSpeed += 10;
	}
}
Ejemplo n.º 26
0
//=========================================================
// Start task - selects the correct activity and performs
// any necessary calculations to start the next task on the
// schedule. 
//=========================================================
void CBaseMonster :: StartTask ( Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_TURN_RIGHT:
		{
			float flCurrentYaw;
			
			flCurrentYaw = UTIL_AngleMod( pev->angles.y );
			pev->ideal_yaw = UTIL_AngleMod( flCurrentYaw - pTask->flData );
			SetTurnActivity();
			break;
		}
	case TASK_TURN_LEFT:
		{
			float flCurrentYaw;
			
			flCurrentYaw = UTIL_AngleMod( pev->angles.y );
			pev->ideal_yaw = UTIL_AngleMod( flCurrentYaw + pTask->flData );
			SetTurnActivity();
			break;
		}
	case TASK_REMEMBER:
		{
			Remember ( (int)pTask->flData );
			TaskComplete();
			break;
		}
	case TASK_FORGET:
		{
			Forget ( (int)pTask->flData );
			TaskComplete();
			break;
		}
	case TASK_FIND_HINTNODE:
		{
			m_iHintNode = FindHintNode();

			if ( m_iHintNode != NO_NODE )
			{
				TaskComplete();
			}
			else
			{
				TaskFail();
			}
			break;
		}
	case TASK_STORE_LASTPOSITION:
		{
			m_vecLastPosition = pev->origin;
			TaskComplete();
			break;
		}
	case TASK_CLEAR_LASTPOSITION:
		{
			m_vecLastPosition = g_vecZero;
			TaskComplete();
			break;
		}
	case TASK_CLEAR_HINTNODE:
		{
			m_iHintNode = NO_NODE;
			TaskComplete();
			break;
		}
	case TASK_STOP_MOVING:
		{
			if ( m_IdealActivity == m_movementActivity )
			{
				m_IdealActivity = GetStoppedActivity();
			}

			RouteClear();
			TaskComplete();
			break;
		}
	case TASK_PLAY_SEQUENCE_FACE_ENEMY:
	case TASK_PLAY_SEQUENCE_FACE_TARGET:
	case TASK_PLAY_SEQUENCE:
		{
			m_IdealActivity = ( Activity )( int )pTask->flData;
			break;
		}
	case TASK_PLAY_ACTIVE_IDLE:
		{
			// monsters verify that they have a sequence for the node's activity BEFORE
			// moving towards the node, so it's ok to just set the activity without checking here.
			m_IdealActivity = ( Activity )WorldGraph.m_pNodes[ m_iHintNode ].m_sHintActivity;
			break;
		}
	case TASK_SET_SCHEDULE:
		{
			Schedule_t *pNewSchedule;

			pNewSchedule = GetScheduleOfType( (int)pTask->flData );
			
			if ( pNewSchedule )
			{
				ChangeSchedule( pNewSchedule );
			}
			else
			{
				TaskFail();
			}

			break;
		}
	case TASK_FIND_NEAR_NODE_COVER_FROM_ENEMY:
		{
			if ( m_hEnemy == NULL )
			{
				TaskFail();
				return;
			}

			if ( FindCover( m_hEnemy->pev->origin, m_hEnemy->pev->view_ofs, 0, pTask->flData ) )
			{
				// try for cover farther than the FLData from the schedule.
				TaskComplete();
			}
			else
			{
				// no coverwhatsoever.
				TaskFail();
			}
			break;
		}
	case TASK_FIND_FAR_NODE_COVER_FROM_ENEMY:
		{
			if ( m_hEnemy == NULL )
			{
				TaskFail();
				return;
			}

			if ( FindCover( m_hEnemy->pev->origin, m_hEnemy->pev->view_ofs, pTask->flData, CoverRadius() ) )
			{
				// try for cover farther than the FLData from the schedule.
				TaskComplete();
			}
			else
			{
				// no coverwhatsoever.
				TaskFail();
			}
			break;
		}
	case TASK_FIND_NODE_COVER_FROM_ENEMY:
		{
			if ( m_hEnemy == NULL )
			{
				TaskFail();
				return;
			}

			if ( FindCover( m_hEnemy->pev->origin, m_hEnemy->pev->view_ofs, 0, CoverRadius() ) )
			{
				// try for cover farther than the FLData from the schedule.
				TaskComplete();
			}
			else
			{
				// no coverwhatsoever.
				TaskFail();
			}
			break;
		}
	case TASK_FIND_COVER_FROM_ENEMY:
		{
			entvars_t *pevCover;

			if ( m_hEnemy == NULL )
			{
				// Find cover from self if no enemy available
				pevCover = pev;
//				TaskFail();
//				return;
			}
			else
				pevCover = m_hEnemy->pev;

			if ( FindLateralCover( pevCover->origin, pevCover->view_ofs ) )
			{
				// try lateral first
				m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
				TaskComplete();
			}
			else if ( FindCover( pevCover->origin, pevCover->view_ofs, 0, CoverRadius() ) )
			{
				// then try for plain ole cover
				m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
				TaskComplete();
			}
			else
			{
				// no coverwhatsoever.
				TaskFail();
			}
			break;
		}
	case TASK_FIND_COVER_FROM_ORIGIN:
		{
			if ( FindCover( pev->origin, pev->view_ofs, 0, CoverRadius() ) )
			{
				// then try for plain ole cover
				m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
				TaskComplete();
			}
			else
			{
				// no cover!
				TaskFail();
			}
		}
		break;
	case TASK_FIND_COVER_FROM_BEST_SOUND:
		{
			CSound *pBestSound;

			pBestSound = PBestSound();

			ASSERT( pBestSound != NULL );
			/*
			if ( pBestSound && FindLateralCover( pBestSound->m_vecOrigin, g_vecZero ) )
			{
				// try lateral first
				m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
				TaskComplete();
			}
			*/

			if ( pBestSound && FindCover( pBestSound->m_vecOrigin, g_vecZero, pBestSound->m_iVolume, CoverRadius() ) )
			{
				// then try for plain ole cover
				m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
				TaskComplete();
			}
			else
			{
				// no coverwhatsoever. or no sound in list
				TaskFail();
			}
			break;
		}
	case TASK_FACE_HINTNODE:
		{
			pev->ideal_yaw = WorldGraph.m_pNodes[ m_iHintNode ].m_flHintYaw;
			SetTurnActivity();
			break;
		}
	
	case TASK_FACE_LASTPOSITION:
		MakeIdealYaw ( m_vecLastPosition );
		SetTurnActivity(); 
		break;

	case TASK_FACE_TARGET:
		if ( m_hTargetEnt != NULL )
		{
			MakeIdealYaw ( m_hTargetEnt->pev->origin );
			SetTurnActivity(); 
		}
		else
			TaskFail();
		break;
	case TASK_FACE_ENEMY:
		{
			MakeIdealYaw ( m_vecEnemyLKP );
			SetTurnActivity(); 
			break;
		}
	case TASK_FACE_IDEAL:
		{
			SetTurnActivity();
			break;
		}
	case TASK_FACE_ROUTE:
		{
			if (FRouteClear())
			{
				ALERT(at_aiconsole, "No route to face!\n");
				TaskFail();
			}
			else
			{
				MakeIdealYaw(m_Route[m_iRouteIndex].vecLocation);
				SetTurnActivity();
			}
			break;
		}
	case TASK_WAIT_PVS:
	case TASK_WAIT_INDEFINITE:
		{
			// don't do anything.
			break;
		}
	case TASK_WAIT:
	case TASK_WAIT_FACE_ENEMY:
		{// set a future time that tells us when the wait is over.
			m_flWaitFinished = gpGlobals->time + pTask->flData;	
			break;
		}
	case TASK_WAIT_RANDOM:
		{// set a future time that tells us when the wait is over.
			m_flWaitFinished = gpGlobals->time + RANDOM_FLOAT( 0.1, pTask->flData );
			break;
		}
	case TASK_MOVE_TO_TARGET_RANGE:
		{
			if ( (m_hTargetEnt->pev->origin - pev->origin).Length() < 1 )
				TaskComplete();
			else
			{
				m_vecMoveGoal = m_hTargetEnt->pev->origin;
				if ( !MoveToTarget( ACT_WALK, 2 ) )
					TaskFail();
			}
			break;
		}
	case TASK_RUN_TO_SCRIPT:
	case TASK_WALK_TO_SCRIPT:
		{
			Activity newActivity;

			if ( !m_pGoalEnt || (m_pGoalEnt->pev->origin - pev->origin).Length() < 1 )
				TaskComplete();
			else
			{
				if ( pTask->iTask == TASK_WALK_TO_SCRIPT )
					newActivity = ACT_WALK;
				else
					newActivity = ACT_RUN;
				// This monster can't do this!
				if ( LookupActivity( newActivity ) == ACTIVITY_NOT_AVAILABLE )
					TaskComplete();
				else 
				{
					if ( m_pGoalEnt != NULL )
					{
						Vector vecDest;
						vecDest = m_pGoalEnt->pev->origin;

						if ( !MoveToLocation( newActivity, 2, vecDest ) )
						{
							TaskFail();
							ALERT( at_aiconsole, "%s Failed to reach script!!!\n", STRING(pev->classname) );
							RouteClear();
						}
					}
					else
					{
						TaskFail();
						ALERT( at_aiconsole, "%s: MoveTarget is missing!?!\n", STRING(pev->classname) );
						RouteClear();
					}
				}
			}
			TaskComplete();
			break;
		}
	case TASK_CLEAR_MOVE_WAIT:
		{
			m_flMoveWaitFinished = gpGlobals->time;
			TaskComplete();
			break;
		}
	case TASK_MELEE_ATTACK1_NOTURN:
	case TASK_MELEE_ATTACK1:
		{
			m_IdealActivity = ACT_MELEE_ATTACK1;
			break;
		}
	case TASK_MELEE_ATTACK2_NOTURN:
	case TASK_MELEE_ATTACK2:
		{
			m_IdealActivity = ACT_MELEE_ATTACK2;
			break;
		}
	case TASK_RANGE_ATTACK1_NOTURN:
	case TASK_RANGE_ATTACK1:
		{
			m_IdealActivity = ACT_RANGE_ATTACK1;
			break;
		}
	case TASK_RANGE_ATTACK2_NOTURN:
	case TASK_RANGE_ATTACK2:
		{
			m_IdealActivity = ACT_RANGE_ATTACK2;
			break;
		}
	case TASK_RELOAD_NOTURN:
	case TASK_RELOAD:
		{
			m_IdealActivity = ACT_RELOAD;
			break;
		}
	case TASK_SPECIAL_ATTACK1:
		{
			m_IdealActivity = ACT_SPECIAL_ATTACK1;
			break;
		}
	case TASK_SPECIAL_ATTACK2:
		{
			m_IdealActivity = ACT_SPECIAL_ATTACK2;
			break;
		}
	case TASK_SET_ACTIVITY:
		{
			m_IdealActivity = (Activity)(int)pTask->flData;
			TaskComplete();
			break;
		}
	case TASK_GET_PATH_TO_ENEMY_LKP:
		{
			if ( BuildRoute ( m_vecEnemyLKP, bits_MF_TO_LOCATION, NULL ) )
			{
				TaskComplete();
			}
			else if (BuildNearestRoute( m_vecEnemyLKP, pev->view_ofs, 0, (m_vecEnemyLKP - pev->origin).Length() ))
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToEnemyLKP failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_ENEMY:
		{
			CBaseEntity *pEnemy = m_hEnemy;

			if ( pEnemy == NULL )
			{
				TaskFail();
				return;
			}

			if ( BuildRoute ( pEnemy->pev->origin, bits_MF_TO_ENEMY, pEnemy ) )
			{
				TaskComplete();
			}
			else if (BuildNearestRoute( pEnemy->pev->origin, pEnemy->pev->view_ofs, 0, (pEnemy->pev->origin - pev->origin).Length() ))
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToEnemy failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_ENEMY_CORPSE:
		{
			UTIL_MakeVectors( pev->angles );
			if ( BuildRoute ( m_vecEnemyLKP - gpGlobals->v_forward * 64, bits_MF_TO_LOCATION, NULL ) )
			{
				TaskComplete();
			}
			else
			{
				ALERT ( at_aiconsole, "GetPathToEnemyCorpse failed!!\n" );
				TaskFail();
			}
		}
		break;
	case TASK_GET_PATH_TO_SPOT:
		{
			CBaseEntity *pPlayer = UTIL_FindEntityByClassname( NULL, "player" );
			if ( BuildRoute ( m_vecMoveGoal, bits_MF_TO_LOCATION, pPlayer ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToSpot failed!!\n" );
				TaskFail();
			}
			break;
		}

	case TASK_GET_PATH_TO_TARGET:
		{
			RouteClear();
			if ( m_hTargetEnt != NULL && MoveToTarget( m_movementActivity, 1 ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToSpot failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_SCRIPT:
		{
			RouteClear();
			if ( m_pCine != NULL && MoveToLocation( m_movementActivity, 1, m_pCine->pev->origin ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToSpot failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_HINTNODE:// for active idles!
		{
			if ( MoveToLocation( m_movementActivity, 2, WorldGraph.m_pNodes[ m_iHintNode ].m_vecOrigin ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToHintNode failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_LASTPOSITION:
		{
			m_vecMoveGoal = m_vecLastPosition;

			if ( MoveToLocation( m_movementActivity, 2, m_vecMoveGoal ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToLastPosition failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_BESTSOUND:
		{
			CSound *pSound;

			pSound = PBestSound();

			if ( pSound && MoveToLocation( m_movementActivity, 2, pSound->m_vecOrigin ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToBestSound failed!!\n" );
				TaskFail();
			}
			break;
		}
case TASK_GET_PATH_TO_BESTSCENT:
		{
			CSound *pScent;

			pScent = PBestScent();

			if ( pScent && MoveToLocation( m_movementActivity, 2, pScent->m_vecOrigin ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToBestScent failed!!\n" );
				
				TaskFail();
			}
			break;
		}
	case TASK_RUN_PATH:
		{
			// UNDONE: This is in some default AI and some monsters can't run? -- walk instead?
			if ( LookupActivity( ACT_RUN ) != ACTIVITY_NOT_AVAILABLE )
			{
				m_movementActivity = ACT_RUN;
			}
			else
			{
				m_movementActivity = ACT_WALK;
			}
			TaskComplete();
			break;
		}
	case TASK_WALK_PATH:
		{
			if ( pev->movetype == MOVETYPE_FLY )
			{
				m_movementActivity = ACT_FLY;
			}
			if ( LookupActivity( ACT_WALK ) != ACTIVITY_NOT_AVAILABLE )
			{
				m_movementActivity = ACT_WALK;
			}
			else
			{
				m_movementActivity = ACT_RUN;
			}
			TaskComplete();
			break;
		}
	case TASK_STRAFE_PATH:
		{
			Vector2D	vec2DirToPoint; 
			Vector2D	vec2RightSide;

			// to start strafing, we have to first figure out if the target is on the left side or right side
			UTIL_MakeVectors ( pev->angles );

			vec2DirToPoint = ( m_Route[ 0 ].vecLocation - pev->origin ).Make2D().Normalize();
			vec2RightSide = gpGlobals->v_right.Make2D().Normalize();

			if ( DotProduct ( vec2DirToPoint, vec2RightSide ) > 0 )
			{
				// strafe right
				m_movementActivity = ACT_STRAFE_RIGHT;
			}
			else
			{
				// strafe left
				m_movementActivity = ACT_STRAFE_LEFT;
			}
			TaskComplete();
			break;
		}


	case TASK_WAIT_FOR_MOVEMENT:
		{
			if (FRouteClear())
			{
				TaskComplete();
			}
			break;
		}

	case TASK_EAT:
		{
			Eat( pTask->flData );
			TaskComplete();
			break;
		}
	case TASK_SMALL_FLINCH:
		{
			m_IdealActivity = GetSmallFlinchActivity();
			break;
		}
	case TASK_DIE:
		{
			RouteClear();	
			
			m_IdealActivity = GetDeathActivity();

			pev->deadflag = DEAD_DYING;
			break;
		}
	case TASK_SOUND_WAKE:
		{
			AlertSound();
			TaskComplete();
			break;
		}
	case TASK_SOUND_DIE:
		{
			DeathSound();
			TaskComplete();
			break;
		}
	case TASK_SOUND_IDLE:
		{
			IdleSound();
			TaskComplete();
			break;
		}
	case TASK_SOUND_PAIN:
		{
			PainSound();
			TaskComplete();
			break;
		}
	case TASK_SOUND_DEATH:
		{
			DeathSound();
			TaskComplete();
			break;
		}
	case TASK_SOUND_ANGRY:
		{
			// sounds are complete as soon as we get here, cause we've already played them.
			ALERT ( at_aiconsole, "SOUND\n" );			
			TaskComplete();
			break;
		}
	case TASK_WAIT_FOR_SCRIPT:
		{
			if ( m_pCine->m_iDelay <= 0 && gpGlobals->time >= m_pCine->m_startTime )
			{
				TaskComplete(); //LRC - start playing immediately
			}
			else if (!m_pCine->IsAction() && m_pCine->m_iszIdle)
			{
				m_pCine->StartSequence( (CBaseMonster *)this, m_pCine->m_iszIdle, FALSE );
				if (FStrEq( STRING(m_pCine->m_iszIdle), STRING(m_pCine->m_iszPlay)))
				{
					pev->framerate = 0;
				}
			}
			else
				m_IdealActivity = ACT_IDLE;

			break;
		}
	case TASK_PLAY_SCRIPT:
		{
			if (m_pCine->IsAction())
			{
				//ALERT(at_console,"PlayScript: setting idealactivity %d\n",m_pCine->m_fAction);
				switch(m_pCine->m_fAction)
				{
				case 0:
					m_IdealActivity = ACT_RANGE_ATTACK1; break;
				case 1:
					m_IdealActivity = ACT_RANGE_ATTACK2; break;
				case 2:
					m_IdealActivity = ACT_MELEE_ATTACK1; break;
				case 3:
					m_IdealActivity = ACT_MELEE_ATTACK2; break;
				case 4:
					m_IdealActivity = ACT_SPECIAL_ATTACK1; break;
				case 5:
					m_IdealActivity = ACT_SPECIAL_ATTACK2; break;
				case 6:
					m_IdealActivity = ACT_RELOAD; break;
				case 7:
					m_IdealActivity = ACT_HOP; break;
				}
				pev->framerate = 1.0; // shouldn't be needed, but just in case
				pev->movetype = MOVETYPE_FLY;
				ClearBits(pev->flags, FL_ONGROUND);
			}
			else
			{
				m_pCine->StartSequence( (CBaseMonster *)this, m_pCine->m_iszPlay, TRUE );
				if ( m_fSequenceFinished )
					ClearSchedule();
				pev->framerate = 1.0;
				//ALERT( at_aiconsole, "Script %s has begun for %s\n", STRING( m_pCine->m_iszPlay ), STRING(pev->classname) );
			}
			m_scriptState = SCRIPT_PLAYING;
			break;
		}
	case TASK_ENABLE_SCRIPT:
		{
			m_pCine->DelayStart( 0 );
			TaskComplete();
			break;
		}
//LRC
	case TASK_END_SCRIPT:
		{
			m_pCine->SequenceDone( this );
			TaskComplete();
			break;
		}
	case TASK_PLANT_ON_SCRIPT:
		{
			if ( m_pCine != NULL )
			{
				// Plant on script
				// LRC - if it's a teleport script, do the turn too
				if (m_pCine->m_fMoveTo == 4 || m_pCine->m_fMoveTo == 6)
				{
					if (m_pCine->m_fTurnType == 0) //LRC
						pev->angles.y = m_hTargetEnt->pev->angles.y;
					else if (m_pCine->m_fTurnType == 1)
						pev->angles.y = UTIL_VecToYaw(m_hTargetEnt->pev->origin - pev->origin);
					pev->ideal_yaw = pev->angles.y;
					pev->avelocity = Vector( 0, 0, 0 );
					pev->velocity = Vector( 0, 0, 0 );
					pev->effects |= EF_NOINTERP;
				}

				if (m_pCine->m_fMoveTo != 6)
					pev->origin = m_pGoalEnt->pev->origin;
			}

			TaskComplete();
			break;
		}
	case TASK_FACE_SCRIPT:
		{
			if ( m_pCine != NULL && m_pCine->m_fMoveTo != 0) // movetype "no move" makes us ignore turntype
			{
				switch (m_pCine->m_fTurnType)
				{
				case 0:
					pev->ideal_yaw = UTIL_AngleMod( m_pCine->pev->angles.y );
					break;
				case 1:
					// yes, this is inconsistent- turn to face uses the "target" and turn to angle uses the "cine".
					if (m_hTargetEnt)
						MakeIdealYaw ( m_hTargetEnt->pev->origin );
					else
						MakeIdealYaw ( m_pCine->pev->origin );
					break;
				// default: don't turn
				}
			}

			TaskComplete();
			m_IdealActivity = ACT_IDLE;
			RouteClear();
			break;
		}
	case TASK_SUGGEST_STATE:
		{
			m_IdealMonsterState = (MONSTERSTATE)(int)pTask->flData;
			TaskComplete();
			break;
		}

	case TASK_SET_FAIL_SCHEDULE:
		m_failSchedule = (int)pTask->flData;
		TaskComplete();
		break;

	case TASK_CLEAR_FAIL_SCHEDULE:
		m_failSchedule = SCHED_NONE;
		TaskComplete();
		break;

	default:
		{
			ALERT ( at_aiconsole, "No StartTask entry for %d\n", (SHARED_TASKS)pTask->iTask );
			break;
		}
	}
}
Ejemplo n.º 27
0
int DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity)
{
	CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);

	if(pEntity && pSaveData)
	{
		entvars_t tmpVars;
		Vector    oldOffset;

		CRestore restoreHelper(pSaveData);
		if(globalEntity)
		{
			CRestore tmpRestore(pSaveData);
			tmpRestore.PrecacheMode(0);
			tmpRestore.ReadEntVars("ENTVARS", &tmpVars);

			// HACKHACK - reset the save pointers, we're going to restore for real this time
			pSaveData->size         = pSaveData->pTable[pSaveData->currentIndex].location;
			pSaveData->pCurrentData = pSaveData->pBaseData + pSaveData->size;
			// -------------------

			const globalentity_t *pGlobal = gGlobalState.EntityFromTable(tmpVars.globalname);

			// Don't overlay any instance of the global that isn't the latest
			// pSaveData->szCurrentMapName is the level this entity is coming from
			// pGlobla->levelName is the last level the global entity was active in.
			// If they aren't the same, then this global update is out of date.
			if(!FStrEq(pSaveData->szCurrentMapName, pGlobal->levelName))
				return 0;

			// Compute the new global offset
			oldOffset               = pSaveData->vecLandmarkOffset;
			CBaseEntity *pNewEntity = FindGlobalEntity(tmpVars.classname, tmpVars.globalname);
			if(pNewEntity)
			{
				//				ALERT( at_console, "Overlay %s with %s\n", STRING(pNewEntity->pev->classname), STRING(tmpVars.classname) );
				// Tell the restore code we're overlaying a global entity from another level
				restoreHelper.SetGlobalMode(1); // Don't overwrite global fields
				pSaveData->vecLandmarkOffset = (pSaveData->vecLandmarkOffset - pNewEntity->pev->mins) + tmpVars.mins;
				pEntity                      = pNewEntity; // we're going to restore this data OVER the old entity
				pent                         = ENT(pEntity->pev);
				// Update the global table to say that the global definition of this entity should come from this level
				gGlobalState.EntityUpdate(pEntity->pev->globalname, gpGlobals->mapname);
			}
			else
			{
				// This entity will be freed automatically by the engine.  If we don't do a restore on a matching entity (below)
				// or call EntityUpdate() to move it to this level, we haven't changed global state at all.
				return 0;
			}
		}

		if(pEntity->ObjectCaps() & FCAP_MUST_SPAWN)
		{
			pEntity->Restore(restoreHelper);
			pEntity->Spawn();
		}
		else
		{
			pEntity->Restore(restoreHelper);
			pEntity->Precache();
		}

		// Again, could be deleted, get the pointer again.
		pEntity = (CBaseEntity *)GET_PRIVATE(pent);

#if 0
		if ( pEntity && pEntity->pev->globalname && globalEntity ) 
		{
			ALERT( at_console, "Global %s is %s\n", STRING(pEntity->pev->globalname), STRING(pEntity->pev->model) );
		}
#endif

		// Is this an overriding global entity (coming over the transition), or one restoring in a level
		if(globalEntity)
		{
			//			ALERT( at_console, "After: %f %f %f %s\n", pEntity->pev->origin.x, pEntity->pev->origin.y, pEntity->pev->origin.z, STRING(pEntity->pev->model) );
			pSaveData->vecLandmarkOffset = oldOffset;
			if(pEntity)
			{
				UTIL_SetOrigin(pEntity->pev, pEntity->pev->origin);
				pEntity->OverrideReset();
			}
		}
		else if(pEntity && pEntity->pev->globalname)
		{
			const globalentity_t *pGlobal = gGlobalState.EntityFromTable(pEntity->pev->globalname);
			if(pGlobal)
			{
				// Already dead? delete
				if(pGlobal->state == GLOBAL_DEAD)
					return -1;
				else if(!FStrEq(STRING(gpGlobals->mapname), pGlobal->levelName))
				{
					pEntity->MakeDormant(); // Hasn't been moved to this level yet, wait but stay alive
				}
				// In this level & not dead, continue on as normal
			}
			else
			{
				ALERT(at_error, "Global Entity %s (%s) not in table!!!\n", STRING(pEntity->pev->globalname), STRING(pEntity->pev->classname));
				// Spawned entities default to 'On'
				gGlobalState.EntityAdd(pEntity->pev->globalname, gpGlobals->mapname, GLOBAL_ON);
			}
		}
	}
	return 0;
}
Ejemplo n.º 28
0
void CBigMomma::StartTask( Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_FIND_NODE:
		{
			CBaseEntity *pTarget = m_hTargetEnt;
			if ( !HasMemory( bits_MEMORY_ADVANCE_NODE ) )
			{
				if ( pTarget )
					pev->netname = m_hTargetEnt->pev->target;
			}
			NodeStart( pev->netname );
			TaskComplete();
			ALERT( at_aiconsole, "BM: Found node %s\n", STRING(pev->netname) );
		}
		break;

	case TASK_NODE_DELAY:
		m_nodeTime = gpGlobals->time + pTask->flData;
		TaskComplete();
		ALERT( at_aiconsole, "BM: FAIL! Delay %.2f\n", pTask->flData );
		break;

	case TASK_PROCESS_NODE:
		ALERT( at_aiconsole, "BM: Reached node %s\n", STRING(pev->netname) );
		NodeReach();
		TaskComplete();
		break;

	case TASK_PLAY_NODE_PRESEQUENCE:
	case TASK_PLAY_NODE_SEQUENCE:
		{
			int sequence;
			if ( pTask->iTask == TASK_PLAY_NODE_SEQUENCE )
				sequence = GetNodeSequence();
			else
				sequence = GetNodePresequence();

			ALERT( at_aiconsole, "BM: Playing node sequence %s\n", STRING(sequence) );
			if ( sequence )
			{
				sequence = LookupSequence( STRING( sequence ) );
				if ( sequence != -1 )
				{
					pev->sequence = sequence;
					pev->frame = 0;
					ResetSequenceInfo( );
					ALERT( at_aiconsole, "BM: Sequence %s\n", STRING(GetNodeSequence()) );
					return;
				}
			}
			TaskComplete();
		}
		break;

	case TASK_NODE_YAW:
		pev->ideal_yaw = GetNodeYaw();
		TaskComplete();
		break;

	case TASK_WAIT_NODE:
		m_flWait = gpGlobals->time + GetNodeDelay();
		if ( m_hTargetEnt->pev->spawnflags & SF_INFOBM_WAIT )
			ALERT( at_aiconsole, "BM: Wait at node %s forever\n", STRING(pev->netname) );
		else
			ALERT( at_aiconsole, "BM: Wait at node %s for %.2f\n", STRING(pev->netname), GetNodeDelay() );
		break;


	case TASK_MOVE_TO_NODE_RANGE:
		{
			CBaseEntity *pTarget = m_hTargetEnt;
			if ( !pTarget )
				TaskFail();
			else
			{
				if ( (pTarget->pev->origin - pev->origin).Length() < GetNodeRange() )
					TaskComplete();
				else
				{
					Activity act = ACT_WALK;
					if ( pTarget->pev->spawnflags & SF_INFOBM_RUN )
						act = ACT_RUN;

					m_vecMoveGoal = pTarget->pev->origin;
					if ( !MoveToTarget( act, 2 ) )
					{
						TaskFail();
					}
				}
			}
		}
		ALERT( at_aiconsole, "BM: Moving to node %s\n", STRING(pev->netname) );

		break;

	case TASK_MELEE_ATTACK1:
		// Play an attack sound here
		EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pAttackSounds), 1.0, ATTN_NORM, 0, PITCH_NORM );
		CBaseMonster::StartTask( pTask );
		break;

	default: 
		CBaseMonster::StartTask( pTask );
		break;
	}
}
Ejemplo n.º 29
0
int FindTransition( void *pmodel, int iEndingAnim, int iGoalAnim, int *piDir )
{
	studiohdr_t *pstudiohdr;
	
	pstudiohdr = (studiohdr_t *)pmodel;
	if (! pstudiohdr)
		return iGoalAnim;

	mstudioseqdesc_t	*pseqdesc;
	pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);

	// bail if we're going to or from a node 0
	if (pseqdesc[iEndingAnim].entrynode == 0 || pseqdesc[iGoalAnim].entrynode == 0)
	{
		return iGoalAnim;
	}

	int	iEndNode;

	// ALERT( at_console, "from %d to %d: ", pEndNode->iEndNode, pGoalNode->iStartNode );

	if (*piDir > 0)
	{
		iEndNode = pseqdesc[iEndingAnim].exitnode;
	}
	else
	{
		iEndNode = pseqdesc[iEndingAnim].entrynode;
	}

	if (iEndNode == pseqdesc[iGoalAnim].entrynode)
	{
		*piDir = 1;
		return iGoalAnim;
	}

	byte *pTransition = ((byte *)pstudiohdr + pstudiohdr->transitionindex);

	int iInternNode = pTransition[(iEndNode-1)*pstudiohdr->numtransitions + (pseqdesc[iGoalAnim].entrynode-1)];

	if (iInternNode == 0)
		return iGoalAnim;

	int i;

	// look for someone going
	for (i = 0; i < pstudiohdr->numseq; i++)
	{
		if (pseqdesc[i].entrynode == iEndNode && pseqdesc[i].exitnode == iInternNode)
		{
			*piDir = 1;
			return i;
		}
		if (pseqdesc[i].nodeflags)
		{
			if (pseqdesc[i].exitnode == iEndNode && pseqdesc[i].entrynode == iInternNode)
			{
				*piDir = -1;
				return i;
			}
		}
	}

	ALERT( at_console, "error in transition graph" );
	return iGoalAnim;
}
Ejemplo n.º 30
0
//=========================================================
// MakeMonster-  this is the code that drops the monster
//=========================================================
void CMonsterMaker::MakeMonster( void )
{
	edict_t	*pent;
	entvars_t		*pevCreate;

	if ( m_iMaxLiveChildren > 0 && m_cLiveChildren >= m_iMaxLiveChildren )
	{// not allowed to make a new one yet. Too many live ones out right now.
		return;
	}

	if ( !m_flGround )
	{
		// set altitude. Now that I'm activated, any breakables, etc should be out from under me. 
		TraceResult tr;

		UTIL_TraceLine ( pev->origin, pev->origin - Vector ( 0, 0, 2048 ), ignore_monsters, ENT(pev), &tr );
		m_flGround = tr.vecEndPos.z;
	}

	Vector mins = pev->origin - Vector( 34, 34, 0 );
	Vector maxs = pev->origin + Vector( 34, 34, 0 );
	maxs.z = pev->origin.z;
	mins.z = m_flGround;

	CBaseEntity *pList[2];
	int count = UTIL_EntitiesInBox( pList, 2, mins, maxs, FL_CLIENT|FL_MONSTER );
	if ( count )
	{
		// don't build a stack of monsters!
		return;
	}

	pent = CREATE_NAMED_ENTITY( m_iszMonsterClassname );

	if ( FNullEnt( pent ) )
	{
		ALERT ( at_console, "NULL Ent in MonsterMaker!\n" );
		return;
	}
	
	// If I have a target, fire!
	if ( !FStringNull ( pev->target ) )
	{
		// delay already overloaded for this entity, so can't call SUB_UseTargets()
		FireTargets( STRING(pev->target), this, this, USE_TOGGLE, 0 );
	}

	pevCreate = VARS( pent );
	pevCreate->origin = pev->origin;
	pevCreate->angles = pev->angles;
	SetBits( pevCreate->spawnflags, SF_MONSTER_FALL_TO_GROUND );

	// Children hit monsterclip brushes
	if ( pev->spawnflags & SF_MONSTERMAKER_MONSTERCLIP )
		SetBits( pevCreate->spawnflags, SF_MONSTER_HITMONSTERCLIP );

	DispatchSpawn( ENT( pevCreate ) );
	pevCreate->owner = edict();

	if ( !FStringNull( pev->netname ) )
	{
		// if I have a netname (overloaded), give the child monster that name as a targetname
		pevCreate->targetname = pev->netname;
	}

	m_cLiveChildren++;// count this monster
	m_cNumMonsters--;

	if ( m_cNumMonsters == 0 )
	{
		// Disable this forever.  Don't kill it because it still gets death notices
		SetThink( NULL );
		SetUse( NULL );
	}
}