// // Update_Chain - Repositions the chain links each frame. This single function // maintains the positions of all of the links. Only one link // is thinking every frame. // void UpdateChain() { vec3_t t1, t2, t3; vec3_t temp; gedict_t *owner = PROG_TO_EDICT( self->s.v.owner ), *goal, *goal2; if (!owner->hook_out) { self->s.v.think = (func_t) RemoveChain; self->s.v.nextthink = g_globalvars.time; return; } VectorSubtract(owner->hook->s.v.origin, owner->s.v.origin, temp); VectorScale(temp, 0.25, t1); VectorAdd(t1, owner->s.v.origin, t1); VectorScale(temp, 0.50, t2); VectorAdd(t2, owner->s.v.origin, t2); VectorScale(temp, 0.75, t3); VectorAdd(t3, owner->s.v.origin, t3); goal = PROG_TO_EDICT(self->s.v.goalentity); goal2 = PROG_TO_EDICT(goal->s.v.goalentity); // These numbers are correct assuming 3 links. // 4 links would be *20 *40 *60 and *80 setorigin (self, PASSVEC3(t1)); setorigin (goal, PASSVEC3(t2)); setorigin (goal2, PASSVEC3(t3)); self->s.v.nextthink = g_globalvars.time + 0.1; }
void FireSentryBulletsNEW( int shotcount, gedict_t * targ, float spread_x, float spread_y, float spread_z ) { vec3_t src; vec3_t dst; vec3_t norm_dir; sgAimNew( self, targ, src, dst, norm_dir ); ClearMultiDamage( ); traceline( PASSVEC3( src ), PASSVEC3( dst ), 0, self ); VectorScale( norm_dir, 4, puff_org ); VectorSubtract( g_globalvars.trace_endpos, puff_org, puff_org ); for ( ; shotcount > 0 ; shotcount-- ) { // для каждого выстрела определяем trace_ent trace_endpos // т.к.выстрелы могут убрать препятствия traceline( PASSVEC3( src ), PASSVEC3( dst ), 0, self ); // TraceAttack требует нормализованый вектор для корректного определения blood_org if(g_globalvars.trace_fraction != 1) TraceAttack( 4, norm_dir ); } ApplyMultiDamage( ); Multi_Finish( ); }
void BotReport( ) { gedict_t *te; for ( te = world; ( te = trap_find( te, FOFS( s.v.classname ), "player" ) ); ) { if ( te->has_disconnected ) continue; if ( te->isBot ) { G_bprint(3,"Bot: %s, state %d, menu %d flags %d velocity %3.0f\norigin [%.0f %.0f %.0f]\n", te->s.v.netname,te->action,te->current_menu, (int)(te->s.v.flags), vlen(te->s.v.velocity), PASSVEC3(te->s.v.origin) ); if( te->wp ) G_bprint(3, "wp [%.0f %.0f %.0f]\n", PASSVEC3(te->wp->origin)); else G_bprint(3, "nowp\n"); if( te->end_wp ) G_bprint(3, "endwp [%.0f %.0f %.0f]\n", PASSVEC3(te->end_wp->origin)); } } }
/* ================= LightningDamage ================= */ void LightningDamage( vec3_t p1, vec3_t p2, gedict_t * from, float damage ) { gedict_t *e1, *e2; vec3_t f; VectorSubtract( p2, p1, f ); // f = p2 - p1; VectorNormalize( f ); // normalize (f); f[0] = 0 - f[1]; f[1] = f[0]; f[2] = 0; VectorScale( f, 16, f ); //f = f*16; e1 = e2 = world; traceline( PASSVEC3( p1 ), PASSVEC3( p2 ), false, self ); if ( PROG_TO_EDICT( g_globalvars.trace_ent )->s.v.takedamage ) { LightningHit( from, damage ); if ( streq( self->s.v.classname, "player" ) ) { if ( streq( other->s.v.classname, "player" ) ) PROG_TO_EDICT( g_globalvars.trace_ent )->s.v. velocity[2] += 400; } } e1 = PROG_TO_EDICT( g_globalvars.trace_ent ); //traceline (p1 + f, p2 + f, FALSE, self); traceline( p1[0] + f[0], p1[1] + f[1], p1[2] + f[2], p2[0] + f[0], p2[1] + f[1], p2[2] + f[2], false, self ); if ( PROG_TO_EDICT( g_globalvars.trace_ent ) != e1 && PROG_TO_EDICT( g_globalvars.trace_ent )->s.v.takedamage ) { LightningHit( from, damage ); } e2 = PROG_TO_EDICT( g_globalvars.trace_ent ); traceline( p1[0] - f[0], p1[1] - f[1], p1[2] - f[2], p2[0] - f[0], p2[1] - f[1], p2[2] - f[2], false, self ); if ( PROG_TO_EDICT( g_globalvars.trace_ent ) != e1 && PROG_TO_EDICT( g_globalvars.trace_ent ) != e2 && PROG_TO_EDICT( g_globalvars.trace_ent )->s.v.takedamage ) { LightningHit( from, damage ); } }
/* ================ SpawnMeatSpray ================ */ void SpawnMeatSpray( vec3_t org, vec3_t vel ) { gedict_t *missile; //vec3_t org; missile = spawn(); missile->s.v.owner = EDICT_TO_PROG( self ); missile->s.v.movetype = MOVETYPE_BOUNCE; missile->s.v.solid = SOLID_NOT; makevectors( self->s.v.angles ); VectorCopy( vel, missile->s.v.velocity ); // missile->s.v.velocity = vel; missile->s.v.velocity[2] = missile->s.v.velocity[2] + 250 + 50 * g_random(); SetVector( missile->s.v.avelocity, 3000, 1000, 2000 ); // missile.avelocity = '3000 1000 2000'; // set missile duration missile->s.v.nextthink = g_globalvars.time + 1; missile->s.v.think = ( func_t ) SUB_Remove; setmodel( missile, "progs/zom_gib.mdl" ); setsize( missile, 0, 0, 0, 0, 0, 0 ); setorigin( missile, PASSVEC3( org ) ); }
void Bot_CL_KeyMove( ) { int forwardmove = 0, sidemove = 0, upmove = 0; int buttons = 0; buttons = ( ( self->s.v.button0 ) ? 1 : 0 ) + ( ( self->s.v.button2 ) ? 2 : 0 ); sidemove += self->maxstrafespeed * CL_KeyState( KEY_MOVERIGHT ); sidemove -= self->maxstrafespeed * CL_KeyState( KEY_MOVELEFT ); upmove += 200 * CL_KeyState( KEY_MOVEUP ); upmove -= 200 * CL_KeyState( KEY_MOVEDOWN ); forwardmove += self->maxfbspeed * CL_KeyState( KEY_MOVEFORWARD ); forwardmove -= self->maxfbspeed * CL_KeyState( KEY_MOVEBACK ); if ( self->s.v.v_angle[0] > 80 ) self->s.v.v_angle[0] = 80; else { if ( self->s.v.v_angle[0] < -70 ) self->s.v.v_angle[0] = -70; } //self->s.v.v_angle[2] = 0; self->s.v.v_angle[1] = anglemod( self->s.v.v_angle[1] ); trap_SetBotCMD( NUM_FOR_EDICT( self ), bot_frametime * 1000, PASSVEC3(self->s.v.v_angle), forwardmove, sidemove, upmove, buttons, self->s.v.impulse ); }
/* ================ SpectatorImpulseCommand Called by SpectatorThink if the spectator entered an impulse ================ */ void SpectatorImpulseCommand() { gedict_t *goal; if ( self->s.v.impulse == 1 ) { // teleport the spectator to the next spawn point // note that if the spectator is tracking, this doesn't do // much goal = PROG_TO_EDICT( self->s.v.goalentity ); goal = find( goal, FOFS( s.v.classname ), "info_player_deathmatch" ); if ( !goal ) goal = find( world, FOFS( s.v.classname ), "info_player_deathmatch" ); if ( goal ) { setorigin( self, PASSVEC3( goal->s.v.origin ) ); VectorCopy( goal->s.v.angles, self->s.v.angles ); self->s.v.fixangle = true; // turn this way immediately } else goal = world; self->s.v.goalentity = EDICT_TO_PROG( goal ); } self->s.v.impulse = 0; }
/*QUAKED trigger_teleport (.5 .5 .5) ? PLAYER_ONLY SILENT Any object touching this will be transported to the corresponding info_teleport_destination entity. You must set the "target" field, and create an object with a "targetname" field that matches. If the trigger_teleport has a targetname, it will only teleport entities when it has been fired. */ void SP_trigger_teleport( ) { vec3_t o; if ( !CheckExistence( ) ) { dremove( self ); return; } InitTrigger( ); self->s.v.touch = ( func_t ) teleport_touch; // find the destination if ( !self->s.v.target ) G_Error( "no target" ); self->s.v.use = ( func_t ) teleport_use; if ( !( ( int ) ( self->s.v.spawnflags ) & SILENT ) ) { trap_precache_sound( "ambience/hum1.wav" ); VectorAdd( self->s.v.mins, self->s.v.maxs, o ); VectorScale( o, 0.5, o ); //o = (self.mins + self.maxs)*0.5; trap_ambientsound( PASSVEC3( o ), "ambience/hum1.wav", 0.5, ATTN_STATIC ); } }
void fire_fly() { gedict_t *fireball; fireball = spawn(); fireball->s.v.solid = SOLID_TRIGGER; fireball->s.v.movetype = MOVETYPE_TOSS; fireball->isMissile = true; // well, you can really treat fireball as missilie, nothing bad gonna heppen. SetVector( fireball->s.v.velocity, ( g_random() * 100 ) - 50, ( g_random() * 100 ) - 50, self->speed + ( g_random() * 200 ) ); fireball->classname = "fireball"; setmodel( fireball, "progs/lavaball.mdl" ); setsize( fireball, 0, 0, 0, 0, 0, 0 ); setorigin( fireball, PASSVEC3( self->s.v.origin ) ); fireball->s.v.nextthink = g_globalvars.time + 5; fireball->think = ( func_t ) SUB_Remove; fireball->touch = ( func_t ) fire_touch; self->s.v.nextthink = g_globalvars.time + ( g_random() * 5 ) + 3; self->think = ( func_t ) fire_fly; }
void FlagThink() { if ( !isCTF() ) return; self->s.v.nextthink = g_globalvars.time + 0.1; if (self->cnt == FLAG_AT_BASE) return; if (self->cnt == FLAG_DROPPED) { self->cnt2 += 0.1; if ( g_globalvars.time > self->super_time ) { RegenFlag( self ); G_bprint( 2, "The %s flag has been returned\n", redtext( ( (int) self->s.v.items & IT_KEY1) ? "BLUE" : "RED" ) ); } return; } if (self->cnt == FLAG_RETURNED) { setorigin( self, PASSVEC3(self->s.v.oldorigin) ); self->cnt = FLAG_AT_BASE; return; } self->cnt2 += 0.1; }
static void fb_spawn_door(gedict_t* ent) { gedict_t* original = ent; vec3_t position; VectorScale (original->s.v.mins, 0.5, position); VectorMA (position, 0.5, original->s.v.maxs, position); position[2] = min (original->s.v.mins[2], original->s.v.maxs[2]) + 24; ent = CreateMarker(PASSVEC3(position)); ent->classname = "door_marker"; ent->fb.door_entity = original; ent->s.v.solid = SOLID_NOT; // this will be set to SOLID_TRIGGER if MARKER_DOOR_TOUCHABLE flag set if (ent->fb.wait < 0) { // TODO: ? return; } else if ((int)ent->s.v.spawnflags & SECRET_OPEN_ONCE) { // TODO: ? return; } else { if (ent->s.v.health) { //Add_takedamage(ent); } adjust_view_ofs_z(ent); //BecomeMarker(ent); } }
void Laser_Touch( ) { vec3_t org; if ( other == PROG_TO_EDICT( self->s.v.owner ) ) return; // don't explode on owner if ( trap_pointcontents( PASSVEC3( self->s.v.origin ) ) == CONTENT_SKY ) { ent_remove( self ); return; } sound( self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC ); normalize( self->s.v.velocity, org ); VectorScale( org, 8, org ); VectorSubtract( self->s.v.origin, org, org ); //org = self->s.v.origin - 8*normalize(self->s.v.velocity); if ( other->s.v.health ) { SpawnBlood( org, 15 ); TF_T_Damage( other, self, PROG_TO_EDICT( self->s.v.owner ), 15, 0, TF_TD_ELECTRICITY ); } else { TempEffectCount( org, TE_GUNSHOT, 5); } dremove( self ); }
void fire_fly( ) { gedict_t *fireball; fireball = spawn( ); newmis = fireball; g_globalvars.newmis = EDICT_TO_PROG( newmis ); fireball->s.v.solid = SOLID_TRIGGER; fireball->s.v.movetype = MOVETYPE_TOSS; SetVector( fireball->s.v.velocity, ( g_random( ) * 100 ) - 50, ( g_random( ) * 100 ) - 50, self->speed + ( g_random( ) * 200 ) ); fireball->s.v.classname = "fireball"; setmodel( fireball, "progs/lavaball.mdl" ); setsize( fireball, 0, 0, 0, 0, 0, 0 ); setorigin( fireball, PASSVEC3( self->s.v.origin ) ); fireball->s.v.nextthink = g_globalvars.time + 5; fireball->s.v.think = ( func_t ) SUB_Remove; fireball->s.v.touch = ( func_t ) fire_touch; self->s.v.nextthink = g_globalvars.time + ( g_random( ) * 5 ) + 3; self->s.v.think = ( func_t ) fire_fly; }
void LaunchLaser( vec3_t org, vec3_t vec ) { if ( !strcmp( self->s.v.classname, "monster_enforcer" ) ) sound( self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM ); normalize( vec, vec ); newmis = spawn( ); g_globalvars.newmis = EDICT_TO_PROG( newmis ); newmis->s.v.owner = EDICT_TO_PROG( self ); newmis->s.v.movetype = MOVETYPE_FLY; newmis->s.v.solid = SOLID_BBOX; newmis->s.v.effects = EF_DIMLIGHT; setmodel( newmis, "progs/laser.mdl" ); setsize( newmis, 0, 0, 0, 0, 0, 0 ); setorigin( newmis, PASSVEC3( org ) ); //newmis->s.v.velocity = vec * 600; VectorScale( vec, 600, newmis->s.v.velocity ); vectoangles( newmis->s.v.velocity, newmis->s.v.angles ); newmis->s.v.nextthink = g_globalvars.time + 5; newmis->s.v.think = ( func_t ) SUB_Remove; newmis->s.v.touch = ( func_t ) Laser_Touch; }
void FireAmbient() { trap_precache_sound( "ambience/fire1.wav" ); // attenuate fast trap_ambientsound( PASSVEC3( self->s.v.origin ), "ambience/fire1.wav", 0.5, ATTN_STATIC ); }
void bubble_split( ) { gedict_t *bubble; bubble = spawn( ); setmodel( bubble, "progs/s_bubble.spr" ); setorigin( bubble, PASSVEC3( self->s.v.origin ) ); bubble->s.v.movetype = MOVETYPE_NOCLIP; bubble->s.v.solid = SOLID_NOT; VectorCopy( self->s.v.velocity, bubble->s.v.velocity ); bubble->s.v.nextthink = g_globalvars.time + 0.5; bubble->s.v.think = ( func_t ) bubble_bob; bubble->s.v.touch = ( func_t ) bubble_remove; bubble->s.v.classname = "bubble"; bubble->s.v.frame = 1; bubble->cnt = 10; setsize( bubble, -8, -8, -8, 8, 8, 8 ); self->s.v.frame = 1; self->cnt = 10; if ( self->s.v.waterlevel != 3 ) ent_remove( self ); }
void SUB_regen() { self->s.v.model = self->mdl; // restore original model self->s.v.solid = SOLID_TRIGGER; // allow it to be touched again sound( self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM ); // play respawn sound setorigin( self, PASSVEC3( self->s.v.origin ) ); }
void SP_misc_explobox2( ) { float oldz; if ( !CheckExistence( ) ) { dremove( self ); return; } self->s.v.solid = SOLID_BBOX; self->s.v.movetype = MOVETYPE_NONE; trap_precache_model( "maps/b_exbox2.bsp" ); setmodel( self, "maps/b_exbox2.bsp" ); setsize( self, 0, 0, 0, 32, 32, 32 ); trap_precache_sound( "weapons/r_exp3.wav" ); self->s.v.health = 20; self->th_die = barrel_explode; self->s.v.takedamage = DAMAGE_AIM; self->s.v.origin[2] += 2; oldz = self->s.v.origin[2]; droptofloor( self ); if ( oldz - self->s.v.origin[2] > 250 ) { G_dprintf( "item fell out of level at '%f %f %f'\n", PASSVEC3( self->s.v.origin ) ); ent_remove( self ); } }
/* ============= visible returns 1 if the entity is visible to self, even if not infront () ============= */ float visible( gedict_t *targ ) { vec3_t spot1, spot2; VectorAdd( self->s.v.origin, self->s.v.view_ofs, spot1 ); VectorAdd( targ->s.v.origin, targ->s.v.view_ofs, spot2 ); traceline( PASSVEC3( spot1 ), PASSVEC3( spot2 ), true, self ); // see through other monsters if ( g_globalvars.trace_inopen && g_globalvars.trace_inwater ) return false; // sight line crossed contents if ( g_globalvars.trace_fraction == 1 ) return true; return false; }
void CheckBelowBuilding( gedict_t * bld ) { vec3_t below; VectorCopy( bld->s.v.origin, below ); if ( streq( bld->s.v.classname, "detpack" ) ) below[2] = below[2] - 8; else below[2] = below[2] - 24; traceline( PASSVEC3( bld->s.v.origin ), PASSVEC3( below ), 1, bld ); if ( g_globalvars.trace_fraction == 1 ) { bld->s.v.movetype = MOVETYPE_TOSS; bld->s.v.flags = ( int ) bld->s.v.flags - ( ( int ) bld->s.v.flags & FL_ONGROUND ); } }
void SP_func_door_secret() { if ( self->s.v.sounds == 0 ) self->s.v.sounds = 3; if ( self->s.v.sounds == 1 ) { trap_precache_sound( "doors/latch2.wav" ); trap_precache_sound( "doors/winch2.wav" ); trap_precache_sound( "doors/drclos4.wav" ); self->s.v.noise1 = "doors/latch2.wav"; self->s.v.noise2 = "doors/winch2.wav"; self->s.v.noise3 = "doors/drclos4.wav"; } if ( self->s.v.sounds == 2 ) { trap_precache_sound( "doors/airdoor1.wav" ); trap_precache_sound( "doors/airdoor2.wav" ); self->s.v.noise2 = "doors/airdoor1.wav"; self->s.v.noise1 = "doors/airdoor2.wav"; self->s.v.noise3 = "doors/airdoor2.wav"; } if ( self->s.v.sounds == 3 ) { trap_precache_sound( "doors/basesec1.wav" ); trap_precache_sound( "doors/basesec2.wav" ); self->s.v.noise2 = "doors/basesec1.wav"; self->s.v.noise1 = "doors/basesec2.wav"; self->s.v.noise3 = "doors/basesec2.wav"; } if ( self->dmg == 0 ) self->dmg = 2; // Magic formula... VectorCopy( self->s.v.angles, self->mangle ); SetVector( self->s.v.angles, 0, 0, 0 ); self->s.v.solid = SOLID_BSP; self->s.v.movetype = MOVETYPE_PUSH; self->s.v.classname = "door"; setmodel( self, self->s.v.model ); setorigin( self, PASSVEC3( self->s.v.origin ) ); self->s.v.touch = ( func_t ) secret_touch; self->s.v.blocked = ( func_t ) secret_blocked; self->speed = 50; self->s.v.use = ( func_t ) fd_secret_use; if ( !self->s.v.targetname || ( int ) ( self->s.v.spawnflags ) & SECRET_YES_SHOOT ) { self->s.v.health = 10000; self->s.v.takedamage = DAMAGE_YES; self->th_pain = fd_secret_use; } VectorCopy( self->s.v.origin, self->oldorigin ); // self.oldorigin = self.origin; if ( self->wait == 0 ) self->wait = 5; // 5 seconds before closing }
/*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8) Non-displayed light. Default light value is 300 Default style is 10 Makes sparking, broken fluorescent sound */ void SP_light_fluorospark() { if ( !self->style ) self->style = 10; trap_precache_sound( "ambience/buzz1.wav" ); trap_ambientsound( PASSVEC3( self->s.v.origin ), "ambience/buzz1.wav", 0.5, ATTN_STATIC ); }
/* ============ After moving, set origin to exact final destination ============ */ void SUB_CalcMoveDone() { setorigin( self, PASSVEC3( self->finaldest ) ); SetVector( self->s.v.velocity, 0, 0, 0 ); //self->s.v.nextthink = -1; if ( self->think1 ) self->think1(); }
void spike_touch() { //float rand; if ( other == PROG_TO_EDICT( self->s.v.owner ) ) return; if ( self->voided ) { return; } self->voided = 1; if ( other->s.v.solid == SOLID_TRIGGER ) return; // trigger field, do nothing if ( trap_pointcontents( PASSVEC3( self->s.v.origin ) ) == CONTENT_SKY ) { ent_remove( self ); return; } // hit something that bleeds if ( other->s.v.takedamage ) { spawn_touchblood( 9 ); other->deathtype = "nail"; T_Damage( other, self, PROG_TO_EDICT( self->s.v.owner ), 9 ); } else { trap_WriteByte( MSG_MULTICAST, SVC_TEMPENTITY ); if ( !strcmp( self->s.v.classname, "wizspike" ) ) trap_WriteByte( MSG_MULTICAST, TE_WIZSPIKE ); else if ( !strcmp( self->s.v.classname, "knightspike" ) ) trap_WriteByte( MSG_MULTICAST, TE_KNIGHTSPIKE ); else trap_WriteByte( MSG_MULTICAST, TE_SPIKE ); trap_WriteCoord( MSG_MULTICAST, self->s.v.origin[0] ); trap_WriteCoord( MSG_MULTICAST, self->s.v.origin[1] ); trap_WriteCoord( MSG_MULTICAST, self->s.v.origin[2] ); trap_multicast( PASSVEC3( self->s.v.origin ), MULTICAST_PHS ); } ent_remove( self ); }
/* ================ W_FireAxe ================ */ void W_FireAxe() { vec3_t source, dest; vec3_t org; makevectors( self->s.v.v_angle ); VectorCopy( self->s.v.origin, source ); source[2] += 16; VectorScale( g_globalvars.v_forward, 64, dest ); VectorAdd( dest, source, dest ) //source = self->s.v.origin + '0 0 16'; traceline( PASSVEC3( source ), PASSVEC3( dest ), false, self ); if ( g_globalvars.trace_fraction == 1.0 ) return; VectorScale( g_globalvars.v_forward, 4, org ); VectorSubtract( g_globalvars.trace_endpos, org, org ); // org = trace_endpos - v_forward*4; if ( PROG_TO_EDICT( g_globalvars.trace_ent )->s.v.takedamage ) { PROG_TO_EDICT( g_globalvars.trace_ent )->axhitme = 1; SpawnBlood( org, 20 ); if ( deathmatch > 3 ) T_Damage( PROG_TO_EDICT( g_globalvars.trace_ent ), self, self, 75 ); else T_Damage( PROG_TO_EDICT( g_globalvars.trace_ent ), self, self, 20 ); } else { // hit wall sound( self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM ); trap_WriteByte( MSG_MULTICAST, SVC_TEMPENTITY ); trap_WriteByte( MSG_MULTICAST, TE_GUNSHOT ); trap_WriteByte( MSG_MULTICAST, 3 ); trap_WriteCoord( MSG_MULTICAST, org[0] ); trap_WriteCoord( MSG_MULTICAST, org[1] ); trap_WriteCoord( MSG_MULTICAST, org[2] ); trap_multicast( PASSVEC3( org ), MULTICAST_PVS ); } }
/*QUAKED ambient_swamp2 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) */ void SP_ambient_swamp2( ) { if ( !CheckExistence( ) ) { dremove( self ); return; } trap_precache_sound( "ambience/swamp2.wav" ); trap_ambientsound( PASSVEC3( self->s.v.origin ), "ambience/swamp2.wav", 0.5, ATTN_STATIC ); }
/*QUAKED ambient_comp_hum (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) */ void SP_ambient_comp_hum( ) { if ( !CheckExistence( ) ) { dremove( self ); return; } trap_precache_sound( "ambience/comp1.wav" ); trap_ambientsound( PASSVEC3( self->s.v.origin ), "ambience/comp1.wav", 1, ATTN_STATIC ); }
/* ================ SpawnBlood ================ */ void SpawnBlood( vec3_t org, float damage ) { trap_WriteByte( MSG_MULTICAST, SVC_TEMPENTITY ); trap_WriteByte( MSG_MULTICAST, TE_BLOOD ); trap_WriteByte( MSG_MULTICAST, 1 ); trap_WriteCoord( MSG_MULTICAST, org[0] ); trap_WriteCoord( MSG_MULTICAST, org[1] ); trap_WriteCoord( MSG_MULTICAST, org[2] ); trap_multicast( PASSVEC3( org ), MULTICAST_PVS ); }
//========================================================================= // Laserbolt touch function. Just moves through the player and comes out // the other side. void LaserBolt_Touch( ) { vec3_t org; if ( other == PROG_TO_EDICT( self->s.v.owner ) ) return; // don't explode on same person twice if ( other == PROG_TO_EDICT( self->s.v.enemy ) && self->s.v.enemy ) return; if ( trap_pointcontents( PASSVEC3( self->s.v.origin ) ) == CONTENT_SKY ) { dremove( self ); return; } normalize( self->s.v.velocity, org ); VectorScale( org, 8, org ); VectorSubtract( self->s.v.origin, org, org ); if ( other->s.v.health ) { SpawnBlood( org, 15 ); tf_data.deathmsg = DMSG_LASERBOLT; TF_T_Damage( other, self, PROG_TO_EDICT( self->s.v.enemy ), 30, 2, TF_TD_ELECTRICITY ); VectorCopy( self->s.v.oldorigin, self->s.v.velocity ); self->s.v.owner = EDICT_TO_PROG( other ); setmodel( self, "" ); self->s.v.touch = ( func_t ) SUB_Null; self->s.v.nextthink = g_globalvars.time + 0.1; self->s.v.think = ( func_t ) LaserBolt_Think; return; } else { sound( self, 1, "enforcer/enfstop.wav", 1, 1 ); trap_WriteByte( MSG_MULTICAST, SVC_TEMPENTITY ); trap_WriteByte( MSG_MULTICAST, 11/*TE_SPIKE*/ ); trap_WriteCoord( MSG_MULTICAST, self->s.v.origin[0] ); trap_WriteCoord( MSG_MULTICAST, self->s.v.origin[1] ); trap_WriteCoord( MSG_MULTICAST, self->s.v.origin[2] ); trap_multicast( PASSVEC3( self->s.v.origin ), 1 ); } dremove( self ); }
static void PM_Accelerate (vec3_t vel_after_friction, qbool onGround, vec3_t orig_wishdir, vec3_t vel_result, qbool trace) { float addspeed, accelspeed, currentspeed; float wishspeed = 320; // FIXME: assuming attemping sv_maxspeed float accel = 10; // FIXME: assumption vec3_t velocity; vec3_t wishdir; VectorCopy (vel_after_friction, velocity); if (onGround) { velocity[2] = 0; } wishdir[0] = orig_wishdir[0]; wishdir[1] = orig_wishdir[1]; wishdir[2] = 0; wishspeed = VectorNormalize (wishdir); wishspeed = sv_maxspeed; // fixme: we scale back up to maximum just as passing command currentspeed = DotProduct (velocity, wishdir); addspeed = wishspeed - currentspeed; if (addspeed <= 0) { VectorCopy (vel_after_friction, vel_result); #ifdef DEBUG_MOVEMENT if (trace) { G_bprint (PRINT_HIGH, "%3.2f,KTX,%4.1f,%4.1f,%4.1f,%4.1f,%4.1f,%4.1f,%3.2f,%3.2f,%3.2f,0,%4.1f,%4.1f,%4.1f\n", g_globalvars.time, PASSVEC3 (vel_after_friction), PASSVEC3 (wishdir), wishspeed, currentspeed, addspeed, PASSVEC3 (vel_result) ); } #endif return; } accelspeed = accel * g_globalvars.frametime * wishspeed; VectorMA(vel_after_friction, min(accelspeed, addspeed), wishdir, vel_result); #ifdef DEBUG_MOVEMENT if (trace) { G_bprint (PRINT_HIGH, "%3.2f,KTX,%4.1f,%4.1f,%4.1f,%4.1f,%4.1f,%4.1f,%3.2f,%3.2f,%3.2f,%3.2f,%4.1f,%4.1f,%4.1f\n", g_globalvars.time, PASSVEC3 (vel_after_friction), PASSVEC3 (wishdir), wishspeed, currentspeed, addspeed, accelspeed, PASSVEC3 (vel_result) ); } #endif }