nuclide/Source/shared/decals.c
Marco Hladik 9d869d5c0a Fix damage overlay for splitscreen games
Starting to mess with decal colours. DO NOT TOUCH. This is awaiting engine fixes potentially.
2019-03-12 01:22:50 +01:00

148 lines
3.1 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_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" \
"}";
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();
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);
break;
}
}
self.size = drawgetimagesize(self.classname);
if (serverkeyfloat("*bspversion") == 30) {
decalname = sprintf("decal_%s", self.classname);
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