nuclide/src/shared/spraylogo.cpp

167 lines
4.1 KiB
C++

/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef SSQC
void
Spray_RemoveAll(entity entOwner)
{
for (entity eFind = world;(eFind = find(eFind, classname, "Spray"));) {
if (eFind.owner == entOwner) {
remove(eFind);
}
}
}
float
Spray_SendEntity(entity ePVSEnt, float fChanged)
{
WriteByte(MSG_ENTITY, ENT_SPRAY);
WriteCoord(MSG_ENTITY, self.origin[0]);
WriteCoord(MSG_ENTITY, self.origin[1]);
WriteCoord(MSG_ENTITY, self.origin[2]);
WriteCoord(MSG_ENTITY, self.angles[0]);
WriteCoord(MSG_ENTITY, self.angles[1]);
WriteCoord(MSG_ENTITY, self.angles[2]);
WriteEntity(MSG_ENTITY, self.owner);
return TRUE;
}
void
CSEv_Spraylogo(void)
{
entity spray;
vector src;
vector co;
src = self.origin + self.view_ofs;
makevectors(self.v_angle);
traceline(src, src + v_forward * 128, FALSE, self);
if (trace_fraction >= 1.0f) {
return;
}
/* we only allow one active spray */
Spray_RemoveAll(self);
/* spawn the new one */
spray = spawn();
spray.classname = "Spray";
spray.owner = self;
spray.solid = SOLID_NOT;
setorigin(spray, trace_endpos);
/* calculate the rotation by taking our current view and mapping it
* against the surface we're looking at */
makevectors([self.v_angle[0] * -1, self.v_angle[1], self.v_angle[2]]);
co = v_forward -(v_forward * trace_plane_normal) * trace_plane_normal;
/* quick fix */
if (trace_plane_normal[2] == 0) {
co = '0 0 1';
}
/* apply the angles and apply networking */
spray.angles = vectoangles(co, trace_plane_normal);
spray.SendEntity = Spray_SendEntity;
spray.SendFlags = 1;
sound(self, CHAN_VOICE, "player/sprayer.wav", 1.0, ATTN_NORM);
}
#endif
#ifdef CSQC
class CSpraylogo
{
vector m_vecPosition;
vector m_vecAngles;
int m_iOwnerID;
string m_strName;
string m_m_strPath;
int m_iInitialized;
virtual float(void) predraw;
};
const string g_spray_mat = \
"{\n" \
"cull disable\n" \
"polygonOffset\n" \
"{\n" \
"map $rt:%s\n" \
"blendfunc blend\n" \
"rgbGen vertex\n" \
"}\n" \
"}";
float
CSpraylogo::predraw(void)
{
int iSize;
/* TODO: Don't query this & width/height every frame */
iSize = getplayerkeyblob(m_iOwnerID, "spray", __NULL__, 0);
if (iSize <= 0) {
return PREDRAW_NEXT;
}
if (m_iInitialized == FALSE) {
void *image;
m_iInitialized = TRUE;
/* load the blob */
image = memalloc(iSize + 1);
getplayerkeyblob(m_iOwnerID, "spray", image, iSize);
r_uploadimage(m_m_strPath, 64, 64, image, iSize, 0);
memfree(image);
/* push the material into memory */
shaderforname(m_strName, sprintf(g_spray_mat, m_m_strPath));
} else {
vector width;
vector height;
vector light;
light = getlight(m_vecPosition) / 255;
/* TODO: handle spray dimensions independently */
makevectors(m_vecAngles);
width = v_up / 64;
height = v_forward / 64;
adddecal(m_strName, m_vecPosition, width, height, light, 1.0f);
addentity(this);
}
return PREDRAW_NEXT;
}
void
Spray_Parse(void)
{
spawnfunc_CSpraylogo();
CSpraylogo spSelf =(CSpraylogo)self;
spSelf.drawmask = MASK_ENGINE;
spSelf.m_vecPosition[0] = readcoord();
spSelf.m_vecPosition[1] = readcoord();
spSelf.m_vecPosition[2] = readcoord();
spSelf.m_vecAngles[0] = readcoord();
spSelf.m_vecAngles[1] = readcoord();
spSelf.m_vecAngles[2] = readcoord();
spSelf.m_iInitialized = FALSE;
spSelf.m_iOwnerID = readentitynum() - 1;
spSelf.m_strName = sprintf("spray_%i", spSelf.m_iOwnerID);
spSelf.m_m_strPath = sprintf("simg_%i", spSelf.m_iOwnerID);
}
#endif