q3rally/engine/code/game/g_rally_mapobjects.c
2021-03-24 20:13:01 +00:00

341 lines
8.9 KiB
C

/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
Copyright (C) 2002-2021 Q3Rally Team (Per Thormann - q3rally@gmail.com)
This file is part of q3rally source code.
q3rally source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
q3rally source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with q3rally; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "g_local.h"
/*
static int EMPTY_BARREL_MASS = 50;
static int FULL_BARREL_MASS = 200;
static int BARREL_LEAK_TIME = 60000;
void Touch_Barrel (gentity_t *self, gentity_t *other, trace_t *trace );
*/
void DropToFloor( gentity_t *self ){
trace_t tr;
vec3_t dest;
// drop to floor
VectorSet( dest, self->s.origin[0], self->s.origin[1], self->s.origin[2] - 4096 );
trap_Trace( &tr, self->s.origin, self->r.mins, self->r.maxs, dest, self->s.number, MASK_PLAYERSOLID );
VectorCopy(tr.endpos, dest);
// allow to ride movers
self->s.groundEntityNum = tr.entityNum;
G_SetOrigin( self, dest );
}
/*
void Think_Barrel_Poison (gentity_t *self ){
self->nextthink = level.time + 200;
if (self->leaktime && self->leaktime > level.time){
CreatePoisonCloudHazard(self, self->r.currentOrigin);
G_RadiusDamage_NoKnockBack(self->r.currentOrigin, self, self->damage, 208, self, MOD_POISON);
// self->mass = EMPTY_BARREL_MASS + ((float)(FULL_BARREL_MASS - EMPTY_BARREL_MASS) * (1 - (level.time - self->leaktime) / (float)BARREL_LEAK_TIME));
}
}
*/
/*
void Barrel_Damage (gentity_t *self, vec3_t kick ){
vec3_t vel;
if (self->leaktime < level.time){
switch(self->s.weapon){
case HT_OIL:
CreateOilHazard(self, self->r.currentOrigin);
self->leaktime = level.time + 5000;
break;
case HT_BIO:
CreateBioHazard(self, self->r.currentOrigin);
self->leaktime = level.time + 5000;
break;
case HT_POISON:
self->leaktime = level.time + 5000;
break;
case HT_EXPLOSIVE:
CreateFireHazard(self, self->r.currentOrigin);
self->leaktime = level.time + 2000;
break;
}
}
BG_EvaluateTrajectoryDelta(&self->s.pos, level.time, vel);
BG_EvaluateTrajectory(&self->s.pos, level.time, self->s.pos.trBase);
VectorCopy(self->s.pos.trBase, self->r.currentOrigin);
VectorAdd (vel, kick, self->s.pos.trDelta);
self->s.pos.trTime = level.time;
self->s.pos.trType = TR_GRAVITY;
}
*/
/*
void Touch_Barrel (gentity_t *self, gentity_t *other, trace_t *trace ){
vec3_t force, torque, r, start, dest;
int damage;
float dp;
trace_t tr;
if ( other->client ) {
return;
}
// STONELANCE
if (self->leaktime < level.time){
switch(self->s.weapon){
case HT_OIL:
CreateOilHazard(self, self->r.currentOrigin);
self->leaktime = level.time + 5000;
break;
case HT_BIO:
CreateBioHazard(self, self->r.currentOrigin);
self->leaktime = level.time + 5000;
break;
case HT_POISON:
self->leaktime = level.time + 5000;
break;
case HT_EXPLOSIVE:
CreateFireHazard(self, self->r.currentOrigin);
self->leaktime = level.time + 2000;
break;
}
}
// END
// Com_Printf("barrel touched by %s\n", other->classname);
// Com_Printf("barrel located at %s\n", vtos(self->r.currentOrigin));
// Com_Printf("trace ended at %s\n", vtos(trace->endpos));
// Com_Printf("other ent located at %s\n", vtos(other->r.currentOrigin));
damage = other->damage;
if (damage <= 0)
damage = 100;
// VectorSubtract(self->r.currentOrigin, trace->endpos, force);
// Com_Printf("collision location to object cm %s\n", vtos(force));
// VectorNormalize(force);
// VectorScale(force, damage, force);
VectorNormalize2(other->s.pos.trDelta, force);
// assume barrel not moving
//VectorScale(self->s.pos.trDelta, self->mass, mv1);
VectorScale(other->s.pos.trDelta, other->mass / (float)(self->mass + other->mass), force);
self->s.pos.trType = TR_GRAVITY;
VectorCopy(self->r.currentOrigin, self->s.pos.trBase);
//VectorAdd(self->s.pos.trDelta, force, self->s.pos.trDelta);
VectorScale(force, 10, force);
VectorCopy(force, self->s.pos.trDelta);
self->s.pos.trTime = level.time;
// Com_Printf("force %s\n", vtos(force));
VectorCopy(self->r.currentOrigin, start);
start[2] += self->r.mins[2] / 1.1;
BG_EvaluateTrajectory(&self->s.pos, level.time + 100, dest);
dest[2] += self->r.mins[2] / 1.1;
//trap_Trace( &tr, self->r.currentOrigin, self->r.mins, self->r.maxs, dest, self->s.number, MASK_SOLID );
trap_Trace( &tr, start, NULL, NULL, dest, self->s.number, MASK_PLAYERSOLID );
if (tr.fraction < 1){
// If startsolid normal will be 0
// Com_Printf("normal %f, %f, %f\n", tr.plane.normal[0], tr.plane.normal[1], tr.plane.normal[2]);
dp = DotProduct(tr.plane.normal, force);
// Com_Printf("dp %f\n", dp);
if (dp < 0){
VectorMA(force, -dp, tr.plane.normal, force);
VectorCopy(force, self->s.pos.trDelta);
}
if (self->s.pos.trDelta[2] < 40)
self->s.pos.trDelta[2] += 40;
}
// Com_Printf("barrel velocity after collision %s\n", vtos(self->s.pos.trDelta));
// to overcome gravity
SnapVector(self->s.pos.trDelta);
// torque
VectorSubtract(trace->endpos, self->r.currentOrigin, r);
CrossProduct(r, other->s.pos.trDelta, torque);
VectorScale(torque, 1.0F / (self->mass), self->s.apos.trDelta);
//Com_Printf("barrel rotates at %f %f %f\n", self->s.apos.trDelta[0], self->s.apos.trDelta[1], self->s.apos.trDelta[2]);
self->s.apos.trDelta[YAW] = 0;
self->s.apos.trDelta[ROLL] = 0;
VectorCopy(self->r.currentAngles, self->s.apos.trBase);
self->s.apos.trTime = level.time;
self->s.apos.trType = TR_LINEAR;
// Com_Printf("barrel feels a force of %s\n", vtos(force));
// Com_Printf("barrel rotates at %f %f %f\n", self->s.apos.trBase[0], self->s.apos.trBase[1], self->s.apos.trBase[2]);
// Com_Printf("barrel is on %f\n", self->s.groundEntityNum);
trap_LinkEntity (self);
}
*/
void Barrel_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod ){
self->health = 1000;
}
// *********************** Harmful Barrels ************************
//
// Biohazard Barrels
//
void SP_rally_misc_barrelbio( gentity_t *ent ){
ent->die = Barrel_Die;
ent->s.modelindex = G_ModelIndex( "models/mapobjects/barrels/b_bio.md3" );
ent->classname = "barrel";
VectorSet(ent->r.mins, -8, -8, -13);
VectorSet(ent->r.maxs, 8, 8, 13);
ent->s.eType = ET_GENERAL;
ent->clipmask = MASK_PLAYERSOLID;
// ent->r.contents = CONTENTS_BODY;
// ent->mass = FULL_BARREL_MASS;
// ent->coRest = 0.4;
// ent->objectType = OT_BARREL;
// ent->s.weapon = HT_BIO;
// ent->health = 1000;
// ent->takedamage = qtrue;
ent->s.origin[2] += 1;
DropToFloor(ent);
trap_LinkEntity (ent);
}
//
// Explosive Barrel
//
void SP_rally_misc_barrelexp( gentity_t *ent ){
ent->die = Barrel_Die;
ent->s.modelindex = G_ModelIndex( "models/mapobjects/barrels/b_exp.md3" );
ent->classname = "barrel";
VectorSet(ent->r.mins, -8, -8, -13);
VectorSet(ent->r.maxs, 8, 8, 13);
ent->s.eType = ET_GENERAL;
ent->clipmask = MASK_PLAYERSOLID;
// ent->r.contents = CONTENTS_BODY;
// ent->mass = FULL_BARREL_MASS;
// ent->coRest = 0.4;
// ent->objectType = OT_BARREL;
// ent->s.weapon = HT_EXPLOSIVE;
// ent->health = 1000;
// ent->damage = 60;
// ent->takedamage = qtrue;
ent->s.origin[2] += 1;
DropToFloor(ent);
trap_LinkEntity (ent);
}
//
// Poison Barrel
//
void SP_rally_misc_barrelpoison( gentity_t *ent ){
ent->die = Barrel_Die;
// ent->think = Think_Barrel_Poison;
// ent->nextthink = level.time + FRAMETIME;
ent->s.modelindex = G_ModelIndex( "models/mapobjects/barrels/b_psn.md3" );
ent->classname = "barrel";
VectorSet(ent->r.mins, -8, -8, -13);
VectorSet(ent->r.maxs, 8, 8, 13);
ent->s.eType = ET_GENERAL;
ent->clipmask = MASK_PLAYERSOLID;
// ent->r.contents = CONTENTS_BODY;
// ent->mass = FULL_BARREL_MASS;
// ent->coRest = 0.4;
// ent->objectType = OT_BARREL;
// ent->s.weapon = HT_POISON;
// ent->health = 1000;
// ent->damage = 5;
// ent->takedamage = qtrue;
ent->s.origin[2] += 1;
DropToFloor(ent);
trap_LinkEntity (ent);
}
//
// Oil Barrel
//
void SP_rally_misc_barreloil( gentity_t *ent ){
ent->die = Barrel_Die;
ent->s.modelindex = G_ModelIndex( "models/mapobjects/barrels/b_oil.md3" );
ent->classname = "barrel";
VectorSet(ent->r.mins, -8, -8, -13);
VectorSet(ent->r.maxs, 8, 8, 13);
ent->s.eType = ET_GENERAL;
ent->clipmask = MASK_PLAYERSOLID;
// ent->r.contents = CONTENTS_BODY;
// ent->mass = FULL_BARREL_MASS;
// ent->coRest = 0.4;
// ent->objectType = OT_BARREL;
// ent->s.weapon = HT_OIL;
// ent->health = 1000;
// ent->takedamage = qtrue;
ent->s.origin[2] += 1;
DropToFloor(ent);
trap_LinkEntity (ent);
}