PDA

View Full Version : Copying/creating and removing brush entities



Puchi
14-04-2016, 08:22 AM
I want to copy a brush entity every time a player joins, and remove it when the player leaves.
To do all that, I want to to assign a target name with the number you can grab via "g_PlayerFuncs.FindPlayerByIndex". This gives the brush entity a unique targetname i can use with that player alone.
what would be the best way, i know i can use trigger_entitycreate and continue in AS. Or is there an AS solution?

further, currently I do this:

for (int iPlayer = 1; iPlayer <= g_Engine.maxClients; ++iPlayer)
{
CBasePlayer@ pPlayer = g_PlayerFuncs.FindPlayerByIndex(iPlayer);

if (pPlayer !is null && pPlayer.IsConnected())
{

I assume i can use "pPlayer.IsConnected()" to remove the brush entity with that player index?

Solokiller
14-04-2016, 09:20 AM
You assumed correctly. It would be something like this:



/**
* Creates a copy of a brush and gives it a name.
* @param szTemplateTargetname Targetname of the brush to copy the model from.
* @param szTargetname Targetname to give to the entity.
* @return On success, returns the new entity, null otherwise.
*/
CBaseEntity@ CreateBrushCopy( const string& in szTemplateTargetname, const string& in szTargetname )
{
CBaseEntity@ pEntity = g_EntityFuncs.FindEntityByTargetname( null, szTemplateTargetname );

if( pEntity is null )
{
//Brush was removed.
return null;
}

//Sanity check. Brush models start with a *
if( !string( pEntity.pev.model ).StartsWith( "*" ) )
{
return null;
}

Vector vecOrigin; //Set destination origin here

CBaseEntity@ pNew = g_EntityFuncs.Create( "func_wall", vecOrigin, g_vecZero, true );

if( pNew is null )
{
//Couldn't create the entity for some reason
return null;
}

//Copy the brush model.
pNew.SetModel( pEntity.pev.model );

//Give it a name
pNew.pev.targetname = szTargetname;

//Copy additional keyvalues here

g_EntityFuncs.DispatchSpawn( pNew.edict() );

return pNew;
}


To generate a unique name, you can use the player's entity index:


/**
* Generates a unique targetname for an entity based on a player.
* @param szBaseName The base of the targetname, e.g. "brush".
* @param pPlayer The player to use to generate the unique name.
* @return Unique name, or an empty string. e.g. "brush3"
*/
string GenerateUniquePlayerName( const string& in szBaseName, CBasePlayer@ pPlayer )
{
if( pPlayer is null )
return "";

return szBaseName + pPlayer.entindex();
}


If the entindex isn't good enough, or you need more than just a unique name (connection instance perhaps?), you can use the engine assigned user id:


szBaseName + GetPlayerUserId( pPlayer.edict() );


This name is guaranteed to be unique even if the player leaves and another joins into the same slot, unless the server runs for so long on one map that it overflows the auth id counter and starts reusing them (which will pretty much never happen, unless you brute force it).

Puchi
14-04-2016, 10:04 AM
You assumed correctly. It would be something like this:



/**
* Creates a copy of a brush and gives it a name.
* @param szTemplateTargetname Targetname of the brush to copy the model from.
* @param szTargetname Targetname to give to the entity.
* @return On success, returns the new entity, null otherwise.
*/
CBaseEntity@ CreateBrushCopy( const string& in szTemplateTargetname, const string& in szTargetname )
{
CBaseEntity@ pEntity = g_EntityFuncs.FindEntityByTargetname( null, szTemplateTargetname );

if( pEntity is null )
{
//Brush was removed.
return null;
}

//Sanity check. Brush models start with a *
if( !string( pEntity.pev.model ).StartsWith( "*" ) )
{
return null;
}

Vector vecOrigin; //Set destination origin here

CBaseEntity@ pNew = g_EntityFuncs.Create( "func_wall", vecOrigin, g_vecZero, true );

if( pNew is null )
{
//Couldn't create the entity for some reason
return null;
}

//Copy the brush model.
pNew.SetModel( pEntity.pev.model );

//Give it a name
pNew.pev.targetname = szTargetname;

//Copy additional keyvalues here

g_EntityFuncs.DispatchSpawn( pNew.edict() );

return pNew;
}



Awesome, Sir.
This is even more easy than I imagined, and fits my needs without an interface in the map which could interfere. Gonna try later.

Puchi
17-04-2016, 10:39 AM
working like a charm.
however, had to correct "pNew.SetModel( pEntity.pev.model );" to "g_EntityFuncs.SetModel(pNew,pEntity.pev.model);"