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 ); }
/* ============= GetMadAtAttacker T_Damage calls this when a monster is hurt ============= */ void GetMadAtAttacker( gedict_t *attacker ) { if ( !attacker || attacker == world ) return; // ignore world attacks if ( k_bloodfest && attacker->ct != ctPlayer) return; // in bloodfest mode get mad only on players. if ( attacker == self ) return; // do not mad on self. if ( attacker == PROG_TO_EDICT( self->s.v.enemy )) return; // alredy mad on this. // get mad unless of the same class (except for soldiers) if ( streq( self->s.v.classname, attacker->s.v.classname ) && strneq( self->s.v.classname, "monster_army" ) ) return; // OK, we are MAD! // remember current enemy if it was "player enemy", later we restore it if ( PROG_TO_EDICT( self->s.v.enemy )->ct == ctPlayer ) self->oldenemy = PROG_TO_EDICT( self->s.v.enemy ); // set new enemy self->s.v.enemy = EDICT_TO_PROG( attacker ); FoundTarget (); }
// // 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; }
//========================================================================= // Think function for the timer which checks the distance between the // Engineer and the building he's using void CheckDistance( ) { vec3_t dist; gedict_t *owner, *enemy; owner = PROG_TO_EDICT( self->s.v.owner ); enemy = PROG_TO_EDICT( self->s.v.enemy ); // Check to see if the Engineer's spanner'ed a different building // without leaving the area of this one. if ( owner->building != enemy ) { dremove( self ); return; } VectorSubtract( enemy->s.v.origin, owner->s.v.origin, dist ); if ( vlen( dist ) > 64 ) { CenterPrint( owner, "\n" ); owner->menu_count = MENU_REFRESH_RATE; owner->current_menu = MENU_DEFAULT; owner->building = world; dremove( self ); return; } self->s.v.nextthink = g_globalvars.time + 0.3; }
void tdeath_touch( ) { // gedict_t *spot; if ( other == PROG_TO_EDICT( self->s.v.owner ) ) return; if ( streq( other->s.v.classname, "player" ) ) { if ( other->invincible_finished > g_globalvars.time ) { self->s.v.classname = "teledeath2"; } if ( strneq( PROG_TO_EDICT( self->s.v.owner )->s.v.classname, "player" ) ) { T_Damage( PROG_TO_EDICT( self->s.v.owner ), self, self, 5000 ); return; } } if ( other->s.v.health ) { T_Damage( other, self, self, 5000 ); } if ( other->s.v.think == ( func_t ) TeamFortress_DetpackExplode ) { other->s.v.solid = SOLID_NOT; other->s.v.nextthink = g_globalvars.time + 1 + g_random( ) * 2; dremove( other->oldenemy ); G_bprint( 1, "%s's detpack was telefragged by %s\n", other->real_owner->s.v.netname, PROG_TO_EDICT( self->s.v.owner )->s.v.netname ); } }
/* ====================== SV_MoveToGoal ====================== */ void SV_MoveToGoal (void) { edict_t *ent, *goal; float dist; #ifdef QUAKE2 edict_t *enemy; #endif ent = PROG_TO_EDICT(pr_global_struct->self); goal = PROG_TO_EDICT(ent->v.goalentity); dist = G_FLOAT(OFS_PARM0); if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) ) { G_FLOAT(OFS_RETURN) = 0; return; } // if the next step hits the enemy, return immediately #ifdef QUAKE2 enemy = PROG_TO_EDICT(ent->v.enemy); if (enemy != sv.edicts && SV_CloseEnough (ent, enemy, dist) ) #else if ( PROG_TO_EDICT(ent->v.enemy) != sv.edicts && SV_CloseEnough (ent, goal, dist) ) #endif return; // bump around... if ( (rand()&3)==1 || !SV_StepDirection (ent, ent->v.ideal_yaw, dist)) { SV_NewChaseDir (ent, goal, dist); } }
void DeathBubblesSpawn() { gedict_t *bubble; if ( PROG_TO_EDICT( self->s.v.owner )->s.v.waterlevel != 3 ) return; bubble = spawn(); setmodel( bubble, "progs/s_bubble.spr" ); setorigin( bubble, PROG_TO_EDICT( self->s.v.owner )->s.v.origin[0], PROG_TO_EDICT( self->s.v.owner )->s.v.origin[1], PROG_TO_EDICT( self->s.v.owner )->s.v.origin[2] + 24 ); bubble->s.v.movetype = MOVETYPE_NOCLIP; bubble->s.v.solid = SOLID_NOT; SetVector( bubble->s.v.velocity, 0, 0, 15 ); bubble->s.v.nextthink = g_globalvars.time + 0.5; bubble->think = ( func_t ) bubble_bob; bubble->classname = "bubble"; bubble->s.v.frame = 0; bubble->cnt = 0; setsize( bubble, -8, -8, -8, 8, 8, 8 ); self->s.v.nextthink = g_globalvars.time + 0.1; self->think = ( func_t ) DeathBubblesSpawn; self->air_finished = self->air_finished + 1; if ( self->air_finished >= self->bubble_count ) ent_remove( self ); }
int Sentry_FindTarget( ) { gedict_t *client; float r; float gotone; float loopc; r = 0; loopc = 0; gotone = 0; while ( loopc < 6 && !gotone ) { client = checkclient( ); gotone = CheckTarget( client ); loopc = loopc + 1; } if ( !gotone ) return 0; self->s.v.enemy = EDICT_TO_PROG( client ); if ( strneq( PROG_TO_EDICT( self->s.v.enemy )->s.v.classname, "player" ) ) { self->s.v.enemy = PROG_TO_EDICT( self->s.v.enemy )->s.v.enemy; if ( strneq( PROG_TO_EDICT( self->s.v.enemy )->s.v.classname, "player" ) ) { self->s.v.enemy = EDICT_TO_PROG( world ); return 0; } } Sentry_FoundTarget( ); return 1; }
/* ================ TraceAttack ================ */ void TraceAttack( float damage, vec3_t dir ) { vec3_t vel, org, tmp; VectorScale( g_globalvars.v_up, crandom(), tmp ); VectorAdd( dir, tmp, vel ); VectorScale( g_globalvars.v_right, crandom(), tmp ); VectorAdd( vel, tmp, vel ); VectorNormalize( vel ); VectorScale( g_globalvars.trace_plane_normal, 2, tmp ); VectorAdd( vel, tmp, vel ); VectorScale( vel, 200, vel ); /*vel = normalize(dir + v_up*crandom() + v_right*crandom()); vel = vel + 2*trace_plane_normal; vel = vel * 200; */ VectorScale( dir, 4, tmp ); VectorSubtract( g_globalvars.trace_endpos, tmp, org ); // org = trace_endpos - dir*4; if ( PROG_TO_EDICT( g_globalvars.trace_ent )->s.v.takedamage ) { blood_count = blood_count + 1; VectorCopy( org, blood_org ); // blood_org = org; AddMultiDamage( PROG_TO_EDICT( g_globalvars.trace_ent ), damage ); } else { puff_count = puff_count + 1; } }
// Called from client.c void GrappleService() { vec3_t hookVector, hookVelocity; gedict_t *enemy; // drop the hook if player lets go of fire if ( !self->s.v.button0 ) { if ( self->s.v.weapon == IT_HOOK ) { GrappleReset( self->hook ); return; } } enemy = PROG_TO_EDICT( self->hook->s.v.enemy ); // If hooked to a player, track them directly! if ( enemy->ct == ctPlayer ) { VectorSubtract( enemy->s.v.origin, self->s.v.origin, hookVector ); } else VectorSubtract( self->hook->s.v.origin, self->s.v.origin, hookVector ); // No longer going to factor maxspeed into grapple velocity // Using standard grapple velocity of 800 set from original 3wave // purectf velocity = 2.35 * 320 or 360 * 1 = 750 or 846 VectorCopy( hookVector, hookVelocity ); VectorNormalize( hookVelocity ); if ( self->ctf_flag & CTF_RUNE_HST ) VectorScale( hookVelocity, 1000, self->s.v.velocity ); else VectorScale( hookVelocity, 800, self->s.v.velocity ); if ( vlen(hookVector) <= 100 ) // cancel chain sound { FreezeGravity( self ); if ( self->ctf_sound ) { // If there is a chain, ditch it now. We're // close enough. Having extra entities lying around // is never a good idea. if ( self->hook->s.v.goalentity ) { PROG_TO_EDICT(self->hook->s.v.goalentity)->s.v.think = (func_t) RemoveChain; PROG_TO_EDICT(self->hook->s.v.goalentity)->s.v.nextthink = g_globalvars.time; } sound( self, CHAN_NO_PHS_ADD + CHAN_WEAPON, "weapons/chain3.wav", 1, ATTN_NORM ); self->ctf_sound = false; // reset the sound channel. } } }
/* ==================== SV_ClipToLinks Mins and maxs enclose the entire area swept by the move ==================== */ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip ) { int i, numtouch; edict_t *touchlist[MAX_EDICTS], *touch; trace_t trace; numtouch = SV_AreaEdicts (clip->boxmins, clip->boxmaxs, touchlist, MAX_EDICTS, AREA_SOLID); // touch linked edicts for (i = 0; i < numtouch; i++) { touch = touchlist[i]; if (touch == clip->passedict) continue; if (touch->v.solid == SOLID_TRIGGER) Host_Error ("Trigger in clipping list"); if (clip->type == MOVE_NOMONSTERS && touch->v.solid != SOLID_BSP) continue; if (clip->passedict && clip->passedict->v.size[0] && !touch->v.size[0]) continue; // points never interact // might intersect, so do an exact clip if (clip->trace.allsolid) return; if (clip->passedict) { if (PROG_TO_EDICT(touch->v.owner) == clip->passedict) continue; // don't clip against own missiles if (PROG_TO_EDICT(clip->passedict->v.owner) == touch) continue; // don't clip against owner } if ((int)touch->v.flags & FL_MONSTER) trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end); else trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end); if (trace.allsolid || trace.startsolid || trace.fraction < clip->trace.fraction) { trace.e.ent = touch; if (clip->trace.startsolid) { clip->trace = trace; clip->trace.startsolid = true; } else clip->trace = trace; } else if (trace.startsolid) clip->trace.startsolid = true; } }
//////////////// // GlobalParams: // time // self // other=world /////////////// void G_EdictThink() { self = PROG_TO_EDICT( g_globalvars.self ); other = PROG_TO_EDICT( g_globalvars.other ); if ( self->s.v.think ) { ( ( void ( * )() ) ( self->s.v.think ) ) (); } else { G_dprintf( "Null think func" ); } }
void door_use() { gedict_t *oself; self->s.v.message = ""; // door message are for touch only PROG_TO_EDICT( self->s.v.owner )->s.v.message = ""; PROG_TO_EDICT( self->s.v.enemy )->s.v.message = ""; oself = self; self = PROG_TO_EDICT( self->s.v.owner ); door_fire(); self = oself; }
//////////////// // GlobalParams: // time // self=pusher // other=check // if the pusher has a "blocked" function, call it // otherwise, just stay in place until the obstacle is gone /////////////// void G_EdictBlocked() { self = PROG_TO_EDICT( g_globalvars.self ); other = PROG_TO_EDICT( g_globalvars.other ); if ( self->s.v.blocked ) { ( ( void ( * )() ) ( self->s.v.blocked ) ) (); } else { //G_Printf("Null blocked func"); } }
//========================================================================= // Ammo/Weapon exploded by the EMP grenade void EMPExplode( ) { float expsize; expsize = 10; if ( self->s.v.touch == ( func_t ) weapon_touch ) expsize = 60; else { if ( streq( self->s.v.classname, "item_shells" ) ) expsize = 50 + self->aflag; else { if ( streq( self->s.v.classname, "item_spikes" ) ) expsize = 40; else { if ( streq( self->s.v.classname, "item_rockets" ) ) expsize = 100 + self->aflag * 4; else { if ( streq( self->s.v.classname, "item_cells" ) ) expsize = 100 + self->aflag * 3; else { if ( streq( self->s.v.classname, "item_weapon" ) ) expsize = 60; else { G_dprintf( "EMPExplode: Attempting to explode a %s\n", self->s.v.classname ); return; } } } } } } tf_data.deathmsg = DMSG_GREN_EMP_AMMO; T_RadiusDamage( self, PROG_TO_EDICT( self->s.v.enemy ), expsize, world ); trap_WriteByte( MSG_MULTICAST, SVC_TEMPENTITY ); trap_WriteByte( MSG_MULTICAST, TE_EXPLOSION ); 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 ); // Respawn Respawn_Item( self, PROG_TO_EDICT( self->s.v.enemy ) ); }
void BigAssCarry ( ) { vec3_t vtemp; makevectors ( PROG_TO_EDICT( self->s.v.owner )->s.v.v_angle ); vtemp[0] = ( PROG_TO_EDICT( self->s.v.owner )->s.v.origin[0] + ( g_globalvars.v_forward[0] * 12 ) + 0 ) + ( g_globalvars.v_right[0] * 5 ); vtemp[1] = ( PROG_TO_EDICT( self->s.v.owner )->s.v.origin[1] + ( g_globalvars.v_forward[1] * 12 ) + 0 ) + ( g_globalvars.v_right[1] * 5 ); vtemp[2] = ( PROG_TO_EDICT( self->s.v.owner )->s.v.origin[2] + ( g_globalvars.v_forward[2] * 12 ) + 20 ) + ( g_globalvars.v_right[2] * 5 ); setorigin (self, PASSVEC3( vtemp ) ); VectorCopy( PROG_TO_EDICT( self->s.v.owner )->s.v.angles, self->s.v.angles ); //self->s.v.angles = PROG_TO_EDICT( self->s.v.owner )->s.v.angles; self->s.v.think = ( func_t ) BigAssCarry; self->s.v.nextthink = g_globalvars.time + 0.02; }
int Sentry_FindTarget_Angel( ) { gedict_t *client; gedict_t *enemy = PROG_TO_EDICT( self->s.v.enemy ); if ( enemy != world ) { if ( CheckTarget( enemy ) ) { if ( g_globalvars.time > self->height ) { Sentry_FoundTarget( ); return 1; } else return 0; } } for ( client = world; (client = trap_find( client, FOFS( s.v.classname ), "player" )); ) { if ( CheckTarget( client ) ) { self->s.v.enemy = EDICT_TO_PROG( client ); self->height = g_globalvars.time + 0.1 * ( int ) ( g_random( ) * tfset_sgppl ); // self.height = g_globalvars.time + 0.1 * Q_rint(sgppl); if ( self->height == g_globalvars.time ) { Sentry_FoundTarget( ); return 1; } return 0; } } self->s.v.enemy = EDICT_TO_PROG( world ); return 0; }
/* ================ 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; }
void ReadyThink () { float i1; char *txt, *gr; gedict_t *p=NULL, *p2=NULL; p2 = PROG_TO_EDICT( self->s.v.owner ); if( ( p2->ct == ctPlayer && !( p2->ready ) ) // forcestart breaked via break command || ( p2->ct == ctSpec && !k_force ) // forcestart breaked via forcebreak command (spectator admin) ) { k_force = 0; G_bprint(2, "%s interrupts countdown\n", p2->netname ); ent_remove ( self ); return; } k_attendees = CountPlayers(); if ( !isCanStart(NULL, true) ) { k_force = 0; G_bprint(2, "Forcestart canceled\n"); ent_remove ( self ); return; } self->attack_finished--; i1 = self->attack_finished; if( i1 <= 0 ) { k_force = 0; AdminMatchStart(); ent_remove ( self ); return; } txt = va( "%s second%s left before game starts", dig3( i1 ), ( i1 == 1 ? "" : "s") ); gr = va( "\n%s!", redtext("Get ready") ); for( p = world; (p = find_client( p )); ) if ( p->ct == ctPlayer ) G_centerprint(p, "%s%s", txt, (p->ready ? "" : gr)); else G_centerprint(p, "%s", txt); self->s.v.nextthink = g_globalvars.time + 1; }
// Electrocute whoever's in the water void ToasterElec ( ) { gedict_t *te; self->s.v.effects = 4; sound(self, 1, "weapons/lhit.wav", 1, 1); if ( self->s.v.waterlevel > 0 ) { te = findradius( world, self->s.v.origin, 950 ); while ( te ) { if ( streq( te->s.v.classname, "player" ) && te->s.v.waterlevel > 1 ) { if ( te->radsuit_finished < g_globalvars.time ) { mtf_deathmsg( 7 ); TF_T_Damage( te, self, PROG_TO_EDICT( self->s.v.owner ), 250, 2, 0 ); } } te = findradius( te, self->s.v.origin, 950 ); } dremove( self ); } else { dremove( self ); return; } }
/* ============= SV_Physics_Follow Entities that are "stuck" to another entity ============= */ void SV_Physics_Follow (edict_t *ent) { // regular thinking SV_RunThink (ent); VectorAdd (PROG_TO_EDICT(ent->v.aiment)->v.origin, ent->v.v_angle, ent->v.origin); SV_LinkEdict (ent, true); }
void shooter_think( ) { spikeshooter_use( ); self->s.v.nextthink = g_globalvars.time + self->wait; VectorScale( self->s.v.movedir, 500, PROG_TO_EDICT( g_globalvars.newmis )->s.v.velocity ); // newmis->s.v.velocity = self->s.v.movedir * 500; }
/* ============= SV_Physics_Follow Entities that are "stuck" to another entity ============= */ void SV_Physics_Follow (edict_t *ent) { vec3_t vf, vr, vu, angles, v; edict_t *e; // regular thinking if (!SV_RunThink (ent)) return; e = PROG_TO_EDICT(ent->v.aiment); if (e->v.angles[0] == ent->v.punchangle[0] && e->v.angles[1] == ent->v.punchangle[1] && e->v.angles[2] == ent->v.punchangle[2]) { // quick case for no rotation VectorAdd(e->v.origin, ent->v.view_ofs, ent->v.origin); } else { angles[0] = -ent->v.punchangle[0]; angles[1] = ent->v.punchangle[1]; angles[2] = ent->v.punchangle[2]; AngleVectors (angles, vf, vr, vu); v[0] = ent->v.view_ofs[0] * vf[0] + ent->v.view_ofs[1] * vr[0] + ent->v.view_ofs[2] * vu[0]; v[1] = ent->v.view_ofs[0] * vf[1] + ent->v.view_ofs[1] * vr[1] + ent->v.view_ofs[2] * vu[1]; v[2] = ent->v.view_ofs[0] * vf[2] + ent->v.view_ofs[1] * vr[2] + ent->v.view_ofs[2] * vu[2]; angles[0] = -e->v.angles[0]; angles[1] = e->v.angles[1]; angles[2] = e->v.angles[2]; AngleVectors (angles, vf, vr, vu); ent->v.origin[0] = v[0] * vf[0] + v[1] * vf[1] + v[2] * vf[2] + e->v.origin[0]; ent->v.origin[1] = v[0] * vr[0] + v[1] * vr[1] + v[2] * vr[2] + e->v.origin[1]; ent->v.origin[2] = v[0] * vu[0] + v[1] * vu[1] + v[2] * vu[2] + e->v.origin[2]; } VectorAdd (e->v.angles, ent->v.v_angle, ent->v.angles); SV_LinkEdict (ent, true); }
//////////////// // GlobalParams: // time // self=pusher // other=check // if the pusher has a "blocked" function, call it // otherwise, just stay in place until the obstacle is gone /////////////// void G_EdictBlocked() { self = PROG_TO_EDICT( g_globalvars.self ); other = PROG_TO_EDICT( g_globalvars.other ); if ( self->s.v.blocked ) { ( ( void ( * )() ) ( self->s.v.blocked ) ) (); } else { #ifdef PARANOID G_dprintf("Null blocked func"); #endif } }
void spikeshooter_use( ) { if ( ( int ) ( self->s.v.spawnflags ) & SPAWNFLAG_LASER ) { sound( self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM ); LaunchLaser( self->s.v.origin, self->s.v.movedir ); } else { sound( self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM ); launch_spike( self->s.v.origin, self->s.v.movedir ); VectorScale( self->s.v.movedir, 500, PROG_TO_EDICT( g_globalvars.newmis )->s.v.velocity ); // newmis->s.v.velocity = self->s.v.movedir * 500; if ( ( int ) ( self->s.v.spawnflags ) & SPAWNFLAG_SUPERSPIKE ) PROG_TO_EDICT( g_globalvars.newmis )->s.v.touch = ( func_t ) superspike_touch; } }
/* ================ SpectatorImpulseCommand Called by SpectatorThink if the spectator entered an impulse ================ */ void SpectatorImpulseCommand() { gedict_t *goal; if ( self->ct != ctSpec ) { self->s.v.impulse = 0; return; } goal = PROG_TO_EDICT( self->s.v.goalentity ); if( self->k_adminc && self->s.v.impulse >= 1 && self->s.v.impulse <= 9 ) { AdminImpBot(); } else 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 ); // if track someone - return if ( (int)(goal - world) >= 1 && (int)(goal - world) <= MAX_CLIENTS ) { // qqshka - heh, not all guys like this warning // G_sprint(self, 2, "stop %s first\n", redtext("tracking")); self->s.v.impulse = 0; return; } 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; }
/* ============= ai_melee ============= */ void ai_melee() { vec3_t delta; float ldmg; if ( !self->s.v.enemy ) return; // removed before stroke VectorSubtract( PROG_TO_EDICT( self->s.v.enemy )->s.v.origin, self->s.v.origin, delta ); if ( vlen( delta ) > 60 ) return; ldmg = ( g_random() + g_random() + g_random() ) * 3; PROG_TO_EDICT( self->s.v.enemy )->deathtype = dtSQUISH; // FIXME T_Damage( PROG_TO_EDICT( self->s.v.enemy ), self, self, ldmg ); }
void DelayThink() { activator = PROG_TO_EDICT( self->s.v.enemy ); SUB_UseTargets(); ent_remove( self ); }
//=========================================================================== // Physics // //=========================================================================== //////////////// // GlobalParams: // time // self // other /////////////// void G_EdictTouch() { self = PROG_TO_EDICT( g_globalvars.self ); other = PROG_TO_EDICT( g_globalvars.other ); if ( self->s.v.touch ) { /*#ifdef DEBUG if(self->s.v.classname && other->s.v.classname) if(!strcmp(self->s.v.classname,"player")||!strcmp(other->s.v.classname,"player")) G_dprintf( "touch %s <-> %s\n", self->s.v.classname,other->s.v.classname); #endif*/ ( ( void ( * )() ) ( self->s.v.touch ) ) (); } else { G_dprintf( "Null touch func" ); } }
struct edict_s *ProgsToEdict (progfuncs_t *progfuncs, int progs) { if ((unsigned)progs >= (unsigned)maxedicts) { printf("Bad entity index %i\n", progs); progs = 0; } return (struct edict_s *)PROG_TO_EDICT(progfuncs, progs); }