diff --git a/platform/test_maps.pk3dir/maps/test_dlights.bsp b/platform/test_maps.pk3dir/maps/test_dlights.bsp new file mode 100644 index 00000000..5d4761bc Binary files /dev/null and b/platform/test_maps.pk3dir/maps/test_dlights.bsp differ diff --git a/platform/test_maps.pk3dir/maps/test_dlights.map b/platform/test_maps.pk3dir/maps/test_dlights.map new file mode 100644 index 00000000..1dfc869c --- /dev/null +++ b/platform/test_maps.pk3dir/maps/test_dlights.map @@ -0,0 +1,149 @@ + +// entity 0 +{ +"classname" "worldspawn" +// brush 0 +{ +( 248 192 -64 ) ( 248 -192 -64 ) ( -264 192 -64 ) measure/floor [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( 256 192 8 ) ( -256 192 8 ) ( 256 192 0 ) measure/floor [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 256 192 8 ) ( 256 192 0 ) ( 256 -192 8 ) measure/floor [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( -256 -192 -128 ) ( 256 -192 -128 ) ( -256 192 -128 ) measure/floor [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( -256 -192 0 ) ( -256 -192 8 ) ( 256 -192 0 ) measure/floor [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( -256 -192 0 ) ( -256 192 0 ) ( -256 -192 8 ) measure/floor [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +// brush 1 +{ +( 248 192 192 ) ( 248 -192 192 ) ( -264 192 192 ) measure/floor [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( 256 192 264 ) ( -256 192 264 ) ( 256 192 256 ) measure/floor [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 256 192 264 ) ( 256 192 256 ) ( 256 -192 264 ) measure/floor [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( -256 -192 128 ) ( 256 -192 128 ) ( -256 192 128 ) measure/floor [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( -256 -192 256 ) ( -256 -192 264 ) ( 256 -192 256 ) measure/floor [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( -256 -192 256 ) ( -256 192 256 ) ( -256 -192 264 ) measure/floor [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +// brush 2 +{ +( 184 192 192 ) ( 184 -192 192 ) ( -328 192 192 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( 192 192 264 ) ( -320 192 264 ) ( 192 192 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( -256 192 8 ) ( -256 192 0 ) ( -256 -192 8 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( -768 -192 -128 ) ( -256 -192 -128 ) ( -768 192 -128 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( -320 -192 256 ) ( -320 -192 264 ) ( 192 -192 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( -320 -192 256 ) ( -320 192 256 ) ( -320 -192 264 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +// brush 3 +{ +( 760 192 192 ) ( 760 -192 192 ) ( 248 192 192 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( 768 192 264 ) ( 256 192 264 ) ( 768 192 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 320 192 8 ) ( 320 192 0 ) ( 320 -192 8 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( -192 -192 -128 ) ( 320 -192 -128 ) ( -192 192 -128 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( 256 -192 256 ) ( 256 -192 264 ) ( 768 -192 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 256 -192 256 ) ( 256 192 256 ) ( 256 -192 264 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +// brush 4 +{ +( 184 -192 192 ) ( 184 -576 192 ) ( -328 -192 192 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( 192 -192 264 ) ( -320 -192 264 ) ( 192 -192 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 320 96 8 ) ( 320 96 0 ) ( 320 -288 8 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( -768 -576 -128 ) ( -256 -576 -128 ) ( -768 -192 -128 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( 272 -256 256 ) ( 272 -256 264 ) ( 784 -256 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( -320 -576 256 ) ( -320 -192 256 ) ( -320 -576 264 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +// brush 5 +{ +( 184 256 192 ) ( 184 -128 192 ) ( -328 256 192 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( 192 256 264 ) ( -320 256 264 ) ( 192 256 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 320 544 8 ) ( 320 544 0 ) ( 320 160 8 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( -768 -128 -128 ) ( -256 -128 -128 ) ( -768 256 -128 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( 272 192 256 ) ( 272 192 264 ) ( 784 192 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( -320 -128 256 ) ( -320 256 256 ) ( -320 -128 264 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +} +// entity 1 +{ +"classname" "info_player_start" +} +// entity 2 +{ +"classname" "info_player_deathmatch" +} + +// entity 5 +{ +"classname" "func_button" +"target" "foobar2" +// brush 0 +{ +( 88 -40 0 ) ( 88 -80 0 ) ( 48 -40 0 ) next/rusty7 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( 88 -48 72 ) ( 48 -48 72 ) ( 88 -48 64 ) next/rusty7 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 80 -40 72 ) ( 80 -40 64 ) ( 80 -80 72 ) next/rusty7 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 48 -80 -64 ) ( 88 -80 -64 ) ( 48 -40 -64 ) next/rusty7 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( 40 -80 64 ) ( 40 -80 72 ) ( 80 -80 64 ) next/rusty7 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 48 -80 64 ) ( 48 -40 64 ) ( 48 -80 72 ) next/rusty7 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +} +// entity 6 +{ +"classname" "func_button" +"target" "foobar1" +// brush 0 +{ +( 88 152 0 ) ( 88 112 0 ) ( 48 152 0 ) next/rusty7 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( 88 144 72 ) ( 48 144 72 ) ( 88 144 64 ) next/rusty7 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 80 152 72 ) ( 80 152 64 ) ( 80 112 72 ) next/rusty7 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 48 112 -64 ) ( 88 112 -64 ) ( 48 152 -64 ) next/rusty7 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( 40 112 64 ) ( 40 112 72 ) ( 80 112 64 ) next/rusty7 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 48 112 64 ) ( 48 152 64 ) ( 48 112 72 ) next/rusty7 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +} + +{ +"classname" "point_message" +"origin" "-160.000000 128.000000 32.000000" +"message" "White dynamic light with no style pattern." +} +{ +"classname" "dynamic_light" +"origin" "-192.000000 128.000000 64.000000" +"_light" "255 255 255" +"brightness" "250" +} + +{ +"classname" "point_message" +"origin" "-160.000000 -64.000000 32.000000" +"message" "Small blinking yellow dynamic light." +} +{ +"classname" "dynamic_light" +"origin" "-192.000000 -64.000000 64.000000" +"style" "9" +"_light" "255 255 128" +"brightness" "150" +} + +{ +"classname" "point_message" +"origin" "120.000000 128.000000 32.000000" +"message" "Toggable white flickering dynamic light." +} +{ +"classname" "dynamic_light" +"origin" "192.000000 128.000000 64.000000" +"targetname" "foobar1" +"style" "1" +"_light" "255 255 255" +"brightness" "250" +} + +{ +"classname" "point_message" +"origin" "120.000000 -64.000000 32.000000" +"message" "Toggable red slow pulsing dynamic light." +} +{ +"classname" "dynamic_light" +"origin" "192.000000 -128.000000 64.000000" +"targetname" "foobar2" +"style" "2" +"_light" "255 0 0" +"brightness" "250" +} diff --git a/src/client/cstrike/player.c b/src/client/cstrike/player.c index dfa8ee10..4bd3932a 100644 --- a/src/client/cstrike/player.c +++ b/src/client/cstrike/player.c @@ -15,7 +15,7 @@ */ void -Player_ReadEntity(float new) +Player_ReceiveEntity(float new) { float fl; player pl = (player)self; diff --git a/src/client/entry.c b/src/client/entry.c index cf1a5a8a..264037ff 100644 --- a/src/client/entry.c +++ b/src/client/entry.c @@ -184,7 +184,7 @@ CSQC_UpdateView(float w, float h, float focus) for (s = numclientseats; s-- > 0;) { pSeat = &g_seats[s]; - + View_CalcViewport(s, w, h); setproperty(VF_ACTIVESEAT, (float)s); @@ -205,7 +205,7 @@ CSQC_UpdateView(float w, float h, float focus) pSeat->m_vecPredictedVelocity = pl.velocity; pSeat->m_flPredictedFlags = pl.flags; - // Don't hide the player entity + /* Don't hide the player entity */ if (autocvar_cl_thirdperson == TRUE && pl.health) { setproperty(VF_VIEWENTITY, (float)0); } else { @@ -232,13 +232,13 @@ CSQC_UpdateView(float w, float h, float focus) } else { setsensitivityscaler(pl.viewzoom); } - + if (pl.viewzoom <= 0.0f) { setsensitivityscaler(1.0f); } pl.viewzoom = oldzoom; - + View_Stairsmooth(); if (pSeat->m_pWeaponFX) { @@ -385,32 +385,32 @@ CSQC_InputEvent(float fEventType, float fKey, float fCharacter, float fDeviceID) pSeat = &g_seats[s]; switch (fEventType) { - case IE_KEYDOWN: - break; - case IE_KEYUP: - break; - case IE_MOUSEABS: - mouse_pos[0] = fKey; - mouse_pos[1] = fCharacter; - break; - case IE_MOUSEDELTA: - mouse_pos[0] += fKey; - mouse_pos[1] += fCharacter; - - if (mouse_pos[0] < 0) { - mouse_pos[0] = 0; - } else if (mouse_pos[0] > video_res[0]) { - mouse_pos[0] = video_res[0]; - } - - if (mouse_pos[1] < 0) { - mouse_pos[1] = 0; - } else if (mouse_pos[1] > video_res[1]) { - mouse_pos[1] = video_res[1]; - } - break; - default: - return TRUE; + case IE_KEYDOWN: + break; + case IE_KEYUP: + break; + case IE_MOUSEABS: + mouse_pos[0] = fKey; + mouse_pos[1] = fCharacter; + break; + case IE_MOUSEDELTA: + mouse_pos[0] += fKey; + mouse_pos[1] += fCharacter; + + if (mouse_pos[0] < 0) { + mouse_pos[0] = 0; + } else if (mouse_pos[0] > video_res[0]) { + mouse_pos[0] = video_res[0]; + } + + if (mouse_pos[1] < 0) { + mouse_pos[1] = 0; + } else if (mouse_pos[1] > video_res[1]) { + mouse_pos[1] = video_res[1]; + } + break; + default: + return TRUE; } VGUI_Input(fEventType, fKey, fCharacter, fDeviceID); @@ -524,7 +524,7 @@ CSQC_Parse_Event(void) pos = getproperty(VF_ORIGIN); ang = getproperty(VF_ANGLES); } - + pSeat->m_vecCameraOrigin = pos; pSeat->m_vecCameraAngle = ang; g_iIntermission = TRUE; @@ -604,9 +604,9 @@ CSQC_ConsoleCommand(string sCMD) /* the engine will hide the p1 etc commands... which is fun... */ int s = (float)getproperty(VF_ACTIVESEAT); pSeat = &g_seats[s]; - + tokenize(sCMD); - + switch (argv(0)) { case "dev_sentence": static CBaseEntity foo; @@ -799,17 +799,17 @@ CSQC_Ent_Update(float new) if (new) { spawnfunc_CBaseEntity(); } - me.ReadEntity(readfloat()); + me.ReceiveEntity(readfloat()); break; case ENT_PLAYER: - Player_ReadEntity(new); + Player_ReceiveEntity(new); break; case ENT_SPRITE: env_sprite spr = (env_sprite)self; if (new) { spawnfunc_env_sprite(); } - spr.ReadEntity(readfloat()); + spr.ReceiveEntity(readfloat()); break; break; case ENT_SPRAY: @@ -821,12 +821,19 @@ CSQC_Ent_Update(float new) case ENT_AMBIENTSOUND: Sound_ParseLoopingEntity(self, new); break; + case ENT_DLIGHT: + light_dynamic dl = (light_dynamic)self; + if (new) { + spawnfunc_light_dynamic(); + } + dl.ReceiveEntity(readfloat()); + break; case ENT_ENVLASER: env_laser l = (env_laser)self; if (new) { spawnfunc_env_laser(); } - l.ReadEntity(readfloat()); + l.ReceiveEntity(readfloat()); break; default: if (Game_Entity_Update(t, new) == FALSE) { diff --git a/src/client/npc.c b/src/client/npc.c index d78c48c1..1a27d859 100644 --- a/src/client/npc.c +++ b/src/client/npc.c @@ -20,7 +20,7 @@ class CBaseNPC:CBaseEntity float frame_last; virtual float() predraw; - virtual void(float flChanged) ReadEntity; + virtual void(float flChanged) ReceiveEntity; }; float @@ -56,7 +56,7 @@ CBaseNPC::predraw(void) } void -CBaseNPC::ReadEntity(float fl) +CBaseNPC::ReceiveEntity(float fl) { if (fl & NPC_MODELINDEX) modelindex = readshort(); diff --git a/src/client/valve/player.c b/src/client/valve/player.c index 66cef8fc..79d9efa2 100644 --- a/src/client/valve/player.c +++ b/src/client/valve/player.c @@ -15,7 +15,7 @@ */ void -Player_ReadEntity(float new) +Player_ReceiveEntity(float new) { float fl; player pl = (player)self; diff --git a/src/gs-entbase/client.src b/src/gs-entbase/client.src index 8ce7ecc8..c6c6cc22 100644 --- a/src/gs-entbase/client.src +++ b/src/gs-entbase/client.src @@ -20,6 +20,7 @@ client/env_laser.cpp client/func_lod.cpp client/func_dustmotes.cpp client/light_environment.cpp +client/light_dynamic.cpp client/sky_camera.cpp client/info_notnull.cpp client/point_message.cpp diff --git a/src/gs-entbase/client/baseentity.cpp b/src/gs-entbase/client/baseentity.cpp index 5cad4fe6..fed51881 100644 --- a/src/gs-entbase/client/baseentity.cpp +++ b/src/gs-entbase/client/baseentity.cpp @@ -223,7 +223,7 @@ CBaseEntity::Sentence(string msg) m_flSentenceTime = time; } -void CBaseEntity::ReadEntity(float flChanged) +void CBaseEntity::ReceiveEntity(float flChanged) { if (flChanged & BASEFL_CHANGED_ORIGIN) { origin[0] = readcoord(); diff --git a/src/gs-entbase/client/baseentity.h b/src/gs-entbase/client/baseentity.h index d657bcd7..2c437745 100644 --- a/src/gs-entbase/client/baseentity.h +++ b/src/gs-entbase/client/baseentity.h @@ -38,7 +38,7 @@ class CBaseEntity virtual void(string, string) SpawnKey; virtual void(string) Sentence; virtual void(void) ProcessWordQue; - virtual void(float flChanged) ReadEntity; + virtual void(float flChanged) ReceiveEntity; virtual float(void) predraw; virtual void(void) postdraw; virtual void(void) customphysics; diff --git a/src/gs-entbase/client/env_laser.cpp b/src/gs-entbase/client/env_laser.cpp index 91b78867..d91d82fc 100644 --- a/src/gs-entbase/client/env_laser.cpp +++ b/src/gs-entbase/client/env_laser.cpp @@ -35,7 +35,7 @@ class env_laser virtual void(void) Init; virtual void(void) Initialized; - virtual void(float flChanged) ReadEntity; + virtual void(float flChanged) ReceiveEntity; virtual float(void) predraw; }; @@ -54,7 +54,7 @@ float env_laser::predraw(void) return PREDRAW_NEXT; } -void env_laser::ReadEntity(float flChanged) +void env_laser::ReceiveEntity(float flChanged) { if (flChanged & ENVLASER_CHANGED_ORIGIN) { origin[0] = readcoord(); diff --git a/src/gs-entbase/client/env_sprite.cpp b/src/gs-entbase/client/env_sprite.cpp index e6d07fc1..3c682e3a 100644 --- a/src/gs-entbase/client/env_sprite.cpp +++ b/src/gs-entbase/client/env_sprite.cpp @@ -22,7 +22,7 @@ class env_sprite:CBaseEntity virtual void(void) Init; virtual void(void) Initialized; - virtual void(float flChanged) ReadEntity; + virtual void(float flChanged) ReceiveEntity; virtual void(void) think; }; @@ -41,7 +41,7 @@ void env_sprite::think(void) nextthink = time + (1 / framerate); } -void env_sprite::ReadEntity(float flChanged) +void env_sprite::ReceiveEntity(float flChanged) { origin[0] = readcoord(); origin[1] = readcoord(); diff --git a/src/gs-entbase/client/light_dynamic.cpp b/src/gs-entbase/client/light_dynamic.cpp new file mode 100644 index 00000000..d811d676 --- /dev/null +++ b/src/gs-entbase/client/light_dynamic.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * 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. + */ + +/* this has to match gs-entbase/server/light_dynamic.cpp! */ +enumflags +{ + DLIGHTFL_CHANGED_ORIGIN, + DLIGHTFL_CHANGED_ANGLES, + DLIGHTFL_CHANGED_LIGHT, + DLIGHTFL_CHANGED_INTENSITY, + DLIGHTFL_CHANGED_INNERCONE, + DLIGHTFL_CHANGED_CONE, + DLIGHTFL_CHANGED_DISTANCE, + DLIGHTFL_CHANGED_RADIUS, + DLIGHTFL_CHANGED_STYLE, + DLIGHTFL_CHANGED_STATE +}; + +class light_dynamic +{ + vector m_vecLight; + float m_flIntensity; + float m_flInnerCone; + float m_flCone; + float m_flDistance; + float m_flRadius; + float m_flStyle; + int m_iState; + + void(void) light_dynamic; + + virtual void(float) ReceiveEntity; + virtual float(void) predraw; +}; + +float +light_dynamic::predraw(void) +{ + if (!m_iState) { + return PREDRAW_NEXT; + } + + /* TODO: We need to handle the second cone light */ + dynamiclight_add(origin, m_flIntensity, m_vecLight, m_flStyle); + + addentity(this); + return PREDRAW_NEXT; +} + +void light_dynamic::ReceiveEntity(float flFlags) +{ + if (flFlags & DLIGHTFL_CHANGED_ORIGIN) { + origin[0] = readcoord(); + origin[1] = readcoord(); + origin[2] = readcoord(); + setorigin(this, origin); + } + + if (flFlags & DLIGHTFL_CHANGED_ANGLES) { + angles[0] = readcoord(); + angles[1] = readcoord(); + angles[2] = readcoord(); + } + + if (flFlags & DLIGHTFL_CHANGED_LIGHT) { + m_vecLight[0] = readbyte() / 255; + m_vecLight[1] = readbyte() / 255; + m_vecLight[2] = readbyte() / 255; + } + + if (flFlags & DLIGHTFL_CHANGED_INTENSITY) + m_flIntensity = readfloat(); + if (flFlags & DLIGHTFL_CHANGED_INNERCONE) + m_flInnerCone = readfloat(); + if (flFlags & DLIGHTFL_CHANGED_CONE) + m_flCone = readfloat(); + if (flFlags & DLIGHTFL_CHANGED_DISTANCE) + m_flDistance = readfloat(); + if (flFlags & DLIGHTFL_CHANGED_RADIUS) + m_flRadius = readfloat(); + if (flFlags & DLIGHTFL_CHANGED_STYLE) + m_flStyle = readbyte(); + if (flFlags & DLIGHTFL_CHANGED_STATE) + m_iState = readbyte(); + + classname = "light_dynamic"; + drawmask = MASK_ENGINE; +} + +void light_dynamic::light_dynamic(void) +{ +} diff --git a/src/gs-entbase/client/point_message.cpp b/src/gs-entbase/client/point_message.cpp index ec72ed02..833d307d 100644 --- a/src/gs-entbase/client/point_message.cpp +++ b/src/gs-entbase/client/point_message.cpp @@ -32,7 +32,8 @@ class point_message:CBaseEntity virtual void(string, string) SpawnKey; }; -void point_message::SpawnKey(string strField, string strKey) +void +point_message::SpawnKey(string strField, string strKey) { switch (strField) { case "radius": @@ -50,14 +51,16 @@ void point_message::SpawnKey(string strField, string strKey) } } -void point_message::point_message(void) +void +point_message::point_message(void) { m_flRadius = 512; m_strMessage = "No message"; Init(); } -int PointMessage_Visible(vector p1, vector p2, vector ang) +int +PointMessage_Visible(vector p1, vector p2, vector ang) { vector delta; float fov; @@ -75,18 +78,14 @@ int PointMessage_Visible(vector p1, vector p2, vector ang) return FALSE; } -void PointMessage_Draw(void) +void +PointMessage_Draw(void) { vector vecPlayer; -#ifdef WASTES - vecPlayer = viewClient.vecPlayerOrigin; - vecPlayer += [0, 0, getstatf(ST_VIEWHEIGHT)]; -#else int s = (float)getproperty(VF_ACTIVESEAT); pSeat = &g_seats[s]; vecPlayer = pSeat->m_vecPredictedOrigin; -#endif string msg; float distance; diff --git a/src/gs-entbase/decals.h b/src/gs-entbase/decals.h index c0e284c3..3fe20b39 100644 --- a/src/gs-entbase/decals.h +++ b/src/gs-entbase/decals.h @@ -22,7 +22,7 @@ class decal #ifdef SERVER virtual float(entity, float) SendEntity; #else - virtual void(void) ReadEntity; + virtual void(void) ReceiveEntity; virtual float() predraw; virtual void(void) BuildShader; #endif diff --git a/src/gs-entbase/server.src b/src/gs-entbase/server.src index 3677ad2d..3b9fb0d3 100644 --- a/src/gs-entbase/server.src +++ b/src/gs-entbase/server.src @@ -61,6 +61,7 @@ server/func_pendulum.cpp server/func_vehicle.cpp server/func_vehiclecontrols.cpp server/light.cpp +server/light_dynamic.cpp server/stubs.cpp server/infodecal.cpp server/player_weaponstrip.cpp diff --git a/src/gs-entbase/server/light.cpp b/src/gs-entbase/server/light.cpp index 48a4d027..fe09056a 100644 --- a/src/gs-entbase/server/light.cpp +++ b/src/gs-entbase/server/light.cpp @@ -66,7 +66,8 @@ class light:CBaseTrigger virtual void(string, string) SpawnKey; }; -void light::Trigger(entity act, int state) +void +light::Trigger(entity act, int state) { switch (state) { case TRIG_OFF: @@ -86,7 +87,8 @@ void light::Trigger(entity act, int state) } } -void light::Respawn(void) +void +light::Respawn(void) { if (spawnflags & 1) { lightstyle(m_flStyle, "a"); @@ -116,7 +118,8 @@ light::SpawnKey(string strKey, string strValue) } } -void light::light(void) +void +light::light(void) { m_strPattern = "m"; CBaseTrigger::CBaseTrigger(); @@ -129,4 +132,3 @@ void light::light(void) CLASSEXPORT(light_spot, light) CLASSEXPORT(light_environment, light) - diff --git a/src/gs-entbase/server/light_dynamic.cpp b/src/gs-entbase/server/light_dynamic.cpp new file mode 100644 index 00000000..f6f19001 --- /dev/null +++ b/src/gs-entbase/server/light_dynamic.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * 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. + */ + +/*QUAKED light_dynamic (1 0 0) (-8 -8 -8) (8 8 8) +"targetname" Name +"target" Name of an entity in the map that light will point at. +"_light" Color of the spotlight in RGB255 format. +"brightness" Intensity of the spotlight. +"_inner_cone" Angles of the inner spotlight beam. 0 = omnidirectional. +"_cone" Angles of the outer spotlight beam. 0 = omnidirectional. +"distance" Distance that light is allowed to cast, in inches. +"spotlight_radius" Radius of the resulting spotlight that's cast at a wall. +"style" Select one of the hard-coded lightstyles. + +Dynamic light entity. Can be parented to things, it even has some inputs that +may be interesting. +*/ + +/* this has to match gs-entbase/client/light_dynamic.cpp! */ +enumflags +{ + DLIGHTFL_CHANGED_ORIGIN, /* don't move these */ + DLIGHTFL_CHANGED_ANGLES, /* don't move these */ + DLIGHTFL_CHANGED_LIGHT, + DLIGHTFL_CHANGED_INTENSITY, + DLIGHTFL_CHANGED_INNERCONE, + DLIGHTFL_CHANGED_CONE, + DLIGHTFL_CHANGED_DISTANCE, + DLIGHTFL_CHANGED_RADIUS, + DLIGHTFL_CHANGED_STYLE, + DLIGHTFL_CHANGED_STATE +}; + +class light_dynamic:CBaseTrigger +{ + vector m_vecLight; + float m_flIntensity; + float m_flInnerCone; + float m_flCone; + float m_flDistance; + float m_flRadius; + float m_flStyle; + int m_iState; + + void(void) light_dynamic; + virtual void(entity, int) Trigger; + virtual void(void) Respawn; + virtual float(entity, float) SendEntity; + virtual void(string, string) SpawnKey; + virtual void(entity, string, string) Input; + virtual void(void) ParentUpdate; +}; + +void +light_dynamic::ParentUpdate(void) +{ + if (m_parent) { + entity p = find(world, ::targetname, m_parent); + + if (!p) { + return; + } + + SetOrigin(p.origin); + } +} + +void +light_dynamic::Trigger(entity act, int state) +{ + switch (state) { + case TRIG_OFF: + m_iState = 0; + break; + case TRIG_ON: + m_iState = 1; + break; + default: + m_iState = 1 - m_iState; + } + + SendFlags |= DLIGHTFL_CHANGED_STATE; +} + +void +light_dynamic::Respawn(void) +{ + SetSolid(SOLID_NOT); + SetOrigin(m_oldOrigin); + SetAngles(m_oldAngle); + m_iState = 1; + + SendFlags = DLIGHTFL_CHANGED_ORIGIN | \ + DLIGHTFL_CHANGED_ANGLES | \ + DLIGHTFL_CHANGED_LIGHT | \ + DLIGHTFL_CHANGED_INTENSITY | \ + DLIGHTFL_CHANGED_INNERCONE | \ + DLIGHTFL_CHANGED_CONE | \ + DLIGHTFL_CHANGED_DISTANCE | \ + DLIGHTFL_CHANGED_RADIUS | \ + DLIGHTFL_CHANGED_STYLE | \ + DLIGHTFL_CHANGED_STATE; +} + +float +light_dynamic::SendEntity(entity ePVSEnt, float flFlags) +{ + WriteByte(MSG_ENTITY, ENT_DLIGHT); + WriteFloat(MSG_ENTITY, flFlags); + + if (flFlags & DLIGHTFL_CHANGED_ORIGIN) { + WriteCoord(MSG_ENTITY, origin[0]); + WriteCoord(MSG_ENTITY, origin[1]); + WriteCoord(MSG_ENTITY, origin[2]); + } + + if (flFlags & DLIGHTFL_CHANGED_ANGLES) { + WriteCoord(MSG_ENTITY, angles[0]); + WriteCoord(MSG_ENTITY, angles[1]); + WriteCoord(MSG_ENTITY, angles[2]); + } + + if (flFlags & DLIGHTFL_CHANGED_LIGHT) { + WriteByte(MSG_ENTITY, m_vecLight[0]); + WriteByte(MSG_ENTITY, m_vecLight[1]); + WriteByte(MSG_ENTITY, m_vecLight[2]); + } + + if (flFlags & DLIGHTFL_CHANGED_INTENSITY) + WriteFloat(MSG_ENTITY, m_flIntensity); + if (flFlags & DLIGHTFL_CHANGED_INNERCONE) + WriteFloat(MSG_ENTITY, m_flInnerCone); + if (flFlags & DLIGHTFL_CHANGED_CONE) + WriteFloat(MSG_ENTITY, m_flCone); + if (flFlags & DLIGHTFL_CHANGED_DISTANCE) + WriteFloat(MSG_ENTITY, m_flDistance); + if (flFlags & DLIGHTFL_CHANGED_RADIUS) + WriteFloat(MSG_ENTITY, m_flRadius); + if (flFlags & DLIGHTFL_CHANGED_STYLE) + WriteByte(MSG_ENTITY, m_flStyle); + if (flFlags & DLIGHTFL_CHANGED_STATE) + WriteByte(MSG_ENTITY, m_iState); + + return TRUE; +} + +void +light_dynamic::Input(entity eAct, string strInput, string strData) +{ + switch (strInput) { + case "Color": + m_vecLight = stov(strData); + SendFlags |= DLIGHTFL_CHANGED_LIGHT; + break; + case "brightness": + m_flIntensity = stof(strData); + SendFlags |= DLIGHTFL_CHANGED_INTENSITY; + break; + case "distance": + m_flDistance = stof(strData); + SendFlags |= DLIGHTFL_CHANGED_DISTANCE; + break; + case "_inner_cone": + m_flInnerCone = stof(strData); + SendFlags |= DLIGHTFL_CHANGED_INNERCONE; + break; + case "_cone": + m_flCone = stof(strData); + SendFlags |= DLIGHTFL_CHANGED_CONE; + break; + case "spotlight_radius": + m_flRadius = stof(strData); + SendFlags |= DLIGHTFL_CHANGED_RADIUS; + break; + case "style": + m_flStyle = stof(strData); + SendFlags |= DLIGHTFL_CHANGED_STYLE; + break; + case "TurnOn": + Trigger(eAct, TRIG_ON); + break; + case "TurnOff": + Trigger(eAct, TRIG_OFF); + break; + case "Toggle": + Trigger(eAct, TRIG_TOGGLE); + break; + default: + CBaseTrigger::Input(eAct, strInput, strData); + } +} + +void +light_dynamic::SpawnKey(string strKey, string strValue) +{ + switch (strKey) { + case "_light": + m_vecLight = stov(strValue); + break; + case "light": + case "brightness": + m_flIntensity = stof(strValue); + break; + case "_inner_cone": + m_flInnerCone = stof(strValue); + break; + case "_cone": + m_flCone = stof(strValue); + break; + case "distance": + m_flDistance = stof(strValue); + break; + case "spotlight_radius": + m_flRadius = stof(strValue); + break; + case "style": + m_flStyle = stof(strValue); + break; + default: + CBaseTrigger::SpawnKey(strKey, strValue); + } +} + +void +light_dynamic::light_dynamic(void) +{ + m_iState = 1; + m_vecLight = [255,255,255]; + CBaseTrigger::CBaseTrigger(); + gflags = GF_CANRESPAWN; + + /* FIXME: this is really bad, but FTE refuses to network things without a model + * or something along those lines - so we're force networking these right + * now. */ + pvsflags = PVSF_IGNOREPVS; +} + +CLASSEXPORT(dynamic_light, light_dynamic) diff --git a/src/gs-entbase/shared/decals.cpp b/src/gs-entbase/shared/decals.cpp index a253db78..4181f575 100644 --- a/src/gs-entbase/shared/decals.cpp +++ b/src/gs-entbase/shared/decals.cpp @@ -47,7 +47,7 @@ decal::SendEntity(entity pvsent, float changedflags) } #else void -decal::ReadEntity(void) +decal::ReceiveEntity(void) { origin[0] = readcoord(); origin[1] = readcoord(); @@ -238,6 +238,6 @@ void Decal_Parse(void) /* convert us to an object of type decal */ spawnfunc_decal(); new = (decal)self; - new.ReadEntity(); + new.ReceiveEntity(); } #endif diff --git a/src/shared/entities.h b/src/shared/entities.h index 53494e4f..a0636858 100644 --- a/src/shared/entities.h +++ b/src/shared/entities.h @@ -20,6 +20,7 @@ enum ENT_ENTITY = 1, ENT_PLAYER, ENT_AMBIENTSOUND, + ENT_DLIGHT, ENT_ENVLASER, ENT_SPRITE, ENT_SPRAY,