Ripping things out, move most weapon projectiles into EntityDef

This commit is contained in:
Marco Cawthorne 2023-07-27 23:08:26 -07:00
parent 24964d27c9
commit 753af7e8fb
Signed by: eukara
GPG Key ID: CE2032F0A2882A22
25 changed files with 327 additions and 886 deletions

View File

@ -24,16 +24,6 @@ ClientGame_EventParse(float fHeader)
case EV_HITNOTIFY:
pSeatLocal->m_flDamageIndicator = 1.0f;
break;
case EV_SPARK:
vector vSparkPos, vSparkAngle;
vSparkPos[0] = readcoord();
vSparkPos[1] = readcoord();
vSparkPos[2] = readcoord();
vSparkAngle[0] = readcoord();
vSparkAngle[1] = readcoord();
vSparkAngle[2] = readcoord();
FX_Spark(vSparkPos, vSparkAngle);
break;
case EV_BLOOD:
vector vBloodPos = g_vec_null;
vector vBloodColor = g_vec_null;
@ -48,45 +38,6 @@ ClientGame_EventParse(float fHeader)
FX_Blood(vBloodPos, vBloodColor);
break;
case EV_EXPLOSION:
vector vExploPos = g_vec_null;
vExploPos[0] = readcoord();
vExploPos[1] = readcoord();
vExploPos[2] = readcoord();
FX_Explosion(vExploPos);
break;
case EV_MODELGIB:
vector vecPos = g_vec_null;
vecPos[0] = readcoord();
vecPos[1] = readcoord();
vecPos[2] = readcoord();
vector vSize = g_vec_null;
vSize[0] = readcoord();
vSize[1] = readcoord();
vSize[2] = readcoord();
float fStyle = readbyte();
int count = readbyte();
FX_BreakModel(count, vecPos, vSize, [0,0,0], fStyle);
break;
case EV_IMPACT:
int iType;
vector vOrigin, vNormal;
iType = (int)readbyte();
vOrigin[0] = readcoord();
vOrigin[1] = readcoord();
vOrigin[2] = readcoord();
vNormal[0] = readcoord();
vNormal[1] = readcoord();
vNormal[2] = readcoord();
FX_Impact(iType, vOrigin, vNormal);
break;
case EV_GAUSSBEAM:
FX_GaussBeam_Parse();
break;

View File

@ -51,10 +51,6 @@ ClientGame_RendererRestart(string rstr)
Obituary_Precache();
FX_Blood_Init();
FX_BreakModel_Init();
FX_Explosion_Init();
FX_Spark_Init();
FX_Impact_Init();
FX_GaussBeam_Init();
BEAM_TRIPMINE = particleeffectnum("weapon_tripmine.beam");

View File

@ -128,10 +128,10 @@ HLMultiplayerRules::PlayerDeath(NSClientPlayer pl)
#endif
/* either gib, or make a corpse */
if (pl.health < 0) {
if (pl.health < -50) {
vector gibDir = vectoangles(pl.origin - g_dmg_eAttacker.origin);
float gibStrength = g_dmg_iDamage * 2.0f;
BreakModel_Entity(pl, gibDir, gibStrength, 8);
BreakModel_Entity(pl, gibDir, gibStrength);
} else {
FX_Corpse_Spawn((player)pl, ANIM_DIESIMPLE);
}
@ -202,11 +202,11 @@ HLMultiplayerRules::PlayerSpawn(NSClientPlayer pp)
pl.gravity = __NULL__;
pl.SetFrame(1);
pl.SendFlags = UPDATE_ALL;
pl.iBleeds = TRUE;
pl.SetInfoKey("*spec", "0");
pl.SetInfoKey("*dead", "0");
pl.SetInfoKey("*deaths", ftos(pl.deaths));
pl.SetPropData("actor_human");
pl.SetCanBleed(true);
LevelNewParms();
LevelDecodeParms(pl);

View File

@ -1,164 +0,0 @@
/*
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef CLIENT
void
FX_BreakModel_Init(void)
{
precache_model("models/glassgibs.mdl");
precache_model("models/woodgibs.mdl");
precache_model("models/metalplategibs.mdl");
precache_model("models/fleshgibs.mdl");
precache_model("models/ceilinggibs.mdl");
precache_model("models/computergibs.mdl");
precache_model("models/rockgibs.mdl");
precache_model("models/cindergibs.mdl");
precache_sound("debris/bustglass1.wav");
precache_sound("debris/bustglass2.wav");
precache_sound("debris/bustglass3.wav");
precache_sound("debris/bustcrate1.wav");
precache_sound("debris/bustcrate2.wav");
precache_sound("debris/bustcrate3.wav");
precache_sound("debris/bustmetal1.wav");
precache_sound("debris/bustmetal2.wav");
precache_sound("debris/bustflesh1.wav");
precache_sound("debris/bustflesh2.wav");
precache_sound("debris/bustconcrete1.wav");
precache_sound("debris/bustconcrete2.wav");
precache_sound("debris/bustceiling.wav");
}
#endif
void
FX_BreakModel(int count, vector vMins, vector vMaxs, vector vVel, float fStyle)
{
#ifdef SERVER
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_MODELGIB);
WriteCoord(MSG_MULTICAST, vMins[0]);
WriteCoord(MSG_MULTICAST, vMins[1]);
WriteCoord(MSG_MULTICAST, vMins[2]);
WriteCoord(MSG_MULTICAST, vMaxs[0]);
WriteCoord(MSG_MULTICAST, vMaxs[1]);
WriteCoord(MSG_MULTICAST, vMaxs[2]);
WriteByte(MSG_MULTICAST, fStyle);
WriteByte(MSG_MULTICAST, count);
msg_entity = self;
vector vWorldPos;
vWorldPos[0] = vMins[0] + (0.5 * (vMaxs[0] - vMins[0]));
vWorldPos[1] = vMins[1] + (0.5 * (vMaxs[1] - vMins[1]));
vWorldPos[2] = vMins[2] + (0.5 * (vMaxs[2] - vMins[2]));
multicast(vWorldPos, MULTICAST_PVS);
#else
static void FX_BreakModel_Remove(void) { remove(self) ; }
float fModelCount = 0;
vector vecPos;
string sModel = "";
switch (fStyle) {
case GSMATERIAL_GLASS:
case GSMATERIAL_GLASS_UNBREAKABLE:
sModel = "models/glassgibs.mdl";
fModelCount = 8;
break;
case GSMATERIAL_WOOD:
sModel = "models/woodgibs.mdl";
fModelCount = 3;
break;
case GSMATERIAL_METAL:
sModel = "models/metalplategibs.mdl";
fModelCount = 13;
break;
case GSMATERIAL_FLESH:
sModel = "models/fleshgibs.mdl";
fModelCount = 4;
break;
case GSMATERIAL_TILE:
sModel = "models/ceilinggibs.mdl";
fModelCount = 4;
break;
case GSMATERIAL_COMPUTER:
sModel = "models/computergibs.mdl";
fModelCount = 15;
break;
case GSMATERIAL_ROCK:
sModel = "models/rockgibs.mdl";
fModelCount = 3;
break;
default:
case GSMATERIAL_CINDER:
sModel = "models/cindergibs.mdl";
fModelCount = 9;
break;
}
vector vWorldPos;
vWorldPos = vMins + (0.5 * (vMaxs - vMins));
switch (fStyle) {
case GSMATERIAL_GLASS:
pointsound(vWorldPos, sprintf("debris/bustglass%d.wav", random(1, 4)), 1.0f, ATTN_NORM);
break;
case GSMATERIAL_WOOD:
pointsound(vWorldPos, sprintf("debris/bustcrate%d.wav", random(1, 4)), 1.0f, ATTN_NORM);
break;
case GSMATERIAL_METAL:
case GSMATERIAL_COMPUTER:
pointsound(vWorldPos, sprintf("debris/bustmetal%d.wav", random(1, 3)), 1.0f, ATTN_NORM);
break;
case GSMATERIAL_FLESH:
pointsound(vWorldPos, sprintf("debris/bustflesh%d.wav", random(1, 3)), 1.0f, ATTN_NORM);
break;
case GSMATERIAL_CINDER:
case GSMATERIAL_ROCK:
pointsound(vWorldPos, sprintf("debris/bustconcrete%d.wav", random(1, 4)), 1.0f, ATTN_NORM);
break;
case GSMATERIAL_TILE:
pointsound(vWorldPos, "debris/bustceiling.wav", 1.0f, ATTN_NORM);
break;
}
for (int i = 0; i < count; i++) {
entity eGib = spawn();
eGib.classname = "gib";
vecPos[0] = vMins[0] + (random() * (vMaxs[0] - vMins[0]));
vecPos[1] = vMins[1] + (random() * (vMaxs[1] - vMins[1]));
vecPos[2] = vMins[2] + (random() * (vMaxs[2] - vMins[2]));
setorigin(eGib, vecPos);
setmodel(eGib, sModel);
setcustomskin(eGib, "", sprintf("geomset 0 %f\n", random(1, fModelCount + 1)));
eGib.movetype = MOVETYPE_BOUNCE;
eGib.solid = SOLID_NOT;
eGib.avelocity[0] = random()*600;
eGib.avelocity[1] = random()*600;
eGib.avelocity[2] = random()*600;
eGib.think = FX_BreakModel_Remove;
eGib.nextthink = time + 10;
if ((fStyle == GSMATERIAL_GLASS) || (fStyle == GSMATERIAL_GLASS_UNBREAKABLE)) {
eGib.alpha = 0.5f;
}
eGib.drawmask = MASK_ENGINE;
}
#endif
}

View File

@ -1,114 +0,0 @@
/*
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef CLIENT
var int FX_EXPLOSION_MAIN;
var int FX_EXPLOSION_BS;
var int FX_EXPLOSION_SPARK;
void
FX_Explosion_Init(void)
{
Sound_Precache("fx.explosion");
precache_model("sprites/fexplo.spr");
FX_EXPLOSION_MAIN = particleeffectnum("fx_explosion.main");
FX_EXPLOSION_BS = particleeffectnum("fx_explosion.blacksmoke");
FX_EXPLOSION_SPARK = particleeffectnum("fx_spark.effect");
}
#endif
void
FX_Explosion(vector vecPos)
{
#ifdef SERVER
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_EXPLOSION);
WriteCoord(MSG_MULTICAST, vecPos[0]);
WriteCoord(MSG_MULTICAST, vecPos[1]);
WriteCoord(MSG_MULTICAST, vecPos[2]);
msg_entity = self;
multicast(vecPos, MULTICAST_PVS);
#else
static void FX_Explosion_Spark(void)
{
if (self.alpha < 0) {
remove(self);
return;
}
pointparticles(FX_EXPLOSION_SPARK, self.origin, randomvec(), 1);
self.alpha--;
self.nextthink = time + 0.1f + (random() * 0.1f);
}
static float FX_Explosion_DLight(void)
{
dynamiclight_add(self.origin, 256 * self.alpha, [1.0,0.45,0]);
self.alpha -= frametime;
if (self.alpha <= 0.0f) {
remove(self);
} else {
addentity(self);
}
return PREDRAW_NEXT;
}
entity dlight = spawn();
setorigin(dlight, vecPos);
dlight.predraw = FX_Explosion_DLight;
dlight.drawmask = MASK_ENGINE;
dlight.alpha = 2.0f;
DecalGroups_Place("ExplosionScorch", vecPos);
vecPos[2] += 48;
env_sprite eExplosion = spawn(env_sprite);
makevectors(view_angles);
setorigin(eExplosion, vecPos + [0,0,48] + (v_forward * -32));
setmodel(eExplosion, "sprites/fexplo.spr");
Sound_Play(eExplosion, CHAN_WEAPON, "fx.explosion");
//eExplosion.think = FX_Explosion_Animate;
eExplosion.SetRenderMode(RM_ADDITIVE);
eExplosion.SetRenderAmt(1.0f);
eExplosion.SetRenderColor([1,1,1]);
eExplosion.drawmask = MASK_ENGINE;
eExplosion.m_iMaxFrame = modelframecount(eExplosion.modelindex);
eExplosion.m_bLoops = 0;
eExplosion.m_flFramerate = 20;
eExplosion.nextthink = time + 0.05f;
eExplosion.scale = 2.0f;
for (int i = 0; i < 2; i++) {
entity sparks = spawn();
sparks.alpha = 5;
sparks.movetype = MOVETYPE_TOSS;
sparks.think = FX_Explosion_Spark;
sparks.nextthink = time + 0.1f;
sparks.drawmask = MASK_ENGINE;
sparks.velocity[0] = random(-128,128);
sparks.velocity[1] = random(-128,128);
sparks.velocity[2] = (400 + random() * 64);
setorigin(sparks, vecPos);
}
pointparticles(FX_EXPLOSION_MAIN, vecPos, [0,0,0], 1);
pointparticles(FX_EXPLOSION_BS, vecPos, [0,0,0], 1);
#endif
}

View File

@ -1,231 +0,0 @@
/*
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef CLIENT
var int FX_IMPACT_BLACKBITS;
var int FX_IMPACT_SMOKE_BROWN;
var int FX_IMPACT_SMOKE_GREY;
var int FX_IMPACT_SPARK;
var int DECAL_IMPACT_DEFAULT;
var int DECAL_IMPACT_ALIEN;
var int DECAL_IMPACT_FLESH;
var int DECAL_IMPACT_FOLIAGE;
var int DECAL_IMPACT_COMPUTER;
var int DECAL_IMPACT_DIRT;
var int DECAL_IMPACT_VENT;
var int DECAL_IMPACT_GRATE;
var int DECAL_IMPACT_METAL;
var int DECAL_IMPACT_GLASS;
var int DECAL_IMPACT_SAND;
var int DECAL_IMPACT_SLOSH;
var int DECAL_IMPACT_SNOW;
var int DECAL_IMPACT_TILE;
var int DECAL_IMPACT_WOOD;
var int DECAL_IMPACT_CONCRETE;
void
FX_Impact_Init(void)
{
Sound_Precache("sfx_impact.default");
Sound_Precache("sfx_impact.alien");
Sound_Precache("sfx_impact.flesh");
Sound_Precache("sfx_impact.foliage");
Sound_Precache("sfx_impact.computer");
Sound_Precache("sfx_impact.dirt");
Sound_Precache("sfx_impact.vent");
Sound_Precache("sfx_impact.grate");
Sound_Precache("sfx_impact.metal");
Sound_Precache("sfx_impact.glass");
Sound_Precache("sfx_impact.sand");
Sound_Precache("sfx_impact.slosh");
Sound_Precache("sfx_impact.snow");
Sound_Precache("sfx_impact.tile");
Sound_Precache("sfx_impact.wood");
Sound_Precache("sfx_impact.concrete");
FX_IMPACT_BLACKBITS = particleeffectnum("fx_impact.blackbits");
FX_IMPACT_SMOKE_GREY = particleeffectnum("fx_impact.smoke_grey");
FX_IMPACT_SMOKE_BROWN = particleeffectnum("fx_impact.smoke_brown");
FX_IMPACT_SPARK = particleeffectnum("fx_impact.spark");
/* engine-side particle system decals for non HL1 BSP */
DECAL_IMPACT_DEFAULT = particleeffectnum("decal_impact.default");
DECAL_IMPACT_ALIEN = particleeffectnum("decal_impact.alien");
DECAL_IMPACT_FLESH = particleeffectnum("decal_impact.flesh");
DECAL_IMPACT_FOLIAGE = particleeffectnum("decal_impact.foliage");
DECAL_IMPACT_COMPUTER = particleeffectnum("decal_impact.computer");
DECAL_IMPACT_DIRT = particleeffectnum("decal_impact.dirt");
DECAL_IMPACT_VENT = particleeffectnum("decal_impact.vent");
DECAL_IMPACT_GRATE = particleeffectnum("decal_impact.grate");
DECAL_IMPACT_METAL = particleeffectnum("decal_impact.metal");
DECAL_IMPACT_GLASS = particleeffectnum("decal_impact.glass");
DECAL_IMPACT_SAND = particleeffectnum("decal_impact.sand");
DECAL_IMPACT_SLOSH = particleeffectnum("decal_impact.slosh");
DECAL_IMPACT_SNOW = particleeffectnum("decal_impact.snow");
DECAL_IMPACT_TILE = particleeffectnum("decal_impact.tile");
DECAL_IMPACT_WOOD = particleeffectnum("decal_impact.wood");
DECAL_IMPACT_CONCRETE = particleeffectnum("decal_impact.concrete");
precache_model("sprites/wsplash3.spr");
}
#endif
void
FX_Impact(impactType_t iType, vector vecPos, vector vNormal)
{
#ifdef SERVER
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_IMPACT);
WriteByte(MSG_MULTICAST, (float)iType);
WriteCoord(MSG_MULTICAST, vecPos[0]);
WriteCoord(MSG_MULTICAST, vecPos[1]);
WriteCoord(MSG_MULTICAST, vecPos[2]);
WriteCoord(MSG_MULTICAST, vNormal[0]);
WriteCoord(MSG_MULTICAST, vNormal[1]);
WriteCoord(MSG_MULTICAST, vNormal[2]);
msg_entity = self;
multicast(vecPos, MULTICAST_PVS);
#else
/* decals */
if (serverkeyfloat("*bspversion") == BSPVER_HL) {
switch (iType) {
case IMPACT_GLASS:
Decals_Place(vecPos, sprintf("{break%d", floor(random(1,4))));
break;
case IMPACT_MELEE:
Decals_Place(vecPos, sprintf("{shot%d", floor(random(1,6))));
break;
default:
Decals_Place(vecPos, sprintf("{bigshot%d", floor(random(1,6))));
break;
}
} else {
switch (iType) {
case IMPACT_GLASS:
pointparticles(DECAL_IMPACT_GLASS, vecPos, vNormal, 1);
break;
case IMPACT_WOOD:
pointparticles(DECAL_IMPACT_WOOD, vecPos, vNormal, 1);
break;
case IMPACT_METAL:
pointparticles(DECAL_IMPACT_METAL, vecPos, vNormal, 1);
break;
case IMPACT_FLESH:
pointparticles(DECAL_IMPACT_FLESH, vecPos, vNormal, 1);
break;
default:
pointparticles(DECAL_IMPACT_DEFAULT, vecPos, vNormal, 1);
break;
}
}
switch (iType) {
case IMPACT_MELEE:
case IMPACT_EXPLOSION:
break;
case IMPACT_DIRT:
case IMPACT_GLASS:
case IMPACT_FOLIAGE:
case IMPACT_SNOW:
case IMPACT_SAND:
pointparticles(FX_IMPACT_BLACKBITS, vecPos, vNormal, 1);
break;
case IMPACT_WOOD:
pointparticles(FX_IMPACT_SPARK, vecPos, vNormal, 1);
pointparticles(FX_IMPACT_BLACKBITS, vecPos, vNormal, 1);
pointparticles(FX_IMPACT_SMOKE_BROWN, vecPos, vNormal, 1);
break;
case IMPACT_GRATE:
case IMPACT_VENT:
case IMPACT_METAL:
pointparticles(FX_IMPACT_SPARK, vecPos, vNormal, 1);
pointparticles(FX_IMPACT_BLACKBITS, vecPos, vNormal, 1);
break;
case IMPACT_SLOSH:
env_sprite splash = spawn(env_sprite);
setorigin(splash, vecPos + [0,0,24]);
setmodel(splash, "sprites/wsplash3.spr");
splash.SetRenderMode(RM_ADDITIVE);
splash.SetRenderAmt(1.0f);
splash.SetRenderColor([1,1,1]);
splash.drawmask = MASK_ENGINE;
splash.m_iMaxFrame = modelframecount(splash.modelindex);
splash.m_bLoops = 0;
splash.m_flFramerate = 20;
splash.nextthink = time + 0.05f;
break;
case IMPACT_FLESH:
FX_Blood(vecPos, vNormal);
break;
default:
pointparticles(FX_IMPACT_SPARK, vecPos, vNormal, 1);
pointparticles(FX_IMPACT_BLACKBITS, vecPos, vNormal, 1);
pointparticles(FX_IMPACT_SMOKE_GREY, vecPos, vNormal, 1);
break;
}
switch (iType) {
case IMPACT_ALIEN:
Sound_PlayAt(vecPos, "sfx_impact.alien");
break;
case IMPACT_COMPUTER:
Sound_PlayAt(vecPos, "sfx_impact.computer");
break;
case IMPACT_CONCRETE:
Sound_PlayAt(vecPos, "sfx_impact.concrete");
break;
case IMPACT_DIRT:
Sound_PlayAt(vecPos, "sfx_impact.dirt");
break;
case IMPACT_FLESH:
Sound_PlayAt(vecPos, "sfx_impact.flesh");
break;
case IMPACT_FOLIAGE:
Sound_PlayAt(vecPos, "sfx_impact.foliage");
break;
case IMPACT_GLASS:
Sound_PlayAt(vecPos, "sfx_impact.glass");
break;
case IMPACT_GRATE:
Sound_PlayAt(vecPos, "sfx_impact.grate");
break;
case IMPACT_METAL:
Sound_PlayAt(vecPos, "sfx_impact.metal");
break;
case IMPACT_SLOSH:
Sound_PlayAt(vecPos, "sfx_impact.slosh");
break;
case IMPACT_SNOW:
Sound_PlayAt(vecPos, "sfx_impact.snow");
break;
case IMPACT_TILE:
Sound_PlayAt(vecPos, "sfx_impact.tile");
break;
case IMPACT_VENT:
Sound_PlayAt(vecPos, "sfx_impact.vent");
break;
case IMPACT_WOOD:
Sound_PlayAt(vecPos, "sfx_impact.wood");
break;
default:
Sound_PlayAt(vecPos, "sfx_impact.default");
break;
}
#endif
}

View File

@ -1,46 +0,0 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef CLIENT
var float PARTICLE_SPARK;
void
FX_Spark_Init(void)
{
Sound_Precache("env_spark.sfx");
PARTICLE_SPARK = particleeffectnum("fx_spark.effect");
}
#endif
void
FX_Spark(vector pos, vector ang)
{
#ifdef SERVER
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_SPARK);
WriteCoord(MSG_MULTICAST, pos[0]);
WriteCoord(MSG_MULTICAST, pos[1]);
WriteCoord(MSG_MULTICAST, pos[2]);
WriteCoord(MSG_MULTICAST, ang[0]);
WriteCoord(MSG_MULTICAST, ang[1]);
WriteCoord(MSG_MULTICAST, ang[2]);
msg_entity = self;
multicast(pos, MULTICAST_PVS);
#else
pointparticles(PARTICLE_SPARK, pos, ang, 1);
Sound_PlayAt(pos, "env_spark.sfx");
#endif
}

View File

@ -10,11 +10,7 @@ pmove.qc
fx_blood.qc
fx_gaussbeam.qc
fx_breakmodel.qc
fx_explosion.qc
fx_spark.qc
fx_corpse.qc
fx_impact.qc
items.h
weapons.h

View File

@ -14,88 +14,7 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef CLIENT
/* Here's a list of bone names that we are aware of on HL player models.
Usually we'd use skeletalobjects to share the same skeleton/anim with
another model - but because FTEQW does not support that for HLMDL we
are forced to manually position the bones of our attachnment
by iterating over them and manually setting their position in 3D-space.
*/
string g_pbones[] =
{
"Bip01",
"Bip01 Footsteps",
"Bip01 Pelvis",
"Bip01 L Leg",
"Bip01 L Leg1",
"Bip01 L Foot",
"Bip01 L Toe0",
"Bip01 L Toe01",
"Bip01 L Toe02",
"Dummy16",
"Bip01 R Leg",
"Bip01 R Leg1",
"Bip01 R Foot",
"Bip01 R Toe0",
"Bip01 R Toe01",
"Bip01 R Toe02",
"Dummy11",
"Bip01 Spine",
"Bip01 Spine1",
"Bip01 Spine2",
"Bip01 Spine3",
"Bip01 Neck",
"Bip01 Head",
"Dummy21",
"Dummy08",
"Bone02",
"Bone03",
"Bone04",
"Dummy05",
"Bone09",
"Bone10",
"Dummy04",
"Bone05",
"Bone06",
"Dummy03",
"Bone07",
"Bone08",
"Dummy09",
"Bone11",
"Bone12",
"Dummy10",
"Bone13",
"Bone14",
"Bone15",
"Bip01 L Arm",
"Bip01 L Arm1",
"Bip01 L Arm2",
"Bip01 L Hand",
"Bip01 L Finger0",
"Bip01 L Finger01",
"Bip01 L Finger02",
"Dummy06",
"Bip01 L Finger1",
"Bip01 L Finger11",
"Bip01 L Finger12",
"Dummy07",
"Bip01 R Arm",
"Bip01 R Arm1",
"Bip01 R Arm2",
"Bip01 R Hand",
"Bip01 R Finger0",
"Bip01 R Finger01",
"Bip01 R Finger02",
"Dummy01",
"Bip01 R Finger1",
"Bip01 R Finger11",
"Bip01 R Finger12",
"Dummy02",
"Box02",
"Bone08",
"Bone15"
};
#endif
#include "skeleton.h"
/* all custom SendFlags bits we can possibly send */
enumflags
@ -153,9 +72,6 @@ class player:NSClientPlayer
virtual void UpdatePlayerAnimation(float);
#ifdef CLIENT
////virtual void(void) draw;
//virtual float() predraw;
//virtual void(void) postdraw;
virtual void UpdatePlayerAttachments(bool);
virtual void ReceiveEntity(float,float);
virtual void PredictPreFrame(void);

82
src/shared/skeleton.h Normal file
View File

@ -0,0 +1,82 @@
#ifdef CLIENT
/* Here's a list of bone names that we are aware of on HL player models.
Usually we'd use skeletalobjects to share the same skeleton/anim with
another model - but because FTEQW does not support that for HLMDL we
are forced to manually position the bones of our attachnment
by iterating over them and manually setting their position in 3D-space.
*/
string g_pbones[] =
{
"Bip01",
"Bip01 Footsteps",
"Bip01 Pelvis",
"Bip01 L Leg",
"Bip01 L Leg1",
"Bip01 L Foot",
"Bip01 L Toe0",
"Bip01 L Toe01",
"Bip01 L Toe02",
"Dummy16",
"Bip01 R Leg",
"Bip01 R Leg1",
"Bip01 R Foot",
"Bip01 R Toe0",
"Bip01 R Toe01",
"Bip01 R Toe02",
"Dummy11",
"Bip01 Spine",
"Bip01 Spine1",
"Bip01 Spine2",
"Bip01 Spine3",
"Bip01 Neck",
"Bip01 Head",
"Dummy21",
"Dummy08",
"Bone02",
"Bone03",
"Bone04",
"Dummy05",
"Bone09",
"Bone10",
"Dummy04",
"Bone05",
"Bone06",
"Dummy03",
"Bone07",
"Bone08",
"Dummy09",
"Bone11",
"Bone12",
"Dummy10",
"Bone13",
"Bone14",
"Bone15",
"Bip01 L Arm",
"Bip01 L Arm1",
"Bip01 L Arm2",
"Bip01 L Hand",
"Bip01 L Finger0",
"Bip01 L Finger01",
"Bip01 L Finger02",
"Dummy06",
"Bip01 L Finger1",
"Bip01 L Finger11",
"Bip01 L Finger12",
"Dummy07",
"Bip01 R Arm",
"Bip01 R Arm1",
"Bip01 R Arm2",
"Bip01 R Hand",
"Bip01 R Finger0",
"Bip01 R Finger01",
"Bip01 R Finger02",
"Dummy01",
"Bip01 R Finger1",
"Bip01 R Finger11",
"Bip01 R Finger12",
"Dummy02",
"Box02",
"Bone08",
"Bone15"
};
#endif

View File

@ -110,53 +110,6 @@ w_crossbow_holster(player pl)
Weapons_ViewAnimation(pl, CROSSBOW_HOLSTER1);
}
#ifdef SERVER
void Crossbolt_Touch(void) {
/* explode mode, multiplayer */
if (self.weapon) {
float dmg = Skill_GetValue("plr_xbow_bolt_monster", 50);
FX_Explosion(self.origin);
Damage_Radius(self.origin, self.owner, dmg, dmg * 2.5f, TRUE, WEAPON_CROSSBOW);
if (random() < 0.5) {
sound(self, 1, "weapons/explode3.wav", 1.0f, ATTN_NORM);
} else {
sound(self, 1, "weapons/explode4.wav", 1.0f, ATTN_NORM);
}
remove(self);
return;
}
/* walls, etc. */
if (other.takedamage != DAMAGE_YES) {
FX_Spark(self.origin, trace_plane_normal);
Sound_Play(self, 1, "weapon_crossbow.hit");
/* disappear bolt after ~ 10 seconds */
self.velocity = [0,0,0];
self.movetype = MOVETYPE_NONE;
self.solid = SOLID_NOT;
self.think = Util_Destroy;
self.nextthink = time + 15.0f;
makevectors(self.angles);
setorigin(self, self.origin + v_forward * -16);
return;
}
/* anything else that can take damage */
Damage_Apply(other, self.owner, Skill_GetValue("plr_xbow_bolt_monster", 50), WEAPON_CROSSBOW, DMG_BLUNT);
Sound_Play(self, 1, "weapon_crossbow.hitbody");
if (other.iBleeds == FALSE) {
FX_Spark(self.origin, trace_plane_normal);
} else {
FX_Blood(self.origin, [1,0,0]);
}
/* disappear... immediately */
remove(self);
}
#endif
void
w_crossbow_primary(player pl)
{
@ -178,12 +131,12 @@ w_crossbow_primary(player pl)
#ifndef CLIENT
HLGameRules rules = (HLGameRules) g_grMode;
Weapons_MakeVectors(pl);
/* multiplayer uses hitscan when zoomed in */
if (rules.IsMultiplayer() == true && pl.viewzoom < 1.0) {
vector src, dest;
src = pl.origin + pl.view_ofs;
Weapons_MakeVectors(pl);
dest = src + v_forward * 4096;
traceline(src, dest, MOVE_LAGGED, pl);
@ -191,7 +144,7 @@ w_crossbow_primary(player pl)
Damage_Apply(trace_ent, pl, Skill_GetValue("plr_xbow_bolt_monster", 50), WEAPON_CROSSBOW, DMG_BLUNT);
if (other.iBleeds == FALSE)
FX_Spark(trace_endpos, trace_plane_normal);
pointparticles(particleeffectnum("platform.spark"), self.origin, trace_plane_normal, 1);
else
FX_Blood(trace_endpos, [1,0,0]);
@ -208,27 +161,12 @@ w_crossbow_primary(player pl)
bolt_used.nextthink = time + 10.0f;
}
} else {
entity bolt = spawn();
setmodel(bolt, "models/crossbow_bolt.mdl");
setorigin(bolt, Weapons_GetCameraPos(pl) + (v_forward * 16));
bolt.owner = pl;
bolt.velocity = v_forward * 2000;
bolt.movetype = MOVETYPE_FLYMISSILE;
bolt.solid = SOLID_BBOX;
//bolt.flags |= FL_LAGGEDMOVE;
bolt.gravity = 0.5f;
bolt.angles = vectoangles(bolt.velocity);
bolt.avelocity[2] = 10;
bolt.touch = Crossbolt_Touch;
/* zoomed out = explosive */
if (rules.IsMultiplayer() == true) {
bolt.weapon = 1;
/* Turok's explosive bolt had a trail; assumed the same with HL considering documented cut content. */
bolt.traileffectnum = particleeffectnum("weapon_crossbow.trail");
NSProjectile_SpawnDef("projectile_arrowExplosive", pl);
} else {
NSProjectile_SpawnDef("projectile_arrow", pl);
}
setsize(bolt, [0,0,0], [0,0,0]);
}
if (pl.crossbow_mag > 0) {

View File

@ -131,7 +131,7 @@ w_crowbar_primary(player pl)
if (trace_ent.iBleeds) {
FX_Blood(trace_endpos, [1,0,0]);
} else {
FX_Impact(IMPACT_MELEE, trace_endpos, trace_plane_normal);
SurfData_Impact(trace_ent, trace_endpos, trace_plane_normal);
}
if (trace_ent.takedamage) {

View File

@ -31,6 +31,8 @@ void w_handgrenade_precache(void)
#ifdef SERVER
Sound_Precache("weapon_handgrenade.bounce");
precache_model("models/w_grenade.mdl");
particleeffectnum("fx_explosion.main");
precache_model("sprites/fexplo.spr");
#else
precache_model("models/v_grenade.mdl");
precache_model("models/p_grenade.mdl");
@ -78,9 +80,10 @@ void w_handgrenade_throw(player pl)
static void WeaponFrag_Throw_Explode(void)
{
float dmg = Skill_GetValue("plr_hand_grenade", 150);
FX_Explosion(self.origin);
pointparticles(particleeffectnum("fx_explosion.main"), self.origin, [0,0,0], 1);
Damage_Radius(self.origin, self.owner, dmg, dmg * 2.5f, TRUE, WEAPON_HANDGRENADE);
sound(self, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM);
Sound_Play(self, CHAN_VOICE, "fx.explosion");
remove(self);
}

View File

@ -220,33 +220,7 @@ w_mp5_secondary(player pl)
pl.ammo_m203_grenade--;
#ifdef SERVER
static void Grenade_ExplodeTouch(void) {
float dmg = Skill_GetValue("plr_9mmAR_grenade", 100);
FX_Explosion(self.origin);
Damage_Radius(self.origin, self.owner, dmg, dmg * 2.5f, TRUE, WEAPON_HANDGRENADE);
if (random() < 0.5) {
sound(self, 1, "weapons/explode3.wav", 1, ATTN_NORM);
} else {
sound(self, 1, "weapons/explode4.wav", 1, ATTN_NORM);
}
remove(self);
}
Weapons_MakeVectors(pl);
entity gren = spawn();
setmodel(gren, "models/grenade.mdl");
setorigin(gren, Weapons_GetCameraPos(pl) + (v_forward * 16.0f));
gren.owner = pl;
gren.velocity = v_forward * 800.0f;
gren.angles = vectoangles(gren.velocity);
gren.avelocity[0] = random(-100.0f, -500.0f);
gren.gravity = 0.5f;
gren.movetype = MOVETYPE_BOUNCE;
//gren.flags |= FL_LAGGEDMOVE;
gren.solid = SOLID_BBOX;
setsize(gren, [0,0,0], [0,0,0]);
gren.touch = Grenade_ExplodeTouch;
NSProjectile_SpawnDef("projectile_ARgrenade", pl);
Sound_Play(pl, CHAN_WEAPON, "weapon_mp5.gl");
#endif

View File

@ -35,6 +35,7 @@ void w_rpg_precache(void)
Sound_Precache("weapon_rpg.empty");
precache_model("models/w_rpg.mdl");
precache_model("models/rpgrocket.mdl");
Sound_Precache("fx.explosion");
#else
precache_model("models/v_rpg.mdl");
precache_model("models/p_rpg.mdl");
@ -115,50 +116,12 @@ void w_rpg_primary(player pl)
pl.rpg_mag--;
#ifdef SERVER
static void Rocket_Touch(void) {
float dmg = Skill_GetValue("plr_rpg", 100);
FX_Explosion(self.origin);
Damage_Radius(self.origin, self.owner, dmg, dmg * 2.5f, TRUE, WEAPON_RPG);
sound(self, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM);
remove(self);
}
static void Rocket_BuildSpeed(void){
/* Calculate new direction */
if (self.weapon) {
vector ownerTarget = self.owner.origin + self.owner.view_ofs;
makevectors(self.owner.v_angle);
traceline(ownerTarget, ownerTarget + v_forward * 8096, FALSE, self.owner);
self.angles = vectoangles(trace_endpos - self.origin);
}
/* Increase speed towards it */
makevectors(self.angles);
self.velocity += (v_forward * 2000) * frametime;
self.nextthink = time;
}
Weapons_MakeVectors(pl);
entity rocket = spawn();
setmodel(rocket, "models/rpgrocket.mdl");
setorigin(rocket, Weapons_GetCameraPos(pl) + (v_forward * 16));
rocket.owner = pl;
rocket.movetype = MOVETYPE_FLY;
rocket.solid = SOLID_BBOX;
//bolt.flags |= FL_LAGGEDMOVE;
rocket.gravity = 0.5f;
rocket.velocity = (pl.WaterLevel() >= WATERLEVEL_SUBMERGED) ? (v_forward * 100): (v_forward * 250);
rocket.angles = vectoangles(rocket.velocity);
rocket.avelocity[2] = 10;
rocket.touch = Rocket_Touch;
rocket.think = Rocket_BuildSpeed;
rocket.nextthink = time + 0.15f;
rocket.traileffectnum = particleeffectnum("weapon_rpg.trail");
if (pl.ammo_rpg_state > 0) {
rocket.weapon = 1;
NSProjectile_SpawnDef("projectile_rocket_homing", pl);
} else {
NSProjectile_SpawnDef("projectile_rocket", pl);
}
setsize(rocket, [0,0,0], [0,0,0]);
Sound_Play(pl, CHAN_WEAPON, "weapon_rpg.shoot");
#endif

View File

@ -32,45 +32,15 @@ enum
};
#ifdef SERVER
void
s_satchel_drop(entity master, vector src, vector vel)
{
static void s_satchel_touch(void)
{
if (other != world)
return;
Sound_Play(self, CHAN_BODY, "weapon_satchel.bounce");
}
entity satch;
satch = spawn();
satch.owner = master;
satch.classname = "satchel";
satch.movetype = MOVETYPE_BOUNCE;
satch.solid = SOLID_BBOX;
satch.frame = 1;
satch.gravity = 0.5f;
satch.friction = 0.8f;
satch.velocity = vel;
satch.avelocity = [0,400,0];
satch.touch = s_satchel_touch;
setmodel(satch, "models/w_satchel.mdl");
setsize(satch, [-1,-1,-4], [1,1,4]);
setorigin(satch, src);
}
void
s_satchel_detonate(entity master)
{
for (entity b = world; (b = find(b, ::classname, "satchel"));) {
for (entity b = world; (b = find(b, ::classname, "projectile_satchel"));) {
if (b.owner != master)
continue;
float dmg = Skill_GetValue("plr_satchel", 150);
FX_Explosion(b.origin);
Damage_Radius(b.origin, master, dmg, dmg * 2.5f, TRUE, WEAPON_SATCHEL);
sound(b, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM);
remove(b);
NSProjectile satchelEnt = (NSProjectile)b;
satchelEnt._Explode();
}
}
#endif
@ -168,11 +138,7 @@ w_satchel_primary(player pl)
#ifdef SERVER
/* if we don't have any satchels placed yet, place one */
if (!pl.satchel_chg) {
vector throw;
Weapons_MakeVectors(pl);
throw = pl.velocity + (v_forward * 274);
s_satchel_drop(pl, pl.origin, throw);
NSProjectile_SpawnDef("projectile_satchel", pl);
pl.satchel_chg++;
pl.ammo_satchel--;
pl.mode_tempstate = 1; /* mark us as having deployed something */
@ -223,10 +189,7 @@ w_satchel_secondary(player pl)
Weapons_ViewAnimation(pl, RADIO_DRAW);
#ifdef SERVER
vector throw;
Weapons_MakeVectors(pl);
throw = pl.velocity + (v_forward * 274);
s_satchel_drop(pl, pl.origin, throw);
NSProjectile_SpawnDef("projectile_satchel", pl);
#endif
if (pl.flags & FL_CROUCHING)

View File

@ -73,9 +73,10 @@ monster_tripmine::Trip(int walkthrough)
Pain = __NULL__;
takedamage = DAMAGE_NO;
dmg = Skill_GetValue("plr_tripmine", 150);
FX_Explosion(origin);
pointparticles(particleeffectnum("fx_explosion.main"), origin, [0,0,0], 1);
Damage_Radius(origin, real_owner, dmg, dmg * 2.5f, TRUE, WEAPON_TRIPMINE);
sound(this, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM);
Sound_Play(self, CHAN_VOICE, "fx.explosion");
Destroy();
}
@ -283,7 +284,7 @@ w_tripmine_primary(player pl)
vector ang = vectoangles(trace_plane_normal);
monster_tripmine mine = spawn(monster_tripmine, real_owner: pl, angles: ang, spawnflags: MSF_MULTIPLAYER);
mine.health = 0;
mine.SetOrigin(trace_endpos - (v_forward * 8));
mine.SetOrigin(trace_endpos + (trace_plane_normal * 8));
Sound_Play(pl, CHAN_WEAPON, "weapon_tripmine.deploy");
Sound_Play(mine, CHAN_WEAPON, "weapon_tripmine.charge");

View File

@ -16,4 +16,38 @@ entityDef weapon_9mmAR
entityDef weapon_mp5
{
"spawnclass" "weapon_9mmAR"
}
entityDef projectile_ARgrenade
{
"spawnclass" "NSProjectile"
"model" "models/grenade.mdl"
"offset" "16 0 0"
"velocity" "800 0 0"
"angular_velocity" "-300 0 0"
"gravity" "0.5"
"bounce" "1"
"mins" "0 0 0"
"maxs" "0 0 0"
"detonate_on_fuse" "0"
"detonate_on_death" "1"
"detonate_on_world" "1"
"detonate_on_actor" "1"
"snd_explode" "fx.explosion"
"model_detonate" "fx_explosion.main"
"def_damage" "damage_ARgrneadeDirect"
"def_splash_damage" "damage_ARgrneadeSplash"
}
entityDef damage_ARgrneadeDirect
{
"damage" "50"
}
entityDef damage_ARgrneadeSplash
{
"damage" "skill:plr_9mmAR_grenade"
"radius" "160"
}

View File

@ -11,4 +11,42 @@ entityDef weapon_crossbow
"inv_item" "$WEAPON_CROSSBOW"
"snd_acquire" "weapon.pickup"
"snd_respawn" "item.respawn"
}
entityDef projectile_arrow
{
"spawnclass" "NSProjectile"
"model" "models/crossbow_bolt.mdl"
"velocity" "2000 0 0"
"angular_velocity" "0 0 20"
"smoke_fly" "weapon_crossbow.trail"
"mins" "0 0 0"
"maxs" "0 0 0"
"def_damage" "damage_arrowDirect"
"model_detonate" "fx_spark.main"
"snd_explode" "fx.spark"
"detonate_on_fuse" "0"
"detonate_on_death" "1"
"detonate_on_world" "1"
"detonate_on_actor" "1"
}
entityDef damage_arrowDirect
{
"damage" "skill:plr_xbow_bolt_monster"
}
entityDef projectile_arrowExplosive
{
"inherit" "projectile_arrow"
"def_damage" ""
"def_splash_damage" "damage_arrowSplash"
"model_detonate" "fx_explosion.main"
"snd_explode" "fx.explosion"
}
entityDef damage_arrowSplash
{
"damage" "skill:plr_xbow_bolt_monster"
"radius" "125"
}

View File

@ -11,4 +11,58 @@ entityDef weapon_rpg
"inv_item" "$WEAPON_RPG"
"snd_acquire" "weapon.pickup"
"snd_respawn" "item.respawn"
}
entityDef projectile_rocket
{
"spawnclass" "NSProjectile"
"model" "models/rpgrocket.mdl"
"def_damage" "damage_rocketDirect"
"def_splash_damage" "damage_rocketSplash"
"health" "0"
"velocity" "250"
"angular_velocity" "0 0 200"
"fuse" "10"
"detonate_on_fuse" "0"
"detonate_on_death" "1"
"detonate_on_world" "1"
"detonate_on_actor" "1"
"impact_damage_effect" "1"
"impact_gib" "1"
"thrust" "2000"
"thrust_start" "0.1"
"thrust_end" "2"
"smoke_fly" "weapon_rpg.trail"
"model_detonate" "fx_explosion.main"
"light_color" "1 0.8 0.4"
"light_radius" "160"
"light_offset" "0 0 0"
"explode_light_color" "2 1.6 0.8"
"explode_light_radius" "320"
"explode_light_fadetime" "0.5"
"snd_explode" "fx.explosion"
}
entityDef projectile_rocket_homing
{
"inherit" "projectile_rocket"
"thrust_homing" "1"
}
entityDef damage_rocketDirect
{
"damage" "skill:plr_rocketlauncher_impact"
"damage_random" "skill:plr_rocketlauncher_impact_rand"
}
entityDef damage_rocketSplash
{
"damage" "skill:plr_rpg"
"radius" "250"
}

View File

@ -11,4 +11,31 @@ entityDef weapon_satchel
"inv_item" "$WEAPON_SATCHEL"
"snd_acquire" "weapon.pickup"
"snd_respawn" "item.respawn"
}
entityDef projectile_satchel
{
"spawnclass" "NSProjectile"
"model" "models/w_satchel.mdl"
"velocity" "274 0 0"
"angular_velocity" "0 400 0"
"friction" "0.8"
"gravity" "0.5"
"bounce" "1"
"frame" "1"
"mins" "-1 -1 -4"
"maxs" "1 1 4"
"snd_bounce" "weapon_satchel.bounce"
"inherit_velocity" "1"
"def_splash_damage" "damage_satchelExplosion"
"model_detonate" "fx_explosion.main"
"snd_explode" "fx.explosion"
}
entityDef damage_satchelExplosion
{
"damage" "skill:plr_satchel"
"radius" "375"
}

View File

@ -42,8 +42,8 @@ r_part +main
lightradiusfade 300
lightrgb 1.0 0.5 0.4
lightrgbfade 0.36 0.19 0.19
count 1
model "sprites/fexplo.spr" framestart=0 framecount=29 framerate=20 additive scalemin=32 scalemax=32 orient
count 0 0 1
model "sprites/fexplo.spr" framestart=0 framecount=29 framerate=20 additive
}
r_part +main

View File

@ -70,3 +70,39 @@ r_part smoke_grey
spawnvel 20
veladd 20
}
r_part water
{
count 0 0 1
model "sprites/wsplash3.spr" framestart=0 frameend=14 framerate=20 additive
}
r_part slime
{
lighttime 0.5
lightradius 256
lightradiusfade 300
lightrgb 0.0 1.0 0.0
lightrgbfade 0.0 0.0 0.0
}
r_part +slime
{
count 0 0 1
model "sprites/wsplash3.spr" framestart=0 frameend=14 framerate=20 additive
}
r_part lava
{
lighttime 0.5
lightradius 256
lightradiusfade 300
lightrgb 1.0 0.0 0.0
lightrgbfade 0.0 0.0 0.0
}
r_part +lava
{
count 0 0 1
model "sprites/wsplash3.spr" framestart=0 frameend=14 framerate=20 additive
}

View File

@ -1,4 +1,4 @@
r_part effect
r_part main
{
type texturedspark
texture ball

View File

@ -195,4 +195,28 @@ gs_material_vent
stepleft "step_vent.left"
stepright "step_vent.right"
break "func_breakable.break_metal"
}
water
{
part_bulletimpact "fx_impact.water"
bulletimpact "sfx_impact.slosh"
stepleft "step_slosh.left"
stepright "step_slosh.right"
}
lava
{
part_bulletimpact "impact_default.main"
bulletimpact "sfx_impact.slosh"
stepleft "step_slosh.left"
stepright "step_slosh.right"
}
slime
{
part_bulletimpact "impact_default.main"
bulletimpact "sfx_impact.slosh"
stepleft "step_slosh.left"
stepright "step_slosh.right"
}