- Added Rewolf decore_* entities from the demo

- Added early Rewolf Health/Armor HUD variants
- Added original scoreboard from the early Half-Life versions for valve/scihunt/rewolf
- Fixed some skybox behaviour to only apply to BSP30
- Changed the env_message and game_text display to use "creditsfont" instead of the conchars
- Tweaked damage radius and prediction for some entities and weapons
- Added world_items
- Added item_healthkit
- Added item_battery
- Fixed level transition logic
- impulse 101 now fills up health and armor/suit in mod valve
- Some tweaks to Damage_Apply so that healing can be performed without funky visuals
- Added stub monsters for valve/rewolf that'll soon support scripted sequences
- Tweaked chat system to get rid of quotation marks around messages
- Added support for changing the window caption to reflect the mod you're playing
- Lots of small little things in terms of cleanup
This commit is contained in:
Marco Cawthorne 2019-03-19 20:01:24 +01:00
parent fccb01c704
commit 9ce909e291
88 changed files with 1899 additions and 583 deletions

View file

@ -2583,7 +2583,7 @@ float(string conname, float inevtype, float parama, float paramb, float paramc)
Forwards input events to the named console. Mouse updates should be absolute only. */
#endif
#ifdef CSQC
#if defined(CSQC) || defined(MENU)
void(string newcaption) setwindowcaption = #0:setwindowcaption; /* Part of FTE_CSQC_WINDOWCAPTION
Replaces the title of the game window, as seen when task switching or just running in windowed mode. */

View file

@ -73,6 +73,13 @@ struct
float fBob;
float damage_alpha;
vector damage_pos;
/* Camera Bob */
float flCamMove;
float flCamTime;
int iCamCycle;
float flCamFracSin;
float flCamDelta;
//Player fields
entity ePlayer;

View file

@ -630,16 +630,78 @@ float CSQC_Ent_ParseMapEntity(void)
switch (strField) {
case "classname":
/*if (strValue == "env_cubemap") {
iClass = TRUE;
eEnt = spawn(CEnvCubemap);
} else */if (strValue == "worldspawn") {
switch (strValue) {
case "worldspawn":
eEnt = spawn(worldspawn);
iClass = TRUE;
} else if (strValue == "env_sound") {
break;
case "env_sound":
eEnt = spawn(env_sound);
iClass = TRUE;
} else {
break;
#ifdef REWOLF
case "decore_asteroid":
eEnt = spawn(decore_asteroid);
iClass = TRUE;
break;
case "decore_baboon":
eEnt = spawn(decore_baboon);
iClass = TRUE;
break;
case "decore_bodygib":
eEnt = spawn(decore_bodygib);
iClass = TRUE;
break;
case "decore_butterflyflock":
eEnt = spawn(decore_butterflyflock);
iClass = TRUE;
break;
case "decore_explodable":
eEnt = spawn(decore_explodable);
iClass = TRUE;
break;
case "decore_foot":
eEnt = spawn(decore_foot);
iClass = TRUE;
break;
case "decore_goldskull":
eEnt = spawn(decore_goldskull);
iClass = TRUE;
break;
case "decore_hatgib":
eEnt = spawn(decore_hatgib);
iClass = TRUE;
break;
case "decore_nest":
eEnt = spawn(decore_nest);
iClass = TRUE;
break;
case "decore_pteradon":
eEnt = spawn(decore_pteradon);
iClass = TRUE;
break;
case "decore_torch":
eEnt = spawn(decore_torch);
iClass = TRUE;
break;
case "decore_spacedebris":
eEnt = spawn(decore_spacedebris);
iClass = TRUE;
break;
case "decore_swampplants":
eEnt = spawn(decore_swampplants);
iClass = TRUE;
break;
case "decore_mushroom":
eEnt = spawn(decore_mushroom);
iClass = TRUE;
break;
case "decore_mushroom2":
eEnt = spawn(decore_mushroom2);
iClass = TRUE;
break;
#endif
default:
eEnt.classname = strValue;
}
break;

View file

@ -3,6 +3,7 @@
#define CSQC
#define VALVE
#define REWOLF
#includelist
../builtins.h
@ -16,10 +17,12 @@ defs.h
vgui.h
util.c
valve/init.c
rewolf/init.c
../gs-entbase/client.src
rewolf/decore.cpp
sound.c
text.c
voice.c
@ -63,7 +66,7 @@ valve/view.c
view.c
damage.c
chat.c
valve/hud.c
rewolf/hud.c
valve/hud_weaponselect.c
valve/scoreboard.c

View file

@ -0,0 +1,176 @@
/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
class CBaseDecor:CBaseEntity
{
int m_iBody;
virtual void(string, string) SpawnKey;
};
void CBaseDecor::Initialized(void)
{
setmodel(this, model);
setorigin(this, origin);
setcustomskin(this, "", sprintf("geomset 0 %i\n", m_iBody));
drawmask = MASK_ENGINE;
}
void CBaseDecor::SpawnKey(string strField, string strKey)
{
switch (strField) {
case "body":
m_iBody = stoi(strKey);
break;
default:
CBaseEntity::SpawnKey(strField, strKey);
break;
}
}
/* Let's begin */
class decore_asteroid:CBaseDecor
{
virtual void() Initialized = {
model = "models/asteroid.mdl";
CBaseDecor::Initialized();
};
};
class decore_baboon:CBaseDecor
{
virtual void() Initialized = {
model = "models/baboon.mdl";
CBaseDecor::Initialized();
};
};
class decore_bodygib:CBaseDecor
{
void() decore_bodygib = {
model = "models/bodygib.mdl";
CBaseDecor::Initialized();
};
};
class decore_butterflyflock:CBaseDecor
{
virtual void() Initialized = {
model = "models/butterfly.mdl";
CBaseDecor::Initialized();
};
};
class decore_explodable:CBaseDecor
{
virtual void() Initialized = {
model = "models/EXPLODABLE!!!!";
CBaseDecor::Initialized();
};
};
class decore_foot:CBaseDecor
{
virtual void() Initialized = {
model = "models/FOOT!!!!";
CBaseDecor::Initialized();
};
};
class decore_goldskull:CBaseDecor
{
virtual void() Initialized = {
model = "models/goldskull.mdl";
CBaseDecor::Initialized();
};
};
class decore_hatgib:CBaseDecor
{
virtual void() Initialized = {
model = "models/hatgib.mdl";
CBaseDecor::Initialized();
};
};
class decore_nest:CBaseDecor
{
virtual void() Initialized = {
model = "models/ornest.mdl";
CBaseDecor::Initialized();
};
};
class decore_pteradon:CBaseDecor
{
virtual void() Initialized = {
model = "models/pteradon2.mdl";
CBaseDecor::Initialized();
};
};
class decore_torch:CBaseDecor
{
virtual void() Initialized = {
precache_model("sprites/torch.spr");
model = "models/torch.mdl";
CBaseDecor::Initialized();
this.effects |= EF_FULLBRIGHT;
sprite flame = spawn(sprite);
setorigin(flame, origin + [0,0,24]);
setmodel(flame, "sprites/torch.spr");
flame.effects = EF_ADDITIVE;
flame.drawmask = MASK_ENGINE;
flame.maxframe = modelframecount(flame.modelindex);
flame.loops = 1;
flame.framerate = 10;
flame.nextthink = time + 0.05f;
};
};
class decore_spacedebris:CBaseDecor
{
virtual void() Initialized = {
CBaseDecor::Initialized();
};
virtual void(string strField, string strKey) SpawnKey = {
switch (strField) {
case "modelname":
model = strKey;
break;
default:
CBaseEntity::SpawnKey(strField, strKey);
break;
}
};
};
class decore_swampplants:CBaseDecor
{
virtual void() Initialized = {
model = "models/swampstuff.mdl";
CBaseDecor::Initialized();
};
};
class decore_mushroom:CBaseDecor
{
virtual void() Initialized = {
model = "models/mushroom.mdl";
CBaseDecor::Initialized();
};
};
class decore_mushroom2:CBaseDecor
{
virtual void() Initialized = {
model = "models/mushroom2.mdl";
CBaseDecor::Initialized();
};
};

257
Source/client/rewolf/hud.c Normal file
View file

@ -0,0 +1,257 @@
/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
/* Use first frame for drawing (needs precache) */
#define HUD_NUMS "sprites/640hud7.spr_0.tga"
#define GM_NUMS "sprites/numbers.spr_0.tga"
#define HUD_ALPHA 0.5
/* New Gunman digits */
#define NUMSIZE_X 18/256
#define NUMSIZE_Y 32/32
float spr_hudnum[10] = {
0 / 256,
18 / 256,
(18*2) / 256,
(18*3) / 256,
(18*4) / 256,
(18*5) / 256,
(18*6) / 256,
(18*7) / 256,
(18*8) / 256,
(18*9) / 256
};
void HUD_DrawWeaponSelect(void);
void HUD_Init(void)
{
precache_model("sprites/640hud7.spr");
precache_model("sprites/numbers.spr");
precache_model("sprites/armor.spr");
precache_model("sprites/hudpulse.spr");
precache_pic("gfx/vgui/640_metalhud_small.tga");
precache_pic("gfx/vgui/640_metalhud.tga");
}
/*
=================
HUD_DrawNumber
Draws a normal number
=================
*/
void HUD_DrawNumber(int iNumber, vector vPos, float fAlpha, vector vColor)
{
drawsubpic(vPos, [18,32], GM_NUMS, [spr_hudnum[iNumber], 0],
[NUMSIZE_X, NUMSIZE_Y], vColor, fAlpha, DRAWFLAG_ADDITIVE);
}
void HUD_DrawSeperator(vector pos)
{
drawsubpic(pos, [2,24], HUD_NUMS, [240/256, 0],
[2/256, 24/128], g_hud_color, HUD_ALPHA, DRAWFLAG_ADDITIVE);
}
/*
=================
HUD_DrawNums
Draws numerals quickly for health, armor etc.
=================
*/
void HUD_DrawNums(float fNumber, vector vPos, float fAlpha, vector vColor)
{
int iNumber = fNumber;
if (iNumber > 0) {
while (iNumber > 0) {
HUD_DrawNumber((float)iNumber % 10, vPos, fAlpha, vColor);
iNumber = iNumber / 10;
vPos[0] -= 20;
}
} else {
HUD_DrawNumber(0, vPos, fAlpha, vColor);
}
}
/*
=================
HUD_DrawHealth
Draw the current amount of health
=================
*/
void HUD_DrawHealth(void)
{
vector pos;
vector hcol;
player pl;
pl = (player)pSeat->ePlayer;
/* Shift digits by 128 units for the larger HUD */
if (video_res[0] <= 640) {
pos = video_mins + [0, video_res[1] - 128];
} else {
pos = video_mins + [128, video_res[1] - 128];
}
/* Obligatory low-health color tint */
if (pl.health <= 25) {
hcol = [1,0,0];
} else {
hcol = [0,1,1];
}
/* Because we've got little space, the number 100 is its own graphic */
if (pl.health >= 100) {
drawsubpic(pos+[34,30], [42,32], GM_NUMS, [192/256, 0],
[42/256, 32/32], hcol, 1.0f, DRAWFLAG_ADDITIVE);
} else {
HUD_DrawNums(pl.health, pos + [56,30], 1.0f, hcol);
}
if (pl.armor >= 100) {
drawsubpic(pos+[34,64], [42,32], GM_NUMS, [192/256, 0],
[42/256, 32/32], [0,1,0], 1.0f, DRAWFLAG_ADDITIVE);
} else {
HUD_DrawNums(pl.armor, pos + [56,64], 1.0f, [0,1,0]);
}
/* Minimal VS Larger HUD */
if (video_res[0] <= 640) {
drawpic(pos, "gfx/vgui/640_metalhud_small.tga", [128,128],
[1,1,1], 1.0f);
} else {
pos[0] -= 128;
/* Armor bar */
float ap = pl.armor / 100;
if (ap) {
drawsubpic(pos+[28,18], [95*ap,32], "sprites/armor.spr_0.tga",
[0, 0], [0.7421875*ap, 1], [1,1,1], 1.0f, DRAWFLAG_NORMAL);
}
/* Health, TODO: make it scroll */
if (pl.health <= 20) {
drawpic(pos + [35,53], "sprites/hudpulse.spr_4.tga", [128,32],
[1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
} else if (pl.health <= 40) {
drawpic(pos + [35,53], "sprites/hudpulse.spr_3.tga", [128,32],
[1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
} else if (pl.health <= 60) {
drawpic(pos + [35,53], "sprites/hudpulse.spr_2.tga", [128,32],
[1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
} else if (pl.health <= 80) {
drawpic(pos + [35,53], "sprites/hudpulse.spr_1.tga", [128,32],
[1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
} else {
drawpic(pos + [35,53], "sprites/hudpulse.spr_0.tga", [128,32],
[1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
}
drawpic(pos, "gfx/vgui/640_metalhud.tga", [256,128], [1,1,1], 1.0f);
}
}
void HUD_DrawAmmo1(void)
{
player pl = (player)pSeat->ePlayer;
vector pos;
static int old_ammo1;
static float ammo1_alpha;
if (pl.a_ammo1 != old_ammo1) {
ammo1_alpha = 1.0;
old_ammo1 = pl.a_ammo1;
}
if (ammo1_alpha >= HUD_ALPHA) {
ammo1_alpha -= frametime * 0.5;
} else {
ammo1_alpha = HUD_ALPHA;
}
pos = video_mins + [video_res[0] - 48, video_res[1] - 42];
/* Magazine/Clip */
if (pl.a_ammo1 != -1) {
HUD_DrawNums(pl.a_ammo1, pos + [-80,0], ammo1_alpha, g_hud_color);
}
HUD_DrawSeperator(pos + [-50,0]);
}
void HUD_DrawAmmo2(void)
{
player pl = (player)pSeat->ePlayer;
vector pos;
static int old_ammo2;
static float ammo2_alpha;
if (pl.a_ammo2 != old_ammo2) {
ammo2_alpha = 1.0;
old_ammo2 = pl.a_ammo2;
}
if (ammo2_alpha >= HUD_ALPHA) {
ammo2_alpha -= frametime * 0.5;
} else {
ammo2_alpha = HUD_ALPHA;
}
pos = video_mins + [video_res[0] - 48, video_res[1] - 42];
/* Leftover Ammo */
HUD_DrawNums(pl.a_ammo2, pos, ammo2_alpha, g_hud_color);
}
void HUD_DrawAmmo3(void)
{
player pl = (player)pSeat->ePlayer;
vector pos;
static int old_ammo3;
static float ammo3_alpha;
if (pl.a_ammo3 != old_ammo3) {
ammo3_alpha = 1.0;
old_ammo3 = pl.a_ammo3;
}
if (ammo3_alpha >= HUD_ALPHA) {
ammo3_alpha -= frametime * 0.5;
} else {
ammo3_alpha = HUD_ALPHA;
}
pos = video_mins + [video_res[0] - 48, video_res[1] - 42];
/* Special */
if (pl.a_ammo3) {
HUD_DrawNums(pl.a_ammo3, pos + [0, -32], ammo3_alpha, g_hud_color);
}
}
void HUD_Draw(void)
{
g_hud_color = autocvar_con_color * (1 / 255);
Damage_Draw();
HUD_DrawHealth();
Weapons_DrawCrosshair();
HUD_DrawWeaponSelect();
}
void VGUI_DrawSpectatorHUD(void)
{
// FIXME
}

View file

@ -0,0 +1,29 @@
/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
/*
=================
Client_Init
Comparable to worldspawn in SSQC in that it's mostly used for precaches
=================
*/
void Client_Init(float apilevel, string enginename, float engineversion)
{
precache_model("sprites/640hud1.spr");
precache_model("sprites/640hud2.spr");
precache_model("sprites/640hud3.spr");
precache_model("sprites/640hud4.spr");
precache_model("sprites/640hud5.spr");
precache_model("sprites/640hud6.spr");
}
void Game_RendererRestarted(string rstr)
{
}

View file

@ -6,6 +6,12 @@
*
****/
/* FIXME: Remove this once the builtin exists */
float getchannellevel(entity foo, float chanid)
{
return bound(0, cos(time), 1) * 100;
}
/* This really shouldn't be here, but it'll be fine for the time being */
.int initedsci;
float Scientist_PreDraw(void)
@ -15,6 +21,8 @@ float Scientist_PreDraw(void)
setcustomskin(self, "", sprintf("geomset 1 %d\n", self.colormod[0]));
self.initedsci = TRUE;
}
self.bonecontrol5 = getchannellevel(self, CHAN_VOICE);
/* HACK: We're abusing this networked field, so reset */
self.colormod = [0,0,0];

View file

@ -21,6 +21,13 @@ struct
float fBob;
float damage_alpha;
vector damage_pos;
/* Camera Bob */
float flCamMove;
float flCamTime;
int iCamCycle;
float flCamFracSin;
float flCamDelta;
//Player fields
entity ePlayer;

View file

@ -1,3 +1,14 @@
/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
#define SCORE_HEADER_C [255/255,156/255,0]
#define SCORE_LINE_C [255/255,200/255,0]
void Scores_Init(void)
{
@ -5,5 +16,55 @@ void Scores_Init(void)
void Scores_Draw(void)
{
vector pos;
player pl;
pl = (player)pSeat->ePlayer;
pos = video_mins + [(video_res[0] / 2) - 145, 30];
drawfill(pos, [290, 1], SCORE_LINE_C, 1.0f, DRAWFLAG_ADDITIVE);
drawfont = FONT_20;
drawstring(pos + [0,-18], "Player", [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
drawstring(pos + [124,-18], "kills / deaths", [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
drawstring(pos + [240,-18], "latency", [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
pos[1] += 12;
for (int i = -1; i > -32; i--) {
float l;
string ping;
string kills;
string deaths;
string name;
name = getplayerkeyvalue(i, "name");
/* Out of players */
if (!name) {
break;
} else if (name == getplayerkeyvalue(pl.entnum-1, "name")) {
drawfill(pos, [290, 13], [0,0,1], 0.5f, DRAWFLAG_ADDITIVE);
}
drawstring(pos, getplayerkeyvalue(i, "name"), [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
drawstring(pos + [154,0], "/", [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
/* Get the kills and align them left to right */
kills = getplayerkeyvalue(i, "frags");
l = stringwidth(kills, FALSE, [20,20]);
drawstring(pos + [150 - l,0], kills, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
/* Deaths are right to left aligned */
deaths = getplayerkeyvalue(i, "*deaths");
drawstring(pos + [165,0], deaths, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
/* Get the latency and align it left to right */
ping = getplayerkeyvalue(i, "ping");
l = stringwidth(ping, FALSE, [20,20]);
drawstring(pos + [290 - l,0], ping, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
pos[1] += 20;
}
drawfont = FONT_CON;
}

View file

@ -6,6 +6,8 @@
*
****/
var int autocvar_v_cambob = FALSE;
void View_Init(void)
{
#ifdef CSTRIKE
@ -66,7 +68,7 @@ void View_CalcBob(void)
float cycle;
vector vel;
if (self.flags & FL_ONGROUND == -1) {
return;
}
@ -89,6 +91,52 @@ void View_CalcBob(void)
pSeat->fBob = bound(-7, fBob, 4);
}
/*
=================
View_CalcCameraBob
=================
*/
void View_CalcCamBob(void)
{
float flPlayerSpeed;
if (!autocvar_v_cambob) {
return;
}
flPlayerSpeed = vlen(pSeat->vPlayerVelocity);
if (flPlayerSpeed < 5) {
pSeat->flCamMove = 0;
pSeat->flCamTime = 0;
} else if (pSeat->fPlayerFlags & FL_ONGROUND) {
if ( flPlayerSpeed > 210 ) {
pSeat->flCamMove = clframetime * 3;
} else if (flPlayerSpeed > 100) {
pSeat->flCamMove = clframetime * 1.5;
} else {
pSeat->flCamMove = clframetime;
}
}
pSeat->flCamTime = (pSeat->flCamTime += pSeat->flCamMove);
pSeat->iCamCycle = (int)pSeat->flCamTime;
pSeat->flCamFracSin = fabs(sin(pSeat->flCamTime * M_PI));
pSeat->flCamDelta = pSeat->flCamFracSin * 0.002 * flPlayerSpeed;
if ((pSeat->fPlayerFlags & FL_CROUCHING) && (pSeat->fPlayerFlags & FL_ONGROUND)) {
pSeat->flCamDelta *= 6;
}
view_angles[0] += pSeat->flCamDelta;
if (pSeat->iCamCycle & 1) {
pSeat->flCamDelta = -pSeat->flCamDelta;
}
view_angles[2] += pSeat->flCamDelta;
}
/*
====================
View_DropPunchAngle
@ -184,6 +232,7 @@ void View_DrawViewModel(void)
}
addentity(eViewModel);
}
View_CalcCamBob();
}
void View_PostDraw(void)

View file

@ -8,10 +8,11 @@
string __fullspawndata;
class CBaseEntity {
class CBaseEntity
{
string targetname;
string target;
void() CBaseEntity;
virtual void() Init;
@ -19,8 +20,9 @@ class CBaseEntity {
virtual void(string, string) SpawnKey;
};
void CBaseEntity :: SpawnKey (string strField, string strKey) {
switch ( strField ) {
void CBaseEntity::SpawnKey(string strField, string strKey)
{
switch (strField) {
case "targetname":
targetname = strKey;
break;
@ -28,29 +30,29 @@ void CBaseEntity :: SpawnKey (string strField, string strKey) {
target = strKey;
break;
case "origin":
origin = stov( strKey );
setorigin( this, origin );
origin = stov(strKey);
setorigin(this, origin);
break;
case "angles":
angles = stov( strKey );
angles = stov(strKey);
break;
case "model":
model = strKey;
break;
case "style":
style = stof( strKey );
style = stof(strKey);
break;
case "color":
color = stov( strKey );
color = stov(strKey);
break;
case "movetype":
movetype = stof( strKey );
movetype = stof(strKey);
break;
case "solid":
solid = stof( strKey );
solid = stof(strKey);
break;
case "scale":
scale = stof( strKey );
scale = stof(strKey);
break;
default:
//dprint(sprintf("Unknown field %s, value %s\n", strField, strKey));

View file

@ -85,7 +85,8 @@ reverbinfo_t reverbPresets [35] = {
{ 1.0000f, 0.7000f, 0.3162f, 0.4477f, 1.0000f, 1.5100f, 1.2500f, 1.1400f, 0.8913f, 0.0200f, [0,0,0], 1.4125f, 0.0300f, [0,0,0], 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
};
class env_sound:CBaseEntity {
class env_sound:CBaseEntity
{
int m_iRoomType;
int m_iRadius;
@ -222,7 +223,7 @@ void env_sound::env_sound(void)
}
}
void env_sound::SpawnKey (string strField, string strKey)
void env_sound::SpawnKey(string strField, string strKey)
{
switch (strField) {
case "roomtype":

View file

@ -10,6 +10,9 @@ var string g_skyname = "desert";
void Sky_Update(void)
{
if (serverkeyfloat("*bspversion") != 30) {
return;
}
localcmd(sprintf("sky %s\n", g_skyname));
}

View file

@ -46,8 +46,8 @@ void Sprite_Animated(void)
me.colormod[1] = readfloat();
me.colormod[2] = readfloat();
me.drawmask = MASK_ENGINE;
me.nextthink = time + ( 1 / me.framerate );
me.maxframe = modelframecount( me.modelindex );
me.nextthink = time + (1 / me.framerate);
me.maxframe = modelframecount(me.modelindex);
me.loops = 1; /* repeats */
setorigin(me, me.origin);
}
@ -67,8 +67,8 @@ void Sprite_ParseEvent(void)
spr.colormod[1] = readfloat();
spr.colormod[2] = readfloat();
spr.drawmask = MASK_ENGINE;
spr.nextthink = time + ( 1 / spr.framerate );
spr.maxframe = modelframecount( spr.modelindex );
spr.nextthink = time + (1 / spr.framerate);
spr.maxframe = modelframecount(spr.modelindex);
spr.loops = 0; /* does not repeat */
setorigin(spr, spr.origin);
}

View file

@ -24,6 +24,7 @@ gametext_t g_textchannels[5];
void GameText_Draw(void)
{
drawfont = FONT_20;
for (int i = 0; i < 5; i++) {
float a = 0.0f;
vector rpos;
@ -37,8 +38,7 @@ void GameText_Draw(void)
if (g_textchannels[i].m_flTime > mtime) {
continue;
}
strwidth = stringwidth(g_textchannels[i].m_strMessage, TRUE, [12,12]);
strwidth = stringwidth(g_textchannels[i].m_strMessage, TRUE, [20,20]);
if (g_textchannels[i].m_flPosX == -1) {
rpos[0] = (video_res[0] / 2) - (strwidth/2);
@ -67,13 +67,15 @@ void GameText_Draw(void)
}
if (g_textchannels[i].m_flPosX >= 0.5) {
drawstring(rpos, g_textchannels[i].m_strMessage, '12 12', g_textchannels[i].m_vecColor2, a, 0 );
drawstring(rpos, g_textchannels[i].m_strMessage, '20 20', g_textchannels[i].m_vecColor2, a, DRAWFLAG_ADDITIVE );
} else {
drawstring(rpos, g_textchannels[i].m_strMessage, '12 12', g_textchannels[i].m_vecColor2, a, 0 );
drawstring(rpos, g_textchannels[i].m_strMessage, '20 20', g_textchannels[i].m_vecColor2, a, DRAWFLAG_ADDITIVE );
}
g_textchannels[i].m_flTime += clframetime;
}
drawfont = FONT_CON;
}
void GameText_Parse(void)

View file

@ -2,6 +2,7 @@
../gs-entbase/server/defs.h
../gs-entbase/server/baseentity.cpp
../gs-entbase/server/basetrigger.cpp
../gs-entbase/server/basemonster.cpp
../gs-entbase/server/ambient_generic.cpp
../gs-entbase/server/cycler.cpp
../gs-entbase/server/cycler_sprite.cpp
@ -24,6 +25,7 @@
../gs-entbase/server/func_illusionary.cpp
../gs-entbase/server/func_ladder.cpp
../gs-entbase/server/func_train.cpp
../gs-entbase/server/func_tracktrain.cpp
../gs-entbase/server/func_pushable.cpp
../gs-entbase/server/func_wall.cpp
../gs-entbase/server/func_wall_toggle.cpp

View file

@ -6,8 +6,7 @@
*
****/
enumflags
{
enumflags {
AS_ARADIUS,
AS_SRADIUS,
AS_MRADIUS,
@ -22,15 +21,10 @@ class ambient_generic:CBaseTrigger
string m_strSoundPath;
float m_flVolume;
float m_flRadius;
int m_iToggleSwitch;
float m_flPitch;
int m_iToggleSwitch;
int m_iLoop;
/* int m_iPreset;
float m_flVolume_Start;
float m_flFadeIn;
float m_flFadeOut;*/ // TODO: Do this in CSQC
void() ambient_generic;
virtual void() Respawn;
@ -42,6 +36,7 @@ void ambient_generic::UseNormal(void)
{
sound(this, CHAN_VOICE, m_strActivePath, m_flVolume, m_flRadius, m_flPitch);
}
void ambient_generic::UseLoop(void)
{
if (m_iToggleSwitch == TRUE) {
@ -50,7 +45,6 @@ void ambient_generic::UseLoop(void)
m_strActivePath = m_strSoundPath;
}
m_iToggleSwitch = 1 - m_iToggleSwitch;
UseNormal();
}
@ -71,13 +65,13 @@ void ambient_generic::Respawn(void)
m_iToggleSwitch = TRUE;
UseNormal();
}
if (m_iLoop) {
Trigger = UseLoop;
}
}
void ambient_generic::ambient_generic (void)
void ambient_generic::ambient_generic(void)
{
for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) {
switch (argv(i)) {
@ -92,7 +86,6 @@ void ambient_generic::ambient_generic (void)
break;
case "volume":
m_flVolume = stof(argv(i+1));
//volume = __NULL__;
break;
case "pitch":
m_flPitch = stof(argv(i+1));
@ -103,7 +96,7 @@ void ambient_generic::ambient_generic (void)
}
if (!m_strSoundPath) {
objerror("ambient_generic: No sound file specified. Aborting.");
objerror("ambient_generic: No sound file specified!");
}
precache_sound(m_strSoundPath);
@ -125,6 +118,6 @@ void ambient_generic::ambient_generic (void)
m_flRadius = ATTN_STATIC;
}
ambient_generic::Respawn();
CBaseTrigger::CBaseTrigger();
ambient_generic::Respawn();
}

View file

@ -50,6 +50,7 @@ void CBaseEntity :: CBaseEntity ( void )
gflags |= GF_CANRESPAWN;
m_oldModel = Util_FixModel(model);
precache_model(m_oldModel);
m_oldSolid = solid;
m_oldHealth = health;
m_oldOrigin = origin;

View file

@ -0,0 +1,101 @@
/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
class CBaseMonster:CBaseEntity
{
void() CBaseMonster;
virtual void() touch;
virtual void() Hide;
virtual void() Respawn;
virtual void() PlayerUse;
virtual void(int) vPain;
virtual void(int) vDeath;
virtual void() Physics;
virtual void() Gib;
};
void CBaseMonster::Gib(void)
{
takedamage = DAMAGE_NO;
Effect_GibHuman(this.origin);
Hide();
}
void CBaseMonster::Physics(void)
{
input_movevalues = [0,0,0];
input_impulse = 0;
input_buttons = 0;
input_angles = angles = v_angle;
input_timelength = frametime;
movetype = MOVETYPE_WALK;
runstandardplayerphysics(this);
movetype = MOVETYPE_NONE;
}
void CBaseMonster::touch(void)
{
if (other.movetype == MOVETYPE_WALK) {
velocity = normalize(other.origin - origin) * -128;
}
}
void CBaseMonster::PlayerUse(void)
{
}
void CBaseMonster::vPain(int iHitBody)
{
}
void CBaseMonster::vDeath(int iHitBody)
{
customphysics = __NULL__;
if (health < -50) {
Gib();
return;
}
solid = SOLID_CORPSE;
}
void CBaseMonster::Hide(void)
{
setmodel(this, "");
solid = SOLID_NOT;
movetype = MOVETYPE_NONE;
customphysics = __NULL__;
}
void CBaseMonster::Respawn(void)
{
setorigin(this, m_oldOrigin);
angles = v_angle;
solid = SOLID_SLIDEBOX;
movetype = MOVETYPE_NONE;
setmodel(this, m_oldModel);
setsize(this, VEC_HULL_MIN + [0,0,36], VEC_HULL_MAX + [0,0,36]);
takedamage = DAMAGE_YES;
iBleeds = TRUE;
customphysics = Physics;
health = 100;
velocity = [0,0,0];
}
void CBaseMonster::CBaseMonster(void)
{
CBaseEntity::CBaseEntity();
precache_model(m_oldModel);
Respawn();
}

View file

@ -28,6 +28,7 @@ Notes
class cycler:CBaseTrigger
{
void() cycler;
virtual void() Respawn;
virtual void(entity, int, int) vPain;
};
@ -41,12 +42,16 @@ void cycler::vPain(entity attacker, int type, int damage)
health = 9999;
}
void cycler::cycler(void)
void cycler::Respawn(void)
{
CBaseEntity::CBaseEntity();
precache_model(m_oldModel);
setmodel(this, m_oldModel);
CBaseEntity::Respawn();
solid = SOLID_BBOX;
takedamage = DAMAGE_YES;
health = 9999;
}
void cycler::cycler(void)
{
CBaseEntity::CBaseEntity();
Respawn();
}

View file

@ -16,6 +16,5 @@ class cycler_sprite:CBaseTrigger
void cycler_sprite::cycler_sprite(void)
{
CBaseEntity::CBaseEntity();
precache_model(m_oldModel);
Respawn();
CBaseEntity::Respawn();
}

View file

@ -43,8 +43,9 @@ void env_explosion::Trigger(void)
Effect_CreateExplosion(origin);
if (!(spawnflags & ENVEXPLO_NODAMAGE)) {
Damage_Radius(origin, this, 500, m_iMagnitude, TRUE);
Damage_Radius(origin, this, m_iMagnitude, m_iMagnitude * 2.5f, TRUE);
}
// TODO: Respawn after round instead?
if (!(spawnflags & ENVEXPLO_REPEATABLE)) {
remove(this);

View file

@ -94,6 +94,10 @@ void env_sprite::env_sprite(void)
if (!m_flFramerate) {
m_flFramerate = 10;
}
if (!m_flScale) {
m_flScale = 1.0f;
}
CBaseTrigger::CBaseTrigger();
precache_model(m_oldModel);

View file

@ -31,6 +31,7 @@ class func_breakable:CBaseTrigger
void() func_breakable;
virtual void() Respawn;
virtual void() Explode;
virtual void() Trigger;
virtual void() PlayerTouch;
/*virtual void() PressureDeath;*/
@ -74,6 +75,20 @@ void func_breakable::vPain (entity attacker, int type, int damage)
}
}
void func_breakable::Explode(void)
{
vector vWorldPos;
vWorldPos[0] = absmin[0] + ( 0.5 * ( absmax[0] - absmin[0] ) );
vWorldPos[1] = absmin[1] + ( 0.5 * ( absmax[1] - absmin[1] ) );
vWorldPos[2] = absmin[2] + ( 0.5 * ( absmax[2] - absmin[2] ) );
Effect_BreakModel(20, absmin, absmax, '0 0 0', m_iMaterial);
Effect_CreateExplosion(vWorldPos);
Damage_Radius(vWorldPos, this, m_flExplodeMag, m_flExplodeMag * 2.5f, TRUE);
CBaseTrigger::UseTargets();
CBaseEntity::Hide();
}
void func_breakable::vDeath (entity attacker, int type, int damage)
{
if (m_iMaterial == MATERIAL_GLASS_UNBREAKABLE) {
@ -82,18 +97,21 @@ void func_breakable::vDeath (entity attacker, int type, int damage)
health = 0;
print(sprintf("BREAK: %v [x] %v [=] %d\n", mins, maxs, vlen(mins - maxs)));
Effect_BreakModel(20, absmin, absmax, '0 0 0', m_iMaterial);
/* This may seem totally absurd. That's because it is. It's very
* unreliable but exploding breakables in close proximity it WILL cause
* an OVERFLOW because we'll be busy running through thousands
* of entities in total when one breakable damages another in a frame.
* The only way around this is to set a hard-coded limit of loops per
* frame and that would break functionality. */
if (m_flExplodeMag) {
vector vWorldPos;
vWorldPos[0] = absmin[0] + ( 0.5 * ( absmax[0] - absmin[0] ) );
vWorldPos[1] = absmin[1] + ( 0.5 * ( absmax[1] - absmin[1] ) );
vWorldPos[2] = absmin[2] + ( 0.5 * ( absmax[2] - absmin[2] ) );
Effect_CreateExplosion(vWorldPos);
think = Explode;
nextthink = time + random(0.0,0.5);
} else {
Effect_BreakModel(20, absmin, absmax, '0 0 0', m_iMaterial);
CBaseTrigger::UseTargets();
CBaseEntity::Hide();
}
CBaseTrigger::UseTargets();
CBaseEntity::Hide();
}
void func_breakable::Trigger(void)

View file

@ -20,22 +20,24 @@ enumflags
FR_LRADIUS
};
class CFuncRotating : CBaseTrigger
class func_rotating : CBaseTrigger
{
vector m_vecMoveDir;
float m_flSpeed;
void() CFuncRotating;
float m_flDamage;
void() func_rotating;
virtual void() Respawn;
virtual void() Trigger;
virtual void() Rotate;
virtual void() Blocked;
virtual void() SetMovementDirection;
};
void CFuncRotating :: Rotate( void )
void func_rotating :: Rotate( void )
{
nextthink = ltime + 10.0f;
}
void CFuncRotating :: Trigger ( void )
void func_rotating :: Trigger ( void )
{
if ( vlen( avelocity ) ) {
avelocity = [0,0,0];
@ -44,14 +46,18 @@ void CFuncRotating :: Trigger ( void )
}
}
void CFuncRotating :: Blocked ( void )
void func_rotating :: Blocked ( void )
{
if ( spawnflags & FR_FANPAIN ) {
// Damage_Apply( other, this, m_iDamage, other.origin, FALSE );
if (avelocity == [0,0,0]) {
return;
}
if (other.takedamage == DAMAGE_YES) {
Damage_Apply(other, this, m_flDamage, other.origin, TRUE);
}
}
void CFuncRotating :: Respawn ( void )
void func_rotating :: Respawn ( void )
{
movetype = MOVETYPE_PUSH;
setorigin( this, origin );
@ -68,9 +74,15 @@ void CFuncRotating :: Respawn ( void )
think = Rotate;
nextthink = ltime + 1.5f;
}
blocked = Blocked;
if (spawnflags & FR_FANPAIN) {
touch = Blocked;
}
}
void CFuncRotating :: SetMovementDirection ( void )
void func_rotating :: SetMovementDirection ( void )
{
if ( spawnflags & FR_ZAXIS ) {
m_vecMoveDir = '0 0 1';
@ -85,7 +97,7 @@ void CFuncRotating :: SetMovementDirection ( void )
}
}
void CFuncRotating :: CFuncRotating ( void )
void func_rotating :: func_rotating ( void )
{
precache_model( model );
for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) {
@ -96,18 +108,19 @@ void CFuncRotating :: CFuncRotating ( void )
case "speed":
m_flSpeed = stof( argv( i + 1 ) );
break;
case "dmg":
m_flDamage = stof( argv( i + 1 ) );
break;
default:
break;
}
}
if ( !m_flSpeed ) {
m_flSpeed = 100;
}
CBaseTrigger::CBaseTrigger();
CFuncRotating::SetMovementDirection();
CFuncRotating::Respawn();
func_rotating::SetMovementDirection();
func_rotating::Respawn();
}
CLASSEXPORT( func_rotating, CFuncRotating )

View file

@ -0,0 +1,118 @@
/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
class func_tracktrain:CBaseTrigger
{
float m_flSpeed;
void() func_tracktrain;
virtual void() Find;
virtual void() NextPath;
virtual void() GoToTarget;
virtual void() Trigger;
virtual void() Respawn;
};
void func_tracktrain::GoToTarget(void)
{
float flTravelTime;
vector vel_to_pos;
entity f;
f = find(world, CBaseTrigger::m_strTargetName, m_strTarget);
if (!f) {
print("^1func_tracktrain^7: Trigger-Target not found! Removing.\n");
return;
}
vel_to_pos = (f.origin - origin);
flTravelTime = (vlen(vel_to_pos) / m_flSpeed);
if (!flTravelTime) {
NextPath();
print(sprintf("TRAIN %s SPEED: %f\n", m_strTargetName, flTravelTime));
return;
}
velocity = (vel_to_pos * (1 / flTravelTime));
think = NextPath;
nextthink = (time + flTravelTime);
}
void func_tracktrain::NextPath(void)
{
CBaseTrigger current_target;
print(sprintf("^2func_tracktrain^7: Talking to current target %s... ", m_strTarget));
current_target = (CBaseTrigger)find(world, CBaseTrigger::m_strTargetName, m_strTarget);
if (!current_target) {
print("^1FAILED.\n");
} else {
print("^2SUCCESS.\n");
}
m_strTarget = current_target.m_strTarget;
velocity = [0,0,0];
GoToTarget();
}
void func_tracktrain::Trigger(void)
{
GoToTarget();
}
void func_tracktrain::Find(void)
{
entity f = find(world, CBaseTrigger::m_strTargetName, m_strTarget);
if (!f) {
print(sprintf("^1func_tracktrain^7: End-Target %s not found! Removing.\n",m_strTarget));
remove(this);
return;
}
print("^2func_tracktrain^7: Successfully found first target.\n");
setorigin(this, f.origin);
}
void func_tracktrain::Respawn(void)
{
solid = SOLID_BSP;
movetype = MOVETYPE_PUSH;
//blocked = Blocked;
setmodel(this, m_oldModel);
setorigin(this, m_oldOrigin);
/* Make sure we got some time for the paths to spawn */
nextthink = ltime + 0.1f;
think = Find;
}
void func_tracktrain::func_tracktrain(void)
{
for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) {
switch ( argv( i ) ) {
case "speed":
m_flSpeed = stof(argv(i+1));
break;
default:
break;
}
}
//if (!m_flSpeed) {
m_flSpeed = 50;
//}
CBaseTrigger::CBaseTrigger();
Respawn();
}

View file

@ -12,22 +12,82 @@ class func_train:CBaseTrigger
void() func_train;
virtual void() Find;
virtual void() MoveEnd;
virtual void() NextPath;
virtual void() GoToTarget;
virtual void() Trigger;
virtual void() Respawn;
};
void func_train::GoToTarget(void)
{
float flTravelTime;
vector vel_to_pos;
entity f;
f = find(world, CBaseTrigger::m_strTargetName, m_strTarget);
if (!f) {
print("^1func_train^7: Trigger-Target not found! Removing.\n");
return;
}
vector vecWorldPos;
vecWorldPos[0] = absmin[0] + ( 0.5 * ( absmax[0] - absmin[0] ) );
vecWorldPos[1] = absmin[1] + ( 0.5 * ( absmax[1] - absmin[1] ) );
vecWorldPos[2] = absmin[2] + ( 0.5 * ( absmax[2] - absmin[2] ) );
vel_to_pos = (f.origin - vecWorldPos);
flTravelTime = (vlen(vel_to_pos) / m_flSpeed);
if (!flTravelTime) {
NextPath();
print(sprintf("TRAIN %s SPEED: %f\n", m_strTargetName, flTravelTime));
return;
}
velocity = (vel_to_pos * (1 / flTravelTime));
think = NextPath;
nextthink = (time + flTravelTime);
}
void func_train::NextPath(void)
{
CBaseTrigger current_target;
print(sprintf("^2func_train^7: Talking to current target %s... ", m_strTarget));
current_target = (CBaseTrigger)find(world, CBaseTrigger::m_strTargetName, m_strTarget);
if (!current_target) {
print("^1FAILED.\n");
} else {
print("^2SUCCESS.\n");
}
m_strTarget = current_target.m_strTarget;
velocity = [0,0,0];
if (m_strTarget) {
GoToTarget();
}
}
void func_train::Trigger(void)
{
GoToTarget();
}
void func_train::Find(void)
{
entity f = find(world, CBaseTrigger::m_strTargetName, m_strTarget);
if (!f) {
print("^1func_train^7: End-Target not found! Removing.\n");
print(sprintf("^1func_train^7: End-Target %s not found! Removing.\n",m_strTarget));
remove(this);
return;
}
print("^2func_train^7: Successfully found first target.\n");
vector vecWorldPos;
vecWorldPos[0] = absmin[0] + ( 0.5 * ( absmax[0] - absmin[0] ) );
vecWorldPos[1] = absmin[1] + ( 0.5 * ( absmax[1] - absmin[1] ) );
@ -37,45 +97,22 @@ void func_train::Find(void)
setorigin(this, vecWorldPos);
}
void func_train::MoveEnd(void)
void func_train::Respawn(void)
{
CBaseTrigger f = (CBaseTrigger)find(world, CBaseTrigger::m_strTargetName, m_strTarget);
m_strTarget = f.m_strTargetName;
solid = SOLID_BSP;
movetype = MOVETYPE_PUSH;
//blocked = Blocked;
velocity = [0,0,0];
}
setmodel(this, m_oldModel);
setorigin(this, m_oldOrigin);
void func_train::Trigger(void)
{
entity f = find(world, CBaseTrigger::m_strTargetName, m_strTarget);
if (!f) {
print("^1func_train^7: Trigger-Target not found! Removing.\n");
return;
}
vector vecWorldPos;
vecWorldPos[0] = absmin[0] + ( 0.5 * ( absmax[0] - absmin[0] ) );
vecWorldPos[1] = absmin[1] + ( 0.5 * ( absmax[1] - absmin[1] ) );
vecWorldPos[2] = absmin[2] + ( 0.5 * ( absmax[2] - absmin[2] ) );
vector vecDifference = (f.origin - vecWorldPos);
float flTravel = vlen(vecDifference);
float flTravelTime = (flTravel / m_flSpeed);
think = MoveEnd;
nextthink = (time + flTravelTime);
print(sprintf("TRAIN %s SPEED: %v\n", this.classname, (vecDifference * (1 / flTravelTime))));
//velocity = (vecDifference * (1 / flTravelTime));
/* Make sure we got some time for the paths to spawn */
nextthink = ltime + 0.1f;
think = Find;
}
void func_train::func_train(void)
{
CBaseTrigger::CBaseTrigger();
for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) {
switch ( argv( i ) ) {
case "speed":
@ -86,15 +123,10 @@ void func_train::func_train(void)
}
}
solid = SOLID_BSP;
movetype = MOVETYPE_PUSH;
//blocked = Blocked;
if (!m_flSpeed) {
m_flSpeed = 100;
}
setmodel(this, m_oldModel);
setorigin(this, m_oldOrigin);
// start trains on the second frame, to make sure their targets have had
// a chance to spawn
nextthink = time + 0.25f;
think = Find;
CBaseTrigger::CBaseTrigger();
Respawn();
}

View file

@ -27,5 +27,3 @@ void func_wall :: Trigger ( void )
frame = 1 - frame;
}
CLASSEXPORT(func_tracktrain, func_wall)

View file

@ -6,4 +6,96 @@
*
****/
// TODO
/*
* Scripted Sequences
* ==================
* Allow a monster to be selected and given an action to perform.
* This is done in the form of an animation.
*/
/* If enabled, the sequence can be triggered more than once.
* Otherwise the entity will be removed once the sequence is complete. */
#define SSFL_REPEATABLE 4
/* Seemingly unused. */
#define SSFL_LEAVECORPSE 8
/* If enabled, the sequence cannot be interrupted.
* The monster will ignore damage until the sequence is complete,
* as with the aiscripted_sequence entity. */
#define SSFL_NOINTERRUPT 32
/* Seemingly unused. */
#define SSFL_OVERRIDEAI 64
/* If enabled, when the sequence is completed, the monster will be placed back
* where the Action Animation started. */
#define SSFL_NOSCRIPTMOVE 128
/* m_iMove, how we move to perform m_iActionAnim */
enum {
SS_NO, /* Don't move or turn */
SS_WALK, /* Walk to the scripted_sequence */
SS_RUN, /* Run to the scripted_sequence */
SS_UNUSED,
SS_INSTANTANEOUS, /* Warp to the location of the scripted_sequence and perform the animation. */
SS_TURNTOFACE /* Turn to the scripted_sequence's angle before performing the animation. */
};
class scripted_sequence:CBaseTrigger
{
/* Target name OR classname description */
string m_strMonster;
/* After the monster has moved to the action point, play this animation */
string m_strActionAnim;
/* Animation to play until the scripted_sequence is triggered */
string m_strIdleAnim;
/* Search radius for m_targetMonster if a classname is specified */
float m_flSearchRadius;
/* How we move to perform m_iActionAnim */
int m_iMove;
void() scripted_sequence;
virtual void() Trigger;
virtual void() Respawn;
};
void scripted_sequence::Trigger(void)
{
}
void scripted_sequence::Respawn(void)
{
}
void scripted_sequence::scripted_sequence(void)
{
int nfields = tokenize(__fullspawndata);
for (int i = 1; i < (nfields-1); i += 2) {
switch (argv(i)) {
case "m_iszEntity":
m_strMonster = argv(i+1);
break;
case "m_iszPlay":
m_strActionAnim = argv(i+1);
break;
case "m_iszIdle":
m_strIdleAnim = argv(i+1);
break;
case "m_flRadius":
m_flSearchRadius = stof(argv(i+1));
break;
case "m_flRepeat":
break;
case "m_fMoveTo":
m_iMove = stoi(argv(i+1));
break;
default:
break;
}
}
}

View file

@ -11,7 +11,7 @@ class info_null
void() info_null;
};
void info_null :: info_null ( void )
void info_null::info_null(void)
{
remove( self );
}
@ -21,36 +21,11 @@ class info_notnull:CBaseTrigger
void() info_notnull;
};
void info_notnull :: info_notnull ( void )
void info_notnull::info_notnull(void)
{
CBaseTrigger::CBaseTrigger();
}
CLASSEXPORT( info_node, info_notnull )
CLASSEXPORT( info_target, info_notnull )
CLASSEXPORT( env_sound, info_null )
/*class CSuit : CBaseTrigger
{
void CSuit;
virtual void() Trigger;
};
void CSuit :: Trigger ( void )
{
CBaseTrigger::UseTargets();
remove( self );
}
void CSuit :: CSuit ( void )
{
CBaseTrigger::CBaseTrigger();
solid = SOLID_TRIGGER;
model = "models/w_suit.mdl";
precache_model( model );
setmodel( this, model );
touch = Trigger;
}
SPAWNEXPORT item_suit ( void ) { spawnfunc_CSuit(); }
SPAWNEXPORT world_items ( void ) { spawnfunc_CSuit(); }*/
CLASSEXPORT(info_node, info_notnull)
CLASSEXPORT(info_target, info_notnull)
CLASSEXPORT(env_sound, info_null)

View file

@ -6,37 +6,43 @@
*
****/
class trigger_auto : CBaseTrigger
class trigger_auto:CBaseTrigger
{
float m_flDelay;
void() trigger_auto;
virtual void() think;
virtual void() Respawn;
};
void trigger_auto :: think ( void )
void trigger_auto::think(void)
{
// This is weird, because ents may not be spawned yet.
// However, Half-Life doesn't care about this, either.
// So why should we?
CBaseTrigger::UseTargets_Delay( m_flDelay );
CBaseTrigger::UseTargets_Delay(m_flDelay);
if ( spawnflags & 1 ) {
remove( this );
if (spawnflags & 1) {
remove(this);
}
}
void trigger_auto :: trigger_auto ( void )
void trigger_auto::Respawn(void)
{
for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) {
switch ( argv( i ) ) {
nextthink = time + 0.2f;
}
void trigger_auto::trigger_auto(void)
{
for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) {
switch (argv(i)) {
case "delay":
m_flDelay = stof( argv( i + 1 ) );
m_flDelay = stof(argv(i+1));
break;
default:
break;
}
}
CBaseTrigger::CBaseTrigger();
nextthink = time + 0.2f;
Respawn();
}

View file

@ -10,11 +10,11 @@ vector g_landmarkpos;
enumflags
{
LC_NOINTERMISSION, // Unused?
LC_NOINTERMISSION,
LC_USEONLY
};
class trigger_changelevel : CBaseTrigger
class trigger_changelevel:CBaseTrigger
{
string m_strMap;
string m_strLandmark;
@ -24,48 +24,48 @@ class trigger_changelevel : CBaseTrigger
void() trigger_changelevel;
virtual void() Change;
virtual void() Trigger;
virtual int( entity, entity ) IsInside;
virtual void() Respawn;
virtual int(entity, entity) IsInside;
};
int trigger_changelevel :: IsInside ( entity ePlayer, entity eVolume ) {
if ( ePlayer.absmin[0] > eVolume.absmax[0] ||
int trigger_changelevel::IsInside(entity ePlayer, entity eVolume)
{
if (ePlayer.absmin[0] > eVolume.absmax[0] ||
ePlayer.absmin[1] > eVolume.absmax[1] ||
ePlayer.absmin[2] > eVolume.absmax[2] ||
ePlayer.absmax[0] < eVolume.absmin[0] ||
ePlayer.absmax[1] < eVolume.absmin[1] ||
ePlayer.absmax[2] < eVolume.absmin[2] )
ePlayer.absmax[2] < eVolume.absmin[2])
return FALSE;
return TRUE;
}
void trigger_changelevel :: Change ( void )
void trigger_changelevel::Change(void)
{
if ( m_strLandmark ) {
entity landmark = find( world, ::targetname, m_strLandmark );
if (m_strLandmark) {
entity landmark = find(world, CBaseTrigger::m_strTargetName, m_strLandmark);
g_landmarkpos = m_activator.origin - landmark.origin;
changelevel( m_strMap, m_strLandmark );
changelevel(m_strMap, m_strLandmark);
} else {
changelevel( m_strMap );
changelevel(m_strMap);
}
}
void trigger_changelevel :: Trigger ( void )
void trigger_changelevel::Trigger(void)
{
//entity eVolume;
if ( time < 5 ) {
if (time < 5) {
return;
}
/*eVolume = find( world, ::targetname, m_strLandmark );
if ( eVolume && eVolume.classname == "CTriggerVolume" ) {
if ( IsInside( other, eVolume ) == FALSE ) {
/*eVolume = find(world, ::targetname, m_strLandmark);
if (eVolume && eVolume.classname == "CTriggerVolume") {
if (IsInside(other, eVolume) == FALSE) {
return;
}
}*/
m_activator = other;
if ( m_flChangeDelay ) {
if (m_flChangeDelay) {
think = Change;
nextthink = time + m_flChangeDelay;
} else {
@ -73,36 +73,48 @@ void trigger_changelevel :: Trigger ( void )
}
}
void trigger_changelevel :: trigger_changelevel ( void )
void trigger_changelevel::Respawn(void)
{
for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) {
switch ( argv( i ) ) {
if (!(spawnflags & LC_USEONLY)) {
touch = Trigger;
}
}
void trigger_changelevel::trigger_changelevel(void)
{
for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) {
switch (argv(i)) {
case "map":
m_strMap = argv( i + 1 );
m_strMap = argv(i+1);
break;
case "landmark":
m_strLandmark = argv( i + 1 );
m_strLandmark = argv(i+1);
break;
case "changedelay":
m_flChangeDelay = stof( argv( i + 1 ) );
m_flChangeDelay = stof(argv(i+1));
break;
default:
break;
}
}
CBaseTrigger::CBaseTrigger();
if ( !( spawnflags & LC_USEONLY ) ) {
touch = Trigger;
}
CBaseTrigger::InitBrushTrigger();
trigger_changelevel::Respawn();
}
CLASSEXPORT( info_landmark, info_notnull )
vector Landmark_GetSpot(void)
{
entity landmark = find(world, targetname, startspot);
entity landmark = find(world, CBaseTrigger::m_strTargetName, startspot);
if (!landmark) {
print(sprintf("^1ERROR^7: Cannot find startspot \"%s\"!\n",startspot));
return __NULL__;
}
return landmark.origin + g_landmarkpos;
}
class info_landmark:CBaseTrigger
{
};

View file

@ -6,12 +6,31 @@
*
****/
class trigger_endsection : CBaseTrigger
class trigger_endsection:CBaseTrigger
{
void() trigger_endsection;
virtual void() Trigger;
virtual void() Respawn;
}
void trigger_endsection :: Trigger ( void )
void trigger_endsection::Trigger ( void )
{
localcmd( "disconnect\n" );
}
/* TODO: Make this redundant */
void trigger_endsection::Respawn(void)
{
solid = SOLID_TRIGGER;
#ifdef GS_DEVELOPER
alpha = 0.5f;
#endif
}
void trigger_endsection::trigger_endsection(void)
{
CBaseEntity::CBaseEntity();
CBaseTrigger::InitBrushTrigger();
trigger_endsection::Respawn();
}

View file

@ -26,8 +26,6 @@ class trigger_hurt:CBaseTrigger
void trigger_hurt::Trigger(void)
{
if (solid != SOLID_NOT) {
#ifdef GS_DEVELOPER
print("trigger_hurt: de-activated.\n");

View file

@ -14,7 +14,7 @@ enumflags
TM_PUSHABLES
};
class trigger_multiple : CBaseTrigger
class trigger_multiple:CBaseTrigger
{
float m_flDelay;
float m_flWait;
@ -23,7 +23,7 @@ class trigger_multiple : CBaseTrigger
virtual void() Respawn;
};
void trigger_multiple :: touch ( void )
void trigger_multiple::touch(void)
{
eActivator = other;
@ -31,8 +31,8 @@ void trigger_multiple :: touch ( void )
return;
}
if ( m_flDelay > 0 ) {
CBaseTrigger::UseTargets_Delay( m_flDelay );
if (m_flDelay > 0) {
CBaseTrigger::UseTargets_Delay(m_flDelay);
} else {
CBaseTrigger::UseTargets();
}
@ -49,7 +49,8 @@ void trigger_multiple :: touch ( void )
#endif
}
void trigger_multiple :: Respawn ( void )
/* TODO: Make this redundant */
void trigger_multiple::Respawn(void)
{
solid = SOLID_TRIGGER;
#ifdef GS_DEVELOPER
@ -57,15 +58,15 @@ void trigger_multiple :: Respawn ( void )
#endif
}
void trigger_multiple :: trigger_multiple ( void )
void trigger_multiple::trigger_multiple(void)
{
for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) {
switch ( argv( i ) ) {
for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) {
switch (argv(i)) {
case "delay":
m_flDelay = stof( argv( i + 1 ) );
m_flDelay = stof(argv(i+1));
break;
case "wait":
m_flWait = stof( argv( i + 1 ) );
m_flWait = stof(argv(i+1));
break;
default:
break;

View file

@ -26,7 +26,7 @@ void trigger_once::touch(void)
{
eActivator = other;
if ( m_flDelay > 0 ) {
if (m_flDelay > 0) {
CBaseTrigger::UseTargets_Delay(m_flDelay);
} else {
CBaseTrigger::UseTargets();
@ -37,6 +37,7 @@ void trigger_once::touch(void)
#endif
}
/* TODO: Make this redundant */
void trigger_once::Respawn(void)
{
solid = SOLID_TRIGGER;
@ -47,10 +48,10 @@ void trigger_once::Respawn(void)
void trigger_once::trigger_once(void)
{
for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) {
switch ( argv( i ) ) {
for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) {
switch (argv(i)) {
case "delay":
m_flDelay = stof( argv( i + 1 ) );
m_flDelay = stof(argv(i + 1));
break;
default:
break;

View file

@ -10,26 +10,28 @@
#define TP_STARTOFF 2
#define TP_AAAA 4
class trigger_push : CBaseTrigger
class trigger_push:CBaseTrigger
{
vector m_vecMoveDir;
float m_flDelay;
float m_flSpeed;
void() trigger_push;
virtual void() touch;
virtual void() Respawn;
virtual void() Trigger;
virtual void() SetMovementDirection;
};
void trigger_push :: SetMovementDirection ( void )
void trigger_push::SetMovementDirection(void)
{
if ( angles == '0 -1 0' ) {
if (angles == '0 -1 0') {
m_vecMoveDir = '0 0 1';
} else if ( angles == '0 -2 0' ) {
} else if (angles == '0 -2 0') {
m_vecMoveDir = '0 0 -1';
} else {
makevectors( angles );
makevectors(angles);
m_vecMoveDir = v_forward;
}
@ -37,19 +39,18 @@ void trigger_push :: SetMovementDirection ( void )
//m_vecMoveDir *= 1;
}
void trigger_push :: Trigger ( void )
void trigger_push::Trigger(void)
{
if ( solid == SOLID_NOT ) {
if (solid == SOLID_NOT) {
solid = SOLID_TRIGGER;
} else {
solid = SOLID_NOT;
}
}
void trigger_push :: touch ( void )
void trigger_push::touch(void)
{
switch( other.movetype )
{
switch(other.movetype) {
case MOVETYPE_NONE:
case MOVETYPE_PUSH:
case MOVETYPE_NOCLIP:
@ -57,16 +58,16 @@ void trigger_push :: touch ( void )
return;
}
if ( other.solid != SOLID_NOT && other.solid != SOLID_BSP ) {
if ( spawnflags & TP_ONCE ) {
if (other.solid != SOLID_NOT && other.solid != SOLID_BSP) {
if (spawnflags & TP_ONCE) {
other.velocity = other.velocity + (m_flSpeed * m_vecMoveDir);
if ( other.velocity[2] > 0 ) {
if (other.velocity[2] > 0) {
other.flags &= ~FL_ONGROUND;
}
Hide();
} else {
/*vector vecPush = m_flSpeed * m_vecMoveDir;
if ( other.flags & FL_BASEVELOCITY ) {
if (other.flags & FL_BASEVELOCITY) {
vecPush = vecPush + other.basevelocity;
}
@ -76,28 +77,28 @@ void trigger_push :: touch ( void )
}
}
void trigger_push :: Respawn ( void )
void trigger_push::Respawn(void)
{
if ( angles == '0 0 0' ) {
if (angles == '0 0 0') {
angles[1] = 360;
}
SetMovementDirection();
if ( m_flSpeed == 0 ) {
if (m_flSpeed == 0) {
m_flSpeed = 100;
}
if ( spawnflags & TP_STARTOFF ) {
if (spawnflags & TP_STARTOFF) {
solid = SOLID_NOT;
}
}
void trigger_push :: trigger_push ( void )
void trigger_push::trigger_push(void)
{
for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) {
switch ( argv( i ) ) {
for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) {
switch (argv(i)) {
case "speed":
m_flSpeed = stof( argv( i + 1 ) );
m_flSpeed = stof(argv(i + 1));
break;
default:
break;

View file

@ -6,4 +6,4 @@
*
****/
CLASSEXPORT( trigger_relay, trigger_once )
CLASSEXPORT(trigger_relay, trigger_once)

View file

@ -6,16 +6,17 @@
*
****/
class trigger_teleport : CBaseTrigger
class trigger_teleport:CBaseTrigger
{
void() trigger_teleport;
virtual void() touch;
virtual void() Respawn;
};
void trigger_teleport :: touch ( void )
void trigger_teleport::touch(void)
{
if ( other.health > 0 || other.solid == SOLID_SLIDEBOX ) {
if (other.health > 0 || other.solid == SOLID_SLIDEBOX) {
entity eTarget = find(world, CBaseTrigger::m_strTargetName, m_strTarget);
if (eTarget) {
@ -24,7 +25,8 @@ void trigger_teleport :: touch ( void )
}
}
void trigger_teleport :: Respawn( void )
/* TODO: Make this redundant */
void trigger_teleport::Respawn(void)
{
solid = SOLID_TRIGGER;
#ifdef GS_DEVELOPER
@ -32,10 +34,10 @@ void trigger_teleport :: Respawn( void )
#endif
}
void trigger_teleport :: trigger_teleport ( void )
void trigger_teleport::trigger_teleport(void)
{
CBaseTrigger::CBaseTrigger();
CBaseTrigger::InitBrushTrigger();
}
CLASSEXPORT( info_teleport_destination, info_notnull )
CLASSEXPORT(info_teleport_destination, info_notnull)

View file

@ -11,13 +11,11 @@ class trigger_transition
void() trigger_transition;
};
void trigger_transition :: trigger_transition ( void )
void trigger_transition::trigger_transition(void)
{
solid = SOLID_NOT;
movetype = MOVETYPE_NONE;
setmodel( this, model );
setmodel(this, model);
model = __NULL__;
modelindex = 0;
}
CLASSEXPORT( trigger_transition, trigger_transition )
}

View file

@ -1,49 +0,0 @@
/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
class CWorld
{
void() CWorld;
virtual void() Precaches;
virtual void() SetupLight;
};
void CWorld :: Precaches ( void )
{
Material_Init();
Weapon_Init();
}
void CWorld :: SetupLight ( void )
{
// Valve BSP only
if ( serverkeyfloat( "*bspversion" ) == 30 ) {
lightstyle( 0, "m" );
lightstyle( 1, "mmnmmommommnonmmonqnmmo" );
lightstyle( 2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba" );
lightstyle( 3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg" );
lightstyle( 4, "mamamamamama" );
lightstyle( 5, "jklmnopqrstuvwxyzyxwvutsrqponmlkj" );
lightstyle( 6, "nmonqnmomnmomomno" );
lightstyle( 7, "mmmaaaabcdefgmmmmaaaammmaamm" );
lightstyle( 8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa" );
lightstyle( 9, "aaaaaaaazzzzzzzz" );
lightstyle( 10, "mmamammmmammamamaaamammma" );
lightstyle( 11, "abcdefghijklmnopqrrqponmlkjihgfedcba" );
}
clientstat( 16, EV_FLOAT, ::view_ofs[2] );
}
void CWorld :: CWorld ( void )
{
CWorld::Precaches();
CWorld::SetupLight();
}
//CLASSEXPORT( worldspawn, CWorld )

View file

@ -8,6 +8,25 @@
var int g_initialized = FALSE;
const string AGPL_TEXT = "\
========================================================================\
The FREE-CS PROJECT \
Copyright (C) 2016-2019 Marco Hladik <marco@icculus.org> \
\
This program is free software: you can redistribute it and/or modify\
it under the terms of the GNU Affero General Public License as\
published by the Free Software Foundation, either version 3 of the\
License, or (at your option) any later version.\
\
This program is distributed in the hope that it will be useful,\
but WITHOUT ANY WARRANTY; without even the implied warranty of\
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\
GNU Affero General Public License for more details.\
\
You should have received a copy of the GNU Affero General Public License\
along with this program. If not, see <https://www.gnu.org/licenses/>.\
========================================================================";
void cvar_init(void)
{
/* TODO: Shove these into defaults.cfg instead of forcing them */
@ -28,6 +47,9 @@ void m_init(void)
{
vector g_btnsize;
print(AGPL_TEXT);
print("\n\n");
registercommand("menu_customgame");
font_console = loadfont( "font", "", "12", -1 );
font_label = loadfont( "label", "gfx/shell/mssansserif.ttf", "10 12 14", -1 );

View file

@ -48,6 +48,13 @@ void game_printinfo(int i)
print("==================================\n");
}
void games_set(int id)
{
gameinfo_current = id;
setwindowcaption(games[id].game);
cvar_set("com_fullgamename", games[id].game);
}
void games_init(void)
{
int gameidx;
@ -145,7 +152,7 @@ void games_init(void)
}
}
if (games[gameidx].gamedir == cvar_string("game")) {
gameinfo_current = gameidx;
games_set(gameidx);
}
game_printinfo(gameidx);
}
@ -176,7 +183,7 @@ void customgame_btnactivate_start(void)
{
int nextgame = customgame_lbMods.GetSelected();
gameinfo_current = nextgame;
games_set(nextgame);
localcmd(sprintf("gamedir \"%s\"\n", games[nextgame].gamedir));
localcmd("snd_restart\nwait\nvid_reload\nmenu_restart\nmenu_customgame\n");
// TODO: Re-init important menu bits and bobs.

View file

@ -16,9 +16,9 @@ void SV_SendChat(entity eSender, string sMessage, entity eEnt, float fType)
if (eEnt) {
msg_entity = eEnt;
multicast('0 0 0', MULTICAST_ONE);
multicast([0,0,0], MULTICAST_ONE);
} else {
multicast('0 0 0', MULTICAST_ALL);
multicast([0,0,0], MULTICAST_ALL);
}
}
@ -40,33 +40,31 @@ void Game_ParseClientCommand(string sCommand)
return;
}
string chat = substring(sCommand, 4, strlen(sCommand) - 4);
// Players talk to players, spectators to spectators.
if (self.health ) {
if (argv(0) == "say") {
localcmd(sprintf("echo %s: %s\n", self.netname, chat));
SV_SendChat(self, chat, world, 0);
localcmd(sprintf("echo %s: %s\n", self.netname, argv(1)));
SV_SendChat(self, argv(1), world, 0);
return;
} else if (argv(0) == "say_team") {
localcmd(sprintf("echo [TEAM %d] %s: %s\n", self.team, self.netname, chat));
localcmd(sprintf("echo [TEAM %d] %s: %s\n", self.team, self.netname, argv(1)));
for (entity eFind = world; (eFind = find(eFind, classname, "player"));) {
if (eFind.team == self.team) {
SV_SendChat(self, chat, eFind, 1);
SV_SendChat(self, argv(1), eFind, 1);
}
}
return;
}
} else {
if (argv(0) == "say") {
localcmd(sprintf("echo [DEAD] %s: %s\n", self.netname, chat));
localcmd(sprintf("echo [DEAD] %s: %s\n", self.netname, argv(1)));
for (entity eFind = world; (eFind = find(eFind, classname, "spectator"));) {
SV_SendChat(self, chat, eFind, 1);
SV_SendChat(self, argv(1), eFind, 1);
}
return;
} else if (argv(0) == "say_team") {
localcmd(sprintf("echo [DEAD] %s: %s\n", self.netname, chat));
return;
localcmd(sprintf("echo [DEAD] %s: %s\n", self.netname, argv(1)));
return;
}
}
@ -75,108 +73,8 @@ void Game_ParseClientCommand(string sCommand)
float Game_ConsoleCmd(string sCommand)
{
/*CBot bot;
if (!self) {
for (other = world; (other = find(other, classname, "player"));) {
if (clienttype(other) == CLIENTTYPE_REAL) {
self = other;
break;
}
}
}*/
tokenize(sCommand);
switch (argv(0)) {
/*case "bot_add":
bot = (CBot)spawnclient();
if (!bot) {
print("Server is full\n");
return TRUE;
}
bot.CreateRandom();
break;
case "bot_follow":
if (!self) {
return TRUE;
}
for (other = world; (other = find(other, classname, "Player"));) {
if (clienttype(other) != CLIENTTYPE_BOT) {
continue;
}
bot = (CBot)other;
if (bot.route) {
// RT_RouteChange(bot.route, bot.origin, self.origin);
} else {
// RT_Destroy(bot.route);
// bot.route = RT_RouteCreate(bot.origin, self.origin);
}
}
break;
case "bot_kill":
if (!self) {
return TRUE;
}
for (other = world; (other = find(other, classname, "Player"));) {
if (clienttype(other) != CLIENTTYPE_BOT) {
continue;
}
if (argv(1)) {
if (other.netname == argv(1)) {
//Damage_Apply(other, other, 500, DAMAGE_SUICIDE, 0);
break;
}
} else {
//Damage_Apply(other, other, 500, DAMAGE_SUICIDE, 0);
}
}
break;
case "bot_kick":
if (!self) {
return TRUE;
}
for (other = world; (other = find(other, classname, "Player"));) {
if (clienttype(other) != CLIENTTYPE_BOT) {
continue;
}
if (argv(1)) {
if (other.netname == argv(1)) {
dropclient(other);
break;
}
} else {
dropclient(other);
}
}
break;
case "way_add":
if (!self) {
return TRUE;
}
Way_Waypoint_Create(self, TRUE);
break;
case "way_delete":
if (!self) {
return TRUE;
}
Way_Waypoint_Delete(Way_FindClosestWaypoint(self.origin));
break;
case "way_radius":
if (!self) {
return TRUE;
}
Way_Waypoint_SetRadius(Way_FindClosestWaypoint(self.origin), stof(argv(1)));
break;
case "way_makejump":
if (!self) {
return TRUE;
}
Way_Waypoint_MakeJump(Way_FindClosestWaypoint(self.origin));
break;
case "way_save":
Way_DumpWaypoints(argv(1));
break;
case "way_load":
Way_ReadWaypoints(argv(1));
break;*/
case "vox":
Vox_Broadcast(argv(1));
break;
@ -338,23 +236,18 @@ void Game_Worldspawn(void)
precache_sound("hostage/hos3.wav");
precache_sound("hostage/hos4.wav");
precache_sound("hostage/hos5.wav");
precache_sound("player/pl_pain2.wav");
precache_sound("player/pl_pain4.wav");
precache_sound("player/pl_pain5.wav");
precache_sound("player/pl_pain6.wav");
precache_sound("player/pl_pain7.wav");
precache_sound("player/die1.wav");
precache_sound("player/die2.wav");
precache_sound("player/die3.wav");
precache_sound("player/headshot1.wav");
precache_sound("player/headshot2.wav");
precache_sound("player/headshot3.wav");
precache_sound("items/tr_kevlar.wav");
precache_sound("weapons/ak47-1.wav");
precache_sound("weapons/ak47-2.wav");
precache_sound("weapons/ak47_boltpull.wav");

View file

@ -9,6 +9,7 @@
#define CLASSEXPORT(classname,classa) void classname ( void ) { spawnfunc_##classa(); }
var int autocvar_mp_flashlight = TRUE;
var int g_hlbsp_materials = FALSE;
void Effect_Impact( int iType, vector vPos, vector vNormal );
void Effect_CreateExplosion( vector vPos );
@ -31,6 +32,7 @@ entity eActivator;
.entity eUser;
.float material;
.float armor;
.float deaths;
.float fStepTime;
string startspot;

View file

@ -94,8 +94,10 @@ void init(float prevprogs)
}
}
fclose(fileMaterial);
g_hlbsp_materials = TRUE;
} else {
error("Failed to load sound/materials.txt!\n");
error("Failed to load sound/materials.txt!\n");
g_hlbsp_materials = FALSE;
}
PMove_Init();

View file

@ -15,7 +15,7 @@ Footsteps_Update
Run every frame for each player, plays material based footsteps
=================
*/
void Footsteps_Update( void ) {
void Footsteps_Update(void) {
float fSpeed;
float fVol;
string sMaterial = "";
@ -24,20 +24,24 @@ void Footsteps_Update( void ) {
if (self.flags & FL_CROUCHING) {
return;
}
if (!g_hlbsp_materials) {
return;
}
if ( ( self.movetype == MOVETYPE_WALK ) && ( self.flags & FL_ONGROUND ) ) {
if ( ( self.velocity[0] == 0 && self.velocity[1] == 0 ) || self.fStepTime > time ) {
if ((self.movetype == MOVETYPE_WALK) && (self.flags & FL_ONGROUND)) {
if ((self.velocity[0] == 0 && self.velocity[1] == 0) || self.fStepTime > time) {
return;
}
fSpeed = vlen( self.velocity );
traceline( self.origin + self.view_ofs, self.origin + '0 0 -48', FALSE, self );
sTexture = getsurfacetexture( trace_ent, getsurfacenearpoint( trace_ent, trace_endpos ) );
fSpeed = vlen(self.velocity);
traceline(self.origin + self.view_ofs, self.origin + '0 0 -48', FALSE, self);
sTexture = getsurfacetexture(trace_ent, getsurfacenearpoint(trace_ent, trace_endpos));
if ( fSpeed < 140 ) {
if (fSpeed < 140) {
self.fStepTime = time + 0.35;
fVol = 0.15f;
} else if ( fSpeed < 270 ) {
} else if (fSpeed < 270) {
self.fStepTime = time + 0.35;
fVol = 0.35f;
} else {
@ -45,7 +49,7 @@ void Footsteps_Update( void ) {
fVol = 0.75;
}
switch( (float)hash_get( hashMaterials, sTexture ) ) {
switch((float)hash_get(hashMaterials, sTexture)) {
case 'M':
sMaterial = "metal";
break;
@ -81,17 +85,17 @@ void Footsteps_Update( void ) {
break;
}
if ( self.iStep ) {
if ( random() < 0.5f ) {
sound( self, CHAN_BODY, sprintf( "player/pl_%s1.wav", sMaterial), fVol, ATTN_STATIC );
if (self.iStep) {
if (random() < 0.5f) {
sound(self, CHAN_BODY, sprintf("player/pl_%s1.wav", sMaterial), fVol, ATTN_STATIC);
} else {
sound( self, CHAN_BODY, sprintf( "player/pl_%s2.wav", sMaterial), fVol, ATTN_STATIC );
sound(self, CHAN_BODY, sprintf("player/pl_%s2.wav", sMaterial), fVol, ATTN_STATIC);
}
} else {
if ( random() < 0.5f ) {
sound( self, CHAN_BODY, sprintf( "player/pl_%s3.wav", sMaterial), fVol, ATTN_STATIC );
if (random() < 0.5f) {
sound(self, CHAN_BODY, sprintf("player/pl_%s3.wav", sMaterial), fVol, ATTN_STATIC);
} else {
sound( self, CHAN_BODY, sprintf( "player/pl_%s4.wav", sMaterial), fVol, ATTN_STATIC );
sound(self, CHAN_BODY, sprintf("player/pl_%s4.wav", sMaterial), fVol, ATTN_STATIC);
}
}

View file

@ -17,6 +17,12 @@ defs.h
../gs-entbase/server.src
valve/monster_rat.cpp
valve/monster_scientist_dead.cpp
rewolf/gunman_cycler.cpp
rewolf/monster_human_bandit.cpp
rewolf/monster_human_chopper.cpp
rewolf/monster_human_demoman.cpp
rewolf/monster_human_gunman.cpp
rewolf/monster_human_unarmed.cpp
../shared/decals.c
../shared/effects.c
@ -52,6 +58,7 @@ valve/ammo.cpp
../shared/valve/weapon_common.c
spawn.c
vox.c
valve/client.c
client.c
@ -61,7 +68,6 @@ server.c
valve/damage.c
traceattack.c
vox.c
footsteps.c
flashlight.c

View file

@ -0,0 +1,11 @@
/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
class gunman_cycler:cycler
{
};

View file

@ -0,0 +1,10 @@
class monster_human_bandit:CBaseMonster
{
void() monster_human_bandit;
};
void monster_human_bandit::monster_human_bandit(void)
{
model = "models/bandit.mdl";
CBaseMonster::CBaseMonster();
}

View file

@ -0,0 +1,20 @@
/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
class monster_human_chopper:CBaseEntity
{
void() monster_human_chopper;
};
void monster_human_chopper::monster_human_chopper(void)
{
model = "models/chopper.mdl";
CBaseEntity::CBaseEntity();
setmodel(this, m_oldModel);
setorigin(this, origin);
}

View file

@ -0,0 +1,10 @@
class monster_human_demoman:CBaseMonster
{
void() monster_human_demoman;
};
void monster_human_demoman::monster_human_demoman(void)
{
model = "models/demolitionman.mdl";
CBaseMonster::CBaseMonster();
}

View file

@ -0,0 +1,10 @@
class monster_human_gunman:CBaseMonster
{
void() monster_human_gunman;
};
void monster_human_gunman::monster_human_gunman(void)
{
model = "models/gunmantrooper.mdl";
CBaseMonster::CBaseMonster();
}

View file

@ -0,0 +1,10 @@
class monster_human_unarmed:CBaseMonster
{
void() monster_human_unarmed;
};
void monster_human_unarmed::monster_human_unarmed(void)
{
model = "models/gunmantrooper.mdl";
CBaseMonster::CBaseMonster();
}

View file

@ -57,6 +57,7 @@ valve/item_healthkit.cpp
scihunt/shdata_parse.c
spawn.c
vox.c
scihunt/client.c
client.c
@ -66,7 +67,6 @@ server.c
valve/damage.c
traceattack.c
vox.c
footsteps.c
flashlight.c

View file

@ -104,6 +104,7 @@ void Game_PutClientInServer(void)
pl.vDeath = Player_Death;
pl.iBleeds = TRUE;
forceinfokey(pl, "*spec", "0");
forceinfokey(self, "*deaths", ftos(self.deaths));
if (cvar("sv_playerslots") == 1) {
Game_DecodeChangeParms();

View file

@ -279,6 +279,7 @@ class monster_scientist:CBaseEntity
entity m_eRescuer;
float m_flScreamTime;
float m_flPainTime;
float m_flChangePath;
float m_flTraceTime;
float m_flPitch;
@ -424,19 +425,23 @@ void monster_scientist::Physics(void)
}
}
spvel = vlen(velocity);
if (spvel < 5) {
frame = (m_iFlags & SCIF_SCARED) ? SCIA_SCARED1:SCIA_IDLE1;
} else if (spvel <= 140) {
frame = (m_iFlags & SCIF_SCARED) ? SCIA_WALKSCARED:SCIA_WALK;
} else if (spvel <= 240) {
frame = (m_iFlags & SCIF_SCARED) ? SCIA_RUNSCARED:SCIA_RUN;
}
input_angles = angles = v_angle;
input_timelength = frametime;
movetype = MOVETYPE_WALK;
if (m_flPainTime > time) {
input_movevalues = [0,0,0];
} else {
spvel = vlen(velocity);
if (spvel < 5) {
frame = (m_iFlags & SCIF_SCARED) ? SCIA_SCARED1:SCIA_IDLE1;
} else if (spvel <= 140) {
frame = (m_iFlags & SCIF_SCARED) ? SCIA_WALKSCARED:SCIA_WALK;
} else if (spvel <= 240) {
frame = (m_iFlags & SCIF_SCARED) ? SCIA_RUNSCARED:SCIA_RUN;
}
}
runstandardplayerphysics(this);
Footsteps_Update();
@ -488,13 +493,24 @@ void monster_scientist::PlayerUse(void)
void monster_scientist::vPain(int iHitBody)
{
WarnOthers();
if (m_flPainTime > time) {
return;
}
if (random() < 0.75f) {
return;
}
int rand = floor(random(0,sci_sndpain.length));
sound(this, CHAN_VOICE, sci_sndpain[rand], 1.0, ATTN_NORM, m_flPitch);
frame = SCIA_FLINCH + floor(random(0, 5));
m_iFlags |= SCIF_FEAR;
WarnOthers();
m_flPainTime = time + 1.0f;
}
void monster_scientist::vDeath(int iHitBody)
@ -519,7 +535,7 @@ void monster_scientist::vDeath(int iHitBody)
solid = SOLID_CORPSE;
//takedamage = DAMAGE_NO;
if (style != SCI_DEAD) {
frame = SCIA_DIE_SIMPLE + floor(random(0, 6));
style = SCI_DEAD;
@ -606,3 +622,5 @@ void monster_scientist::monster_scientist(void)
m_flPitch = 100; // Slick
}
}
CLASSEXPORT(qreate_arcade, monster_scientist)

View file

@ -16,6 +16,7 @@ defs.h
../gs-entbase/server.src
valve/monster_rat.cpp
valve/monster_scientist.cpp
valve/monster_scientist_dead.cpp
../shared/decals.c
@ -47,11 +48,14 @@ valve/items.cpp
valve/item_longjump.cpp
valve/item_suit.cpp
valve/item_healthkit.cpp
valve/item_battery.cpp
valve/world_items.cpp
valve/ammo.cpp
../shared/valve/weapons.c
../shared/valve/weapon_common.c
spawn.c
vox.c
valve/client.c
client.c
@ -61,7 +65,6 @@ server.c
valve/damage.c
traceattack.c
vox.c
footsteps.c
flashlight.c

View file

@ -12,10 +12,12 @@ void Game_ClientConnect(void)
{
bprint(PRINT_HIGH, sprintf("%s connected\n", self.netname));
}
void Game_ClientDisconnect(void)
{
bprint(PRINT_HIGH, sprintf("%s disconnected\n", self.netname));
}
void Game_ClientKill(void)
{
@ -84,7 +86,6 @@ void Game_PutClientInServer(void)
player pl = (player)self;
entity spot;
pl.classname = "player";
pl.health = self.max_health = 100;
//forceinfokey(self, "*dead", "0");
@ -104,10 +105,13 @@ void Game_PutClientInServer(void)
pl.vDeath = Player_Death;
pl.iBleeds = TRUE;
forceinfokey(pl, "*spec", "0");
forceinfokey(self, "*deaths", ftos(self.deaths));
if (cvar("sv_playerslots") == 1) {
Game_DecodeChangeParms();
if (startspot) {
if (startspot != "") {
print(sprintf("[LEVEL] Startspot is \"%s\"\n", startspot));
setorigin(pl, Landmark_GetSpot());
} else {
spot = find(world, classname, "info_player_start");
@ -146,24 +150,22 @@ void Game_ParseClientCommand(string cmd)
{
tokenize(cmd);
/*if (argv(1) == "timeleft") {
if (argv(1) == "timeleft") {
float fTimeLeft = cvar("mp_timelimit") - (time / 60);
Vox_Singlecast(self, sprintf("we have %s minutes remaining", Vox_TimeToString(fTimeLeft)));
return;
}*/
string chat = substring(cmd, 4, strlen(cmd) - 4);
}
// Players talk to players, spectators to spectators.
if (argv(0) == "say") {
localcmd(sprintf("echo %s: %s\n", self.netname, chat));
SV_SendChat(self, chat, world, 0);
localcmd(sprintf("echo [SERVER] %s: %s\n", self.netname, argv(1)));
SV_SendChat(self, argv(1), world, 0);
return;
} else if (argv(0) == "say_team") {
localcmd(sprintf("echo [TEAM %d] %s: %s\n", self.team, self.netname, chat));
localcmd(sprintf("echo [TEAM %d] %s: %s\n", self.team, self.netname, argv(1)));
for (entity eFind = world; (eFind = find(eFind, classname, "player"));) {
if (eFind.team == self.team) {
SV_SendChat(self, chat, eFind, 1);
SV_SendChat(self, argv(1), eFind, 1);
}
}
return;

View file

@ -36,7 +36,7 @@ Generic function that applies damage, pain and suffering
void Damage_Apply(entity eTarget, entity eAttacker, float fDamage, vector vHitPos, int a)
{
// Apply the damage finally
if (eTarget.armor) {
if (eTarget.armor && fDamage > 0) {
float flArmor;
float flNewDamage;
@ -56,18 +56,27 @@ void Damage_Apply(entity eTarget, entity eAttacker, float fDamage, vector vHitPo
fDamage = rint(fDamage);
eTarget.health -= fDamage;
eTarget.dmg_take = fDamage;
eTarget.dmg_inflictor = eAttacker;
if (fDamage > 0) {
eTarget.dmg_take = fDamage;
eTarget.dmg_inflictor = eAttacker;
} else if (eTarget.max_health && eTarget.health > eTarget.max_health) {
eTarget.health = eTarget.max_health;
}
// Target is dead and a client....
if (eTarget.health <= 0) {
if (eTarget.flags & FL_CLIENT) {
//eTarget.fDeaths++;
//forceinfokey(eTarget, "*deaths", ftos(eTarget.fDeaths));
eTarget.deaths++;
forceinfokey(eTarget, "*deaths", ftos(eTarget.deaths));
}
if ((eTarget.flags & FL_CLIENT) && (eAttacker.flags & FL_CLIENT)) {
eAttacker.frags++;
if (eTarget == eAttacker) {
eAttacker.frags--;
} else {
eAttacker.frags++;
}
//Damage_CastOrbituary(eAttacker, eTarget, eAttacker.weapon);
}
}
@ -80,8 +89,8 @@ void Damage_Apply(entity eTarget, entity eAttacker, float fDamage, vector vHitPo
} else {
self.vPain(trace_surface_id);
}
if (self.iBleeds == TRUE) {
if (self.iBleeds == TRUE && fDamage > 0) {
Effect_CreateBlood(vHitPos, [0,0,0]);
}
@ -157,11 +166,6 @@ void Damage_Radius(vector org, entity eAttacker, float fDamage, float fRadius, i
if (fDiff > 0) {
Damage_Apply(c, eAttacker, fDamage, vecRealPos, 0);
/*if (c.movetype != MOVETYPE_NONE) {
vPush = vectoangles(vecRealPos - org);
makevectors(vPush);
c.velocity += (v_forward * fDamage * 5) + (v_up * fDamage * 2.5);
}*/
}
}

View file

@ -38,6 +38,8 @@ void Game_Input(void)
if (cvar("sv_cheats") == 1) {
player pl = (player)self;
if (self.impulse == 101) {
pl.health = 100;
pl.armor = 100;
Weapons_AddItem(pl, WEAPON_CROWBAR);
Weapons_AddItem(pl, WEAPON_GLOCK);
Weapons_AddItem(pl, WEAPON_PYTHON);

View file

@ -0,0 +1,60 @@
/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
class item_battery:CBaseEntity
{
void() item_battery;
virtual void() Respawn;
virtual void() touch;
};
void item_battery::touch(void)
{
if (other.classname == "player") {
if (other.armor >= 100) {
return;
}
/* Move this somewhere else? */
other.armor += 15;
if (other.armor > 100) {
other.armor = 100;
}
sound(other, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM);
if (cvar("sv_playerslots") == 1) {
remove(self);
} else {
Hide();
think = Respawn;
nextthink = time + 20.0f;
}
}
}
void item_battery::Respawn(void)
{
solid = SOLID_TRIGGER;
movetype = MOVETYPE_TOSS;
setmodel(this, m_oldModel);
setsize(this, [-8,-8,0], [8,8,48]);
setorigin(this, m_oldOrigin);
think = __NULL__;
nextthink = -1;
sound(this, CHAN_ITEM, "items/suitchargeok1.wav", 1, ATTN_NORM, 150);
droptofloor();
}
void item_battery::item_battery(void)
{
model = "models/w_battery.mdl";
CBaseEntity::CBaseEntity();
item_healthkit::Respawn();
}

View file

@ -8,5 +8,51 @@
class item_healthkit:CBaseEntity
{
void() item_healthkit;
virtual void() Respawn;
virtual void() touch;
};
void item_healthkit::touch(void)
{
if (other.classname == "player") {
if (other.health >= other.max_health) {
return;
}
Damage_Apply(other, this, -20, this.origin, TRUE);
sound(this, CHAN_ITEM, "items/smallmedkit1.wav", 1, ATTN_NORM);
if (cvar("sv_playerslots") == 1) {
remove(self);
} else {
Hide();
think = Respawn;
nextthink = time + 20.0f;
}
}
}
void item_healthkit::Respawn(void)
{
solid = SOLID_TRIGGER;
movetype = MOVETYPE_TOSS;
setmodel(this, m_oldModel);
setsize(this, [-8,-8,0], [8,8,48]);
setorigin(this, m_oldOrigin);
think = __NULL__;
nextthink = -1;
sound(this, CHAN_ITEM, "items/suitchargeok1.wav", 1, ATTN_NORM, 150);
droptofloor();
}
void item_healthkit::item_healthkit(void)
{
precache_sound("items/smallmedkit1.wav");
precache_sound("items/suitchargeok1.wav");
model = "models/w_medkit.mdl";
CBaseEntity::CBaseEntity();
item_healthkit::Respawn();
}

View file

@ -0,0 +1,18 @@
/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
class monster_scientist:CBaseMonster
{
void() monster_scientist;
};
void monster_scientist::monster_scientist(void)
{
model = "models/scientist.mdl";
CBaseMonster::CBaseMonster();
}

View file

@ -6,15 +6,17 @@
*
****/
void Player_Pain(void)
void Player_Pain(int hit)
{
}
void Player_Death(void)
void Player_Death(int hit)
{
player pl = (player)self;
pl.movetype = MOVETYPE_NONE;
pl.solid = SOLID_NOT;
pl.takedamage = DAMAGE_NO;
pl.health = pl.armor = pl.activeweapon = pl.g_items = 0;
PutClientInServer();
}

View file

@ -0,0 +1,35 @@
/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
/* This is one of those leftovers from trying to get a game out in time */
class world_items:CBaseTrigger
{
void() world_items;
};
void world_items::world_items(void)
{
int nfields = tokenize(__fullspawndata);
for (int i = 1; i < (nfields - 1); i += 2) {
switch (argv(i)) {
case "type":
float type = stof(argv(i+1));
switch (type) {
case 44:
spawnfunc_item_battery();
break;
case 45:
spawnfunc_item_suit();
break;
default:
}
default:
break;
}
}
}

View file

@ -6,6 +6,8 @@
*
****/
var int autocvar_cl_decals = TRUE;
#include "decals.h"
#define DECALS_MAX 30
@ -14,6 +16,9 @@
entity g_decals;
void Decals_Init(void)
{
if (serverkeyfloat("*bspversion") != 30) {
return;
}
entity nextdecal = spawn();
g_decals = nextdecal;
for (int i = 0; i <= DECALS_MAX; i++) {
@ -47,6 +52,9 @@ entity Decals_Next(vector pos)
void Decals_PlaceSmall(vector pos)
{
if (serverkeyfloat("*bspversion") != 30) {
return;
}
#ifdef CSQC
// TODO
#else
@ -60,6 +68,9 @@ void Decals_PlaceSmall(vector pos)
void Decals_PlaceBig(vector pos)
{
if (serverkeyfloat("*bspversion") != 30) {
return;
}
#ifdef CSQC
// TODO
#else
@ -73,6 +84,9 @@ void Decals_PlaceBig(vector pos)
void Decals_PlaceGlass(vector pos)
{
if (serverkeyfloat("*bspversion") != 30) {
return;
}
#ifdef CSQC
// TODO
#else
@ -86,6 +100,9 @@ void Decals_PlaceGlass(vector pos)
void Decals_PlaceScorch(vector pos)
{
if (serverkeyfloat("*bspversion") != 30) {
return;
}
#ifdef CSQC
// TODO
#else
@ -121,6 +138,10 @@ const string g_decalshader_add = \
float Decal_PreDraw(void)
{
if (!autocvar_cl_decals) {
return PREDRAW_NEXT;
}
adddecal(self.classname, self.origin, self.mins, self.maxs, self.color, 1.0f);
addentity(self);
return PREDRAW_NEXT;

View file

@ -31,6 +31,7 @@ class player
int shotgun_mag;
int crossbow_mag;
int rpg_mag;
int satchel_chg;
int cannon_mag;
#ifdef CSQC

View file

@ -31,6 +31,7 @@ class player
int shotgun_mag;
int crossbow_mag;
int rpg_mag;
int satchel_chg;
#ifdef CSQC
/* External model */

View file

@ -24,10 +24,8 @@ enum
void w_crossbow_precache(void)
{
#ifdef CSQC
precache_model("models/v_crossbow.mdl");
precache_model("models/crossbow_bolt.mdl");
#else
precache_model("models/v_crossbow.mdl");
precache_model("models/w_crossbow.mdl");
precache_model("models/p_crossbow.mdl");
precache_sound("weapons/xbow_reload1.wav");
@ -35,7 +33,6 @@ void w_crossbow_precache(void)
precache_sound("weapons/xbow_hit1.wav");
precache_sound("weapons/xbow_hitbod1.wav");
precache_sound("weapons/xbow_hitbod2.wav");
#endif
}
string w_crossbow_vmodel(void)
{
@ -90,23 +87,12 @@ void w_crossbow_holster(void)
void w_crossbow_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
if (pl.w_attack_next) {
return;
}
#ifdef CSQC
if (pl.a_ammo1) {
Weapons_ViewAnimation(CROSSBOW_FIRE1);
Weapons_PlaySound(pl, CHAN_ITEM, "weapons/xbow_reload1.wav", 1, ATTN_NORM);
} else {
Weapons_ViewAnimation(CROSSBOW_FIRE3);
}
Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/xbow_fire1.wav", 1, ATTN_NORM);
#endif
static void Crossbolt_Touch(void) {
#ifdef SSQC
static void Crossbolt_Touch(void) {
Effect_CreateSpark(self.origin, trace_plane_normal);
if (other.takedamage == DAMAGE_YES) {
@ -119,46 +105,49 @@ void w_crossbow_primary(void)
} else {
Weapons_PlaySound(self, CHAN_WEAPON, "weapons/xbow_hit1.wav", 1, ATTN_NORM);
}
#endif
remove(self);
}
Weapons_MakeVectors();
entity bolt = spawn();
#ifdef SSQC
static float bolt_nosend(entity pvsent, float fl) {
return FALSE;
}
bolt.SendEntity = bolt_nosend;
bolt.SendFlags = 1;
#else
setmodel(bolt, "models/crossbow_bolt.mdl");
bolt.drawmask = MASK_ENGINE;
#endif
setorigin(bolt, Weapons_GetCameraPos() + (v_forward * 16));
bolt.owner = self;
bolt.velocity = v_forward * 2000;
bolt.movetype = MOVETYPE_FLY;
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;
setsize(bolt, [0,0,0], [0,0,0]);
if (pl.crossbow_mag) {
Weapons_PlaySound(pl, CHAN_ITEM, "weapons/xbow_reload1.wav", 1, ATTN_NORM);
}
Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/xbow_fire1.wav", 1, ATTN_NORM);
#else
if (pl.a_ammo1) {
Weapons_ViewAnimation(CROSSBOW_FIRE1);
} else {
Weapons_ViewAnimation(CROSSBOW_FIRE3);
}
Weapons_ViewPunchAngle([-2,0,0]);
#endif
pl.w_attack_next = 0.75f;
pl.w_idle_next = 10.0f;
}
void w_crossbow_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
if (pl.w_attack_next) {
return;
}
/* Simple toggle of fovs */
if (pl.viewzoom == 1.0f) {
pl.viewzoom = 0.2;
pl.viewzoom = 0.2f;
} else {
pl.viewzoom = 1.0f;
}

View file

@ -62,7 +62,7 @@ void w_glock_draw(void)
}
void w_glock_holster(void)
{
#ifdef SSQC
#ifdef CSQC
Weapons_ViewAnimation(GLOCK_HOLSTER);
#endif
}

View file

@ -69,21 +69,29 @@ void w_hornetgun_primary(void)
if (pl.w_attack_next > 0.0) {
return;
}
#ifdef SSQC
Weapons_PlaySound(pl, CHAN_WEAPON, sprintf("agrunt/ag_fire%d.wav", floor(random(1,4))), 1, ATTN_NORM);
#else
Weapons_ViewAnimation(HORNETGUN_SHOOT);
#endif
pl.w_attack_next = 0.25;
pl.w_idle_next = 2.5f;
}
void w_hornetgun_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
if (pl.w_attack_next) {
return;
}
#ifdef SSQC
Weapons_PlaySound(pl, CHAN_WEAPON, sprintf("agrunt/ag_fire%d.wav", floor(random(1,4))), 1, ATTN_NORM);
#else
Weapons_ViewAnimation(HORNETGUN_SHOOT);
#endif
pl.w_attack_next = 0.1;
pl.w_idle_next = 2.5f;
}
@ -93,6 +101,7 @@ void w_hornetgun_reload(void)
}
void w_hornetgun_release(void)
{
#ifdef CSQC
int r;
player pl = (player)self;
if (pl.w_idle_next > 0.0) {
@ -115,6 +124,7 @@ void w_hornetgun_release(void)
pl.w_idle_next = 2.2f;
break;
}
#endif
}
void w_hornetgun_crosshair(void)
{

View file

@ -67,7 +67,9 @@ void w_mp5_draw(void)
void w_mp5_holster(void)
{
#ifdef CSQC
Weapons_ViewAnimation(MP5_DRAW);
#endif
}
void w_mp5_primary(void)
@ -119,7 +121,7 @@ void w_mp5_secondary(void)
static void Grenade_ExplodeTouch(void) {
Effect_CreateExplosion( self.origin );
Damage_Radius( self.origin, self, 100, 256, TRUE );
Damage_Radius( self.origin, self.owner, 100, 100 * 2.5f, TRUE );
sound( self, CHAN_WEAPON, sprintf( "weapons/explode%d.wav", floor( random() * 2 ) + 3 ), 1, ATTN_NORM );
remove(self);
}

View file

@ -23,7 +23,7 @@ void w_python_precache(void)
precache_model("models/v_357.mdl");
precache_model("models/w_357.mdl");
precache_model("models/p_357.mdl");
precache_sound("weapons/357_shot1.wav");
precache_sound("weapons/357_shot2.wav");
}
@ -62,7 +62,9 @@ void w_python_draw(void)
void w_python_holster(void)
{
#ifdef CSQC
Weapons_ViewAnimation(PYTHON_HOLSTER);
#endif
}
void w_python_primary(void)
{
@ -73,17 +75,17 @@ void w_python_primary(void)
#ifdef SSQC
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 40, [0.00873, 0.00873]);
#endif
Weapons_ViewAnimation(PYTHON_FIRE1);
Weapons_ViewPunchAngle([-10,0,0]);
if (random() < 0.5) {
Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/357_shot1.wav", 1, ATTN_NORM);
} else {
Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/357_shot2.wav", 1, ATTN_NORM);
}
#else
Weapons_ViewAnimation(PYTHON_FIRE1);
Weapons_ViewPunchAngle([-10,0,0]);
#endif
pl.w_attack_next = 0.75f;
pl.w_idle_next = 10.0f;
}
@ -107,19 +109,24 @@ void w_python_reload(void)
if (pl.w_attack_next > 0.0) {
return;
}
#ifdef CSQC
Weapons_ViewAnimation(PYTHON_RELOAD);
#endif
pl.w_attack_next = 3.25f;
pl.w_idle_next = 10.0f;
}
void w_python_release(void)
{
#ifdef CSQC
player pl = (player)self;
if (pl.w_idle_next > Math_Time()) {
return;
}
int r = floor(random(0,3));
switch (r) {
case 0:
Weapons_ViewAnimation(PYTHON_IDLE1);
@ -133,6 +140,7 @@ void w_python_release(void)
}
pl.w_idle_next = Math_Time() + 15.0f;
#endif
}
void w_python_crosshair(void)
{

View file

@ -23,43 +23,9 @@ enum
RADIO_HOLSTER
};
void w_satchel_draw(void)
{
#ifdef CSQC
Weapons_ViewAnimation(SATCHEL_DRAW);
#else
player pl = (player)self;
Weapons_UpdateAmmo(pl, __NULL__, pl.ammo_satchel, __NULL__);
#endif
}
void w_satchel_holster(void)
{
}
void w_satchel_primary(void)
{
}
void w_satchel_secondary(void)
{
}
void w_satchel_reload(void)
{
}
void w_satchel_release(void)
{
}
void w_satchel_precache(void)
{
}
string w_satchel_vmodel(void)
{
return "models/v_satchel.mdl";
return "models/v_satchel_radio.mdl";
}
string w_satchel_wmodel(void)
{
@ -73,6 +39,130 @@ string w_satchel_deathmsg(void)
{
return "";
}
void w_satchel_precache(void)
{
precache_model("models/w_satchel.mdl");
precache_model("models/v_satchel.mdl");
precache_model("models/v_satchel_radio.mdl");
precache_model("models/p_satchel.mdl");
}
void w_satchel_draw(void)
{
#ifdef CSQC
Weapons_ViewAnimation(SATCHEL_DRAW);
#else
player pl = (player)self;
Weapons_UpdateAmmo(pl, pl.satchel_chg, pl.ammo_satchel, __NULL__);
#endif
}
void w_satchel_holster(void)
{
}
#ifdef SSQC
void s_satchel_drop(entity master, vector src, vector vel)
{
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];
setmodel(satch, "models/w_satchel.mdl");
setsize(satch, [-4,-4,-4], [4,4,4]);
setorigin(satch, src);
}
void s_satchel_detonate(entity master)
{
for (entity b = world; (b = find(b, ::classname, "satchel"));) {
if (b.owner == master) {
Effect_CreateExplosion(b.origin);
Damage_Radius(b.origin, master, 150, 150 * 2.5f, TRUE);
sound(b, CHAN_WEAPON, sprintf( "weapons/explode%d.wav", floor( random() * 2 ) + 3 ), 1, ATTN_NORM);
remove(b);
}
}
}
#endif
void w_satchel_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next) {
return;
}
#ifdef SSQC
if (!pl.satchel_chg) {
vector throw;
Weapons_MakeVectors();
throw = pl.velocity + (v_forward * 274);
s_satchel_drop(self, pl.origin, throw);
pl.satchel_chg++;
} else {
s_satchel_detonate(pl);
pl.satchel_chg = 0;
}
Weapons_UpdateAmmo(pl, pl.satchel_chg, pl.ammo_satchel, __NULL__);
#else
if (!pl.a_ammo1) {
Weapons_ViewAnimation(RADIO_DRAW);
} else {
Weapons_ViewAnimation(RADIO_USE);
}
#endif
pl.w_attack_next = 1.0f;
pl.w_idle_next = 2.5f;
}
void w_satchel_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next) {
return;
}
#ifdef SSQC
vector throw;
Weapons_MakeVectors();
throw = pl.velocity + (v_forward * 274);
s_satchel_drop(self, pl.origin, throw);
pl.satchel_chg++;
Weapons_UpdateAmmo(pl, pl.satchel_chg, pl.ammo_satchel, __NULL__);
#else
Weapons_ViewAnimation(RADIO_DRAW);
#endif
pl.w_attack_next = 1.0f;
pl.w_idle_next = 2.5f;
}
void w_satchel_reload(void)
{
}
void w_satchel_release(void)
{
#ifdef CSQC
player pl = (player)self;
if (pl.w_idle_next) {
return;
}
Weapons_ViewAnimation(RADIO_FIDGET);
pl.w_idle_next = 15.0f;
#endif
}
void w_satchel_hudpic(int s, vector pos)
{
@ -85,7 +175,6 @@ void w_satchel_hudpic(int s, vector pos)
#endif
}
weapon_t w_satchel =
{
ITEM_SATCHEL,

View file

@ -57,19 +57,17 @@ void w_shotgun_draw(void)
void w_shotgun_holster(void)
{
#ifdef CSQC
Weapons_ViewAnimation(SHOTGUN_HOLSTER);
#endif
}
void w_shotgun_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
if (pl.w_attack_next) {
return;
}
Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/sbarrel1.wav", 1, ATTN_NORM);
Weapons_ViewAnimation(SHOTGUN_FIRE1);
Weapons_ViewPunchAngle([-5,0,0]);
#ifdef SSQC
/* Singleplayer is more accurate */
if (cvar("sv_playerslots") == 1) {
@ -77,15 +75,19 @@ void w_shotgun_primary(void)
} else {
TraceAttack_FireBullets(4, pl.origin + pl.view_ofs, 5, [0.08716,0.04362]);
}
Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/sbarrel1.wav", 1, ATTN_NORM);
#else
Weapons_ViewAnimation(SHOTGUN_FIRE1);
Weapons_ViewPunchAngle([-5,0,0]);
#endif
pl.w_attack_next = Math_Time() + 0.75;
pl.w_idle_next = Math_Time() + 2.5f;
pl.w_attack_next = 0.75;
pl.w_idle_next = 2.5f;
}
void w_shotgun_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
if (pl.w_attack_next) {
return;
}
@ -96,11 +98,12 @@ void w_shotgun_secondary(void)
} else {
TraceAttack_FireBullets(8, pl.origin + pl.view_ofs, 5, [0.17365,0.04362]);
}
#endif
Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/dbarrel1.wav", 1, ATTN_NORM);
#else
Weapons_ViewAnimation(SHOTGUN_FIRE2);
Weapons_ViewPunchAngle([-10,0,0]);
#endif
pl.w_attack_next = 1.5f;
pl.w_idle_next = 2.5f;
}
@ -110,8 +113,9 @@ void w_shotgun_reload(void)
}
void w_shotgun_release(void)
{
#ifdef CSQC
player pl = (player)self;
if (pl.w_idle_next > 0.0) {
if (pl.w_idle_next) {
return;
}
@ -129,6 +133,7 @@ void w_shotgun_release(void)
}
pl.w_idle_next = 15.0f;
#endif
}
void w_shotgun_crosshair(void)
{

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,15 +0,0 @@
!!ver 110
#ifdef VERTEX_SHADER
void main ()
{
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
void main ()
{
discard;
}
#endif

View file

@ -48,7 +48,6 @@ varying vec2 lm_c;
float m = (diffuse_f.r + diffuse_f.g + diffuse_f.b) / 3.0f;
diffuse_f.rgb = vec3(m,m,m);
#endif
gl_FragColor = diffuse_f;
}

Binary file not shown.

Binary file not shown.