void DoManipulateAction(gentity_t*self) { vec3_t fwd, fwd_o, start_o, nvel, a, otherLoc; gentity_t*gripEnt; trace_t tr; gripEnt = &g_entities[self->client->ps.fd.forceGripEntityNum]; if(gripEnt->client) VectorCopy(gripEnt->client->ps.origin, otherLoc); else VectorCopy(gripEnt->s.origin, otherLoc); self->client->dangerTime = level.time; self->client->ps.eFlags &= ~EF_INVULNERABLE; self->client->invulnerableTimer = 0; if(!(self->client->pers.cmd.buttons & BUTTON_FORCEPOWER) && !(self->client->pers.cmd.generic_cmd & GENCMD_FORCE_MANIPULATE)) { WP_ForcePowerStop(self,FP_MANIPULATE); return; } if (!ValidManipulateEnt(self,gripEnt)) { WP_ForcePowerStop(self,FP_MANIPULATE); self->client->ps.fd.forceGripEntityNum = ENTITYNUM_NONE; if (gripEnt && gripEnt->client && gripEnt->inuse) { gripEnt->client->ps.forceGripChangeMovetype = PM_NORMAL; } return; } VectorSubtract(otherLoc, self->client->ps.origin, a); trap_Trace(&tr, self->client->ps.origin, NULL, NULL, otherLoc, self->s.number, MASK_PLAYERSOLID); //[ForceSys] if (VectorLength(a) > MAX_GRIP_DISTANCE) { WP_ForcePowerStop(self, FP_MANIPULATE); return; } self->client->ps.fd.forcePowerDuration[FP_MANIPULATE] = level.time + 500; if (self->client->ps.fd.forcePowerDebounce[FP_MANIPULATE] < level.time) { //2 damage per second while choking, resulting in 10 damage total (not including The Squeeze<tm>) self->client->ps.fd.forcePowerDebounce[FP_MANIPULATE] = level.time + 1000; G_Damage(gripEnt, self, self, NULL, NULL, 2, DAMAGE_NO_ARMOR, MOD_FORCE_DARK); } Jetpack_Off(gripEnt); //make sure the guy being gripped has his jetpack off. if(gripEnt->client) { gripEnt->client->ps.fd.forceGripBeingGripped = level.time + 1000; if(gripEnt->client->otherKillerVehWeapon!=-1) { gripEnt->r.currentAngles[0]=Q_irand(0,100); gripEnt->r.currentAngles[1]=Q_irand(0,100); gripEnt->client->otherKillerVehWeapon = -1;//yea.... } gripEnt->client->ps.otherKiller = self->s.number; gripEnt->client->ps.otherKillerTime = level.time + 5000; gripEnt->client->ps.otherKillerDebounceTime = level.time + 100; //[Asteroids] gripEnt->client->otherKillerMOD = MOD_UNKNOWN; gripEnt->client->otherKillerWeaponType = WP_NONE; //[/Asteroids] gripEnt->client->ps.forceGripChangeMovetype = PM_FLOAT; } if(gripEnt->client) { if (gripEnt->client->ps.forceGripMoveInterval < level.time) { float nvLen = 0; VectorCopy(gripEnt->client->ps.origin, start_o); AngleVectors(self->client->ps.viewangles, fwd, NULL, NULL); fwd_o[0] = self->client->ps.origin[0] + fwd[0]*128; fwd_o[1] = self->client->ps.origin[1] + fwd[1]*128; fwd_o[2] = self->client->ps.origin[2] + fwd[2]*128; fwd_o[2] += 16; VectorSubtract(fwd_o, start_o, nvel); nvLen = VectorLength(nvel); if (nvLen < 16) { //within x units of desired spot VectorNormalize(nvel); gripEnt->client->ps.velocity[0] = nvel[0]*8; gripEnt->client->ps.velocity[1] = nvel[1]*8; gripEnt->client->ps.velocity[2] = nvel[2]*8; } else if (nvLen < 64) { VectorNormalize(nvel); gripEnt->client->ps.velocity[0] = nvel[0]*128; gripEnt->client->ps.velocity[1] = nvel[1]*128; gripEnt->client->ps.velocity[2] = nvel[2]*128; } else if (nvLen < 128) { VectorNormalize(nvel); gripEnt->client->ps.velocity[0] = nvel[0]*256; gripEnt->client->ps.velocity[1] = nvel[1]*256; gripEnt->client->ps.velocity[2] = nvel[2]*256; } else if (nvLen < 200) { VectorNormalize(nvel); gripEnt->client->ps.velocity[0] = nvel[0]*512; gripEnt->client->ps.velocity[1] = nvel[1]*512; gripEnt->client->ps.velocity[2] = nvel[2]*512; } else { VectorNormalize(nvel); gripEnt->client->ps.velocity[0] = nvel[0]*700; gripEnt->client->ps.velocity[1] = nvel[1]*700; gripEnt->client->ps.velocity[2] = nvel[2]*700; } gripEnt->client->ps.forceGripMoveInterval = level.time + 3; //only update velocity every 300ms, so as to avoid heavy bandwidth usage } if ((level.time - gripEnt->client->ps.fd.forceGripStarted) > 3000 && !self->client->ps.fd.forceGripDamageDebounceTime) { //if we managed to lift him into the air for 2 seconds, give him a crack if (gripEnt->client->ps.fd.forcePowersActive & (1 << FP_MANIPULATE)) { //choking, so don't let him keep gripping himself WP_ForcePowerStop(gripEnt, FP_MANIPULATE); return; } } else if ((level.time - gripEnt->client->ps.fd.forceGripStarted) > 4000) { WP_ForcePowerStop(self, FP_MANIPULATE); return; } }//end FORCE_LEVEL_3 else //If not a client { float nvLen = 0; VectorCopy(gripEnt->s.origin, start_o); AngleVectors(self->client->ps.viewangles, fwd, NULL, NULL); fwd_o[0] = self->client->ps.origin[0] + fwd[0]*128; fwd_o[1] = self->client->ps.origin[1] + fwd[1]*128; fwd_o[2] = self->client->ps.origin[2] + fwd[2]*128; fwd_o[2] += 16; VectorSubtract(fwd_o, start_o, nvel); nvLen = VectorLength(nvel); if (nvLen < 16) { //within x units of desired spot VectorNormalize(nvel); gripEnt->s.pos.trDelta[0] = nvel[0]*8; gripEnt->s.pos.trDelta[1] = nvel[1]*8; gripEnt->s.pos.trDelta[2] = nvel[2]*8; } else if (nvLen < 64) { VectorNormalize(nvel); gripEnt->s.pos.trDelta[0] = nvel[0]*128; gripEnt->s.pos.trDelta[1] = nvel[1]*128; gripEnt->s.pos.trDelta[2] = nvel[2]*128; } else if (nvLen < 128) { VectorNormalize(nvel); gripEnt->s.pos.trDelta[0] = nvel[0]*256; gripEnt->s.pos.trDelta[1] = nvel[1]*256; gripEnt->s.pos.trDelta[2] = nvel[2]*256; } else if (nvLen < 200) { VectorNormalize(nvel); gripEnt->s.pos.trDelta[0] = nvel[0]*512; gripEnt->s.pos.trDelta[1] = nvel[1]*512; gripEnt->s.pos.trDelta[2] = nvel[2]*512; } else { VectorNormalize(nvel); gripEnt->s.pos.trDelta[0] = nvel[0]*700; gripEnt->s.pos.trDelta[1] = nvel[1]*700; gripEnt->s.pos.trDelta[2] = nvel[2]*700; } //gripEnt->client->ps.forceGripMoveInterval = level.time + 300; //only update velocity every 300ms, so as to avoid heavy bandwidth usage } }
void DoGripAction(gentity_t *self, forcePowers_t forcePower) {//racc - have someone in our grip, deal with them. gentity_t *gripEnt; int gripLevel = 0; trace_t tr; vec3_t a; self->client->dangerTime = level.time; self->client->ps.eFlags &= ~EF_INVULNERABLE; self->client->invulnerableTimer = 0; gripEnt = &g_entities[self->client->ps.fd.forceGripEntityNum]; if (!ValidGripEnt(self,gripEnt)) { WP_ForcePowerStop(self,FP_GRIP); self->client->ps.fd.forceGripEntityNum = ENTITYNUM_NONE; if (gripEnt && gripEnt->client && gripEnt->inuse) { gripEnt->client->ps.forceGripChangeMovetype = PM_NORMAL; } return; } if(gripEnt->client) VectorSubtract(gripEnt->client->ps.origin, self->client->ps.origin, a); else VectorSubtract(gripEnt->s.pos.trBase,self->client->ps.origin,a); if(gripEnt->client) trap_Trace(&tr, self->client->ps.origin, NULL, NULL, gripEnt->client->ps.origin, self->s.number, MASK_PLAYERSOLID); else trap_Trace(&tr, self->client->ps.origin, NULL, NULL, gripEnt->s.pos.trBase, self->s.number, MASK_PLAYERSOLID); //[ForceSys] gripLevel = self->client->ps.fd.forcePowerLevel[FP_GRIP]; if (VectorLength(a) > MAX_GRIP_DISTANCE) { WP_ForcePowerStop(self, forcePower); return; } if(gripEnt->client) { if ( !InFront( gripEnt->client->ps.origin, self->client->ps.origin, self->client->ps.viewangles, 0.9f ) && gripLevel < FORCE_LEVEL_3) { WP_ForcePowerStop(self, forcePower); return; } } else { if ( !InFront( gripEnt->s.pos.trBase, self->client->ps.origin, self->client->ps.viewangles, 0.9f ) && gripLevel < FORCE_LEVEL_3) { WP_ForcePowerStop(self, forcePower); return; } } if (self->client->ps.fd.forcePowerDebounce[FP_GRIP] < level.time) { //2 damage per second while choking, resulting in 10 damage total (not including The Squeeze<tm>) self->client->ps.fd.forcePowerDebounce[FP_GRIP] = level.time + 1000; G_Damage(gripEnt, self, self, NULL, NULL, 2, DAMAGE_NO_ARMOR, MOD_FORCE_DARK); } Jetpack_Off(gripEnt); //make sure the guy being gripped has his jetpack off. if (gripLevel == FORCE_LEVEL_1) { if(gripEnt->client) gripEnt->client->ps.fd.forceGripBeingGripped = level.time + 1000; if(gripEnt->client) if ((level.time - gripEnt->client->ps.fd.forceGripStarted) > 5000) { WP_ForcePowerStop(self, forcePower); return; } } if (gripLevel == FORCE_LEVEL_2||gripLevel==FORCE_LEVEL_3) { gripEnt->client->ps.fd.forceGripBeingGripped = level.time + 1000; if (gripEnt->client->ps.forceGripMoveInterval < level.time) { if(gripLevel == FORCE_LEVEL_2) gripEnt->client->ps.velocity[2] = 15; else gripEnt->client->ps.velocity[2] = 30; gripEnt->client->ps.forceGripMoveInterval = level.time + 300; //only update velocity every 300ms, so as to avoid heavy bandwidth usage } gripEnt->client->ps.otherKiller = self->s.number; gripEnt->client->ps.otherKillerTime = level.time + 5000; gripEnt->client->ps.otherKillerDebounceTime = level.time + 100; //[Asteroids] gripEnt->client->otherKillerMOD = MOD_UNKNOWN; gripEnt->client->otherKillerVehWeapon = 0; gripEnt->client->otherKillerWeaponType = WP_NONE; //[/Asteroids] gripEnt->client->ps.forceGripChangeMovetype = PM_FLOAT; if(gripEnt->client) { if ((level.time - gripEnt->client->ps.fd.forceGripStarted) > 3000 && !self->client->ps.fd.forceGripDamageDebounceTime) { //if we managed to lift him into the air for 2 seconds, give him a crack self->client->ps.fd.forceGripDamageDebounceTime = 1; if(gripLevel == FORCE_LEVEL_2) G_Damage(gripEnt, self, self, NULL, NULL, 20, DAMAGE_NO_ARMOR, MOD_FORCE_DARK); else G_Damage(gripEnt, self, self, NULL, NULL, 75, DAMAGE_NO_ARMOR, MOD_FORCE_DARK); //Must play custom sounds on the actual entity. Don't use G_Sound (it creates a temp entity for the sound) G_EntitySound( gripEnt, CHAN_VOICE, G_SoundIndex(va( "*choke%d.wav", Q_irand( 1, 3 ) )) ); gripEnt->client->ps.forceHandExtend = HANDEXTEND_CHOKE; gripEnt->client->ps.forceHandExtendTime = level.time + 2000; if (gripEnt->client->ps.fd.forcePowersActive & (1 << FP_GRIP)) { //choking, so don't let him keep gripping himself WP_ForcePowerStop(gripEnt, FP_GRIP); return; } } else if ((level.time - gripEnt->client->ps.fd.forceGripStarted) > 4000) { WP_ForcePowerStop(self, forcePower); return; } } } }
void hurt_touch( gentity_t *self, gentity_t *other, trace_t *trace ) { int dflags; if ( self->flags & FL_INACTIVE ) {//set by target_deactivate return; } if ( !other->takedamage ) { return; } if ( self->timestamp > level.time ) { return; } if (self->damage == -1 && other && other->client && other->health < 1) { other->client->ps.fallingToDeath = 0; respawn(other); return; } if (self->damage == -1 && other && other->client && other->client->ps.fallingToDeath) { return; } if ( self->spawnflags & 16 ) { self->timestamp = level.time + 1000; } else { self->timestamp = level.time + FRAMETIME; } // play sound /* if ( !(self->spawnflags & 4) && self->damage != -1 ) { G_Sound( other, CHAN_AUTO, self->noise_index ); } */ if (self->spawnflags & 8) dflags = DAMAGE_NO_PROTECTION; else dflags = 0; if (self->damage == -1 && other && other->client) { if (other->client->ps.otherKillerTime > level.time) { //we're as good as dead, so if someone pushed us into this then remember them other->client->ps.otherKillerTime = level.time + 20000; other->client->ps.otherKillerDebounceTime = level.time + 10000; } other->client->ps.fallingToDeath = level.time; //rag on the way down, this flag will automatically be cleared for us on respawn other->client->ps.eFlags |= EF_RAG; //make sure his jetpack is off Jetpack_Off(other); if (other->NPC) { //kill it now vec3_t vDir; VectorSet(vDir, 0, 1, 0); G_Damage(other, other, other, vDir, other->client->ps.origin, Q3_INFINITE, 0, MOD_FALLING); } else { G_EntitySound(other, CHAN_VOICE, G_SoundIndex("*falling1.wav")); } self->timestamp = 0; //do not ignore others } else { int dmg = self->damage; if (dmg == -1) { //so fall-to-blackness triggers destroy evertyhing dmg = 99999; self->timestamp = 0; } if (self->activator && self->activator->inuse && self->activator->client) { G_Damage (other, self->activator, self->activator, NULL, NULL, dmg, dflags|DAMAGE_NO_PROTECTION, MOD_TRIGGER_HURT); } else { G_Damage (other, self, self, NULL, NULL, dmg, dflags|DAMAGE_NO_PROTECTION, MOD_TRIGGER_HURT); } } }