Added item_suit and item_longjump... they do not do anything interesting yet. Decals: Added glass break decals upon impact Damage: Brush-entity radius damage should to work better now Also seperated the weapons table from generic weapon entry functions. This should make maintaining mods easier Fixed references from sv_clientslots to sv_playerslots. My brain gets confused between the Quake games at this point. I blame FTE Fixed sprite animation cycle length check. It attempted to play one more frame than any sprite ever has. Needs more heavy testing?
179 lines
3.6 KiB
C
179 lines
3.6 KiB
C
/***
|
|
*
|
|
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
|
|
*
|
|
* See the file LICENSE attached with the sources for usage details.
|
|
*
|
|
****/
|
|
|
|
#include "decals.h"
|
|
|
|
#define DECALS_MAX 30
|
|
|
|
#ifdef SSQC
|
|
entity g_decals;
|
|
void Decals_Init(void)
|
|
{
|
|
entity nextdecal = spawn();
|
|
g_decals = nextdecal;
|
|
for (int i = 0; i <= DECALS_MAX; i++) {
|
|
nextdecal.classname = "tempdecal";
|
|
nextdecal.owner = spawn();
|
|
|
|
if (i == DECALS_MAX) {
|
|
nextdecal.owner = g_decals;
|
|
} else {
|
|
nextdecal = nextdecal.owner;
|
|
}
|
|
}
|
|
}
|
|
|
|
entity Decals_Next(vector pos)
|
|
{
|
|
entity ret = g_decals;
|
|
g_decals = g_decals.owner;
|
|
|
|
/* Check for a tempdecal within a radius of 8 units and overwrite that one
|
|
* instead */
|
|
for (entity b = world; (b = find(b, ::classname, "tempdecal"));) {
|
|
if (vlen(b.origin - pos) < 8) {
|
|
return b;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
void Decals_PlaceSmall(vector pos)
|
|
{
|
|
#ifdef CSQC
|
|
// TODO
|
|
#else
|
|
entity decal = Decals_Next(pos);
|
|
setorigin(decal, pos);
|
|
decal.texture = sprintf("{shot%d", floor(random(1,6)));
|
|
decal.think = infodecal;
|
|
decal.nextthink = time /*+ 0.1f*/;
|
|
#endif
|
|
}
|
|
|
|
void Decals_PlaceBig(vector pos)
|
|
{
|
|
#ifdef CSQC
|
|
// TODO
|
|
#else
|
|
entity decal = Decals_Next(pos);
|
|
setorigin(decal, pos);
|
|
decal.texture = sprintf("{bigshot%d", floor(random(1,6)));
|
|
decal.think = infodecal;
|
|
decal.nextthink = time /*+ 0.1f*/;
|
|
#endif
|
|
}
|
|
|
|
void Decals_PlaceGlass(vector pos)
|
|
{
|
|
#ifdef CSQC
|
|
// TODO
|
|
#else
|
|
entity decal = Decals_Next(pos);
|
|
setorigin(decal, pos);
|
|
decal.texture = sprintf("{break%d", floor(random(1,4)));
|
|
decal.think = infodecal;
|
|
decal.nextthink = time /*+ 0.1f*/;
|
|
#endif
|
|
}
|
|
|
|
void Decals_PlaceScorch(vector pos)
|
|
{
|
|
#ifdef CSQC
|
|
// TODO
|
|
#else
|
|
entity decal = Decals_Next(pos);
|
|
setorigin(decal, pos);
|
|
decal.texture = sprintf("{scorch%d", floor(random(1,4)));
|
|
decal.think = infodecal;
|
|
decal.nextthink = time /*+ 0.1f*/;
|
|
#endif
|
|
}
|
|
|
|
#ifdef CSQC
|
|
|
|
const string g_decalshader = \
|
|
"{\n" \
|
|
"polygonOffset\n" \
|
|
"{\n" \
|
|
"clampmap %s\n" \
|
|
"rgbgen vertex\n" \
|
|
"blendfunc GL_ZERO GL_SRC_COLOR\n" \
|
|
"}\n" \
|
|
"}";
|
|
|
|
const string g_decalshader_add = \
|
|
"{\n" \
|
|
"polygonOffset\n" \
|
|
"{\n" \
|
|
"clampmap %s\n" \
|
|
"rgbgen vertex\n" \
|
|
"blendfunc add\n" \
|
|
"}\n" \
|
|
"}";
|
|
|
|
float Decal_PreDraw(void)
|
|
{
|
|
adddecal(self.classname, self.origin, self.mins, self.maxs, self.color, 1.0f);
|
|
addentity(self);
|
|
return PREDRAW_NEXT;
|
|
}
|
|
|
|
void Decal_Parse(void)
|
|
{
|
|
string decalname = "";
|
|
string decalshader = "";
|
|
|
|
self.origin[0] = readcoord();
|
|
self.origin[1] = readcoord();
|
|
self.origin[2] = readcoord();
|
|
|
|
self.angles[0] = readcoord();
|
|
self.angles[1] = readcoord();
|
|
self.angles[2] = readcoord();
|
|
self.classname = readstring();
|
|
|
|
self.color = [1,1,1];
|
|
|
|
for (int i = 0; i < g_decalwad.length; i++) {
|
|
if (self.classname == g_decalwad[i].name) {
|
|
self.color[0] = (g_decalwad[i].color[0] / 255);
|
|
self.color[1] = (g_decalwad[i].color[1] / 255);
|
|
self.color[2] = (g_decalwad[i].color[2] / 255);
|
|
self.style = g_decalwad[i].flags;
|
|
break;
|
|
}
|
|
}
|
|
|
|
self.size = drawgetimagesize(self.classname);
|
|
|
|
if (serverkeyfloat("*bspversion") == 30) {
|
|
decalname = sprintf("decal_%s", self.classname);
|
|
|
|
if (self.style & DFLAG_ADDITIVE) {
|
|
decalshader = sprintf(g_decalshader_add, self.classname);
|
|
} else {
|
|
decalshader = sprintf(g_decalshader, self.classname);
|
|
}
|
|
shaderforname(decalname, decalshader);
|
|
self.classname = decalname;
|
|
}
|
|
|
|
makevectors(self.angles);
|
|
float surf = getsurfacenearpoint(world, self.origin);
|
|
vector s_dir = getsurfacepointattribute(world, surf, 0, SPA_S_AXIS);
|
|
vector t_dir = getsurfacepointattribute(world, surf, 0, SPA_T_AXIS);
|
|
self.mins = v_up / self.size[0];
|
|
self.maxs = t_dir / self.size[1];
|
|
|
|
self.predraw = Decal_PreDraw;
|
|
self.drawmask = MASK_ENGINE;
|
|
}
|
|
#endif
|