void SP_func_timer( gentity_t *self ) { G_SpawnFloat( "random", "1", &self->random); G_SpawnFloat( "wait", "1", &self->wait ); self->e_UseFunc = useF_func_timer_use; self->e_ThinkFunc = thinkF_func_timer_think; if ( self->random >= self->wait ) { self->random = self->wait - FRAMETIME; gi.Printf( "func_timer at %s has random >= wait\n", vtos( self->s.origin ) ); } if ( self->spawnflags & 1 ) { self->nextthink = level.time + FRAMETIME; self->activator = self; } self->svFlags = SVF_NOCLIENT; }
/*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); }
void SP_func_timer( gentity_t *self ) { G_SpawnFloat( "random", "0", &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 / 1000.f ); //Gordon div 1000 for milisecs...*cough* G_Printf( "func_timer at %s has random >= wait\n", vtos( self->s.origin ) ); } if ( self->spawnflags & 1 ) { self->nextthink = level.time + FRAMETIME; self->activator = self; } self->r.svFlags = SVF_NOCLIENT; }
void SP_fx_cloudlayer( gentity_t *ent ) { // HACK: this effect is never played, rather it just caches the shaders I need cgame side G_EffectIndex( "world/haze_cache" ); G_SpawnFloat( "radius", "2048", &ent->radius ); G_SpawnFloat( "random", "128", &ent->random ); G_SpawnFloat( "wait", "0", &ent->wait ); ent->s.eType = ET_CLOUD; // dumb G_SetOrigin( ent, ent->s.origin ); ent->contents = 0; VectorSet( ent->maxs, 200, 200, 200 ); VectorScale( ent->maxs, -1, ent->mins ); gi.linkentity( ent ); }
/** QUAKED func_plat (0 .5 .8) ? Plats are always drawn in the extended position so they will light correctly. "lip" default 8, protrusion above rest position "height" total height of movement, defaults to model height "speed" overrides default 200. "dmg" overrides default 2 "model2" .md3 model to also draw "color" constantLight color "light" constantLight radius */ void SP_func_plat(gentity_t *ent) { float lip, height; ent->sound1to2 = ent->sound2to1 = G_SoundIndex("sound/movers/plats/pt1_strt.wav"); ent->soundPos1 = ent->soundPos2 = G_SoundIndex("sound/movers/plats/pt1_end.wav"); VectorClear (ent->s.angles); G_SpawnFloat("speed", "200", &ent->speed); G_SpawnInt("dmg", "2", &ent->damage); G_SpawnFloat("wait", "1", &ent->wait); G_SpawnFloat("lip", "8", &lip); ent->wait = 1000; // create second position trap_SetBrushModel(ent, ent->model); if (!G_SpawnFloat("height", "0", &height)) { height = (ent->r.maxs[2] - ent->r.mins[2]) - lip; } // pos1 is the rest (bottom) position, pos2 is the top VectorCopy(ent->s.origin, ent->pos2); VectorCopy(ent->pos2, ent->pos1); ent->pos1[2] -= height; InitMover(ent); // touch function keeps the plat from returning while // a live player is standing on it ent->touch = Touch_Plat; ent->blocked = Blocked_Door; ent->parent = ent; // so it can be treated as a door // spawn the trigger if one hasn't been custom made if (!ent->targetname) { SpawnPlatTrigger(ent); } }
void SP_func_timer( gentity_t *self ) { 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 - 1;//NOTE: was - FRAMETIME, but FRAMETIME is in msec (100) and these numbers are in *seconds*! trap->Print( "func_timer at %s has random >= wait\n", vtos( self->s.origin ) ); } if ( self->spawnflags & 1 ) { self->nextthink = level.time + FRAMETIME; self->activator = self; } self->r.svFlags = SVF_NOCLIENT; }
void SP_trigger_multiple( gentity_t *ent ) { char buffer[MAX_QPATH]; char *s; if ( G_SpawnString( "noise", "*NOSOUND*", &s ) ) { Q_strncpyz( buffer, s, sizeof(buffer) ); COM_DefaultExtension( buffer, sizeof(buffer), ".wav"); ent->noise_index = G_SoundIndex(buffer); } G_SpawnFloat( "wait", "0", &ent->wait );//was 0.5 ... but that means wait can never be zero... we should probably put it back to 0.5, though... G_SpawnFloat( "random", "0", &ent->random ); if ( (ent->wait > 0) && (ent->random >= ent->wait) ) { ent->random = ent->wait - FRAMETIME; gi.Printf(S_COLOR_YELLOW"trigger_multiple has random >= wait\n"); } ent->delay *= 1000;//1 = 1 msec, 1000 = 1 sec if ( !ent->speed && ent->target2 && ent->target2[0] ) { ent->speed = 1000; } else { ent->speed *= 1000; } ent->e_TouchFunc = touchF_Touch_Multi; ent->e_UseFunc = useF_Use_Multi; if ( ent->team && ent->team[0] ) { ent->noDamageTeam = TranslateTeamName( ent->team ); ent->team = NULL; } InitTrigger( ent ); gi.linkentity (ent); }
/*QUAKED func_timer (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) START_ON This should be renamed trigger_timer... Repeatedly fires its targets. Can be turned on or off by using. "wait" base time between triggering all targets, default is 1 "random" wait variance, default is 0 so, the basic time between firing is a random time between (wait - random) and (wait + random) */ void SP_func_timer(gentity_t *self) { G_SpawnFloat("random", "1", &self->random); G_SpawnFloat("wait", "1", &self->wait); self->use = Use_Func_Timer; 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", VectorToString(self->s.origin)); } if (self->spawnflags & 1) { self->nextthink = level.time + FRAMETIME; self->activator = self; } self->r.svFlags = SVF_NOCLIENT; }
/*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; VectorClear( ent->r.mins ); VectorClear( ent->r.maxs ); trap_LinkEntity (ent); G_SpawnFloat( "roll", "0", &roll ); ent->s.clientNum = roll/360.0 * 256; }
/*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; VectorClear( &ent->r.mins ); VectorClear( &ent->r.maxs ); trap->SV_LinkEntity ((sharedEntity_t *)ent); G_SpawnFloat( "roll", "0", &roll ); ent->s.clientNum = (int)(roll/360.0f * 256); }
//---------------------------------------------------------- void SP_fx_explosion_trail( gentity_t *ent ) { // We have to be useable, otherwise we won't spawn in if ( !ent->targetname ) { gi.Printf( S_COLOR_RED"ERROR: fx_explosion_trail at %s has no targetname specified\n", vtos( ent->s.origin )); G_FreeEntity( ent ); return; } // Get our defaults G_SpawnString( "fxFile", "env/exp_trail_comp", &ent->fxFile ); G_SpawnInt( "damage", "128", &ent->damage ); G_SpawnFloat( "radius", "128", &ent->radius ); G_SpawnFloat( "speed", "350", &ent->speed ); // Try and associate an effect file, unfortunately we won't know if this worked or not until the CGAME trys to register it... ent->fxID = G_EffectIndex( ent->fxFile ); if ( ent->fullName ) { G_EffectIndex( ent->fullName ); } if ( ent->model ) { ent->s.modelindex2 = G_ModelIndex( ent->model ); } // Give us a bit of time to spawn in the other entities, since we may have to target one of 'em ent->e_ThinkFunc = thinkF_fx_explosion_trail_link; ent->nextthink = level.time + 500; // Save our position and link us up! G_SetOrigin( ent, ent->s.origin ); VectorSet( ent->maxs, FX_ENT_RADIUS, FX_ENT_RADIUS, FX_ENT_RADIUS ); VectorScale( ent->maxs, -1, ent->mins ); gi.linkentity( ent ); }
/*QUAKED trigger_multiple (.5 .5 .5) ? AXIS_ONLY ALLIED_ONLY NOBOT BOTONLY SOLDIERONLY LTONLY MEDICONLY ENGINEERONLY COVERTOPSONLY "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 ); if ( ent->random >= ent->wait && ent->wait >= 0 ) { ent->random = ent->wait - (FRAMETIME * 0.001f); G_Printf( "trigger_multiple has random >= wait\n" ); } ent->touch = Touch_Multi; ent->use = Use_Multi; ent->s.eType = ET_TRIGGER_MULTIPLE; InitTrigger( ent); #ifdef VISIBLE_TRIGGERS ent->r.svFlags &= ~SVF_NOCLIENT; #endif // VISIBLE_TRIGGERS trap_LinkEntity (ent); }
void SP_gfx_portal_camera( gentity_t *self ) { float roll; VectorClear( self->r.mins ); VectorClear( self->r.maxs ); trap_LinkEntity( self ); G_SpawnFloat( "roll", "0", &roll ); self->s.clientNum = roll / 360.0f * 256; }
/*QUAKED func_breakable (0 .8 .5) ? INVINCIBLE IMPACT CRUSHER THIN SABERONLY HEAVY_WEAP USE_NOT_BREAK PLAYER_USE NO_EXPLOSION INVINCIBLE - can only be broken by being used IMPACT - does damage on impact CRUSHER - won't reverse movement when hit an obstacle THIN - can be broken by impact damage, like glass SABERONLY - only takes damage from sabers HEAVY_WEAP - only takes damage by a heavy weapon, like an emplaced gun or AT-ST gun. USE_NOT_BREAK - Using it doesn't make it break, still can be destroyed by damage PLAYER_USE - Player can use it with the use button NO_EXPLOSION - Does not play an explosion effect, though will still create chunks if specified When destroyed, fires it's trigger and chunks and plays sound "noise" or sound for type if no noise specified "targetname" entities with matching target will fire it "paintarget" target to fire when hit (but not destroyed) "wait" how long minimum to wait between firing paintarget each time hit "delay" When killed or used, how long (in seconds) to wait before blowing up (none by default) "model2" .md3 model to also draw "target" all entities with a matching targetname will be used when this is destoryed "health" default is 10 "radius" Chunk code tries to pick a good volume of chunks, but you can alter this to scale the number of spawned chunks. (default 1) (.5) is half as many chunks, (2) is twice as many chunks Damage: default is none "splashDamage" - damage to do "splashRadius" - radius for above damage "team" - This cannot take damage from members of this team: "player" "neutral" "enemy" Don't know if these work: "color" constantLight color "light" constantLight radius "material" - default is "0 - MAT_METAL" - choose from this list: 0 = MAT_METAL (basic blue-grey scorched-DEFAULT) 1 = MAT_GLASS 2 = MAT_ELECTRICAL (sparks only) 3 = MAT_ELEC_METAL (METAL2 chunks and sparks) 4 = MAT_DRK_STONE (brown stone chunks) 5 = MAT_LT_STONE (tan stone chunks) 6 = MAT_GLASS_METAL (glass and METAL2 chunks) 7 = MAT_METAL2 (electronic type of metal) 8 = MAT_NONE (no chunks) 9 = MAT_GREY_STONE (grey colored stone) 10 = MAT_METAL3 (METAL and METAL2 chunk combo) 11 = MAT_CRATE1 (yellow multi-colored crate chunks) 12 = MAT_GRATE1 (grate chunks--looks horrible right now) 13 = MAT_ROPE (for yavin_trial, no chunks, just wispy bits ) 14 = MAT_CRATE2 (red multi-colored crate chunks) 15 = MAT_WHITE_METAL (white angular chunks for Stu, NS_hideout ) */ void SP_func_breakable( gentity_t *self ) { if(!(self->spawnflags & 1)) { if(!self->health) { self->health = 10; } } if ( self->spawnflags & 16 ) // saber only { self->flags |= FL_DMG_BY_SABER_ONLY; } else if ( self->spawnflags & 32 ) // heavy weap { self->flags |= FL_DMG_BY_HEAVY_WEAP_ONLY; } if (self->health) { self->takedamage = qtrue; } G_SoundIndex("sound/weapons/explosions/cargoexplode.wav");//precaching G_SpawnFloat( "radius", "1", &self->radius ); // used to scale chunk code if desired by a designer G_SpawnInt( "material", "0", (int*)&self->material ); CacheChunkEffects( self->material ); self->e_UseFunc = useF_funcBBrushUse; //if ( self->paintarget ) { self->e_PainFunc = painF_funcBBrushPain; } self->e_TouchFunc = touchF_funcBBrushTouch; if ( self->team && self->team[0] ) { self->noDamageTeam = TranslateTeamName( self->team ); if(self->noDamageTeam == TEAM_FREE) { G_Error("team name %s not recognized\n", self->team); } } self->team = NULL; if (!self->model) { G_Error("func_breakable with NULL model\n"); } InitBBrush( self ); }
/* ============ G_SpawnItem Sets the clipping size and plants the object on the floor. Items can't be immediately dropped to floor, because they might be on an entity that hasn't spawned yet. ============ */ void G_SpawnItem (gentity_t *ent, gitem_t *item) { G_SpawnFloat( "random", "0", &ent->random ); G_SpawnFloat( "wait", "0", &ent->wait ); RegisterItem( item ); if ( G_ItemDisabled(item) ) return; ent->item = item; // some movers spawn on the second frame, so delay item // spawns until the third frame so they can ride trains ent->nextthink = level.time + FRAMETIME * 2; ent->think = FinishSpawningItem; ent->physicsBounce = 0.50; // items are bouncy if ( item->giType == IT_POWERUP ) { G_SoundIndex( "sounds/items/powerup_respawn" ); G_SpawnFloat( "noglobalsound", "0", &ent->speed); } }
/* ============ G_SpawnItem Sets the clipping size and plants the object on the floor. Items can't be immediately dropped to floor, because they might be on an entity that hasn't spawned yet. ============ */ void G_SpawnItem (gentity_t *ent, gitem_t *item) { if ( G_ItemSuppressed( item->giType, item->giTag ) ) { return; } //item = G_CheckReplaceItem( ent, item ); G_SpawnFloat( "random", "0", &ent->random ); G_SpawnFloat( "wait", "0", &ent->wait ); RegisterItem( item ); ent->item = item; // some movers spawn on the second frame, so delay item // spawns until the third frame so they can ride trains ent->nextthink = level.time + FRAMETIME * 2; ent->think = FinishSpawningItem; ent->physicsBounce = 0.50; // items are bouncy if ( item->giType == IT_POWERUP ) { G_SoundIndex( "sound/items/poweruprespawn.wav" );//cgs.media.poweruprespawn } }
/* =============== SP_trigger_equipment =============== */ void SP_trigger_equipment(gentity_t * self) { char *buffer; G_SpawnFloat("wait", "0.5", &self->wait); G_SpawnFloat("random", "0", &self->random); if(self->random >= self->wait && self->wait >= 0) { self->random = self->wait - FRAMETIME; G_Printf(S_COLOR_YELLOW "WARNING: trigger_equipment has random >= wait\n"); } G_SpawnString("equipment", "", &buffer); BG_ParseCSVEquipmentList(buffer, self->wTriggers, WP_NUM_WEAPONS, self->uTriggers, UP_NUM_UPGRADES); self->touch = trigger_equipment_touch; self->use = trigger_equipment_use; InitTrigger(self); trap_LinkEntity(self); }
/* =============== SP_trigger_buildable =============== */ void SP_trigger_buildable(gentity_t * self) { char *buffer; G_SpawnFloat("wait", "0.5", &self->wait); G_SpawnFloat("random", "0", &self->random); if(self->random >= self->wait && self->wait >= 0) { self->random = self->wait - FRAMETIME; G_Printf(S_COLOR_YELLOW "WARNING: trigger_buildable has random >= wait\n"); } G_SpawnString("buildables", "", &buffer); BG_ParseCSVBuildableList(buffer, self->bTriggers, BA_NUM_BUILDABLES); self->touch = trigger_buildable_touch; self->use = trigger_buildable_use; InitTrigger(self); trap_LinkEntity(self); }
/* =============== SP_trigger_class =============== */ void SP_trigger_class(gentity_t * self) { char *buffer; G_SpawnFloat("wait", "0.5", &self->wait); G_SpawnFloat("random", "0", &self->random); if(self->random >= self->wait && self->wait >= 0) { self->random = self->wait - FRAMETIME; G_Printf(S_COLOR_YELLOW "WARNING: trigger_class has random >= wait\n"); } G_SpawnString("classes", "", &buffer); BG_ParseCSVClassList(buffer, self->cTriggers, PCL_NUM_CLASSES); self->touch = trigger_class_touch; self->use = trigger_class_use; InitTrigger(self); trap_LinkEntity(self); }
/*QUAKED func_bobbing (0 .5 .8) ? X_AXIS Y_AXIS Normally bobs on the Z axis "model2" .md3 model to also draw "height" amplitude of bob (32 default) "speed" seconds to complete a bob cycle (4 default) "phase" the 0.0 to 1.0 offset in the cycle to start at "dmg" damage to inflict when blocked (2 default) "color" constantLight color "light" constantLight radius */ void SP_func_bobbing (gentity_t *ent) { float height; float phase; G_SpawnFloat( "speed", "4", &ent->speed ); G_SpawnFloat( "height", "32", &height ); G_SpawnInt( "dmg", "2", &ent->damage ); G_SpawnFloat( "phase", "0", &phase ); trap->SV_SetBrushModel( (sharedEntity_t *)ent, ent->model ); InitMover( ent ); VectorCopy( &ent->s.origin, &ent->s.pos.trBase ); VectorCopy( &ent->s.origin, &ent->r.currentOrigin ); ent->s.pos.trDuration = (int)(ent->speed * 1000); ent->s.pos.trTime = (int)(ent->s.pos.trDuration * phase); ent->s.pos.trType = TR_SINE; // set the axis of bobbing if ( ent->spawnflags & 1 ) ent->s.pos.trDelta.x = height; else if ( ent->spawnflags & 2 ) ent->s.pos.trDelta.y = height; else ent->s.pos.trDelta.z = height; }
/*QUAKED trigger_multiple (.5 .5 .5) ? USE_BUTTON RED_ONLY BLUE_ONLY USE_BUTTON - Won't fire unless player is in it and pressing use button (in addition to any other conditions) RED_ONLY - Only red team can use BLUE_ONLY - Only blue team can use "roffname" If set, will play a roff upon activation "rofftarget" If set with roffname, will activate the roff an entity with this as its targetname. Otherwise uses roff on activating entity. "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 ) { if (ent->roffname) { ent->roffid = trap_ROFF_Cache(ent->roffname); } else { ent->roffid = -1; } G_SpawnFloat( "wait", "0.5", &ent->wait ); G_SpawnFloat( "random", "0", &ent->random ); 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); }
//---------------------------------------------------------- void SP_fx_runner( gentity_t *ent ) { char *fxFile; // Get our defaults G_SpawnInt( "delay", "400", &ent->delay ); G_SpawnFloat( "random", "0", &ent->random ); if (!ent->s.angles[0] && !ent->s.angles[1] && !ent->s.angles[2]) { // didn't have angles, so give us the default of up VectorSet( ent->s.angles, -90, 0, 0 ); } // make us useable if we can be targeted if ( ent->targetname ) { ent->use = fx_runner_use; } G_SpawnString( "fxFile", "", &fxFile ); G_SpawnString( "fxTarget", "", &ent->roffname ); if ( !fxFile || !fxFile[0] ) { Com_Printf( S_COLOR_RED"ERROR: fx_runner %s at %s has no fxFile specified\n", ent->targetname, vtos(ent->s.origin) ); G_FreeEntity( ent ); return; } // Try and associate an effect file, unfortunately we won't know if this worked or not // until the CGAME trys to register it... ent->bolt_Head = G_EffectIndex( fxFile ); //It is dirty, yes. But no one likes adding things to the entity structure. // Give us a bit of time to spawn in the other entities, since we may have to target one of 'em ent->think = fx_runner_link; ent->nextthink = level.time + 300; // Save our position and link us up! G_SetOrigin( ent, ent->s.origin ); VectorSet( ent->r.maxs, FX_ENT_RADIUS, FX_ENT_RADIUS, FX_ENT_RADIUS ); VectorScale( ent->r.maxs, -1, ent->r.mins ); trap_LinkEntity( ent ); }
/*QUAKED target_fog (1 1 0) (-8 -8 -8) (8 8 8) color picker chooses color of fog "distance" sets fog distance. Use value '0' to give control back to the game (and use the fog values specified in the sky shader if present) "time" time it takes to change fog to new value. default time is 1 sec */ void SP_target_fog(gentity_t *ent) { int dist; float ftime; ent->use = Use_target_fog; // ent->s.density will carry the 'distance' value if (G_SpawnInt("distance", "0", &dist) && dist >= 0) { ent->s.density = dist; } // ent->s.time will carry the 'time' value if (G_SpawnFloat("time", "0.5", &ftime) && ftime >= 0) { ent->s.time = ftime * 1000; // sec to ms } }
/*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; }
/* =============== SP_spawn_particle_system Spawn function for particle system =============== */ void SP_misc_particle_system(gentity_t *self) { char *s; G_SetOrigin(self, self->s.origin); G_SpawnString("psName", "", &s); G_SpawnFloat("wait", "0", &self->wait); //add the particle system to the client precache list self->s.modelindex = G_ParticleSystemIndex(s); if (self->spawnflags & 1) self->s.eFlags |= EF_NODRAW; self->use = SP_use_particle_system; self->s.eType = ET_PARTICLE_SYSTEM; trap_LinkEntity(self); }
/** QUAKED func_button (0 .5 .8) ? When a button is touched, it moves some distance in the direction of its angle, triggers all of its targets, waits some time, then returns to its original position where it can be triggered again. "model2" .md3 model to also draw "angle" determines the opening direction "target" all entities with a matching targetname will be used "speed" override the default 40 speed "wait" override the default 1 second wait (-1 = never return) "lip" override the default 4 pixel lip remaining at end of move "health" if set, the button must be killed instead of touched "color" constantLight color "light" constantLight radius */ void SP_func_button(gentity_t *ent) { vec3_t abs_movedir; float distance; vec3_t size; float lip; ent->sound1to2 = G_SoundIndex("sound/movers/switches/butn2.wav"); if (!ent->speed) { ent->speed = 40; } if (!ent->wait) { ent->wait = 1; } ent->wait *= 1000; // first position VectorCopy(ent->s.origin, ent->pos1); // calculate second position trap_SetBrushModel(ent, ent->model); G_SpawnFloat("lip", "4", &lip); G_SetMovedir(ent->s.angles, ent->movedir); abs_movedir[0] = fabs(ent->movedir[0]); abs_movedir[1] = fabs(ent->movedir[1]); abs_movedir[2] = fabs(ent->movedir[2]); VectorSubtract(ent->r.maxs, ent->r.mins, size); distance = abs_movedir[0] * size[0] + abs_movedir[1] * size[1] + abs_movedir[2] * size[2] - lip; VectorMA(ent->pos1, distance, ent->movedir, ent->pos2); if (ent->health) { // shootable button ent->takedamage = qtrue; } else { // touchable button ent->touch = Touch_Button; } InitMover(ent); }
/*QUAKED func_button (0 .5 .8) ? When a button is touched, it moves some distance in the direction of its angle, triggers all of its targets, waits some time, then returns to its original position where it can be triggered again. "model2" .md3 model to also draw "angle" determines the opening direction "target" all entities with a matching targetname will be used "speed" override the default 40 speed "wait" override the default 1 second wait (-1 = never return) "lip" override the default 4 pixel lip remaining at end of move "health" if set, the button must be killed instead of touched "color" constantLight color "light" constantLight radius */ void SP_func_button( gentity_t *ent ) { vector3 abs_movedir; float distance; vector3 size; float lip; ent->sound1to2 = G_SoundIndex("sound/movers/switches/butn2.wav"); if ( !ent->speed ) { ent->speed = 40; } if ( !ent->wait ) { ent->wait = 1; } ent->wait *= 1000; // first position VectorCopy( &ent->s.origin, &ent->pos1 ); // calculate second position trap->SV_SetBrushModel( (sharedEntity_t *)ent, ent->model ); G_SpawnFloat( "lip", "4", &lip ); G_SetMovedir( &ent->s.angles, &ent->movedir ); abs_movedir.x = fabsf(ent->movedir.x); abs_movedir.y = fabsf(ent->movedir.y); abs_movedir.z = fabsf(ent->movedir.z); VectorSubtract( &ent->r.maxs, &ent->r.mins, &size ); distance = abs_movedir.x * size.x + abs_movedir.y * size.y + abs_movedir.z * size.z - lip; VectorMA (&ent->pos1, distance, &ent->movedir, &ent->pos2); if (ent->health) { // shootable button ent->takedamage = qtrue; } else { // touchable button ent->touch = Touch_Button; } InitMover( ent ); }
/* =============== SP_misc_light_flare Spawn function for light flare =============== */ void SP_misc_light_flare(gentity_t *self) { self->s.eType = ET_LIGHTFLARE; self->s.modelindex = G_ShaderIndex(self->targetShaderName); VectorCopy(self->pos2, self->s.origin2); //try to find a spot near to the flare which is empty. This //is used to facilitate visibility testing findEmptySpot(self->s.origin, 8.0f, self->s.angles2); self->use = SP_use_light_flare; G_SpawnFloat("speed", "200", &self->speed); self->s.time = self->speed; G_SpawnInt("mindist", "0", &self->s.generic1); if (self->spawnflags & 1) self->s.eFlags |= EF_NODRAW; trap_LinkEntity(self); }
//---------------------------------------------------------- void SP_fx_runner( gentity_t *ent ) { // Get our defaults G_SpawnInt( "delay", "200", &ent->delay ); G_SpawnFloat( "random", "0", &ent->random ); G_SpawnInt( "splashRadius", "16", &ent->splashRadius ); G_SpawnInt( "splashDamage", "5", &ent->splashDamage ); if ( !G_SpawnAngleHack( "angle", "0", ent->s.angles )) { // didn't have angles, so give us the default of up VectorSet( ent->s.angles, -90, 0, 0 ); } if ( !ent->fxFile ) { gi.Printf( S_COLOR_RED"ERROR: fx_runner %s at %s has no fxFile specified\n", ent->targetname, vtos(ent->s.origin) ); G_FreeEntity( ent ); return; } // Try and associate an effect file, unfortunately we won't know if this worked or not // until the CGAME trys to register it... ent->fxID = G_EffectIndex( ent->fxFile ); ent->s.eType = ET_MOVER; // Give us a bit of time to spawn in the other entities, since we may have to target one of 'em ent->e_ThinkFunc = thinkF_fx_runner_link; ent->nextthink = level.time + 400; // Save our position and link us up! G_SetOrigin( ent, ent->s.origin ); VectorSet( ent->maxs, FX_ENT_RADIUS, FX_ENT_RADIUS, FX_ENT_RADIUS ); VectorScale( ent->maxs, -1, ent->mins ); gi.linkentity( ent ); }
/*QUAKED target_scriptrunner (1 0 0) (-4 -4 -4) (4 4 4) runonactivator x x x x x x INACTIVE --- SPAWNFLAGS --- runonactivator - Will run the script on the entity that used this or tripped the trigger that used this INACTIVE - start off ----- KEYS ------ Usescript - Script to run when used count - how many times to run, -1 = infinite. Default is once wait - can't be used again in this amount of seconds (Default is 1 second if it's multiple-use) delay - how long to wait after use to run script */ void SP_target_scriptrunner( gentity_t *self ) { float v; if ( self->spawnflags & 128 ) { self->flags |= FL_INACTIVE; } if ( !self->count ) { self->count = 1;//default 1 use only } // FIXME: this is a hack... because delay is read in as an int, so I'm bypassing that because it's too late in the project to change it and I want to be able to set less than a second delays // no one should be setting a radius on a scriptrunner, if they are this would be bad, take this out for the next project v = 0.0f; G_SpawnFloat( "delay", "0", &v ); self->delay = v * 1000;//sec to ms self->wait *= 1000;//sec to ms G_SetOrigin( self, self->s.origin ); self->use = target_scriptrunner_use; }