void Weapon_FlamethrowerFire( gentity_t *ent ) { gentity_t *traceEnt; vec3_t start; vec3_t trace_start; vec3_t trace_end; trace_t trace; VectorCopy( ent->r.currentOrigin, start ); start[2] += ent->client->ps.viewheight; VectorCopy( start, trace_start ); VectorMA( start, -8, forward, start ); VectorMA( start, 10, right, start ); VectorMA( start, -6, up, start ); // prevent flame thrower cheat, run & fire while aiming at the ground, don't get hurt // 72 total box height, 18 xy -> 77 trace radius (from view point towards the ground) is enough to cover the area around the feet VectorMA( trace_start, 77.0, forward, trace_end ); trap_Trace( &trace, trace_start, flameChunkMins, flameChunkMaxs, trace_end, ent->s.number, MASK_SHOT | MASK_WATER ); if ( trace.fraction != 1.0 ) { // additional checks to filter out false positives if ( trace.endpos[2] > ( ent->r.currentOrigin[2] + ent->r.mins[2] - 8 ) && trace.endpos[2] < ent->r.currentOrigin[2] ) { // trigger in a 21 radius around origin trace_start[0] -= trace.endpos[0]; trace_start[1] -= trace.endpos[1]; if ( trace_start[0] * trace_start[0] + trace_start[1] * trace_start[1] < 441 ) { // set self in flames G_BurnMeGood( ent, ent ); } } } traceEnt = fire_flamechunk( ent, start, forward ); }
// Josh: Won't gib if already in limbo, same as shrub void G_CensorPenalize(gentity_t *ent) { if (!ent->client) { return; } // forty - #127 - Burn a potty mouth if (g_censorPenalty.integer & CNSRPNLTY_BURN) { if ( ent->client->sess.sessionTeam != TEAM_SPECTATOR && !(ent->client->ps.pm_flags & PMF_LIMBO) && ent->health >= 0 && level.match_pause == PAUSE_NONE ) { G_BurnMeGood(ent, ent, NULL); AP(va("chat \"^7%s ^7burnt his fingers.\" -1", ent->client->pers.netname)); } } // forty - #127 - censor xp penalty if (g_censorPenalty.integer & CNSRPNLTY_XP) { if (ent->client->sess.sessionTeam != TEAM_SPECTATOR) { CPx(ent - g_entities, va("chat \"^1Warning^7: Watch you mouth!^* You have Lost %d XP.\"", g_censorXP.integer)); G_LoseSkillPoints(ent, BG_ClassSkillForClass(ent->client->sess.playerType), g_censorXP.integer); } } if (g_censorPenalty.integer & CNSRPNLTY_TMPMUTE) { ent->client->sess.auto_unmute_time = (level.time + 1000 * (g_censorMuteTime.integer)); CPx(ent - g_entities, va("print \"^5You've been auto-muted for %d seconds for language.\n\"", g_censorMuteTime.integer)); AP(va("chat \"%s^7 has been auto-muted for %d seconds for language.\" -1", ent->client->pers.netname, g_censorMuteTime.integer)); } if (g_censorPenalty.integer & CNSRPNLTY_KILL) { Force_Suicide(ent); return; } if (g_censorPenalty.integer & CNSRPNLTY_NOGIB) { // KILL, don't GIB ent->flags &= ~FL_GODMODE; ent->client->ps.stats[STAT_HEALTH] = ent->health = 0; ent->client->ps.persistant[PERS_HWEAPON_USE] = 0; // TTimo - if at MG42 player_die(ent, ent, ent, 135, MOD_UNKNOWN); } }
void G_FlameDamage( gentity_t *self ) { gentity_t *body; int entityList[MAX_GENTITIES]; int i, e, numListedEntities; float radius, boxradius, dist; vec3_t mins, maxs, point, v; trace_t tr; radius = self->speed; boxradius = 1.41421356 * radius; // radius * sqrt(2) for bounding box enlargement for ( i = 0 ; i < 3 ; i++ ) { mins[i] = self->r.currentOrigin[i] - boxradius; maxs[i] = self->r.currentOrigin[i] + boxradius; } numListedEntities = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); for ( e = 0 ; e < numListedEntities ; e++ ) { body = &g_entities[entityList[ e ]]; if ( !body->takedamage ) { continue; } // JPW NERVE don't catch fire if invulnerable or same team in no FF if ( body->client ) { if ( body->client->ps.powerups[PW_INVULNERABLE] >= level.time ) { body->flameQuota = 0; body->s.onFireEnd = level.time - 1; continue; } if ( !( g_friendlyFire.integer ) && OnSameTeam( body,self->parent ) ) { continue; } } // jpw // JPW NERVE don't catch fire if under water or invulnerable if ( body->waterlevel >= 3 ) { body->flameQuota = 0; body->s.onFireEnd = level.time - 1; continue; } // jpw if ( !body->r.bmodel ) { VectorCopy( body->r.currentOrigin, point ); if ( body->client ) { point[2] += body->client->ps.viewheight; } VectorSubtract( point, self->r.currentOrigin, v ); } else { for ( i = 0 ; i < 3 ; i++ ) { if ( self->s.origin[i] < body->r.absmin[i] ) { v[i] = body->r.absmin[i] - self->r.currentOrigin[i]; } else if ( self->r.currentOrigin[i] > body->r.absmax[i] ) { v[i] = self->r.currentOrigin[i] - body->r.absmax[i]; } else { v[i] = 0; } } } dist = VectorLength( v ); // The person who shot the flame only burns when within 1/2 the radius if ( body->s.number == self->r.ownerNum && dist >= ( radius * 0.5 ) ) { continue; } if ( dist >= radius ) { continue; } // Non-clients that take damage get damaged here if ( !body->client ) { if ( body->health > 0 ) { G_Damage( body, self->parent, self->parent, vec3_origin, self->r.currentOrigin, 2, 0, MOD_FLAMETHROWER ); } continue; } // JPW NERVE -- do a trace to see if there's a wall btwn. body & flame centroid -- prevents damage through walls trap_Trace( &tr, self->r.currentOrigin, NULL, NULL, point, body->s.number, MASK_SHOT ); if ( tr.fraction < 1.0 ) { continue; } // jpw // now check the damageQuota to see if we should play a pain animation // first reduce the current damageQuota with time if ( body->flameQuotaTime && body->flameQuota > 0 ) { body->flameQuota -= (int)( ( (float)( level.time - body->flameQuotaTime ) / 1000 ) * 2.5f ); if ( body->flameQuota < 0 ) { body->flameQuota = 0; } } G_BurnMeGood( self, body ); } }
/** * @brief burn command - burns players */ static void Svcmd_Burn(void) { int pids[MAX_CLIENTS]; char name[MAX_NAME_LENGTH], err[MAX_STRING_CHARS]; gentity_t *vic; qboolean doAll = qfalse; // FIXME: usage // make all outputs nice - cp with icon? // reason? // ignore in intermission if (level.intermissiontime) { G_Printf("Burn command not allowed during intermission.\n"); return; } if (trap_Argc() < 2) { doAll = qtrue; } trap_Argv(1, name, sizeof(name)); if (!Q_stricmp(name, "-1") || doAll) { int it, count = 0; for (it = 0; it < level.numConnectedClients; it++) { vic = g_entities + level.sortedClients[it]; if (!(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) { continue; } vic->client->ps.eFlags |= EF_SMOKING; // FIXME: add mod param? mod_unknown instead of flamer G_BurnMeGood(vic, vic, NULL); count++; } if (count > 0) { CPx(-1, va("cp \"^9%d players burned.\"", count)); } else { G_Printf("No players in team or they are already burned.\n"); } return; } if (ClientNumbersFromString(name, pids) != 1) { G_MatchOnePlayer(pids, err, sizeof(err)); G_Printf("Error - can't burn - %s.\n", err); return; } vic = &g_entities[pids[0]]; if (!(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) { G_Printf("Player must be on a team to be burned.\n"); return; } vic->client->ps.eFlags |= EF_SMOKINGBLACK; // FIXME: add mod param? mod_unknown instead of flamer G_BurnMeGood(vic, vic, NULL); CPx(-1, va("cp \"^7%s^7 is burned.\"", vic->client->pers.netname)); return; }