diff --git a/Source/Client/Entities.c b/Source/Client/Entities.c index 50abcb69..8c7bf9f1 100755 --- a/Source/Client/Entities.c +++ b/Source/Client/Entities.c @@ -122,6 +122,30 @@ void CSQC_Ent_Update( float flIsNew ) { self.classname = sprintf( "spray_%s", sLogo ); self.predraw = Effect_Spraypaint; self.drawmask = MASK_ENGINE; + } else if ( fEntType == ENT_DECAL ) { + string decalname = ""; + string decalshader = ""; + + self.origin_x = readcoord(); + self.origin_y = readcoord(); + self.origin_z = readcoord(); + + self.angles_x = readcoord(); + self.angles_y = readcoord(); + self.angles_z = readcoord(); + + self.color_x = 1.0f - ( readbyte() / 255 ); + self.color_y = 1.0f - ( readbyte() / 255 ); + self.color_z = 1.0f - ( readbyte() / 255 ); + self.classname = readstring(); + decalname = sprintf("decal_%s", self.classname); + decalshader = sprintf("{\npolygonOffset\n{\nclampmap %s\nblendFunc filter\n}\n}", self.classname); + shaderforname(decalname, decalshader); + self.size = drawgetimagesize(self.classname); + self.classname = decalname; + + self.predraw = Effect_Decal; + self.drawmask = MASK_ENGINE; } } diff --git a/Source/Globals.h b/Source/Globals.h index 1a5c2589..6f8aa9a5 100755 --- a/Source/Globals.h +++ b/Source/Globals.h @@ -87,7 +87,8 @@ enum { ENT_PLAYER = 1, ENT_AMBIENTSOUND, ENT_SPRITE, - ENT_SPRAY + ENT_SPRAY, + ENT_DECAL }; enum { diff --git a/Source/Server/InfoDecal.c b/Source/Server/InfoDecal.c new file mode 100644 index 00000000..16904063 --- /dev/null +++ b/Source/Server/InfoDecal.c @@ -0,0 +1,115 @@ +/* + Copyright 2016-2018 Marco "eukara" Hladik + + MIT LICENSE + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* decal name */ +.string texture; + +/* We need to save trace infos temporarily in order to figure out what to + * project the decal against. Half-Life's infodecal entity only stores origin, + * but not angles. So we have to figure them out ourselves. */ +typedef struct { + float fraction; + vector normal; + vector endpos; +} traced_t; + +float infodecal_send(entity pvsent, float cflags) +{ + WriteByte(MSG_ENTITY, ENT_DECAL); + 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]); + /* Figure this thing out */ + WriteByte(MSG_ENTITY, 255); + WriteByte(MSG_ENTITY, 0); + WriteByte(MSG_ENTITY, 0); + WriteString(MSG_ENTITY, self.texture ); + return TRUE; +} + +void infodecal(void) +{ + traced_t tmp[6]; + int i = 0; + int b = 0; + float frac = 1.0f; + vector vpos = self.origin; + + /* Unrolled because I'm lazy */ + makevectors([0, 0, 0]); + traceline(vpos + (v_forward * -1), vpos + (v_forward * 128), 1, self); + tmp[0].fraction = trace_fraction; + tmp[0].normal = trace_plane_normal; + tmp[0].endpos = trace_endpos; + traceline(vpos + (v_forward * 1), vpos + (v_forward * -128), 1, self); + tmp[1].fraction = trace_fraction; + tmp[1].normal = trace_plane_normal; + tmp[1].endpos = trace_endpos; + traceline(vpos + (v_right * -1), vpos + (v_right * 128), 1, self); + tmp[2].fraction = trace_fraction; + tmp[2].normal = trace_plane_normal; + tmp[2].endpos = trace_endpos; + traceline(vpos + (v_right * 1), vpos + (v_right * -128), 1, self); + tmp[3].fraction = trace_fraction; + tmp[3].normal = trace_plane_normal; + tmp[3].endpos = trace_endpos; + traceline(vpos + (v_up * -1), vpos + (v_up * 128), 1, self); + tmp[4].fraction = trace_fraction; + tmp[4].normal = trace_plane_normal; + tmp[4].endpos = trace_endpos; + traceline(vpos + (v_up * 1), vpos + (v_up * -128), 1, self); + tmp[5].fraction = trace_fraction; + tmp[5].normal = trace_plane_normal; + tmp[5].endpos = trace_endpos; + + for (i = 0; i < 6; i++) { + if ( tmp[i].fraction < frac ) { + frac = tmp[i].fraction; + b = i; + } + } + + if (frac == 1.0f) { + objerror(sprintf("infodecal tracing failed at %v\n", self.origin)); + return; + } + + makevectors(vectoangles(tmp[b].endpos - self.origin )); + vector cpl = v_forward - (v_forward * tmp[b].normal) * tmp[b].normal; + + if (tmp[b].normal[2] == 0) { + cpl = [0, 0, 1]; + } + + self.angles = vectoangles(cpl, tmp[b].normal); + self.solid = SOLID_NOT; + self.pvsflags = PVSF_NOREMOVE | PVSF_IGNOREPVS; + self.SendEntity = infodecal_send; + self.SendFlags = 1; +} diff --git a/Source/Server/Player.c b/Source/Server/Player.c index 68b3b12b..7d80e8f2 100755 --- a/Source/Server/Player.c +++ b/Source/Server/Player.c @@ -94,7 +94,7 @@ void Player_Death( int iHitBody ) { setsize( eCorpse, self.mins, self.maxs ); eCorpse.angles = [ 0, self.angles_y, 0 ]; eCorpse.movetype = MOVETYPE_BOUNCE; - + // Drop primary weapon as well as the bomb if present if ( self.fSlotPrimary ) { Weapon_DropWeapon( SLOT_PRIMARY ); diff --git a/Source/Server/progs.src b/Source/Server/progs.src index ec776e98..28dc4b11 100755 --- a/Source/Server/progs.src +++ b/Source/Server/progs.src @@ -69,6 +69,7 @@ FuncDoorRotating.c FuncVehicle.c ArmouryEntity.c AmbientSound.c +InfoDecal.c Bot/Bot.h diff --git a/Source/Shared/Effects.c b/Source/Shared/Effects.c index 6da38fc8..deadf3d0 100755 --- a/Source/Shared/Effects.c +++ b/Source/Shared/Effects.c @@ -417,3 +417,12 @@ void Effect_BreakModel( vector vMins, vector vMaxs, vector vVel, float fStyle ) } #endif } + +#ifdef CSQC +float Effect_Decal( void ) { + makevectors( self.angles ); + adddecal( self.classname, self.origin, v_up / self.size[0], v_forward / self.size[1], self.color, 1.0f ); + addentity( self ); + return PREDRAW_NEXT; +} +#endif diff --git a/freecs/csprogs.dat b/freecs/csprogs.dat index f464e418..6cabe2fc 100644 Binary files a/freecs/csprogs.dat and b/freecs/csprogs.dat differ diff --git a/freecs/default.cfg b/freecs/default.cfg index d08293b9..401d2dab 100755 --- a/freecs/default.cfg +++ b/freecs/default.cfg @@ -75,7 +75,7 @@ seta sv_accelerate "8" seta con_textsize "12" seta con_color "255 170 0" seta vgui_color "255 170 0" -seta cross_color 0 255 0 +seta cross_color "0 255 0" hostname "FreeCS Server" seta vid_conautoscale "1" @@ -93,6 +93,7 @@ seta r_imageexensions "tga bmp pcx" seta gl_blacklist_debug_glsl 0 seta vid_conautoscale "1" seta scr_conalpha "1" +seta scr_sshot_type "tga" seta con_notifylines "0" seta con_logcenterprint "0" seta maxplayers "8" diff --git a/freecs/menu.dat b/freecs/menu.dat index a7ba655a..6fee065b 100755 Binary files a/freecs/menu.dat and b/freecs/menu.dat differ diff --git a/freecs/progs.dat b/freecs/progs.dat index 113cc5e4..83087fe9 100644 Binary files a/freecs/progs.dat and b/freecs/progs.dat differ