nuclide/Source/shared/decals.c
Marco Hladik 9ce909e291 - 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
2019-03-19 20:01:24 +01:00

200 lines
4 KiB
C

/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
var int autocvar_cl_decals = TRUE;
#include "decals.h"
#define DECALS_MAX 30
#ifdef SSQC
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++) {
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)
{
if (serverkeyfloat("*bspversion") != 30) {
return;
}
#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)
{
if (serverkeyfloat("*bspversion") != 30) {
return;
}
#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)
{
if (serverkeyfloat("*bspversion") != 30) {
return;
}
#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)
{
if (serverkeyfloat("*bspversion") != 30) {
return;
}
#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)
{
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;
}
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