void SP_trigger_hurt(gentity_t * self) { InitTrigger(self); G_SpawnBoolean("start_off", "0", &self->start_off); G_SpawnBoolean("silent", "0", &self->silent); G_SpawnBoolean("no_protection", "0", &self->no_protection); G_SpawnBoolean("slow", "0", &self->slow); self->soundIndex = G_SoundIndex("sound/player/fry.ogg"); self->touch = hurt_touch; if(!self->damage) { self->damage = 5; } self->r.contents = CONTENTS_TRIGGER; /* if(self->spawnflags & 2) { self->use = hurt_use; } */ // link in to the world if starting active if(!self->start_off) { trap_LinkEntity(self); } }
void SP_target_relay(gentity_t * self) { G_SpawnBoolean("red_only", "0", &self->red_only); G_SpawnBoolean("blue_only", "0", &self->blue_only); G_SpawnFloat("random", "0", &self->random); self->use = target_relay_use; }
void SP_target_print(gentity_t * ent) { G_SpawnBoolean("red_only", "0", &ent->red_only); G_SpawnBoolean("blue_only", "0", &ent->blue_only); G_SpawnBoolean("private", "0", &ent->priv); ent->use = Use_Target_Print; }
/*QUAKED trigger_flagonly_multiple (.5 .5 .5) ? Player must be carrying the appropriate flag for it to trigger. Either red_only or blue_only must be set. */ void SP_trigger_flagonly_multiple(gentity_t * ent) { G_SpawnBoolean("red_only", "0", &ent->red_only); G_SpawnBoolean("blue_only", "0", &ent->blue_only); ent->touch = Touch_Flagonly_Multi; //ent->use = Use_Multi; InitTrigger(ent); trap_LinkEntity(ent); }
void SP_func_timer(gentity_t * self) { qboolean start_on; G_SpawnFloat("random", "1", &self->random); G_SpawnFloat("wait", "1", &self->wait); self->use = func_timer_use; self->think = func_timer_think; if(self->random >= self->wait) { self->random = self->wait - FRAMETIME; G_Printf("func_timer at %s has random >= wait\n", vtos(self->s.origin)); } G_SpawnBoolean("start_on", "0", &start_on); if(start_on) { self->nextthink = level.time + FRAMETIME; self->activator = self; } self->r.svFlags = SVF_NOCLIENT; }
/*QUAKED target_push (.5 .5 .5) (-8 -8 -8) (8 8 8) bouncepad Pushes the activator in the direction.of angle, or towards a target apex. "speed" defaults to 1000 if "bouncepad", play bounce noise instead of windfly */ void SP_target_push(gentity_t * self) { qboolean bouncepad; if(!self->speed) { self->speed = 1000; } G_SetMovedir(self->s.angles, self->s.origin2); VectorScale(self->s.origin2, self->speed, self->s.origin2); // Tr3B: FIXME sounds G_SpawnBoolean("bouncepad", "0", &bouncepad); if(bouncepad) { self->soundIndex = G_SoundIndex("sound/world/jumppad.wav"); } else { self->soundIndex = G_SoundIndex("sound/misc/windfly.wav"); } if(self->target) { VectorCopy(self->s.origin, self->r.absmin); VectorCopy(self->s.origin, self->r.absmax); self->think = AimAtTarget; self->nextthink = level.time + FRAMETIME; } self->use = Use_target_push; }
/*QUAKED misc_portal_camera (0 0 1) (-8 -8 -8) (8 8 8) slowrotate fastrotate noswing The target for a misc_portal_director. You can set either angles or target another entity to determine the direction of view. "roll" an angle modifier to orient the camera around the target vector; */ void SP_misc_portal_camera(gentity_t * ent) { float roll; G_SpawnBoolean("slowrotate", "0", &ent->slowrotate); G_SpawnBoolean("fastrotate", "0", &ent->fastrotate); G_SpawnBoolean("swing", "0", &ent->swing); VectorClear(ent->r.mins); VectorClear(ent->r.maxs); trap_LinkEntity(ent); G_SpawnFloat("roll", "0", &roll); ent->s.clientNum = roll / 360.0 * 256; }
void SP_target_laser(gentity_t * self) { G_SpawnBoolean("start_on", "0", &self->start_on); // let everything else get spawned before we start firing self->think = target_laser_start; self->nextthink = level.time + FRAMETIME; }
/*QUAKED trigger_multiple (.5 .5 .5) ? "wait" : Seconds between triggerings, 0.5 default, -1 = one time only. "random" wait variance, default is 0 Variable sized repeatable trigger. Must be targeted at one or more entities. so, the basic time between firing is a random time between (wait - random) and (wait + random) */ void SP_trigger_multiple(gentity_t * ent) { G_SpawnFloat("wait", "0.5", &ent->wait); G_SpawnFloat("random", "0", &ent->random); G_SpawnBoolean("red_only", "0", &ent->red_only); G_SpawnBoolean("blue_only", "0", &ent->blue_only); if(ent->random >= ent->wait && ent->wait >= 0) { ent->random = ent->wait - FRAMETIME; G_Printf("trigger_multiple has random >= wait\n"); } ent->touch = Touch_Multi; ent->use = Use_Multi; InitTrigger(ent); trap_LinkEntity(ent); }
/* =================== G_SpawnGEntityFromSpawnVars Spawn an entity and fill in all of the level fields from level.spawnVars[], then call the class specfic spawn function =================== */ void G_SpawnGEntityFromSpawnVars( void ) { int i, j; gentity_t *spawningEntity; // get the next free entity spawningEntity = G_NewEntity(); for ( i = 0; i < level.numSpawnVars; i++ ) { G_ParseField( level.spawnVars[ i ][ 0 ], level.spawnVars[ i ][ 1 ], spawningEntity ); } if(G_SpawnBoolean( "nop", qfalse ) || G_SpawnBoolean( "notunv", qfalse )) { G_FreeEntity( spawningEntity ); return; } /* * will have only the classname or missing it… * both aren't helping us and might even create a error later * in the server, where we dont know as much anymore about it, * so we fail rather here, so mappers have a chance to remove it */ if( level.numSpawnVars <= 1 ) { G_Error( S_ERROR "encountered ghost-entity #%i with only one field: %s = %s\n", spawningEntity->s.number, level.spawnVars[ 0 ][ 0 ], level.spawnVars[ 0 ][ 1 ] ); } // move editor origin to pos VectorCopy( spawningEntity->s.origin, spawningEntity->s.pos.trBase ); VectorCopy( spawningEntity->s.origin, spawningEntity->r.currentOrigin ); // don't leave any "gaps" between multiple names j = 0; for (i = 0; i < MAX_ENTITY_ALIASES; ++i) { if (spawningEntity->names[i]) spawningEntity->names[j++] = spawningEntity->names[i]; } spawningEntity->names[ j ] = NULL; /* * for backward compatbility, since before targets were used for calling, * we'll have to copy them over to the called-targets as well for now */ if(!spawningEntity->callTargetCount) { for (i = 0; i < MAX_ENTITY_TARGETS && i < MAX_ENTITY_CALLTARGETS; i++) { if (!spawningEntity->targets[i]) continue; spawningEntity->calltargets[i].event = "target"; spawningEntity->calltargets[i].eventType = ON_DEFAULT; spawningEntity->calltargets[i].actionType = ECA_DEFAULT; spawningEntity->calltargets[i].name = spawningEntity->targets[i]; spawningEntity->callTargetCount++; } } // don't leave any "gaps" between multiple targets j = 0; for (i = 0; i < MAX_ENTITY_TARGETS; ++i) { if (spawningEntity->targets[i]) spawningEntity->targets[j++] = spawningEntity->targets[i]; } spawningEntity->targets[ j ] = NULL; // if we didn't get necessary fields (like the classname), don't bother spawning anything if ( !G_CallSpawnFunction( spawningEntity ) ) { G_FreeEntity( spawningEntity ); } }
void SP_target_speaker(gentity_t * ent) { char buffer[MAX_QPATH]; char *s; if(G_SpawnString("s_sound", "NOSOUND", &s)) { G_SpawnBoolean("s_looping", "0", &ent->soundLooping); G_SpawnBoolean("s_waitfortrigger", "0", &ent->soundWaitForTrigger); G_SpawnBoolean("s_global", "0", &ent->soundGlobal); G_SpawnBoolean("s_activator", "0", &ent->soundActivator); G_SpawnFloat("wait", "0", &ent->wait); G_SpawnFloat("random", "0", &ent->random); } else if(G_SpawnString("s_shader", "NOSOUND", &s)) { // Doom3 compatibility mode G_SpawnBoolean("s_looping", "0", &ent->soundLooping); G_SpawnBoolean("s_waitfortrigger", "0", &ent->soundWaitForTrigger); G_SpawnBoolean("s_global", "0", &ent->soundGlobal); G_SpawnBoolean("s_activator", "0", &ent->soundActivator); G_SpawnFloat("wait", "0", &ent->wait); G_SpawnFloat("random", "0", &ent->random); } else if(G_SpawnString("noise", "NOSOUND", &s)) { // Q3A compatibility mode ent->soundLooping = ent->spawnflags & 1 ? qtrue : qfalse; ent->soundWaitForTrigger = ent->spawnflags & 2 ? qtrue : qfalse; ent->soundGlobal = ent->spawnflags & 4 ? qtrue : qfalse; ent->soundActivator = ent->spawnflags & 8 ? qtrue : qfalse; } else { //G_Error("speaker without a noise key at %s", vtos(ent->s.origin)); G_Printf(S_COLOR_YELLOW "WARNING: speaker '%s' without a noise key at %s", ent->name, vtos(ent->s.origin)); } // force all client reletive sounds to be "activator" speakers that // play on the entity that activates it if(s[0] == '*') { ent->soundActivator = qtrue; } Q_strncpyz(buffer, s, sizeof(buffer)); Com_DefaultExtension(buffer, sizeof(buffer), ".wav"); ent->soundIndex = G_SoundIndex(buffer); // a repeating speaker can be done completely client side ent->s.eType = ET_SPEAKER; ent->s.eventParm = ent->soundIndex; ent->s.frame = ent->wait * 10; ent->s.clientNum = ent->random * 10; // check for prestarted looping sound if(ent->soundLooping && !ent->soundWaitForTrigger) { ent->s.loopSound = ent->soundIndex; } ent->use = Use_Target_Speaker; if(ent->soundGlobal) { ent->r.svFlags |= SVF_BROADCAST; } VectorCopy(ent->s.origin, ent->s.pos.trBase); // must link the entity so we get areas and clusters so // the server can determine who to send updates to trap_LinkEntity(ent); }