/* * W_Fire_Rocket */ edict_t *W_Fire_Rocket( edict_t *self, vec3_t start, vec3_t angles, int speed, float damage, int minKnockback, int maxKnockback, int stun, int minDamage, int radius, int timeout, int mod, int timeDelta ) { edict_t *rocket; if( GS_Instagib() ) damage = 9999; rocket = W_Fire_LinearProjectile( self, start, angles, speed, damage, minKnockback, maxKnockback, stun, minDamage, radius, timeout, timeDelta ); rocket->s.type = ET_ROCKET; //rocket trail sfx if( mod == MOD_ROCKET_S ) { rocket->s.modelindex = trap_ModelIndex( PATH_ROCKET_STRONG_MODEL ); rocket->s.effects |= EF_STRONG_WEAPON; rocket->s.sound = trap_SoundIndex( S_WEAPON_ROCKET_S_FLY ); } else { rocket->s.modelindex = trap_ModelIndex( PATH_ROCKET_WEAK_MODEL ); rocket->s.effects &= ~EF_STRONG_WEAPON; rocket->s.sound = trap_SoundIndex( S_WEAPON_ROCKET_W_FLY ); } rocket->touch = W_Touch_Rocket; rocket->think = G_FreeEdict; rocket->classname = "rocket"; rocket->style = mod; return rocket; }
/* * W_Fire_Plasma */ edict_t *W_Fire_Plasma( edict_t *self, vec3_t start, vec3_t angles, float damage, int minKnockback, int maxKnockback, int stun, int minDamage, int radius, int speed, int timeout, int mod, int timeDelta ) { edict_t *plasma; if( GS_Instagib() ) damage = 9999; plasma = W_Fire_LinearProjectile( self, start, angles, speed, damage, minKnockback, maxKnockback, stun, minDamage, radius, timeout, timeDelta ); plasma->s.type = ET_PLASMA; plasma->classname = "plasma"; plasma->style = mod; plasma->think = W_Think_Plasma; plasma->touch = W_AutoTouch_Plasma; plasma->nextThink = level.time + 1; plasma->timeout = level.time + timeout; if( mod == MOD_PLASMA_S ) { plasma->s.modelindex = trap_ModelIndex( PATH_PLASMA_STRONG_MODEL ); plasma->s.sound = trap_SoundIndex( S_WEAPON_PLASMAGUN_S_FLY ); plasma->s.effects |= EF_STRONG_WEAPON; } else { plasma->s.modelindex = trap_ModelIndex( PATH_PLASMA_WEAK_MODEL ); plasma->s.sound = trap_SoundIndex( S_WEAPON_PLASMAGUN_W_FLY ); plasma->s.effects &= ~EF_STRONG_WEAPON; } return plasma; }
/* * W_Fire_Grenade */ edict_t *W_Fire_Grenade( edict_t *self, vec3_t start, vec3_t dir, int speed, float damage, int minKnockback, int maxKnockback, int stun, int minDamage, float radius, int timeout, int mod, int timeDelta ) { edict_t *grenade; if( GS_Instagib() ) { damage = 9999; } grenade = W_Fire_TossProjectile( self, start, dir, speed, damage, minKnockback, maxKnockback, stun, minDamage, radius, timeout, timeDelta ); VectorClear( grenade->s.angles ); grenade->style = mod; grenade->s.type = ET_GRENADE; grenade->movetype = MOVETYPE_BOUNCEGRENADE; grenade->touch = W_Touch_Grenade; grenade->use = NULL; grenade->think = W_Grenade_Explode; grenade->classname = "grenade"; grenade->enemy = NULL; VectorSet( grenade->avelocity, 300, 300, 300 ); if( mod == MOD_GRENADE_S ) { grenade->s.modelindex = trap_ModelIndex( PATH_GRENADE_STRONG_MODEL ); grenade->s.effects |= EF_STRONG_WEAPON; } else { grenade->s.modelindex = trap_ModelIndex( PATH_GRENADE_WEAK_MODEL ); grenade->s.effects &= ~EF_STRONG_WEAPON; } GClip_LinkEntity( grenade ); return grenade; }
/* * W_Fire_Grenade */ edict_t *W_Fire_Grenade( edict_t *self, vec3_t start, vec3_t angles, int speed, float damage, int minKnockback, int maxKnockback, int stun, int minDamage, float radius, int timeout, int mod, int timeDelta, qboolean aim_up ) { edict_t *grenade; static cvar_t *g_grenade_gravity = NULL; if( GS_Instagib() ) damage = 9999; if( !g_grenade_gravity ) g_grenade_gravity = trap_Cvar_Get( "g_grenade_gravity", "1.3", CVAR_DEVELOPER ); if( aim_up ) { angles[PITCH] -= 10; // aim some degrees upwards from view dir // clamp to front side of the player angles[PITCH] += -90; // rotate to make easier the check while( angles[PITCH] < -360 ) angles[PITCH] += 360; clamp( angles[PITCH], -180, 0 ); angles[PITCH] += 90; while( angles[PITCH] > 360 ) angles[PITCH] -= 360; } grenade = W_Fire_TossProjectile( self, start, angles, speed, damage, minKnockback, maxKnockback, stun, minDamage, radius, timeout, timeDelta ); VectorClear( grenade->s.angles ); grenade->style = mod; grenade->s.type = ET_GRENADE; grenade->movetype = MOVETYPE_BOUNCEGRENADE; grenade->touch = W_Touch_Grenade; grenade->use = NULL; grenade->think = W_Grenade_Explode; grenade->classname = "grenade"; grenade->gravity = g_grenade_gravity->value; grenade->enemy = NULL; if( mod == MOD_GRENADE_S ) { grenade->s.modelindex = trap_ModelIndex( PATH_GRENADE_STRONG_MODEL ); grenade->s.effects |= EF_STRONG_WEAPON; } else { grenade->s.modelindex = trap_ModelIndex( PATH_GRENADE_WEAK_MODEL ); grenade->s.effects &= ~EF_STRONG_WEAPON; } GClip_LinkEntity( grenade ); return grenade; }
static void G_Client_AssignTeamSkin( edict_t *ent, char *userinfo ) { char skin[MAX_QPATH], model[MAX_QPATH]; const char *userskin, *usermodel; // index skin file userskin = GS_TeamSkinName( ent->s.team ); // is it a team skin? if( !userskin ) // NULL indicates *user defined* { userskin = Info_ValueForKey( userinfo, "skin" ); if( !userskin || !userskin[0] || !COM_ValidateRelativeFilename( userskin ) || strchr( userskin, '/' ) || strstr( userskin, "invisibility" ) ) userskin = NULL; } // index player model usermodel = Info_ValueForKey( userinfo, "model" ); if( !usermodel || !usermodel[0] || !COM_ValidateRelativeFilename( usermodel ) || strchr( usermodel, '/' ) ) usermodel = NULL; if( userskin && usermodel ) { Q_snprintfz( model, sizeof( model ), "$models/players/%s", usermodel ); Q_snprintfz( skin, sizeof( skin ), "models/players/%s/%s", usermodel, userskin ); } else { Q_snprintfz( model, sizeof( model ), "$models/players/%s", DEFAULT_PLAYERMODEL ); Q_snprintfz( skin, sizeof( skin ), "models/players/%s/%s", DEFAULT_PLAYERMODEL, DEFAULT_PLAYERSKIN ); } if( !ent->deadflag ) ent->s.modelindex = trap_ModelIndex( model ); ent->s.skinnum = trap_SkinIndex( skin ); }
//QUAKED light_mine (0 1 0) (-2 -2 -12) (2 2 12) void SP_light_mine( edict_t *ent ) { ent->movetype = MOVETYPE_NONE; ent->r.solid = SOLID_YES; ent->s.modelindex = trap_ModelIndex( "models/objects/minelite/light1/tris.md2" ); GClip_LinkEntity( ent ); }
/* * GClip_SetBrushModel * * Also sets mins and maxs for inline bmodels */ void GClip_SetBrushModel( edict_t *ent, const char *name ) { struct cmodel_s *cmodel; if( !name ) { G_Error( "GClip_SetBrushModel: NULL model in '%s'", ent->classname ? ent->classname : "no classname" ); // racesow GClip_UnlinkEntity( ent ); G_FreeEdict( ent ); return; // !racesow } if( !name[0] ) { ent->s.modelindex = 0; return; } if( name[0] != '*' ) { ent->s.modelindex = trap_ModelIndex( name ); return; } // if it is an inline model, get the size information for it // world model is special if( !strcmp( name, "*0" ) ) { ent->s.modelindex = 0; cmodel = trap_CM_InlineModel( 0 ); trap_CM_InlineModelBounds( cmodel, ent->r.mins, ent->r.maxs ); return; } // brush model ent->s.modelindex = trap_ModelIndex( name ); assert( ent->s.modelindex == (unsigned int)atoi( name + 1 ) ); cmodel = trap_CM_InlineModel( ent->s.modelindex ); trap_CM_InlineModelBounds( cmodel, ent->r.mins, ent->r.maxs ); GClip_LinkEntity( ent ); }
void SP_func_explosive( edict_t *self ) { G_InitMover( self ); self->projectileInfo.maxDamage = max( self->dmg, 1 ); self->projectileInfo.minDamage = min( self->dmg, 1 ); self->projectileInfo.maxKnockback = self->projectileInfo.maxDamage; self->projectileInfo.minKnockback = self->projectileInfo.minDamage; self->projectileInfo.stun = self->projectileInfo.maxDamage * 100; self->projectileInfo.radius = st.radius; if( !self->projectileInfo.radius ) self->projectileInfo.radius = self->dmg + 100; if( self->spawnflags & 1 ) { self->r.svflags |= SVF_NOCLIENT; self->r.solid = SOLID_NOT; self->use = func_explosive_spawn; } else { if( self->targetname ) self->use = func_explosive_use; } if( self->use != func_explosive_use ) { if( !self->health ) self->health = 100; self->die = func_explosive_explode; self->takedamage = DAMAGE_YES; } self->max_health = self->health; // HACK HACK HACK if( st.debris1 && st.debris1[0] ) self->count = trap_ModelIndex( st.debris1 ); if( st.debris2 && st.debris2[0] ) self->viewheight = trap_ModelIndex( st.debris2 ); GClip_LinkEntity( self ); }
/* * GClip_SetBrushModel * * Also sets mins and maxs for inline bmodels */ void GClip_SetBrushModel( edict_t *ent, char *name ) { struct cmodel_s *cmodel; if( !name ) { //racesow G_Printf( "Warning: GClip_SetBrushModel: NULL model in '%s'", ent->classname ? ent->classname : "no classname\n" ); GClip_UnlinkEntity( ent ); G_FreeEdict( ent ); return; //!racesow } if( !name[0] ) { ent->s.modelindex = 0; return; } if( name[0] != '*' ) { ent->s.modelindex = trap_ModelIndex( name ); return; } // if it is an inline model, get the size information for it // world model is special if( !strcmp( name, "*0" ) ) { ent->s.modelindex = 0; cmodel = trap_CM_InlineModel( 0 ); trap_CM_InlineModelBounds( cmodel, ent->r.mins, ent->r.maxs ); return; } // racesow: THIS IS A VERY DIRTY "FIX": it assigns normally unreachable models (the ones over MAX_MODELS) to unrelated models.. // normally this only affects buggy maps that otherwise wouldn't load (like amt-freestyle3) // brush model //ent->s.modelindex = trap_ModelIndex( name ); // <- This is the unmodified version ent->s.modelindex = atoi( name+1 ); // !racesow assert( ent->s.modelindex == (unsigned int)atoi( name + 1 ) ); cmodel = trap_CM_InlineModel( ent->s.modelindex ); trap_CM_InlineModelBounds( cmodel, ent->r.mins, ent->r.maxs ); GClip_LinkEntity( ent ); }
/* * W_Fire_GunbladeBlast */ edict_t *W_Fire_GunbladeBlast( edict_t *self, vec3_t start, vec3_t angles, float damage, int minKnockback, int maxKnockback, int stun, int minDamage, int radius, int speed, int timeout, int mod, int timeDelta ) { edict_t *blast; if( GS_Instagib() ) damage = 9999; blast = W_Fire_LinearProjectile( self, start, angles, speed, damage, minKnockback, maxKnockback, stun, minDamage, radius, timeout, timeDelta ); blast->s.modelindex = trap_ModelIndex( PATH_GUNBLADEBLAST_STRONG_MODEL ); blast->s.type = ET_BLASTER; blast->s.effects |= EF_STRONG_WEAPON; blast->touch = W_Touch_GunbladeBlast; blast->classname = "gunblade_blast"; blast->style = mod; blast->s.sound = trap_SoundIndex( S_WEAPON_PLASMAGUN_S_FLY ); return blast; }
/* * W_Fire_Electrobolt_Weak */ edict_t *W_Fire_Electrobolt_Weak( edict_t *self, vec3_t start, vec3_t angles, float speed, float damage, int minKnockback, int maxKnockback, int stun, int timeout, int mod, int timeDelta ) { edict_t *bolt; if( GS_Instagib() ) damage = 9999; // projectile, weak mode bolt = W_Fire_LinearProjectile( self, start, angles, speed, damage, minKnockback, maxKnockback, stun, 0, 0, timeout, timeDelta ); bolt->s.modelindex = trap_ModelIndex( PATH_ELECTROBOLT_WEAK_MODEL ); bolt->s.type = ET_ELECTRO_WEAK; //add particle trail and light bolt->s.ownerNum = ENTNUM( self ); bolt->touch = W_Touch_Bolt; bolt->classname = "bolt"; bolt->style = mod; bolt->s.effects &= ~EF_STRONG_WEAPON; return bolt; }
//========================================== // just a debug tool //========================================== void AI_JumpadGuess_ShowPoint( vec3_t origin, char *modelname ) { edict_t *ent; ent = G_Spawn(); VectorCopy ( origin, ent->s.origin); VectorClear ( ent->movedir ); ent->movetype = MOVETYPE_NONE; ent->clipmask = MASK_WATER; ent->solid = SOLID_NOT; ent->s.type = ET_GENERIC; ent->s.renderfx |= RF_NOSHADOW; VectorClear ( ent->mins ); VectorClear ( ent->maxs ); ent->s.modelindex = trap_ModelIndex ( modelname ); ent->nextthink = level.time + 20000; ent->think = G_FreeEdict; ent->classname = "checkent"; trap_LinkEntity (ent); }
void G_PrecacheMedia( void ) { // // MODELS // // THIS ORDER MUST MATCH THE DEFINES IN gs_public.h // you can add more, max 255 trap_ModelIndex( "#gunblade/gunblade.md3" ); // WEAP_GUNBLADE trap_ModelIndex( "#machinegun/machinegun.md3" ); // WEAP_MACHINEGUN trap_ModelIndex( "#riotgun/riotgun.md3" ); // WEAP_RIOTGUN trap_ModelIndex( "#glauncher/glauncher.md3" ); // WEAP_GRENADELAUNCHER trap_ModelIndex( "#rlauncher/rlauncher.md3" ); // WEAP_ROCKETLAUNCHER trap_ModelIndex( "#plasmagun/plasmagun.md3" ); // WEAP_PLASMAGUN trap_ModelIndex( "#lasergun/lasergun.md3" ); // WEAP_LASERGUN trap_ModelIndex( "#electrobolt/electrobolt.md3" ); // WEAP_ELECTROBOLT trap_ModelIndex( "#instagun/instagun.md3" ); // WEAP_INSTAGUN //------------------- // precache our basic player models, they are just a very few trap_ModelIndex( "$models/players/bigvic" ); trap_SkinIndex( "models/players/bigvic/default" ); // FIXME: Temporarily use normal gib until the head is fixed trap_ModelIndex( "models/objects/gibs/illuminati1/illuminati1.md3" ); // // SOUNDS // // jalfixme : most of these sounds can be played from the clients trap_SoundIndex( S_WORLD_WATER_IN ); // feet hitting water trap_SoundIndex( S_WORLD_WATER_OUT ); // feet leaving water trap_SoundIndex( S_WORLD_UNDERWATER ); trap_SoundIndex( S_WORLD_SLIME_IN ); trap_SoundIndex( S_WORLD_SLIME_OUT ); trap_SoundIndex( S_WORLD_UNDERSLIME ); trap_SoundIndex( S_WORLD_LAVA_IN ); trap_SoundIndex( S_WORLD_LAVA_OUT ); trap_SoundIndex( S_WORLD_UNDERLAVA ); trap_SoundIndex( va( S_PLAYER_BURN_1_to_2, 1 ) ); trap_SoundIndex( va( S_PLAYER_BURN_1_to_2, 2 ) ); //wsw: pb disable unreferenced sounds //trap_SoundIndex (S_LAND); // landing thud trap_SoundIndex( S_HIT_WATER ); trap_SoundIndex( S_WEAPON_NOAMMO ); // announcer // readyup trap_SoundIndex( S_ANNOUNCER_READY_UP_POLITE ); trap_SoundIndex( S_ANNOUNCER_READY_UP_PISSEDOFF ); // countdown trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_GET_READY_TO_FIGHT_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_GET_READY_TO_FIGHT_1_to_2, 2 ) ); trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_READY_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_READY_1_to_2, 2 ) ); trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, 1, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, 2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, 3, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, 1, 2 ) ); trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, 2, 2 ) ); trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, 3, 2 ) ); trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_FIGHT_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_FIGHT_1_to_2, 2 ) ); // postmatch trap_SoundIndex( va( S_ANNOUNCER_POSTMATCH_GAMEOVER_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_POSTMATCH_GAMEOVER_1_to_2, 2 ) ); // timeout trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_MATCH_RESUMED_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_MATCH_RESUMED_1_to_2, 2 ) ); trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_TIMEOUT_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_TIMEOUT_1_to_2, 2 ) ); trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_TIMEIN_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_TIMEIN_1_to_2, 2 ) ); // callvote trap_SoundIndex( va( S_ANNOUNCER_CALLVOTE_CALLED_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_CALLVOTE_CALLED_1_to_2, 2 ) ); trap_SoundIndex( va( S_ANNOUNCER_CALLVOTE_FAILED_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_CALLVOTE_FAILED_1_to_2, 2 ) ); trap_SoundIndex( va( S_ANNOUNCER_CALLVOTE_PASSED_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_CALLVOTE_PASSED_1_to_2, 2 ) ); trap_SoundIndex( S_ANNOUNCER_CALLVOTE_VOTE_NOW ); // overtime trap_SoundIndex( S_ANNOUNCER_OVERTIME_GOING_TO_OVERTIME ); trap_SoundIndex( S_ANNOUNCER_OVERTIME_OVERTIME ); trap_SoundIndex( va( S_ANNOUNCER_OVERTIME_SUDDENDEATH_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_OVERTIME_SUDDENDEATH_1_to_2, 2 ) ); // score trap_SoundIndex( va( S_ANNOUNCER_SCORE_TAKEN_LEAD_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_SCORE_TAKEN_LEAD_1_to_2, 2 ) ); trap_SoundIndex( va( S_ANNOUNCER_SCORE_LOST_LEAD_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_SCORE_LOST_LEAD_1_to_2, 2 ) ); trap_SoundIndex( va( S_ANNOUNCER_SCORE_TIED_LEAD_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_SCORE_TIED_LEAD_1_to_2, 2 ) ); if( GS_TeamBasedGametype() ) { trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_TAKEN_LEAD_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_TAKEN_LEAD_1_to_2, 2 ) ); trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_LOST_LEAD_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_LOST_LEAD_1_to_2, 2 ) ); trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_TIED_LEAD_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_TIED_LEAD_1_to_2, 2 ) ); trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_TIED_LEAD_1_to_2, 1 ) ); trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_TIED_LEAD_1_to_2, 2 ) ); //trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_1_to_4_TAKEN_LEAD_1_to_2, 3, 1 ) ); //trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_1_to_4_TAKEN_LEAD_1_to_2, 3, 2 ) ); //trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_1_to_4_TAKEN_LEAD_1_to_2, 4, 1 ) ); //trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_1_to_4_TAKEN_LEAD_1_to_2, 4, 2 ) ); } // // LIGHTSTYLES // // light animation tables. 'a' is total darkness, 'z' is doublebright. // 0 normal trap_ConfigString( CS_LIGHTS+0, "m" ); // 1 FLICKER (first variety) trap_ConfigString( CS_LIGHTS+1, "mmnmmommommnonmmonqnmmo" ); // 2 SLOW STRONG PULSE trap_ConfigString( CS_LIGHTS+2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba" ); // 3 CANDLE (first variety) trap_ConfigString( CS_LIGHTS+3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg" ); // 4 FAST STROBE trap_ConfigString( CS_LIGHTS+4, "mamamamamama" ); // 5 GENTLE PULSE 1 trap_ConfigString( CS_LIGHTS+5, "jklmnopqrstuvwxyzyxwvutsrqponmlkj" ); // 6 FLICKER (second variety) trap_ConfigString( CS_LIGHTS+6, "nmonqnmomnmomomno" ); // 7 CANDLE (second variety) trap_ConfigString( CS_LIGHTS+7, "mmmaaaabcdefgmmmmaaaammmaamm" ); // 8 CANDLE (third variety) trap_ConfigString( CS_LIGHTS+8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa" ); // 9 SLOW STROBE (fourth variety) trap_ConfigString( CS_LIGHTS+9, "aaaaaaaazzzzzzzz" ); // 10 FLUORESCENT FLICKER trap_ConfigString( CS_LIGHTS+10, "mmamammmmammamamaaamammma" ); // 11 SLOW PULSE NOT FADE TO BLACK trap_ConfigString( CS_LIGHTS+11, "abcdefghijklmnopqrrqponmlkjihgfedcba" ); // styles 32-62 are assigned by the light program for switchable lights // 63 testing trap_ConfigString( CS_LIGHTS+63, "a" ); }
/* * Finish_SpawningItem */ static void Finish_SpawningItem( edict_t *ent ) { trace_t tr; vec3_t dest; gsitem_t *item = ent->item; assert( item ); ent->s.itemNum = item->tag; VectorCopy( item_box_mins, ent->r.mins ); VectorCopy( item_box_maxs, ent->r.maxs ); if( ent->model ) { ent->s.modelindex = trap_ModelIndex( ent->model ); } else { if( item->world_model[0] ) ent->s.modelindex = trap_ModelIndex( item->world_model[0] ); if( item->world_model[1] ) ent->s.modelindex2 = trap_ModelIndex( item->world_model[1] ); } ent->r.solid = SOLID_TRIGGER; ent->r.svflags &= ~SVF_NOCLIENT; ent->movetype = MOVETYPE_TOSS; ent->touch = Touch_Item; ent->attenuation = 1; if( ent->spawnflags & 1 ) ent->gravity = 0; G_Trace( &tr, ent->s.origin, ent->r.mins, ent->r.maxs, ent->s.origin, ent, MASK_SOLID ); if( tr.startsolid ) { vec3_t end; // move it 16 units up, cause it's typical they share the leaf with the floor VectorCopy( ent->s.origin, end ); end[2] += 16; G_Trace( &tr, end, ent->r.mins, ent->r.maxs, ent->s.origin, ent, MASK_SOLID ); if( tr.startsolid ) { G_Printf( "Warning: %s %s spawns inside solid. Inhibited\n", ent->classname, vtos( ent->s.origin ) ); G_FreeEdict( ent ); return; } VectorCopy( tr.endpos, ent->s.origin ); } // drop the item to floor if( ent->gravity ) { VectorSet( dest, ent->s.origin[0], ent->s.origin[1], ent->s.origin[2] - 128 ); G_Trace( &tr, ent->s.origin, ent->r.mins, ent->r.maxs, dest, ent, MASK_SOLID ); VectorCopy( tr.endpos, ent->s.origin ); } if( item->type & IT_HEALTH ) { if( item->tag == HEALTH_SMALL || item->tag == HEALTH_ULTRA ) ent->style = HEALTH_IGNORE_MAX; else if( item->tag == HEALTH_MEGA ) ent->style = HEALTH_IGNORE_MAX|HEALTH_TIMED; } if( ent->team ) { ent->flags &= ~FL_TEAMSLAVE; ent->chain = ent->teamchain; ent->teamchain = NULL; ent->r.svflags |= SVF_NOCLIENT; ent->r.solid = SOLID_NOT; // team slaves and targeted items aren't present at start if( ent == ent->teammaster && !ent->targetname ) { ent->nextThink = level.time + 1; ent->think = DoRespawn; GClip_LinkEntity( ent ); } } else if( ent->targetname ) { ent->r.svflags |= SVF_NOCLIENT; ent->r.solid = SOLID_NOT; } GClip_LinkEntity( ent ); AI_AddGoalEntity( ent ); }
edict_t *Drop_Item( edict_t *ent, gsitem_t *item ) { edict_t *dropped; vec3_t forward, right; vec3_t offset; if( !G_Gametype_CanDropItem( item, qfalse ) ) return NULL; dropped = G_Spawn(); dropped->classname = item->classname; dropped->item = item; dropped->spawnflags = DROPPED_ITEM; VectorCopy( item_box_mins, dropped->r.mins ); VectorCopy( item_box_maxs, dropped->r.maxs ); dropped->r.solid = SOLID_TRIGGER; dropped->movetype = MOVETYPE_TOSS; dropped->touch = drop_temp_touch; dropped->stop = AI_AddGoalEntity; dropped->r.owner = ent; dropped->r.svflags &= ~SVF_NOCLIENT; dropped->s.team = ent->s.team; dropped->s.type = ET_ITEM; dropped->s.itemNum = item->tag; dropped->s.effects = 0; // default effects are applied client side dropped->s.modelindex = trap_ModelIndex( dropped->item->world_model[0] ); dropped->s.modelindex2 = trap_ModelIndex( dropped->item->world_model[1] ); dropped->attenuation = 1; if( ent->r.client ) { trace_t trace; AngleVectors( ent->r.client->ps.viewangles, forward, right, NULL ); VectorSet( offset, 24, 0, -16 ); G_ProjectSource( ent->s.origin, offset, forward, right, dropped->s.origin ); G_Trace( &trace, ent->s.origin, dropped->r.mins, dropped->r.maxs, dropped->s.origin, ent, CONTENTS_SOLID ); VectorCopy( trace.endpos, dropped->s.origin ); dropped->spawnflags |= DROPPED_PLAYER_ITEM; // ugly hack for dropping backpacks if( item->tag == AMMO_PACK_WEAK || item->tag == AMMO_PACK_STRONG || item->tag == AMMO_PACK ) { int w; qboolean anything = qfalse; for( w = WEAP_GUNBLADE + 1; w < WEAP_TOTAL; w++ ) { if( item->tag == AMMO_PACK_WEAK || item->tag == AMMO_PACK ) { int weakTag = GS_FindItemByTag( w )->weakammo_tag; if( ent->r.client->ps.inventory[weakTag] > 0 ) { dropped->invpak[weakTag] = ent->r.client->ps.inventory[weakTag]; ent->r.client->ps.inventory[weakTag] = 0; anything = qtrue; } } if( item->tag == AMMO_PACK_STRONG || item->tag == AMMO_PACK ) { int strongTag = GS_FindItemByTag( w )->ammo_tag; if( ent->r.client->ps.inventory[strongTag] ) { dropped->invpak[strongTag] = ent->r.client->ps.inventory[strongTag]; ent->r.client->ps.inventory[strongTag] = 0; anything = qtrue; } } } if( !anything ) // if nothing was added to the pack, don't bother spawning it { G_FreeEdict( dropped ); return NULL; } } // power-ups are special if( ( item->type & IT_POWERUP ) && item->quantity ) { if( ent->r.client->ps.inventory[item->tag] ) { dropped->count = ent->r.client->ps.inventory[item->tag]; ent->r.client->ps.inventory[item->tag] = 0; } else { dropped->count = item->quantity; } } } else { AngleVectors( ent->s.angles, forward, right, NULL ); VectorCopy( ent->s.origin, dropped->s.origin ); // ugly hack for dropping backpacks if( item->tag == AMMO_PACK_WEAK || item->tag == AMMO_PACK_STRONG || item->tag == AMMO_PACK ) { int w; for( w = WEAP_GUNBLADE + 1; w < WEAP_TOTAL; w++ ) { if( item->tag == AMMO_PACK_WEAK || item->tag == AMMO_PACK ) { gsitem_t *ammo = GS_FindItemByTag( GS_FindItemByTag( w )->weakammo_tag ); if( ammo ) dropped->invpak[ammo->tag] = ammo->quantity; } if( item->tag == AMMO_PACK_STRONG || item->tag == AMMO_PACK ) { gsitem_t *ammo = GS_FindItemByTag( GS_FindItemByTag( w )->ammo_tag ); if( ammo ) dropped->invpak[ammo->tag] = ammo->quantity; } } } // power-ups are special if( ( item->type & IT_POWERUP ) && item->quantity ) { dropped->count = item->quantity; } } VectorScale( forward, 100, dropped->velocity ); dropped->velocity[2] = 300; dropped->think = drop_make_touchable; dropped->nextThink = level.time + 1000; ent->r.client->teamstate.last_drop_item = item; VectorCopy( dropped->s.origin, ent->r.client->teamstate.last_drop_location ); GClip_LinkEntity( dropped ); return dropped; }
/* * PrecacheItem * * Precaches all data needed for a given item. * This will be called for each item spawned in a level, * and for each item in each client's inventory. */ void PrecacheItem( gsitem_t *it ) { int i; const char *s, *start; char data[MAX_QPATH]; int len; gsitem_t *ammo; if( !it ) return; if( it->pickup_sound ) trap_SoundIndex( it->pickup_sound ); for( i = 0; i < MAX_ITEM_MODELS; i++ ) { if( it->world_model[i] ) trap_ModelIndex( it->world_model[i] ); } if( it->icon ) trap_ImageIndex( it->icon ); // parse everything for its ammo if( it->ammo_tag ) { ammo = GS_FindItemByTag( it->ammo_tag ); if( ammo != it ) PrecacheItem( ammo ); } // parse the space separated precache string for other items for( i = 0; i < 3; i++ ) { if( i == 0 ) s = it->precache_models; else if( i == 1 ) s = it->precache_sounds; else s = it->precache_images; if( !s || !s[0] ) continue; while( *s ) { start = s; while( *s && *s != ' ' ) s++; len = s-start; if( len >= MAX_QPATH || len < 5 ) G_Error( "PrecacheItem: %s has bad precache string", it->classname ); memcpy( data, start, len ); data[len] = 0; if( *s ) s++; if( i == 0 ) trap_ModelIndex( data ); else if( i == 1 ) trap_SoundIndex( data ); else trap_ImageIndex( data ); } } }