Adjusting spawn-angle to match spawnpoints.

This commit is contained in:
Marco Cawthorne 2020-04-04 00:52:45 +02:00
parent 5e936559ea
commit e1b38f008a
18 changed files with 189 additions and 96 deletions

View File

@ -245,6 +245,13 @@ CSQC_UpdateView(float w, float h, float focus)
}
}
Predict_PostFrame((player)self);
if (pSeat->pWeaponFX) {
CBaseFX p = (CBaseFX)pSeat->pWeaponFX;
p.Draw();
}
addentities(MASK_ENGINE);
setproperty(VF_MIN, video_mins);
setproperty(VF_SIZE, video_res);
@ -322,8 +329,6 @@ CSQC_UpdateView(float w, float h, float focus)
CSQC_DrawCenterprint();
}
}
Predict_PostFrame((player)self);
}
DSP_UpdateListener();
@ -572,6 +577,14 @@ CSQC_Parse_Event(void)
Effect_Impact(iType, vOrigin, vNormal);
break;
case EV_ANGLE:
vector a;
a[0] = readfloat();
a[1] = readfloat();
a[2] = readfloat();
setproperty(VF_CL_VIEWANGLES, a);
setproperty(VF_ANGLES, a);
break;
default:
Game_Parse_Event(fHeader);
}

36
src/client/fx.c Normal file
View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <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.
*/
class CBaseFX
{
int m_iBaseJoint;
void() CBaseFX;
virtual void() Draw;
};
void
CBaseFX::Draw(void)
{
}
void
CBaseFX::CBaseFX(void)
{
drawmask = MASK_ENGINE;
}

View File

@ -78,6 +78,7 @@ struct
int iInputDuck;
float fInputSendNext;
entity pWeaponFX;
} seats[4], *pSeat;
void HUD_DrawAmmo1(void);

View File

@ -29,6 +29,7 @@ View_Init(void)
pSeat->eMuzzleflash = spawn();
pSeat->eMuzzleflash.classname = "mflash";
pSeat->eMuzzleflash.renderflags = RF_ADDITIVE;
pSeat->pWeaponFX = spawn(CBaseFX);
}
}

View File

@ -6,6 +6,7 @@
baseentity.h
decals.h
materials.h
../client/fx.c
client/baseentity.cpp
client/env_cubemap.cpp
client/env_glow.cpp

View File

@ -28,3 +28,15 @@ void Client_TriggerCamera(entity target, vector pos, vector end, float wait)
msg_entity = target;
multicast([0,0,0], MULTICAST_ONE);
}
void Client_FixAngle(entity target, vector ang)
{
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_ANGLE);
WriteFloat(MSG_MULTICAST, ang[0]);
WriteFloat(MSG_MULTICAST, ang[1]);
WriteFloat(MSG_MULTICAST, ang[2]);
msg_entity = target;
multicast([0,0,0], MULTICAST_ONE);
}

View File

@ -75,7 +75,6 @@ Gamerules_Spawn(player pl)
spot = find(world, classname, "info_player_start");
setorigin(pl, spot.origin);
pl.angles = spot.angles;
pl.fixangle = TRUE;
}
Weapons_RefreshAmmo(pl);
} else {
@ -84,6 +83,6 @@ Gamerules_Spawn(player pl)
spot = Spawn_SelectRandom("info_player_deathmatch");
setorigin(pl, spot.origin);
pl.angles = spot.angles;
pl.fixangle = TRUE;
}
Client_FixAngle(pl, pl.angles);
}

View File

@ -28,6 +28,7 @@ void TraceAttack_FireBullets(int , vector, int, vector, int);
void Damage_Radius( vector, entity, float, float, int, int);
void Damage_Apply( entity, entity, float, int, int);
void Client_TriggerCamera( entity eTarget, vector vPos, vector vEndPos, float fResetTime );
void Client_FixAngle(entity, vector);
void Game_Input(void);
int Rules_IsTeamPlay(void);

View File

@ -138,7 +138,6 @@ Gamerules_Spawn(player pl)
spot = find(world, classname, "info_player_start");
setorigin(pl, spot.origin);
pl.angles = spot.angles;
pl.fixangle = TRUE;
}
Weapons_RefreshAmmo(pl);
} else {
@ -147,11 +146,11 @@ Gamerules_Spawn(player pl)
spot = Spawn_SelectRandom("info_player_deathmatch");
setorigin(pl, spot.origin);
pl.angles = spot.angles;
pl.fixangle = TRUE;
pl.ammo_9mm = 68;
Weapons_AddItem(pl, WEAPON_CROWBAR);
Weapons_AddItem(pl, WEAPON_GLOCK);
pl.g_items |= ITEM_SUIT;
}
Client_FixAngle(pl, pl.angles);
}

View File

@ -115,7 +115,6 @@ Gamerules_Spawn(player pl)
spot = find(world, classname, "info_player_start");
setorigin(pl, spot.origin);
pl.angles = spot.angles;
pl.fixangle = TRUE;
}
Weapons_RefreshAmmo(pl);
} else {
@ -124,11 +123,11 @@ Gamerules_Spawn(player pl)
spot = Spawn_SelectRandom("info_player_deathmatch");
setorigin(pl, spot.origin);
pl.angles = spot.angles;
pl.fixangle = TRUE;
pl.ammo_9mm = 68;
Weapons_AddItem(pl, WEAPON_CROWBAR);
Weapons_AddItem(pl, WEAPON_GLOCK);
pl.g_items |= ITEM_SUIT;
}
Client_FixAngle(pl, pl.angles);
}

View File

@ -74,7 +74,6 @@ Gamerules_Spawn(player pl)
Gamerules_SetNewParms();
spot = find(world, classname, "info_player_start");
setorigin(pl, spot.origin);
pl.angles = spot.angles;
pl.fixangle = TRUE;
}
} else {
@ -82,9 +81,9 @@ Gamerules_Spawn(player pl)
spot = Spawn_SelectRandom("info_player_deathmatch");
setorigin(pl, spot.origin);
pl.angles = spot.angles;
pl.fixangle = TRUE;
pl.g_items |= ITEM_SUIT;
}
Client_FixAngle(pl, pl.angles);
}
void weaponbox_spawn(player pl)

View File

@ -74,15 +74,14 @@ Gamerules_Spawn(player pl)
spot = find(world, classname, "info_player_start");
setorigin(pl, spot.origin);
pl.angles = spot.angles;
pl.fixangle = TRUE;
}
} else {
spot = Spawn_SelectRandom("info_player_deathmatch");
setorigin(pl, spot.origin);
pl.angles = spot.angles;
pl.fixangle = TRUE;
pl.g_items |= ITEM_SUIT;
}
Client_FixAngle(pl, pl.angles);
}
void weaponbox_spawn(player pl)

View File

@ -75,16 +75,15 @@ Gamerules_Spawn(player pl)
spot = find(world, classname, "info_player_start");
setorigin(pl, spot.origin);
pl.angles = spot.angles;
pl.fixangle = TRUE;
}
} else {
Gamerules_SetNewParms();
spot = Spawn_SelectRandom("info_player_deathmatch");
setorigin(pl, spot.origin);
pl.angles = spot.angles;
pl.fixangle = TRUE;
pl.g_items |= ITEM_SUIT;
SHData_GetItems();
}
Client_FixAngle(pl, pl.angles);
}

View File

@ -118,7 +118,6 @@ Gamerules_Spawn(player pl)
spot = find(world, classname, "info_player_start");
setorigin(pl, spot.origin);
pl.angles = spot.angles;
pl.fixangle = TRUE;
}
Weapons_RefreshAmmo(pl);
} else {
@ -127,11 +126,11 @@ Gamerules_Spawn(player pl)
spot = Spawn_SelectRandom("info_player_deathmatch");
setorigin(pl, spot.origin);
pl.angles = spot.angles;
pl.fixangle = TRUE;
pl.ammo_9mm = 68;
Weapons_AddItem(pl, WEAPON_CROWBAR);
Weapons_AddItem(pl, WEAPON_GLOCK);
pl.g_items |= ITEM_SUIT;
}
Client_FixAngle(pl, pl.angles);
}

View File

@ -23,6 +23,7 @@ enum {
EV_WEAPON_SECONDARYATTACK,
EV_WEAPON_RELOAD,
EV_WEAPON_PICKUP,
EV_ANGLE,
EV_IMPACT,
EV_GIBHUMAN,
EV_BLOOD,

View File

@ -123,8 +123,7 @@ grapple_predraw(void)
vector col2 = getlight(morg) / 255;
makevectors(view_angles);
R_BeginPolygon(autocvar_cl_tonguemode == 1 ? "sprites/_tongue.spr_0.tga" : "sprites/tongue.spr_0.tga", 0, 0);
R_PolygonVertex(forg + v_right * fsize[0] - v_up * fsize[1],
[1,1], col1, 1.0f);

View File

@ -23,6 +23,90 @@ Gauss Weapon
*/
#ifdef CSQC
#define FXGAUSS_BEAMCOLOR [1,0.5,0]
class FXGauss:CBaseFX
{
int m_iBeams;
vector m_vecStart;
vector m_vecAngle;
void() FXGauss;
virtual void() Draw;
};
void
FXGauss::Draw(void)
{
player pl = (player)self;
int iLoop = 6;
vector src, endpos;
vector gunpos = gettaginfo(pSeat->eViewModel, 33);
if (alpha <= 0.0f) {
return;
}
src = m_vecStart;
makevectors(m_vecAngle);
vector endpos = src + v_forward * 1024;
traceline(src, endpos, FALSE, pl);
/* drawing the first bit */
vector fsize = [3,3];
makevectors(view_angles);
R_BeginPolygon("sprites/xbeam1.spr_0.tga", 1, 0);
R_PolygonVertex(gunpos + v_right * fsize[0] - v_up * fsize[1],
[1,1], FXGAUSS_BEAMCOLOR, alpha);
R_PolygonVertex(gunpos - v_right * fsize[0] - v_up * fsize[1],
[0,1], FXGAUSS_BEAMCOLOR, alpha);
R_PolygonVertex(trace_endpos - v_right * fsize[0] + v_up * fsize[1],
[0,0], FXGAUSS_BEAMCOLOR, alpha);
R_PolygonVertex(trace_endpos + v_right * fsize[0] + v_up * fsize[1],
[1,0], FXGAUSS_BEAMCOLOR, alpha);
R_EndPolygon();
if (m_iBeams == 0) {
alpha -= clframetime * 3;
return;
}
// reflection equation:
vector x = v_forward;
while (iLoop > 0) {
float n;
vector r;
n = -dotproduct(trace_plane_normal, x);
r = 2 * trace_plane_normal * n + x;
x = r;
src = trace_endpos + (x * 1);
endpos = trace_endpos + (x * 8192);
traceline(src, endpos, FALSE, pl);
makevectors(view_angles);
R_BeginPolygon("sprites/xbeam1.spr_0.tga", 1, 0);
R_PolygonVertex(src + v_right * fsize[0] - v_up * fsize[1],
[1,1], FXGAUSS_BEAMCOLOR, alpha);
R_PolygonVertex(src - v_right * fsize[0] - v_up * fsize[1],
[0,1], FXGAUSS_BEAMCOLOR, alpha);
R_PolygonVertex(trace_endpos - v_right * fsize[0] + v_up * fsize[1],
[0,0], FXGAUSS_BEAMCOLOR, alpha);
R_PolygonVertex(trace_endpos + v_right * fsize[0] + v_up * fsize[1],
[1,0], FXGAUSS_BEAMCOLOR, alpha);
R_EndPolygon();
iLoop--;
}
alpha -= clframetime * 3;
}
void
FXGauss::FXGauss(void)
{
CBaseFX::CBaseFX();
}
#endif
enum
{
GAUSS_IDLE1,
@ -45,6 +129,7 @@ void w_gauss_precache(void)
precache_model("models/p_gauss.mdl");
precache_sound("weapons/gauss2.wav");
precache_model("sprites/yelflare1.spr");
precache_model("sprites/xbeam1.spr");
precache_sound("weapons/electro4.wav");
precache_sound("weapons/electro5.wav");
precache_sound("weapons/electro6.wav");
@ -87,6 +172,14 @@ void w_gauss_draw(void)
{
Weapons_SetModel("models/v_gauss.mdl");
Weapons_ViewAnimation(GAUSS_DRAW);
/* link the FX class */
#ifdef CSQC
entity eold = self;
self = pSeat->pWeaponFX;
spawnfunc_FXGauss();
self = eold;
#endif
}
void w_gauss_holster(void)
@ -94,71 +187,16 @@ void w_gauss_holster(void)
Weapons_ViewAnimation(GAUSS_HOLSTER);
}
#ifdef CSQC
void w_gauss_placeorbs(vector org)
{
static float glow_think(void) {
if (self.alpha <= 0.0f) {
remove(self);
return PREDRAW_NEXT;
}
self.alpha -= (clframetime * 0.25);
addentity(self);
return PREDRAW_NEXT;
}
entity glow = spawn();
glow.drawmask = MASK_ENGINE;
setmodel(glow, "sprites/yelflare1.spr");
setsize(glow, [0,0,0], [0,0,0]);
setorigin(glow, org);
glow.predraw = glow_think;
glow.effects = EF_ADDITIVE;
glow.alpha = 1.0f;
glow.scale = 0.25f;
glow.colormod = [255, 255, 0] / 255;
glow.movetype = MOVETYPE_BOUNCE;
glow.velocity[0] = random() - 0.5;
glow.velocity[1] = random() - 0.5;
glow.velocity[2] = random() * 8;
glow.velocity *= 64;
}
void w_gauss_placeimpact(vector org)
{
static float glow_think(void) {
if (self.alpha <= 0.0f) {
remove(self);
return PREDRAW_NEXT;
}
self.alpha -= (clframetime * 0.5);
dynamiclight_add(self.origin, 256 * self.alpha, self.colormod);
addentity(self);
return PREDRAW_NEXT;
}
entity glow = spawn();
glow.drawmask = MASK_ENGINE;
setmodel(glow, "sprites/yelflare1.spr");
setorigin(glow, org);
glow.predraw = glow_think;
glow.effects = EF_ADDITIVE;
glow.alpha = 1.0f;
glow.colormod = [255, 200, 0] / 255;
for (int i = 0; i < 3; i++) {
w_gauss_placeorbs(org);
}
}
#endif
#ifdef SSQC
void w_gauss_fire(int one)
{
player pl = (player)self;
int iLoop = 10;
int iLoop = 6;
Weapons_MakeVectors();
vector src = Weapons_GetCameraPos();
vector endpos = src + v_forward * 1024;
traceline(src, endpos, FALSE, pl);
#ifdef SSQC
sound(pl, CHAN_WEAPON, "weapons/gauss2.wav", 1, ATTN_NORM);
int iDamage = one ? 20 : 200;
@ -170,15 +208,6 @@ void w_gauss_fire(int one)
Damage_Apply(trace_ent, self, iDamage, WEAPON_GAUSS, DMG_ELECTRO);
sound(trace_ent, CHAN_ITEM, sprintf("weapons/electro%d.wav", random(0,3)+4), 1, ATTN_NORM);
}
#else
te_beam(world, gettaginfo(pSeat->eViewModel, 33), trace_endpos);
if (getsurfacetexture(trace_ent, getsurfacenearpoint(trace_ent, trace_endpos)) != "sky") {
w_gauss_placeimpact(trace_endpos);
} else {
return;
}
#endif
if (one) {
return;
} else {
@ -203,7 +232,6 @@ void w_gauss_fire(int one)
traceline(src, endpos, FALSE, pl);
te_beam(world, src, trace_endpos);
iLoop--;
#ifdef SSQC
if (trace_ent.takedamage == DAMAGE_YES) {
Damage_Apply(trace_ent, self, iDamage, WEAPON_GAUSS, DMG_ELECTRO);
sound(trace_ent, CHAN_ITEM, sprintf("weapons/electro%d.wav", random(0,3)+4), 1, ATTN_NORM);
@ -214,17 +242,9 @@ void w_gauss_fire(int one)
} else {
break;
}
#else
if (getsurfacetexture(trace_ent, getsurfacenearpoint(trace_ent, trace_endpos)) != "sky") {
te_beam(world, src, trace_endpos);
w_gauss_placeimpact(trace_endpos);
} else {
break;
}
#endif
}
}
#endif
void w_gauss_primary(void)
{
@ -246,11 +266,17 @@ void w_gauss_primary(void)
Weapons_ViewAnimation(GAUSS_FIRE2);
#ifdef CSQC
FXGauss p = (FXGauss)pSeat->pWeaponFX;
p.m_iBeams = 0;
p.m_vecAngle = input_angles;
p.m_vecStart = pl.net_origin + pl.view_ofs;
p.alpha = 1.0f;
pl.a_ammo2 -= 2;
Weapons_ViewPunchAngle([-2,0,0]);
#else
pl.ammo_uranium -= 2;
#endif
w_gauss_fire(1);
#endif
pl.w_attack_next = 0.2f;
pl.w_idle_next = 2.5f;
@ -330,10 +356,17 @@ void w_gauss_release(void)
pl.a_ammo3 = 0;
return;
} else if (pl.a_ammo3 == 2) {
w_gauss_fire(0);
Weapons_ViewAnimation(GAUSS_FIRE1);
#ifdef CSQC
FXGauss p = (FXGauss)pSeat->pWeaponFX;
p.m_iBeams = 1;
p.m_vecAngle = input_angles;
p.m_vecStart = pl.net_origin + pl.view_ofs;
p.alpha = 1.0f;
soundupdate(pl, CHAN_WEAPON, "", -1, ATTN_NORM, 0, 0, 0);
Weapons_ViewPunchAngle([-5,0,0]);
#else
w_gauss_fire(0);
#endif
pl.w_attack_next = 1.5f;
pl.w_idle_next = 4.0f;

View File

@ -76,9 +76,11 @@ void Weapons_Primary(void)
{
player pl = (player)self;
int i = pl.activeweapon;
if (g_weapons[i].primary != __NULL__) {
g_weapons[i].primary();
}
#ifdef SSQC
if (g_weapons[i].updateammo != __NULL__) {
g_weapons[i].updateammo(pl);