From e0418bd2d422527b03b43dbeb61984d800666943 Mon Sep 17 00:00:00 2001 From: P3rlE <97919909+P3rlE@users.noreply.github.com> Date: Sat, 19 Mar 2022 21:49:08 +0100 Subject: [PATCH] Added more options to func_breakable !!! use the new entities.def !!! --- engine/code/cgame/cg_main.c | 5 +- engine/code/cgame/cg_weapons.c | 2 +- engine/code/client/cl_cin.c | 4 +- engine/code/game/bg_public.h | 7 +- engine/code/game/g_mover.c | 121 +++++++++++++----- engine/code/qcommon/q_shared.h | 4 +- q3rallycode.ppr | Bin 31734 -> 32955 bytes .../q3rally.game/baseq3r/entities.def | 14 +- 8 files changed, 107 insertions(+), 50 deletions(-) diff --git a/engine/code/cgame/cg_main.c b/engine/code/cgame/cg_main.c index 5f7e7023..bfa0a1de 100644 --- a/engine/code/cgame/cg_main.c +++ b/engine/code/cgame/cg_main.c @@ -1334,16 +1334,17 @@ static void CG_RegisterGraphics( void ) { // wall marks cgs.media.bulletMarkShader = trap_R_RegisterShader( "gfx/damage/bullet_mrk" ); cgs.media.burnMarkShader = trap_R_RegisterShader( "gfx/damage/burn_med_mrk" ); -// Q3Rally Code Start cgs.media.bioMarkShader = trap_R_RegisterShader( "gfx/damage/bio_mark" ); cgs.media.oilMarkShader = trap_R_RegisterShader( "gfx/damage/oil_mark" ); cgs.media.sparkShader = trap_R_RegisterShader( "gfx/damage/spark" ); -// Q3Rally Code END cgs.media.holeMarkShader = trap_R_RegisterShader( "gfx/damage/hole_lg_mrk" ); cgs.media.energyMarkShader = trap_R_RegisterShader( "gfx/damage/plasma_mrk" ); cgs.media.shadowMarkShader = trap_R_RegisterShader( "markShadow" ); cgs.media.wakeMarkShader = trap_R_RegisterShader( "wake" ); cgs.media.bloodMarkShader = trap_R_RegisterShader( "bloodMark" ); + +//explosion effect + cgs.media.rocketExplosionShader = trap_R_RegisterShader("rocketExplosion"); // register the inline models cgs.numInlineModels = trap_CM_NumInlineModels(); diff --git a/engine/code/cgame/cg_weapons.c b/engine/code/cgame/cg_weapons.c index 643a5840..1c22b022 100644 --- a/engine/code/cgame/cg_weapons.c +++ b/engine/code/cgame/cg_weapons.c @@ -763,7 +763,7 @@ void CG_RegisterWeapon( int weaponNum ) { MAKERGB( weaponInfo->flashDlightColor, 1, 0.75f, 0 ); weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/rocket/rocklf1a.wav", qfalse ); - cgs.media.rocketExplosionShader = trap_R_RegisterShader( "rocketExplosion" ); + //cgs.media.rocketExplosionShader = trap_R_RegisterShader( "rocketExplosion" ); break; #ifdef MISSIONPACK diff --git a/engine/code/client/cl_cin.c b/engine/code/client/cl_cin.c index 4e0dbbdf..0be0d895 100644 --- a/engine/code/client/cl_cin.c +++ b/engine/code/client/cl_cin.c @@ -1434,7 +1434,7 @@ if (cinTable[currentHandle].fileType == FT_OGM) cinTable[currentHandle].buf = Cin_OGM_GetOutput(&newW, &newH); if (newW != cinTable[currentHandle].CIN_WIDTH) - { + { cinTable[currentHandle].CIN_WIDTH = newW; resolutionChange = qtrue; } @@ -1693,7 +1693,7 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi */ if (cinTable[currentHandle].alterGameState) { - CL_ShowMainMenu(); + VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_NONE ); } else { cinTable[currentHandle].playonwalls = cl_inGameVideo->integer; } diff --git a/engine/code/game/bg_public.h b/engine/code/game/bg_public.h index 3d3d4933..441d3a85 100644 --- a/engine/code/game/bg_public.h +++ b/engine/code/game/bg_public.h @@ -764,9 +764,7 @@ typedef enum { MOD_ROCKET_SPLASH, MOD_PLASMA, MOD_PLASMA_SPLASH, -// Q3Rally Code Start MOD_FLAME_THROWER, -// Q3Rally Code End MOD_RAILGUN, MOD_LIGHTNING, MOD_BFG, @@ -787,7 +785,6 @@ typedef enum { MOD_KAMIKAZE, MOD_JUICED, #endif -// STONELANCE MOD_UPSIDEDOWN, MOD_BO_SHOCKS, MOD_CAR_COLLISION, @@ -799,8 +796,8 @@ typedef enum { MOD_MINE, MOD_POISON, MOD_FIRE, -// END - MOD_GRAPPLE + MOD_GRAPPLE, + MOD_BREAKABLE_SPLASH } meansOfDeath_t; diff --git a/engine/code/game/g_mover.c b/engine/code/game/g_mover.c index 7b61399b..d0de82ca 100644 --- a/engine/code/game/g_mover.c +++ b/engine/code/game/g_mover.c @@ -1869,57 +1869,110 @@ BREAKABLE =============================================================================== */ +void Think_Breakable( gentity_t *ent ) { + Break_Breakable( ent, ent->activator ); +} + //other is the player that broke the func_breakable void Break_Breakable(gentity_t *ent, gentity_t *other) { - vec3_t size; - vec3_t center; - int count = 0; - int spawnflags = 0; - gentity_t *tmp; - //int type = EV_EMIT_DEBRIS_LIGHT; + vec3_t size; + vec3_t center; + int count = 0; + int sound = 0; + int spawnflags = 0; + gentity_t *tmp, *tmp2; + int type = EV_EMIT_DEBRIS_LIGHT; - // Get the center of the glass (code donated by Perle) - VectorSubtract(ent->r.maxs, ent->r.mins, size); + if ( other != ent->activator && !strcmp( other->classname, "func_breakable" ) ) { + //if the splash damage from another func_breakable is causing this func_breakable to break + //then delay the break to get a nice chain explosion effect + ent->activator = other; + ent->think = Think_Breakable; + ent->nextthink = level.time + 400; + return; + } + + // Get the center of the func_breakable (code donated by Perle) + VectorSubtract(ent->r.maxs, ent->r.mins, size); VectorScale(size, 0.5, size); VectorAdd(ent->r.mins, size, center); + ent->takedamage = qfalse; + ent->s.eType = ET_INVISIBLE; + G_UseTargets( ent, other ); - ent->takedamage = qfalse; - ent->s.eType = ET_INVISIBLE; - G_UseTargets( ent, other ); - //need to store properties of the entity in seperate variables because we're going to free the entity - if ( ent->count > 0) { - count = ent->count; - spawnflags = ent->spawnflags; - } - G_FreeEntity( ent ); + //need to store properties of the entity in separate variables because we're going to free the entity + if ( ent->count > 0) { + count = ent->count; + spawnflags = ent->spawnflags; + } - //spray out debris - if ( count > 0 ) { - tmp = G_TempEntity( center, PickDebrisType ( spawnflags ) ); - tmp->s.eventParm = count; - } + + + + if ( ent->soundPos2 ) + sound = ent->soundPos2; + + //apply radius damage + if ( ent->damage ) + G_RadiusDamage( center, ent, ent->damage, ent->splashRadius, ent, MOD_BREAKABLE_SPLASH ); + + + //free the entity so it disappears + G_FreeEntity( ent ); + + + //spray out debris + if ( count > 0 ) { + tmp = G_TempEntity( center, PickDebrisType( spawnflags ) ); + tmp->s.eventParm = count; + } + + //play sound + if ( sound ) + { + tmp2 = G_TempEntity( center, EV_GENERAL_SOUND ); + tmp2->s.eventParm = sound; + } + + //show explosion effect + if (spawnflags & 8192) { + G_TempEntity(center, EV_EXPLOSION); + } } +void Use_Breakable (gentity_t *ent, gentity_t *other, gentity_t *activator) { + Break_Breakable( ent, activator ); +} /*QUAKED func_breakable (0 .5 .8) ? see PickDebrisType in g_util.c for spawnflags A bmodel that just sits there, doing nothing. It is removed when it received a set amount of damage. -"model2" .md3 model to also draw -"color" constantLight color -"light" constantLight radius -"health" the amount of damage required before this entity is removed +"model2" .md3 model to also draw +"color" constantLight color +"light" constantLight radius +"health" the amount of damage required before this entity is removed */ void SP_func_breakable( gentity_t *ent ) { - trap_SetBrushModel( ent, ent->model ); - InitMover( ent ); - VectorCopy( ent->s.origin, ent->s.pos.trBase ); - VectorCopy( ent->s.origin, ent->r.currentOrigin ); - ent->takedamage = qtrue; - ent->use = 0; - ent->r.contents = CONTENTS_SOLID; - ent->clipmask = MASK_SOLID; + char *noise; + + trap_SetBrushModel( ent, ent->model ); + InitMover( ent ); + VectorCopy( ent->s.origin, ent->s.pos.trBase ); + VectorCopy( ent->s.origin, ent->r.currentOrigin ); + ent->takedamage = qtrue; + ent->use = Use_Breakable; + ent->r.contents = CONTENTS_SOLID; + ent->clipmask = MASK_SOLID; + + G_SpawnInt( "dmg", "0", &ent->damage ); + G_SpawnInt( "radius", "120", &ent->splashRadius ); //120 is default splash radius of a rocket + + G_SpawnString("breaksound", "", &noise); + if (strlen(noise) > 0) { + ent->soundPos2 = G_SoundIndex(noise); + } } /* diff --git a/engine/code/qcommon/q_shared.h b/engine/code/qcommon/q_shared.h index 81862195..8f706595 100644 --- a/engine/code/qcommon/q_shared.h +++ b/engine/code/qcommon/q_shared.h @@ -67,7 +67,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define BASETA "missionpack" #ifndef PRODUCT_VERSION -#define PRODUCT_VERSION "v0.4_r518" +#define PRODUCT_VERSION "v0.4_r519" #endif @@ -1609,7 +1609,7 @@ signed signed_10bit4:10; //-511 to 511 unsigned :24; //Do not use unsigned c7:8; //Unsigned char 0 to 255 -//powerups +ÿpo??ps unsigned :16; //Do not use signed s2:16; //Signed -32767 to 32767 diff --git a/q3rallycode.ppr b/q3rallycode.ppr index c796c51eacbb4ecbe9b8816edd576e8ec3ea6397..9bb15e04d77c42ee07468cb4ce9b972331134fc0 100644 GIT binary patch literal 32955 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