/* ============================== G_FireAllTargetsOf "activator" should be set to the entity that initiated the firing. For all t in the entities, where t.targetnames[i] matches ent.targets[j] for any (i,j) pairs, call the t.use function. ============================== */ void G_EventFireEntity( gentity_t *self, gentity_t *activator, gentityCallEvent_t eventType ) { gentity_t *currentTarget = nullptr; int targetIndex; gentityCall_t call; call.activator = activator; while( ( currentTarget = G_IterateCallEndpoints( currentTarget, &targetIndex, self ) ) != nullptr ) { if( eventType && self->calltargets[ targetIndex ].eventType != eventType ) { continue; } call.caller = self; //reset the caller in case there have been nested calls call.definition = &self->calltargets[ targetIndex ]; G_CallEntity(currentTarget, &call); if ( !self->inuse ) { G_Printf( S_WARNING "entity was removed while using targets\n" ); return; } } }
/* ============================== G_FireAllTargetsOf "activator" should be set to the entity that initiated the firing. For all t in the entities, where t.targetnames[i] matches ent.targets[j] for any (i,j) pairs, call the t.use function. ============================== */ void G_EventFireEntity( gentity_t *self, gentity_t *activator, gentityCallEvent_t eventType ) { gentity_t *currentTarget = NULL; int targetIndex; gentityCall_t call; call.activator = activator; if ( self->shaderKey && self->shaderReplacement ) { G_SetShaderRemap( self->shaderKey, self->shaderReplacement, level.time * 0.001 ); trap_SetConfigstring( CS_SHADERSTATE, BuildShaderStateConfig() ); } while( ( currentTarget = G_IterateCallEndpoints( currentTarget, &targetIndex, self ) ) != NULL ) { if( eventType && self->calltargets[ targetIndex ].eventType != eventType ) { continue; } call.caller = self; //reset the caller in case there have been nested calls call.definition = &self->calltargets[ targetIndex ]; G_CallEntity(currentTarget, &call); if ( !self->inuse ) { G_Printf( S_WARNING "entity was removed while using targets\n" ); return; } } }
void G_FireEntityRandomly( gentity_t *entity, gentity_t *activator ) { int targetIndex; gentity_t *possibleTarget = nullptr; int totalChoiceCount = 0; gentityCall_t call; gentityTargetChoice_t choices[ MAX_GENTITIES ]; gentityTargetChoice_t *selectedChoice; //collects the targets while( ( possibleTarget = G_IterateCallEndpoints( possibleTarget, &targetIndex, entity ) ) != nullptr ) { choices[ totalChoiceCount ].recipient = possibleTarget; choices[ totalChoiceCount ].callDefinition = &entity->calltargets[targetIndex]; totalChoiceCount++; } if ( totalChoiceCount == 0 ) return; //return a random one from among the choices selectedChoice = &choices[ rand() / ( RAND_MAX / totalChoiceCount + 1 ) ]; call.definition = selectedChoice->callDefinition; call.caller = entity; call.activator = activator; G_CallEntity( selectedChoice->recipient, &call ); }
void Svcmd_EntityFire_f() { char argument[ MAX_STRING_CHARS ]; int entityNum; gentity_t *selection; gentityCall_t call; gentityCallDefinition_t callDefinition = { nullptr, ON_DEFAULT, nullptr, nullptr, ECA_DEFAULT }; if ( trap_Argc() < 2 || trap_Argc() > 3 ) { G_Printf( "usage: entityFire <entityNum> [<action>]\n" ); return; } trap_Argv( 1, argument, sizeof( argument ) ); entityNum = atoi( argument ); if ( entityNum >= level.num_entities || entityNum < MAX_CLIENTS ) { G_Printf( "invalid entityId %d\n", entityNum ); return; } selection = &g_entities[entityNum]; if (!selection->inuse) { G_Printf("entity slot %d is not in use\n", entityNum); return; } if( trap_Argc() >= 3 ) { trap_Argv( 2, argument, sizeof( argument ) ); callDefinition.action = argument; callDefinition.actionType = G_GetCallActionTypeFor( callDefinition.action ); } G_Printf( "firing %s:%s\n", etos( selection ), callDefinition.action ? callDefinition.action : "default" ); if(selection->names[0]) callDefinition.name = selection->names[0]; call.definition = &callDefinition; call.caller = &g_entities[ ENTITYNUM_NONE ]; call.activator = &g_entities[ ENTITYNUM_NONE ] ; G_CallEntity(selection, &call); }