mirror of
https://github.com/UberGames/rpgxEF.git
synced 2025-02-20 19:12:09 +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;
|
eState->solid = 0;
|
||||||
eShared->contents = 0;
|
eShared->contents = 0;
|
||||||
self->clipmask = 0;
|
self->clipmask = 0;
|
||||||
if(self->spawnflags & 256) {
|
if(self->spawnflags & 256 && !strcmp(self->classname, "func_breakable")) {
|
||||||
eShared->svFlags |= SVF_NOCLIENT;
|
eShared->svFlags |= SVF_NOCLIENT;
|
||||||
eState->eFlags |= EF_NODRAW;
|
eState->eFlags |= EF_NODRAW;
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ void SP_func_breakable( gentity_t *self )
|
||||||
level.numBrushEnts++;
|
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
|
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
|
AUTOANIMATE - Will cycle it's anim
|
||||||
DEADSOLID - Stay solid even when destroyed (in case damage model is rather large).
|
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 )
|
if ( ent->spawnflags & 1 )
|
||||||
{//Blocks movement
|
{//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 )
|
else if ( ent->health )
|
||||||
{//Can only be shot
|
{//Can only be shot
|
||||||
eShared->contents = CONTENTS_SHOTCLIP;
|
eShared->contents = CONTENTS_SHOTCLIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ent->damage = ent->health;
|
||||||
|
|
||||||
ent->use = breakable_use;
|
ent->use = breakable_use;
|
||||||
|
|
||||||
if ( ent->health )
|
if ( ent->health )
|
||||||
|
|
|
@ -1553,6 +1553,7 @@ qboolean IsBorg(gentity_t *ent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void InitBBrush(gentity_t *ent);
|
extern void InitBBrush(gentity_t *ent);
|
||||||
|
extern void SP_misc_model_breakable(gentity_t* self);
|
||||||
/*
|
/*
|
||||||
============
|
============
|
||||||
G_Repair
|
G_Repair
|
||||||
|
@ -1566,7 +1567,7 @@ void G_Repair(gentity_t *ent, gentity_t *tr_ent, float rate) {
|
||||||
float max = 0;
|
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 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1575,7 +1576,7 @@ void G_Repair(gentity_t *ent, gentity_t *tr_ent, float rate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if player is near the breakable
|
// 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);
|
distance = VectorLength(help);
|
||||||
for(i = 0; i < 3; i++) {
|
for(i = 0; i < 3; i++) {
|
||||||
if(tr_ent->r.maxs[i] > max) {
|
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) {
|
if(distance > 80 + max) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1599,6 +1601,7 @@ void G_Repair(gentity_t *ent, gentity_t *tr_ent, float rate) {
|
||||||
// still not repaired of let's go on
|
// still not repaired of let's go on
|
||||||
tr_ent->health += rate;
|
tr_ent->health += rate;
|
||||||
} else {
|
} else {
|
||||||
|
if(!strcmp(tr_ent->classname, "func_breakable")) {
|
||||||
// else restore it
|
// else restore it
|
||||||
tr_ent->s.solid = CONTENTS_BODY;
|
tr_ent->s.solid = CONTENTS_BODY;
|
||||||
trap_SetBrushModel(tr_ent, tr_ent->model);
|
trap_SetBrushModel(tr_ent, tr_ent->model);
|
||||||
|
@ -1623,5 +1626,9 @@ void G_Repair(gentity_t *ent, gentity_t *tr_ent, float rate) {
|
||||||
if(tr_ent->target) {
|
if(tr_ent->target) {
|
||||||
G_UseTargets2(tr_ent, tr_ent, 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_SetOrigin( gentity_t *ent, vec3_t origin );
|
||||||
void G_SetAngles( gentity_t *ent, vec3_t anlges ); //RPG-X | GSIO01 | 24.08.2009
|
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_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_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 );
|
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);
|
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;
|
float dist;
|
||||||
gentity_t *ent;
|
gentity_t *ent;
|
||||||
int entityList[MAX_GENTITIES];
|
int entityList[MAX_GENTITIES];
|
||||||
|
@ -1103,6 +1103,7 @@ int G_RadiusListOfType(char *classname, vec3_t origin, float radius, gentity_t *
|
||||||
vec3_t v;
|
vec3_t v;
|
||||||
int i, e;
|
int i, e;
|
||||||
int ent_count = 0;
|
int ent_count = 0;
|
||||||
|
qboolean valid = qfalse;
|
||||||
|
|
||||||
if ( radius < 1 )
|
if ( radius < 1 )
|
||||||
{
|
{
|
||||||
|
@ -1121,9 +1122,19 @@ int G_RadiusListOfType(char *classname, vec3_t origin, float radius, gentity_t *
|
||||||
{
|
{
|
||||||
ent = &g_entities[entityList[e]];
|
ent = &g_entities[entityList[e]];
|
||||||
|
|
||||||
if ((ent == ignore) || !(ent->inuse) || strcmp(classname, ent->classname))
|
if ((ent == ignore) || !(ent->inuse))
|
||||||
continue;
|
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 */
|
/* find the distance from the edge of the bounding box */
|
||||||
for ( i = 0 ; i < 3 ; i++ )
|
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_list[ent_count] = ent;
|
||||||
ent_count++;
|
ent_count++;
|
||||||
|
|
||||||
|
valid = qfalse;
|
||||||
}
|
}
|
||||||
/* we are done, return how many we found */
|
/* we are done, return how many we found */
|
||||||
return(ent_count);
|
return(ent_count);
|
||||||
|
|
|
@ -113,16 +113,19 @@ static void WP_FireHyperspanner(gentity_t *ent, qboolean alt_fire) {
|
||||||
float modifier;
|
float modifier;
|
||||||
gentity_t *validEnts[MAX_GENTITIES];
|
gentity_t *validEnts[MAX_GENTITIES];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int i, nearest = -1, nearestd = 512;
|
int i, nearest = -1;
|
||||||
|
float nearestd = 65000;
|
||||||
vec3_t dVec, end;
|
vec3_t dVec, end;
|
||||||
vec3_t mins = { -40, -40, -40 }, maxs = { 40, 40, 40 };
|
vec3_t mins = { -40, -40, -40 }, maxs = { 40, 40, 40 };
|
||||||
|
char* classnames[] = { "func_breakable", "misc_model_breakable" };
|
||||||
|
|
||||||
/* find all vlaid entities in range */
|
/* 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);
|
//G_Printf("Found %d possible candidates\n", count);
|
||||||
if(count) {
|
if(count) {
|
||||||
trace_t tr;
|
trace_t tr;
|
||||||
for(i = 0; i < count; i++) {
|
for(i = 0; i < count; i++) {
|
||||||
|
// TODO: fix problems with small distance
|
||||||
VectorSubtract(ent->r.currentOrigin, validEnts[i]->s.origin, dVec);
|
VectorSubtract(ent->r.currentOrigin, validEnts[i]->s.origin, dVec);
|
||||||
VectorMA(validEnts[i]->s.origin, 1024, dVec, end);
|
VectorMA(validEnts[i]->s.origin, 1024, dVec, end);
|
||||||
//G_Printf("Checking entity: %d\n", i);
|
//G_Printf("Checking entity: %d\n", i);
|
||||||
|
@ -131,7 +134,7 @@ static void WP_FireHyperspanner(gentity_t *ent, qboolean alt_fire) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//G_Printf("Nothing is blocking view ...\n");
|
//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) {
|
if(VectorLength(dVec) < nearestd) {
|
||||||
nearest = validEnts[i]->s.number;
|
nearest = validEnts[i]->s.number;
|
||||||
nearestd = VectorLength(dVec);
|
nearestd = VectorLength(dVec);
|
||||||
|
|
Loading…
Reference in a new issue