mirror of
https://github.com/UberGames/rpgxEF.git
synced 2025-02-15 16:41:16 +00:00
Added repair support for misc_model_breakable
This commit is contained in:
parent
32d2c4c077
commit
e2dfbeec15
5 changed files with 53 additions and 29 deletions
|
@ -36,7 +36,7 @@ void breakable_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker,
|
|||
eState->solid = 0;
|
||||
eShared->contents = 0;
|
||||
self->clipmask = 0;
|
||||
if(self->spawnflags & 256) {
|
||||
if(self->spawnflags & 256 && !strcmp(self->classname, "func_breakable")) {
|
||||
eShared->svFlags |= SVF_NOCLIENT;
|
||||
eState->eFlags |= EF_NODRAW;
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ void SP_func_breakable( gentity_t *self )
|
|||
level.numBrushEnts++;
|
||||
}
|
||||
|
||||
/*QUAKED misc_model_breakable (1 0 0) (-16 -16 -16) (16 16 16) SOLID AUTOANIMATE DEADSOLID NO_DMODEL INVINCIBLE x x x x
|
||||
/*QUAKED misc_model_breakable (1 0 0) (-16 -16 -16) (16 16 16) SOLID AUTOANIMATE DEADSOLID NO_DMODEL INVINCIBLE x x x REPAIRABLE
|
||||
SOLID - Movement is blocked by it, if not set, can still be broken by explosions and shots if it has health
|
||||
AUTOANIMATE - Will cycle it's anim
|
||||
DEADSOLID - Stay solid even when destroyed (in case damage model is rather large).
|
||||
|
@ -366,13 +366,15 @@ void SP_misc_model_breakable( gentity_t *ent )
|
|||
|
||||
if ( ent->spawnflags & 1 )
|
||||
{//Blocks movement
|
||||
eShared->contents = CONTENTS_BODY;//Was CONTENTS_SOLID, but only architecture should be this
|
||||
eShared->contents = CONTENTS_BODY; //Was CONTENTS_SOLID, but only architecture should be this
|
||||
}
|
||||
else if ( ent->health )
|
||||
{//Can only be shot
|
||||
eShared->contents = CONTENTS_SHOTCLIP;
|
||||
}
|
||||
|
||||
ent->damage = ent->health;
|
||||
|
||||
ent->use = breakable_use;
|
||||
|
||||
if ( ent->health )
|
||||
|
|
|
@ -1553,6 +1553,7 @@ qboolean IsBorg(gentity_t *ent) {
|
|||
}
|
||||
|
||||
extern void InitBBrush(gentity_t *ent);
|
||||
extern void SP_misc_model_breakable(gentity_t* self);
|
||||
/*
|
||||
============
|
||||
G_Repair
|
||||
|
@ -1566,7 +1567,7 @@ void G_Repair(gentity_t *ent, gentity_t *tr_ent, float rate) {
|
|||
float max = 0;
|
||||
|
||||
// if count isn't 0 the breakable is not damaged and if target is no breakable it does not make sense to go on
|
||||
if(tr_ent->count != 0 || Q_stricmp(tr_ent->classname, "func_breakable")) {
|
||||
if(tr_ent->count != 0 || strstr(tr_ent->classname, "breakable") == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1575,7 +1576,7 @@ void G_Repair(gentity_t *ent, gentity_t *tr_ent, float rate) {
|
|||
}
|
||||
|
||||
// check if player is near the breakable
|
||||
VectorSubtract(tr_ent->s.origin, ent->client->ps.origin, help);
|
||||
VectorSubtract(tr_ent->s.origin, ent->r.currentOrigin, help);
|
||||
distance = VectorLength(help);
|
||||
for(i = 0; i < 3; i++) {
|
||||
if(tr_ent->r.maxs[i] > max) {
|
||||
|
@ -1583,6 +1584,7 @@ void G_Repair(gentity_t *ent, gentity_t *tr_ent, float rate) {
|
|||
}
|
||||
}
|
||||
|
||||
//G_Printf("goodDst=%f, curDst=%f\n", 80 + max, distance);
|
||||
if(distance > 80 + max) {
|
||||
return;
|
||||
}
|
||||
|
@ -1599,29 +1601,34 @@ void G_Repair(gentity_t *ent, gentity_t *tr_ent, float rate) {
|
|||
// still not repaired of let's go on
|
||||
tr_ent->health += rate;
|
||||
} else {
|
||||
// else restore it
|
||||
tr_ent->s.solid = CONTENTS_BODY;
|
||||
trap_SetBrushModel(tr_ent, tr_ent->model);
|
||||
tr_ent->r.svFlags &= ~SVF_NOCLIENT;
|
||||
tr_ent->s.eFlags &= ~EF_NODRAW;
|
||||
InitBBrush(tr_ent);
|
||||
tr_ent->health = tr_ent->damage;
|
||||
if(!strcmp(tr_ent->classname, "func_breakable")) {
|
||||
// else restore it
|
||||
tr_ent->s.solid = CONTENTS_BODY;
|
||||
trap_SetBrushModel(tr_ent, tr_ent->model);
|
||||
tr_ent->r.svFlags &= ~SVF_NOCLIENT;
|
||||
tr_ent->s.eFlags &= ~EF_NODRAW;
|
||||
InitBBrush(tr_ent);
|
||||
tr_ent->health = tr_ent->damage;
|
||||
|
||||
if(tr_ent->health) {
|
||||
tr_ent->takedamage = qtrue;
|
||||
}
|
||||
if(tr_ent->health) {
|
||||
tr_ent->takedamage = qtrue;
|
||||
}
|
||||
|
||||
tr_ent->use = breakable_use;
|
||||
tr_ent->use = breakable_use;
|
||||
|
||||
if(tr_ent->paintarget) {
|
||||
tr_ent->pain = breakable_pain;
|
||||
}
|
||||
if(tr_ent->paintarget) {
|
||||
tr_ent->pain = breakable_pain;
|
||||
}
|
||||
|
||||
tr_ent->clipmask = 0;
|
||||
tr_ent->count = 1;
|
||||
tr_ent->clipmask = 0;
|
||||
tr_ent->count = 1;
|
||||
|
||||
if(tr_ent->target) {
|
||||
G_UseTargets2(tr_ent, tr_ent, tr_ent->target);
|
||||
if(tr_ent->target) {
|
||||
G_UseTargets2(tr_ent, tr_ent, tr_ent->target);
|
||||
}
|
||||
} else if(!strcmp(tr_ent->classname, "misc_model_breakable")) {
|
||||
tr_ent->health = tr_ent->damage;
|
||||
SP_misc_model_breakable(tr_ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -819,7 +819,7 @@ void G_AddEvent( gentity_t *ent, int event, int eventParm );
|
|||
void G_SetOrigin( gentity_t *ent, vec3_t origin );
|
||||
void G_SetAngles( gentity_t *ent, vec3_t anlges ); //RPG-X | GSIO01 | 24.08.2009
|
||||
int G_RadiusList ( vec3_t origin, float radius, gentity_t *ignore, qboolean takeDamage, gentity_t *ent_list[MAX_GENTITIES]);
|
||||
int G_RadiusListOfType(char *classname, vec3_t origin, float radius, gentity_t *ignore, gentity_t *entlist[MAX_GENTITIES]);
|
||||
int G_RadiusListOfTypes(char *classname[], int count, vec3_t origin, float radius, gentity_t *ignore, gentity_t *ent_list[MAX_GENTITIES]);
|
||||
gentity_t *G_GetNearestEnt(char *classname, vec3_t origin, float radius, gentity_t *ignore, qboolean takeDamage);
|
||||
gentity_t *G_GetNearestPlayer(vec3_t origin, float radius, gentity_t *ignore );
|
||||
|
||||
|
|
|
@ -1094,7 +1094,7 @@ int G_RadiusList ( vec3_t origin, float radius, gentity_t *ignore, qboolean take
|
|||
return(ent_count);
|
||||
}
|
||||
|
||||
int G_RadiusListOfType(char *classname, vec3_t origin, float radius, gentity_t *ignore, gentity_t *ent_list[MAX_GENTITIES]) {
|
||||
int G_RadiusListOfTypes(char *classname[], int count, vec3_t origin, float radius, gentity_t *ignore, gentity_t *ent_list[MAX_GENTITIES]) {
|
||||
float dist;
|
||||
gentity_t *ent;
|
||||
int entityList[MAX_GENTITIES];
|
||||
|
@ -1103,6 +1103,7 @@ int G_RadiusListOfType(char *classname, vec3_t origin, float radius, gentity_t *
|
|||
vec3_t v;
|
||||
int i, e;
|
||||
int ent_count = 0;
|
||||
qboolean valid = qfalse;
|
||||
|
||||
if ( radius < 1 )
|
||||
{
|
||||
|
@ -1121,9 +1122,19 @@ int G_RadiusListOfType(char *classname, vec3_t origin, float radius, gentity_t *
|
|||
{
|
||||
ent = &g_entities[entityList[e]];
|
||||
|
||||
if ((ent == ignore) || !(ent->inuse) || strcmp(classname, ent->classname))
|
||||
if ((ent == ignore) || !(ent->inuse))
|
||||
continue;
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
if(!strcmp(ent->classname, classname[i])) {
|
||||
valid = qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
if(!valid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* find the distance from the edge of the bounding box */
|
||||
for ( i = 0 ; i < 3 ; i++ )
|
||||
{
|
||||
|
@ -1149,6 +1160,7 @@ int G_RadiusListOfType(char *classname, vec3_t origin, float radius, gentity_t *
|
|||
ent_list[ent_count] = ent;
|
||||
ent_count++;
|
||||
|
||||
valid = qfalse;
|
||||
}
|
||||
/* we are done, return how many we found */
|
||||
return(ent_count);
|
||||
|
|
|
@ -113,16 +113,19 @@ static void WP_FireHyperspanner(gentity_t *ent, qboolean alt_fire) {
|
|||
float modifier;
|
||||
gentity_t *validEnts[MAX_GENTITIES];
|
||||
int count = 0;
|
||||
int i, nearest = -1, nearestd = 512;
|
||||
int i, nearest = -1;
|
||||
float nearestd = 65000;
|
||||
vec3_t dVec, end;
|
||||
vec3_t mins = { -40, -40, -40 }, maxs = { 40, 40, 40 };
|
||||
char* classnames[] = { "func_breakable", "misc_model_breakable" };
|
||||
|
||||
/* find all vlaid entities in range */
|
||||
count = G_RadiusListOfType("func_breakable", ent->s.origin, 512, NULL, validEnts);
|
||||
count = G_RadiusListOfTypes(classnames, 2, ent->r.currentOrigin, 512, NULL, validEnts);
|
||||
//G_Printf("Found %d possible candidates\n", count);
|
||||
if(count) {
|
||||
trace_t tr;
|
||||
for(i = 0; i < count; i++) {
|
||||
// TODO: fix problems with small distance
|
||||
VectorSubtract(ent->r.currentOrigin, validEnts[i]->s.origin, dVec);
|
||||
VectorMA(validEnts[i]->s.origin, 1024, dVec, end);
|
||||
//G_Printf("Checking entity: %d\n", i);
|
||||
|
@ -131,7 +134,7 @@ static void WP_FireHyperspanner(gentity_t *ent, qboolean alt_fire) {
|
|||
continue;
|
||||
}
|
||||
//G_Printf("Nothing is blocking view ...\n");
|
||||
VectorSubtract(ent->s.origin, validEnts[i]->s.origin, dVec);
|
||||
VectorSubtract(ent->r.currentOrigin, validEnts[i]->s.origin, dVec);
|
||||
if(VectorLength(dVec) < nearestd) {
|
||||
nearest = validEnts[i]->s.number;
|
||||
nearestd = VectorLength(dVec);
|
||||
|
|
Loading…
Reference in a new issue