diff --git a/base/resources.pk3dir/def/player.def b/base/resources.pk3dir/decls/def/player.def similarity index 100% rename from base/resources.pk3dir/def/player.def rename to base/resources.pk3dir/decls/def/player.def diff --git a/base/resources.pk3dir/def/spawns.def b/base/resources.pk3dir/decls/def/spawns.def similarity index 100% rename from base/resources.pk3dir/def/spawns.def rename to base/resources.pk3dir/decls/def/spawns.def diff --git a/base/resources.pk3dir/def/weapons.def b/base/resources.pk3dir/decls/def/weapons.def similarity index 100% rename from base/resources.pk3dir/def/weapons.def rename to base/resources.pk3dir/decls/def/weapons.def diff --git a/base/resources.pk3dir/efx/abandoned.efx b/base/resources.pk3dir/decls/efx/abandoned.efx similarity index 100% rename from base/resources.pk3dir/efx/abandoned.efx rename to base/resources.pk3dir/decls/efx/abandoned.efx diff --git a/base/resources.pk3dir/efx/alley.efx b/base/resources.pk3dir/decls/efx/alley.efx similarity index 100% rename from base/resources.pk3dir/efx/alley.efx rename to base/resources.pk3dir/decls/efx/alley.efx diff --git a/base/resources.pk3dir/efx/arena.efx b/base/resources.pk3dir/decls/efx/arena.efx similarity index 100% rename from base/resources.pk3dir/efx/arena.efx rename to base/resources.pk3dir/decls/efx/arena.efx diff --git a/base/resources.pk3dir/efx/auditorium.efx b/base/resources.pk3dir/decls/efx/auditorium.efx similarity index 100% rename from base/resources.pk3dir/efx/auditorium.efx rename to base/resources.pk3dir/decls/efx/auditorium.efx diff --git a/base/resources.pk3dir/efx/bathroom.efx b/base/resources.pk3dir/decls/efx/bathroom.efx similarity index 100% rename from base/resources.pk3dir/efx/bathroom.efx rename to base/resources.pk3dir/decls/efx/bathroom.efx diff --git a/base/resources.pk3dir/efx/carpetedhallway.efx b/base/resources.pk3dir/decls/efx/carpetedhallway.efx similarity index 100% rename from base/resources.pk3dir/efx/carpetedhallway.efx rename to base/resources.pk3dir/decls/efx/carpetedhallway.efx diff --git a/base/resources.pk3dir/efx/cave.efx b/base/resources.pk3dir/decls/efx/cave.efx similarity index 100% rename from base/resources.pk3dir/efx/cave.efx rename to base/resources.pk3dir/decls/efx/cave.efx diff --git a/base/resources.pk3dir/efx/chapel.efx b/base/resources.pk3dir/decls/efx/chapel.efx similarity index 100% rename from base/resources.pk3dir/efx/chapel.efx rename to base/resources.pk3dir/decls/efx/chapel.efx diff --git a/base/resources.pk3dir/efx/city.efx b/base/resources.pk3dir/decls/efx/city.efx similarity index 100% rename from base/resources.pk3dir/efx/city.efx rename to base/resources.pk3dir/decls/efx/city.efx diff --git a/base/resources.pk3dir/efx/citystreets.efx b/base/resources.pk3dir/decls/efx/citystreets.efx similarity index 100% rename from base/resources.pk3dir/efx/citystreets.efx rename to base/resources.pk3dir/decls/efx/citystreets.efx diff --git a/base/resources.pk3dir/efx/concerthall.efx b/base/resources.pk3dir/decls/efx/concerthall.efx similarity index 100% rename from base/resources.pk3dir/efx/concerthall.efx rename to base/resources.pk3dir/decls/efx/concerthall.efx diff --git a/base/resources.pk3dir/efx/default.efx b/base/resources.pk3dir/decls/efx/default.efx similarity index 100% rename from base/resources.pk3dir/efx/default.efx rename to base/resources.pk3dir/decls/efx/default.efx diff --git a/base/resources.pk3dir/efx/dizzy.efx b/base/resources.pk3dir/decls/efx/dizzy.efx similarity index 100% rename from base/resources.pk3dir/efx/dizzy.efx rename to base/resources.pk3dir/decls/efx/dizzy.efx diff --git a/base/resources.pk3dir/efx/drugged.efx b/base/resources.pk3dir/decls/efx/drugged.efx similarity index 100% rename from base/resources.pk3dir/efx/drugged.efx rename to base/resources.pk3dir/decls/efx/drugged.efx diff --git a/base/resources.pk3dir/efx/dustyroom.efx b/base/resources.pk3dir/decls/efx/dustyroom.efx similarity index 100% rename from base/resources.pk3dir/efx/dustyroom.efx rename to base/resources.pk3dir/decls/efx/dustyroom.efx diff --git a/base/resources.pk3dir/efx/forest.efx b/base/resources.pk3dir/decls/efx/forest.efx similarity index 100% rename from base/resources.pk3dir/efx/forest.efx rename to base/resources.pk3dir/decls/efx/forest.efx diff --git a/base/resources.pk3dir/efx/hallway.efx b/base/resources.pk3dir/decls/efx/hallway.efx similarity index 100% rename from base/resources.pk3dir/efx/hallway.efx rename to base/resources.pk3dir/decls/efx/hallway.efx diff --git a/base/resources.pk3dir/efx/hangar.efx b/base/resources.pk3dir/decls/efx/hangar.efx similarity index 100% rename from base/resources.pk3dir/efx/hangar.efx rename to base/resources.pk3dir/decls/efx/hangar.efx diff --git a/base/resources.pk3dir/efx/library.efx b/base/resources.pk3dir/decls/efx/library.efx similarity index 100% rename from base/resources.pk3dir/efx/library.efx rename to base/resources.pk3dir/decls/efx/library.efx diff --git a/base/resources.pk3dir/efx/livingroom.efx b/base/resources.pk3dir/decls/efx/livingroom.efx similarity index 100% rename from base/resources.pk3dir/efx/livingroom.efx rename to base/resources.pk3dir/decls/efx/livingroom.efx diff --git a/base/resources.pk3dir/efx/mountains.efx b/base/resources.pk3dir/decls/efx/mountains.efx similarity index 100% rename from base/resources.pk3dir/efx/mountains.efx rename to base/resources.pk3dir/decls/efx/mountains.efx diff --git a/base/resources.pk3dir/efx/museum.efx b/base/resources.pk3dir/decls/efx/museum.efx similarity index 100% rename from base/resources.pk3dir/efx/museum.efx rename to base/resources.pk3dir/decls/efx/museum.efx diff --git a/base/resources.pk3dir/efx/paddedcell.efx b/base/resources.pk3dir/decls/efx/paddedcell.efx similarity index 100% rename from base/resources.pk3dir/efx/paddedcell.efx rename to base/resources.pk3dir/decls/efx/paddedcell.efx diff --git a/base/resources.pk3dir/efx/parkinglot.efx b/base/resources.pk3dir/decls/efx/parkinglot.efx similarity index 100% rename from base/resources.pk3dir/efx/parkinglot.efx rename to base/resources.pk3dir/decls/efx/parkinglot.efx diff --git a/base/resources.pk3dir/efx/plain.efx b/base/resources.pk3dir/decls/efx/plain.efx similarity index 100% rename from base/resources.pk3dir/efx/plain.efx rename to base/resources.pk3dir/decls/efx/plain.efx diff --git a/base/resources.pk3dir/efx/psychotic.efx b/base/resources.pk3dir/decls/efx/psychotic.efx similarity index 100% rename from base/resources.pk3dir/efx/psychotic.efx rename to base/resources.pk3dir/decls/efx/psychotic.efx diff --git a/base/resources.pk3dir/efx/quarry.efx b/base/resources.pk3dir/decls/efx/quarry.efx similarity index 100% rename from base/resources.pk3dir/efx/quarry.efx rename to base/resources.pk3dir/decls/efx/quarry.efx diff --git a/base/resources.pk3dir/efx/room.efx b/base/resources.pk3dir/decls/efx/room.efx similarity index 100% rename from base/resources.pk3dir/efx/room.efx rename to base/resources.pk3dir/decls/efx/room.efx diff --git a/base/resources.pk3dir/efx/sewerpipe.efx b/base/resources.pk3dir/decls/efx/sewerpipe.efx similarity index 100% rename from base/resources.pk3dir/efx/sewerpipe.efx rename to base/resources.pk3dir/decls/efx/sewerpipe.efx diff --git a/base/resources.pk3dir/efx/smallwaterroom.efx b/base/resources.pk3dir/decls/efx/smallwaterroom.efx similarity index 100% rename from base/resources.pk3dir/efx/smallwaterroom.efx rename to base/resources.pk3dir/decls/efx/smallwaterroom.efx diff --git a/base/resources.pk3dir/efx/stonecorridor.efx b/base/resources.pk3dir/decls/efx/stonecorridor.efx similarity index 100% rename from base/resources.pk3dir/efx/stonecorridor.efx rename to base/resources.pk3dir/decls/efx/stonecorridor.efx diff --git a/base/resources.pk3dir/efx/stoneroom.efx b/base/resources.pk3dir/decls/efx/stoneroom.efx similarity index 100% rename from base/resources.pk3dir/efx/stoneroom.efx rename to base/resources.pk3dir/decls/efx/stoneroom.efx diff --git a/base/resources.pk3dir/efx/subway.efx b/base/resources.pk3dir/decls/efx/subway.efx similarity index 100% rename from base/resources.pk3dir/efx/subway.efx rename to base/resources.pk3dir/decls/efx/subway.efx diff --git a/base/resources.pk3dir/efx/underpass.efx b/base/resources.pk3dir/decls/efx/underpass.efx similarity index 100% rename from base/resources.pk3dir/efx/underpass.efx rename to base/resources.pk3dir/decls/efx/underpass.efx diff --git a/base/resources.pk3dir/efx/underwater.efx b/base/resources.pk3dir/decls/efx/underwater.efx similarity index 100% rename from base/resources.pk3dir/efx/underwater.efx rename to base/resources.pk3dir/decls/efx/underwater.efx diff --git a/base/resources.pk3dir/sound/footsteps.sndshd b/base/resources.pk3dir/decls/sound/footsteps.sndshd similarity index 100% rename from base/resources.pk3dir/sound/footsteps.sndshd rename to base/resources.pk3dir/decls/sound/footsteps.sndshd diff --git a/base/resources.pk3dir/sound/weapons.sndshd b/base/resources.pk3dir/decls/sound/weapons.sndshd similarity index 100% rename from base/resources.pk3dir/sound/weapons.sndshd rename to base/resources.pk3dir/decls/sound/weapons.sndshd diff --git a/base/resources.pk3dir/gfx/palette.lmp b/base/resources.pk3dir/gfx/palette.lmp new file mode 100644 index 00000000..56739613 Binary files /dev/null and b/base/resources.pk3dir/gfx/palette.lmp differ diff --git a/base/resources.pk3dir/gfx/palette.tga b/base/resources.pk3dir/gfx/palette.tga new file mode 100644 index 00000000..9ba8701f Binary files /dev/null and b/base/resources.pk3dir/gfx/palette.tga differ diff --git a/base/resources.pk3dir/glsl/caustics.glsl b/base/resources.pk3dir/glsl/caustics.glsl deleted file mode 100644 index d35cf49b..00000000 --- a/base/resources.pk3dir/glsl/caustics.glsl +++ /dev/null @@ -1,38 +0,0 @@ -//======= Copyright (c) 2015-2022 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Scrolling shader for patches that get blended on top of existing geometry -// with vertex colors defining fading out -//============================================================================== - -!!ver 110 -!!samps diffuse - -#include "sys/defs.h" - -varying vec2 tex1_c; -varying vec2 tex2_c; -varying vec4 vex_color; - -#ifdef VERTEX_SHADER - void main ( void ) - { - tex1_c = v_texcoord + vec2(e_time * 0.25, e_time * 0.25); - tex2_c = v_texcoord * 0.5 + vec2(e_time * 0.1, e_time * 0.2); - vex_color = v_colour; - - gl_Position = ftetransform(); - } -#endif - -#ifdef FRAGMENT_SHADER - void main ( void ) - { - vec3 diffuse_f = texture2D( s_diffuse, tex1_c ).rgb * vex_color.a; - diffuse_f *= texture2D( s_diffuse, tex2_c ).rgb * vex_color.a; - - gl_FragColor = vec4(diffuse_f, 1.0); - } -#endif - diff --git a/base/resources.pk3dir/glsl/caustics_a.glsl b/base/resources.pk3dir/glsl/caustics_a.glsl deleted file mode 100644 index b599ee48..00000000 --- a/base/resources.pk3dir/glsl/caustics_a.glsl +++ /dev/null @@ -1,39 +0,0 @@ -//======= Copyright (c) 2015-2022 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Alternate version of caustics that's practically inverted for subtract blends -//============================================================================== - -!!ver 110 -!!samps diffuse - -#include "sys/defs.h" - -varying vec2 tex1_c; -varying vec2 tex2_c; -varying vec4 vex_color; - -#ifdef VERTEX_SHADER - void main ( void ) - { - tex1_c = v_texcoord + vec2(e_time * 0.25, e_time * 0.25); - tex2_c = v_texcoord * 0.5 + vec2(e_time * 0.1, e_time * 0.2); - vex_color = v_colour; - - gl_Position = ftetransform(); - } -#endif - -#ifdef FRAGMENT_SHADER - void main ( void ) - { - vec3 diffuse_f = texture2D( s_diffuse, tex1_c ).rgb; - diffuse_f *= texture2D( s_diffuse, tex2_c ).rgb; - - diffuse_f = mix(diffuse_f, vec3(1.0,1.0,1.0), 1.0 - vex_color.a); - - gl_FragColor = vec4(diffuse_f, 1.0); - } -#endif - diff --git a/base/resources.pk3dir/glsl/clutter.glsl b/base/resources.pk3dir/glsl/clutter.glsl deleted file mode 100644 index 62816fdf..00000000 --- a/base/resources.pk3dir/glsl/clutter.glsl +++ /dev/null @@ -1,41 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Shader used for fading out surfaces after a certain distance. -// It only has a diffuse map. -//============================================================================== - -!!ver 110 -!!permu FOG -!!samps diffuse=0 - -#include "sys/defs.h" -#include "sys/fog.h" - -varying vec2 tex_c; -varying float eyedist; - -#ifdef VERTEX_SHADER -void main () -{ - tex_c = v_texcoord; - eyedist = abs( length( e_eyepos - v_position.xyz ) ) / 2048.0; - - if (eyedist > 1.0) { - eyedist = 1.0; - } else if (eyedist < 0.0) { - eyedist = 0.0; - } - - gl_Position = ftetransform(); -} -#endif - -#ifdef FRAGMENT_SHADER -void main () -{ - vec4 diffuse_f = texture2D(s_diffuse, tex_c); - gl_FragColor = vec4( diffuse_f.rgb, (1.0 - eyedist) * diffuse_f.a); -} -#endif diff --git a/base/resources.pk3dir/glsl/decal.glsl b/base/resources.pk3dir/glsl/decal.glsl deleted file mode 100644 index 5ef8a04e..00000000 --- a/base/resources.pk3dir/glsl/decal.glsl +++ /dev/null @@ -1,172 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Lightmapped surface that sticks to walls. -// -// diffusemap = albedo (rgba) -// normalmap = normal (rgb), reflectmask (a) -//============================================================================== - -!!ver 110 -!!permu FOG -!!permu BUMP -!!permu DELUXE -!!permu LIGHTSTYLED -!!samps diffuse - -!!samps lightmap -!!samps =BUMP normalmap reflectcube -!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3 -!!samps =DELUXE deluxemap -!!samps =LIGHTSTYLED =DELUXE deluxemap1 deluxemap2 deluxemap3 - -!!permu FAKESHADOWS -!!cvardf r_glsl_pcf -!!cvardf r_fullbright -!!samps =FAKESHADOWS shadowmap - -#include "sys/defs.h" - -// basics -varying vec2 tex_c; -varying vec2 lm0; - -// unfortunately we do support lightstyles -#if defined(LIGHTSTYLED) -varying vec2 lm1, lm2, lm3; -#endif - -// useful for terrain blending -varying vec4 vex_color; - -// dynamic shadows -#ifdef FAKESHADOWS -varying vec4 vtexprojcoord; -#endif - -#ifdef BUMP -varying vec3 eyevector; -varying mat3 invsurface; -#endif - -#ifdef VERTEX_SHADER - void lightmapped_init(void) - { - lm0 = v_lmcoord; - #if defined(LIGHTSTYLED) - lm1 = v_lmcoord2; - lm2 = v_lmcoord3; - lm3 = v_lmcoord4; - #endif - } - - void main () - { - lightmapped_init(); - tex_c = v_texcoord; - vex_color = v_colour; - gl_Position = ftetransform(); - - #ifdef FAKESHADOWS - vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); - #endif - - #ifdef BUMP - vec3 eyeminusvertex = e_eyepos - v_position.xyz; - eyevector.x = dot(eyeminusvertex, v_svector.xyz); - eyevector.y = dot(eyeminusvertex, v_tvector.xyz); - eyevector.z = dot(eyeminusvertex, v_normal.xyz); - invsurface[0] = v_svector; - invsurface[1] = v_tvector; - invsurface[2] = v_normal; - #endif - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - #include "sys/pcf.h" - - #if defined(LIGHTSTYLED) - #define LIGHTMAP0 texture2D(s_lightmap0, lm0).rgb - #define LIGHTMAP1 texture2D(s_lightmap1, lm1).rgb - #define LIGHTMAP2 texture2D(s_lightmap2, lm2).rgb - #define LIGHTMAP3 texture2D(s_lightmap3, lm3).rgb - #else - #define LIGHTMAP texture2D(s_lightmap, lm0).rgb - #endif - - vec3 lightmap_fragment() - { - vec3 lightmaps; - -#if defined(LIGHTSTYLED) - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb; - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb; - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb; - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb; -#else - lightmaps = LIGHTMAP * e_lmscale.rgb; -#endif - return (r_fullbright == 1) ? vec3(1.0, 1.0, 1.0) : lightmaps; - } - - vec3 lightmap_fragment(vec3 normal_f) - { -#ifndef DELUXE - return lightmap_fragment(); -#else - vec3 lightmaps; - - #if defined(LIGHTSTYLED) - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb * dot(normal_f, (texture2D(s_deluxemap0, lm0).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb * dot(normal_f, (texture2D(s_deluxemap1, lm1).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb * dot(normal_f, (texture2D(s_deluxemap2, lm2).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb * dot(normal_f, (texture2D(s_deluxemap3, lm3).rgb - 0.5) * 2.0); - #else - lightmaps = LIGHTMAP * e_lmscale.rgb * dot(normal_f, (texture2D(s_deluxemap, lm0).rgb - 0.5) * 2.0); - #endif - - return (r_fullbright == 1) ? vec3(1.0, 1.0, 1.0) : lightmaps; -#endif - } - - void main (void) - { - vec4 diffuse_f; - float alpha; - - diffuse_f = texture2D(s_diffuse, tex_c); - diffuse_f.rgb *= diffuse_f.a; - - #ifdef FAKESHADOWS - diffuse_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord); - #endif - - // the lighting stage for the world - #if defined(BUMP) - vec3 cube_c; - vec3 env_f; - vec3 normal_f = normalize(texture2D(s_normalmap, tex_c).rgb - 0.5); - float refl = texture2D(s_normalmap, tex_c).a; - diffuse_f.rgb *= lightmap_fragment(normal_f); - - cube_c = reflect(normalize(-eyevector), normal_f.rgb); - cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2]; - cube_c = (m_model * vec4(cube_c.xyz, 0.0)).xyz; - env_f = textureCube(s_reflectcube, cube_c).rgb * (e_lmscale.rgb * 0.25); - diffuse_f.rgb = mix(env_f, diffuse_f.rgb, refl); - #else - diffuse_f.rgb *= lightmap_fragment(); - #endif - - // start blend at half-way point - alpha = diffuse_f.a; - - if (alpha > 1.0) - alpha = 1.0; - - gl_FragColor = vec4(fog3(diffuse_f.rgb), alpha); - } -#endif diff --git a/base/resources.pk3dir/glsl/decal_reflectcube.glsl b/base/resources.pk3dir/glsl/decal_reflectcube.glsl deleted file mode 100644 index 8725374c..00000000 --- a/base/resources.pk3dir/glsl/decal_reflectcube.glsl +++ /dev/null @@ -1,56 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// The diffusemap (monochrome) decides the reflectivity of a surface. -// Using a cube environmentmap as a source for reflectivity. -//============================================================================== - -!!ver 110 -!!permu FOG -!!permu BUMP -!!permu DELUXE -!!samps diffuse normalmap reflectcube - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec3 eyevector; -varying mat3 invsurface; -varying vec2 wat_c; - -#ifdef VERTEX_SHADER - void main (void) - { - invsurface[0] = v_svector; - invsurface[1] = v_tvector; - invsurface[2] = v_normal; - - vec3 eyeminusvertex = e_eyepos - v_position.xyz; - eyevector.x = dot(eyeminusvertex, v_svector.xyz); - eyevector.y = dot(eyeminusvertex, v_tvector.xyz); - eyevector.z = dot(eyeminusvertex, v_normal.xyz); - - tex_c = v_texcoord; - wat_c = tex_c + vec2(e_time * 0.01, sin(e_time) * 0.005); - gl_Position = ftetransform(); - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - void main (void) - { - vec3 cube_c; - vec4 out_f = vec4(1.0, 1.0, 1.0, 1.0); - vec4 diffuse_f = texture2D(s_diffuse, tex_c); - cube_c = reflect(normalize(-eyevector), texture2D(s_normalmap, wat_c).rgb * 0.35); - cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2]; - cube_c = (m_model * vec4(cube_c.xyz, 0.0)).xyz; - out_f.rgb = textureCube(s_reflectcube, cube_c).rgb; - out_f.rgb *= diffuse_f.r + diffuse_f.b + diffuse_f.g / 3.0; - - // Add fog to the final fragment - gl_FragColor = fog4(out_f); - } -#endif diff --git a/base/resources.pk3dir/glsl/default2d.glsl b/base/resources.pk3dir/glsl/default2d.glsl deleted file mode 100644 index c6a9f7da..00000000 --- a/base/resources.pk3dir/glsl/default2d.glsl +++ /dev/null @@ -1,29 +0,0 @@ -!!ver 100-450 -!!samps 1 - -varying vec2 tc; -varying vec4 vc; - -#ifdef VERTEX_SHADER -attribute vec2 v_texcoord; -attribute vec4 v_colour; -void main () -{ - tc = v_texcoord; - vc = v_colour; - gl_Position = ftetransform(); -} -#endif - -#ifdef FRAGMENT_SHADER -void main () -{ - vec4 f = vc; -#ifdef PREMUL - f.rgb *= f.a; -#endif - f *= texture2D(s_t0, tc); - - gl_FragColor = f; -} -#endif diff --git a/base/resources.pk3dir/glsl/defaultadditivesprite.glsl b/base/resources.pk3dir/glsl/defaultadditivesprite.glsl deleted file mode 100644 index a809bfb7..00000000 --- a/base/resources.pk3dir/glsl/defaultadditivesprite.glsl +++ /dev/null @@ -1,27 +0,0 @@ -!!permu FOG -!!samps 1 - -#include "sys/fog.h" -#ifdef VERTEX_SHADER -attribute vec2 v_texcoord; -attribute vec4 v_colour; -varying vec2 tc; -varying vec4 vc; -void main () -{ - tc = v_texcoord; - vc = v_colour; - gl_Position = ftetransform(); -} -#endif - -#ifdef FRAGMENT_SHADER -varying vec2 tc; -varying vec4 vc; -uniform vec4 e_colourident; -void main () -{ - vec4 diffuse_f = texture2D(s_t0, tc); - gl_FragColor = fog4additive(diffuse_f * vc * e_colourident); -} -#endif diff --git a/base/resources.pk3dir/glsl/defaultfill.glsl b/base/resources.pk3dir/glsl/defaultfill.glsl deleted file mode 100644 index af3793fc..00000000 --- a/base/resources.pk3dir/glsl/defaultfill.glsl +++ /dev/null @@ -1,20 +0,0 @@ -!!ver 100-450 - -#ifdef VERTEX_SHADER -attribute vec4 v_colour; -varying vec4 vc; - -void main () -{ - vc = v_colour; - gl_Position = ftetransform(); -} -#endif - -#ifdef FRAGMENT_SHADER -varying vec4 vc; -void main () -{ - gl_FragColor = vc; -} -#endif diff --git a/base/resources.pk3dir/glsl/defaultskin.glsl b/base/resources.pk3dir/glsl/defaultskin.glsl index ed2b79cf..fa7b69e5 100644 --- a/base/resources.pk3dir/glsl/defaultskin.glsl +++ b/base/resources.pk3dir/glsl/defaultskin.glsl @@ -1,43 +1,64 @@ -!!ver 130 -!!permu FRAMEBLEND +//======= Copyright (c) 2015-2021 Vera Visions LLC. All rights reserved. ======= +// +// Purpose: +// +// Skinned objects, aka rigged objects are handled here. +// Skeletal operations are performed on the GPU (hopefully) and we don't care +// about lightmaps, but query the engine for a dir + ambient term which may +// come from the lightgrid or not exist at all. At that point it should be +// the rtlight shader doing the major work though. +//============================================================================== + +!!ver 100 150 + +!!permu FOG +!!permu BUMP +!!permu DELUXE +!!permu SPECULAR +!!permu FULLBRIGHT +!!permu FAKESHADOWS +!!permu OFFSETMAPPING !!permu SKELETAL !!permu UPPERLOWER -!!permu FOG -!!samps diffuse reflectcube upper lower -!!cvardf gl_affinemodels=0 -!!cvardf gl_ldr=1 -!!cvardf gl_halflambert=1 -!!cvardf gl_mono=0 -!!cvardf gl_kdither=0 -!!cvardf gl_stipplealpha=0 + +!!samps diffuse +!!samps =BUMP normalmap +!!samps =SPECULAR specular reflectcube +!!samps =FULLBRIGHT fullbright +!!samps =UPPERLOWER upper lower +!!samps =FAKESHADOWS shadowmap !!permu FAKESHADOWS !!cvardf r_glsl_pcf !!samps =FAKESHADOWS shadowmap -!!cvardf r_skipDiffuse +!!cvarf r_glsl_offsetmapping_scale +!!cvarf gl_specular + +#ifndef FRESNEL +#define FRESNEL 0.25f +#endif #include "sys/defs.h" -#include "sys/fog.h" -#if gl_affinemodels == 1 - #define affine noperspective -#else - #define affine -#endif +// always required +varying vec2 tc; +varying vec3 lightvector; +varying vec3 light; -#ifdef REFLECTCUBE +// from this point forth, if we check for SPECULAR this means we're in PBR territory +#ifdef BUMP varying vec3 eyevector; varying mat3 invsurface; +#define PBR #endif +// r_shadows 2 #ifdef FAKESHADOWS varying vec4 vtexprojcoord; #endif -affine varying vec2 tex_c; -varying vec3 light; - +// our basic vertex shader #ifdef VERTEX_SHADER #include "sys/skeletal.h" @@ -48,292 +69,145 @@ varying vec3 light; return ( dot( normal, dir ) * 0.5 ) + 0.5; } -#ifdef CHROME - /* Rotate Light Vector */ - vec3 rlv(vec3 axis, vec3 origin, vec3 lightpoint) - { - vec3 offs; - vec3 result; - offs[0] = lightpoint[0] - origin[0]; - offs[1] = lightpoint[1] - origin[1]; - offs[2] = lightpoint[2] - origin[2]; - result[0] = dot(offs[0], axis[0]); - result[1] = dot(offs[1], axis[1]); - result[2] = dot(offs[2], axis[2]); - return result; - } -#endif - - vec3 VectorIRotate( vec3 inPos, mat3x4 xform ) - { - vec3 outPos; - outPos.x = inPos.x*xform[0][0] + inPos.y*xform[1][0] + inPos.z*xform[2][0]; - outPos.y = inPos.x*xform[0][1] + inPos.y*xform[1][1] + inPos.z*xform[2][1]; - outPos.z = inPos.x*xform[0][2] + inPos.y*xform[1][2] + inPos.z*xform[2][2]; - return outPos; - } - - vec3 VectorTransform( vec3 inPos, mat3x4 xform ) - { - vec3 outPos; - outPos.x = dot( inPos, xform[0].xyz ) + xform[0][3]; - outPos.y = dot( inPos, xform[1].xyz ) + xform[1][3]; - outPos.z = dot( inPos, xform[2].xyz ) + xform[2][3]; - return outPos; - } - void main () { vec3 n, s, t, w; gl_Position = skeletaltransform_wnst(w,n,s,t); - tex_c = v_texcoord; - #if gl_halflambert==1 - light = e_light_ambient + (e_light_mul * halflambert(n, e_light_dir)); - #else + #ifdef PBR + vec3 eyeminusvertex = e_eyepos - w.xyz; + eyevector.x = dot(eyeminusvertex, s.xyz); + eyevector.y = dot(eyeminusvertex, t.xyz); + eyevector.z = dot(eyeminusvertex, n.xyz); + invsurface[0] = s; + invsurface[1] = t; + invsurface[2] = n; + #endif + light = e_light_ambient + (e_light_mul * lambert(n, e_light_dir)); + + tc = v_texcoord; + lightvector.x = dot(e_light_dir, s.xyz); + lightvector.y = dot(e_light_dir, t.xyz); + lightvector.z = dot(e_light_dir, n.xyz); + + #ifdef FAKESHADOWS + vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); #endif - - light *= e_lmscale.r; - - if (gl_ldr == 1.0) { - if (light.r > 1.5) - light.r = 1.5; - if (light.g > 1.5) - light.g = 1.5; - if (light.b > 1.5) - light.b = 1.5; - - light.rgb * 0.5; - light.rgb = floor(light.rgb * vec3(32,64,32))/vec3(32,64,32); - light.rgb * 2.0; - light.rgb *= 0.75; - } - -#ifdef CHROME - #ifndef SKELETAL - vec3 rorg = rlv(vec3(0,0,0), w, e_light_dir); - vec3 viewc = normalize(rorg - w); - float d = dot(n, viewc); - vec3 reflected; - reflected.x = n.x * 2.0 * d - viewc.x; - reflected.y = n.y * 2.0 * d - viewc.y; - reflected.z = n.z * 2.0 * d - viewc.z; - tex_c.x = 0.5 + reflected.y * 0.5; - tex_c.y = 0.5 - reflected.z * 0.5; - #else - /* code contributed by Slartibarty */ - vec3 tmp = e_eyepos * -1.0f; - - int boneid = int(v_bone.r); - tmp.x += m_bones_mat3x4[boneid][0][3]; - tmp.y += m_bones_mat3x4[boneid][1][3]; - tmp.z += m_bones_mat3x4[boneid][2][3]; - - tmp = normalize( tmp ); - vec3 chromeUp = normalize( cross( tmp, vec3( m_modelview[0][0], m_modelview[1][0], m_modelview[2][0] ) ) ); - vec3 chromeRight = normalize( cross( chromeUp, tmp ) ); - - chromeUp = VectorIRotate( chromeUp, m_bones_mat3x4[boneid] ); - chromeRight = VectorIRotate( chromeRight, m_bones_mat3x4[boneid] ); - - float na; - - // calc s coord - na = dot( v_normal, chromeRight ); - tex_c.x = ( na + 1.0 ) * 0.5; - - // calc t coord - na = dot( v_normal, chromeUp ); - tex_c.y = ( na + 1.0 ) * 0.5; - #endif -#endif - -#ifdef REFLECTCUBE - invsurface[0] = v_svector; - invsurface[1] = v_tvector; - invsurface[2] = v_normal; - vec3 eyeminusvertex = e_eyepos - v_position.xyz; - eyevector.x = dot( eyeminusvertex, v_svector.xyz ); - eyevector.y = dot( eyeminusvertex, v_tvector.xyz ); - eyevector.z = dot( eyeminusvertex, v_normal.xyz ); -#endif } #endif - #ifdef FRAGMENT_SHADER + #include "sys/fog.h" + + #if defined(SPECULAR) + uniform float cvar_gl_specular; + #endif + + #ifdef FAKESHADOWS #include "sys/pcf.h" + #endif - vec4 kernel_dither(sampler2D targ, vec2 texc) + #ifdef OFFSETMAPPING + #include "sys/offsetmapping.h" + #endif + + float LightingFuncGGX(vec3 N, vec3 V, vec3 L, float roughness, float F0) { - int x = int(mod(gl_FragCoord.x, 2.0)); - int y = int(mod(gl_FragCoord.y, 2.0)); - int index = x + y * 2; - vec2 coord_ofs; - vec2 size; + float alpha = roughness*roughness; - size.x = 1.0 / textureSize(targ, 0).x; - size.y = 1.0 / textureSize(targ, 0).y; + vec3 H = normalize(V+L); - if (index == 0) - coord_ofs = vec2(0.25, 0.0); - else if (index == 1) - coord_ofs = vec2(0.50, 0.75); - else if (index == 2) - coord_ofs = vec2(0.75, 0.50); - else if (index == 3) - coord_ofs = vec2(0.00, 0.25); + float dotNL = clamp(dot(N,L), 0.0, 1.0); + float dotLH = clamp(dot(L,H), 0.0, 1.0); + float dotNH = clamp(dot(N,H), 0.0, 1.0); - return texture2D(targ, texc + coord_ofs * size); - } + float F, D, vis; - vec3 hsv2rgb(float h, float s, float v) - { - int i; - float f,p,q,t; - vec3 col = vec3(0,0,0); + // D + float alphaSqr = alpha*alpha; + float pi = 3.14159f; + float denom = dotNH * dotNH *(alphaSqr-1.0) + 1.0f; + D = alphaSqr/(pi * denom * denom); - h = max(0.0, min(360.0, h)); - s = max(0.0, min(100.0, s)); - v = max(0.0, min(100.0, v)); + // F + float dotLH5 = pow(1.0f-dotLH,5); + F = F0 + (1.0-F0)*(dotLH5); - s /= 100; - v /= 100; + // V + float k = alpha/2.0f; + float k2 = k*k; + float invK2 = 1.0f-k2; + vis = 1.0/(dotLH*dotLH*invK2 + k2); - if (s == 0) { - col.x= col.y = col.z = int(v*255); - return col / 255.0; - } - - h /= 60; - i = int(floor(h)); - f = h - i; - p = v * (1 - s); - q = v * (1 - s * f); - t = v * (1 - s * (1 - f)); - - switch (i) { - case 0: - col[0] = int(255*v); - col[1] = int(255*t); - col[2] = int(255*p); - break; - case 1: - col[0] = int(255*q); - col[1] = int(255*v); - col[2] = int(255*p); - break; - case 2: - col[0] = int(255*p); - col[1] = int(255*v); - col[2] = int(255*t); - break; - case 3: - col[0] = int(255*p); - col[1] = int(255*q); - col[2] = int(255*v); - break; - case 4: - col[0] = int(255*t); - col[1] = int(255*p); - col[2] = int(255*v); - break; - default: - col[0] = int(255*v); - col[1] = int(255*p); - col[2] = int(255*q); - } - return col / 255.0; + float specular = dotNL * D * F * vis; + return specular; } void main () { - vec4 diffuse_f; - -#if r_skipDiffuse==1 - diffuse_f = vec4(1.0, 1.0, 1.0, 1.0); -#else - #if gl_kdither==1 - diffuse_f = kernel_dither(s_diffuse, tex_c); - #else - diffuse_f = texture2D(s_diffuse, tex_c); + #ifdef OFFSETMAPPING + vec2 tcoffsetmap = offsetmap(s_normalmap, tc, eyevector); + #define tc tcoffsetmap + #endif + + vec4 albedo_f = texture2D(s_diffuse, tc); + + #ifdef BUMP + vec3 normal_f = normalize(texture2D(s_normalmap, tc).rgb - 0.5); + #else + vec3 normal_f = vec3(0.0, 0.0, 1.0); #endif -#endif #ifdef UPPER - vec4 uc = texture2D(s_upper, tex_c); - - if (e_colourident.z == 2.0) { - vec3 topcolor = hsv2rgb(e_colourident.x * 360, 100, 100); - diffuse_f.rgb += uc.rgb*topcolor*uc.a; - } else { - diffuse_f.rgb += uc.rgb*e_uppercolour*uc.a; - } + vec4 uc = texture2D(s_upper, tc); + albedo_f.rgb += uc.rgb * e_uppercolour * uc.a; #endif #ifdef LOWER - vec4 lc = texture2D(s_lower, tex_c); - - if (e_colourident.z == 2.0) { - vec3 bottomcolor = hsv2rgb(e_colourident.y * 360, 100, 100); - diffuse_f.rgb += lc.rgb*bottomcolor*lc.a; - } else { - diffuse_f.rgb += lc.rgb*e_lowercolour*lc.a; - } + vec4 lc = texture2D(s_lower, tc); + albedo_f.rgb += lc.rgb * e_lowercolour * lc.a; #endif - diffuse_f.rgb *= light; + #ifdef PBR + float metalness_f = texture2D(s_specular, tc).r; + float roughness_f = texture2D(s_specular, tc).g; + float ao = texture2D(s_specular, tc).b; -#ifdef REFLECTCUBE + /* coords */ vec3 cube_c; - vec4 out_f = vec4( 1.0, 1.0, 1.0, 1.0 ); - cube_c = reflect( normalize( -eyevector ), vec3( 0, 0, 1 ) ); + /* calculate cubemap texcoords */ + cube_c = reflect(-normalize(eyevector), normal_f.rgb); cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2]; - cube_c = ( m_model * vec4( cube_c.xyz, 0.0 ) ).xyz; - out_f.rgb = mix( textureCube( s_reflectcube, cube_c ).rgb, diffuse_f.rgb, diffuse_f.a ); - diffuse_f = out_f; -#endif + cube_c = (m_model * vec4(cube_c.xyz, 0.0)).xyz; - if (e_colourident.z != 2.0) { - diffuse_f *= e_colourident; - } + /* do PBR reflection using cubemap */ + gl_FragColor = albedo_f + (metalness_f * textureCube(s_reflectcube, cube_c)); - #if gl_stipplealpha==1 - float alpha = e_colourident.a; - int x = int(mod(gl_FragCoord.x, 2.0)); - int y = int(mod(gl_FragCoord.y, 2.0)); - - if (alpha <= 0.0) { - discard; - } else if (alpha <= 0.25) { - diffuse_f.a = 1.0; - if (x + y == 2) - discard; - if (x + y == 1) - discard; - } else if (alpha <= 0.5) { - diffuse_f.a = 1.0; - if (x + y == 2) - discard; - if (x + y == 0) - discard; - } else if (alpha < 1.0) { - diffuse_f.a = 1.0; - if (x + y == 2) - discard; - } + /* do PBR specular using our handy function */ + gl_FragColor += (LightingFuncGGX(normal_f, normalize(eyevector), normalize(lightvector), roughness_f, FRESNEL) * gl_FragColor); + #else + gl_FragColor = albedo_f; #endif - #if gl_mono==1 - float bw = (diffuse_f.r + diffuse_f.g + diffuse_f.b) / 3.0; - diffuse_f.rgb = vec3(bw, bw, bw); - #endif + /* this isn't necessary if we're not doing lightgrid terms */ + gl_FragColor.rgb *= light; + /* r_shadows 2 */ #ifdef FAKESHADOWS - diffuse_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord); + gl_FragColor.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord); #endif - gl_FragColor = fog4(diffuse_f); + + #ifdef PBR + gl_FragColor.rgb *= ao; + #endif + + #ifdef FULLBRIGHT + vec4 fb = texture2D(s_fullbright, tc); + gl_FragColor.rgb += fb.rgb * fb.a * e_glowmod.rgb; + #endif + + gl_FragColor = fog4(gl_FragColor * e_colourident); } #endif diff --git a/base/resources.pk3dir/glsl/defaultskybox.glsl b/base/resources.pk3dir/glsl/defaultskybox.glsl deleted file mode 100644 index 144e75a2..00000000 --- a/base/resources.pk3dir/glsl/defaultskybox.glsl +++ /dev/null @@ -1,30 +0,0 @@ -!!ver 130 -!!permu FOG -!!samps reflectcube -!!cvardf gl_mono=0 - -#include "sys/defs.h" -#include "sys/fog.h" - -varying vec3 pos; -#ifdef VERTEX_SHADER -void main () -{ - pos = v_position.xyz - e_eyepos; - pos.y = -pos.y; - gl_Position = ftetransform(); -} -#endif -#ifdef FRAGMENT_SHADER -void main () -{ - vec4 skybox = textureCube(s_reflectcube, pos); - - if (gl_mono == 1.0) { - float bw = (skybox.r + skybox.g + skybox.b) / 3.0; - skybox.rgb = vec3(bw, bw, bw) * 1.5; - } - - gl_FragColor = vec4(fog3(skybox.rgb), 1.0); -} -#endif diff --git a/base/resources.pk3dir/glsl/defaultsprite.glsl b/base/resources.pk3dir/glsl/defaultsprite.glsl deleted file mode 100644 index 2ee22702..00000000 --- a/base/resources.pk3dir/glsl/defaultsprite.glsl +++ /dev/null @@ -1,74 +0,0 @@ -!!ver 130 -!!permu FOG -!!samps 1 -!!cvardf gl_mono=0 -!!cvardf gl_kdither=0 - -#include "sys/fog.h" -#ifdef VERTEX_SHADER -attribute vec2 v_texcoord; -attribute vec4 v_colour; -varying vec2 tc; -varying vec4 vc; -void main () -{ - tc = v_texcoord; - vc = v_colour; - gl_Position = ftetransform(); -} -#endif - -#ifdef FRAGMENT_SHADER -varying vec2 tc; -varying vec4 vc; -uniform vec4 e_colourident; -uniform vec4 e_vlscale; - - vec4 kernel_dither(sampler2D targ, vec2 texc) - { - int x = int(mod(gl_FragCoord.x, 2.0)); - int y = int(mod(gl_FragCoord.y, 2.0)); - int index = x + y * 2; - vec2 coord_ofs; - vec2 size; - - size.x = 1.0 / textureSize(targ, 0).x; - size.y = 1.0 / textureSize(targ, 0).y; - - if (index == 0) - coord_ofs = vec2(0.25, 0.0); - else if (index == 1) - coord_ofs = vec2(0.50, 0.75); - else if (index == 2) - coord_ofs = vec2(0.75, 0.50); - else if (index == 3) - coord_ofs = vec2(0.00, 0.25); - - return texture2D(targ, texc + coord_ofs * size); - } - - void main () - { - vec4 col; - - #if gl_kdither==1 - col = texture2D(s_t0, tc); - #else - col = texture2D(s_t0, tc); - #endif - - #ifdef MASK - if (col.a < float(MASK)) - discard; - #endif - - col = fog4blend(col * vc * e_colourident * e_vlscale); - - #if gl_mono==1 - float bw = (col.r + col.g + col.b) / 3.0; - col.rgb = vec3(bw, bw, bw) * 1.5; - #endif - - gl_FragColor = col; - } -#endif diff --git a/base/resources.pk3dir/glsl/defaultwall.glsl b/base/resources.pk3dir/glsl/defaultwall.glsl index f3beb2ff..28760d3b 100644 --- a/base/resources.pk3dir/glsl/defaultwall.glsl +++ b/base/resources.pk3dir/glsl/defaultwall.glsl @@ -1,37 +1,56 @@ -!!ver 130 -!!permu LIGHTSTYLED -!!permu FOG -!!samps diffuse reflectcube normalmap +//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= +// +// Purpose: +// +// Lightmapped surface that contains an environment cube as a reflection. +// Alpha channel of the diffuse decides reflectivity. +//============================================================================== +!!ver 100 150 + +!!permu FOG +!!permu BUMP +!!permu DELUXE +!!permu SPECULAR +!!permu FULLBRIGHT !!permu FAKESHADOWS -!!cvardf r_glsl_pcf +!!permu OFFSETMAPPING + +!!samps diffuse lightmap +!!samps =BUMP normalmap +!!samps =DELUXE deluxemap +!!samps =SPECULAR specular reflectcube +!!samps =FULLBRIGHT fullbright +!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3 +!!samps =LIGHTSTYLED =DELUXE deluxemap1 deluxemap2 deluxemap3 !!samps =FAKESHADOWS shadowmap -!!samps lightmap -!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3 -!!cvardf gl_mono -!!cvardf gl_kdither -!!cvardf gl_stipplealpha -!!cvardf gl_ldr - +!!cvardf r_glsl_pcf +!!cvarf r_glsl_offsetmapping_scale !!cvardf r_skipDiffuse +!!cvardf r_skipNormal +!!cvardf r_skipSpecular !!cvardf r_skipLightmap +#ifndef FRESNEL +#define FRESNEL 0.25f +#endif + #include "sys/defs.h" -#include "sys/fog.h" varying vec2 tex_c; +#ifdef BUMP +varying vec3 eyevector; +varying mat3 invsurface; +#define PBR +#endif + varying vec2 lm0; #ifdef LIGHTSTYLED varying vec2 lm1, lm2, lm3; #endif -#ifdef REFLECTCUBE -varying vec3 eyevector; -varying mat3 invsurface; -#endif - #ifdef FAKESHADOWS varying vec4 vtexprojcoord; #endif @@ -47,179 +66,183 @@ varying mat3 invsurface; #endif } - void main () + void main (void) { lightmapped_init(); - tex_c = v_texcoord; - gl_Position = ftetransform(); - /* HACK: func_conveyor needs us to scroll this surface! */ - if (e_glowmod.g == 0.5) - tex_c[0] += (e_time * (e_glowmod.b * 1024.0)) * -0.01; - -#ifdef REFLECTCUBE + #ifdef PBR invsurface[0] = v_svector; invsurface[1] = v_tvector; invsurface[2] = v_normal; vec3 eyeminusvertex = e_eyepos - v_position.xyz; - eyevector.x = dot( eyeminusvertex, v_svector.xyz ); - eyevector.y = dot( eyeminusvertex, v_tvector.xyz ); - eyevector.z = dot( eyeminusvertex, v_normal.xyz ); -#endif + eyevector.x = dot(eyeminusvertex, v_svector.xyz); + eyevector.y = dot(eyeminusvertex, v_tvector.xyz); + eyevector.z = dot(eyeminusvertex, v_normal.xyz); + #endif + + tex_c = v_texcoord; + gl_Position = ftetransform(); + + #ifdef FAKESHADOWS + vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); + #endif } #endif #ifdef FRAGMENT_SHADER + #include "sys/fog.h" #include "sys/pcf.h" + #ifdef OFFSETMAPPING + #include "sys/offsetmapping.h" + #endif + #if r_skipLightmap==0 - vec3 lightmap_fragment(void) + #ifdef LIGHTSTYLED + #define LIGHTMAP0 texture2D(s_lightmap0, lm0).rgb + #define LIGHTMAP1 texture2D(s_lightmap1, lm1).rgb + #define LIGHTMAP2 texture2D(s_lightmap2, lm2).rgb + #define LIGHTMAP3 texture2D(s_lightmap3, lm3).rgb + #else + #define LIGHTMAP texture2D(s_lightmap, lm0).rgb + #endif +#else + #ifdef LIGHTSTYLED + #define LIGHTMAP0 vec3(0.5,0.5,0.5) + #define LIGHTMAP1 vec3(0.5,0.5,0.5) + #define LIGHTMAP2 vec3(0.5,0.5,0.5) + #define LIGHTMAP3 vec3(0.5,0.5,0.5) + #else + #define LIGHTMAP vec3(0.5,0.5,0.5) + #endif +#endif + + float LightingFuncGGX(vec3 N, vec3 V, vec3 L, float roughness, float F0) + { + float alpha = roughness*roughness; + + vec3 H = normalize(V+L); + + float dotNL = clamp(dot(N,L), 0.0, 1.0); + float dotLH = clamp(dot(L,H), 0.0, 1.0); + float dotNH = clamp(dot(N,H), 0.0, 1.0); + + float F, D, vis; + + // D + float alphaSqr = alpha*alpha; + float pi = 3.14159f; + float denom = dotNH * dotNH *(alphaSqr-1.0) + 1.0f; + D = alphaSqr/(pi * denom * denom); + + // F + float dotLH5 = pow(1.0f-dotLH,5); + F = F0 + (1.0-F0)*(dotLH5); + + // V + float k = alpha/2.0f; + float k2 = k*k; + float invK2 = 1.0f-k2; + vis = 1.0/(dotLH*dotLH*invK2 + k2); + + float specular = dotNL * D * F * vis; + return specular; + } + + vec3 lightmap_fragment() { vec3 lightmaps; -#ifdef LIGHTSTYLED - lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb; - lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb; - lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb; - lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb; -#else - lightmaps = texture2D(s_lightmap, lm0).rgb * e_lmscale.rgb; -#endif - if (gl_ldr == 1.0) { - - if (lightmaps.r > 1.5) - lightmaps.r = 1.5; - if (lightmaps.g > 1.5) - lightmaps.g = 1.5; - if (lightmaps.b > 1.5) - lightmaps.b = 1.5; - - lightmaps.rgb * 0.5; - lightmaps.rgb = floor(lightmaps.rgb * vec3(32,64,32))/vec3(32,64,32); - lightmaps.rgb * 2.0; - } - + #ifdef LIGHTSTYLED + lightmaps = LIGHTMAP0 * e_lmscale[0].rgb; + lightmaps += LIGHTMAP1 * e_lmscale[1].rgb; + lightmaps += LIGHTMAP2 * e_lmscale[2].rgb; + lightmaps += LIGHTMAP3 * e_lmscale[3].rgb; + #else + lightmaps = LIGHTMAP * e_lmscale.rgb; + #endif return lightmaps; } -#else - vec3 lightmap_fragment(void) + +#if r_skipNormal==0 + vec3 lightmap_fragment(vec3 normal_f) { - return vec3(1.0,1.0,1.0); + #ifndef DELUXE + return lightmap_fragment(); + #else + vec3 lightmaps; + + #ifdef LIGHTSTYLED + lightmaps = LIGHTMAP0 * e_lmscale[0].rgb * dot(normal_f, texture2D(s_deluxemap0, lm0).rgb); + lightmaps += LIGHTMAP1 * e_lmscale[1].rgb * dot(normal_f, texture2D(s_deluxemap1, lm1).rgb); + lightmaps += LIGHTMAP2 * e_lmscale[2].rgb * dot(normal_f, texture2D(s_deluxemap2, lm2).rgb); + lightmaps += LIGHTMAP3 * e_lmscale[3].rgb * dot(normal_f, texture2D(s_deluxemap3, lm3).rgb); + #else + lightmaps = LIGHTMAP * e_lmscale.rgb * dot(normal_f, texture2D(s_deluxemap, lm0).rgb); + #endif + + return lightmaps; + #endif } #endif - vec4 kernel_dither(sampler2D targ, vec2 texc) + void main (void) { - int x = int(mod(gl_FragCoord.x, 2.0)); - int y = int(mod(gl_FragCoord.y, 2.0)); - int index = x + y * 2; - vec2 coord_ofs; - vec2 size; - - size.x = 1.0 / textureSize(targ, 0).x; - size.y = 1.0 / textureSize(targ, 0).y; - - if (index == 0) - coord_ofs = vec2(0.25, 0.0); - else if (index == 1) - coord_ofs = vec2(0.50, 0.75); - else if (index == 2) - coord_ofs = vec2(0.75, 0.50); - else if (index == 3) - coord_ofs = vec2(0.00, 0.25); - - return texture2D(targ, texc + coord_ofs * size); - } - - void main ( void ) - { - vec4 diffuse_f; - -#if r_skipDiffuse==1 - diffuse_f = vec4(1.0,1.0,1.0,1.0); -#else - #if gl_kdither==1 - diffuse_f = kernel_dither(s_diffuse, tex_c); + #ifdef OFFSETMAPPING + vec2 tcoffsetmap = offsetmap(s_normalmap, tex_c, eyevector); #else - diffuse_f = texture2D(s_diffuse, tex_c); + #define tcoffsetmap tex_c #endif -#endif -/* get the alphatesting out of the way first */ -#ifdef MASK - /* HACK: terrible hack, CSQC sets this to mark surface as an entity - only entities are alphatested - ever */ - if (e_glowmod.r == 0.5) - if (diffuse_f.a < 0.6) { - discard; - } -#endif - /* lighting */ - //diffuse_f.rgb = vec3(1,1,1); - diffuse_f.rgb *= lightmap_fragment(); + /* samplers */ + vec4 albedo_f = texture2D(s_diffuse, tcoffsetmap); // diffuse RGBA + vec3 normal_f = normalize(texture2D(s_normalmap, tcoffsetmap).rgb - 0.5); // normalmap RGB -#ifdef REFLECTCUBE - #ifdef BUMP - #ifndef FLATTENNORM - vec3 normal_f = normalize(texture2D(s_normalmap, tex_c).rgb - 0.5); - #else - // For very flat surfaces and gentle surface distortions, the 8-bit precision per channel in the normalmap - // can be insufficient. This is a hack to instead have very wobbly normalmaps that make use of the 8 bits - // and then scale the wobblyness back once in the floating-point domain. - vec3 normal_f = texture2D(s_normalmap, tex_c).rgb - 0.5; - normal_f.x *= 0.0625; - normal_f.y *= 0.0625; - normal_f = normalize(normal_f); - #endif - #else - vec3 normal_f = vec3(0, 0, 1); - #endif + /* deluxe/light */ + vec3 deluxe = normalize(texture2D(s_deluxemap, lm0).rgb); + + #ifdef PBR + float metalness_f =texture2D(s_specular, tcoffsetmap).r; // specularmap R + float roughness_f = texture2D(s_specular, tcoffsetmap).g; // specularmap G + float ao = texture2D(s_specular, tcoffsetmap).b; // specularmap B + + /* coords */ vec3 cube_c; - cube_c = reflect( normalize(-eyevector), normal_f); + /* calculate cubemap texcoords */ + cube_c = reflect(-normalize(eyevector), normal_f.rgb); cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2]; - cube_c = ( m_model * vec4(cube_c.xyz, 0.0)).xyz; - diffuse_f.rgb = mix( textureCube(s_reflectcube, cube_c ).rgb, diffuse_f.rgb, diffuse_f.a); -#endif + cube_c = (m_model * vec4(cube_c.xyz, 0.0)).xyz; - diffuse_f *= e_colourident; + /* do PBR reflection using cubemap */ + gl_FragColor = albedo_f + (metalness_f * textureCube(s_reflectcube, cube_c)); - #if gl_stipplealpha==1 - float alpha = e_colourident.a; - int x = int(mod(gl_FragCoord.x, 2.0)); - int y = int(mod(gl_FragCoord.y, 2.0)); - - if (alpha <= 0.0) { - discard; - } else if (alpha <= 0.25) { - diffuse_f.a = 1.0; - if (x + y == 2) - discard; - if (x + y == 1) - discard; - } else if (alpha <= 0.5) { - diffuse_f.a = 1.0; - if (x + y == 2) - discard; - if (x + y == 0) - discard; - } else if (alpha < 1.0) { - diffuse_f.a = 1.0; - if (x + y == 2) - discard; - } + /* do PBR specular using our handy function */ + gl_FragColor += (LightingFuncGGX(normal_f, normalize(eyevector), deluxe, roughness_f, FRESNEL) * gl_FragColor); + #else + gl_FragColor = albedo_f; #endif - #if gl_mono==1 - float bw = (diffuse_f.r + diffuse_f.g + diffuse_f.b) / 3.0; - diffuse_f.rgb = vec3(bw, bw, bw); - #endif + /* calculate lightmap fragment on top */ + gl_FragColor.rgb *= lightmap_fragment(normal_f); + /* r_shadows 2 */ #ifdef FAKESHADOWS - diffuse_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord); + gl_FragColor.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord); #endif - gl_FragColor = fog4(diffuse_f); - + /* emissive texture/fullbright bits */ + #ifdef FULLBRIGHT + vec3 emission_f = texture2D(s_fullbright, tcoffsetmap).rgb; // fullbrightmap RGB + gl_FragColor.rgb += emission_f; + #endif + + /* ambient occlusion */ + #ifdef PBR + gl_FragColor.rgb *= ao; + #endif + + /* and let the engine add fog on top */ + gl_FragColor = fog4(gl_FragColor); } #endif diff --git a/base/resources.pk3dir/glsl/defaultwarp.glsl b/base/resources.pk3dir/glsl/defaultwarp.glsl deleted file mode 100644 index 0770d245..00000000 --- a/base/resources.pk3dir/glsl/defaultwarp.glsl +++ /dev/null @@ -1,146 +0,0 @@ -!!ver 100 450 -!!permu FOG -!!samps diffuse lightmap -!!cvardf gl_mono=0 -!!cvardf gl_stipplealpha=0 -!!cvardf r_waterRipples=0 - -#include "sys/defs.h" -#include "sys/fog.h" - -varying vec2 tc; - -#ifdef LIT -varying vec2 lm0; -#endif - -#ifdef VERTEX_SHADER - void main () - { - tc = v_texcoord.st; - #ifdef FLOW - tc.s += e_time * -0.5; - #endif - #ifdef LIT - lm0 = v_lmcoord; - #endif - gl_Position = ftetransform(); - } -#endif - -#ifdef FRAGMENT_SHADER -#ifndef ALPHA - #define USEALPHA 1.0 -#else - #define USEALPHA float(ALPHA) -#endif - - - -// Hash functions shamefully stolen from: -// https://www.shadertoy.com/view/4djSRW -#define HASHSCALE1 .1031 -#define HASHSCALE3 vec3(.1031, .1030, .0973) - -float hash12(vec2 p) -{ - vec3 p3 = fract(vec3(p.xyx) * HASHSCALE1); - p3 += dot(p3, p3.yzx + 19.19); - return fract((p3.x + p3.y) * p3.z); -} - -vec2 hash22(vec2 p) -{ - vec3 p3 = fract(vec3(p.xyx) * HASHSCALE3); - p3 += dot(p3, p3.yzx+19.19); - return fract((p3.xx+p3.yz)*p3.zy); - -} - - void main () - { - vec2 ntc; - ntc.s = tc.s + sin(tc.t+ e_time)*0.125; - ntc.t = tc.t + sin(tc.s+ e_time)*0.125; - vec4 diffuse_f = texture2D(s_diffuse, ntc); - - diffuse_f *= e_colourident; - - // awful stipple alpha code - #if gl_stipplealpha==1 - float alpha = USEALPHA * e_colourident.a; - int x = int(mod(gl_FragCoord.x, 2.0)); - int y = int(mod(gl_FragCoord.y, 2.0)); - - if (alpha <= 0.0) { - discard; - } else if (alpha <= 0.25) { - diffuse_f.a = 1.0; - if (x + y == 2) - discard; - if (x + y == 1) - discard; - } else if (alpha <= 0.5) { - diffuse_f.a = 1.0; - if (x + y == 2) - discard; - if (x + y == 0) - discard; - } else if (alpha < 1.0) { - diffuse_f.a = 1.0; - if (x + y == 2) - discard; - } - #else - #ifdef LIT - - #define MAX_RADIUS 2 - - #if r_waterRipples ==1 - float resolution = 5.0f; - float riptime = e_time; - vec2 uv = tc.xy * resolution; - vec2 p0 = floor(uv); - vec2 circles = vec2(0.); - for (int j = -MAX_RADIUS; j <= MAX_RADIUS; ++j) { - for (int i = -MAX_RADIUS; i <= MAX_RADIUS; ++i) { - vec2 pi = p0 + vec2(i, j); - #if DOUBLE_HASH - vec2 hsh = hash22(pi); - #else - vec2 hsh = pi; - #endif - vec2 p = pi + hash22(hsh); - - float t = fract(0.3* riptime + hash12(hsh)); - vec2 v = p - uv; - float d = length(v) - (float(MAX_RADIUS) + 1.)*t; - - float h = 1e-3; - float d1 = d - h; - float d2 = d + h; - float p1 = sin(31.*d1) * smoothstep(-0.6, -0.3, d1) * smoothstep(0., -0.3, d1); - float p2 = sin(31.*d2) * smoothstep(-0.6, -0.3, d2) * smoothstep(0., -0.3, d2); - circles += .05 * normalize(v) * ((p2 - p1) / (2. * h) * (1. - t) * (1. - t)); - } - } - circles /= float((MAX_RADIUS*2+1)*(MAX_RADIUS*2+1)); - - float intensity = mix(0.01, 0.15, smoothstep(0.1, 0.6, abs(fract(0.05* riptime + 0.5)*2.-1.))); - vec3 n = vec3(circles, sqrt(1. - dot(circles, circles))); - - diffuse_f = texture2D(s_diffuse, tc + n.yz); - #endif - //diffuse_f.rgb += pow(clamp(dot(n, normalize(vec3(1., 0.7, 0.5))), 0., 1.), 6.); - diffuse_f.rgb *= (texture2D(s_lightmap, lm0) * e_lmscale).rgb; - #endif - #endif - - #if gl_mono==1 - float bw = (diffuse_f.r + diffuse_f.g + diffuse_f.b) / 3.0; - diffuse_f.rgb = vec3(bw, bw, bw); - #endif - - gl_FragColor = fog4(diffuse_f); - } -#endif diff --git a/base/resources.pk3dir/glsl/depthonly.glsl b/base/resources.pk3dir/glsl/depthonly.glsl deleted file mode 100644 index 99f4db6d..00000000 --- a/base/resources.pk3dir/glsl/depthonly.glsl +++ /dev/null @@ -1,29 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// None. -//============================================================================== - -!!ver 110 -!!permu FRAMEBLEND -!!permu SKELETAL - -#include "sys/defs.h" - -#ifdef VERTEX_SHADER - #include "sys/skeletal.h" - - void main () - { - gl_Position = skeletaltransform(); - } -#endif - -#ifdef FRAGMENT_SHADER - void main () - { - gl_FragColor = vec4(0, 0, 0, 1); - } -#endif - diff --git a/base/resources.pk3dir/glsl/fade.glsl b/base/resources.pk3dir/glsl/fade.glsl deleted file mode 100644 index 931308fb..00000000 --- a/base/resources.pk3dir/glsl/fade.glsl +++ /dev/null @@ -1,44 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Fades surfaces in with distance. It's the opposite of the clutter shader. -//============================================================================== - -!!ver 110 -!!samps diffuse=0 - -#include "sys/defs.h" -#include "sys/fog.h" - -varying vec2 tex_c; -varying float eyedist; - -#ifndef TINT -#define TINT 1.0,1.0,1.0 -#endif - -#ifdef VERTEX_SHADER -void main () -{ - tex_c = v_texcoord; - eyedist = abs( length( e_eyepos - v_position.xyz ) ) / 1024.0; - - if (eyedist > 1.0) { - eyedist = 1.0; - } else if (eyedist < 0.0) { - eyedist = 0.0; - } - - gl_Position = ftetransform(); -} -#endif - -#ifdef FRAGMENT_SHADER -void main () -{ - gl_FragColor = vec4( texture2D( s_diffuse, tex_c ).rgb * eyedist, eyedist ); - gl_FragColor *= e_colourident; - gl_FragColor.rgb *= vec3(TINT); -} -#endif diff --git a/base/resources.pk3dir/glsl/fill.glsl b/base/resources.pk3dir/glsl/fill.glsl deleted file mode 100644 index 876dba04..00000000 --- a/base/resources.pk3dir/glsl/fill.glsl +++ /dev/null @@ -1,33 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Fills any surface with a diffuse texture and applies vertex colors. -//============================================================================== - -!!ver 110 -!!samps tex=0 - -varying vec2 tc; -varying vec4 vc; - -#ifdef VERTEX_SHADER -attribute vec2 v_texcoord; -attribute vec4 v_colour; -void main () -{ - tc = v_texcoord; - vc = v_colour; - gl_Position = ftetransform(); -} -#endif - -#ifdef FRAGMENT_SHADER -void main () -{ - vec4 f = vc; - f.rgb *= f.a; - f *= texture2D(s_tex, tc); - gl_FragColor = f; -} -#endif diff --git a/base/resources.pk3dir/glsl/fullbright_reflect.glsl b/base/resources.pk3dir/glsl/fullbright_reflect.glsl deleted file mode 100644 index fdf4a5eb..00000000 --- a/base/resources.pk3dir/glsl/fullbright_reflect.glsl +++ /dev/null @@ -1,62 +0,0 @@ -!!ver 110 -!!samps diffuse reflectcube normalmap - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec3 eyevector; -varying mat3 invsurface; - -#ifdef VERTEX_SHADER - void main () - { - tex_c = v_texcoord; - gl_Position = ftetransform(); - - invsurface[0] = v_svector; - invsurface[1] = v_tvector; - invsurface[2] = v_normal; - vec3 eyeminusvertex = e_eyepos - v_position.xyz; - eyevector.x = dot( eyeminusvertex, v_svector.xyz ); - eyevector.y = dot( eyeminusvertex, v_tvector.xyz ); - eyevector.z = dot( eyeminusvertex, v_normal.xyz ); - } -#endif - -#ifdef FRAGMENT_SHADER - void main ( void ) - { - vec4 diffuse_f = texture2D(s_diffuse, tex_c); - - if (diffuse_f.rgb == vec3(0,0,1)) { - diffuse_f.rgb = vec3(0,0,0); - discard; - } - - #ifdef BUMP - #ifndef FLATTENNORM - vec3 normal_f = normalize(texture2D(s_normalmap, tex_c).rgb - 0.5); - #else - // For very flat surfaces and gentle surface distortions, the 8-bit precision per channel in the normalmap - // can be insufficient. This is a hack to instead have very wobbly normalmaps that make use of the 8 bits - // and then scale the wobblyness back once in the floating-point domain. - vec3 normal_f = texture2D(s_normalmap, tex_c).rgb - 0.5; - normal_f.x *= 0.0625; - normal_f.y *= 0.0625; - normal_f = normalize(normal_f); - #endif - #else - vec3 normal_f = vec3(0, 0, 1); - #endif - vec3 cube_c; - vec4 out_f = vec4( 1.0, 1.0, 1.0, 1.0 ); - - cube_c = reflect( normalize(-eyevector), normal_f); - cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2]; - cube_c = ( m_model * vec4(cube_c.xyz, 0.0)).xyz; - out_f.rgb = mix( textureCube(s_reflectcube, cube_c ).rgb, diffuse_f.rgb, diffuse_f.a); - diffuse_f = out_f * e_colourident; - - gl_FragColor = diffuse_f; - } -#endif diff --git a/base/resources.pk3dir/glsl/heat.glsl b/base/resources.pk3dir/glsl/heat.glsl deleted file mode 100644 index db989367..00000000 --- a/base/resources.pk3dir/glsl/heat.glsl +++ /dev/null @@ -1,56 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Non-lit surface that predominantly offers environment cube reflection -// modulated by the diffusemap's RGB. This is used for glass, for example. -//============================================================================== - -!!ver 110 -!!permu FOG -!!samps diffusemap=0 normalmap=1 reflect=2 - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec3 eyevector; -varying mat3 invsurface; -varying vec4 tf; - -#ifdef VERTEX_SHADER -void main () -{ - - tex_c = v_texcoord; - invsurface[0] = v_svector; - invsurface[1] = v_tvector; - invsurface[2] = v_normal; - vec3 eyeminusvertex = e_eyepos - v_position.xyz; - eyevector.x = dot( eyeminusvertex, v_svector.xyz ); - eyevector.y = dot( eyeminusvertex, v_tvector.xyz ); - eyevector.z = dot( eyeminusvertex, v_normal.xyz ); - tf = ftetransform(); - gl_Position = tf; -} -#endif - -#ifdef FRAGMENT_SHADER -#include "sys/fog.h" -void main () -{ - vec2 stc; - vec3 out_f; - vec4 diffuse_f = texture2D(s_diffusemap, tex_c); - vec3 norm_f; - - norm_f = ( texture2D( s_normalmap, tex_c + vec2( e_time * 0.01, 0.0 ) ).xyz); - norm_f += ( texture2D( s_normalmap, tex_c - vec2( 0, e_time * 0.01 ) ).xyz); - norm_f -= 1.0 - ( 4.0 / 256.0 ); - norm_f = normalize( norm_f ); - - stc = (1.0 + (tf.xy / tf.w)) * 0.5; - - diffuse_f.rgb = texture2D(s_reflect, stc + norm_f.st).rgb; - gl_FragColor = diffuse_f; -} -#endif diff --git a/base/resources.pk3dir/glsl/lensflare.glsl b/base/resources.pk3dir/glsl/lensflare.glsl deleted file mode 100644 index ac650c41..00000000 --- a/base/resources.pk3dir/glsl/lensflare.glsl +++ /dev/null @@ -1,33 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Shader used for fading out surfaces after a certain distance. -// It only has a diffuse map. -//============================================================================== - -!!ver 110 -!!samps diffuse=0 - -#include "sys/defs.h" -#include "sys/fog.h" - -varying vec2 tex_c; -varying vec4 vex_color; - -#ifdef VERTEX_SHADER -void main () -{ - tex_c = v_texcoord; - vex_color = v_colour; - gl_Position = ftetransform(); -} -#endif - -#ifdef FRAGMENT_SHADER -void main () -{ - vec4 diffuse_f = texture2D(s_diffuse, tex_c) * vex_color.a; - gl_FragColor = diffuse_f; -} -#endif diff --git a/base/resources.pk3dir/glsl/lightmapped.glsl b/base/resources.pk3dir/glsl/lightmapped.glsl deleted file mode 100644 index abbff2fa..00000000 --- a/base/resources.pk3dir/glsl/lightmapped.glsl +++ /dev/null @@ -1,245 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Lightmapped surface. -// -// diffusemap = albedo (rgba) -// normalmap = normal (rgb), reflectmask (a) -//============================================================================== - -!!ver 110 -!!permu FOG - -!!permu BUMP -!!permu DELUXE -!!permu LIGHTSTYLED -!!permu FULLBRIGHT -!!permu UPPERLOWER -!!samps diffuse - -!!samps lightmap -!!samps =BUMP normalmap reflectcube -!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3 -!!samps =DELUXE deluxemap -!!samps =LIGHTSTYLED =DELUXE deluxemap1 deluxemap2 deluxemap3 -!!samps =FULLBRIGHT fullbright -!!samps =UPPERLOWER upper - -!!permu FAKESHADOWS -!!cvardf r_glsl_pcf -!!cvardf r_fullbright -!!samps =FAKESHADOWS shadowmap - -!!cvardf r_skipDiffuse -!!cvardf r_skipFullbright -!!cvardf r_skipNormal -!!cvardf r_skipEnvmap -!!cvardf r_skipLightmap -!!cvardf r_skipDetail - -#include "sys/defs.h" - -// basics -varying vec2 tex_c; -varying vec2 lm0; - -// unfortunately we do support lightstyles -#if defined(LIGHTSTYLED) -varying vec2 lm1, lm2, lm3; -#endif - -// useful for terrain blending -varying vec4 vex_color; - -// dynamic shadows -#ifdef FAKESHADOWS -varying vec4 vtexprojcoord; -#endif - -#ifdef BUMP -varying vec3 eyevector; -varying mat3 invsurface; -#endif - -varying vec3 norm; - -#ifdef VERTEX_SHADER - void lightmapped_init(void) - { - lm0 = v_lmcoord; - #if defined(LIGHTSTYLED) - lm1 = v_lmcoord2; - lm2 = v_lmcoord3; - lm3 = v_lmcoord4; - #endif - } - - void main () - { - lightmapped_init(); - tex_c = v_texcoord; - vex_color = v_colour; - gl_Position = ftetransform(); - - #ifdef FAKESHADOWS - vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); - #endif - - #ifdef BUMP - vec3 eyeminusvertex = e_eyepos - v_position.xyz; - eyevector.x = dot(eyeminusvertex, v_svector.xyz); - eyevector.y = dot(eyeminusvertex, v_tvector.xyz); - eyevector.z = dot(eyeminusvertex, v_normal.xyz); - invsurface[0] = v_svector; - invsurface[1] = v_tvector; - invsurface[2] = v_normal; - #endif - norm = v_normal; - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - #include "sys/pcf.h" - - #if defined(LIGHTSTYLED) - #define LIGHTMAP0 texture2D(s_lightmap0, lm0).rgb - #define LIGHTMAP1 texture2D(s_lightmap1, lm1).rgb - #define LIGHTMAP2 texture2D(s_lightmap2, lm2).rgb - #define LIGHTMAP3 texture2D(s_lightmap3, lm3).rgb - #else - #define LIGHTMAP texture2D(s_lightmap, lm0).rgb - #endif - -#if r_skipLightmap == 0 - vec3 lightmap_fragment() - { - vec3 lightmaps; - -#if defined(LIGHTSTYLED) - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb; - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb; - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb; - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb; -#else - lightmaps = LIGHTMAP * e_lmscale.rgb; -#endif - return (r_fullbright == 1) ? vec3(1.0, 1.0, 1.0) : lightmaps; - } - - vec3 lightmap_fragment(vec3 normal_f) - { -#ifndef DELUXE - return lightmap_fragment(); -#else - vec3 lightmaps; - - #if defined(LIGHTSTYLED) - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb * dot(normal_f, texture2D(s_deluxemap0, lm0).rgb); - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb * dot(normal_f, texture2D(s_deluxemap1, lm1).rgb); - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb * dot(normal_f, texture2D(s_deluxemap2, lm2).rgb); - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb * dot(normal_f, texture2D(s_deluxemap3, lm3).rgb); - #else - lightmaps = LIGHTMAP * e_lmscale.rgb * dot(normal_f, texture2D(s_deluxemap, lm0).rgb); - #endif - - return (r_fullbright == 1) ? vec3(1.0, 1.0, 1.0) : lightmaps; -#endif - } -#else - vec3 lightmap_fragment() - { - return vec3(1.0,1.0,1.0); - } - vec3 lightmap_fragment(vec3 normal_f) - { - return vec3(1.0,1.0,1.0); - } -#endif - - float lambert(vec3 normal, vec3 dir) - { - return max(dot(normal, dir), 0.0); - } - - void main (void) - { - vec4 diffuse_f; - float alpha; - - #if r_skipDiffuse == 0 - diffuse_f = texture2D(s_diffuse, tex_c); - #else - diffuse_f = vec4(1.0, 1.0, 1.0, 1.0); - #endif - -#ifdef MASK - // alpha-testing happens here - if (diffuse_f.a < MASK) - discard; -#endif - - #if r_skipDetail == 0 - #if defined(UPPERLOWER) - diffuse_f.rgb *= (texture2D(s_upper, tex_c * 4.0).rgb + 0.5); - #endif - #endif - - #ifdef FAKESHADOWS - diffuse_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord); - #endif - - // the lighting stage for the world - #if defined(BUMP) - float refl = texture2D(s_normalmap, tex_c).a; - - // whether to respect our bump, or to act flat - #if r_skipNormal == 0 - vec3 normal_f = normalize(texture2D(s_normalmap, tex_c).rgb - 0.5); - diffuse_f.rgb *= lightmap_fragment(normal_f); - #else - vec3 normal_f = vec3(0.0, 0.0, 1.0); - diffuse_f.rgb *= lightmap_fragment(); - #endif - - // environment mapping happens here - #if r_skipEnvmap == 0 - vec3 cube_c; - vec3 env_f; - cube_c = reflect(normalize(-eyevector), vec3(0.0, 0.0, 1.0)); - cube_c = cube_c.x * invsurface[0] + - cube_c.y * invsurface[1] + - cube_c.z * invsurface[2]; - cube_c = (m_model * vec4(cube_c.xyz, 0.0)).xyz; - env_f = textureCube(s_reflectcube, cube_c).rgb * (e_lmscale.rgb * 0.25); - diffuse_f.rgb = mix(env_f, diffuse_f.rgb, refl); - #else - diffuse_f.rgb = mix(vec3(0.0, 0.0, 0.0), diffuse_f.rgb, refl); - #endif - #else - diffuse_f.rgb *= lightmap_fragment(); - #endif - - #if defined(FULLBRIGHT) && r_skipFullbright == 0 - diffuse_f.rgb += texture2D(s_fullbright, tex_c).rgb; - #endif - - #if defined (VERTEXLIT) - vec3 light; - /* directional light */ - light = (vec3(0.5,0.5,0.5) * lambert(norm, vec3(-1,-0.5,0.5))) * 2.0; - light += (vec3(0.25,0.25,0.25) * lambert(norm, reflect(norm, vec3(0.75, 0, 0)))) * 0.5; - light *= 2.0; - diffuse_f.rgb = texture2D(s_diffuse, tex_c).rgb * light; - #endif - - // start blend at half-way point - alpha = vex_color.a * 1.5; - - if (alpha > 1.0) - alpha = 1.0; - - gl_FragColor = vec4(fog3(diffuse_f.rgb), alpha); - } -#endif diff --git a/base/resources.pk3dir/glsl/lightmapped_reflect.glsl b/base/resources.pk3dir/glsl/lightmapped_reflect.glsl deleted file mode 100644 index ba533a8e..00000000 --- a/base/resources.pk3dir/glsl/lightmapped_reflect.glsl +++ /dev/null @@ -1,167 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Lightmapped surface that effectively acts as a mirror. -// Alpha channel of the diffusemap is referenced for reflectivity. -//============================================================================== - -!!ver 110 -!!permu FOG -!!permu BUMP -!!permu DELUXE -!!samps diffuse lightmap deluxemap normalmap -!!samps reflect=0 - -!!permu FAKESHADOWS -!!cvardf r_glsl_pcf -!!samps =FAKESHADOWS shadowmap - -!!cvardf r_skipDiffuse -!!cvardf r_skipNormal -!!cvardf r_skipLightmap - -#include "sys/defs.h" - -varying vec2 tex_c; -varying mat3 invsurface; -varying vec4 tf; - -varying vec2 lm0; -#ifdef LIGHTSTYLED -varying vec2 lm1, lm2, lm3; -#endif - -#ifdef FAKESHADOWS - varying vec4 vtexprojcoord; -#endif - -#ifdef VERTEX_SHADER - void lightmapped_init(void) - { - lm0 = v_lmcoord; - #ifdef LIGHTSTYLED - lm1 = v_lmcoord2; - lm2 = v_lmcoord3; - lm3 = v_lmcoord4; - #endif - } - - void main (void) - { - lightmapped_init(); - invsurface[0] = v_svector; - invsurface[1] = v_tvector; - invsurface[2] = v_normal; - - tf = ftetransform(); - tex_c = v_texcoord; - gl_Position = tf; - - #ifdef FAKESHADOWS - vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); - #endif - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - #include "sys/pcf.h" - - #define s_reflect s_t0 - -#if r_skipLightmap==0 - #ifdef LIGHTSTYLED - #define LIGHTMAP0 texture2D(s_lightmap0, lm0).rgb - #define LIGHTMAP1 texture2D(s_lightmap1, lm1).rgb - #define LIGHTMAP2 texture2D(s_lightmap2, lm2).rgb - #define LIGHTMAP3 texture2D(s_lightmap3, lm3).rgb - #else - #define LIGHTMAP texture2D(s_lightmap, lm0).rgb - #endif -#else - #ifdef LIGHTSTYLED - #define LIGHTMAP0 vec3(0.5,0.5,0.5) - #define LIGHTMAP1 vec3(0.5,0.5,0.5) - #define LIGHTMAP2 vec3(0.5,0.5,0.5) - #define LIGHTMAP3 vec3(0.5,0.5,0.5) - #else - #define LIGHTMAP vec3(0.5,0.5,0.5) - #endif -#endif - - vec3 lightmap_fragment() - { - vec3 lightmaps; - -#ifdef LIGHTSTYLED - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb; - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb; - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb; - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb; -#else - lightmaps = LIGHTMAP * e_lmscale.rgb; -#endif - return lightmaps; - } - -#if r_skipNormal==0 - vec3 lightmap_fragment(vec3 normal_f) - { -#ifndef DELUXE - return lightmap_fragment(); -#else - vec3 lightmaps; - - #if defined(LIGHTSTYLED) - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb * dot(normal_f, texture2D(s_deluxemap0, lm0).rgb); - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb * dot(normal_f, texture2D(s_deluxemap1, lm1).rgb); - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb * dot(normal_f, texture2D(s_deluxemap2, lm2).rgb); - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb * dot(normal_f, texture2D(s_deluxemap3, lm3).rgb ); - #else - lightmaps = LIGHTMAP * e_lmscale.rgb * dot(normal_f, texture2D(s_deluxemap, lm0).rgb); - #endif - - return lightmaps; -#endif - } -#endif - - void main (void) - { - vec2 stc; - vec4 diffuse_f; - - #if r_skipDiffuse == 0 - diffuse_f = texture2D(s_diffuse, tex_c); - #else - diffuse_f = vec4(1.0, 1.0, 1.0, 1.0); - #endif - - #if r_skipNormal==1 - #define normal_f vec3(0.0,0.0,0.5) - #else - vec3 normal_f = normalize(texture2D(s_normalmap, tex_c).rgb - 0.5); - #endif - - float refl = texture2D(s_normalmap, tex_c).a; - - #if r_skipNormal==1 - diffuse_f.rgb *= lightmap_fragment(); - #else - diffuse_f.rgb *= lightmap_fragment(normal_f); - #endif - - /* map the reflection buffer onto the surface */ - stc = (1.0 + (tf.xy / tf.w)) * 0.5; - stc.t -= 1.5* invsurface[2].z / 1080.0; - - diffuse_f.rgb = mix(texture2D(s_reflect, stc).rgb, diffuse_f.rgb, refl); - - #ifdef FAKESHADOWS - diffuse_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord); - #endif - - gl_FragColor = fog4(diffuse_f); - } -#endif diff --git a/base/resources.pk3dir/glsl/lightmapped_specular.glsl b/base/resources.pk3dir/glsl/lightmapped_specular.glsl deleted file mode 100644 index a4e477e0..00000000 --- a/base/resources.pk3dir/glsl/lightmapped_specular.glsl +++ /dev/null @@ -1,166 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Lightmapped surface, normalmap's alpha contains the reference for how -// specular it should be. -//============================================================================== - -!!ver 110 -!!permu FOG -!!permu BUMP -!!permu DELUXE -!!samps diffuse normalmap lightmap deluxemap - -!!permu FAKESHADOWS -!!cvardf r_glsl_pcf -!!samps =FAKESHADOWS shadowmap - -!!cvardf r_skipDiffuse -!!cvardf r_skipNormal -!!cvardf r_skipSpecular -!!cvardf r_skipLightmap - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec3 eyevector; - -varying vec2 lm0; -#ifdef LIGHTSTYLED -varying vec2 lm1, lm2, lm3; -#endif - -#ifdef FAKESHADOWS - varying vec4 vtexprojcoord; -#endif - -#ifdef VERTEX_SHADER - void lightmapped_init(void) - { - lm0 = v_lmcoord; - #ifdef LIGHTSTYLED - lm1 = v_lmcoord2; - lm2 = v_lmcoord3; - lm3 = v_lmcoord4; - #endif - } - - void main () - { - lightmapped_init(); - tex_c = v_texcoord; - - vec3 eyeminusvertex = e_eyepos - v_position.xyz; - eyevector.x = dot(eyeminusvertex, v_svector.xyz); - eyevector.y = dot(eyeminusvertex, v_tvector.xyz); - eyevector.z = dot(eyeminusvertex, v_normal.xyz); - - gl_Position = ftetransform(); - - #ifdef FAKESHADOWS - vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); - #endif - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - #include "sys/pcf.h" - -#if r_skipLightmap==0 - #ifdef LIGHTSTYLED - #define LIGHTMAP0 texture2D(s_lightmap0, lm0).rgb - #define LIGHTMAP1 texture2D(s_lightmap1, lm1).rgb - #define LIGHTMAP2 texture2D(s_lightmap2, lm2).rgb - #define LIGHTMAP3 texture2D(s_lightmap3, lm3).rgb - #else - #define LIGHTMAP texture2D(s_lightmap, lm0).rgb - #endif -#else - #ifdef LIGHTSTYLED - #define LIGHTMAP0 vec3(0.5,0.5,0.5) - #define LIGHTMAP1 vec3(0.5,0.5,0.5) - #define LIGHTMAP2 vec3(0.5,0.5,0.5) - #define LIGHTMAP3 vec3(0.5,0.5,0.5) - #else - #define LIGHTMAP vec3(0.5,0.5,0.5) - #endif -#endif - - vec3 lightmap_fragment() - { - vec3 lightmaps; - -#ifdef LIGHTSTYLED - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb; - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb; - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb; - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb; -#else - lightmaps = LIGHTMAP * e_lmscale.rgb; -#endif - return lightmaps; - } - -#if r_skipNormal==0 - vec3 lightmap_fragment(vec3 normal_f) - { -#ifndef DELUXE - return lightmap_fragment(); -#else - vec3 lightmaps; - - #if defined(LIGHTSTYLED) - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb * dot(normal_f, texture2D(s_deluxemap0, lm0).rgb); - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb * dot(normal_f, texture2D(s_deluxemap1, lm1).rgb); - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb * dot(normal_f, texture2D(s_deluxemap2, lm2).rgb); - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb * dot(normal_f, texture2D(s_deluxemap3, lm3).rgb); - #else - lightmaps = LIGHTMAP * e_lmscale.rgb * dot(normal_f, texture2D(s_deluxemap, lm0).rgb); - #endif - - return lightmaps; -#endif - } -#endif - - void main (void) - { - #if r_skipDiffuse==0 - vec4 diffuse_f = texture2D(s_diffuse, tex_c); - #else - vec4 diffuse_f = vec4(1.0,1.0,1.0,1.0); - #endif - - #if r_skipNormal==1 - vec3 normal_f = normalize(texture2D(s_normalmap, tex_c).rgb - 0.5); - #else - #define normal_f vec3(0.0,0.0,0.5) - #endif - - if (diffuse_f.a < 0.5) { - discard; - } - - #ifdef FAKESHADOWS - diffuse_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord); - #endif - - #if r_skipNormal==1 - diffuse_f.rgb *= lightmap_fragment(); - #else - diffuse_f.rgb *= lightmap_fragment(normal_f); - #endif - - #if r_skipSpecular==0 - float gloss = texture2D(s_normalmap, tex_c).a * 0.1; - vec3 halfdir = normalize(normalize(eyevector) - e_light_dir); - float spec = pow(max(dot(halfdir, normal_f), 0.0), FTE_SPECULAR_EXPONENT); - spec *= gloss; - diffuse_f.rgb += spec; - #endif - - gl_FragColor = fog4(diffuse_f); - } -#endif diff --git a/base/resources.pk3dir/glsl/portal.glsl b/base/resources.pk3dir/glsl/portal.glsl deleted file mode 100644 index d6a5ec44..00000000 --- a/base/resources.pk3dir/glsl/portal.glsl +++ /dev/null @@ -1,36 +0,0 @@ -//======= Copyright (c) 2023 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Unlit surface. -//============================================================================== - -!!ver 110 -!!permu FOG -!!samps diffuse - -#include "sys/defs.h" -#include "sys/fog.h" - -varying vec2 tex_c; - -#ifdef VERTEX_SHADER -void main () -{ - tex_c = v_texcoord; - gl_Position = ftetransform(); -} -#endif - -#ifdef FRAGMENT_SHADER -void main () -{ - vec4 d_f = vec4(1.0, 1.0, 1.0, 1.0) - texture2D( s_diffuse, tex_c ); - - if (d_f.a > 0.5) { - discard; - } - - gl_FragColor = fog4( d_f ); -} -#endif diff --git a/base/resources.pk3dir/glsl/pp_colorcorrect.glsl b/base/resources.pk3dir/glsl/pp_colorcorrect.glsl deleted file mode 100644 index 5f226171..00000000 --- a/base/resources.pk3dir/glsl/pp_colorcorrect.glsl +++ /dev/null @@ -1,31 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Default post-processing shader for the framebuffer. -// Does a 'dodge' filter onto the final scene. -//============================================================================== - -!!samps screen=0 - -#ifdef VERTEX_SHADER -attribute vec2 v_texcoord; -varying vec2 texcoord; - -void main() -{ - texcoord = v_texcoord.xy; - texcoord.y = 1.0 - texcoord.y; - gl_Position = ftetransform(); -} -#endif - -#ifdef FRAGMENT_SHADER -varying vec2 texcoord; -void main() -{ - vec4 colortint = vec4(COLOR); - vec3 dodged = vec3(1.0,1.0,1.0) - (colortint.rgb * colortint.a); - gl_FragColor.rgb = texture2D(s_screen, texcoord).rgb / dodged; -} -#endif diff --git a/base/resources.pk3dir/glsl/reflect.glsl b/base/resources.pk3dir/glsl/reflect.glsl deleted file mode 100644 index 8bdea399..00000000 --- a/base/resources.pk3dir/glsl/reflect.glsl +++ /dev/null @@ -1,53 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Non-lit surface that predominantly offers environment cube reflection -// modulated by the diffusemap's RGB. This is used for glass, for example. -//============================================================================== - -!!ver 110 -!!permu FOG -!!samps diffusemap=0 normalmap=1 cubemap:samplerCube=2 - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec3 eyevector; -varying mat3 invsurface; - -#ifdef VERTEX_SHADER -void main () -{ - - tex_c = v_texcoord; - invsurface[0] = v_svector; - invsurface[1] = v_tvector; - invsurface[2] = v_normal; - vec3 eyeminusvertex = e_eyepos - v_position.xyz; - eyevector.x = dot( eyeminusvertex, v_svector.xyz ); - eyevector.y = dot( eyeminusvertex, v_tvector.xyz ); - eyevector.z = dot( eyeminusvertex, v_normal.xyz ); - gl_Position = ftetransform(); -} -#endif - -#ifdef FRAGMENT_SHADER -#include "sys/fog.h" -void main () -{ - vec3 out_f; - vec3 diffuse_f = texture2D(s_diffusemap, tex_c).rgb; - vec3 normal_f = texture2D(s_normalmap, tex_c).rgb - 0.5; - normal_f.x *= 0.2; - normal_f.y *= 0.2; - normal_f = normalize(normal_f); - vec3 rtc = reflect( normalize( -eyevector ), normal_f ); - rtc = rtc.x * invsurface[0] + rtc.y * invsurface[1] + rtc.z * invsurface[2]; - rtc = ( m_model * vec4( rtc.xyz, 0.0 ) ).xyz; - - diffuse_f = textureCube(s_cubemap, rtc).rgb * (diffuse_f * 2.5); - - gl_FragColor = fog4(vec4( diffuse_f, 1.0 )); -} -#endif diff --git a/base/resources.pk3dir/glsl/refract.glsl b/base/resources.pk3dir/glsl/refract.glsl deleted file mode 100644 index 4aab4786..00000000 --- a/base/resources.pk3dir/glsl/refract.glsl +++ /dev/null @@ -1,45 +0,0 @@ -!!ver 110 -!!samps refraction=0 normalmap=1 - -#include "sys/defs.h" - -varying vec2 tex_c; -varying mat3 invsurface; -varying vec4 tf_c; -varying vec3 eyeminusvertex; - -#ifdef VERTEX_SHADER - void main () - { - invsurface[0] = v_svector; - invsurface[1] = v_tvector; - invsurface[2] = v_normal; - tf_c = ftetransform(); - tex_c = v_texcoord; - gl_Position = tf_c; - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - void main ( void ) - { - vec2 refl_c; - vec3 refr_f; - vec3 norm_f; - vec4 out_f = vec4( 1.0, 1.0, 1.0, 1.0 ); - - norm_f = ( texture2D( s_normalmap, tex_c + vec2( e_time * 0.01, 0.0 ) ).xyz); - norm_f += ( texture2D( s_normalmap, tex_c - vec2( 0, e_time * 0.01 ) ).xyz); - norm_f -= 1.0 - ( 4.0 / 256.0 ); - norm_f = normalize( norm_f ); - - // Reflection/View coordinates - refl_c = ( 1.0 + ( tf_c.xy / tf_c.w ) ) * 0.5; - - refr_f = texture2D( s_refraction, refl_c + ( norm_f.st) ).rgb; - out_f.rgb = refr_f; - - gl_FragColor = out_f; - } -#endif diff --git a/base/resources.pk3dir/glsl/rtlight.glsl b/base/resources.pk3dir/glsl/rtlight.glsl index 13b57e4f..b33f38b1 100644 --- a/base/resources.pk3dir/glsl/rtlight.glsl +++ b/base/resources.pk3dir/glsl/rtlight.glsl @@ -1,181 +1,230 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= +//======= Copyright (c) 2015-2021 Vera Visions LLC. All rights reserved. ======= // // Purpose: // -// Code for all the dynamic light passes. The renderer is not aware of any -// surface properties beyond diffuse, normal and specularity. -// Alpha-masked surfaces suffer greatly because of this. -// -// diffusemap = albedo (rgba) -// normalmap = normal (rgb), reflectmask (a) +// Lightmapped surface that contains an environment cube as a reflection. +// Alpha channel of the diffuse decides reflectivity. //============================================================================== -!!ver 100 300 +!!ver 100 150 + !!permu BUMP !!permu FRAMEBLEND !!permu SKELETAL -!!permu FOG !!permu UPPERLOWER +!!permu FOG +!!permu REFLECTCUBEMASK +!!cvarf r_glsl_offsetmapping_scale !!cvardf r_glsl_pcf -!!samps diffuse -!!samps =BUMP normalmap reflectcube -!!samps =PCF shadowmap -!!samps =CUBE projectionmap -!!samps =UPPERLOWER upper +!!cvardf r_glsl_fresnel -!!cvardf r_skipDiffuse +!!samps diffuse shadowmap projectionmap +!!samps =BUMP normalmap +!!samps =UPPERLOWER upper lower +!!samps =SPECULAR specular reflectcube +!!samps =FAKESHADOWS shadowmap #include "sys/defs.h" -//if there's no vertex normals known, disable some stuff. -//FIXME: this results in dupe permutations. -#ifdef NOBUMP - #undef SPECULAR - #undef BUMP -#endif - -varying vec2 tex_c; +varying vec2 tcbase; varying vec3 lightvector; -#define VERTEXCOLOURS - -#if defined(VERTEXCOLOURS) - varying vec4 vc; +#ifdef VERTEXCOLOURS +varying vec4 vc; #endif -#ifdef BUMP - varying vec3 eyevector; - varying mat3 invsurface; +#ifdef SPECULAR +varying vec3 eyevector; +varying mat3 invsurface; +#define PBR #endif -#if defined(PCF) || defined(CUBE) || defined(SPOT) || defined(ORTHO) - varying vec4 vtexprojcoord; +#if defined(PCF) || defined(CUBE) || defined(SPOT) +varying vec4 vtexprojcoord; #endif #ifdef VERTEX_SHADER #include "sys/skeletal.h" - void main () { vec3 n, s, t, w; gl_Position = skeletaltransform_wnst(w,n,s,t); - n = normalize(n); - s = normalize(s); - t = normalize(t); - tex_c = v_texcoord; - #ifdef ORTHO - vec3 lightminusvertex = -l_lightdirection; + tcbase = v_texcoord; //pass the texture coords straight through + vec3 lightminusvertex = l_lightposition - w.xyz; + + #ifdef NOBUMP + //the only important thing is distance + lightvector = lightminusvertex; + #else + //the light direction relative to the surface normal, for bumpmapping. lightvector.x = dot(lightminusvertex, s.xyz); lightvector.y = dot(lightminusvertex, t.xyz); lightvector.z = dot(lightminusvertex, n.xyz); - #else - vec3 lightminusvertex = l_lightposition - w.xyz; - #ifdef NOBUMP - lightvector = lightminusvertex; - #else - // light direction relative to the surface normal, for bumpmapping. - lightvector.x = dot(lightminusvertex, s.xyz); - lightvector.y = dot(lightminusvertex, t.xyz); - lightvector.z = dot(lightminusvertex, n.xyz); - #endif #endif - #if defined(VERTEXCOLOURS) + #ifdef VERTEXCOLOURS vc = v_colour; #endif - #ifdef BUMP + #ifdef SPECULAR vec3 eyeminusvertex = e_eyepos - w.xyz; eyevector.x = dot(eyeminusvertex, s.xyz); eyevector.y = dot(eyeminusvertex, t.xyz); eyevector.z = dot(eyeminusvertex, n.xyz); - invsurface = mat3(v_svector, v_tvector, v_normal); + invsurface[0] = v_svector; + invsurface[1] = v_tvector; + invsurface[2] = v_normal; #endif - #if defined(PCF) || defined(SPOT) || defined(CUBE) || defined(ORTHO) + #if defined(PCF) || defined(SPOT) || defined(CUBE) //for texture projections/shadowmapping on dlights vtexprojcoord = (l_cubematrix*vec4(w.xyz, 1.0)); #endif -} + } #endif + #ifdef FRAGMENT_SHADER + vec3 LightingFuncShlick(vec3 N, vec3 V, vec3 L, float roughness, vec3 Cdiff, vec3 F0) + { + vec3 H = normalize(V+L); + float NL = clamp(dot(N,L), 0.001, 1.0); + float LH = clamp(dot(L,H), 0.0, 1.0); + float NH = clamp(dot(N,H), 0.0, 1.0); + float NV = clamp(abs(dot(N,V)), 0.001, 1.0); + float VH = clamp(dot(V,H), 0.0, 1.0); + float PI = 3.14159f; + + //Fresnel term + //the fresnel models glancing light. + //(Schlick) + vec3 F = F0 + (1.0-F0)*pow(1.0-VH, 5.0); + + //Schlick + float k = roughness*0.79788456080286535587989211986876; + float G = (LH/(LH*(1.0-k)+k)) * (NH/(NH*(1.0-k)+k)); + + //microfacet distribution + float a = roughness*roughness; + a *= a; + float t = (NH*NH*(a-1.0)+1.0); + + float D = a/(PI*t*t); + + if (r_glsl_fresnel == 1) + return vec3(F); + if (r_glsl_fresnel == 2) + return vec3(G); + if (r_glsl_fresnel == 3) + return vec3(D); + + return ((1.0-F)*(Cdiff/PI) + + (F*G*D)/(4*NL*NV)) * NL; + } + #include "sys/fog.h" #include "sys/pcf.h" + #ifdef OFFSETMAPPING + #include "sys/offsetmapping.h" + #endif + void main () { + + #ifdef OFFSETMAPPING + vec2 tcoffsetmap = offsetmap(s_normalmap, tcbase, eyevector); + #define tcbase tcoffsetmap + #endif + + vec4 albedo_f = texture2D(s_diffuse, tcbase); + + #ifdef BUMP + vec3 normal_f = normalize(texture2D(s_normalmap, tcbase).rgb - 0.5); + #else + vec3 normal_f = vec3(0.0, 0.0, 1.0); + #endif + #ifdef ORTHO float colorscale = 1.0; #else float colorscale = max(1.0 - (dot(lightvector, lightvector)/(l_lightradius*l_lightradius)), 0.0); #endif - /* filter the light by the shadowmap. logically a boolean, but we allow fractions for softer shadows */ #ifdef PCF + /* filter the light by the shadowmap. logically a boolean, but we allow fractions for softer shadows */ colorscale *= ShadowmapFilter(s_shadowmap, vtexprojcoord); #endif - /* filter the colour by the spotlight. discard anything behind the light so we don't get a mirror image */ - #if defined(SPOT) - if (vtexprojcoord.w < 0.0) - discard; - + #ifdef SPOT + /* filter the colour by the spotlight. discard anything behind the light so we don't get a mirror image */ + if (vtexprojcoord.w < 0.0) discard; vec2 spot = ((vtexprojcoord.st)/vtexprojcoord.w); colorscale*=1.0-(dot(spot,spot)); #endif - #if defined(FLAT) - vec4 bases = vec4(FLAT, FLAT, FLAT, 1.0); - #else - #if r_skipDiffuse == 0 - vec4 bases = texture2D(s_diffuse, tex_c); + if (colorscale > 0) + { + vec3 out_f; + + #ifdef FLAT + albedo_f = vec4(FLAT, FLAT, FLAT, 1.0); #else - vec4 bases = vec4(1.0, 1.0, 1.0, 1.0); - #endif - #endif - - #ifdef BUMP - vec3 normal_f = normalize(texture2D(s_normalmap, tex_c).rgb - 0.5) * 2.0; - float refl = 1.0 - texture2D(s_normalmap, tex_c).a; - #endif - - #ifdef NOBUMP - // surface can only support ambient lighting, even for lights that try to avoid it. - vec3 diff = bases.rgb * (l_lightcolourscale.x + l_lightcolourscale.y); - #else - vec3 nl = normalize(lightvector); - #ifdef BUMP - vec3 diff = bases.rgb * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(normal_f, nl), 0.0)); - #else - //we still do bumpmapping even without normal_f to ensure colours are always sane. light.exe does it too. - vec3 diff = bases.rgb * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(vec3(0.0, 0.0, 1.0), nl), 0.0)); - #endif - #endif - - /* respect the reflectcube surface */ - #ifdef BUMP - vec3 rtc = reflect(-eyevector, normal_f); - rtc = rtc.x * invsurface[0] + rtc.y * invsurface[1] + rtc.z * invsurface[2]; - rtc = (m_model * vec4(rtc.xyz,0.0)).xyz; - diff += textureCube(s_reflectcube, rtc).rgb * refl; - #endif - - /* filter the colour by the cubemap projection */ - #ifdef CUBE - diff *= textureCube(s_projectionmap, vtexprojcoord.xyz).rgb; - #endif - - diff.rgb *= bases.a; - - diff *= colorscale * l_lightcolour; - diff.rgb *= vc.a; - - #if defined(UPPERLOWER) - diff.rgb *= (texture2D(s_upper, tex_c * 4.0).rgb + 0.5); + #ifdef VERTEXCOLOURS + albedo_f.rgb *= albedo_f.a; + #endif #endif - gl_FragColor = vec4(fog3additive(diff), vc.a); + #ifdef UPPER + vec4 uc = texture2D(s_upper, tcbase); + albedo_f.rgb += uc.rgb*e_uppercolour*uc.a; + #endif + + #ifdef LOWER + vec4 lc = texture2D(s_lower, tcbase); + albedo_f.rgb += lc.rgb*e_lowercolour*lc.a; + #endif + + #ifdef PBR + float metalness_f =texture2D(s_specular, tcbase).r; + float roughness_f = texture2D(s_specular, tcbase).g; + float ao = texture2D(s_specular, tcbase).b; + + vec3 nl = normalize(lightvector); + out_f = albedo_f.rgb * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(normal_f.rgb, nl), 0.0)); + + const vec3 dielectricSpecular = vec3(0.04, 0.04, 0.04); + const vec3 black = vec3(0.0, 0.0, 0.0); + vec3 F0 = mix(dielectricSpecular, albedo_f.rgb, metalness_f); + albedo_f.rgb = mix(albedo_f.rgb * (1.0 - dielectricSpecular.r), black, metalness_f); + + out_f = LightingFuncShlick(normal_f.rgb, normalize(eyevector), nl, roughness_f, albedo_f.rgb, F0); + + vec3 cube_c = reflect(-eyevector, normal_f.rgb); + cube_c = cube_c.x*invsurface[0] + cube_c.y*invsurface[1] + cube_c.z*invsurface[2]; + cube_c = vec4(m_model * vec4(cube_c.xyz,0.0)).xyz; + + out_f.rgb = out_f.rgb + (vec3(metalness_f,metalness_f,metalness_f) * textureCube(s_reflectcube, cube_c).rgb); + #endif + + #ifdef CUBE + /* filter the colour by the cubemap projection */ + out_f *= textureCube(s_projectionmap, vtexprojcoord.xyz).rgb; + #endif + + #ifdef PROJECTION + /* 2d projection, not used */ + out_f *= texture2d(s_projectionmap, shadowcoord); + #endif + + #ifdef VERTEXCOLOURS + out_f *= vc.rgb * vc.a; + #endif + + gl_FragColor.rgb = fog3additive(out_f * colorscale * l_lightcolour); + } else { + gl_FragColor.rgb = vec3(0.0); + } } -#endif +#endif diff --git a/base/resources.pk3dir/glsl/skybox.glsl b/base/resources.pk3dir/glsl/skybox.glsl deleted file mode 100644 index 3188c9c2..00000000 --- a/base/resources.pk3dir/glsl/skybox.glsl +++ /dev/null @@ -1,53 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Basic skybox shader with two clouds rendered on top using a dodge filter. -//============================================================================== - -!!ver 110 -!!permu FOG -!!samps box:samplerCube=0 cloudA=1 cloudB=2 -#include "sys/defs.h" -#include "sys/fog.h" - -varying vec3 cloudpos; -varying vec3 boxpos; -#ifdef VERTEX_SHADER -void main () -{ - boxpos = v_position.xyz - e_eyepos; - cloudpos = v_position.xyz; - gl_Position = ftetransform(); -} -#endif -#ifdef FRAGMENT_SHADER - - -#define s_cloud1 s_t0 -#define s_cloud2 s_t1 -void main () -{ - vec4 skybox = textureCube( s_box, boxpos ); - vec2 tccoord; - vec3 dir = cloudpos - e_eyepos; - dir.z *= 3.0; - dir.xy /= 0.5 * length( dir ); - tccoord = ( dir.xy + e_time * 0.015 ); - vec4 cloud1_f = texture2D( s_cloudA, tccoord ); - tccoord = ( dir.xy + e_time * 0.02 ); - vec4 cloud2_f = texture2D( s_cloudB, tccoord ); - - vec3 dodged1 = vec3(1.0,1.0,1.0) - (cloud1_f.rgb * vec3(cloud1_f.a, cloud1_f.a, cloud1_f.a)); - vec3 dodged2 = vec3(1.0,1.0,1.0) - (cloud2_f.rgb * vec3(cloud2_f.a, cloud2_f.a, cloud2_f.a)); - - gl_FragColor.rgb = skybox.rgb / dodged1; - gl_FragColor.rgb = gl_FragColor.rgb / dodged2; - gl_FragColor *= e_lmscale; - -#ifdef FOGGED - gl_FragColor.rgb = fog3(gl_FragColor.rgb); -#endif -} -#endif - diff --git a/base/resources.pk3dir/glsl/skybox_hdr.glsl b/base/resources.pk3dir/glsl/skybox_hdr.glsl deleted file mode 100644 index 95147d8e..00000000 --- a/base/resources.pk3dir/glsl/skybox_hdr.glsl +++ /dev/null @@ -1,63 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Basic skybox shader with two clouds rendered on top using a dodge filter. -//============================================================================== - -!!ver 110 -!!permu FOG -!!samps hdr_40:samplerCube=0 hdr_250:samplerCube=1 hdr_1600:samplerCube=2 cloudA=3 cloudB=4 -#include "sys/defs.h" -#include "sys/fog.h" - -varying vec3 cloudpos; -varying vec3 boxpos; - -#ifdef VERTEX_SHADER -void main () -{ - boxpos = v_position.xyz - e_eyepos; - cloudpos = v_position.xyz; - gl_Position = ftetransform(); -} -#endif - -#ifdef FRAGMENT_SHADER -void main () -{ - float hdr_scale; - vec3 sky_out; - vec3 skybox_40 = textureCube( s_hdr_40, boxpos ).rgb; - vec3 skybox_250 = textureCube( s_hdr_250, boxpos ).rgb; - vec3 skybox_1600 = textureCube( s_hdr_1600, boxpos ).rgb; - hdr_scale = (e_lmscale.r + e_lmscale.g + e_lmscale.b) / 3.0; - - if (hdr_scale > 1.0) { - sky_out = mix(skybox_250, skybox_40, hdr_scale - 1.0); - } else { - sky_out = mix(skybox_1600, skybox_250, hdr_scale); - } - - /* the cloud bits */ - vec2 tccoord; - vec3 dir = cloudpos - e_eyepos; - dir.z *= 3.0; - dir.xy /= 0.5 * length( dir ); - tccoord = ( dir.xy + e_time * 0.015 ); - vec4 cloud1_f = texture2D( s_cloudA, tccoord ); - tccoord = ( dir.xy + e_time * 0.02 ); - vec4 cloud2_f = texture2D( s_cloudB, tccoord ); - - vec3 dodged1 = vec3(1.0,1.0,1.0) - (cloud1_f.rgb * vec3(cloud1_f.a, cloud1_f.a, cloud1_f.a)); - vec3 dodged2 = vec3(1.0,1.0,1.0) - (cloud2_f.rgb * vec3(cloud2_f.a, cloud2_f.a, cloud2_f.a)); - - gl_FragColor.rgb = sky_out / dodged1; - gl_FragColor.rgb = gl_FragColor.rgb / dodged2; - -#ifdef FOGGED - gl_FragColor.rgb = fog3(gl_FragColor.rgb); -#endif -} -#endif - diff --git a/base/resources.pk3dir/glsl/skybox_parallax.glsl b/base/resources.pk3dir/glsl/skybox_parallax.glsl deleted file mode 100644 index 6130947d..00000000 --- a/base/resources.pk3dir/glsl/skybox_parallax.glsl +++ /dev/null @@ -1,54 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// A skybox cube with two cloud layers, which get occluded by a blended -// second skybox cube. -//============================================================================== - -!!ver 110 -!!permu FOG -!!samps cloudA=0 cloudB=1 box:samplerCube=2 mountains:samplerCube=3 -#include "sys/defs.h" -#include "sys/fog.h" - -varying vec3 cloudpos; -varying vec3 boxpos; -#ifdef VERTEX_SHADER -void main () -{ - boxpos = v_position.xyz - e_eyepos; - cloudpos = v_position.xyz; - gl_Position = ftetransform(); -} -#endif -#ifdef FRAGMENT_SHADER - -void main () -{ - vec4 mountains = textureCube( s_mountains, boxpos ); - vec4 box = textureCube( s_box, boxpos ); - vec2 tccoord; - vec3 dir = cloudpos - e_eyepos; - dir.z *= 3.0; - dir.xy /= 0.5 * length( dir ); - tccoord = ( dir.xy + e_time * 0.015 ); - vec4 cloud1_f = texture2D( s_cloudA, tccoord ); - tccoord = ( dir.xy + e_time * 0.02 ); - vec4 cloud2_f = texture2D( s_cloudA, tccoord ); - - gl_FragColor.rgb = mix( box.rgb, cloud1_f.rgb, cloud1_f.a ); - gl_FragColor = vec4( mix( gl_FragColor.rgb, cloud2_f.rgb, cloud2_f.a ), 1.0 ); - - if (mountains.a > 0.9) { - gl_FragColor.rgb = mix( gl_FragColor.rgb, mountains.rgb, mountains.a); - } - - gl_FragColor *= e_lmscale; - -#ifdef FOGGED - gl_FragColor.rgb = fog3(gl_FragColor.rgb); -#endif -} -#endif - diff --git a/base/resources.pk3dir/glsl/skybox_valley.glsl b/base/resources.pk3dir/glsl/skybox_valley.glsl deleted file mode 100644 index 2b1d3475..00000000 --- a/base/resources.pk3dir/glsl/skybox_valley.glsl +++ /dev/null @@ -1,53 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Terrain shader for tw_valley's skyroom. -//============================================================================== - -!!ver 110 -!!permu FOG -!!samps box:samplerCube=0 cloudA=1 cloudB=2 -#include "sys/defs.h" -#include "sys/fog.h" - -varying vec3 cloudpos; -varying vec3 boxpos; -#ifdef VERTEX_SHADER -void main () -{ - boxpos = v_position.xyz - e_eyepos; - cloudpos = v_position.xyz; - gl_Position = ftetransform(); -} -#endif -#ifdef FRAGMENT_SHADER - - -#define s_cloud1 s_t0 -#define s_cloud2 s_t1 -void main () -{ - vec4 skybox = textureCube( s_box, boxpos ); - vec2 tccoord; - vec3 dir = cloudpos - e_eyepos; - dir.z *= 4.0; - dir.xy /= 0.5 * length( dir ); - tccoord = ( dir.xy + e_time * 0.015 ) * 0.75; - vec4 cloud1_f = texture2D( s_cloudA, tccoord ); - tccoord = ( dir.xy + e_time * 0.02 ) * 0.75; - vec4 cloud2_f = texture2D( s_cloudB, tccoord ); - - vec3 dodged1 = vec3(1.0,1.0,1.0) - (cloud1_f.rgb * vec3(cloud1_f.a, cloud1_f.a, cloud1_f.a)); - vec3 dodged2 = vec3(1.0,1.0,1.0) - (cloud2_f.rgb * vec3(cloud2_f.a, cloud2_f.a, cloud2_f.a)); - - gl_FragColor.rgb = skybox.rgb / dodged1; - gl_FragColor.rgb = gl_FragColor.rgb / dodged2; - gl_FragColor *= e_lmscale; - -#ifdef FOGGED - gl_FragColor.rgb = fog3(gl_FragColor.rgb); -#endif -} -#endif - diff --git a/base/resources.pk3dir/glsl/sprite.glsl b/base/resources.pk3dir/glsl/sprite.glsl deleted file mode 100644 index c0f6f10d..00000000 --- a/base/resources.pk3dir/glsl/sprite.glsl +++ /dev/null @@ -1,33 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Trisoup whose diffusemap multiplies against the glColor values. -//============================================================================== - -!!ver 110 -!!samps diffuse - -varying vec2 tex_c; -varying vec4 vex_color; - -#ifdef VERTEX_SHADER -attribute vec2 v_texcoord; -attribute vec4 v_colour; - void main () - { - tex_c = v_texcoord; - vex_color = v_colour; - gl_Position = ftetransform(); - } -#endif - -#ifdef FRAGMENT_SHADER - void main () - { - vec4 diffuse_f = vex_color; - diffuse_f.rgb *= diffuse_f.a; - diffuse_f *= texture2D(s_diffuse, tex_c); - gl_FragColor = diffuse_f; - } -#endif diff --git a/base/resources.pk3dir/glsl/sprite_fixed.glsl b/base/resources.pk3dir/glsl/sprite_fixed.glsl deleted file mode 100644 index c0f6f10d..00000000 --- a/base/resources.pk3dir/glsl/sprite_fixed.glsl +++ /dev/null @@ -1,33 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Trisoup whose diffusemap multiplies against the glColor values. -//============================================================================== - -!!ver 110 -!!samps diffuse - -varying vec2 tex_c; -varying vec4 vex_color; - -#ifdef VERTEX_SHADER -attribute vec2 v_texcoord; -attribute vec4 v_colour; - void main () - { - tex_c = v_texcoord; - vex_color = v_colour; - gl_Position = ftetransform(); - } -#endif - -#ifdef FRAGMENT_SHADER - void main () - { - vec4 diffuse_f = vex_color; - diffuse_f.rgb *= diffuse_f.a; - diffuse_f *= texture2D(s_diffuse, tex_c); - gl_FragColor = diffuse_f; - } -#endif diff --git a/base/resources.pk3dir/glsl/sprite_vscroll.glsl b/base/resources.pk3dir/glsl/sprite_vscroll.glsl deleted file mode 100644 index d166f439..00000000 --- a/base/resources.pk3dir/glsl/sprite_vscroll.glsl +++ /dev/null @@ -1,34 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Trisoup whose diffusemap multiplies against the glColor values. -//============================================================================== - -!!ver 110 -!!samps diffuse - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec4 vex_color; - -#ifdef VERTEX_SHADER - void main () - { - tex_c = v_texcoord; - tex_c.y -= e_time; - vex_color = v_colour; - gl_Position = ftetransform(); - } -#endif - -#ifdef FRAGMENT_SHADER - void main () - { - vec4 diffuse_f = vex_color; - diffuse_f.rgb *= diffuse_f.a; - diffuse_f *= texture2D(s_diffuse, tex_c); - gl_FragColor = diffuse_f; - } -#endif diff --git a/base/resources.pk3dir/glsl/terrain.glsl b/base/resources.pk3dir/glsl/terrain.glsl deleted file mode 100644 index c75145c2..00000000 --- a/base/resources.pk3dir/glsl/terrain.glsl +++ /dev/null @@ -1,167 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Default terrain shader that blends between two surfaces and creates a -// realistic transition using the diffusemaps' monochrome channel for masking. -//============================================================================== - -!!ver 110 -!!permu FOG -!!permu BUMP -!!permu DELUXE -!!permu UPPERLOWER -!!samps 6 - -!!samps lightmap -!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3 -!!samps =DELUXE deluxemap -!!samps =LIGHTSTYLED =DELUXE deluxemap1 deluxemap2 deluxemap3 -!!samps =UPPERLOWER upper - -!!permu FAKESHADOWS -!!cvardf r_glsl_pcf -!!samps =FAKESHADOWS shadowmap - -!!cvardf r_skipNormal -!!cvardf r_skipLightmap - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec4 vex_color; - -varying vec2 lm0; -#ifdef LIGHTSTYLED -varying vec2 lm1, lm2, lm3; -#endif - -#ifdef FAKESHADOWS - varying vec4 vtexprojcoord; -#endif - -#ifdef VERTEX_SHADER - void lightmapped_init(void) - { - lm0 = v_lmcoord; - #ifdef LIGHTSTYLED - lm1 = v_lmcoord2; - lm2 = v_lmcoord3; - lm3 = v_lmcoord4; - #endif - } - - void main ( void ) - { - lightmapped_init(); - tex_c = v_texcoord; - vex_color = v_colour; - gl_Position = ftetransform(); - - #ifdef FAKESHADOWS - vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); - #endif - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - #include "sys/pcf.h" - -#if r_skipLightmap==0 - #ifdef LIGHTSTYLED - #define LIGHTMAP0 texture2D(s_lightmap0, lm0).rgb - #define LIGHTMAP1 texture2D(s_lightmap1, lm1).rgb - #define LIGHTMAP2 texture2D(s_lightmap2, lm2).rgb - #define LIGHTMAP3 texture2D(s_lightmap3, lm3).rgb - #else - #define LIGHTMAP texture2D(s_lightmap, lm0).rgb - #endif -#else - #ifdef LIGHTSTYLED - #define LIGHTMAP0 vec3(0.5,0.5,0.5) - #define LIGHTMAP1 vec3(0.5,0.5,0.5) - #define LIGHTMAP2 vec3(0.5,0.5,0.5) - #define LIGHTMAP3 vec3(0.5,0.5,0.5) - #else - #define LIGHTMAP vec3(0.5,0.5,0.5) - #endif -#endif - - vec3 lightmap_fragment() - { - vec3 lightmaps; - -#ifdef LIGHTSTYLED - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb; - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb; - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb; - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb; -#else - lightmaps = LIGHTMAP * e_lmscale.rgb; -#endif - return lightmaps; - } - -#if r_skipNormal==0 - vec3 lightmap_fragment(vec3 normal_f) - { -#ifndef DELUXE - return lightmap_fragment(); -#else - vec3 lightmaps; - - #if defined(LIGHTSTYLED) - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb * dot(normal_f, (texture2D(s_deluxemap0, lm0).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb * dot(normal_f, (texture2D(s_deluxemap1, lm1).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb * dot(normal_f, (texture2D(s_deluxemap2, lm2).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb * dot(normal_f, (texture2D(s_deluxemap3, lm3).rgb - 0.5) * 2.0); - #else - lightmaps = LIGHTMAP * e_lmscale.rgb * dot(normal_f, (texture2D(s_deluxemap, lm0).rgb - 0.5) * 2.0); - #endif - - return lightmaps; -#endif - } -#endif - - void main ( void ) - { - vec4 diff1_f = texture2D( s_t0, tex_c); - vec4 diff2_f = texture2D( s_t1, tex_c); - float alpha = 1.0; - float bw = 1.0 - (diff2_f.r + diff2_f.g + diff2_f.b) / 3.0; - - #if r_skipNormal==0 - vec3 normal1_f = normalize(texture2D(s_t2, tex_c).rgb - 0.5); - vec3 normal2_f = normalize(texture2D(s_t3, tex_c).rgb - 0.5); - #endif - - if (vex_color.a < 1.0) { - if (bw > vex_color.a) { - alpha = 0.0; - } - } - - /* light */ - #if r_skipNormal==0 - diff1_f.rgb *= lightmap_fragment(normal1_f); - diff2_f.rgb *= lightmap_fragment(normal2_f); - #else - diff1_f.rgb *= lightmap_fragment(); - diff2_f.rgb *= lightmap_fragment(); - #endif - - vec3 output_f = mix(diff1_f.rgb, diff2_f.rgb, alpha); - - #ifdef FAKESHADOWS - output_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord); - #endif - - #if defined(UPPERLOWER) - output_f.rgb *= (texture2D(s_upper, tex_c * 4.0).rgb + 0.5); - #endif - - gl_FragColor = fog4( vec4( output_f.rgb, 1.0 ) ); - } -#endif diff --git a/base/resources.pk3dir/glsl/terrain_alpha.glsl b/base/resources.pk3dir/glsl/terrain_alpha.glsl deleted file mode 100644 index 9448d78a..00000000 --- a/base/resources.pk3dir/glsl/terrain_alpha.glsl +++ /dev/null @@ -1,169 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Blending terrain and masking its edges for a smooth transition into alpha. -//============================================================================== - -!!ver 110 -!!permu FOG -!!permu BUMP -!!permu DELUXE -!!permu UPPERLOWER -!!samps diffuse normalmap - -!!samps lightmap -!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3 -!!samps =DELUXE deluxemap -!!samps =LIGHTSTYLED =DELUXE deluxemap1 deluxemap2 deluxemap3 -!!samps =UPPERLOWER upper - -!!permu FAKESHADOWS -!!cvardf r_glsl_pcf -!!samps =FAKESHADOWS shadowmap - -!!cvardf r_skipDiffuse -!!cvardf r_skipLightmap -!!cvardf r_skipNormal - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec4 vex_color; - -varying vec2 lm0; -#ifdef LIGHTSTYLED -varying vec2 lm1, lm2, lm3; -#endif - -#ifdef FAKESHADOWS - varying vec4 vtexprojcoord; -#endif - -#ifdef VERTEX_SHADER - void lightmapped_init(void) - { - lm0 = v_lmcoord; - #ifdef LIGHTSTYLED - lm1 = v_lmcoord2; - lm2 = v_lmcoord3; - lm3 = v_lmcoord4; - #endif - } - - void main ( void ) - { - lightmapped_init(); - tex_c = v_texcoord; - vex_color = v_colour; - - gl_Position = ftetransform(); - - #ifdef FAKESHADOWS - vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); - #endif - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - #include "sys/pcf.h" - -#if r_skipLightmap==0 - #ifdef LIGHTSTYLED - #define LIGHTMAP0 texture2D(s_lightmap0, lm0).rgb - #define LIGHTMAP1 texture2D(s_lightmap1, lm1).rgb - #define LIGHTMAP2 texture2D(s_lightmap2, lm2).rgb - #define LIGHTMAP3 texture2D(s_lightmap3, lm3).rgb - #else - #define LIGHTMAP texture2D(s_lightmap, lm0).rgb - #endif -#else - #ifdef LIGHTSTYLED - #define LIGHTMAP0 vec3(0.5,0.5,0.5) - #define LIGHTMAP1 vec3(0.5,0.5,0.5) - #define LIGHTMAP2 vec3(0.5,0.5,0.5) - #define LIGHTMAP3 vec3(0.5,0.5,0.5) - #else - #define LIGHTMAP vec3(0.5,0.5,0.5) - #endif -#endif - - vec3 lightmap_fragment() - { - vec3 lightmaps; - -#ifdef LIGHTSTYLED - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb; - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb; - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb; - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb; -#else - lightmaps = LIGHTMAP * e_lmscale.rgb; -#endif - return lightmaps; - } - -#if r_skipNormal==0 - vec3 lightmap_fragment(vec3 normal_f) - { -#ifndef DELUXE - return lightmap_fragment(); -#else - vec3 lightmaps; - - #if defined(LIGHTSTYLED) - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb * dot(normal_f, (texture2D(s_deluxemap0, lm0).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb * dot(normal_f, (texture2D(s_deluxemap1, lm1).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb * dot(normal_f, (texture2D(s_deluxemap2, lm2).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb * dot(normal_f, (texture2D(s_deluxemap3, lm3).rgb - 0.5) * 2.0); - #else - lightmaps = LIGHTMAP * e_lmscale.rgb * dot(normal_f, (texture2D(s_deluxemap, lm0).rgb - 0.5) * 2.0); - #endif - - return lightmaps; -#endif - } -#endif - - void main ( void ) - { - #if r_skipDiffuse==0 - vec3 diffuse_f = texture2D(s_diffuse, tex_c).rgb; - #else - vec3 diffuse_f = vec3(1.0,1.0,1.0); - #endif - - float bw = 1.0 - (diffuse_f.r + diffuse_f.g + diffuse_f.b) / 3.0; - vec4 vcol = vex_color; - - #if r_skipNormal==0 - vec3 normal_f; - normal_f = normalize(texture2D(s_normalmap, tex_c).rgb - 0.5); - #endif - - if (vcol.a < 1.0) { - if (bw > vcol.a) { - discard; - } - } - - #if r_skipNormal==0 - diffuse_f.rgb *= lightmap_fragment(normal_f); - #else - diffuse_f.rgb *= lightmap_fragment(); - #endif - - #ifdef FAKESHADOWS - diffuse_f *= ShadowmapFilter(s_shadowmap, vtexprojcoord); - #endif - - - #if defined(UPPERLOWER) - diffuse_f.rgb *= (texture2D(s_upper, tex_c * 4.0).rgb + 0.5); - #endif - - gl_FragColor = vec4(fog3(diffuse_f), 1.0); - } -#endif - diff --git a/base/resources.pk3dir/glsl/terrain_alpha_alt.glsl b/base/resources.pk3dir/glsl/terrain_alpha_alt.glsl deleted file mode 100644 index 9d79d910..00000000 --- a/base/resources.pk3dir/glsl/terrain_alpha_alt.glsl +++ /dev/null @@ -1,173 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Alternative way of blending/masking terrain between to diffuse textures. -//============================================================================== - -!!ver 110 -!!permu FOG -!!permu BUMP -!!permu DELUXE -!!permu UPPERLOWER -!!samps diffuse normalmap - -!!samps lightmap -!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3 -!!samps =DELUXE deluxemap -!!samps =LIGHTSTYLED =DELUXE deluxemap1 deluxemap2 deluxemap3 -!!samps =UPPERLOWER upper - -!!permu FAKESHADOWS -!!cvardf r_glsl_pcf -!!samps =FAKESHADOWS shadowmap - -!!cvardf r_skipDiffuse -!!cvardf r_skipLightmap -!!cvardf r_skipNormal - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec4 vex_color; - -varying vec2 lm0; -#ifdef LIGHTSTYLED -varying vec2 lm1, lm2, lm3; -#endif - -#ifdef FAKESHADOWS - varying vec4 vtexprojcoord; -#endif - -#ifdef VERTEX_SHADER - void lightmapped_init(void) - { - lm0 = v_lmcoord; - #ifdef LIGHTSTYLED - lm1 = v_lmcoord2; - lm2 = v_lmcoord3; - lm3 = v_lmcoord4; - #endif - } - - void main ( void ) - { - lightmapped_init(); - tex_c = v_texcoord; - vex_color = v_colour; - - gl_Position = ftetransform(); - - #ifdef FAKESHADOWS - vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); - #endif - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - #include "sys/pcf.h" - -#if r_skipLightmap==0 - #ifdef LIGHTSTYLED - #define LIGHTMAP0 texture2D(s_lightmap0, lm0).rgb - #define LIGHTMAP1 texture2D(s_lightmap1, lm1).rgb - #define LIGHTMAP2 texture2D(s_lightmap2, lm2).rgb - #define LIGHTMAP3 texture2D(s_lightmap3, lm3).rgb - #else - #define LIGHTMAP texture2D(s_lightmap, lm0).rgb - #endif -#else - #ifdef LIGHTSTYLED - #define LIGHTMAP0 vec3(0.5,0.5,0.5) - #define LIGHTMAP1 vec3(0.5,0.5,0.5) - #define LIGHTMAP2 vec3(0.5,0.5,0.5) - #define LIGHTMAP3 vec3(0.5,0.5,0.5) - #else - #define LIGHTMAP vec3(0.5,0.5,0.5) - #endif -#endif - - vec3 lightmap_fragment() - { - vec3 lightmaps; - -#ifdef LIGHTSTYLED - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb; - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb; - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb; - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb; -#else - lightmaps = LIGHTMAP * e_lmscale.rgb; -#endif - return lightmaps; - } - -#if r_skipNormal==0 - vec3 lightmap_fragment(vec3 normal_f) - { -#ifndef DELUXE - return lightmap_fragment(); -#else - vec3 lightmaps; - - #if defined(LIGHTSTYLED) - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb * dot(normal_f, (texture2D(s_deluxemap0, lm0).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb * dot(normal_f, (texture2D(s_deluxemap1, lm1).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb * dot(normal_f, (texture2D(s_deluxemap2, lm2).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb * dot(normal_f, (texture2D(s_deluxemap3, lm3).rgb - 0.5) * 2.0); - #else - lightmaps = LIGHTMAP * e_lmscale.rgb * dot(normal_f, (texture2D(s_deluxemap, lm0).rgb - 0.5) * 2.0); - #endif - - return lightmaps; -#endif - } -#endif - - void main ( void ) - { - #if r_skipDiffuse==0 - vec3 diffuse_f = texture2D(s_diffuse, tex_c).rgb; - #else - vec3 diffuse_f = vec3(1.0,1.0,1.0); - #endif - - float bw = (diffuse_f.r + diffuse_f.g + diffuse_f.b) / 3.0; - vec4 vcol = vex_color; - float alpha = 1.0; - - #if r_skipNormal==0 - vec3 normal_f; - normal_f = normalize(texture2D(s_normalmap, tex_c).rgb - 0.5) * 2.0; - #endif - - if (vcol.a < 1.0) { - if (bw > vcol.a) { - discard; - } - } - - if (bw > (vcol.a * 0.25)) - alpha = vcol.a; - - #if r_skipNormal==0 - diffuse_f.rgb *= lightmap_fragment(normal_f); - #else - diffuse_f.rgb *= lightmap_fragment(); - #endif - - #ifdef FAKESHADOWS - diffuse_f *= ShadowmapFilter(s_shadowmap, vtexprojcoord); - #endif - - - #if defined(UPPERLOWER) - diffuse_f.rgb *= texture2D(s_upper, tex_c * 4.0).rgb; - #endif - - gl_FragColor = vec4(fog3(diffuse_f), alpha); - } -#endif - diff --git a/base/resources.pk3dir/glsl/terrain_mask.glsl b/base/resources.pk3dir/glsl/terrain_mask.glsl deleted file mode 100644 index 654a267a..00000000 --- a/base/resources.pk3dir/glsl/terrain_mask.glsl +++ /dev/null @@ -1,172 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Blending terrain and masking its edges for a smooth transition into alpha. -//============================================================================== - -!!ver 110 -!!permu FOG -!!permu BUMP -!!permu DELUXE -!!permu UPPERLOWER -!!samps diffuse normalmap - -!!samps lightmap -!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3 -!!samps =DELUXE deluxemap -!!samps =LIGHTSTYLED =DELUXE deluxemap1 deluxemap2 deluxemap3 -!!samps =UPPERLOWER upper - -!!permu FAKESHADOWS -!!cvardf r_glsl_pcf -!!cvardf r_fullbright -!!samps =FAKESHADOWS shadowmap - -!!cvardf r_skipDiffuse -!!cvardf r_skipLightmap -!!cvardf r_skipNormal - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec4 vex_color; - -varying vec2 lm0; -#ifdef LIGHTSTYLED -varying vec2 lm1, lm2, lm3; -#endif - -#ifdef FAKESHADOWS - varying vec4 vtexprojcoord; -#endif - -#ifdef VERTEX_SHADER - void lightmapped_init(void) - { - lm0 = v_lmcoord; - #ifdef LIGHTSTYLED - lm1 = v_lmcoord2; - lm2 = v_lmcoord3; - lm3 = v_lmcoord4; - #endif - } - - void main ( void ) - { - lightmapped_init(); - tex_c = v_texcoord; - vex_color = v_colour; - - gl_Position = ftetransform(); - - #ifdef FAKESHADOWS - vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); - #endif - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - #include "sys/pcf.h" - -#if r_skipLightmap==0 - #ifdef LIGHTSTYLED - #define LIGHTMAP0 texture2D(s_lightmap0, lm0).rgb - #define LIGHTMAP1 texture2D(s_lightmap1, lm1).rgb - #define LIGHTMAP2 texture2D(s_lightmap2, lm2).rgb - #define LIGHTMAP3 texture2D(s_lightmap3, lm3).rgb - #else - #define LIGHTMAP texture2D(s_lightmap, lm0).rgb - #endif -#else - #ifdef LIGHTSTYLED - #define LIGHTMAP0 vec3(0.5,0.5,0.5) - #define LIGHTMAP1 vec3(0.5,0.5,0.5) - #define LIGHTMAP2 vec3(0.5,0.5,0.5) - #define LIGHTMAP3 vec3(0.5,0.5,0.5) - #else - #define LIGHTMAP vec3(0.5,0.5,0.5) - #endif -#endif - - vec3 lightmap_fragment() - { - vec3 lightmaps; - -#ifdef LIGHTSTYLED - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb; - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb; - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb; - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb; -#else - lightmaps = LIGHTMAP * e_lmscale.rgb; -#endif - return (r_fullbright == 1) ? vec3(1.0, 1.0, 1.0) : lightmaps; - } - -#if r_skipNormal==0 - vec3 lightmap_fragment(vec3 normal_f) - { -#ifndef DELUXE - return lightmap_fragment(); -#else - vec3 lightmaps; - - #if defined(LIGHTSTYLED) - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb * dot(normal_f, (texture2D(s_deluxemap0, lm0).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb * dot(normal_f, (texture2D(s_deluxemap1, lm1).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb * dot(normal_f, (texture2D(s_deluxemap2, lm2).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb * dot(normal_f, (texture2D(s_deluxemap3, lm3).rgb - 0.5) * 2.0); - #else - lightmaps = LIGHTMAP * e_lmscale.rgb * dot(normal_f, (texture2D(s_deluxemap, lm0).rgb - 0.5) * 2.0); - #endif - - return (r_fullbright == 1) ? vec3(1.0, 1.0, 1.0) : lightmaps; -#endif - } -#endif - - void main ( void ) - { - #if r_skipDiffuse==0 - vec3 diffuse_f = texture2D(s_diffuse, tex_c).rgb; - #else - vec3 diffuse_f = vec3(1.0,1.0,1.0); - #endif - - float bw = 1.0 - (diffuse_f.r + diffuse_f.g + diffuse_f.b) / 3.0; - vec4 vcol = vex_color; - - #if r_skipNormal==0 - vec3 normal_f; - normal_f = normalize(texture2D(s_normalmap, tex_c).rgb - 0.5); - #endif - - if (vcol.a < 1.0) { - // contrast enhancement - #ifdef BWMASK - bw *= ((bw * 2.0) * BWMASK); - #endif - if (bw > vcol.a) { - discard; - } - } - - #if r_skipNormal==0 - diffuse_f.rgb *= lightmap_fragment(normal_f); - #else - diffuse_f.rgb *= lightmap_fragment(); - #endif - - #ifdef FAKESHADOWS - diffuse_f *= ShadowmapFilter(s_shadowmap, vtexprojcoord); - #endif - - #if defined(UPPERLOWER) - diffuse_f.rgb *= (texture2D(s_upper, tex_c * 4.0).rgb + 0.5); - #endif - - gl_FragColor = vec4(fog3(diffuse_f), 1.0); - } -#endif diff --git a/base/resources.pk3dir/glsl/terrain_skybox.glsl b/base/resources.pk3dir/glsl/terrain_skybox.glsl deleted file mode 100644 index ddfb1151..00000000 --- a/base/resources.pk3dir/glsl/terrain_skybox.glsl +++ /dev/null @@ -1,120 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Terrain shader used for skyroom surfaces. -//============================================================================== - -!!ver 110 -!!permu FOG -!!permu BUMP -!!permu DELUXE -!!samps 4 diffuse - -!!samps lightmap -!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3 -!!samps =DELUXE deluxemap -!!samps =LIGHTSTYLED =DELUXE deluxemap1 deluxemap2 deluxemap3 -!!cvardf r_skipLightmap - -#include "sys/defs.h" -#include "sys/fog.h" - -varying vec2 tex_c; -varying vec4 vex_color; - -varying vec2 lm0; -#ifdef LIGHTSTYLED -varying vec2 lm1, lm2, lm3; -#endif - -#ifdef VERTEX_SHADER - void lightmapped_init(void) - { - lm0 = v_lmcoord; - #ifdef LIGHTSTYLED - lm1 = v_lmcoord2; - lm2 = v_lmcoord3; - lm3 = v_lmcoord4; - #endif - } - - void main () - { - tex_c = v_texcoord; - lm_c = v_lmcoord; - vex_color = v_colour; - gl_Position = ftetransform(); - } -#endif - -#ifdef FRAGMENT_SHADER - vec3 lightmap_fragment() - { - vec3 lightmaps; - -#if r_skipLightmap==0 - #ifdef LIGHTSTYLED - #define LIGHTMAP0 texture2D(s_lightmap0, lm0).rgb - #define LIGHTMAP1 texture2D(s_lightmap1, lm1).rgb - #define LIGHTMAP2 texture2D(s_lightmap2, lm2).rgb - #define LIGHTMAP3 texture2D(s_lightmap3, lm3).rgb - #else - #define LIGHTMAP texture2D(s_lightmap, lm0).rgb - #endif -#else - #ifdef LIGHTSTYLED - #define LIGHTMAP0 vec3(0.5,0.5,0.5) - #define LIGHTMAP1 vec3(0.5,0.5,0.5) - #define LIGHTMAP2 vec3(0.5,0.5,0.5) - #define LIGHTMAP3 vec3(0.5,0.5,0.5) - #else - #define LIGHTMAP vec3(0.5,0.5,0.5) - #endif -#endif - - vec3 lightmap_fragment() - { - vec3 lightmaps; - -#ifdef LIGHTSTYLED - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb; - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb; - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb; - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb; -#else - lightmaps = LIGHTMAP * e_lmscale.rgb; -#endif - return lightmaps; - } - -#if r_skipNormal==0 - vec3 lightmap_fragment(vec3 normal_f) - { -#ifndef DELUXE - return lightmap_fragment(); -#else - vec3 lightmaps; - - #if defined(LIGHTSTYLED) - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb * dot(normal_f, (texture2D(s_deluxemap0, lm0).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb * dot(normal_f, (texture2D(s_deluxemap1, lm1).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb * dot(normal_f, (texture2D(s_deluxemap2, lm2).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb * dot(normal_f, (texture2D(s_deluxemap3, lm3).rgb - 0.5) * 2.0); - #else - lightmaps = LIGHTMAP * e_lmscale.rgb * dot(normal_f, (texture2D(s_deluxemap, lm0).rgb - 0.5) * 2.0); - #endif - - return lightmaps; -#endif - } -#endif - - void main () - { - vec4 diff1_f = texture2D( s_t0, tex_c ); - vec4 diff2_f = texture2D( s_t1, tex_c ); - vec3 output_f = mix( diff1_f.rgb, diff2_f.rgb, vex_color.a ) * lightmap_fragment(normal_f); - gl_FragColor = fog4( vec4( output_f.rgb, 1.0 ) ); - } -#endif diff --git a/base/resources.pk3dir/glsl/terrain_valley.glsl b/base/resources.pk3dir/glsl/terrain_valley.glsl deleted file mode 100644 index a7115abb..00000000 --- a/base/resources.pk3dir/glsl/terrain_valley.glsl +++ /dev/null @@ -1,155 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Terrain shader exclusive to tw_valley. One of the few surfaces that do not -// draw a normalmap as it's too expensive. -//============================================================================== - -!!ver 110 -!!permu FOG -!!samps 6 - -!!samps lightmap -!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3 -!!samps =DELUXE deluxemap -!!samps =LIGHTSTYLED =DELUXE deluxemap1 deluxemap2 deluxemap3 - -!!permu FAKESHADOWS -!!cvardf r_glsl_pcf -!!samps =FAKESHADOWS shadowmap - -!!cvardf r_skipDiffuse -!!cvardf r_skipNormal -!!cvardf r_skipLightmap - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec2 detail_c; -varying vec4 vex_color; - -varying vec2 lm0; -#ifdef LIGHTSTYLED -varying vec2 lm1, lm2, lm3; -#endif - -#ifdef FAKESHADOWS - varying vec4 vtexprojcoord; -#endif - -#ifdef VERTEX_SHADER - void lightmapped_init(void) - { - lm0 = v_lmcoord; - #ifdef LIGHTSTYLED - lm1 = v_lmcoord2; - lm2 = v_lmcoord3; - lm3 = v_lmcoord4; - #endif - } - - void main ( void ) - { - lightmapped_init(); - tex_c = v_texcoord * 2.5; - detail_c = tex_c * 7.5; - vex_color = v_colour; - gl_Position = ftetransform(); - - #ifdef FAKESHADOWS - vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); - #endif - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - #include "sys/pcf.h" - -#if r_skipLightmap==0 - #ifdef LIGHTSTYLED - #define LIGHTMAP0 texture2D(s_lightmap0, lm0).rgb - #define LIGHTMAP1 texture2D(s_lightmap1, lm1).rgb - #define LIGHTMAP2 texture2D(s_lightmap2, lm2).rgb - #define LIGHTMAP3 texture2D(s_lightmap3, lm3).rgb - #else - #define LIGHTMAP texture2D(s_lightmap, lm0).rgb - #endif -#else - #ifdef LIGHTSTYLED - #define LIGHTMAP0 vec3(0.5,0.5,0.5) - #define LIGHTMAP1 vec3(0.5,0.5,0.5) - #define LIGHTMAP2 vec3(0.5,0.5,0.5) - #define LIGHTMAP3 vec3(0.5,0.5,0.5) - #else - #define LIGHTMAP vec3(0.5,0.5,0.5) - #endif -#endif - - vec3 lightmap_fragment() - { - vec3 lightmaps; - -#ifdef LIGHTSTYLED - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb; - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb; - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb; - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb; -#else - lightmaps = LIGHTMAP * e_lmscale.rgb; -#endif - return lightmaps; - } - -#if r_skipNormal==0 - vec3 lightmap_fragment(vec3 normal_f) - { -#ifndef DELUXE - return lightmap_fragment(); -#else - vec3 lightmaps; - - #if defined(LIGHTSTYLED) - lightmaps = LIGHTMAP0 * e_lmscale[0].rgb * dot(normal_f, (texture2D(s_deluxemap0, lm0).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP1 * e_lmscale[1].rgb * dot(normal_f, (texture2D(s_deluxemap1, lm1).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP2 * e_lmscale[2].rgb * dot(normal_f, (texture2D(s_deluxemap2, lm2).rgb - 0.5) * 2.0); - lightmaps += LIGHTMAP3 * e_lmscale[3].rgb * dot(normal_f, (texture2D(s_deluxemap3, lm3).rgb - 0.5) * 2.0); - #else - lightmaps = LIGHTMAP * e_lmscale.rgb * dot(normal_f, (texture2D(s_deluxemap, lm0).rgb - 0.5) * 2.0); - #endif - - return lightmaps; -#endif - } -#endif - - void main ( void ) - { - vec4 diff1_f = texture2D(s_t0, tex_c); - vec4 diff2_f = texture2D(s_t1, tex_c); - vec3 norm1_f = normalize(texture2D(s_t4, tex_c).rgb - 0.5); - vec3 norm2_f = normalize(texture2D(s_t5, tex_c).rgb - 0.5); - - vec3 d1_f = texture2D(s_t2, detail_c).rgb; - vec3 d2_f = texture2D(s_t3, detail_c).rgb; - diff1_f.rgb *= d1_f; - diff2_f.rgb *= d2_f; - - if (float(r_skipNormal) == 1.0) { - diff1_f.rgb *= lightmap_fragment(); - diff2_f.rgb *= lightmap_fragment(); - } else { - diff1_f.rgb *= lightmap_fragment(norm1_f); - diff2_f.rgb *= lightmap_fragment(norm2_f); - } - - vec3 output_f = mix( diff1_f.rgb, diff2_f.rgb, vex_color.a ); - - #ifdef FAKESHADOWS - output_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord); - #endif - - gl_FragColor = fog4( vec4( output_f.rgb, 1.0 ) ); - } -#endif diff --git a/base/resources.pk3dir/glsl/unlit.glsl b/base/resources.pk3dir/glsl/unlit.glsl deleted file mode 100644 index 266c38ba..00000000 --- a/base/resources.pk3dir/glsl/unlit.glsl +++ /dev/null @@ -1,38 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Unlit surface. -//============================================================================== - -!!ver 110 -!!permu FOG -!!samps diffuse - -#include "sys/defs.h" -#include "sys/fog.h" - -varying vec2 tex_c; - -#ifdef VERTEX_SHADER -void main () -{ - tex_c = v_texcoord; - gl_Position = ftetransform(); -} -#endif - -#ifdef FRAGMENT_SHADER -void main () -{ - vec4 d_f = texture2D( s_diffuse, tex_c ); - -#ifdef MASK - // alpha-testing happens here - if (d_f.a < MASK) - discard; -#endif - - gl_FragColor = fog4( d_f ); -} -#endif diff --git a/base/resources.pk3dir/glsl/vertexlit.glsl b/base/resources.pk3dir/glsl/vertexlit.glsl deleted file mode 100644 index 1b84679e..00000000 --- a/base/resources.pk3dir/glsl/vertexlit.glsl +++ /dev/null @@ -1,145 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Lightgrid-lit surface, normalmap's alpha contains environment cube reflec- -// tivity. -//============================================================================== - -!!ver 110 -!!permu FRAMEBLEND -!!permu FULLBRIGHT -!!permu FOG -!!permu BUMP -!!permu SKELETAL -!!samps diffuse -!!samps =BUMP normalmap reflectcube -!!samps =FULLBRIGHT fullbright - -!!cvardf r_skipDiffuse -!!cvardf r_skipFullbright -!!cvardf r_skipNormal -!!cvardf r_skipEnvmap -!!cvardf r_skipLightmap -!!cvardf r_showEnvCubemap - -!!permu FAKESHADOWS -!!cvardf r_glsl_pcf -!!cvardf r_fullbright -!!cvardf r_lambertscale -!!samps =FAKESHADOWS shadowmap - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec3 norm; - -#ifdef BUMP -varying vec3 eyevector; -varying mat3 invsurface; -#endif - -#ifdef FAKESHADOWS - varying vec4 vtexprojcoord; -#endif - -#ifdef VERTEX_SHADER - #include "sys/skeletal.h" - - void main () - { - vec3 n, s, t, w; - gl_Position = skeletaltransform_wnst(w,n,s,t); - norm = n; - n = normalize(n); - s = normalize(s); - t = normalize(t); - tex_c = v_texcoord; - - #ifdef BUMP - /* normalmap */ - invsurface = mat3(s, t, n); - - /* reflect */ - vec3 eyeminusvertex = e_eyepos - w.xyz; - eyevector.x = dot(eyeminusvertex, s.xyz); - eyevector.y = dot(eyeminusvertex, t.xyz); - eyevector.z = dot(eyeminusvertex, n.xyz); - #endif - - #ifdef FAKESHADOWS - vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); - #endif - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - #include "sys/pcf.h" - -#ifdef HALFLAMBERT - float lambert(vec3 normal, vec3 dir) - { - return (lambert(normal, dir) * 0.5) + 0.5; - } -#else - float lambert(vec3 normal, vec3 dir) - { - return max(dot(normal, dir), 0.0); - } -#endif - - void main (void) - { - vec4 diff_f = vec4(1.0, 1.0, 1.0, 1.0); - vec3 light = vec3(0.0, 0.0, 0.0); - - #if r_skipDiffuse == 0 - diff_f = texture2D(s_diffuse, tex_c); - #endif - - // bump goes here - #if r_skipNormal==0 || defined(BUMP) - vec3 normal_f = (texture2D(s_normalmap, tex_c).rgb - 0.5) * 2.0; - #else - vec3 normal_f = vec3(0.0, 0.0, 1.0); - #endif - - #ifdef MASK - if (diff_f.a < MASK) { - discard; - } - #endif - - /* directional light */ - light += (e_light_mul * lambert(norm, e_light_dir)) * 2.0; - light += (e_light_ambient * lambert(norm, reflect(norm, e_light_dir))) * 0.5; - light += (e_light_mul * dot(normal_f, e_light_dir)); - - #ifdef FAKESHADOWS - diff_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord); - #endif - diff_f.rgb *= light; - - #if defined(BUMP) && r_skipEnvmap==0 - vec3 cube_c; - float refl = 1.0 - texture2D(s_normalmap, tex_c).a; - - cube_c = reflect(normalize(eyevector), norm); - cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2]; - cube_c = (m_model * vec4(cube_c.xyz, 0.0)).xyz; - - #if r_showEnvCubemap == 0 - diff_f.rgb += textureCube(s_reflectcube, cube_c).rgb * refl; - #else - diff_f.rgb = textureCube(s_reflectcube, cube_c).rgb; - #endif - #endif - - #if defined(FULLBRIGHT) && r_skipFullbright==0 - diff_f.rgb += texture2D(s_fullbright, tex_c).rgb; - #endif - - gl_FragColor = fog4(diff_f * e_colourident) * e_lmscale; - } -#endif diff --git a/base/resources.pk3dir/glsl/vertexlit_specular.glsl b/base/resources.pk3dir/glsl/vertexlit_specular.glsl deleted file mode 100644 index 29ddfd4e..00000000 --- a/base/resources.pk3dir/glsl/vertexlit_specular.glsl +++ /dev/null @@ -1,148 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Lightgrid-lit surface, normalmap's alpha contains specularity information. -//============================================================================== - -!!ver 110 -!!permu FRAMEBLEND -!!permu FOG -!!permu SKELETAL -!!cvarf gl_specular -!!samps diffuse fullbright normalmap - -!!permu FAKESHADOWS -!!cvardf r_glsl_pcf -!!samps =FAKESHADOWS shadowmap - -!!cvardf r_skipDiffuse -!!cvardf r_skipSpecular -!!cvardf r_skipNormal - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec3 eyevector; -varying vec3 norm; -varying mat3 invsurface; - -#ifdef FAKESHADOWS - varying vec4 vtexprojcoord; -#endif - -#ifdef VERTEX_SHADER - #include "sys/skeletal.h" - -#ifdef CHROME - /* Rotate Light Vector */ - vec3 rlv(vec3 axis, vec3 origin, vec3 lightpoint) - { - vec3 offs; - vec3 result; - offs[0] = lightpoint[0] - origin[0]; - offs[1] = lightpoint[1] - origin[1]; - offs[2] = lightpoint[2] - origin[2]; - result[0] = dot(offs[0], axis[0]); - result[1] = dot(offs[1], axis[1]); - result[2] = dot(offs[2], axis[2]); - return result; - } -#endif - - void main () - { - vec3 n, s, t, w; - gl_Position = skeletaltransform_wnst(w,n,s,t); - norm = n; - n = normalize(n); - s = normalize(s); - t = normalize(t); - - #ifdef CHROME - vec3 rorg = rlv(vec3(0,0,0), w, e_eyepos); - vec3 viewc = normalize(e_eyepos - w); - float d = dot(n, viewc); - vec3 reflected; - reflected.x = n.x * 2.0 * d - viewc.x; - reflected.y = n.y * 2.0 * d - viewc.y; - reflected.z = n.z * 2.0 * d - viewc.z; - tex_c.x = 0.5 + reflected.y * 0.5; - tex_c.y = 0.5 - reflected.z * 0.5; - #else - tex_c = v_texcoord; - #endif - - /* normalmap */ - invsurface = mat3(s, t, n); - - /* reflect */ - eyevector = e_eyepos - w.xyz; - - #ifdef FAKESHADOWS - vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); - #endif - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - #include "sys/pcf.h" - -#ifdef HALFLAMBERT - float lambert(vec3 normal, vec3 dir) - { - return (lambert(normal, dir) * 0.5) + 0.5; - } -#else - float lambert(vec3 normal, vec3 dir) - { - return max(dot(normal, dir), 0.0); - } -#endif - - void main () - { - vec4 fb_f = texture2D(s_fullbright, tex_c); - vec3 light; - - #if r_skipDiffuse==0 - vec4 diffuse_f = texture2D(s_diffuse, tex_c); - #else - vec4 diffuse_f = vec4(1.0,1.0,1.0,1.0); - #endif - - #if r_skipNormal==0 - vec3 normal_f = (texture2D(s_normalmap, tex_c).rgb - 0.5) * 2.0; - float gloss = texture2D(s_normalmap, tex_c).a; - #else - #define normal_f vec3(0.0,0.0,1.0) - float gloss = texture2D(s_normalmap, tex_c).a; - #endif - - if (diffuse_f.a < 0.5) { - discard; - } - - light = (e_light_mul * lambert(norm, e_light_dir)) * 2.0; /* directional light */ - light += (e_light_ambient * lambert(norm, reflect(norm, e_light_dir))) * 0.5; /* reverse ambient */ - light *= 2.0; - - #if r_skipSpecular==0 - vec3 halfdir = normalize(normalize(eyevector) + e_light_dir); - vec3 bumps = normalize(invsurface * (normal_f)); - float spec = pow(max(dot(halfdir, bumps), 0.0), FTE_SPECULAR_EXPONENT); - spec *= 5.0 * (1.0 - gloss); - diffuse_f.rgb += spec; - #endif - - diffuse_f.rgb *= light; - diffuse_f.rgb += fb_f.rgb; - - #ifdef FAKESHADOWS - diffuse_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord); - #endif - - gl_FragColor = fog4( diffuse_f * e_colourident ) * e_lmscale; - } -#endif diff --git a/base/resources.pk3dir/glsl/vertexmap.glsl b/base/resources.pk3dir/glsl/vertexmap.glsl deleted file mode 100644 index 3f9be75b..00000000 --- a/base/resources.pk3dir/glsl/vertexmap.glsl +++ /dev/null @@ -1,36 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Trisoup whose diffusemap multiplies against the glColor values. -//============================================================================== - -!!ver 110 -!!permu FRAMEBLEND -!!permu FOG -!!samps diffuse - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec4 vex_color; - -#ifdef VERTEX_SHADER - void main () - { - tex_c = v_texcoord; - vex_color = v_colour; - gl_Position = ftetransform(); - } -#endif - - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - void main () - { - vec4 diffuse_f = texture2D( s_diffuse, tex_c ); - diffuse_f.rgb *= vex_color.rgb; - gl_FragColor = fog4( diffuse_f ); - } -#endif diff --git a/base/resources.pk3dir/glsl/water.glsl b/base/resources.pk3dir/glsl/water.glsl deleted file mode 100644 index 4b9e2a24..00000000 --- a/base/resources.pk3dir/glsl/water.glsl +++ /dev/null @@ -1,70 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Basic water shader, No diffuse texture, just pure normalmap + refraction -//============================================================================== - -!!ver 110 -!!permu FOG -!!samps 2 normalmap reflectcube - -#include "sys/defs.h" - -varying mat3 invsurface; -varying vec4 tf_c; -varying vec3 eyeminusvertex; -varying vec3 eyevector; -varying vec2 shift1; -varying vec2 shift2; - -#ifdef VERTEX_SHADER - void main () - { - invsurface[0] = v_svector; - invsurface[1] = v_tvector; - invsurface[2] = v_normal; - eyeminusvertex = e_eyepos - v_position.xyz; - eyevector.x = dot( eyeminusvertex, v_svector.xyz ); - eyevector.y = dot( eyeminusvertex, v_tvector.xyz ); - eyevector.z = dot( eyeminusvertex, v_normal.xyz ); - tf_c = ftetransform(); - tf_c.z += 0.1; /* hack to get rid of refraction artifacts */ - shift1 = v_texcoord + vec2( e_time * 0.1, 0.0 ); - shift2 = v_texcoord - vec2( 0, e_time * -0.01 ); - gl_Position = tf_c; - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - void main ( void ) - { - float fres; - vec2 refl_c; - vec3 refl_f; - vec3 refr_f; - vec3 norm_f; - vec4 out_f = vec4( 1.0, 1.0, 1.0, 1.0 ); - - // Use the normalmap to shift the refraction - norm_f = ( texture2D( s_normalmap, shift1 ).xyz); - norm_f += ( texture2D( s_normalmap, shift2 ).xyz); - norm_f -= 1.0 - ( 4.0 / 256.0 ); - norm_f = normalize( norm_f ) * 0.05; - - // Reflection/View coordinates - refl_c = ( 1.0 + ( tf_c.xy / tf_c.w ) ) * 0.5; - refl_c.t -= 1.5 * invsurface[2].z / 1080.0; - - vec3 cube_c = reflect( normalize( -eyevector ), texture2D( s_normalmap, shift2).rgb * 0.35 ); - cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2]; - cube_c = ( m_model * vec4( cube_c.xyz, 0.0 ) ).xyz; - refl_f = textureCube( s_reflectcube, cube_c ).rgb; - refr_f = texture2D( s_t1, refl_c + ( norm_f.st * 0.1 ) ).rgb; - fres = pow( 1.0 - abs( dot( norm_f, normalize( eyeminusvertex ) ) ), 5.0 ); - out_f.rgb = mix( refr_f, refl_f, fres * 0.25 ); - - gl_FragColor = fog4( out_f ); - } -#endif diff --git a/base/resources.pk3dir/glsl/water_dirty.glsl b/base/resources.pk3dir/glsl/water_dirty.glsl deleted file mode 100644 index 77d7888f..00000000 --- a/base/resources.pk3dir/glsl/water_dirty.glsl +++ /dev/null @@ -1,59 +0,0 @@ -//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Dirty water shader (diffuse and normalmap only) where a refraction-ish effect -// is applied onto the diffusemap itself. -//============================================================================== - -!!ver 110 -!!permu FOG -!!samps diffuse normalmap - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec2 lm_c; -varying vec3 invsurface; -varying vec4 tf_c; -varying vec3 eyeminusvertex; -varying vec2 wat1_c; -varying vec2 wat2_c; - -#ifdef VERTEX_SHADER - void main(void) - { - invsurface = v_normal; - eyeminusvertex = e_eyepos - v_position.xyz; - - tf_c = ftetransform(); - tex_c = v_texcoord; - gl_Position = tf_c; - - wat1_c = tex_c + vec2(e_time * 0.05, 0.0); - wat2_c = tex_c - vec2(0, e_time * 0.05); - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - void main(void) - { - vec3 norm_f; - vec4 out_f = vec4(1.0, 1.0, 1.0, 1.0); - vec2 wat3_c; - - // Use the normalmap to shift the refraction - norm_f = (texture2D(s_normalmap, wat1_c).xyz); - norm_f += (texture2D(s_normalmap, wat2_c).xyz); - norm_f -= 1.0 - (4.0 / 256.0); - norm_f = normalize(norm_f); - - wat3_c = tex_c + (norm_f.st * 0.025) + vec2(sin(e_time * 0.1), 0); - - // Load reflection and refraction based on our new coords - out_f.rgb = texture2D(s_diffuse, wat3_c).rgb; - - gl_FragColor = fog4(out_f); - } -#endif diff --git a/base/resources.pk3dir/glsl/water_high.glsl b/base/resources.pk3dir/glsl/water_high.glsl deleted file mode 100644 index a847367c..00000000 --- a/base/resources.pk3dir/glsl/water_high.glsl +++ /dev/null @@ -1,54 +0,0 @@ -!!ver 110 -!!permu FOG -!!samps reflection=0 refraction=1 normalmap=2 - -#include "sys/defs.h" - -varying vec2 tex_c; -varying mat3 invsurface; -varying vec4 tf_c; -varying vec3 eyeminusvertex; - -#ifdef VERTEX_SHADER - void main () - { - invsurface[0] = v_svector; - invsurface[1] = v_tvector; - invsurface[2] = v_normal; - eyeminusvertex = e_eyepos - v_position.xyz; - tf_c = ftetransform(); - tf_c.z += 0.1; /* hack to get rid of refraction artifacts */ - tex_c = v_texcoord; - gl_Position = tf_c; - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - void main ( void ) - { - float fres; - vec2 refl_c; - vec3 refl_f; - vec3 refr_f; - vec3 norm_f; - vec4 out_f = vec4( 1.0, 1.0, 1.0, 1.0 ); - - norm_f = ( texture2D( s_normalmap, tex_c + vec2( e_time * 0.01, 0.0 ) ).xyz); - norm_f += ( texture2D( s_normalmap, tex_c - vec2( 0, e_time * 0.01 ) ).xyz); - norm_f -= 1.0 - ( 4.0 / 256.0 ); - norm_f = normalize( norm_f ); - - // Reflection/View coordinates - refl_c = ( 1.0 + ( tf_c.xy / tf_c.w ) ) * 0.5; - refl_c.t -= 1.5 * invsurface[2].z / 1080.0; - - refl_f = texture2D( s_reflection, refl_c ).rgb; - refr_f = texture2D( s_refraction, refl_c + ( norm_f.st) ).rgb; - - fres = pow( 1.0 - abs( dot( norm_f, normalize( eyeminusvertex ) ) ), 5.0 ); - out_f.rgb = mix( refr_f, refl_f, fres ); - - gl_FragColor = fog4( out_f ); - } -#endif diff --git a/base/resources.pk3dir/glsl/water_sky.glsl b/base/resources.pk3dir/glsl/water_sky.glsl deleted file mode 100644 index cd77f6b3..00000000 --- a/base/resources.pk3dir/glsl/water_sky.glsl +++ /dev/null @@ -1,80 +0,0 @@ -//======= Copyright (c) 2015-2022 Vera Visions LLC. All rights reserved. ======= -// -// Purpose: -// -// Water shader that distorts the reflection based on a supplied normalmap -// and blends it on top of a skybox (cube) image. -//============================================================================== - -!!ver 110 -!!permu FOG -!!samps reflect=0 norm=1 skycube:samplerCube=2 - -#include "sys/defs.h" - -varying vec2 tex_c; -varying vec2 lm_c; -varying mat3 invsurface; -varying vec4 tf_c; -varying vec3 eyeminusvertex; - -varying vec3 eyevector; -varying vec2 shift1; -varying vec2 shift2; - -#ifdef VERTEX_SHADER - void main () - { - invsurface[0] = v_svector; - invsurface[1] = v_tvector; - invsurface[2] = v_normal; - eyeminusvertex = e_eyepos - v_position.xyz; - eyevector.x = dot(eyeminusvertex, v_svector.xyz); - eyevector.y = dot(eyeminusvertex, v_tvector.xyz); - eyevector.z = dot(eyeminusvertex, v_normal.xyz); - - tf_c = ftetransform(); - tf_c.z += 0.1; - shift1 = v_texcoord + vec2( e_time * 0.025, 0.0 ); - shift2 = v_texcoord - vec2( 0, e_time * -0.025 ); - tex_c = v_texcoord; - gl_Position = tf_c; - } -#endif - -#ifdef FRAGMENT_SHADER - #include "sys/fog.h" - void main ( void ) - { - float fres; - vec2 refl_c; - vec3 refl_f; - vec3 refr_f; - vec3 norm_f; - vec3 cube_c; - vec4 out_f = vec4( 1.0, 1.0, 1.0, 1.0 ); - - // Use the normalmap to shift the refraction - norm_f = ( texture2D( s_norm, shift1 ).xyz); - norm_f += ( texture2D( s_norm, shift2 ).xyz); - norm_f -= 1.0 - ( 16.0 / 1024.0 ); - norm_f = normalize( norm_f ); - - // Reflection/View coordinates - refl_c = ( 1.0 + ( tf_c.xy / tf_c.w ) ) * 0.5; - refl_c.t -= 1.5 * invsurface[2].z / 1080.0; - - // Load reflection and refraction based on our new coords - refl_f = texture2D(s_reflect, refl_c + ( norm_f.st * 0.1 )).rgb; - - cube_c = reflect(normalize(eyevector), norm_f.rgb); - cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2]; - cube_c = (m_model * vec4(cube_c.xyz, 0.0)).xyz; - refr_f = textureCube(s_skycube, cube_c).rgb; - - fres = pow( 1.0 - abs( dot( norm_f, normalize( eyeminusvertex ) ) ), 1.0 ); - out_f.rgb = mix( refr_f, refl_f, fres ); - - gl_FragColor = fog4(out_f); - } -#endif diff --git a/base/src/client/hud.qc b/base/src/client/hud.qc index f2bf22b6..bded0474 100644 --- a/base/src/client/hud.qc +++ b/base/src/client/hud.qc @@ -32,12 +32,15 @@ HUD_Draw(void) iconPos[1] = (hudSize[1] - baseIconSize) - baseIconPadding; /* health, armor icons */ + Font_DrawRText(iconPos + [-((baseIconSize/2) + (baseIconPadding/2)) - baseIconPadding, 0], "100", FONT_16); drawpic(iconPos + [-((baseIconSize/2) + (baseIconPadding/2)), 0], "gfx/hud/health", [baseIconSize, baseIconSize], [1,1,1], 1.0f); + Font_DrawText(iconPos + [(baseIconSize/2) + (baseIconPadding/2) + baseIconSize + baseIconPadding, 0], "100", FONT_16); drawpic(iconPos + [(baseIconSize/2) + (baseIconPadding/2), 0], "gfx/hud/armor", [baseIconSize, baseIconSize], [1,1,1], 1.0f); - /* ammo icon */ - iconPos[0] = (hudSize[0] - baseIconSize) - baseIconPadding; - drawpic(iconPos, "gfx/hud/armor", [baseIconSize, baseIconSize], [1,1,1], 1.0f); + /* little point in not drawing these, even if you don't have a suit */ + if (pl.m_activeWeapon) { + pl.m_activeWeapon.UpdateGUI(); + } Textmenu_Draw(); } diff --git a/base/src/server/defs.h b/base/src/server/defs.h index a1c6292f..cca3ce67 100644 --- a/base/src/server/defs.h +++ b/base/src/server/defs.h @@ -13,5 +13,3 @@ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -#include "gamerules.h" \ No newline at end of file diff --git a/base/src/server/gamerules_multiplayer.qc b/base/src/server/gamerules_multiplayer.qc index c2e48e4e..c919ebb3 100644 --- a/base/src/server/gamerules_multiplayer.qc +++ b/base/src/server/gamerules_multiplayer.qc @@ -14,114 +14,15 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -void -MultiplayerRules::MultiplayerRules(void) -{ - -} - -void -MultiplayerRules::FrameStart(void) -{ - if (cvar("mp_timelimit")) - if (time >= (cvar("mp_timelimit") * 60)) { - IntermissionStart(); - } - - IntermissionCycle(); -} - -void -MultiplayerRules::PlayerDeath(NSClientPlayer pl) -{ - Plugin_PlayerObituary(g_dmg_eAttacker, g_dmg_eTarget, g_dmg_iWeapon, g_dmg_iHitBody, g_dmg_iDamage); - - /* death-counter */ - pl.deaths++; - forceinfokey(pl, "*deaths", ftos(pl.deaths)); - - /* update score-counter */ - if (pl.flags & FL_CLIENT || pl.flags & FL_MONSTER) - if (g_dmg_eAttacker.flags & FL_CLIENT) { - if (pl == g_dmg_eAttacker) - g_dmg_eAttacker.frags--; - else - g_dmg_eAttacker.frags++; - } - - /* in DM we only care about the frags */ - if (cvar("mp_fraglimit")) - if (g_dmg_eAttacker.frags >= cvar("mp_fraglimit")) { - IntermissionStart(); - } - - pl.SetMovetype(MOVETYPE_NONE); - pl.SetSolid(SOLID_NOT); - pl.SetModelindex(0); - pl.takedamage = DAMAGE_NO; - pl.armor = pl.activeweapon = pl.g_items = 0; - - pl.think = PutClientInServer; - pl.nextthink = time + 4.0f; -} - -void -MultiplayerRules::PlayerSpawn(NSClientPlayer pl) -{ - /* this is where the mods want to deviate */ - entity spot; - - pl.classname = "player"; - pl.health = pl.max_health = 100; - pl.takedamage = DAMAGE_YES; - pl.solid = SOLID_SLIDEBOX; - pl.movetype = MOVETYPE_WALK; - pl.flags = FL_CLIENT; - pl.viewzoom = 1.0; - pl.model = "models/player.mdl"; - setmodel(pl, pl.model); - - setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); - pl.velocity = [0,0,0]; - pl.gravity = __NULL__; - pl.frame = 1; - pl.SendFlags = UPDATE_ALL; - pl.customphysics = Empty; - pl.iBleeds = TRUE; - forceinfokey(pl, "*spec", "0"); - forceinfokey(pl, "*deaths", ftos(pl.deaths)); - - LevelNewParms(); - LevelDecodeParms(pl); - - spot = Spawn_SelectRandom("info_player_deathmatch"); - setorigin(pl, spot.origin); - pl.angles = spot.angles; - - Client_FixAngle(pl, pl.angles); -} - -float -MultiplayerRules::ConsoleCommand(NSClientPlayer pp, string cmd) -{ - tokenize(cmd); - - switch (argv(0)) { - default: - return (0); - } - - return (1); -} - void Game_InitRules(void) { - g_grMode = spawn(MultiplayerRules); - - if (cvar("sv_playerslots") == 1 || cvar("coop") == 1) { - g_grMode = spawn(SingleplayerRules); - } else { - g_grMode = spawn(MultiplayerRules); - } + g_grMode = NSGameRules::InitFromProgs("maps/mp/gametypes/dm.dat"); } + + +void +Game_Worldspawn(void) +{ + +} \ No newline at end of file diff --git a/base/src/server/progs.src b/base/src/server/progs.src index 523c891c..8b74abf0 100644 --- a/base/src/server/progs.src +++ b/base/src/server/progs.src @@ -22,8 +22,6 @@ defs.h ../../../src/botlib/include.src /* mod specific functions */ -gamerules.qc -gamerules_singleplayer.qc gamerules_multiplayer.qc /* global server/shared code */ diff --git a/base/test_maps.pk3dir/maps/test/pbr.bsp b/base/test_maps.pk3dir/maps/test/pbr.bsp new file mode 100644 index 00000000..54db985e Binary files /dev/null and b/base/test_maps.pk3dir/maps/test/pbr.bsp differ diff --git a/base/test_maps.pk3dir/maps/test/pbr.map b/base/test_maps.pk3dir/maps/test/pbr.map new file mode 100644 index 00000000..cbf4286e --- /dev/null +++ b/base/test_maps.pk3dir/maps/test/pbr.map @@ -0,0 +1,343 @@ + +// entity 0 +{ +"classname" "worldspawn" +// brush 0 +{ +( 248 192 -64 ) ( 248 -192 -64 ) ( -264 192 -64 ) pbrtest/pavingstones094 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 256 192 8 ) ( -256 192 8 ) ( 256 192 0 ) pbrtestz/pavingstones094 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 256 192 8 ) ( 256 192 0 ) ( 256 -192 8 ) pbrtest/pavingstones094 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -256 -192 -128 ) ( 256 -192 -128 ) ( -256 192 -128 ) pbrtest/pavingstones094 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( -256 -192 0 ) ( -256 -192 8 ) ( 256 -192 0 ) pbrtest/pavingstones094 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 0 -184 0 ) ( 0 200 0 ) ( 0 -184 8 ) pbrtest/pavingstones094 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +} +// brush 1 +{ +( 248 192 192 ) ( 248 -192 192 ) ( -264 192 192 ) common/skyportal [ 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 ) common/skyportal [ 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 ) common/skyportal [ 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 ) common/skyportal [ 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 ) common/skyportal [ 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 ) common/skyportal [ 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 ) pbrtest/leather011 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 192 192 264 ) ( -320 192 264 ) ( 192 192 256 ) pbrtest/leather011 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -256 192 8 ) ( -256 192 0 ) ( -256 -192 8 ) pbrtest/leather011 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -768 -192 -128 ) ( -256 -192 -128 ) ( -768 192 -128 ) pbrtest/leather011 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( -320 -192 256 ) ( -320 -192 264 ) ( 192 -192 256 ) pbrtest/leather011 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 -192 256 ) ( -320 192 256 ) ( -320 -192 264 ) pbrtest/leather011 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +} +// brush 3 +{ +( 760 192 192 ) ( 760 -192 192 ) ( 248 192 192 ) pbrtest/tiles032 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 768 192 264 ) ( 256 192 264 ) ( 768 192 256 ) pbrtest/tiles032 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 320 192 8 ) ( 320 192 0 ) ( 320 -192 8 ) pbrtest/tiles032 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -192 -192 -128 ) ( 320 -192 -128 ) ( -192 192 -128 ) pbrtest/tiles032 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 256 -192 256 ) ( 256 -192 264 ) ( 768 -192 256 ) pbrtest/tiles032 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 256 -192 256 ) ( 256 192 256 ) ( 256 -192 264 ) pbrtest/tiles032 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +} +// brush 4 +{ +( 184 -192 192 ) ( 184 -576 192 ) ( -328 -192 192 ) pbrtest/bricks023 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 192 -192 264 ) ( -320 -192 264 ) ( 192 -192 256 ) pbrtest/bricks023 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 320 96 8 ) ( 320 96 0 ) ( 320 -288 8 ) pbrtest/bricks023 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -768 -576 -128 ) ( -256 -576 -128 ) ( -768 -192 -128 ) pbrtest/bricks023 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 272 -256 256 ) ( 272 -256 264 ) ( 784 -256 256 ) pbrtest/bricks023 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 -576 256 ) ( -320 -192 256 ) ( -320 -576 264 ) pbrtest/bricks023 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +} +// brush 5 +{ +( 248 192 -64 ) ( 248 -192 -64 ) ( -264 192 -64 ) pbrtest/marble006 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 256 192 8 ) ( -256 192 8 ) ( 256 192 0 ) pbrtest/marble006 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 0 192 8 ) ( 0 192 0 ) ( 0 -192 8 ) pbrtest/marble006 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -256 -192 -128 ) ( 256 -192 -128 ) ( -256 192 -128 ) pbrtest/marble006 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( -256 -192 0 ) ( -256 -192 8 ) ( 256 -192 0 ) pbrtest/marble006 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -256 -192 0 ) ( -256 192 0 ) ( -256 -192 8 ) pbrtest/marble006 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +} +// brush 6 +{ +patchDef2 +{ +pbrtest/metal012 +( 31 31 0 0 0 ) +( +( ( 0 0 0 0 0 ) ( 2.1020846367 0 -0.0000004728 0 -0.002052817 ) ( 4.1582341194 0 0.437048018 0 -0.0041056345 ) ( 6.2143831253 0 0.8740955591 0 -0.0061584515 ) ( 8.1347332001 0 1.729090929 0 -0.008211269 ) ( 10.0550832748 0 2.5840854645 0 -0.0102640856 ) ( 11.7557048798 0 3.8196604252 0 -0.0123169031 ) ( 13.456328392 0 5.0552344322 0 -0.0143697206 ) ( 14.8628969193 0 6.6173882484 0 -0.0164225381 ) ( 16.2694664001 0 8.1795415878 0 -0.0184753556 ) ( 17.3205070496 0 10.0000009537 0 -0.0205281731 ) ( 18.3715515137 0 11.8204593658 0 -0.0225809887 ) ( 19.0211296082 0 13.8196611404 0 -0.0246338062 ) ( 19.6707115173 0 15.8188619614 0 -0.0266866237 ) ( 19.8904380798 0 17.9094314575 0 -0.0287394412 ) ( 20.1101665497 0 20 0 -0.0307922568 ) ( 19.8904380798 0 22.0905704498 0 -0.0328450762 ) ( 19.6707115173 0 24.1811389923 0 -0.0348978937 ) ( 19.0211296082 0 26.1803417206 0 -0.0369507112 ) ( 18.3715515137 0 28.1795425415 0 -0.0390035287 ) ( 17.3205070496 0 30.0000019073 0 -0.0410563461 ) ( 16.2694664001 0 31.8204574585 0 -0.0431091599 ) ( 14.8628959656 0 33.3826141357 0 -0.0451619774 ) ( 13.456328392 0 34.9447669983 0 -0.0472147949 ) ( 11.7557039261 0 36.1803398132 0 -0.0492676124 ) ( 10.0550842285 0 37.4159126282 0 -0.0513204262 ) ( 8.1347312927 0 38.2709083557 0 -0.0533732474 ) ( 6.214384079 0 39.1259040833 0 -0.0554260612 ) ( 4.1582322121 0 39.562953949 0 -0.0574788824 ) ( 2.1020855904 0 40 0 -0.0595316961 ) ( -0.0000019073 0 40 0 -0.0615845174 ) ) +( ( 0 0 0 0.0041743629 0 ) ( 2.1020846367 0.446811676 -0.0000004728 0.0041743629 -0.002052817 ) ( 4.1582336426 0.8838596344 0.437048018 0.0041743629 -0.0041056345 ) ( 6.2143831253 1.3209075928 0.8740955591 0.0041743629 -0.0061584515 ) ( 8.1347332001 1.7290906906 1.729090929 0.0041743629 -0.008211269 ) ( 10.0550823212 2.1372737885 2.5840854645 0.0041743629 -0.0102640856 ) ( 11.7557048798 2.4987521172 3.8196604252 0.0041743629 -0.0123169031 ) ( 13.4563274384 2.8602304459 5.0552344322 0.0041743629 -0.0143697206 ) ( 14.8628959656 3.1592063904 6.6173882484 0.0041743629 -0.0164225381 ) ( 16.2694664001 3.4581818581 8.1795415878 0.0041743629 -0.0184753556 ) ( 17.3205070496 3.6815876961 10.0000009537 0.0041743629 -0.0205281731 ) ( 18.3715496063 3.9049935341 11.8204593658 0.0041743629 -0.0225809887 ) ( 19.0211296082 4.0430660248 13.8196611404 0.0041743629 -0.0246338062 ) ( 19.67070961 4.1811389923 15.8188619614 0.0041743629 -0.0266866237 ) ( 19.8904380798 4.2278432846 17.9094314575 0.0041743629 -0.0287394412 ) ( 20.1101646423 4.2745475769 20 0.0041743629 -0.0307922568 ) ( 19.8904361725 4.2278432846 22.0905704498 0.0041743629 -0.0328450762 ) ( 19.67070961 4.1811380386 24.1811389923 0.0041743629 -0.0348978937 ) ( 19.0211296082 4.0430660248 26.1803417206 0.0041743629 -0.0369507112 ) ( 18.3715496063 3.9049935341 28.1795425415 0.0041743629 -0.0390035287 ) ( 17.3205070496 3.6815872192 30.0000019073 0.0041743629 -0.0410563461 ) ( 16.2694664001 3.4581818581 31.8204574585 0.0041743629 -0.0431091599 ) ( 14.8628950119 3.1592059135 33.3826141357 0.0041743629 -0.0451619774 ) ( 13.4563274384 2.8602309227 34.9447669983 0.0041743629 -0.0472147949 ) ( 11.7557029724 2.4987516403 36.1803398132 0.0041743629 -0.0492676124 ) ( 10.0550832748 2.1372737885 37.4159126282 0.0041743629 -0.0513204262 ) ( 8.1347312927 1.7290906906 38.2709083557 0.0041743629 -0.0533732474 ) ( 6.2143836021 1.3209080696 39.1259040833 0.0041743629 -0.0554260612 ) ( 4.1582317352 0.8838596344 39.562953949 0.0041743629 -0.0574788824 ) ( 2.1020853519 0.4468121529 40 0.0041743629 -0.0595316961 ) ( -0.0000019073 -0.0000004768 40 0.0041743629 -0.0615845174 ) ) +( ( 0 0 0 0.0083487257 0 ) ( 1.9203500748 0.8549947739 -0.0000004728 0.0083487257 -0.002052817 ) ( 3.7987356186 1.6913061142 0.437048018 0.0083487257 -0.0041056345 ) ( 5.6771216393 2.5276174545 0.8740955591 0.0083487257 -0.0061584515 ) ( 7.4314484596 3.3086938858 1.729090929 0.0083487257 -0.008211269 ) ( 9.1857757568 4.0897712708 2.5840854645 0.0083487257 -0.0102640856 ) ( 10.7393712997 4.7814760208 3.8196604252 0.0083487257 -0.0123169031 ) ( 12.2929668427 5.4731817245 5.0552344322 0.0083487257 -0.0143697206 ) ( 13.5779314041 6.0452852249 6.6173882484 0.0083487257 -0.0164225381 ) ( 14.8628969193 6.6173877716 8.1795415878 0.0083487257 -0.0184753556 ) ( 15.8230714798 7.0448856354 10.0000009537 0.0083487257 -0.0205281731 ) ( 16.783246994 7.4723834991 11.8204593658 0.0083487257 -0.0225809887 ) ( 17.3766670227 7.7365913391 13.8196611404 0.0083487257 -0.0246338062 ) ( 17.9700889587 8.0007991791 15.8188619614 0.0083487257 -0.0266866237 ) ( 18.1708183289 8.0901699066 17.9094314575 0.0083487257 -0.0287394412 ) ( 18.3715515137 8.1795415878 20 0.0083487257 -0.0307922568 ) ( 18.1708183289 8.0901699066 22.0905704498 0.0083487257 -0.0328450762 ) ( 17.9700889587 8.0007991791 24.1811389923 0.0083487257 -0.0348978937 ) ( 17.3766670227 7.7365913391 26.1803417206 0.0083487257 -0.0369507112 ) ( 16.7832450867 7.4723834991 28.1795425415 0.0083487257 -0.0390035287 ) ( 15.8230705261 7.0448856354 30.0000019073 0.0083487257 -0.0410563461 ) ( 14.8628978729 6.6173887253 31.8204574585 0.0083487257 -0.0431091599 ) ( 13.5779304504 6.0452842712 33.3826141357 0.0083487257 -0.0451619774 ) ( 12.2929677963 5.4731817245 34.9447669983 0.0083487257 -0.0472147949 ) ( 10.7393703461 4.7814760208 36.1803398132 0.0083487257 -0.0492676124 ) ( 9.1857757568 4.0897712708 37.4159126282 0.0083487257 -0.0513204262 ) ( 7.4314470291 3.308693409 38.2709083557 0.0083487257 -0.0533732474 ) ( 5.6771221161 2.5276174545 39.1259040833 0.0083487257 -0.0554260612 ) ( 3.7987341881 1.6913051605 39.562953949 0.0083487257 -0.0574788824 ) ( 1.9203505516 0.8549952507 40 0.0083487257 -0.0595316961 ) ( -0.0000014305 -0.0000004768 40 0.0083487257 -0.0615845174 ) ) +( ( 0 0 0 0.0125230886 0 ) ( 1.738615036 1.2631778717 -0.0000004728 0.0125230886 -0.002052817 ) ( 3.4392371178 2.4987521172 0.437048018 0.0125230886 -0.0041056345 ) ( 5.1398596764 3.7343268394 0.8740955591 0.0125230886 -0.0061584515 ) ( 6.7281632423 4.888297081 1.729090929 0.0125230886 -0.008211269 ) ( 8.3164672852 6.0422677994 2.5840854645 0.0125230886 -0.0102640856 ) ( 9.7230358124 7.0641994476 3.8196604252 0.0125230886 -0.0123169031 ) ( 11.1296062469 8.0861320496 5.0552344322 0.0125230886 -0.0143697206 ) ( 12.292965889 8.9313631058 6.6173882484 0.0125230886 -0.0164225381 ) ( 13.4563264847 9.776594162 8.1795415878 0.0125230886 -0.0184753556 ) ( 14.3256340027 10.4081821442 10.0000009537 0.0125230886 -0.0205281731 ) ( 15.1949415207 11.0397720337 11.8204593658 0.0125230886 -0.0225809887 ) ( 15.7322034836 11.4301147461 13.8196611404 0.0125230886 -0.0246338062 ) ( 16.2694664001 11.8204593658 15.8188619614 0.0125230886 -0.0266866237 ) ( 16.4511985779 11.9524965286 17.9094314575 0.0125230886 -0.0287394412 ) ( 16.6329345703 12.0845336914 20 0.0125230886 -0.0307922568 ) ( 16.4511985779 11.9524965286 22.0905704498 0.0125230886 -0.0328450762 ) ( 16.2694644928 11.8204584122 24.1811389923 0.0125230886 -0.0348978937 ) ( 15.7322025299 11.4301147461 26.1803417206 0.0125230886 -0.0369507112 ) ( 15.1949415207 11.0397720337 28.1795425415 0.0125230886 -0.0390035287 ) ( 14.325633049 10.4081821442 30.0000019073 0.0125230886 -0.0410563461 ) ( 13.4563274384 9.776594162 31.8204574585 0.0125230886 -0.0431091599 ) ( 12.2929649353 8.9313621521 33.3826141357 0.0125230886 -0.0451619774 ) ( 11.1296062469 8.0861320496 34.9447669983 0.0125230886 -0.0472147949 ) ( 9.7230358124 7.0641994476 36.1803398132 0.0125230886 -0.0492676124 ) ( 8.3164672852 6.0422677994 37.4159126282 0.0125230886 -0.0513204262 ) ( 6.7281618118 4.8882961273 38.2709083557 0.0125230886 -0.0533732474 ) ( 5.1398601532 3.7343273163 39.1259040833 0.0125230886 -0.0554260612 ) ( 3.4392359257 2.4987511635 39.562953949 0.0125230886 -0.0574788824 ) ( 1.7386157513 1.2631783485 40 0.0125230886 -0.0595316961 ) ( -0.0000014305 -0.0000009537 40 0.0125230886 -0.0615845174 ) ) +( ( 0 0 0 0.0166974515 0 ) ( 1.4065692425 1.5621538162 -0.0000004728 0.0166974515 -0.002052817 ) ( 2.7824015617 3.0901699066 0.437048018 0.0166974515 -0.0041056345 ) ( 4.1582341194 4.6181869507 0.8740955591 0.0166974515 -0.0061584515 ) ( 5.4431986809 6.0452852249 1.729090929 0.0166974515 -0.008211269 ) ( 6.7281637192 7.4723834991 2.5840854645 0.0166974515 -0.0102640856 ) ( 7.8661022186 8.7361917496 3.8196604252 0.0166974515 -0.0123169031 ) ( 9.0040407181 10 5.0552344322 0.0166974515 -0.0143697206 ) ( 9.9452190399 11.0452852249 6.6173882484 0.0166974515 -0.0164225381 ) ( 10.8863983154 12.0905704498 8.1795415878 0.0166974515 -0.0184753556 ) ( 11.5896816254 12.8716468811 10.0000009537 0.0166974515 -0.0205281731 ) ( 12.2929668427 13.6527233124 11.8204593658 0.0166974515 -0.0225809887 ) ( 12.7276201248 14.1354560852 13.8196611404 0.0166974515 -0.0246338062 ) ( 13.1622743607 14.6181869507 15.8188619614 0.0166974515 -0.0266866237 ) ( 13.3093004227 14.7814750671 17.9094314575 0.0166974515 -0.0287394412 ) ( 13.4563274384 14.9447669983 20 0.0166974515 -0.0307922568 ) ( 13.3093004227 14.7814750671 22.0905704498 0.0166974515 -0.0328450762 ) ( 13.1622743607 14.6181869507 24.1811389923 0.0166974515 -0.0348978937 ) ( 12.7276201248 14.1354541779 26.1803417206 0.0166974515 -0.0369507112 ) ( 12.292965889 13.6527233124 28.1795425415 0.0166974515 -0.0390035287 ) ( 11.5896816254 12.8716468811 30.0000019073 0.0166974515 -0.0410563461 ) ( 10.8863983154 12.0905704498 31.8204574585 0.0166974515 -0.0431091599 ) ( 9.9452180862 11.0452842712 33.3826141357 0.0166974515 -0.0451619774 ) ( 9.0040407181 10.0000009537 34.9447669983 0.0166974515 -0.0472147949 ) ( 7.866101265 8.7361907959 36.1803398132 0.0166974515 -0.0492676124 ) ( 6.728164196 7.4723834991 37.4159126282 0.0166974515 -0.0513204262 ) ( 5.4431977272 6.0452842712 38.2709083557 0.0166974515 -0.0533732474 ) ( 4.1582341194 4.6181869507 39.1259040833 0.0166974515 -0.0554260612 ) ( 2.7824003696 3.0901689529 39.562953949 0.0166974515 -0.0574788824 ) ( 1.4065697193 1.5621538162 40 0.0166974515 -0.0595316961 ) ( -0.0000009537 -0.0000014305 40 0.0166974515 -0.0615845174 ) ) +( ( 0 0 0 0.0208718143 0 ) ( 1.0745232105 1.8611288071 -0.0000004728 0.0208718143 -0.002052817 ) ( 2.1255655289 3.6815876961 0.437048018 0.0208718143 -0.0041056345 ) ( 3.1766078472 5.5020465851 0.8740955591 0.0208718143 -0.0061584515 ) ( 4.1582336426 7.2022724152 1.729090929 0.0208718143 -0.008211269 ) ( 5.1398591995 8.9024982452 2.5840854645 0.0208718143 -0.0102640856 ) ( 6.0091667175 10.4081821442 3.8196604252 0.0208718143 -0.0123169031 ) ( 6.8784742355 11.9138679504 5.0552344322 0.0208718143 -0.0143697206 ) ( 7.5974702835 13.1592063904 6.6173882484 0.0208718143 -0.0164225381 ) ( 8.3164672852 14.4045448303 8.1795415878 0.0208718143 -0.0184753556 ) ( 8.8537282944 15.3351097107 10.0000009537 0.0208718143 -0.0205281731 ) ( 9.3909902573 16.2656745911 11.8204593658 0.0208718143 -0.0225809887 ) ( 9.7230358124 16.8407936096 13.8196611404 0.0208718143 -0.0246338062 ) ( 10.0550823212 17.4159145355 15.8188619614 0.0208718143 -0.0266866237 ) ( 10.1674003601 17.6104545593 17.9094314575 0.0208718143 -0.0287394412 ) ( 10.279718399 17.8049964905 20 0.0208718143 -0.0307922568 ) ( 10.1674003601 17.6104545593 22.0905704498 0.0208718143 -0.0328450762 ) ( 10.0550823212 17.4159126282 24.1811389923 0.0208718143 -0.0348978937 ) ( 9.7230358124 16.8407936096 26.1803417206 0.0208718143 -0.0369507112 ) ( 9.3909893036 16.2656726837 28.1795425415 0.0208718143 -0.0390035287 ) ( 8.8537273407 15.3351078033 30.0000019073 0.0208718143 -0.0410563461 ) ( 8.3164672852 14.4045448303 31.8204574585 0.0208718143 -0.0431091599 ) ( 7.5974702835 13.159204483 33.3826141357 0.0208718143 -0.0451619774 ) ( 6.8784747124 11.9138679504 34.9447669983 0.0208718143 -0.0472147949 ) ( 6.0091657639 10.4081821442 36.1803398132 0.0208718143 -0.0492676124 ) ( 5.1398596764 8.9024982452 37.4159126282 0.0208718143 -0.0513204262 ) ( 4.1582326889 7.2022705078 38.2709083557 0.0208718143 -0.0533732474 ) ( 3.1766080856 5.5020465851 39.1259040833 0.0208718143 -0.0554260612 ) ( 2.1255645752 3.6815862656 39.562953949 0.0208718143 -0.0574788824 ) ( 1.0745234489 1.8611297607 40 0.0208718143 -0.0595316961 ) ( -0.0000009537 -0.0000014305 40 0.0208718143 -0.0615845174 ) ) +( ( 0 0 0 0.0250461772 0 ) ( 0.6495797634 1.9992017746 -0.0000004728 0.0250461772 -0.002052817 ) ( 1.2849647999 3.9547157288 0.437048018 0.0250461772 -0.0041056345 ) ( 1.9203498363 5.9102296829 0.8740955591 0.0250461772 -0.0061584515 ) ( 2.5137705803 7.7365913391 1.729090929 0.0250461772 -0.008211269 ) ( 3.1071913242 9.5629520416 2.5840854645 0.0250461772 -0.0102640856 ) ( 3.6327123642 11.1803398132 3.8196604252 0.0250461772 -0.0123169031 ) ( 4.1582336426 12.7977294922 5.0552344322 0.0250461772 -0.0143697206 ) ( 4.5928874016 14.1354560852 6.6173882484 0.0250461772 -0.0164225381 ) ( 5.0275411606 15.4731826782 8.1795415878 0.0250461772 -0.0184753556 ) ( 5.3523306847 16.472782135 10.0000009537 0.0250461772 -0.0205281731 ) ( 5.6771211624 17.4723834991 11.8204593658 0.0250461772 -0.0225809887 ) ( 5.877851963 18.0901699066 13.8196611404 0.0250461772 -0.0246338062 ) ( 6.0785832405 18.7079582214 15.8188619614 0.0250461772 -0.0266866237 ) ( 6.1464824677 18.9169311523 17.9094314575 0.0250461772 -0.0287394412 ) ( 6.2143821716 19.1259040833 20 0.0250461772 -0.0307922568 ) ( 6.1464824677 18.9169311523 22.0905704498 0.0250461772 -0.0328450762 ) ( 6.0785832405 18.7079582214 24.1811389923 0.0250461772 -0.0348978937 ) ( 5.877851963 18.0901699066 26.1803417206 0.0250461772 -0.0369507112 ) ( 5.6771206856 17.4723815918 28.1795425415 0.0250461772 -0.0390035287 ) ( 5.3523306847 16.472782135 30.0000019073 0.0250461772 -0.0410563461 ) ( 5.0275411606 15.4731826782 31.8204574585 0.0250461772 -0.0431091599 ) ( 4.5928869247 14.1354541779 33.3826141357 0.0250461772 -0.0451619774 ) ( 4.1582336426 12.7977294922 34.9447669983 0.0250461772 -0.0472147949 ) ( 3.6327118874 11.1803388596 36.1803398132 0.0250461772 -0.0492676124 ) ( 3.1071915627 9.5629529953 37.4159126282 0.0250461772 -0.0513204262 ) ( 2.5137701035 7.7365894318 38.2709083557 0.0250461772 -0.0533732474 ) ( 1.9203500748 5.9102306366 39.1259040833 0.0250461772 -0.0554260612 ) ( 1.284964323 3.9547138214 39.562953949 0.0250461772 -0.0574788824 ) ( 0.6495800018 1.9992017746 40 0.0250461772 -0.0595316961 ) ( -0.0000004768 -0.0000014305 40 0.0250461772 -0.0615845174 ) ) +( ( 0 0 0 0.0292205401 0 ) ( 0.2246365547 2.1372737885 -0.0000004728 0.0292205401 -0.002052817 ) ( 0.4443640709 4.2278432846 0.437048018 0.0292205401 -0.0041056345 ) ( 0.6640915871 6.3184127808 0.8740955591 0.0292205401 -0.0061584515 ) ( 0.8693072796 8.2709083557 1.729090929 0.0292205401 -0.008211269 ) ( 1.0745227337 10.223405838 2.5840854645 0.0292205401 -0.0102640856 ) ( 1.256257534 11.9524965286 3.8196604252 0.0292205401 -0.0123169031 ) ( 1.4379923344 13.6815872192 5.0552344322 0.0292205401 -0.0143697206 ) ( 1.5883033276 15.1117019653 6.6173882484 0.0292205401 -0.0164225381 ) ( 1.7386145592 16.5418167114 8.1795415878 0.0292205401 -0.0184753556 ) ( 1.8509325981 17.6104545593 10.0000009537 0.0292205401 -0.0205281731 ) ( 1.9632508755 18.6790924072 11.8204593658 0.0292205401 -0.0225809887 ) ( 2.03266716 19.3395462036 13.8196611404 0.0292205401 -0.0246338062 ) ( 2.102083683 20 15.8188619614 0.0292205401 -0.0266866237 ) ( 2.1255645752 20.223405838 17.9094314575 0.0292205401 -0.0287394412 ) ( 2.1490454674 20.446811676 20 0.0292205401 -0.0307922568 ) ( 2.1255645752 20.2234039307 22.0905704498 0.0292205401 -0.0328450762 ) ( 2.102083683 20 24.1811389923 0.0292205401 -0.0348978937 ) ( 2.03266716 19.3395442963 26.1803417206 0.0292205401 -0.0369507112 ) ( 1.9632508755 18.6790924072 28.1795425415 0.0292205401 -0.0390035287 ) ( 1.8509325981 17.6104545593 30.0000019073 0.0292205401 -0.0410563461 ) ( 1.7386145592 16.5418186188 31.8204574585 0.0292205401 -0.0431091599 ) ( 1.5883030891 15.1117019653 33.3826141357 0.0292205401 -0.0451619774 ) ( 1.4379923344 13.6815872192 34.9447669983 0.0292205401 -0.0472147949 ) ( 1.2562572956 11.952495575 36.1803398132 0.0292205401 -0.0492676124 ) ( 1.0745229721 10.223405838 37.4159126282 0.0292205401 -0.0513204262 ) ( 0.8693070412 8.270907402 38.2709083557 0.0292205401 -0.0533732474 ) ( 0.6640915871 6.3184127808 39.1259040833 0.0292205401 -0.0554260612 ) ( 0.4443638325 4.2278413773 39.562953949 0.0292205401 -0.0574788824 ) ( 0.2246365547 2.1372747421 40 0.0292205401 -0.0595316961 ) ( 0 -0.0000019073 40 0.0292205401 -0.0615845174 ) ) +( ( 0 0 0 0.0333949029 0 ) ( -0.219727993 2.0905694962 -0.0000004728 0.0333949029 -0.002052817 ) ( -0.434653759 4.1354551315 0.437048018 0.0333949029 -0.0041056345 ) ( -0.6495800018 6.1803398132 0.8740955591 0.0333949029 -0.0061584515 ) ( -0.8503117561 8.0901699066 1.729090929 0.0333949029 -0.008211269 ) ( -1.0510430336 10 2.5840854645 0.0333949029 -0.0102640856 ) ( -1.2288064957 11.6913061142 3.8196604252 0.0333949029 -0.0123169031 ) ( -1.4065699577 13.3826122284 5.0552344322 0.0333949029 -0.0143697206 ) ( -1.5535964966 14.7814750671 6.6173882484 0.0333949029 -0.0164225381 ) ( -1.7006230354 16.1803398132 8.1795415878 0.0333949029 -0.0184753556 ) ( -1.8104867935 17.2256240845 10.0000009537 0.0333949029 -0.0205281731 ) ( -1.9203510284 18.2709083557 11.8204593658 0.0333949029 -0.0225809887 ) ( -1.9882502556 18.9169311523 13.8196611404 0.0333949029 -0.0246338062 ) ( -2.0561499596 19.562953949 15.8188619614 0.0333949029 -0.0266866237 ) ( -2.079117775 19.7814750671 17.9094314575 0.0333949029 -0.0287394412 ) ( -2.1020855904 20 20 0.0333949029 -0.0307922568 ) ( -2.079117775 19.7814750671 22.0905704498 0.0333949029 -0.0328450762 ) ( -2.0561499596 19.5629520416 24.1811389923 0.0333949029 -0.0348978937 ) ( -1.9882502556 18.9169311523 26.1803417206 0.0333949029 -0.0369507112 ) ( -1.9203505516 18.2709083557 28.1795425415 0.0333949029 -0.0390035287 ) ( -1.8104867935 17.2256240845 30.0000019073 0.0333949029 -0.0410563461 ) ( -1.7006230354 16.1803398132 31.8204574585 0.0333949029 -0.0431091599 ) ( -1.5535964966 14.7814750671 33.3826141357 0.0333949029 -0.0451619774 ) ( -1.4065699577 13.3826141357 34.9447669983 0.0333949029 -0.0472147949 ) ( -1.2288060188 11.6913051605 36.1803398132 0.0333949029 -0.0492676124 ) ( -1.0510430336 10.0000009537 37.4159126282 0.0333949029 -0.0513204262 ) ( -0.8503112793 8.0901679993 38.2709083557 0.0333949029 -0.0533732474 ) ( -0.6495804787 6.1803407669 39.1259040833 0.0333949029 -0.0554260612 ) ( -0.434653759 4.1354532242 39.562953949 0.0333949029 -0.0574788824 ) ( -0.219727993 2.090569973 40 0.0333949029 -0.0595316961 ) ( 0.0000002384 -0.0000019073 40 0.0333949029 -0.0615845174 ) ) +( ( 0 0 0 0.0375692658 0 ) ( -0.6640920639 2.043864727 -0.0000004728 0.0375692658 -0.002052817 ) ( -1.3136720657 4.0430660248 0.437048018 0.0375692658 -0.0041056345 ) ( -1.9632520676 6.0422668457 0.8740955591 0.0375692658 -0.0061584515 ) ( -2.5699300766 7.9094305038 1.729090929 0.0375692658 -0.008211269 ) ( -3.1766085625 9.776594162 2.5840854645 0.0375692658 -0.0102640856 ) ( -3.7138700485 11.4301147461 3.8196604252 0.0375692658 -0.0123169031 ) ( -4.2511320114 13.0836372375 5.0552344322 0.0375692658 -0.0143697206 ) ( -4.6954956055 14.4512481689 6.6173882484 0.0375692658 -0.0164225381 ) ( -5.1398601532 15.8188610077 8.1795415878 0.0375692658 -0.0184753556 ) ( -5.471906662 16.8407936096 10.0000009537 0.0375692658 -0.0205281731 ) ( -5.8039522171 17.8627243042 11.8204593658 0.0375692658 -0.0225809887 ) ( -6.0091676712 18.4943141937 13.8196611404 0.0375692658 -0.0246338062 ) ( -6.214384079 19.1259040833 15.8188619614 0.0375692658 -0.0266866237 ) ( -6.2838001251 19.3395442963 17.9094314575 0.0375692658 -0.0287394412 ) ( -6.3532171249 19.553188324 20 0.0375692658 -0.0307922568 ) ( -6.2838001251 19.3395442963 22.0905704498 0.0375692658 -0.0328450762 ) ( -6.214384079 19.1259040833 24.1811389923 0.0375692658 -0.0348978937 ) ( -6.0091676712 18.4943122864 26.1803417206 0.0375692658 -0.0369507112 ) ( -5.8039522171 17.8627243042 28.1795425415 0.0375692658 -0.0390035287 ) ( -5.4719057083 16.8407917023 30.0000019073 0.0375692658 -0.0410563461 ) ( -5.1398601532 15.8188610077 31.8204574585 0.0375692658 -0.0431091599 ) ( -4.6954956055 14.4512481689 33.3826141357 0.0375692658 -0.0451619774 ) ( -4.2511320114 13.0836372375 34.9447669983 0.0375692658 -0.0472147949 ) ( -3.7138695717 11.4301128387 36.1803398132 0.0375692658 -0.0492676124 ) ( -3.1766085625 9.776594162 37.4159126282 0.0375692658 -0.0513204262 ) ( -2.5699295998 7.9094285965 38.2709083557 0.0375692658 -0.0533732474 ) ( -1.9632520676 6.0422677994 39.1259040833 0.0375692658 -0.0554260612 ) ( -1.3136715889 4.0430641174 39.562953949 0.0375692658 -0.0574788824 ) ( -0.6640920639 2.0438652039 40 0.0375692658 -0.0595316961 ) ( 0.0000004768 -0.0000019073 40 0.0375692658 -0.0615845174 ) ) +( ( 0 0 0 0.0417436287 0 ) ( -1.0510425568 1.820458889 -0.0000004728 0.0417436287 -0.002052817 ) ( -2.0791172981 3.6011362076 0.437048018 0.0417436287 -0.0041056345 ) ( -3.1071920395 5.3818130493 0.8740955591 0.0417436287 -0.0061584515 ) ( -4.0673666 7.0448856354 1.729090929 0.0417436287 -0.008211269 ) ( -5.0275421143 8.7079572678 2.5840854645 0.0417436287 -0.0102640856 ) ( -5.8778533936 10.1807384491 3.8196604252 0.0417436287 -0.0123169031 ) ( -6.7281646729 11.6535215378 5.0552344322 0.0417436287 -0.0143697206 ) ( -7.4314489365 12.8716468811 6.6173882484 0.0417436287 -0.0164225381 ) ( -8.1347341537 14.0897712708 8.1795415878 0.0417436287 -0.0184753556 ) ( -8.6602554321 15 10.0000009537 0.0417436287 -0.0205281731 ) ( -9.1857767105 15.9102287292 11.8204593658 0.0417436287 -0.0225809887 ) ( -9.5105657578 16.472782135 13.8196611404 0.0417436287 -0.0246338062 ) ( -9.8353567123 17.0353355408 15.8188619614 0.0417436287 -0.0266866237 ) ( -9.9452199936 17.2256240845 17.9094314575 0.0417436287 -0.0287394412 ) ( -10.0550842285 17.4159145355 20 0.0417436287 -0.0307922568 ) ( -9.9452199936 17.2256240845 22.0905704498 0.0417436287 -0.0328450762 ) ( -9.8353567123 17.0353355408 24.1811389923 0.0417436287 -0.0348978937 ) ( -9.5105657578 16.472782135 26.1803417206 0.0417436287 -0.0369507112 ) ( -9.1857757568 15.9102287292 28.1795425415 0.0417436287 -0.0390035287 ) ( -8.6602544785 15 30.0000019073 0.0417436287 -0.0410563461 ) ( -8.1347341537 14.0897712708 31.8204574585 0.0417436287 -0.0431091599 ) ( -7.4314489365 12.8716449738 33.3826141357 0.0417436287 -0.0451619774 ) ( -6.7281646729 11.6535224915 34.9447669983 0.0417436287 -0.0472147949 ) ( -5.8778524399 10.1807384491 36.1803398132 0.0417436287 -0.0492676124 ) ( -5.0275421143 8.7079582214 37.4159126282 0.0417436287 -0.0513204262 ) ( -4.0673666 7.044883728 38.2709083557 0.0417436287 -0.0533732474 ) ( -3.1071920395 5.381814003 39.1259040833 0.0417436287 -0.0554260612 ) ( -2.0791163445 3.6011347771 39.562953949 0.0417436287 -0.0574788824 ) ( -1.0510430336 1.8204593658 40 0.0417436287 -0.0595316961 ) ( 0.0000009537 -0.0000014305 40 0.0417436287 -0.0615845174 ) ) +( ( 0 0 0 0.0459179915 0 ) ( -1.4379930496 1.5970525742 -0.0000004728 0.0459179915 -0.002052817 ) ( -2.8445620537 3.1592059135 0.437048018 0.0459179915 -0.0041056345 ) ( -4.2511310577 4.7213592529 0.8740955591 0.0459179915 -0.0061584515 ) ( -5.5648031235 6.1803398132 1.729090929 0.0459179915 -0.008211269 ) ( -6.8784751892 7.6393194199 2.5840854645 0.0459179915 -0.0102640856 ) ( -8.0418357849 8.9313621521 3.8196604252 0.0459179915 -0.0123169031 ) ( -9.2051963806 10.223405838 5.0552344322 0.0459179915 -0.0143697206 ) ( -10.1674013138 11.2920417786 6.6173882484 0.0459179915 -0.0164225381 ) ( -11.1296062469 12.3606796265 8.1795415878 0.0459179915 -0.0184753556 ) ( -11.8486032486 13.159204483 10.0000009537 0.0459179915 -0.0205281731 ) ( -12.5676002502 13.9577312469 11.8204593658 0.0459179915 -0.0225809887 ) ( -13.0119628906 14.4512481689 13.8196611404 0.0459179915 -0.0246338062 ) ( -13.4563274384 14.9447631836 15.8188619614 0.0459179915 -0.0266866237 ) ( -13.6066379547 15.1117019653 17.9094314575 0.0459179915 -0.0287394412 ) ( -13.7569503784 15.2786388397 20 0.0459179915 -0.0307922568 ) ( -13.6066379547 15.1117019653 22.0905704498 0.0459179915 -0.0328450762 ) ( -13.4563274384 14.9447631836 24.1811389923 0.0459179915 -0.0348978937 ) ( -13.0119628906 14.4512481689 26.1803417206 0.0459179915 -0.0369507112 ) ( -12.5675983429 13.9577312469 28.1795425415 0.0459179915 -0.0390035287 ) ( -11.8486022949 13.159204483 30.0000019073 0.0459179915 -0.0410563461 ) ( -11.1296072006 12.3606796265 31.8204574585 0.0459179915 -0.0431091599 ) ( -10.1674003601 11.2920408249 33.3826141357 0.0459179915 -0.0451619774 ) ( -9.2051973343 10.223405838 34.9447669983 0.0459179915 -0.0472147949 ) ( -8.0418348312 8.9313611984 36.1803398132 0.0459179915 -0.0492676124 ) ( -6.8784751892 7.6393203735 37.4159126282 0.0459179915 -0.0513204262 ) ( -5.5648021698 6.1803379059 38.2709083557 0.0459179915 -0.0533732474 ) ( -4.2511320114 4.7213592529 39.1259040833 0.0459179915 -0.0554260612 ) ( -2.8445611 3.159204483 39.562953949 0.0459179915 -0.0574788824 ) ( -1.4379935265 1.5970535278 40 0.0459179915 -0.0595316961 ) ( 0.0000011921 -0.0000014305 40 0.0459179915 -0.0615845174 ) ) +( ( 0 0 0 0.0500923544 0 ) ( -1.7006225586 1.2355742455 -0.0000004728 0.0500923544 -0.002052817 ) ( -3.3640818596 2.4441480637 0.437048018 0.0500923544 -0.0041056345 ) ( -5.0275421143 3.6527223587 0.8740955591 0.0500923544 -0.0061584515 ) ( -6.5811376572 4.7814760208 1.729090929 0.0500923544 -0.008211269 ) ( -8.1347332001 5.9102287292 2.5840854645 0.0500923544 -0.0102640856 ) ( -9.5105657578 6.9098300934 3.8196604252 0.0500923544 -0.0123169031 ) ( -10.8863983154 7.9094305038 5.0552344322 0.0500923544 -0.0143697206 ) ( -12.0243358612 8.7361907959 6.6173882484 0.0500923544 -0.0164225381 ) ( -13.1622753143 9.5629520416 8.1795415878 0.0500923544 -0.0184753556 ) ( -14.0125865936 10.1807384491 10.0000009537 0.0500923544 -0.0205281731 ) ( -14.8628978729 10.7985258102 11.8204593658 0.0500923544 -0.0225809887 ) ( -15.3884181976 11.1803388596 13.8196611404 0.0500923544 -0.0246338062 ) ( -15.9139404297 11.5621528625 15.8188619614 0.0500923544 -0.0266866237 ) ( -16.0917034149 11.6913051605 17.9094314575 0.0500923544 -0.0287394412 ) ( -16.2694664001 11.8204574585 20 0.0500923544 -0.0307922568 ) ( -16.0917034149 11.6913051605 22.0905704498 0.0500923544 -0.0328450762 ) ( -15.9139404297 11.5621528625 24.1811389923 0.0500923544 -0.0348978937 ) ( -15.3884181976 11.1803379059 26.1803417206 0.0500923544 -0.0369507112 ) ( -14.8628978729 10.7985248566 28.1795425415 0.0500923544 -0.0390035287 ) ( -14.0125846863 10.1807384491 30.0000019073 0.0500923544 -0.0410563461 ) ( -13.1622753143 9.5629520416 31.8204574585 0.0500923544 -0.0431091599 ) ( -12.0243358612 8.7361898422 33.3826141357 0.0500923544 -0.0451619774 ) ( -10.8863992691 7.9094305038 34.9447669983 0.0500923544 -0.0472147949 ) ( -9.5105648041 6.909828186 36.1803398132 0.0500923544 -0.0492676124 ) ( -8.1347341537 5.9102296829 37.4159126282 0.0500923544 -0.0513204262 ) ( -6.5811367035 4.7814750671 38.2709083557 0.0500923544 -0.0533732474 ) ( -5.0275421143 3.6527228355 39.1259040833 0.0500923544 -0.0554260612 ) ( -3.3640809059 2.44414711 39.562953949 0.0500923544 -0.0574788824 ) ( -1.7006230354 1.2355747223 40 0.0500923544 -0.0595316961 ) ( 0.0000014305 -0.0000009537 40 0.0500923544 -0.0615845174 ) ) +( ( 0 0 0 0.0542667173 0 ) ( -1.9632515907 0.8740959167 -0.0000004728 0.0542667173 -0.002052817 ) ( -3.8836016655 1.7290906906 0.437048018 0.0542667173 -0.0041056345 ) ( -5.8039512634 2.5840854645 0.8740955591 0.0542667173 -0.0061584515 ) ( -7.5974712372 3.3826112747 1.729090929 0.0542667173 -0.008211269 ) ( -9.3909912109 4.1811380386 2.5840854645 0.0542667173 -0.0102640856 ) ( -10.9792947769 4.8882961273 3.8196604252 0.0542667173 -0.0123169031 ) ( -12.5675983429 5.595454216 5.0552344322 0.0542667173 -0.0143697206 ) ( -13.8812713623 6.1803388596 6.6173882484 0.0542667173 -0.0164225381 ) ( -15.1949424744 6.7652225494 8.1795415878 0.0542667173 -0.0184753556 ) ( -16.176568985 7.2022705078 10.0000009537 0.0542667173 -0.0205281731 ) ( -17.1581935883 7.6393184662 11.8204593658 0.0542667173 -0.0225809887 ) ( -17.7648715973 7.9094295502 13.8196611404 0.0542667173 -0.0246338062 ) ( -18.3715515137 8.1795396805 15.8188619614 0.0542667173 -0.0266866237 ) ( -18.5767650604 8.270907402 17.9094314575 0.0542667173 -0.0287394412 ) ( -18.7819824219 8.3622751236 20 0.0542667173 -0.0307922568 ) ( -18.5767650604 8.270907402 22.0905704498 0.0542667173 -0.0328450762 ) ( -18.3715496063 8.1795396805 24.1811389923 0.0542667173 -0.0348978937 ) ( -17.7648715973 7.9094285965 26.1803417206 0.0542667173 -0.0369507112 ) ( -17.1581935883 7.6393184662 28.1795425415 0.0542667173 -0.0390035287 ) ( -16.1765670776 7.2022705078 30.0000019073 0.0542667173 -0.0410563461 ) ( -15.1949424744 6.7652235031 31.8204574585 0.0542667173 -0.0431091599 ) ( -13.881269455 6.1803379059 33.3826141357 0.0542667173 -0.0451619774 ) ( -12.5676002502 5.5954551697 34.9447669983 0.0542667173 -0.0472147949 ) ( -10.9792938232 4.8882951736 36.1803398132 0.0542667173 -0.0492676124 ) ( -9.3909912109 4.1811380386 37.4159126282 0.0542667173 -0.0513204262 ) ( -7.5974693298 3.3826107979 38.2709083557 0.0542667173 -0.0533732474 ) ( -5.8039522171 2.5840854645 39.1259040833 0.0542667173 -0.0554260612 ) ( -3.883600235 1.7290897369 39.562953949 0.0542667173 -0.0574788824 ) ( -1.9632525444 0.8740959167 40 0.0542667173 -0.0595316961 ) ( 0.0000016689 -0.0000009537 40 0.0542667173 -0.0615845174 ) ) +( ( 0 0 0 0.0584410802 0 ) ( -2.0561494827 0.4370479584 -0.0000004728 0.0584410802 -0.002052817 ) ( -4.0673666 0.8645448685 0.437048018 0.0584410802 -0.0041056345 ) ( -6.0785837173 1.2920427322 0.8740955591 0.0584410802 -0.0061584515 ) ( -7.9569702148 1.6913051605 1.729090929 0.0584410802 -0.008211269 ) ( -9.8353557587 2.0905685425 2.5840854645 0.0584410802 -0.0102640856 ) ( -11.4988155365 2.4441475868 3.8196604252 0.0584410802 -0.0123169031 ) ( -13.1622753143 2.7977266312 5.0552344322 0.0584410802 -0.0143697206 ) ( -14.5381069183 3.0901689529 6.6173882484 0.0584410802 -0.0164225381 ) ( -15.9139404297 3.3826107979 8.1795415878 0.0584410802 -0.0184753556 ) ( -16.9420146942 3.6011347771 10.0000009537 0.0584410802 -0.0205281731 ) ( -17.9700889587 3.8196587563 11.8204593658 0.0584410802 -0.0225809887 ) ( -18.605474472 3.9547138214 13.8196611404 0.0584410802 -0.0246338062 ) ( -19.240858078 4.0897693634 15.8188619614 0.0584410802 -0.0266866237 ) ( -19.455783844 4.1354532242 17.9094314575 0.0584410802 -0.0287394412 ) ( -19.6707115173 4.181137085 20 0.0584410802 -0.0307922568 ) ( -19.455783844 4.1354532242 22.0905704498 0.0584410802 -0.0328450762 ) ( -19.240858078 4.0897693634 24.1811389923 0.0584410802 -0.0348978937 ) ( -18.6054725647 3.9547138214 26.1803417206 0.0584410802 -0.0369507112 ) ( -17.9700889587 3.8196587563 28.1795425415 0.0584410802 -0.0390035287 ) ( -16.9420127869 3.6011347771 30.0000019073 0.0584410802 -0.0410563461 ) ( -15.9139404297 3.3826112747 31.8204574585 0.0584410802 -0.0431091599 ) ( -14.5381069183 3.0901684761 33.3826141357 0.0584410802 -0.0451619774 ) ( -13.1622753143 2.7977266312 34.9447669983 0.0584410802 -0.0472147949 ) ( -11.4988136292 2.44414711 36.1803398132 0.0584410802 -0.0492676124 ) ( -9.8353567123 2.0905685425 37.4159126282 0.0584410802 -0.0513204262 ) ( -7.9569683075 1.6913051605 38.2709083557 0.0584410802 -0.0533732474 ) ( -6.078584671 1.2920427322 39.1259040833 0.0584410802 -0.0554260612 ) ( -4.0673646927 0.8645448685 39.562953949 0.0584410802 -0.0574788824 ) ( -2.0561499596 0.4370479584 40 0.0584410802 -0.0595316961 ) ( 0.0000016689 -0.0000004768 40 0.0584410802 -0.0615845174 ) ) +( ( 0 0 0 0.0626154467 0 ) ( -2.1490464211 0 -0.0000004728 0.0626154467 -0.002052817 ) ( -4.2511310577 -0.0000004768 0.437048018 0.0626154467 -0.0041056345 ) ( -6.3532161713 -0.0000004768 0.8740955591 0.0626154467 -0.0061584515 ) ( -8.3164672852 -0.0000009537 1.729090929 0.0626154467 -0.008211269 ) ( -10.2797193527 -0.0000009537 2.5840854645 0.0626154467 -0.0102640856 ) ( -12.0183334351 -0.0000009537 3.8196604252 0.0626154467 -0.0123169031 ) ( -13.7569503784 -0.0000014305 5.0552344322 0.0626154467 -0.0143697206 ) ( -15.1949424744 -0.0000014305 6.6173882484 0.0626154467 -0.0164225381 ) ( -16.6329345703 -0.0000014305 8.1795415878 0.0626154467 -0.0184753556 ) ( -17.7074584961 -0.0000014305 10.0000009537 0.0626154467 -0.0205281731 ) ( -18.7819805145 -0.0000014305 11.8204593658 0.0626154467 -0.0225809887 ) ( -19.4460735321 -0.0000019073 13.8196611404 0.0626154467 -0.0246338062 ) ( -20.1101646423 -0.0000019073 15.8188619614 0.0626154467 -0.0266866237 ) ( -20.3348007202 -0.0000019073 17.9094314575 0.0626154467 -0.0287394412 ) ( -20.5594387054 -0.0000019073 20 0.0626154467 -0.0307922568 ) ( -20.3348007202 -0.0000019073 22.0905704498 0.0626154467 -0.0328450762 ) ( -20.1101646423 -0.0000019073 24.1811389923 0.0626154467 -0.0348978937 ) ( -19.4460716248 -0.0000019073 26.1803417206 0.0626154467 -0.0369507112 ) ( -18.7819805145 -0.0000014305 28.1795425415 0.0626154467 -0.0390035287 ) ( -17.7074565887 -0.0000014305 30.0000019073 0.0626154467 -0.0410563461 ) ( -16.6329345703 -0.0000014305 31.8204574585 0.0626154467 -0.0431091599 ) ( -15.194940567 -0.0000014305 33.3826141357 0.0626154467 -0.0451619774 ) ( -13.7569503784 -0.0000014305 34.9447669983 0.0626154467 -0.0472147949 ) ( -12.0183334351 -0.0000009537 36.1803398132 0.0626154467 -0.0492676124 ) ( -10.2797193527 -0.0000009537 37.4159126282 0.0626154467 -0.0513204262 ) ( -8.3164653778 -0.0000009537 38.2709083557 0.0626154467 -0.0533732474 ) ( -6.3532161713 -0.0000004768 39.1259040833 0.0626154467 -0.0554260612 ) ( -4.2511291504 -0.0000004768 39.562953949 0.0626154467 -0.0574788824 ) ( -2.1490473747 0 40 0.0626154467 -0.0595316961 ) ( 0.0000016689 0 40 0.0626154467 -0.0615845174 ) ) +( ( 0 0 0 0.0667898059 0 ) ( -2.0561490059 -0.4370484352 -0.0000004728 0.0667898059 -0.002052817 ) ( -4.0673666 -0.8645458221 0.437048018 0.0667898059 -0.0041056345 ) ( -6.0785837173 -1.2920436859 0.8740955591 0.0667898059 -0.0061584515 ) ( -7.9569692612 -1.6913070679 1.729090929 0.0667898059 -0.008211269 ) ( -9.8353557587 -2.0905704498 2.5840854645 0.0667898059 -0.0102640856 ) ( -11.4988145828 -2.4441494942 3.8196604252 0.0667898059 -0.0123169031 ) ( -13.1622753143 -2.7977290154 5.0552344322 0.0667898059 -0.0143697206 ) ( -14.5381069183 -3.0901713371 6.6173882484 0.0667898059 -0.0164225381 ) ( -15.9139385223 -3.3826136589 8.1795415878 0.0667898059 -0.0184753556 ) ( -16.9420127869 -3.6011376381 10.0000009537 0.0667898059 -0.0205281731 ) ( -17.9700889587 -3.8196620941 11.8204593658 0.0667898059 -0.0225809887 ) ( -18.6054725647 -3.9547171593 13.8196611404 0.0667898059 -0.0246338062 ) ( -19.240858078 -4.0897722244 15.8188619614 0.0667898059 -0.0266866237 ) ( -19.455783844 -4.1354560852 17.9094314575 0.0667898059 -0.0287394412 ) ( -19.67070961 -4.1811408997 20 0.0667898059 -0.0307922568 ) ( -19.455783844 -4.1354560852 22.0905704498 0.0667898059 -0.0328450762 ) ( -19.240858078 -4.0897722244 24.1811389923 0.0667898059 -0.0348978937 ) ( -18.6054725647 -3.9547171593 26.1803417206 0.0667898059 -0.0369507112 ) ( -17.9700870514 -3.8196616173 28.1795425415 0.0667898059 -0.0390035287 ) ( -16.9420127869 -3.6011376381 30.0000019073 0.0667898059 -0.0410563461 ) ( -15.9139404297 -3.3826136589 31.8204574585 0.0667898059 -0.0431091599 ) ( -14.538105011 -3.0901713371 33.3826141357 0.0667898059 -0.0451619774 ) ( -13.1622753143 -2.7977290154 34.9447669983 0.0667898059 -0.0472147949 ) ( -11.4988136292 -2.4441494942 36.1803398132 0.0667898059 -0.0492676124 ) ( -9.8353557587 -2.0905704498 37.4159126282 0.0667898059 -0.0513204262 ) ( -7.9569683075 -1.691306591 38.2709083557 0.0667898059 -0.0533732474 ) ( -6.078584671 -1.2920436859 39.1259040833 0.0667898059 -0.0554260612 ) ( -4.0673646927 -0.8645453453 39.562953949 0.0667898059 -0.0574788824 ) ( -2.0561499596 -0.4370484352 40 0.0667898059 -0.0595316961 ) ( 0.0000016689 0.0000004768 40 0.0667898059 -0.0615845174 ) ) +( ( 0 0 0 0.0709641725 0 ) ( -1.9632515907 -0.8740963936 -0.0000004728 0.0709641725 -0.002052817 ) ( -3.8836011887 -1.7290911674 0.437048018 0.0709641725 -0.0041056345 ) ( -5.8039512634 -2.5840864182 0.8740955591 0.0709641725 -0.0061584515 ) ( -7.5974702835 -3.3826127052 1.729090929 0.0709641725 -0.008211269 ) ( -9.3909902573 -4.1811389923 2.5840854645 0.0709641725 -0.0102640856 ) ( -10.9792938232 -4.8882980347 3.8196604252 0.0709641725 -0.0123169031 ) ( -12.5675983429 -5.595457077 5.0552344322 0.0709641725 -0.0143697206 ) ( -13.881269455 -6.1803407669 6.6173882484 0.0709641725 -0.0164225381 ) ( -15.1949424744 -6.7652254105 8.1795415878 0.0709641725 -0.0184753556 ) ( -16.1765670776 -7.2022733688 10.0000009537 0.0709641725 -0.0205281731 ) ( -17.1581935883 -7.6393213272 11.8204593658 0.0709641725 -0.0225809887 ) ( -17.7648715973 -7.9094324112 13.8196611404 0.0709641725 -0.0246338062 ) ( -18.3715496063 -8.1795425415 15.8188619614 0.0709641725 -0.0266866237 ) ( -18.5767650604 -8.2709102631 17.9094314575 0.0709641725 -0.0287394412 ) ( -18.7819805145 -8.3622789383 20 0.0709641725 -0.0307922568 ) ( -18.5767650604 -8.2709102631 22.0905704498 0.0709641725 -0.0328450762 ) ( -18.3715496063 -8.1795425415 24.1811389923 0.0709641725 -0.0348978937 ) ( -17.7648696899 -7.9094314575 26.1803417206 0.0709641725 -0.0369507112 ) ( -17.1581916809 -7.6393213272 28.1795425415 0.0709641725 -0.0390035287 ) ( -16.1765651703 -7.2022733688 30.0000019073 0.0709641725 -0.0410563461 ) ( -15.1949424744 -6.7652254105 31.8204574585 0.0709641725 -0.0431091599 ) ( -13.8812675476 -6.1803407669 33.3826141357 0.0709641725 -0.0451619774 ) ( -12.5675983429 -5.595457077 34.9447669983 0.0709641725 -0.0472147949 ) ( -10.9792928696 -4.888297081 36.1803398132 0.0709641725 -0.0492676124 ) ( -9.3909912109 -4.181139946 37.4159126282 0.0709641725 -0.0513204262 ) ( -7.5974693298 -3.3826122284 38.2709083557 0.0709641725 -0.0533732474 ) ( -5.8039522171 -2.5840864182 39.1259040833 0.0709641725 -0.0554260612 ) ( -3.8835997581 -1.7290906906 39.562953949 0.0709641725 -0.0574788824 ) ( -1.9632520676 -0.8740963936 40 0.0709641725 -0.0595316961 ) ( 0.0000016689 0.0000009537 40 0.0709641725 -0.0615845174 ) ) +( ( 0 0 0 0.0751385316 0 ) ( -1.7006220818 -1.2355747223 -0.0000004728 0.0751385316 -0.002052817 ) ( -3.3640818596 -2.4441490173 0.437048018 0.0751385316 -0.0041056345 ) ( -5.0275411606 -3.6527233124 0.8740955591 0.0751385316 -0.0061584515 ) ( -6.5811367035 -4.7814769745 1.729090929 0.0751385316 -0.008211269 ) ( -8.1347322464 -5.9102306366 2.5840854645 0.0751385316 -0.0102640856 ) ( -9.5105648041 -6.9098310471 3.8196604252 0.0751385316 -0.0123169031 ) ( -10.8863973618 -7.9094324112 5.0552344322 0.0751385316 -0.0143697206 ) ( -12.0243358612 -8.7361927032 6.6173882484 0.0751385316 -0.0164225381 ) ( -13.162273407 -9.562953949 8.1795415878 0.0751385316 -0.0184753556 ) ( -14.0125846863 -10.1807413101 10.0000009537 0.0751385316 -0.0205281731 ) ( -14.8628959656 -10.7985286713 11.8204593658 0.0751385316 -0.0225809887 ) ( -15.3884162903 -11.1803417206 13.8196611404 0.0751385316 -0.0246338062 ) ( -15.9139385223 -11.5621557236 15.8188619614 0.0751385316 -0.0266866237 ) ( -16.0917015076 -11.6913080215 17.9094314575 0.0751385316 -0.0287394412 ) ( -16.2694644928 -11.8204603195 20 0.0751385316 -0.0307922568 ) ( -16.0917015076 -11.6913080215 22.0905704498 0.0751385316 -0.0328450762 ) ( -15.9139385223 -11.5621547699 24.1811389923 0.0751385316 -0.0348978937 ) ( -15.3884162903 -11.1803417206 26.1803417206 0.0751385316 -0.0369507112 ) ( -14.8628959656 -10.7985277176 28.1795425415 0.0751385316 -0.0390035287 ) ( -14.0125846863 -10.1807403564 30.0000019073 0.0751385316 -0.0410563461 ) ( -13.162273407 -9.562953949 31.8204574585 0.0751385316 -0.0431091599 ) ( -12.0243339539 -8.7361917496 33.3826141357 0.0751385316 -0.0451619774 ) ( -10.8863973618 -7.9094324112 34.9447669983 0.0751385316 -0.0472147949 ) ( -9.5105638504 -6.9098300934 36.1803398132 0.0751385316 -0.0492676124 ) ( -8.1347332001 -5.9102306366 37.4159126282 0.0751385316 -0.0513204262 ) ( -6.5811357498 -4.7814760208 38.2709083557 0.0751385316 -0.0533732474 ) ( -5.0275421143 -3.6527237892 39.1259040833 0.0751385316 -0.0554260612 ) ( -3.3640804291 -2.4441480637 39.562953949 0.0751385316 -0.0574788824 ) ( -1.7006225586 -1.2355751991 40 0.0751385316 -0.0595316961 ) ( 0.0000014305 0.0000009537 40 0.0751385316 -0.0615845174 ) ) +( ( 0 0 0 0.0793128982 0 ) ( -1.4379925728 -1.597053051 -0.0000004728 0.0793128982 -0.002052817 ) ( -2.8445615768 -3.1592063904 0.437048018 0.0793128982 -0.0041056345 ) ( -4.2511310577 -4.7213602066 0.8740955591 0.0793128982 -0.0061584515 ) ( -5.5648021698 -6.1803407669 1.729090929 0.0793128982 -0.008211269 ) ( -6.8784742355 -7.6393213272 2.5840854645 0.0793128982 -0.0102640856 ) ( -8.0418338776 -8.9313640594 3.8196604252 0.0793128982 -0.0123169031 ) ( -9.2051944733 -10.2234067917 5.0552344322 0.0793128982 -0.0143697206 ) ( -10.1673994064 -11.2920436859 6.6173882484 0.0793128982 -0.0164225381 ) ( -11.1296043396 -12.3606815338 8.1795415878 0.0793128982 -0.0184753556 ) ( -11.8486003876 -13.1592063904 10.0000009537 0.0793128982 -0.0205281731 ) ( -12.5675964355 -13.9577331543 11.8204593658 0.0793128982 -0.0225809887 ) ( -13.0119609833 -14.4512500763 13.8196611404 0.0793128982 -0.0246338062 ) ( -13.456325531 -14.9447669983 15.8188619614 0.0793128982 -0.0266866237 ) ( -13.6066360474 -15.1117038727 17.9094314575 0.0793128982 -0.0287394412 ) ( -13.7569465637 -15.2786407471 20 0.0793128982 -0.0307922568 ) ( -13.6066360474 -15.1117038727 22.0905704498 0.0793128982 -0.0328450762 ) ( -13.456325531 -14.9447669983 24.1811389923 0.0793128982 -0.0348978937 ) ( -13.0119609833 -14.4512500763 26.1803417206 0.0793128982 -0.0369507112 ) ( -12.5675964355 -13.9577331543 28.1795425415 0.0793128982 -0.0390035287 ) ( -11.8486003876 -13.1592063904 30.0000019073 0.0793128982 -0.0410563461 ) ( -11.1296043396 -12.3606815338 31.8204574585 0.0793128982 -0.0431091599 ) ( -10.1673984528 -11.2920427322 33.3826141357 0.0793128982 -0.0451619774 ) ( -9.2051954269 -10.2234067917 34.9447669983 0.0793128982 -0.0472147949 ) ( -8.0418329239 -8.9313621521 36.1803398132 0.0793128982 -0.0492676124 ) ( -6.8784742355 -7.6393213272 37.4159126282 0.0793128982 -0.0513204262 ) ( -5.5648012161 -6.1803388596 38.2709083557 0.0793128982 -0.0533732474 ) ( -4.2511310577 -4.7213602066 39.1259040833 0.0793128982 -0.0554260612 ) ( -2.8445606232 -3.1592049599 39.562953949 0.0793128982 -0.0574788824 ) ( -1.4379930496 -1.5970535278 40 0.0793128982 -0.0595316961 ) ( 0.0000011921 0.0000014305 40 0.0793128982 -0.0615845174 ) ) +( ( 0 0 0 0.0834872574 0 ) ( -1.0510420799 -1.820458889 -0.0000004728 0.0834872574 -0.002052817 ) ( -2.0791163445 -3.6011366844 0.437048018 0.0834872574 -0.0041056345 ) ( -3.1071910858 -5.381814003 0.8740955591 0.0834872574 -0.0061584515 ) ( -4.0673656464 -7.0448856354 1.729090929 0.0834872574 -0.008211269 ) ( -5.0275402069 -8.7079582214 2.5840854645 0.0834872574 -0.0102640856 ) ( -5.8778514862 -10.1807403564 3.8196604252 0.0834872574 -0.0123169031 ) ( -6.7281627655 -11.6535224915 5.0552344322 0.0834872574 -0.0143697206 ) ( -7.4314470291 -12.8716468811 6.6173882484 0.0834872574 -0.0164225381 ) ( -8.1347312927 -14.0897712708 8.1795415878 0.0834872574 -0.0184753556 ) ( -8.6602525711 -15.0000019073 10.0000009537 0.0834872574 -0.0205281731 ) ( -9.1857738495 -15.9102306366 11.8204593658 0.0834872574 -0.0225809887 ) ( -9.5105628967 -16.4727840424 13.8196611404 0.0834872574 -0.0246338062 ) ( -9.8353538513 -17.0353355408 15.8188619614 0.0834872574 -0.0266866237 ) ( -9.9452171326 -17.2256259918 17.9094314575 0.0834872574 -0.0287394412 ) ( -10.0550813675 -17.4159164429 20 0.0834872574 -0.0307922568 ) ( -9.9452171326 -17.2256259918 22.0905704498 0.0834872574 -0.0328450762 ) ( -9.8353528976 -17.0353355408 24.1811389923 0.0834872574 -0.0348978937 ) ( -9.5105628967 -16.472782135 26.1803417206 0.0834872574 -0.0369507112 ) ( -9.1857728958 -15.9102306366 28.1795425415 0.0834872574 -0.0390035287 ) ( -8.6602516174 -15 30.0000019073 0.0834872574 -0.0410563461 ) ( -8.1347312927 -14.0897731781 31.8204574585 0.0834872574 -0.0431091599 ) ( -7.4314460754 -12.8716468811 33.3826141357 0.0834872574 -0.0451619774 ) ( -6.7281627655 -11.6535234451 34.9447669983 0.0834872574 -0.0472147949 ) ( -5.8778505325 -10.1807384491 36.1803398132 0.0834872574 -0.0492676124 ) ( -5.0275411606 -8.7079582214 37.4159126282 0.0834872574 -0.0513204262 ) ( -4.0673646927 -7.0448846817 38.2709083557 0.0834872574 -0.0533732474 ) ( -3.1071910858 -5.3818149567 39.1259040833 0.0834872574 -0.0554260612 ) ( -2.0791158676 -3.6011347771 39.562953949 0.0834872574 -0.0574788824 ) ( -1.0510425568 -1.8204593658 40 0.0834872574 -0.0595316961 ) ( 0.0000009537 0.0000014305 40 0.0834872574 -0.0615845174 ) ) +( ( 0 0 0 0.0876616165 0 ) ( -0.6640920639 -2.043864727 -0.0000004728 0.0876616165 -0.002052817 ) ( -1.3136720657 -4.0430660248 0.437048018 0.0876616165 -0.0041056345 ) ( -1.9632525444 -6.0422668457 0.8740955591 0.0876616165 -0.0061584515 ) ( -2.5699305534 -7.9094305038 1.729090929 0.0876616165 -0.008211269 ) ( -3.1766090393 -9.7765932083 2.5840854645 0.0876616165 -0.0102640856 ) ( -3.7138710022 -11.4301147461 3.8196604252 0.0876616165 -0.0123169031 ) ( -4.2511329651 -13.0836353302 5.0552344322 0.0876616165 -0.0143697206 ) ( -4.6954965591 -14.4512481689 6.6173882484 0.0876616165 -0.0164225381 ) ( -5.1398611069 -15.8188610077 8.1795415878 0.0876616165 -0.0184753556 ) ( -5.4719076157 -16.8407917023 10.0000009537 0.0876616165 -0.0205281731 ) ( -5.8039531708 -17.8627243042 11.8204593658 0.0876616165 -0.0225809887 ) ( -6.0091695786 -18.4943141937 13.8196611404 0.0876616165 -0.0246338062 ) ( -6.2143850327 -19.1259021759 15.8188619614 0.0876616165 -0.0266866237 ) ( -6.2838010788 -19.3395442963 17.9094314575 0.0876616165 -0.0287394412 ) ( -6.3532180786 -19.5531864166 20 0.0876616165 -0.0307922568 ) ( -6.2838010788 -19.3395442963 22.0905704498 0.0876616165 -0.0328450762 ) ( -6.2143850327 -19.1259021759 24.1811389923 0.0876616165 -0.0348978937 ) ( -6.0091686249 -18.4943122864 26.1803417206 0.0876616165 -0.0369507112 ) ( -5.8039531708 -17.8627243042 28.1795425415 0.0876616165 -0.0390035287 ) ( -5.471906662 -16.8407917023 30.0000019073 0.0876616165 -0.0410563461 ) ( -5.1398611069 -15.8188610077 31.8204574585 0.0876616165 -0.0431091599 ) ( -4.6954965591 -14.4512462616 33.3826141357 0.0876616165 -0.0451619774 ) ( -4.2511329651 -13.0836372375 34.9447669983 0.0876616165 -0.0472147949 ) ( -3.7138705254 -11.4301128387 36.1803398132 0.0876616165 -0.0492676124 ) ( -3.1766090393 -9.776594162 37.4159126282 0.0876616165 -0.0513204262 ) ( -2.5699300766 -7.9094285965 38.2709083557 0.0876616165 -0.0533732474 ) ( -1.9632525444 -6.0422677994 39.1259040833 0.0876616165 -0.0554260612 ) ( -1.3136715889 -4.0430641174 39.562953949 0.0876616165 -0.0574788824 ) ( -0.6640925407 -2.0438652039 40 0.0876616165 -0.0595316961 ) ( 0.0000004768 0.0000019073 40 0.0876616165 -0.0615845174 ) ) +( ( 0 0 0 0.0918359831 0 ) ( -0.2197275162 -2.0905694962 -0.0000004728 0.0918359831 -0.002052817 ) ( -0.4346532822 -4.1354551315 0.437048018 0.0918359831 -0.0041056345 ) ( -0.6495790482 -6.1803398132 0.8740955591 0.0918359831 -0.0061584515 ) ( -0.8503103256 -8.0901699066 1.729090929 0.0918359831 -0.008211269 ) ( -1.0510411263 -10.0000009537 2.5840854645 0.0918359831 -0.0102640856 ) ( -1.2288041115 -11.6913061142 3.8196604252 0.0918359831 -0.0123169031 ) ( -1.4065675735 -13.3826122284 5.0552344322 0.0918359831 -0.0143697206 ) ( -1.5535936356 -14.7814769745 6.6173882484 0.0918359831 -0.0164225381 ) ( -1.7006201744 -16.1803417206 8.1795415878 0.0918359831 -0.0184753556 ) ( -1.8104839325 -17.2256259918 10.0000009537 0.0918359831 -0.0205281731 ) ( -1.9203476906 -18.2709102631 11.8204593658 0.0918359831 -0.0225809887 ) ( -1.9882469177 -18.9169311523 13.8196611404 0.0918359831 -0.0246338062 ) ( -2.0561466217 -19.5629520416 15.8188619614 0.0918359831 -0.0266866237 ) ( -2.0791144371 -19.7814769745 17.9094314575 0.0918359831 -0.0287394412 ) ( -2.1020822525 -20 20 0.0918359831 -0.0307922568 ) ( -2.0791144371 -19.7814769745 22.0905704498 0.0918359831 -0.0328450762 ) ( -2.0561466217 -19.5629520416 24.1811389923 0.0918359831 -0.0348978937 ) ( -1.9882469177 -18.9169311523 26.1803417206 0.0918359831 -0.0369507112 ) ( -1.9203476906 -18.2709102631 28.1795425415 0.0918359831 -0.0390035287 ) ( -1.8104839325 -17.2256240845 30.0000019073 0.0918359831 -0.0410563461 ) ( -1.7006201744 -16.1803417206 31.8204574585 0.0918359831 -0.0431091599 ) ( -1.5535936356 -14.7814750671 33.3826141357 0.0918359831 -0.0451619774 ) ( -1.4065675735 -13.3826141357 34.9447669983 0.0918359831 -0.0472147949 ) ( -1.2288041115 -11.6913051605 36.1803398132 0.0918359831 -0.0492676124 ) ( -1.0510411263 -10.0000009537 37.4159126282 0.0918359831 -0.0513204262 ) ( -0.8503098488 -8.0901689529 38.2709083557 0.0918359831 -0.0533732474 ) ( -0.6495790482 -6.1803407669 39.1259040833 0.0918359831 -0.0554260612 ) ( -0.4346532822 -4.1354532242 39.562953949 0.0918359831 -0.0574788824 ) ( -0.2197275162 -2.090569973 40 0.0918359831 -0.0595316961 ) ( 0.0000002384 0.0000019073 40 0.0918359831 -0.0615845174 ) ) +( ( 0 0 0 0.0960103422 0 ) ( 0.2246363163 -2.1372737885 -0.0000004728 0.0960103422 -0.002052817 ) ( 0.4443638325 -4.2278432846 0.437048018 0.0960103422 -0.0041056345 ) ( 0.6640913486 -6.3184127808 0.8740955591 0.0960103422 -0.0061584515 ) ( 0.8693068027 -8.2709093094 1.729090929 0.0960103422 -0.008211269 ) ( 1.0745222569 -10.223405838 2.5840854645 0.0960103422 -0.0102640856 ) ( 1.2562568188 -11.9524965286 3.8196604252 0.0960103422 -0.0123169031 ) ( 1.4379913807 -13.6815872192 5.0552344322 0.0960103422 -0.0143697206 ) ( 1.5883023739 -15.1117019653 6.6173882484 0.0960103422 -0.0164225381 ) ( 1.7386133671 -16.5418186188 8.1795415878 0.0960103422 -0.0184753556 ) ( 1.850931406 -17.6104545593 10.0000009537 0.0960103422 -0.0205281731 ) ( 1.9632496834 -18.6790924072 11.8204593658 0.0960103422 -0.0225809887 ) ( 2.0326662064 -19.3395462036 13.8196611404 0.0960103422 -0.0246338062 ) ( 2.1020827293 -20 15.8188619614 0.0960103422 -0.0266866237 ) ( 2.1255633831 -20.223405838 17.9094314575 0.0960103422 -0.0287394412 ) ( 2.1490442753 -20.446811676 20 0.0960103422 -0.0307922568 ) ( 2.1255633831 -20.223405838 22.0905704498 0.0960103422 -0.0328450762 ) ( 2.1020824909 -20 24.1811389923 0.0960103422 -0.0348978937 ) ( 2.0326662064 -19.3395442963 26.1803417206 0.0960103422 -0.0369507112 ) ( 1.9632496834 -18.6790904999 28.1795425415 0.0960103422 -0.0390035287 ) ( 1.850931406 -17.6104545593 30.0000019073 0.0960103422 -0.0410563461 ) ( 1.7386133671 -16.5418186188 31.8204574585 0.0960103422 -0.0431091599 ) ( 1.5883021355 -15.1117019653 33.3826141357 0.0960103422 -0.0451619774 ) ( 1.4379913807 -13.6815872192 34.9447669983 0.0960103422 -0.0472147949 ) ( 1.2562565804 -11.9524946213 36.1803398132 0.0960103422 -0.0492676124 ) ( 1.0745222569 -10.2234067917 37.4159126282 0.0960103422 -0.0513204262 ) ( 0.8693065643 -8.270907402 38.2709083557 0.0960103422 -0.0533732474 ) ( 0.6640913486 -6.3184127808 39.1259040833 0.0960103422 -0.0554260612 ) ( 0.4443635941 -4.2278413773 39.562953949 0.0960103422 -0.0574788824 ) ( 0.2246363163 -2.1372742653 40 0.0960103422 -0.0595316961 ) ( 0 0.0000019073 40 0.0960103422 -0.0615845174 ) ) +( ( 0 0 0 0.1001847088 0 ) ( 0.6495802402 -1.9992012978 -0.0000004728 0.1001847088 -0.002052817 ) ( 1.2849655151 -3.9547152519 0.437048018 0.1001847088 -0.0041056345 ) ( 1.92035079 -5.9102296829 0.8740955591 0.1001847088 -0.0061584515 ) ( 2.5137720108 -7.7365903854 1.729090929 0.1001847088 -0.008211269 ) ( 3.1071929932 -9.5629520416 2.5840854645 0.1001847088 -0.0102640856 ) ( 3.6327142715 -11.1803398132 3.8196604252 0.1001847088 -0.0123169031 ) ( 4.1582360268 -12.7977275848 5.0552344322 0.1001847088 -0.0143697206 ) ( 4.5928897858 -14.1354541779 6.6173882484 0.1001847088 -0.0164225381 ) ( 5.0275440216 -15.4731807709 8.1795415878 0.1001847088 -0.0184753556 ) ( 5.3523340225 -16.472782135 10.0000009537 0.1001847088 -0.0205281731 ) ( 5.6771240234 -17.4723834991 11.8204593658 0.1001847088 -0.0225809887 ) ( 5.8778553009 -18.0901699066 13.8196611404 0.1001847088 -0.0246338062 ) ( 6.0785865784 -18.7079563141 15.8188619614 0.1001847088 -0.0266866237 ) ( 6.1464862823 -18.916929245 17.9094314575 0.1001847088 -0.0287394412 ) ( 6.2143859863 -19.1259040833 20 0.1001847088 -0.0307922568 ) ( 6.1464862823 -18.916929245 22.0905704498 0.1001847088 -0.0328450762 ) ( 6.0785865784 -18.7079563141 24.1811389923 0.1001847088 -0.0348978937 ) ( 5.8778548241 -18.0901679993 26.1803417206 0.1001847088 -0.0369507112 ) ( 5.6771240234 -17.4723815918 28.1795425415 0.1001847088 -0.0390035287 ) ( 5.3523335457 -16.4727802277 30.0000019073 0.1001847088 -0.0410563461 ) ( 5.0275440216 -15.4731807709 31.8204574585 0.1001847088 -0.0431091599 ) ( 4.5928893089 -14.1354522705 33.3826141357 0.1001847088 -0.0451619774 ) ( 4.1582360268 -12.7977275848 34.9447669983 0.1001847088 -0.0472147949 ) ( 3.6327137947 -11.1803379059 36.1803398132 0.1001847088 -0.0492676124 ) ( 3.1071929932 -9.5629529953 37.4159126282 0.1001847088 -0.0513204262 ) ( 2.5137712955 -7.7365894318 38.2709083557 0.1001847088 -0.0533732474 ) ( 1.9203510284 -5.9102296829 39.1259040833 0.1001847088 -0.0554260612 ) ( 1.2849650383 -3.9547138214 39.562953949 0.1001847088 -0.0574788824 ) ( 0.6495804787 -1.9992017746 40 0.1001847088 -0.0595316961 ) ( -0.0000004768 0.0000019073 40 0.1001847088 -0.0615845174 ) ) +( ( 0 0 0 0.104359068 0 ) ( 1.0745229721 -1.8611288071 -0.0000004728 0.104359068 -0.002052817 ) ( 2.125565052 -3.6815876961 0.437048018 0.104359068 -0.0041056345 ) ( 3.1766073704 -5.5020465851 0.8740955591 0.104359068 -0.0061584515 ) ( 4.1582331657 -7.2022724152 1.729090929 0.104359068 -0.008211269 ) ( 5.1398587227 -8.9024982452 2.5840854645 0.104359068 -0.0102640856 ) ( 6.0091657639 -10.4081830978 3.8196604252 0.104359068 -0.0123169031 ) ( 6.8784737587 -11.9138679504 5.0552344322 0.104359068 -0.0143697206 ) ( 7.5974698067 -13.1592063904 6.6173882484 0.104359068 -0.0164225381 ) ( 8.3164663315 -14.4045448303 8.1795415878 0.104359068 -0.0184753556 ) ( 8.8537273407 -15.3351097107 10.0000009537 0.104359068 -0.0205281731 ) ( 9.3909893036 -16.2656745911 11.8204593658 0.104359068 -0.0225809887 ) ( 9.7230348587 -16.8407936096 13.8196611404 0.104359068 -0.0246338062 ) ( 10.0550804138 -17.4159145355 15.8188619614 0.104359068 -0.0266866237 ) ( 10.1673984528 -17.6104545593 17.9094314575 0.104359068 -0.0287394412 ) ( 10.2797174454 -17.8049964905 20 0.104359068 -0.0307922568 ) ( 10.1673984528 -17.6104545593 22.0905704498 0.104359068 -0.0328450762 ) ( 10.0550804138 -17.4159145355 24.1811389923 0.104359068 -0.0348978937 ) ( 9.723033905 -16.8407936096 26.1803417206 0.104359068 -0.0369507112 ) ( 9.3909893036 -16.2656726837 28.1795425415 0.104359068 -0.0390035287 ) ( 8.8537273407 -15.3351078033 30.0000019073 0.104359068 -0.0410563461 ) ( 8.3164663315 -14.4045448303 31.8204574585 0.104359068 -0.0431091599 ) ( 7.5974693298 -13.159204483 33.3826141357 0.104359068 -0.0451619774 ) ( 6.8784742355 -11.9138689041 34.9447669983 0.104359068 -0.0472147949 ) ( 6.009165287 -10.4081821442 36.1803398132 0.104359068 -0.0492676124 ) ( 5.1398591995 -8.9024991989 37.4159126282 0.104359068 -0.0513204262 ) ( 4.1582322121 -7.2022714615 38.2709083557 0.104359068 -0.0533732474 ) ( 3.1766076088 -5.5020475388 39.1259040833 0.104359068 -0.0554260612 ) ( 2.1255643368 -3.6815862656 39.562953949 0.104359068 -0.0574788824 ) ( 1.0745234489 -1.8611297607 40 0.104359068 -0.0595316961 ) ( -0.0000009537 0.0000014305 40 0.104359068 -0.0615845174 ) ) +( ( 0 0 0 0.1085334346 0 ) ( 1.4065694809 -1.5621533394 -0.0000004728 0.1085334346 -0.002052817 ) ( 2.7824020386 -3.0901694298 0.437048018 0.1085334346 -0.0041056345 ) ( 4.1582345963 -4.618185997 0.8740955591 0.1085334346 -0.0061584515 ) ( 5.4431996346 -6.0452842712 1.729090929 0.1085334346 -0.008211269 ) ( 6.7281651497 -7.4723825455 2.5840854645 0.1085334346 -0.0102640856 ) ( 7.8661036491 -8.7361907959 3.8196604252 0.1085334346 -0.0123169031 ) ( 9.0040416718 -9.9999990463 5.0552344322 0.1085334346 -0.0143697206 ) ( 9.9452209473 -11.0452833176 6.6173882484 0.1085334346 -0.0164225381 ) ( 10.8864002228 -12.0905685425 8.1795415878 0.1085334346 -0.0184753556 ) ( 11.5896835327 -12.8716449738 10.0000009537 0.1085334346 -0.0205281731 ) ( 12.29296875 -13.652721405 11.8204593658 0.1085334346 -0.0225809887 ) ( 12.7276229858 -14.1354522705 13.8196611404 0.1085334346 -0.0246338062 ) ( 13.1622772217 -14.6181850433 15.8188619614 0.1085334346 -0.0266866237 ) ( 13.3093032837 -14.7814731598 17.9094314575 0.1085334346 -0.0287394412 ) ( 13.4563302994 -14.9447631836 20 0.1085334346 -0.0307922568 ) ( 13.3093032837 -14.7814731598 22.0905704498 0.1085334346 -0.0328450762 ) ( 13.162276268 -14.6181850433 24.1811389923 0.1085334346 -0.0348978937 ) ( 12.7276220322 -14.1354522705 26.1803417206 0.1085334346 -0.0369507112 ) ( 12.29296875 -13.652721405 28.1795425415 0.1085334346 -0.0390035287 ) ( 11.5896835327 -12.8716430664 30.0000019073 0.1085334346 -0.0410563461 ) ( 10.8864002228 -12.0905685425 31.8204574585 0.1085334346 -0.0431091599 ) ( 9.9452199936 -11.0452823639 33.3826141357 0.1085334346 -0.0451619774 ) ( 9.0040426254 -9.9999990463 34.9447669983 0.1085334346 -0.0472147949 ) ( 7.8661026955 -8.7361888885 36.1803398132 0.1085334346 -0.0492676124 ) ( 6.7281656265 -7.4723825455 37.4159126282 0.1085334346 -0.0513204262 ) ( 5.4431986809 -6.0452823639 38.2709083557 0.1085334346 -0.0533732474 ) ( 4.1582350731 -4.6181869507 39.1259040833 0.1085334346 -0.0554260612 ) ( 2.7824010849 -3.0901684761 39.562953949 0.1085334346 -0.0574788824 ) ( 1.4065699577 -1.5621538162 40 0.1085334346 -0.0595316961 ) ( -0.0000009537 0.0000009537 40 0.1085334346 -0.0615845174 ) ) +( ( 0 0 0 0.1127077937 0 ) ( 1.738615036 -1.2631778717 -0.0000004728 0.1127077937 -0.002052817 ) ( 3.4392371178 -2.498752594 0.437048018 0.1127077937 -0.0041056345 ) ( 5.1398591995 -3.7343268394 0.8740955591 0.1127077937 -0.0061584515 ) ( 6.7281627655 -4.888297081 1.729090929 0.1127077937 -0.008211269 ) ( 8.3164672852 -6.0422677994 2.5840854645 0.1127077937 -0.0102640856 ) ( 9.7230358124 -7.0642004013 3.8196604252 0.1127077937 -0.0123169031 ) ( 11.1296052933 -8.0861330032 5.0552344322 0.1127077937 -0.0143697206 ) ( 12.292965889 -8.9313640594 6.6173882484 0.1127077937 -0.0164225381 ) ( 13.4563264847 -9.7765951157 8.1795415878 0.1127077937 -0.0184753556 ) ( 14.325633049 -10.4081840515 10.0000009537 0.1127077937 -0.0205281731 ) ( 15.1949415207 -11.0397729874 11.8204593658 0.1127077937 -0.0225809887 ) ( 15.7322025299 -11.4301156998 13.8196611404 0.1127077937 -0.0246338062 ) ( 16.2694644928 -11.8204593658 15.8188619614 0.1127077937 -0.0266866237 ) ( 16.4511985779 -11.9524974823 17.9094314575 0.1127077937 -0.0287394412 ) ( 16.6329345703 -12.0845355988 20 0.1127077937 -0.0307922568 ) ( 16.4511985779 -11.9524974823 22.0905704498 0.1127077937 -0.0328450762 ) ( 16.2694644928 -11.8204593658 24.1811389923 0.1127077937 -0.0348978937 ) ( 15.7322015762 -11.4301156998 26.1803417206 0.1127077937 -0.0369507112 ) ( 15.194940567 -11.0397720337 28.1795425415 0.1127077937 -0.0390035287 ) ( 14.325633049 -10.4081830978 30.0000019073 0.1127077937 -0.0410563461 ) ( 13.4563264847 -9.7765951157 31.8204574585 0.1127077937 -0.0431091599 ) ( 12.2929649353 -8.9313631058 33.3826141357 0.1127077937 -0.0451619774 ) ( 11.1296062469 -8.0861330032 34.9447669983 0.1127077937 -0.0472147949 ) ( 9.7230348587 -7.0641994476 36.1803398132 0.1127077937 -0.0492676124 ) ( 8.3164672852 -6.0422687531 37.4159126282 0.1127077937 -0.0513204262 ) ( 6.7281618118 -4.8882961273 38.2709083557 0.1127077937 -0.0533732474 ) ( 5.1398596764 -3.7343273163 39.1259040833 0.1127077937 -0.0554260612 ) ( 3.4392356873 -2.4987516403 39.562953949 0.1127077937 -0.0574788824 ) ( 1.7386155128 -1.2631783485 40 0.1127077937 -0.0595316961 ) ( -0.0000014305 0.0000009537 40 0.1127077937 -0.0615845174 ) ) +( ( 0 0 0 0.1168821603 0 ) ( 1.9203500748 -0.8549947739 -0.0000004728 0.1168821603 -0.002052817 ) ( 3.7987360954 -1.6913056374 0.437048018 0.1168821603 -0.0041056345 ) ( 5.6771221161 -2.5276165009 0.8740955591 0.1168821603 -0.0061584515 ) ( 7.4314489365 -3.3086929321 1.729090929 0.1168821603 -0.008211269 ) ( 9.1857757568 -4.0897693634 2.5840854645 0.1168821603 -0.0102640856 ) ( 10.7393722534 -4.7814741135 3.8196604252 0.1168821603 -0.0123169031 ) ( 12.2929677963 -5.4731798172 5.0552344322 0.1168821603 -0.0143697206 ) ( 13.5779333115 -6.0452823639 6.6173882484 0.1168821603 -0.0164225381 ) ( 14.8628978729 -6.6173858643 8.1795415878 0.1168821603 -0.0184753556 ) ( 15.8230724335 -7.0448827744 10.0000009537 0.1168821603 -0.0205281731 ) ( 16.7832489014 -7.4723806381 11.8204593658 0.1168821603 -0.0225809887 ) ( 17.3766689301 -7.7365875244 13.8196611404 0.1168821603 -0.0246338062 ) ( 17.9700889587 -8.0007963181 15.8188619614 0.1168821603 -0.0266866237 ) ( 18.1708202362 -8.0901670456 17.9094314575 0.1168821603 -0.0287394412 ) ( 18.3715515137 -8.1795387268 20 0.1168821603 -0.0307922568 ) ( 18.1708202362 -8.0901670456 22.0905704498 0.1168821603 -0.0328450762 ) ( 17.9700889587 -8.0007953644 24.1811389923 0.1168821603 -0.0348978937 ) ( 17.3766670227 -7.7365875244 26.1803417206 0.1168821603 -0.0369507112 ) ( 16.7832489014 -7.4723796844 28.1795425415 0.1168821603 -0.0390035287 ) ( 15.8230724335 -7.0448827744 30.0000019073 0.1168821603 -0.0410563461 ) ( 14.8628988266 -6.6173858643 31.8204574585 0.1168821603 -0.0431091599 ) ( 13.5779314041 -6.0452823639 33.3826141357 0.1168821603 -0.0451619774 ) ( 12.29296875 -5.4731798172 34.9447669983 0.1168821603 -0.0472147949 ) ( 10.7393703461 -4.7814741135 36.1803398132 0.1168821603 -0.0492676124 ) ( 9.1857767105 -4.0897693634 37.4159126282 0.1168821603 -0.0513204262 ) ( 7.431447506 -3.3086919785 38.2709083557 0.1168821603 -0.0533732474 ) ( 5.6771225929 -2.5276165009 39.1259040833 0.1168821603 -0.0554260612 ) ( 3.7987344265 -1.6913046837 39.562953949 0.1168821603 -0.0574788824 ) ( 1.92035079 -0.8549947739 40 0.1168821603 -0.0595316961 ) ( -0.0000014305 0.0000009537 40 0.1168821603 -0.0615845174 ) ) +( ( 0 0 0 0.1210565194 0 ) ( 2.1020846367 -0.4468121529 -0.0000004728 0.1210565194 -0.002052817 ) ( 4.1582336426 -0.8838601112 0.437048018 0.1210565194 -0.0041056345 ) ( 6.2143831253 -1.3209080696 0.8740955591 0.1210565194 -0.0061584515 ) ( 8.1347332001 -1.7290911674 1.729090929 0.1210565194 -0.008211269 ) ( 10.0550823212 -2.1372747421 2.5840854645 0.1210565194 -0.0102640856 ) ( 11.7557048798 -2.4987530708 3.8196604252 0.1210565194 -0.0123169031 ) ( 13.4563264847 -2.8602313995 5.0552344322 0.1210565194 -0.0143697206 ) ( 14.8628959656 -3.1592068672 6.6173882484 0.1210565194 -0.0164225381 ) ( 16.2694664001 -3.4581828117 8.1795415878 0.1210565194 -0.0184753556 ) ( 17.3205070496 -3.6815886497 10.0000009537 0.1210565194 -0.0205281731 ) ( 18.3715496063 -3.9049949646 11.8204593658 0.1210565194 -0.0225809887 ) ( 19.0211296082 -4.0430669785 13.8196611404 0.1210565194 -0.0246338062 ) ( 19.67070961 -4.181139946 15.8188619614 0.1210565194 -0.0266866237 ) ( 19.8904361725 -4.2278442383 17.9094314575 0.1210565194 -0.0287394412 ) ( 20.1101646423 -4.2745485306 20 0.1210565194 -0.0307922568 ) ( 19.8904361725 -4.2278442383 22.0905704498 0.1210565194 -0.0328450762 ) ( 19.6707077026 -4.181139946 24.1811389923 0.1210565194 -0.0348978937 ) ( 19.0211296082 -4.0430669785 26.1803417206 0.1210565194 -0.0369507112 ) ( 18.371547699 -3.9049944878 28.1795425415 0.1210565194 -0.0390035287 ) ( 17.3205070496 -3.6815886497 30.0000019073 0.1210565194 -0.0410563461 ) ( 16.2694664001 -3.4581828117 31.8204574585 0.1210565194 -0.0431091599 ) ( 14.8628950119 -3.1592068672 33.3826141357 0.1210565194 -0.0451619774 ) ( 13.4563274384 -2.8602318764 34.9447669983 0.1210565194 -0.0472147949 ) ( 11.7557029724 -2.498752594 36.1803398132 0.1210565194 -0.0492676124 ) ( 10.0550832748 -2.1372747421 37.4159126282 0.1210565194 -0.0513204262 ) ( 8.1347312927 -1.7290911674 38.2709083557 0.1210565194 -0.0533732474 ) ( 6.2143831253 -1.3209085464 39.1259040833 0.1210565194 -0.0554260612 ) ( 4.1582317352 -0.8838596344 39.562953949 0.1210565194 -0.0574788824 ) ( 2.1020853519 -0.4468121529 40 0.1210565194 -0.0595316961 ) ( -0.0000019073 0.0000004768 40 0.1210565194 -0.0615845174 ) ) +( ( 0 0 0 0.1252308935 0 ) ( 2.1020846367 0.0000004768 -0.0000004728 0.1252308935 -0.002052817 ) ( 4.1582341194 0.0000009537 0.437048018 0.1252308935 -0.0041056345 ) ( 6.2143831253 0.0000009537 0.8740955591 0.1252308935 -0.0061584515 ) ( 8.1347332001 0.0000014305 1.729090929 0.1252308935 -0.008211269 ) ( 10.0550832748 0.0000019073 2.5840854645 0.1252308935 -0.0102640856 ) ( 11.7557048798 0.0000019073 3.8196604252 0.1252308935 -0.0123169031 ) ( 13.456328392 0.0000023842 5.0552344322 0.1252308935 -0.0143697206 ) ( 14.8628969193 0.000002861 6.6173882484 0.1252308935 -0.0164225381 ) ( 16.2694664001 0.000002861 8.1795415878 0.1252308935 -0.0184753556 ) ( 17.3205070496 0.000002861 10.0000009537 0.1252308935 -0.0205281731 ) ( 18.3715515137 0.000002861 11.8204593658 0.1252308935 -0.0225809887 ) ( 19.0211296082 0.0000033379 13.8196611404 0.1252308935 -0.0246338062 ) ( 19.6707115173 0.0000033379 15.8188619614 0.1252308935 -0.0266866237 ) ( 19.8904380798 0.0000038147 17.9094314575 0.1252308935 -0.0287394412 ) ( 20.1101665497 0.0000038147 20 0.1252308935 -0.0307922568 ) ( 19.8904380798 0.0000038147 22.0905704498 0.1252308935 -0.0328450762 ) ( 19.6707115173 0.0000033379 24.1811389923 0.1252308935 -0.0348978937 ) ( 19.0211296082 0.0000033379 26.1803417206 0.1252308935 -0.0369507112 ) ( 18.3715515137 0.000002861 28.1795425415 0.1252308935 -0.0390035287 ) ( 17.3205070496 0.000002861 30.0000019073 0.1252308935 -0.0410563461 ) ( 16.2694664001 0.000002861 31.8204574585 0.1252308935 -0.0431091599 ) ( 14.8628959656 0.000002861 33.3826141357 0.1252308935 -0.0451619774 ) ( 13.456328392 0.0000023842 34.9447669983 0.1252308935 -0.0472147949 ) ( 11.7557039261 0.0000019073 36.1803398132 0.1252308935 -0.0492676124 ) ( 10.0550842285 0.0000019073 37.4159126282 0.1252308935 -0.0513204262 ) ( 8.1347312927 0.0000014305 38.2709083557 0.1252308935 -0.0533732474 ) ( 6.214384079 0.0000009537 39.1259040833 0.1252308935 -0.0554260612 ) ( 4.1582322121 0.0000009537 39.562953949 0.1252308935 -0.0574788824 ) ( 2.1020855904 0.0000004768 40 0.1252308935 -0.0595316961 ) ( -0.0000019073 0 40 0.1252308935 -0.0615845174 ) ) +) +} +} +// brush 7 +{ +( 1088 64 80 ) ( 1088 -320 80 ) ( 960 64 80 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 -0 ] -0 0.5 0.5 0 0 0 +( 1088 64 64 ) ( 960 64 64 ) ( 1088 64 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 1088 64 64 ) ( 1088 64 0 ) ( 1088 -320 64 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 960 -64 0 ) ( 960 -64 64 ) ( 1088 -64 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 960 -320 0 ) ( 960 64 0 ) ( 960 -320 64 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 960 64 64 ) ( 1088 -320 64 ) ( 1088 64 64 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 -0 ] -0 0.5 0.5 0 0 0 +} +// brush 8 +{ +( 1088 64 64 ) ( 1088 -320 64 ) ( 960 64 64 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 -0 ] -0 0.5 0.5 0 0 0 +( 1088 80 64 ) ( 960 80 64 ) ( 1088 80 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 1088 64 64 ) ( 1088 64 0 ) ( 1088 -320 64 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 960 -320 0 ) ( 1088 -320 0 ) ( 960 64 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 -0 ] -0 0.5 0.5 0 0 0 +( 960 -320 0 ) ( 960 64 0 ) ( 960 -320 64 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 1088 64 0 ) ( 960 64 64 ) ( 1088 64 64 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +// brush 9 +{ +( 1088 64 64 ) ( 1088 -320 64 ) ( 960 64 64 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 -0 ] -0 0.5 0.5 0 0 0 +( 1088 64 64 ) ( 960 64 64 ) ( 1088 64 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 1104 64 64 ) ( 1104 64 0 ) ( 1104 -320 64 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 960 -320 0 ) ( 1088 -320 0 ) ( 960 64 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 -0 ] -0 0.5 0.5 0 0 0 +( 960 -64 0 ) ( 960 -64 64 ) ( 1088 -64 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 1088 -320 64 ) ( 1088 64 0 ) ( 1088 64 64 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +// brush 10 +{ +( 1088 64 64 ) ( 960 64 64 ) ( 1088 64 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 1088 64 64 ) ( 1088 64 0 ) ( 1088 -320 64 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 960 -320 -16 ) ( 1088 -320 -16 ) ( 960 64 -16 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 -0 ] -0 0.5 0.5 0 0 0 +( 960 -64 0 ) ( 960 -64 64 ) ( 1088 -64 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 960 -320 0 ) ( 960 64 0 ) ( 960 -320 64 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 960 64 0 ) ( 1088 -320 0 ) ( 960 -320 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 -0 ] -0 0.5 0.5 0 0 0 +} +// brush 11 +{ +( 1088 64 64 ) ( 1088 -320 64 ) ( 960 64 64 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 -0 ] -0 0.5 0.5 0 0 0 +( 1088 64 64 ) ( 1088 64 0 ) ( 1088 -320 64 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 960 -320 0 ) ( 1088 -320 0 ) ( 960 64 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 -0 ] -0 0.5 0.5 0 0 0 +( 960 -80 0 ) ( 960 -80 64 ) ( 1088 -80 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 960 -320 0 ) ( 960 64 0 ) ( 960 -320 64 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 1088 -64 0 ) ( 960 -64 64 ) ( 960 -64 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +// brush 12 +{ +( 1088 64 64 ) ( 1088 -320 64 ) ( 960 64 64 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 -0 ] -0 0.5 0.5 0 0 0 +( 1088 64 64 ) ( 960 64 64 ) ( 1088 64 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 960 -320 0 ) ( 1088 -320 0 ) ( 960 64 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 -0 ] -0 0.5 0.5 0 0 0 +( 960 -64 0 ) ( 960 -64 64 ) ( 1088 -64 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 944 -320 0 ) ( 944 64 0 ) ( 944 -320 64 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( 960 -320 64 ) ( 960 64 0 ) ( 960 -320 0 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +// brush 13 +{ +( 320 768 128 ) ( 320 384 128 ) ( -320 768 128 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 320 768 64 ) ( -320 768 64 ) ( 320 768 -64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 320 768 64 ) ( 320 768 -64 ) ( 320 384 64 ) pbrtest/bricks045 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -64 ) ( -320 384 64 ) ( 320 384 -64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -64 ) ( -320 768 -64 ) ( -320 384 64 ) pbrtest/bricks045 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 768 64 ) ( 320 384 64 ) ( 320 768 64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +} +// brush 14 +{ +( 320 768 64 ) ( 320 384 64 ) ( -320 768 64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 320 832 64 ) ( -320 832 64 ) ( 320 832 -64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 0 768 64 ) ( 0 768 -64 ) ( 0 384 64 ) pbrtest/bricks045 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -64 ) ( 320 384 -64 ) ( -320 768 -64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -64 ) ( -320 768 -64 ) ( -320 384 64 ) pbrtest/bricks045 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 320 768 -64 ) ( -320 768 64 ) ( 320 768 64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +} +// brush 15 +{ +( 320 768 64 ) ( 320 384 64 ) ( -320 768 64 ) pbrtest/woodsiding001 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 320 768 64 ) ( -320 768 64 ) ( 320 768 -64 ) pbrtest/woodsiding001 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 384 768 64 ) ( 384 768 -64 ) ( 384 384 64 ) pbrtest/woodsiding001 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -64 ) ( 320 384 -64 ) ( -320 768 -64 ) pbrtest/woodsiding001 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -64 ) ( -320 384 64 ) ( 320 384 -64 ) pbrtest/woodsiding001 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 320 384 64 ) ( 320 768 -64 ) ( 320 768 64 ) pbrtest/woodsiding001 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +} +// brush 16 +{ +( 320 768 64 ) ( -320 768 64 ) ( 320 768 -64 ) pbrtest/tiles052 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 320 768 64 ) ( 320 768 -64 ) ( 320 384 64 ) pbrtest/tiles052 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -128 ) ( 320 384 -128 ) ( -320 768 -128 ) pbrtest/tiles052 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( -320 576 -64 ) ( -320 576 64 ) ( 320 576 -64 ) pbrtest/tiles052 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -64 ) ( -320 768 -64 ) ( -320 384 64 ) pbrtest/tiles052 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 768 -64 ) ( 320 384 -64 ) ( -320 384 -64 ) pbrtest/tiles052 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +} +// brush 17 +{ +( 320 768 64 ) ( 320 384 64 ) ( -320 768 64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 320 768 64 ) ( -320 768 64 ) ( 320 768 -64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -64 ) ( 320 384 -64 ) ( -320 768 -64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -64 ) ( -320 384 64 ) ( 320 384 -64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -384 384 -64 ) ( -384 768 -64 ) ( -384 384 64 ) pbrtest/bricks045 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 384 64 ) ( -320 768 -64 ) ( -320 384 -64 ) pbrtest/bricks045 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +} +// brush 18 +{ +( 184 256 192 ) ( 184 -128 192 ) ( -328 256 192 ) pbrtest/metalplates006 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 192 384 264 ) ( -320 384 264 ) ( 192 384 256 ) pbrtest/metalplates006 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 320 544 8 ) ( 320 544 0 ) ( 320 160 8 ) pbrtest/metalplates006 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 272 192 256 ) ( 272 192 264 ) ( 784 192 256 ) pbrtest/metalplates006 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 -128 256 ) ( -320 256 256 ) ( -320 -128 264 ) pbrtest/metalplates006 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -64 448 64 ) ( 64 128 64 ) ( 64 448 64 ) common/caulk [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +} +// brush 19 +{ +( 192 320 264 ) ( -320 320 264 ) ( 192 320 256 ) pbrtest/metalplates006 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 320 544 8 ) ( 320 544 0 ) ( 320 160 8 ) pbrtest/metalplates006 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -768 -128 -128 ) ( -256 -128 -128 ) ( -768 256 -128 ) pbrtest/metalplates006 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 272 192 256 ) ( 272 192 264 ) ( 784 192 256 ) pbrtest/metalplates006 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 64 448 64 ) ( 64 128 64 ) ( -64 448 64 ) common/caulk [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( 64 128 64 ) ( 64 448 -64 ) ( 64 448 64 ) common/caulk [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +// brush 20 +{ +( 192 384 264 ) ( -320 384 264 ) ( 192 384 256 ) pbrtest/metalplates006 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -768 -128 -128 ) ( -256 -128 -128 ) ( -768 256 -128 ) pbrtest/metalplates006 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 272 192 256 ) ( 272 192 264 ) ( 784 192 256 ) pbrtest/metalplates006 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 -128 256 ) ( -320 256 256 ) ( -320 -128 264 ) pbrtest/metalplates006 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 64 448 64 ) ( 64 448 -64 ) ( 64 128 64 ) common/caulk [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +( -64 448 -64 ) ( 64 128 -64 ) ( -64 128 -64 ) common/caulk [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +} +// brush 21 +{ +( 192 320 264 ) ( -320 320 264 ) ( 192 320 256 ) pbrtest/metalplates006 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 272 192 256 ) ( 272 192 264 ) ( 784 192 256 ) pbrtest/metalplates006 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 -128 256 ) ( -320 256 256 ) ( -320 -128 264 ) pbrtest/metalplates006 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 64 448 64 ) ( 64 128 64 ) ( -64 448 64 ) common/caulk [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( -64 128 -64 ) ( 64 128 -64 ) ( -64 448 -64 ) common/caulk [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 +( -64 128 64 ) ( -64 448 -64 ) ( -64 128 -64 ) common/caulk [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +// brush 22 +{ +( 320 768 64 ) ( 320 384 64 ) ( -320 768 64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 320 768 64 ) ( 320 768 -64 ) ( 320 384 64 ) pbrtest/bricks045 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -64 ) ( 320 384 -64 ) ( -320 768 -64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( -320 320 -64 ) ( -320 320 64 ) ( 320 320 -64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 320 384 -64 ) ( -320 384 64 ) ( -320 384 -64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 64 128 64 ) ( 64 448 -64 ) ( 64 448 64 ) common/caulk [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +// brush 23 +{ +( 320 768 64 ) ( 320 384 64 ) ( -320 768 64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -64 ) ( 320 384 -64 ) ( -320 768 -64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( -320 320 -64 ) ( -320 320 64 ) ( 320 320 -64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -64 ) ( -320 768 -64 ) ( -320 384 64 ) pbrtest/bricks045 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 320 384 -64 ) ( -320 384 64 ) ( -320 384 -64 ) pbrtest/bricks045 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -64 128 64 ) ( -64 448 -64 ) ( -64 128 -64 ) common/caulk [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 +} +// brush 24 +{ +( 320 576 64 ) ( -320 576 64 ) ( 320 576 -64 ) pbrtest/woodfloor041 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 320 768 64 ) ( 320 768 -64 ) ( 320 384 64 ) pbrtest/woodfloor041 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -128 ) ( 320 384 -128 ) ( -320 768 -128 ) pbrtest/woodfloor041 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -64 ) ( -320 384 64 ) ( 320 384 -64 ) pbrtest/woodfloor041 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -64 ) ( -320 768 -64 ) ( -320 384 64 ) pbrtest/woodfloor041 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 768 -64 ) ( 320 384 -64 ) ( -320 384 -64 ) pbrtest/woodfloor041 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +} +// brush 25 +{ +( 320 768 64 ) ( 320 384 64 ) ( -320 768 64 ) pbrtest/woodsiding001 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 320 832 64 ) ( -320 832 64 ) ( 320 832 -64 ) pbrtest/woodsiding001 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 320 768 64 ) ( 320 768 -64 ) ( 320 384 64 ) pbrtest/woodsiding001 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( -320 384 -64 ) ( 320 384 -64 ) ( -320 768 -64 ) pbrtest/woodsiding001 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 +( 0 384 -64 ) ( 0 768 -64 ) ( 0 384 64 ) pbrtest/woodsiding001 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +( 320 768 -64 ) ( -320 768 64 ) ( 320 768 64 ) pbrtest/woodsiding001 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 +} +// brush 26 +{ +patchDef2 +{ +pbrtest/metal022 +( 9 3 0 0 0 ) +( +( ( -256 672 -64 0 -0.984375 ) ( -256 672 0 0 -1.234375 ) ( -256 672 64 0 -1.484375 ) ) +( ( -256 640 -64 0.125 -0.984375 ) ( -256 640 0 0.125 -1.234375 ) ( -256 640 64 0.125 -1.484375 ) ) +( ( -224 640 -64 0.25 -0.984375 ) ( -224 640 0 0.25 -1.234375 ) ( -224 640 64 0.25 -1.484375 ) ) +( ( -192 640 -64 0.375 -0.984375 ) ( -192 640 0 0.375 -1.234375 ) ( -192 640 64 0.375 -1.484375 ) ) +( ( -192 672 -64 0.5 -0.984375 ) ( -192 672 0 0.5 -1.234375 ) ( -192 672 64 0.5 -1.484375 ) ) +( ( -192 704 -64 0.625 -0.984375 ) ( -192 704 0 0.625 -1.234375 ) ( -192 704 64 0.625 -1.484375 ) ) +( ( -224 704 -64 0.75 -0.984375 ) ( -224 704 0 0.75 -1.234375 ) ( -224 704 64 0.75 -1.484375 ) ) +( ( -256 704 -64 0.875 -0.984375 ) ( -256 704 0 0.875 -1.234375 ) ( -256 704 64 0.875 -1.484375 ) ) +( ( -256 672 -64 1 -0.984375 ) ( -256 672 0 1 -1.234375 ) ( -256 672 64 1 -1.484375 ) ) +) +} +} +} +// entity 1 +{ +"classname" "info_player_start" +"origin" "-56.000000 0.000000 0.000000" +} +// entity 2 +{ +"classname" "info_player_deathmatch" +"origin" "-56.000000 0.000000 0.000000" +} +// entity 3 +{ +"classname" "env_cubemap" +} +// entity 4 +{ +"classname" "sky_camera" +"origin" "1024.000000 0.000000 32.000000" +} +// entity 5 +{ +"classname" "light_environment" +"origin" "64.000000 0.000000 32.000000" +"color" "0.996 0.941 0.835" +"ambientcolor" "0.678 0.816 0.949" +"intensity" "250" +"sunangle" "321" +"pitch" "-145.86" +"filterradius" "1" +"sunspreadangle" "0" +"samples" "16" +} +// entity 6 +{ +"classname" "light" +"origin" "0.000000 576.000000 0.000000" +"light" "300" +} +// entity 7 +{ +"classname" "env_cubemap" +"origin" "0.000000 576.000000 0.000000" +} +// entity 8 +{ +"classname" "prop_dynamic" +"origin" "64.000000 -64.000000 -32.000000" +"model" "models/logo.iqm" +"angles" "0 135 -45" +"modelscale" "0.45" +"shadows" "1" +"_cs" "1" +} \ No newline at end of file diff --git a/src/botlib/NSBot.h b/src/botlib/NSBot.h index 2e6410b5..22248408 100644 --- a/src/botlib/NSBot.h +++ b/src/botlib/NSBot.h @@ -77,6 +77,7 @@ public: virtual void CheckRoute(void); virtual void PreFrame(void); virtual void PostFrame(void); + virtual void AddedItemCallback(NSItem); virtual void UseButton(void); virtual void SetEnemy(entity); virtual float GetRunSpeed(void); diff --git a/src/botlib/NSBot.qc b/src/botlib/NSBot.qc index 13db7c1e..72b00bd6 100644 --- a/src/botlib/NSBot.qc +++ b/src/botlib/NSBot.qc @@ -298,7 +298,7 @@ NSBot::RunAI(void) input_angles = [0,0,0]; /* attempt to respawn when dead */ - if (IsAlive() == false || health <= 0) { + if (IsAlive() == false) { RouteClear(); WeaponAttack(); SetEnemy(__NULL__); @@ -512,14 +512,16 @@ NSBot::PreFrame(void) void NSBot::PostFrame(void) { -#if 0 - /* we've picked something new up */ - if (m_iOldItems != g_items) { - Weapons_SwitchBest(this); - BotEntLog("%S is now using %S (%d)", netname, g_weapons[activeweapon].name, activeweapon); - m_iOldItems = g_items; +} + +void +NSBot::AddedItemCallback(NSItem newItem) +{ + if (isBot(this) == true) { + SwitchToBestWeapon(false); + } else { + super::AddedItemCallback(newItem); } -#endif } void diff --git a/src/botlib/combat.qc b/src/botlib/combat.qc index 2a5f1038..0683092b 100644 --- a/src/botlib/combat.qc +++ b/src/botlib/combat.qc @@ -22,23 +22,23 @@ NSBot::Pain(entity inflictor, entity attacker, int damage, vector dir, int locat super::Pain(inflictor, attacker, damage, dir, location); if (rules.IsTeamplay()) { - if (g_dmg_eAttacker.flags & FL_CLIENT && g_dmg_eAttacker.team == team) { + if (isPlayer(attacker) && attacker.team == team) { ChatSayTeam("Stop shooting me!"); return; } } /* make this pain our new enemy! */ - if (g_dmg_eAttacker && g_dmg_eAttacker != this) { + if (attacker && attacker != this) { float enemydist = distanceSquared(origin, m_eTarget.origin); - float newdist = distanceSquared(origin, g_dmg_eAttacker.origin); + float newdist = distanceSquared(origin, attacker.origin); if (m_eTarget) { if (newdist < enemydist) { - SetEnemy(g_dmg_eAttacker); + SetEnemy(attacker); } } else { - SetEnemy(g_dmg_eAttacker); + SetEnemy(attacker); } } } @@ -58,21 +58,19 @@ NSBot::SetEnemy(entity en) void NSBot::WeaponThink(void) { -#if 0 - int r = Weapons_IsEmpty(this, activeweapon); + bool isEmpty = m_activeWeapon.IsEmpty(); /* clip empty, but the whole weapon isn't */ - if (r == 0 && a_ammo1 <= 0) { + if (isEmpty == false) { /* stop fire, tap reload */ input_buttons &= ~INPUT_PRIMARY; input_buttons |= INPUT_RELOAD; - } else if (r == 1) { + } else { /* if empty, switch to the next best weapon */ - Weapons_SwitchBest(this, activeweapon); + SwitchToBestWeapon(false); } - m_wtWeaponType = Weapons_GetType(this, activeweapon); -#endif + //m_wtWeaponType = Weapons_GetType(this, activeweapon); } void diff --git a/src/botlib/cvars.h b/src/botlib/cvars.h index 0e5e3edb..e58d23bc 100644 --- a/src/botlib/cvars.h +++ b/src/botlib/cvars.h @@ -35,7 +35,6 @@ var bool autocvar_bot_enable = true; var bool autocvar_bot_pause = false; var bool autocvar_bot_noChat = false; var bool autocvar_bot_fastChat = false; -var bool autocvar_bot_debug = false; var bool autocvar_bot_developer = false; var int autocvar_bot_minClients = -1i; diff --git a/src/client/NSRadar.qc b/src/client/NSRadar.qc index 9f411ef4..0e2554d8 100644 --- a/src/client/NSRadar.qc +++ b/src/client/NSRadar.qc @@ -182,9 +182,9 @@ NSRadar::InitWithMapname(string mapName) string hlFile = strcat("overviews/", mapName, ".txt"); /* try Source first, then GoldSrc */ - if (FileExists(sourceFile)) { + if (fileExists(sourceFile)) { return InitFromSourceHLTVScript(sourceFile); - } else if (FileExists(hlFile)) { + } else if (fileExists(hlFile)) { return InitFromHLTVScript(hlFile); } diff --git a/src/client/event.qc b/src/client/event.qc index 36458a3f..4b87dd9f 100644 --- a/src/client/event.qc +++ b/src/client/event.qc @@ -272,6 +272,32 @@ Event_Parse(float type) case EV_ENTITYEVENT: EV_EntityEvent(); break; + case EV_BLOOD: + vector vBloodPos = g_vec_null; + vector vBloodColor = g_vec_null; + + vBloodPos[0] = readcoord(); + vBloodPos[1] = readcoord(); + vBloodPos[2] = readcoord(); + + vBloodColor[0] = readbyte() / 255; + vBloodColor[1] = readbyte() / 255; + vBloodColor[2] = readbyte() / 255; + break; + case EV_CHAT: + float fSender = readbyte(); + float fTeam = readbyte(); + string sMessage = readstring(); + + CSQC_Parse_Print(Util_ChatFormat(fSender, 0, sMessage), PRINT_CHAT); + break; + case EV_CHAT_TEAM: + float fSender2 = readbyte(); + float fTeam2 = readbyte(); + string sMessage2 = readstring(); + + CSQC_Parse_Print(Util_ChatFormat(fSender2, fTeam2, sMessage2), PRINT_CHAT); + break; default: error(sprintf("event id %d not recognized. abort immediately.\n", type)); } diff --git a/src/client/font.qc b/src/client/font.qc index ae6d43da..bd758104 100644 --- a/src/client/font.qc +++ b/src/client/font.qc @@ -29,7 +29,7 @@ Font_Load(string strFile, font_s &fntNew) filestream fileFont = fopen(strFile, FILE_READ); fntNew.iID = 0; - fntNew.iScaleX = fntNew.iScaleY = -1; + fntNew.iScaleX = fntNew.iScaleY = 12; fntNew.vecColor = [1,1,1]; fntNew.flAlpha = 1.0f; fntNew.iFlags = 0; diff --git a/src/client/view.qc b/src/client/view.qc index 3d6c356e..25f2dfcc 100644 --- a/src/client/view.qc +++ b/src/client/view.qc @@ -131,6 +131,10 @@ View_ForceChange(NSClientPlayer pl, int targetWeapon) m_eViewModelL.frame1time = 0.0f; } +var float autocvar_cg_gunX = 0.0f; +var float autocvar_cg_gunY = 0.0f; +var float autocvar_cg_gunZ = 0.0f; + /* ==================== View_DrawViewModel @@ -250,7 +254,11 @@ View_DrawViewModel(void) if (Client_IsSpectator(cl) || XR_Available(cl) == false) { m_eViewModelL.origin = g_view.GetCameraOrigin(); - m_eViewModel.origin = g_view.GetCameraOrigin(); + makevectors(currentAngle); + m_eViewModelL.origin += (v_forward * cvar("cg_gunX")); + m_eViewModelL.origin += (v_right * cvar("cg_gunY")); + m_eViewModelL.origin += (v_up * cvar("cg_gunZ")); + m_eViewModel.origin = m_eViewModelL.origin; if (Client_IsSpectator(cl)) { m_eViewModel.angles = currentAngle; diff --git a/src/gs-entbase/server/button_target.qc b/src/gs-entbase/server/button_target.qc index de0d03ed..b6d73237 100644 --- a/src/gs-entbase/server/button_target.qc +++ b/src/gs-entbase/server/button_target.qc @@ -74,7 +74,7 @@ button_target::Respawn(void) PlayerUse = PUseWrapper; } else { SetHealth(1); - SetTakedamage(DAMAGE_YES); + MakeVulnerable(); Pain = Death = Damaged; } @@ -87,7 +87,7 @@ button_target::Trigger(entity act, triggermode_t status) { /* make unusable */ PlayerUse = __NULL__; - SetTakedamage(DAMAGE_NO); + MakeInvulnerable(); /* toggle texture frame */ float new_frame = (GetFrame() >= 1) ? 0 : 1; diff --git a/src/gs-entbase/server/env_spark.qc b/src/gs-entbase/server/env_spark.qc index 5ed5975d..2eea7036 100644 --- a/src/gs-entbase/server/env_spark.qc +++ b/src/gs-entbase/server/env_spark.qc @@ -134,7 +134,7 @@ env_spark::Spawned(void) { super::Spawned(); - Sound_Precache("fx.spark"); + Sound_Precache("DoSpark"); _m_iSparkParticle = particleeffectnum("fx_spark.main"); } @@ -182,7 +182,7 @@ void env_spark::SparkOnce(void) { if (HasSpawnFlags(EVSPARK_SILENT) == false) { - StartSoundDef("fx.spark", CHAN_AUTO, true); + StartSoundDef("DoSpark", CHAN_AUTO, true); } pointparticles(_m_iSparkParticle, origin, angles, 1); diff --git a/src/gs-entbase/server/func_breakable.qc b/src/gs-entbase/server/func_breakable.qc index ce4c6d44..7c0bf68c 100644 --- a/src/gs-entbase/server/func_breakable.qc +++ b/src/gs-entbase/server/func_breakable.qc @@ -262,9 +262,9 @@ func_breakable::Respawn(void) m_bCanTouch = true; if (HasSpawnFlags(SF_TRIGGER)) { - SetTakedamage(DAMAGE_NO); + MakeInvulnerable(); } else { - SetTakedamage(DAMAGE_YES); + MakeVulnerable(); } /* initially set the health to that of the ent-data */ @@ -312,7 +312,7 @@ func_breakable::Explode(void) pointparticles(_m_iExplosionParticle, rp, [0,0,0], 1); radiusDamage(GetOrigin(), m_flExplodeMag, 0i, m_flExplodeRad, this); UseTargets(this, TRIG_TOGGLE, 0.0f); /* delay... ignored. */ - SetTakedamage(DAMAGE_NO); + MakeInvulnerable(); Disappear(); } @@ -369,7 +369,7 @@ func_breakable::Death(entity inflictor, entity attacker, int damage, vector dir, EntLog("func_breakable (%s) does not have a surfaceproperty for break", funcbreakable_surftable[material]); Disappear(); - SetTakedamage(DAMAGE_NO); + MakeInvulnerable(); UseTargets(eActivator, TRIG_TOGGLE, 0.0f); } } diff --git a/src/gs-entbase/server/func_door_rotating.qc b/src/gs-entbase/server/func_door_rotating.qc index f4ef7fcb..534a83c6 100644 --- a/src/gs-entbase/server/func_door_rotating.qc +++ b/src/gs-entbase/server/func_door_rotating.qc @@ -229,7 +229,7 @@ func_door_rotating::Respawn(void) super::Respawn(); #ifdef GS_PHYSICS - SetTakedamage(DAMAGE_YES); + MakeVulnerable(); SetHealth(100); Death = func_door_rotating::Unhinge; #endif @@ -354,7 +354,7 @@ func_door_rotating::SpawnKey(string strKey, string strValue) void func_door_rotating::Unhinge(void) { - SetTakedamage(DAMAGE_NO); + MakeInvulnerable(); ReleaseThink(); m_bCanTouch = false; SetSolid(SOLID_PHYSICS_BOX); diff --git a/src/gs-entbase/server/func_guntarget.qc b/src/gs-entbase/server/func_guntarget.qc index a096e99a..2148f630 100644 --- a/src/gs-entbase/server/func_guntarget.qc +++ b/src/gs-entbase/server/func_guntarget.qc @@ -215,7 +215,7 @@ func_guntarget::Death(entity inflictor, entity attacker, int damage, vector dir, void func_guntarget::Start(void) { - SetTakedamage(DAMAGE_YES); + MakeVulnerable(); NextPath(); m_iValue = 0; } @@ -223,7 +223,7 @@ func_guntarget::Start(void) void func_guntarget::Stop(void) { - SetTakedamage(DAMAGE_NO); + MakeInvulnerable(); ClearVelocity(); ReleaseThink(); m_iValue = 1; diff --git a/src/gs-entbase/server/func_physbox.qc b/src/gs-entbase/server/func_physbox.qc index c6b2d906..73f6d61f 100644 --- a/src/gs-entbase/server/func_physbox.qc +++ b/src/gs-entbase/server/func_physbox.qc @@ -91,8 +91,8 @@ void func_physbox::Respawn(void) { super::Respawn(); - health = GetSpawnHealth(); - SetTakedamage(DAMAGE_YES); + SetHealth(GetSpawnFloat("health")); + MakeVulnerable(); SetSolid(SOLID_BBOX); } #endif diff --git a/src/gs-entbase/server/func_pushable.qc b/src/gs-entbase/server/func_pushable.qc index aca404e1..2ca8eac4 100644 --- a/src/gs-entbase/server/func_pushable.qc +++ b/src/gs-entbase/server/func_pushable.qc @@ -175,9 +175,9 @@ func_pushable::Respawn(void) PlayerUse = OnPlayerUse; if (HasSpawnFlags(FNCPUSHABLE_BREAKABLE) == true) { - SetTakedamage(DAMAGE_YES); + MakeVulnerable(); } else { - SetTakedamage(DAMAGE_NO); + MakeInvulnerable(); } if (!m_eCollBox) { diff --git a/src/gs-entbase/server/func_rot_button.qc b/src/gs-entbase/server/func_rot_button.qc index 54b5663e..efd0d5f6 100644 --- a/src/gs-entbase/server/func_rot_button.qc +++ b/src/gs-entbase/server/func_rot_button.qc @@ -175,7 +175,7 @@ func_rot_button::Respawn(void) ReleaseThink(); if (GetSpawnHealth() > 0) { - SetTakedamage(DAMAGE_YES); + MakeVulnerable(); SetHealth(GetSpawnHealth()); } @@ -277,6 +277,6 @@ func_rot_button::TurnToggle(void) void func_rot_button::Death(entity inflictor, entity attacker, int damage, vector dir, int location) { - SetTakedamage(DAMAGE_NO); + MakeInvulnerable(); TurnToggle(); } diff --git a/src/gs-entbase/server/prop_physics.qc b/src/gs-entbase/server/prop_physics.qc index e3bd0a89..def351be 100644 --- a/src/gs-entbase/server/prop_physics.qc +++ b/src/gs-entbase/server/prop_physics.qc @@ -14,8 +14,6 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef PHYSICS_STATIC - enumflags { PHYSPROPSFL_ASLEEP, @@ -95,27 +93,6 @@ prop_physics::Respawn(void) Sleep(); } -#else -class -prop_physics:NSRenderableEntity -{ - void(void) prop_physics; - - virtual void(void) Respawn; -}; - -void -prop_physics::prop_physics(void) -{ -} - -void -prop_physics::Respawn(void) -{ - super::Respawn(); - SetSolid(SOLID_BBOX); -} -#endif CLASSEXPORT(prop_physics_override, prop_physics) CLASSEXPORT(prop_physics_respawnable, prop_physics) diff --git a/src/gs-entbase/server/prop_static.qc b/src/gs-entbase/server/prop_static.qc index f1ab5dcb..db53c59d 100644 --- a/src/gs-entbase/server/prop_static.qc +++ b/src/gs-entbase/server/prop_static.qc @@ -67,6 +67,6 @@ prop_static::Respawn(void) geomtype = GEOMTYPE_TRIMESH; Sleep(); - SetTakedamage(DAMAGE_NO); + MakeInvulnerable(); touch = __NULL__; } diff --git a/src/gs-entbase/shared/ambient_generic.qc b/src/gs-entbase/shared/ambient_generic.qc index 1129c9fc..fa69f7a4 100644 --- a/src/gs-entbase/shared/ambient_generic.qc +++ b/src/gs-entbase/shared/ambient_generic.qc @@ -307,7 +307,7 @@ ambient_generic::UseNormal(entity act, triggermode_t state) multicast(origin, MULTICAST_PHS); } else { /* if the file doesn't exist, assume it's a SoundDef */ - if (FileExists(strcat("sound/", m_strActivePath)) == false) { + if (fileExists(strcat("sound/", m_strActivePath)) == false) { Sound_Play(this, CHAN_BODY, m_strActivePath); } else { sound(this, CHAN_BODY, m_strActivePath, m_flVolume, m_flRadius, m_flPitch); diff --git a/src/nav/nodes.qc b/src/nav/nodes.qc index db105753..534fe11f 100644 --- a/src/nav/nodes.qc +++ b/src/nav/nodes.qc @@ -175,7 +175,7 @@ Nodes_Init(void) InitStart(); /* skip if present. TODO: check if they're out of date? */ - if (FileExists(sprintf("data/%s.way", mapname))) { + if (fileExists(sprintf("data/%s.way", mapname))) { NodeEdit_ReadFile(sprintf("%s.way", mapname), true); } else { Nodes_BuildFromEnts(); diff --git a/src/server/NSGameRules.h b/src/server/NSGameRules.h index ad1a36f3..fbdb6d1c 100644 --- a/src/server/NSGameRules.h +++ b/src/server/NSGameRules.h @@ -60,9 +60,9 @@ public: /** Overridable: Called after running physics on the NSClientPlayer in question. */ virtual void PlayerPostFrame(NSClientPlayer); /** Overridable: Called when a NSClientPlayer dies in the game. */ - virtual void PlayerDeath(NSClientPlayer); + virtual void PlayerDeath(NSClientPlayer, NSActor, NSDict); /** Overridable: Called when a NSClientPlayer feels pain. */ - virtual void PlayerPain(NSClientPlayer); + virtual void PlayerPain(NSClientPlayer, NSActor, NSDict); /** Overridable: Called to check if a NSClientPlayer can attack. */ virtual bool PlayerCanAttack(NSClientPlayer); @@ -118,6 +118,8 @@ public: /** Returns the title of the gamemode running. */ virtual string Title(void); + + nonvirtual NSGameRules InitFromProgs(string pathToProgs); /* spectator */ /* @@ -130,6 +132,7 @@ private: float m_flIntermissionTime; float m_flIntermissionCycle; entity m_eIntermissionPoint; + float m_ruleProgs; }; /* our currently running mode */ diff --git a/src/server/NSGameRules.qc b/src/server/NSGameRules.qc index cb5cd510..a70dbc55 100644 --- a/src/server/NSGameRules.qc +++ b/src/server/NSGameRules.qc @@ -60,7 +60,7 @@ NSGameRules::RestoreComplete(void) void NSGameRules::InitPostEnts(void) { - //print("Init!\n"); + RuleC_CallFunc(m_ruleProgs, world, "CodeCallback_StartGameType"); } /* logic */ @@ -77,45 +77,86 @@ NSGameRules::ConsoleCommand(NSClientPlayer pl, string cmd) bool NSGameRules::ClientCommand(NSClient pl, string cmd) { - return (false); + return RuleC_CallString(m_ruleProgs, pl, cmd, "CodeCallback_ClientCommand"); } + bool NSGameRules::ImpulseCommand(NSClient pl, float num) { - return (false); + return RuleC_CallFloat(m_ruleProgs, pl, num, "CodeCallback_ImpulseCommand"); } -/* client */ void NSGameRules::PlayerConnect(NSClientPlayer pl) { - if (Plugin_PlayerConnect(pl) == FALSE) + if (Plugin_PlayerConnect(pl) == false) { bprint(PRINT_HIGH, sprintf("%s^d connected.\n", pl.netname)); + } + + RuleC_CallFunc(m_ruleProgs, pl, "CodeCallback_PlayerConnect"); } void NSGameRules::PlayerDisconnect(NSClientPlayer pl) { bprint(PRINT_HIGH, sprintf("%s^d disconnected.\n", pl.netname)); + RuleC_CallFunc(m_ruleProgs, pl, "CodeCallback_PlayerDisconnect"); } void NSGameRules::PlayerKill(NSClientPlayer pl) { - //Damage_Apply(pl, pl, pl.health, 0, DMG_SKIP_ARMOR); + NSDict damageDecl = spawn(NSDict); + damageDecl.AddKey("damage", itos(1000)); + damageDecl.AddKey("noGod", "1"); + damageDecl.AddKey("noArmor", "1"); + pl.Damage(pl, pl, damageDecl, 1.0, g_vec_null, pl.GetOrigin()); + remove(damageDecl); } void -NSGameRules::PlayerDeath(NSClientPlayer pl) +NSGameRules::PlayerDeath(NSClientPlayer pl, NSActor attacker, NSDict damageDecl) { - /* implemented by sub-class */ + if (RuleC_CallDamage(m_ruleProgs, pl, attacker, attacker, "", "CodeCallback_PlayerKilled")) { + return; + } + + WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); + WriteByte(MSG_MULTICAST, EV_OBITUARY); + WriteString(MSG_MULTICAST, (attacker.netname) ? attacker.netname : attacker.classname); + WriteString(MSG_MULTICAST, pl.netname); + WriteByte(MSG_MULTICAST, 0); + WriteByte(MSG_MULTICAST, 0); + msg_entity = world; + multicast([0,0,0], MULTICAST_ALL); + + /* death-counter */ + pl.deaths++; + pl.SetInfoKey("*deaths", ftos(pl.deaths)); + + /* update score-counter */ + if (isPlayer(attacker)) { + if (pl == attacker) { + g_dmg_eAttacker.frags--; + } else { + g_dmg_eAttacker.frags++; + } + } } + void -NSGameRules::PlayerPain(NSClientPlayer pl) +NSGameRules::PlayerPain(NSClientPlayer pl, NSActor attacker, NSDict damageDecl) { - /* implemented by sub-class */ + if (RuleC_CallDamage(m_ruleProgs, pl, attacker, attacker, "", "CodeCallback_PlayerDamage")) { + return; + } + + /* fallback code here, or rest implemented by sub-class */ } + void NSGameRules::PlayerSpawn(NSClientPlayer pl) { + RuleC_CallFunc(m_ruleProgs, pl, "CodeCallback_PlayerSpawn"); + /* implemented by sub-class */ } void @@ -322,9 +363,9 @@ NSGameRules::PlayerCanAttack(NSClientPlayer bp) } bool -NSGameRules::PlayerRequestRespawn(NSClientPlayer bp) +NSGameRules::PlayerRequestRespawn(NSClientPlayer pl) { - return false; + return RuleC_CallRequestSpawn(m_ruleProgs, pl, "CodeCallback_PlayerRequestRespawn"); } void @@ -380,3 +421,44 @@ NSGameRules::Title(void) { return "Default"; } + +NSGameRules +NSGameRules::InitFromProgs(string pathToProgs) +{ + NSGameRules newRule; + + /* No progs .dat, exit out */ + if (fileExists(pathToProgs) == false) { + NSError("Progs at %S does not exist.", pathToProgs); + return (__NULL__); + } + + newRule = spawn(NSGameRules); + newRule.m_ruleProgs = addprogs(pathToProgs); + + if (newRule.m_ruleProgs) { + void(void) mainFunction; + mainFunction = externvalue(newRule.m_ruleProgs, "main"); + + if (mainFunction) { + externset(newRule.m_ruleProgs, this, "self"); + thread(mainFunction()); + } else { + NSError("%S does not have a main function.", pathToProgs); + } + } + + return (newRule); +} + +void +setServerInfo(string serverKey, string setValue) +{ + forceinfokey(world, serverKey, setValue); +} + +string +getServerInfo(string serverKey) +{ + return infokey(world, serverKey); +} diff --git a/src/server/defs.h b/src/server/defs.h index 7312e225..2df9d398 100644 --- a/src/server/defs.h +++ b/src/server/defs.h @@ -26,6 +26,7 @@ #include "vote.h" #include "mapcycle.h" #include "maptweaks.h" +#include "scripts.h" /* helper macros */ #define EVALUATE_FIELD(fieldname, changedflag) {\ diff --git a/src/server/entry.qc b/src/server/entry.qc index 0e86a3f9..039b78cb 100644 --- a/src/server/entry.qc +++ b/src/server/entry.qc @@ -43,22 +43,15 @@ The `self` global is the connecting client in question. void ClientConnect(void) { - int playercount = 0; self.gotData = false; /* don't carry over team settings from a previous session */ forceinfokey(self, "*team", "0"); - /* make sure you never change the classname. ever. */ - if (self.classname != "player") { - EntityDef_SpawnClassname("player"); - } - - if (g_ents_initialized) + if (g_ents_initialized) { + Entity_CreateClass("player"); g_grMode.PlayerConnect((NSClientPlayer)self); - - for (entity a = world; (a = find(a, ::classname, "player"));) - playercount++; + } } /** Called when a player leaves the server. At the end of the function the @@ -77,7 +70,7 @@ ClientDisconnect(void) pl.SetMovetype(MOVETYPE_NONE); pl.SetModelindex(0); pl.SetHealth(0); - pl.SetTakedamage(DAMAGE_NO); + pl.MakeInvulnerable(); pl.SetTeam(0); pl.Disappear(); pl.classname = ""; @@ -142,7 +135,7 @@ PutClientInServer(void) g_grMode.PlayerSpawn((NSClientPlayer)self); /* handle transitions */ - if (FileExists("data/trans.dat")) { + if (fileExists("data/trans.dat")) { for (entity a = world; (a = findfloat(a, ::identity, 1));) { NSEntity levelEnt = (NSEntity)a; @@ -464,18 +457,11 @@ ConsoleCmd(string cmd) NSClientPlayer pl; /* some sv commands can only be executed by a player in-world */ - if ( !self ) { - for ( other = world; ( other = find( other, classname, "player" ) ); ) { - if ( clienttype( other ) == CLIENTTYPE_REAL ) { - self = other; - break; - } - } - } - if (!self) { - for ( other = world; ( other = find( other, classname, "spectator" ) ); ) { - if ( clienttype( other ) == CLIENTTYPE_REAL ) { + other = world; + + while ((other = nextent(other))) { + if (clienttype(other) == CLIENTTYPE_REAL) { self = other; break; } @@ -500,14 +486,17 @@ is being executed. float SV_ShouldPause(float newstatus) { - if (serverkeyfloat("background") == 1) + if (serverkeyfloat("background") == 1) { return (0); + } - if (cvar("pausable") == 1) + if (cvar("pausable") == 1) { return (1); + } - if (cvar("sv_playerslots") > 1) + if (cvar("sv_playerslots") > 1) { return (0); + } return newstatus; } @@ -691,7 +680,6 @@ CheckSpawn(void() spawnfunc) if (MapTweak_EntitySpawn(ent) == true) { ent._mapspawned = true; - ent.classname = desiredClass; } else if (EntityDef_SpawnClassname(desiredClass) != __NULL__) { ent._mapspawned = true; } else if (spawnfunc) { @@ -699,6 +687,8 @@ CheckSpawn(void() spawnfunc) ent.classname = desiredClass; ent._mapspawned = true; g_ent_spawned++; + } else { + ent.identity = 0; } /* check if this entity was meant to spawn on the client-side only */ @@ -729,4 +719,4 @@ CheckSpawn(void() spawnfunc) /* needs to be called at least once after spawn, then any time after. */ ent.Respawn(); -} \ No newline at end of file +} diff --git a/src/server/mapC.h b/src/server/mapC.h index b372f0e2..294aaee1 100644 --- a/src/server/mapC.h +++ b/src/server/mapC.h @@ -25,6 +25,8 @@ #include "mapC_math.h" #include "mapC_weapons.h" +.float deaths; + /** @defgroup mapc MapC @brief MapC/Shared Game-Logic API @ingroup multiprogs @@ -52,6 +54,20 @@ spawnClass(string className, vector desiredPos) return spawnFunc(className, desiredPos); } +bool +changeClass(entity target, string newClass) +{ + bool(entity, string) spawnFunc = externvalue(0, "changeClass"); + return spawnFunc(target, newClass); +} + +bool +cacheEntityDef(string className) +{ + bool(string) spawnFunc = externvalue(0, "EntityDef_Precache"); + return spawnFunc(className); +} + /** Sends an input (See NSIO::Input) to an entity. While you're able to manipulate entities in most ways using bare MapC, you might want to change Nuclide specific attributes of them as well. This can only be done using the I/O system. @@ -65,8 +81,8 @@ For the variety of inputs an entity supports, please look at the respective enti void sendInput(entity target, string inputName, string dataString, entity activator) { - void(entity, entity, string, string) inputFunc = externvalue(0, "sendInput"); - inputFunc(target, activator, inputName, setValue); + void(entity, string, string, entity) inputFunc = externvalue(0, "sendInput"); + inputFunc(target, inputName, dataString, activator); } /** Applies damage to a given entity. @@ -177,11 +193,114 @@ timeToString(int realTime, int zoneType, string formatString) { /* supposed to take extra (optional parameters...) */ if (zoneType == 1i) { - strftime(true, formatString); + return strftime(true, formatString); } else { - strftime(true, formatString); + return strftime(true, formatString); } } -/** @} */ // end of multiprogs - \ No newline at end of file +/** Returns the the value of a console variable. + +@param cvarName specifies the console variable to query. +@return The value in string format. */ +string +getCvar(string cvarName) +{ + return cvar_string(cvarName); +} + +/** Returns the the value of a console variable. + +@param cvarName specifies the console variable to query. +@return The value in integer format. */ +int +getCvarInt(string cvarName) +{ + return (int)cvar(cvarName); +} + +/** Returns the the value of a console variable. + +@param cvarName specifies the console variable to query. +@return The value in integer format. */ +bool +fileExists(string fileName) +{ + bool(string) checkFunc = externvalue(0, "fileExists"); + return checkFunc(fileName); +} + +/** Sets the specified serverinfo key to a set value. + +@param serverKey specifies the serverinfo key to set. +@param setValue specifies the value of said key. */ +void +setServerInfo(string serverKey, string setValue) +{ + void(string, string) checkFunc = externvalue(0, "setServerInfo"); + checkFunc(serverKey, setValue); +} + +/** Returns the the value of a serverinfo key. + +@param serverKey specifies the serverinfo key to query. +@return The value in string format. */ +string +getServerInfo(string serverKey) +{ + string(string) checkFunc = externvalue(0, "getServerInfo"); + return checkFunc(serverKey); +} + +/** Sets the specified userinfo key to a set value. + +@param clientEntity specifies the client to poke. +@param userKey specifies the userinfo key to set. +@param setValue specifies the value of said key. */ +void +setUserInfo(entity clientEntity, string userKey, string setValue) +{ + void(entity, string, string) checkFunc = externvalue(0, "setUserInfo"); + checkFunc(clientEntity, userKey, setValue); +} + +/** Returns the the value of a userinfo key. + +@param clientEntity specifies the client to peek at. +@param userKey specifies the userinfo key to query. +@return The value in string format. */ +string +getUserInfo(entity clientEntity, string userKey) +{ + string(entity, string) checkFunc = externvalue(0, "getUserInfo"); + return checkFunc(clientEntity, userKey); +} + +entity +getSpawnpoint(string className) +{ + entity(string) checkFunc = externvalue(0, "Spawn_SelectRandom"); + return checkFunc(className); +} + +entity +placeSpawnpoint(entity targetEntity) +{ + entity(entity) checkFunc = externvalue(0, "placeSpawnpoint"); + return checkFunc(targetEntity); +} + +void +obituary(string A, string B, string C, string D) +{ + void(string, string, string, string) checkFunc = externvalue(0, "obituary"); + checkFunc(A,B,C,D); +} + +void +damage(entity targetEntity, entity inflictingEntity, entity attackingEntity, int damagePoints, int damageFlags, string meansOfDeath, string weaponDef, vector damageOrigin, vector damageDir, string hitLocation, float timeOffset) +{ + +} + +/** @} */ // end of multiprogs \ No newline at end of file diff --git a/src/server/mapC_math.h b/src/server/mapC_math.h index f68e2e26..af1dabad 100644 --- a/src/server/mapC_math.h +++ b/src/server/mapC_math.h @@ -18,5 +18,4 @@ @brief Server-side plugin wrappers for math related functions. */ -#include "../shared/math.h" -#include "../shared/math_vector.h" \ No newline at end of file +#include "../shared/math.h" \ No newline at end of file diff --git a/src/server/mapcycle.qc b/src/server/mapcycle.qc index d9f44391..599b7b9e 100644 --- a/src/server/mapcycle.qc +++ b/src/server/mapcycle.qc @@ -32,7 +32,7 @@ Mapcycle_Load(string filename) /* read the lines in, see if the map exists and define an enumerated alias */ while ((temp = fgets(fs_mapcycle))) { - if (FileExists(strcat("maps/", temp, ".bsp")) == false) + if (fileExists(strcat("maps/", temp, ".bsp")) == false) continue; localcmd(sprintf("alias m%i \"map %s;alias nextmap m%i\"\n", mapCount, temp, mapCount + 1i)); diff --git a/src/server/maptweaks.qc b/src/server/maptweaks.qc index 52aa4e9e..a9eba526 100644 --- a/src/server/maptweaks.qc +++ b/src/server/maptweaks.qc @@ -162,11 +162,8 @@ MapTweak_Check(int num) static bool MapTweak_FinishSpawn(entity targetEntity, string newClassname) { - entity oldSelf = self; - self = targetEntity; - /* found the edef alternative. */ - if (EntityDef_SpawnClassname(newClassname) != __NULL__) { + if (EntityDef_SwitchClass(targetEntity, newClassname) != __NULL__) { return (true); } @@ -181,7 +178,7 @@ MapTweak_EntitySpawn(entity targetEntity) if (g_mapTweakCount <= 0) { return (false); } - + for (int i = 0; i < g_mapTweakCount; i++) { int segments = tokenize(g_mapTweakTable[i].itemTable); @@ -202,4 +199,4 @@ MapTweak_EntitySpawn(entity targetEntity) } return (false); -} \ No newline at end of file +} diff --git a/src/server/scripts.h b/src/server/scripts.h new file mode 100644 index 00000000..bf7c1497 --- /dev/null +++ b/src/server/scripts.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Vera Visions LLC. + * + * 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. +*/ + +void MapC_Init(void); + +void MapC_CallMainFunction(void); + +void MapC_CallNamedFunction(entity, string); + +bool RuleC_CallFunc(float, entity, string); + +bool RuleC_CallDamage(float, entity, entity, entity, string, string); + +bool RuleC_CallRequestSpawn(float, entity, string); + +bool RuleC_CallString(float, entity, string, string); + +bool RuleC_CallFloat(float, entity, float, string); diff --git a/src/server/scripts.qc b/src/server/scripts.qc index 97f349a5..5127e21b 100644 --- a/src/server/scripts.qc +++ b/src/server/scripts.qc @@ -14,6 +14,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/* Map specific Scripting, nicknamed 'MapC' after TF2's cancelled system */ var float g_mapCProgs; void MapC_Init(void) @@ -24,7 +25,7 @@ MapC_Init(void) mapProgs = sprintf("maps/%s.dat", cvar_string("mapname")); /* No mapname.dat, exit out */ - if (FileExists(mapProgs) == false) { + if (fileExists(mapProgs) == false) { NSError("MapC for level %s at %S does not exist.", mapname, mapProgs); return; } @@ -61,4 +62,110 @@ MapC_CallNamedFunction(entity functionActivator, string targetFunction) } } -/* Sends an input to the specified target. */ \ No newline at end of file +/* Gamerule specific Scripting, nicknamed 'RuleC'. */ +bool +RuleC_CallFunc(float progsNum, entity pl, string funcName) +{ + if (progsNum) { + void(void) mainFunction; + mainFunction = externvalue(progsNum, funcName); + + if (mainFunction) { + entity oldSelf = self; + //externset(progsNum, pl, "self"); + self = pl; + mainFunction(); + self = oldSelf; + return (true); + } + } + + return (false); +} + +bool +RuleC_CallDamage(float progsNum, entity target, entity inflictor, entity attacker, string weapon, string funcName) +{ + if (progsNum) { + void(entity inflictor, entity attacker, string weapon) mainFunction; + mainFunction = externvalue(progsNum, funcName); + + if (mainFunction) { + entity oldSelf = self; + externset(progsNum, target, "self"); + self = target; + mainFunction(inflictor, attacker, weapon); + self = oldSelf; + forceinfokey(target, "*deaths", ftos(target.deaths)); + return (true); + } + } + + return (false); +} + +bool +RuleC_CallRequestSpawn(float progsNum, entity pl, string funcName) +{ + bool returnValue = false; + + if (progsNum) { + bool(void) mainFunction; + mainFunction = externvalue(progsNum, funcName); + + if (mainFunction) { + entity oldSelf = self; + externset(progsNum, pl, "self"); + self = pl; + returnValue = mainFunction(); + self = oldSelf; + return (returnValue); + } + } + + return (returnValue); +} + +bool +RuleC_CallString(float progsNum, entity pl, string targetString, string funcName) +{ + bool returnValue = false; + + if (progsNum) { + bool(string) mainFunction; + mainFunction = externvalue(progsNum, funcName); + + if (mainFunction) { + entity oldSelf = self; + externset(progsNum, pl, "self"); + self = pl; + returnValue = mainFunction(targetString); + self = oldSelf; + return (returnValue); + } + } + + return (returnValue); +} + +bool +RuleC_CallFloat(float progsNum, entity pl, float targetFloat, string funcName) +{ + bool returnValue = false; + + if (progsNum) { + bool(float) mainFunction; + mainFunction = externvalue(progsNum, funcName); + + if (mainFunction) { + entity oldSelf = self; + externset(progsNum, pl, "self"); + self = pl; + returnValue = mainFunction(targetFloat); + self = oldSelf; + return (returnValue); + } + } + + return (returnValue); +} diff --git a/src/server/skill.qc b/src/server/skill.qc index a8ccc337..ffe06746 100644 --- a/src/server/skill.qc +++ b/src/server/skill.qc @@ -31,7 +31,7 @@ Skill_Init(void) Skill_ParseConfig("cfg/skill_manifest.cfg"); - if (FileExists(mapSkillFile)) { + if (fileExists(mapSkillFile)) { Skill_ParseConfig(mapSkillFile); } } @@ -48,10 +48,17 @@ Skill_GetValue(string variable, float defaultValue) { float skill = cvar("skill"); - if (skill == 0) + if (skill == 0) { skill = 2; /* default to medium */ + } float val = fabs(cvar(sprintf("sk_%s%d", variable, skill))); + + /* specific skill variable doesn't exist? */ + if (val == 0) { + val = fabs(cvar(sprintf("sk_%s", variable))); + } + return (val == 0) ? defaultValue : val; } @@ -60,11 +67,18 @@ Skill_GetStringValue(string variable, string defaultValue) { float skill = cvar("skill"); - if (skill == 0) + if (skill == 0) { skill = 2; /* default to medium */ + } string val = cvar_string(sprintf("sk_%s%d", variable, skill)); - return (val == 0) ? defaultValue : val; + + /* specific skill variable doesn't exist? */ + if (val == 0) { + val = cvar_string(sprintf("sk_%s", variable)); + } + + return (val == "") ? defaultValue : val; } bool @@ -85,6 +99,9 @@ Skill_ParseConfig(string fileName) if (argCount == 2i) { if (firstArg == "exec") { Skill_ParseConfig(sprintf("cfg/%s", argv(1))); + } else { + /* some games, like Source, don't use set/seta */ + cvar_set(argv(0), argv(1)); } } else if (argCount == 3i) { if (firstArg == "set" || firstArg == "seta") @@ -94,4 +111,4 @@ Skill_ParseConfig(string fileName) fclose(configFile); return (true); -} \ No newline at end of file +} diff --git a/src/server/vote.qc b/src/server/vote.qc index 6bc9a7a9..20cc8bab 100644 --- a/src/server/vote.qc +++ b/src/server/vote.qc @@ -246,7 +246,7 @@ CSEv_CallVote_s(string text) tokenize(text); switch (argv(0)) { case "map": - if (FileExists(sprintf("maps/%s.bsp", argv(1))) == false) { + if (fileExists(sprintf("maps/%s.bsp", argv(1))) == false) { sprint(self, PRINT_CHAT, sprintf("Map '%s' not available on server.\n", argv(1))); break; } diff --git a/src/shared/NSClientPlayer.h b/src/shared/NSClientPlayer.h index 25e08fd3..24fc3245 100644 --- a/src/shared/NSClientPlayer.h +++ b/src/shared/NSClientPlayer.h @@ -93,6 +93,7 @@ public: /* overrides */ virtual void Save(float); virtual void Restore(string,string); + virtual void Spawned(void); virtual void Respawn(void); virtual void EvaluateEntity(void); virtual float SendEntity(entity,float); @@ -218,3 +219,7 @@ enumflags PLAYER_WEAPONFRAME, PLAYER_CUSTOMFIELDSTART, }; + +#ifdef SERVER +void obituary(string, string, string, string); +#endif diff --git a/src/shared/NSClientPlayer.qc b/src/shared/NSClientPlayer.qc index 79242a40..6f7633d8 100644 --- a/src/shared/NSClientPlayer.qc +++ b/src/shared/NSClientPlayer.qc @@ -28,7 +28,7 @@ NSWeapon GetWeaponEntity(int theclientsnumber) if (wasfreed(e)) e = world; //might have been freed... - return e; + return e; } void @@ -44,6 +44,17 @@ NSClientPlayer::SharedInputFrame(void) if (input_cursor_entitynumber) { NSWeapon nextWeapon = GetWeaponEntity(input_cursor_entitynumber); + /* inpur_cursor_entity is not ours! */ + if (nextWeapon.owner != this) { + return; + } + + if (nextWeapon.IsWeapon() == false) { + return; + } + + input_cursor_entitynumber = 0; + if (nextWeapon != m_activeWeapon) { if (nextWeapon && HasExactItem(nextWeapon)) { m_activeWeapon = nextWeapon; @@ -117,8 +128,10 @@ NSClientPlayer::PreFrame(void) NSItem itemEntry = m_itemList; while (itemEntry) { - itemEntry.PredictPreFrame(); - itemEntry = (NSItem)itemEntry.chain; + if (itemEntry.PredictPreFrame) { + itemEntry.PredictPreFrame(); + } + itemEntry = (NSItem)itemEntry.m_nextItem; } if (vehicle) { @@ -165,8 +178,10 @@ NSClientPlayer::PostFrame(void) NSItem itemEntry = m_itemList; while (itemEntry) { - itemEntry.PredictPostFrame(); - itemEntry = (NSItem)itemEntry.chain; + if (itemEntry.PredictPostFrame) { + itemEntry.PredictPostFrame(); + } + itemEntry = (NSItem)itemEntry.m_nextItem; } setorigin(this, origin); /* update bounds */ @@ -216,7 +231,7 @@ NSClientPlayer::ProcessInput(void) /* handle use button presses */ if (input_buttons & INPUT_USE) - InputUse_Down(); + InputUse_Down(); else InputUse_Up(); @@ -235,7 +250,7 @@ NSClientPlayer::ProcessInput(void) /* can't fire when dead, sorry. */ if (health <= 0) canfire = false; - + if (canfire == false) { if (m_activeWeapon) { m_activeWeapon.Release(); @@ -244,6 +259,10 @@ NSClientPlayer::ProcessInput(void) return; } + if (wasfreed(m_activeWeapon)) { + m_activeWeapon = __NULL__; + } + if (!m_activeWeapon) { return; } @@ -439,8 +458,8 @@ NSClientPlayer::VehicleRelink(void) if (m_activeWeapon != __NULL__ && oldWeapon == __NULL__) { m_activeWeapon.SetOwner(this); - m_activeWeapon._SwitchedToCallback(); m_activeWeapon._AddedCallback(); + m_activeWeapon._SwitchedToCallback(); } } @@ -537,7 +556,7 @@ This is basically CSQC_Input_Frame! So games can override this as they please. */ void NSClientPlayer::ClientInputFrame(void) -{ +{ if (Util_IsPaused()) return; @@ -580,8 +599,9 @@ NSClientPlayer::ClientInputFrame(void) input_buttons |= INPUT_JUMP; } - if (pSeat->m_iHUDWeaponSelected) + if (pSeat->m_iHUDWeaponSelected) { input_cursor_entitynumber = pSeat->m_iHUDWeaponSelected; + } /* IW style stance override */ if (pSeat->m_dForceStance == STANCE_CROUCH) { @@ -678,6 +698,9 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged) if (new) { classname = "player"; + mins = g_pmoveVars.GetStandingMins(); + maxs = g_pmoveVars.GetStandingMaxs(); + Physics_SetViewParms(); } READENTITY_INT(modelindex, PLAYER_MODELINDEX) @@ -691,6 +714,9 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged) READENTITY_FLOAT(m_vecRenderColor[2], PLAYER_MODELINDEX) READENTITY_FLOAT(m_flRenderAmt, PLAYER_MODELINDEX) + READENTITY_ENTNUM(m_flFirstInventoryItem, PLAYER_ITEMS) + READENTITY_ENTNUM(activeweapon, PLAYER_WEAPON) + READENTITY_COORD(origin[0], PLAYER_ORIGIN) READENTITY_COORD(origin[1], PLAYER_ORIGIN) READENTITY_COORD(origin[2], PLAYER_ORIGIN) @@ -713,8 +739,6 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged) READENTITY_INT(vv_flags, PLAYER_FLAGS) READENTITY_INT(gflags, PLAYER_FLAGS) READENTITY_INT(pmove_flags, PLAYER_FLAGS) - READENTITY_ENTNUM(m_flFirstInventoryItem, PLAYER_ITEMS) - READENTITY_ENTNUM(activeweapon, PLAYER_WEAPON) READENTITY_BYTE(weaponframe, PLAYER_WEAPONFRAME) READENTITY_BYTE(health, PLAYER_HEALTH) READENTITY_BYTE(armor, PLAYER_HEALTH) @@ -746,36 +770,25 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged) READENTITY_INT(m_iAmmoTypes[i], PLAYER_AMMOTYPES) } + if (flChanged & PLAYER_SIZE) { + setsize(this, mins, maxs); + } + + if (pSeat->m_ePlayer != this) { + return; + } + #ifdef VALVE if (flChanged & PLAYER_AMMOTYPES) { HUD_AmmoNotify_Check(this); } #endif - /* the entities might not be networked yet, - so by tracking desired entnums and updating - them every time they change is sensible. */ - if (flChanged & PLAYER_VEHICLE) { - vehicle = __NULL__; - } - if (flChanged & PLAYER_WEAPON) { - m_activeWeapon = __NULL__; - } - - if (flChanged & PLAYER_ITEMS) { - m_itemList = __NULL__; - } - - /* only do as often as necessary */ - if ((vehicle_entnum && !vehicle) || (m_flFirstInventoryItem && !m_itemList) || (activeweapon && !m_activeWeapon)) - VehicleRelink(); + VehicleRelink(); PredictPreFrame(); - if (flChanged & PLAYER_SIZE) - setsize(this, mins, maxs); - Relink(); if (flChanged & PLAYER_SPECTATE) { @@ -796,13 +809,18 @@ void NSClientPlayer::PredictPreFrame(void) { if (m_activeWeapon) - m_activeWeapon.PredictPreFrame(); + if (m_activeWeapon.PredictPreFrame) + m_activeWeapon.PredictPreFrame(); SAVE_STATE(modelindex) + SAVE_STATE(colormap) + SAVE_STATE(m_iRenderMode) + SAVE_STATE(m_iRenderFX) + SAVE_STATE(m_vecRenderColor) + SAVE_STATE(m_flRenderAmt) SAVE_STATE(origin) SAVE_STATE(v_angle) SAVE_STATE(angles) - SAVE_STATE(colormap) SAVE_STATE(velocity) SAVE_STATE(basevelocity) SAVE_STATE(grapvelocity) @@ -811,9 +829,8 @@ NSClientPlayer::PredictPreFrame(void) SAVE_STATE(gflags) SAVE_STATE(pmove_flags) SAVE_STATE(m_itemList) - SAVE_STATE(m_activeWeapon) + SAVE_STATE(activeweapon) SAVE_STATE(weaponframe) - SAVE_STATE(g_items) SAVE_STATE(health) SAVE_STATE(armor) SAVE_STATE(mins) @@ -834,6 +851,9 @@ NSClientPlayer::PredictPreFrame(void) SAVE_STATE(spec_mode) SAVE_STATE(spec_flags) + SAVE_STATE(m_itemList) + SAVE_STATE(m_activeWeapon) + for (int i = 0i; i < MAX_AMMO_TYPES; i++) { m_iAmmoTypes_net[i] = m_iAmmoTypes[i]; } @@ -853,10 +873,14 @@ void NSClientPlayer::PredictPostFrame(void) { ROLL_BACK(modelindex) + ROLL_BACK(colormap) + ROLL_BACK(m_iRenderMode) + ROLL_BACK(m_iRenderFX) + ROLL_BACK(m_vecRenderColor) + ROLL_BACK(m_flRenderAmt) ROLL_BACK(origin) ROLL_BACK(v_angle) ROLL_BACK(angles) - ROLL_BACK(colormap) ROLL_BACK(velocity) ROLL_BACK(basevelocity) ROLL_BACK(grapvelocity) @@ -865,9 +889,8 @@ NSClientPlayer::PredictPostFrame(void) ROLL_BACK(gflags) ROLL_BACK(pmove_flags) ROLL_BACK(m_itemList) - ROLL_BACK(m_activeWeapon) + ROLL_BACK(activeweapon) ROLL_BACK(weaponframe) - ROLL_BACK(g_items) ROLL_BACK(health) ROLL_BACK(armor) ROLL_BACK(mins) @@ -888,12 +911,19 @@ NSClientPlayer::PredictPostFrame(void) ROLL_BACK(spec_mode) ROLL_BACK(spec_flags) + ROLL_BACK(m_itemList) + ROLL_BACK(m_activeWeapon) + + VehicleRelink(); + for (int i = 0i; i < MAX_AMMO_TYPES; i++) { m_iAmmoTypes[i] = m_iAmmoTypes_net[i]; } if (m_activeWeapon) { - m_activeWeapon.PredictPostFrame(); + if (m_activeWeapon.PredictPostFrame) { + m_activeWeapon.PredictPostFrame(); + } } } #else @@ -1054,7 +1084,7 @@ NSClientPlayer::Respawn(void) /* ================= NSClientPlayer::MakeTempSpectator - + This is what dead players in round matches become, or when we spawn for the first time before selecting a loadout or something. ================= @@ -1067,7 +1097,7 @@ NSClientPlayer::MakeTempSpectator(void) SetModelindex(0); SetSolid(SOLID_NOT); SetMovetype(MOVETYPE_NOCLIP); - SetTakedamage(DAMAGE_NO); + MakeInvulnerable(); maxspeed = 250; AddVFlags(VFL_FAKESPEC); max_health = health = 0; @@ -1094,34 +1124,24 @@ NSClientPlayer::MakeTempSpectator(void) /* ================= NSClientPlayer::MakeDead - + Sets all the appropriate attributes to make sure we're dead ================= */ void NSClientPlayer::Death(entity inflictor, entity attacker, int damage, vector dir, int location) { + RemoveAllItems(false); classname = "player"; health = max_health = 0; armor = 0; g_items = 0; - - if (m_activeWeapon) { - m_activeWeapon.Destroy(); - m_activeWeapon = __NULL__; - } - - if (m_itemList) { - m_itemList.Destroy(); - m_itemList = __NULL__; - } - effects = 0; alpha = 1.0f; SetModelindex(0); SetMovetype(MOVETYPE_NONE); SetSolid(SOLID_NOT); - SetTakedamage(DAMAGE_NO); + MakeInvulnerable(); viewzoom = 1.0; view_ofs = [0,0,0]; vehicle = __NULL__; @@ -1136,10 +1156,17 @@ NSClientPlayer::Death(entity inflictor, entity attacker, int damage, vector dir, m_flDeathTime = time; } +void +NSClientPlayer::Spawned(void) +{ + super::Spawned(); + MakePlayer(); +} + /* ================= NSClientPlayer::MakePlayer - + True participating player, can walk around and everything. ================= */ @@ -1159,16 +1186,18 @@ NSClientPlayer::MakePlayer(void) alpha = 1.0f; SetSolid(SOLID_SLIDEBOX); SetMovetype(MOVETYPE_WALK); - SetTakedamage(DAMAGE_YES); - SetVelocity([0,0,0]); + MakeVulnerable(); + SetSize(VEC_HULL_MIN, VEC_HULL_MAX); + ClearVelocity(); viewzoom = 1.0; vehicle = __NULL__; SetGravity(1.0f); SendFlags = UPDATE_ALL; customphysics = Empty; EnableBleeding(); - scale = 1.0f; - SetSize(VEC_HULL_MIN, VEC_HULL_MAX); + SetScale(1.0f); + Physics_SetViewParms(); + SetSize(g_pmoveVars.GetStandingMins(), g_pmoveVars.GetStandingMaxs()); forceinfokey(this, "*spectator", "0"); forceinfokey(this, "*deaths", ftos(deaths)); forceinfokey(this, "*dead", "0"); @@ -1181,7 +1210,7 @@ NSClientPlayer::MakeSpectator(void) ClientKill(); MakeTempSpectator(); team = 0; - forceinfokey(this, "*team", ftos(team)); + forceinfokey(this, "*team", ftos(team)); } /* @@ -1200,15 +1229,12 @@ NSClientPlayer::EvaluateEntity(void) EVALUATE_FIELD(modelindex, PLAYER_MODELINDEX) EVALUATE_FIELD(colormap, PLAYER_MODELINDEX) - - /* crap the render mode updates in here */ EVALUATE_FIELD(m_iRenderMode, PLAYER_MODELINDEX) EVALUATE_FIELD(m_iRenderFX, PLAYER_MODELINDEX) EVALUATE_VECTOR(m_vecRenderColor, 0, PLAYER_MODELINDEX) EVALUATE_VECTOR(m_vecRenderColor, 1, PLAYER_MODELINDEX) EVALUATE_VECTOR(m_vecRenderColor, 2, PLAYER_MODELINDEX) EVALUATE_FIELD(m_flRenderAmt, PLAYER_MODELINDEX) - EVALUATE_VECTOR(origin, 0, PLAYER_ORIGIN) EVALUATE_VECTOR(origin, 1, PLAYER_ORIGIN) EVALUATE_VECTOR(origin, 2, PLAYER_ORIGIN) @@ -1299,6 +1325,9 @@ NSClientPlayer::SendEntity(entity ePEnt, float flChanged) SENDENTITY_FLOAT(m_vecRenderColor[2], PLAYER_MODELINDEX) SENDENTITY_FLOAT(m_flRenderAmt, PLAYER_MODELINDEX) + SENDENTITY_ENTITY(m_itemList, PLAYER_ITEMS) + SENDENTITY_ENTITY(m_activeWeapon, PLAYER_WEAPON) + SENDENTITY_COORD(origin[0], PLAYER_ORIGIN) SENDENTITY_COORD(origin[1], PLAYER_ORIGIN) SENDENTITY_COORD(origin[2], PLAYER_ORIGIN) @@ -1321,8 +1350,6 @@ NSClientPlayer::SendEntity(entity ePEnt, float flChanged) SENDENTITY_INT(vv_flags, PLAYER_FLAGS) SENDENTITY_INT(gflags, PLAYER_FLAGS) SENDENTITY_INT(pmove_flags, PLAYER_FLAGS) - SENDENTITY_ENTITY(m_itemList, PLAYER_ITEMS) - SENDENTITY_ENTITY(m_activeWeapon, PLAYER_WEAPON) SENDENTITY_BYTE(weaponframe, PLAYER_WEAPONFRAME) SENDENTITY_BYTE(health, PLAYER_HEALTH) SENDENTITY_BYTE(armor, PLAYER_HEALTH) @@ -1439,7 +1466,7 @@ NSClientPlayer::InputUse_Down(void) } else if (!(vv_flags & VFL_USE_RELEASED)) { return; } - + vector vecSource; entity eRad; bool found_use = false; @@ -1528,7 +1555,7 @@ NSClientPlayer::Footsteps_Update(void) StartSoundDef("Player.Wade", CHAN_BODY, true); step_time = time + 2.0f; return; - } else if (waterlevel == 3) { + } else if (waterlevel == 3) { StartSoundDef("Player.Swim", CHAN_BODY, true); step_time = time + 2.0f; return; @@ -1584,31 +1611,27 @@ void NSClientPlayer::Damage(entity inflictor, entity attacker, NSDict damageDecl, float damageScale, vector dmgDir, vector hitLocation) { #ifdef SERVER - super::Damage(inflictor, attacker, damageDecl, damageScale, dmgDir, hitLocation); - -#if 0 + float armorDamage = 0; bool isFriendlyFire = false; - - /* Damage */ - NSSurfacePropEntity eTarget = (NSSurfacePropEntity)t; + string damageString = ReadString(damageDecl.GetString("damage")); + float damagePoints = (float)rint(stof(damageString) * damageScale); + NSSurfacePropEntity ourAttacker = (NSSurfacePropEntity)attacker; /* sanity check */ - if (t.takedamage == DAMAGE_NO) + if (isAlive(this) == false) { return; - - /* for armor damage */ - float flArmor = 0; - float flNewDamage = 0; + } /* player god mode */ - if (eTarget.flags & FL_CLIENT && eTarget.flags & FL_GODMODE) + if (damageDecl.GetBool("noGod") == false && isGodMode(this)) { return; + } /* friendly fire check */ - if (t != c) { - if (IsTeamplay()) { - if (t.flags & FL_CLIENT && c.flags & FL_CLIENT) { - if (t.team == c.team) { + if (this != attacker) { + if (g_grMode.IsTeamplay()) { + if (flags & FL_CLIENT && attacker.flags & FL_CLIENT) { + if (team == attacker.team) { if (autocvar_sv_friendlyFire == false) { return; } else { @@ -1620,66 +1643,61 @@ NSClientPlayer::Damage(entity inflictor, entity attacker, NSDict damageDecl, flo } /* already dead, please avoid recursion */ - if (eTarget.GetHealth() <= 0) + if (GetHealth() <= 0) { return; + } - /* before any calculation is done... */ - g_dmg_iRealDamage = dmg; + /* don't allow any damage */ + if (g_grMode.PlayerCanAttack(this) == false) { + return; + } - /* only clients have armor */ - if (eTarget.flags & FL_CLIENT) { - NSClientPlayer tp = (NSClientPlayer)t; + /* skip armor */ + if (damageDecl.GetBool("noArmor") == false) { + if (armor && damagePoints > 0) { + float postArmorDamage = 0; + float armorRatio = GetDefFloat("armorProtection"); + float armorBonus = GetDefFloat("armorBonus"); - /* don't allow any damage */ - if (PlayerCanAttack(tp) == false) { - g_dmg_eAttacker = (NSEntity)c; - g_dmg_eTarget = (NSEntity)t; - g_dmg_iDamage = 0; - g_dmg_iHitBody = 0; - g_dmg_iFlags = type; - g_dmg_iWeapon = w; - return; - } - - /* skip armor */ - if not (type & DMG_SKIP_ARMOR) - if (tp.armor && dmg > 0) { - - flNewDamage = dmg * 0.2; - flArmor = (dmg - flNewDamage) * 0.5; - - if (flArmor > tp.armor) { - flArmor = tp.armor; - flArmor *= (1/0.5); - flNewDamage = dmg - flArmor; - tp.armor = 0; - } else { - tp.armor -= flArmor; + /* amount of damage the armor absorbs */ + if (armorRatio <= 0.0) { + armorRatio = 0.2; } - dmg = flNewDamage; + + /* armor point cost for health point */ + if (armorBonus <= 0.0) { + armorBonus = 1.0; + } + + /* damage to be applied to health value */ + postArmorDamage = (damagePoints * armorRatio); + + /* figure out how much to deduct from armor. */ + armorDamage = (damagePoints - postArmorDamage) * armorBonus; + + /* to-deduct value exceeds armor value */ + if (armorDamage > armor) { + /* armor points left will cushion whatever damage they can */ + armorDamage = armor * (1.0 / armorBonus); + armor = 0; + postArmorDamage = (damagePoints - armorDamage); + } else { + armor -= armorDamage; + } + + damagePoints = postArmorDamage; } } - dmg = rint(dmg); - eTarget.SetHealth(eTarget.GetHealth() - dmg); - - /* the globals... */ - g_dmg_eAttacker = (NSEntity)c; - g_dmg_eTarget = (NSEntity)t; - g_dmg_iDamage = dmg; - g_dmg_iHitBody = trace_surface_id; - g_dmg_iFlags = type; - g_dmg_iWeapon = w; - - NSLog("%S does %d dmg to %S (body: %d, flags: %i, weapon: %i)", - c.classname, dmg, t.classname, g_dmg_iHitBody, g_dmg_iFlags, g_dmg_iWeapon); + damagePoints = rint(damagePoints); + SetHealth(GetHealth() - damagePoints); /* friendly fire penalty */ if (isFriendlyFire) { int lastDmg = 0i; - NSClientPlayer plC = (NSClientPlayer)c; + NSClientPlayer plC = (NSClientPlayer)attacker; lastDmg = plC.m_iFriendlyDMG; - plC.m_iFriendlyDMG += dmg; + plC.m_iFriendlyDMG += damagePoints; /* kick the client. */ if (plC.m_iFriendlyDMG >= autocvar_mp_td_dmgToKick) { @@ -1692,13 +1710,13 @@ NSClientPlayer::Damage(entity inflictor, entity attacker, NSDict damageDecl, flo } } - bprint(PRINT_CHAT, sprintf("%s ^7attacked a teammate.\n", c.netname)); + bprint(PRINT_CHAT, sprintf("%s ^7attacked a teammate.\n", attacker.netname)); } - if (dmg > 0 || flArmor > 0) { + if (damagePoints > 0 || armorDamage > 0) { vector dmg_origin; - if (c.origin == [0,0,0]) + if (attacker.origin == [0,0,0]) dmg_origin = g_dmg_eTarget.origin; else dmg_origin = g_dmg_eAttacker.origin; @@ -1708,7 +1726,7 @@ NSClientPlayer::Damage(entity inflictor, entity attacker, NSDict damageDecl, flo WriteCoord(MSG_MULTICAST, dmg_origin[0]); WriteCoord(MSG_MULTICAST, dmg_origin[1]); WriteCoord(MSG_MULTICAST, dmg_origin[2]); - WriteInt(MSG_MULTICAST, g_dmg_iRealDamage); + WriteInt(MSG_MULTICAST, damagePoints); WriteInt(MSG_MULTICAST, g_dmg_iFlags); msg_entity = g_dmg_eTarget; multicast([0,0,0], MULTICAST_ONE_R); @@ -1720,25 +1738,28 @@ NSClientPlayer::Damage(entity inflictor, entity attacker, NSDict damageDecl, flo if ((g_dmg_eAttacker.flags & FL_CLIENT) && (g_dmg_eTarget != g_dmg_eAttacker)) { WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); WriteByte(MSG_MULTICAST, EV_HITNOTIFY); - msg_entity = c; + msg_entity = attacker; multicast([0,0,0], MULTICAST_ONE); } } + damageDecl.AddKey("location", vtos(hitLocation)); + /* they died */ - if (eTarget.GetHealth() <= 0) { - if (eTarget.flags & FL_CLIENT) { - PlayerDeath(eTarget); - } else { - eTarget.Death(); - } + if (GetHealth() <= 0) { + g_grMode.PlayerDeath(this, attacker, damageDecl); + Death(inflictor, attacker, (int)damagePoints, dmgDir, 0i); } else { - if (eTarget.flags & FL_CLIENT) { - PlayerPain(eTarget); - } else { - eTarget.Pain(); - } + g_grMode.PlayerPain(this, attacker, damageDecl); + Pain(inflictor, attacker, (int)damagePoints, dmgDir, 0i); } #endif +} + +#ifdef SERVER +void +obituary(string targetName, string attackerName, string weaponDef, string meansOfDeath) +{ + +} #endif -} \ No newline at end of file diff --git a/src/shared/NSEntity.h b/src/shared/NSEntity.h index a62b8f79..773f5255 100644 --- a/src/shared/NSEntity.h +++ b/src/shared/NSEntity.h @@ -76,9 +76,6 @@ public: virtual void SpawnKey(string,string); virtual void Spawned(void); - /** Handles what happens before the entity gets removed from the client game. */ - virtual void OnRemoveEntity(void); - /** Tells the engine to make the entity static, effectively making it inaccessible. It will be removed from the game-logic but remain visible and it will retain its collision and maintain the appearance it had before getting removed. */ @@ -291,8 +288,6 @@ public: /** When called it'll make the entity uninteractable (but not destroy it). It will hide it, as well as remove any collision associated with it. */ nonvirtual void Disappear(void); - /** When called, will remove the entity from the game entirely. */ - nonvirtual void Destroy(void); /** Call this if you want to update bounding boxes to take angles into account. */ nonvirtual void UpdateBounds(void); diff --git a/src/shared/NSEntity.qc b/src/shared/NSEntity.qc index 034fc925..0a58af9f 100644 --- a/src/shared/NSEntity.qc +++ b/src/shared/NSEntity.qc @@ -48,7 +48,7 @@ NSEntity::Spawned(void) } /* used to network our shared ID */ - entityDefID = EntityDef_IDFromName(classname); + entityDefID = EntityDef_NetIDFromName(classname); #endif } @@ -1141,26 +1141,6 @@ NSEntity::SpawnKey(string strKey, string strValue) } } -void -NSEntity::OnRemoveEntity(void) -{ -} - -void -NSEntity::Destroy(void) -{ - removed = 1; /* mark this as cleanly removed */ - OnRemoveEntity(); - customphysics = __NULL__; - modelindex = 0; - solid = 0; - movetype = 0; - classname = 0; - think = __NULL__; - nextthink = 0.0f; - remove(this); -} - void NSEntity::Show(void) { @@ -1497,6 +1477,14 @@ spawnClass(string className, vector desiredPos) return (newEntity); } +#ifdef SERVER +bool +changeClass(entity target, string className) +{ + return EntityDef_SwitchClass((NSEntity)target, className) ? (true) : (false); +} +#endif + void sendInput(entity target, string inputName, string dataString, entity activator) { @@ -1572,8 +1560,46 @@ bool isBot(entity entityToCheck) { #ifdef SERVER - return (clienttype(self) == CLIENTTYPE_BOT) ? (true) : (false); + return (clienttype(entityToCheck) == CLIENTTYPE_BOT) ? (true) : (false); #else return (false); #endif } + + +#ifdef SERVER +void +setUserInfo(entity clientEntity, string serverKey, string setValue) +{ + if (isClient(clientEntity)) { + NSClient client = (NSClient) clientEntity; + client.SetInfoKey(serverKey, setValue); + } +} + +string +getUserInfo(entity clientEntity, string serverKey) +{ + if (isClient(clientEntity)) { + NSClient client = (NSClient) clientEntity; + return client.GetInfoKey(serverKey); + } +} +#endif + +void +placeSpawnpoint(entity target) +{ + vector testorg = target.origin; + + for (int i = 0; i < 32; i++) { + tracebox(testorg, target.mins, target.maxs, testorg, MOVE_NORMAL, target); + + if (!trace_startsolid) { + setorigin(target, testorg); + break; + } + + testorg[2] += 1.0; + } +} diff --git a/src/shared/NSIO.h b/src/shared/NSIO.h index 5577d3df..602b1b4d 100644 --- a/src/shared/NSIO.h +++ b/src/shared/NSIO.h @@ -70,6 +70,11 @@ public: /** Like GetDefVector, but queries a specified def, falling back to reading from our own if it's not defined. */ nonvirtual vector GetSubDefVector(string, string); + /** When called, will remove the entity from the game entirely. */ + nonvirtual void Destroy(void); + /** Handles what happens before the entity gets removed from the client game. */ + virtual void OnRemoveEntity(void); + #ifdef SERVER /** Handles saving a copy of this entity to a given filehandle. Within you want to use the NSIO::SaveFloat() etc. methods to write diff --git a/src/shared/NSIO.qc b/src/shared/NSIO.qc index e6d3a761..9e80945f 100644 --- a/src/shared/NSIO.qc +++ b/src/shared/NSIO.qc @@ -21,7 +21,7 @@ NSIO::NSIO(void) /* Not in Deathmatch */ if (spawnflags & 2048) { if (cvar("sv_playerslots") > 1) { - remove(this); + Destroy(); return; } } @@ -33,6 +33,8 @@ NSIO::NSIO(void) m_strOnUser3 = m_strOnUser4 = __NULL__; #else + owner = __NULL__; + chain = __NULL__; isCSQC = TRUE; effects |= EF_NOSHADOW; #endif @@ -59,6 +61,26 @@ NSIO::Spawned(void) #endif } +void +NSIO::OnRemoveEntity(void) +{ +} + +void +NSIO::Destroy(void) +{ + removed = 1; /* mark this as cleanly removed */ + OnRemoveEntity(); + customphysics = __NULL__; + modelindex = 0; + solid = 0; + movetype = 0; + classname = 0; + think = __NULL__; + nextthink = 0.0f; + remove(this); +} + float NSIO::GetDefAct(string keyName) { @@ -77,7 +99,7 @@ NSIO::GetDefAct(string keyName) string NSIO::GetDefString(string keyName) { - return EntityDef_GetKeyValue(classname, keyName); + return ReadString(EntityDef_GetKeyValue(declclass, keyName)); } vector @@ -109,12 +131,12 @@ NSIO::GetSubDefAct(string subDef, string keyName) { float actCount; string fireValue = GetSubDefString(subDef, keyName); - - /* not in className either. make it known */ - if (subDef == "") { + + /* not in classname either. make it known */ + if (fireValue == "") { return (-1); } - + actCount = tokenizebyseparator(fireValue, ","); if (actCount == 1) { @@ -128,11 +150,12 @@ NSIO::GetSubDefAct(string subDef, string keyName) string NSIO::GetSubDefString(string subDef, string keyName) { - string fireValue = EntityDef_GetKeyValue(subDef, keyName); + string fireDefString = EntityDef_GetKeyValue(subDef, keyName); + string fireValue = ReadString(fireDefString); /* if not in FireInfo, check classname Def */ if (fireValue == "") { - fireValue = EntityDef_GetKeyValue(classname, keyName); + fireValue = GetDefString(keyName); } return (fireValue); @@ -188,15 +211,7 @@ string NSIO::ReadString(string inputString) { if (inputString && inputString != "") { - -#ifdef SERVER - /* is this supposed to be read from a skill cvar? */ - if (substring(inputString, 0, 6) == "skill:") { - return Skill_GetStringValue(substring(inputString, 6, -1), ""); - } -#endif - - return Constants_LookUp(inputString, inputString); + return unpackStringCommand(inputString); } return ""; @@ -250,7 +265,7 @@ NSIO::GetSpawnString(string keyName) } } - return ReadString(EntityDef_GetKeyValue(classname, keyName)); + return ReadString(EntityDef_GetKeyValue(declclass, keyName)); } vector diff --git a/src/shared/NSItem.h b/src/shared/NSItem.h index 64978a61..1b462727 100644 --- a/src/shared/NSItem.h +++ b/src/shared/NSItem.h @@ -113,6 +113,7 @@ public: #endif virtual bool IsWeapon(void); + virtual bool InInventory(void); private: /** Called to signal that the owner added this weapon to their inventory. */ @@ -146,6 +147,7 @@ private: NETWORKED_FLOAT(owner_entnum) #endif - entity chain_net; + NSItem m_nextItem; + NSItem m_nextItem_net; entity owner_net; }; diff --git a/src/shared/NSItem.qc b/src/shared/NSItem.qc index 17987376..91fd8a1d 100644 --- a/src/shared/NSItem.qc +++ b/src/shared/NSItem.qc @@ -17,7 +17,6 @@ void NSItem::NSItem(void) { -#ifdef SERVER m_iClip = -1; m_iWasDropped = 0i; m_iInvItem = 0i; @@ -30,7 +29,8 @@ NSItem::NSItem(void) m_bNoTouch = false; m_bInvCarry = false; m_strRequires = __NULL__; -#endif + m_nextItem = __NULL__; + owner = __NULL__; } #ifdef SERVER @@ -75,7 +75,12 @@ NSItem::SpawnKey(string strKey, string strValue) if (substring(strKey, 0, 8) == "inv_ammo") { string ammoType = substring(strKey, 4, -1); int ammoID = ammoNumForName(ammoType); - m_GiveAmmo[ammoID] = stoi(strValue); + + if (ammoID != -1) { + m_GiveAmmo[ammoID] = stoi(unpackStringCommand(strValue)); + } else { + NSError("Item %S tries to give invalid ammo type %S", declclass, ammoType); + } return; } @@ -315,45 +320,47 @@ NSItem::BecomePickup(void) float NSItem::SendEntity(entity ePEnt, float flChanged) { + /* item is in somebody elses inventory. */ + if (InInventory() == true && ePEnt != GetOwner()) { + return (false); + } + WriteByte(MSG_ENTITY, ENT_ITEM); /* broadcast how much data is expected to be read */ WriteFloat(MSG_ENTITY, flChanged); - if (1) { - SENDENTITY_COORD(origin[0], ITEMFL_CHANGED_ORIGIN_X) - SENDENTITY_COORD(origin[1], ITEMFL_CHANGED_ORIGIN_Y) - SENDENTITY_COORD(origin[2], ITEMFL_CHANGED_ORIGIN_Z) - SENDENTITY_ANGLE(angles[0], ITEMFL_CHANGED_ANGLES_X) - SENDENTITY_ANGLE(angles[1], ITEMFL_CHANGED_ANGLES_Y) - SENDENTITY_ANGLE(angles[2], ITEMFL_CHANGED_ANGLES_Z) - SENDENTITY_SHORT(entityDefID, ITEMFL_CHANGED_MODELINDEX) - SENDENTITY_SHORT(modelindex, ITEMFL_CHANGED_MODELINDEX) - SENDENTITY_BYTE(solid, ITEMFL_CHANGED_SOLID) - SENDENTITY_BYTE(movetype, ITEMFL_CHANGED_FLAGS) - SENDENTITY_INT(flags, ITEMFL_CHANGED_FLAGS) - SENDENTITY_INT(vv_flags, ITEMFL_CHANGED_FLAGS) - SENDENTITY_COORD(mins[0], ITEMFL_CHANGED_SIZE) - SENDENTITY_COORD(mins[1], ITEMFL_CHANGED_SIZE) - SENDENTITY_COORD(mins[2], ITEMFL_CHANGED_SIZE) - SENDENTITY_COORD(maxs[0], ITEMFL_CHANGED_SIZE) - SENDENTITY_COORD(maxs[1], ITEMFL_CHANGED_SIZE) - SENDENTITY_COORD(maxs[2], ITEMFL_CHANGED_SIZE) - SENDENTITY_BYTE(frame, ITEMFL_CHANGED_FRAME) - SENDENTITY_FLOAT(skin, ITEMFL_CHANGED_SKIN) - SENDENTITY_FLOAT(effects, ITEMFL_CHANGED_EFFECTS) - SENDENTITY_FLOAT(scale, ITEMFL_CHANGED_SCALE) - SENDENTITY_COORD(velocity[0], ITEMFL_CHANGED_VELOCITY_X) - SENDENTITY_COORD(velocity[1], ITEMFL_CHANGED_VELOCITY_Y) - SENDENTITY_COORD(velocity[2], ITEMFL_CHANGED_VELOCITY_Z) - SENDENTITY_COORD(avelocity[0], ITEMFL_CHANGED_ANGULARVELOCITY) - SENDENTITY_COORD(avelocity[1], ITEMFL_CHANGED_ANGULARVELOCITY) - SENDENTITY_COORD(avelocity[2], ITEMFL_CHANGED_ANGULARVELOCITY) - SENDENTITY_ENTITY(chain, ITEMFL_CHANGED_CHAIN) - SENDENTITY_ENTITY(owner, ITEMFL_CHANGED_CHAIN) - } else { - /* the item is in the inventory */ - } + SENDENTITY_ENTITY(m_nextItem, ITEMFL_CHANGED_CHAIN) + SENDENTITY_ENTITY(owner, ITEMFL_CHANGED_CHAIN) + SENDENTITY_COORD(origin[0], ITEMFL_CHANGED_ORIGIN_X) + SENDENTITY_COORD(origin[1], ITEMFL_CHANGED_ORIGIN_Y) + SENDENTITY_COORD(origin[2], ITEMFL_CHANGED_ORIGIN_Z) + SENDENTITY_ANGLE(angles[0], ITEMFL_CHANGED_ANGLES_X) + SENDENTITY_ANGLE(angles[1], ITEMFL_CHANGED_ANGLES_Y) + SENDENTITY_ANGLE(angles[2], ITEMFL_CHANGED_ANGLES_Z) + SENDENTITY_FLOAT(entityDefID, ITEMFL_CHANGED_MODELINDEX) + SENDENTITY_SHORT(modelindex, ITEMFL_CHANGED_MODELINDEX) + SENDENTITY_BYTE(solid, ITEMFL_CHANGED_SOLID) + SENDENTITY_BYTE(movetype, ITEMFL_CHANGED_FLAGS) + SENDENTITY_INT(flags, ITEMFL_CHANGED_FLAGS) + SENDENTITY_INT(modelflags, ITEMFL_CHANGED_FLAGS) + SENDENTITY_INT(vv_flags, ITEMFL_CHANGED_FLAGS) + SENDENTITY_COORD(mins[0], ITEMFL_CHANGED_SIZE) + SENDENTITY_COORD(mins[1], ITEMFL_CHANGED_SIZE) + SENDENTITY_COORD(mins[2], ITEMFL_CHANGED_SIZE) + SENDENTITY_COORD(maxs[0], ITEMFL_CHANGED_SIZE) + SENDENTITY_COORD(maxs[1], ITEMFL_CHANGED_SIZE) + SENDENTITY_COORD(maxs[2], ITEMFL_CHANGED_SIZE) + SENDENTITY_BYTE(frame, ITEMFL_CHANGED_FRAME) + SENDENTITY_FLOAT(skin, ITEMFL_CHANGED_SKIN) + SENDENTITY_FLOAT(effects, ITEMFL_CHANGED_EFFECTS) + SENDENTITY_FLOAT(scale, ITEMFL_CHANGED_SCALE) + SENDENTITY_COORD(velocity[0], ITEMFL_CHANGED_VELOCITY_X) + SENDENTITY_COORD(velocity[1], ITEMFL_CHANGED_VELOCITY_Y) + SENDENTITY_COORD(velocity[2], ITEMFL_CHANGED_VELOCITY_Z) + SENDENTITY_COORD(avelocity[0], ITEMFL_CHANGED_ANGULARVELOCITY) + SENDENTITY_COORD(avelocity[1], ITEMFL_CHANGED_ANGULARVELOCITY) + SENDENTITY_COORD(avelocity[2], ITEMFL_CHANGED_ANGULARVELOCITY) return (1); } @@ -361,6 +368,8 @@ NSItem::SendEntity(entity ePEnt, float flChanged) void NSItem::EvaluateEntity(void) { + EVALUATE_FIELD(m_nextItem, ITEMFL_CHANGED_CHAIN) + EVALUATE_FIELD(owner, ITEMFL_CHANGED_CHAIN) EVALUATE_VECTOR(origin, 0, ITEMFL_CHANGED_ORIGIN_X) EVALUATE_VECTOR(origin, 1, ITEMFL_CHANGED_ORIGIN_Y) EVALUATE_VECTOR(origin, 2, ITEMFL_CHANGED_ORIGIN_Z) @@ -368,9 +377,11 @@ NSItem::EvaluateEntity(void) EVALUATE_VECTOR(angles, 1, ITEMFL_CHANGED_ANGLES_Y) EVALUATE_VECTOR(angles, 2, ITEMFL_CHANGED_ANGLES_Z) EVALUATE_FIELD(modelindex, ITEMFL_CHANGED_MODELINDEX) + EVALUATE_FIELD(entityDefID, ITEMFL_CHANGED_MODELINDEX) EVALUATE_FIELD(solid, BASEFL_CHANGED_MODELINDEX) EVALUATE_FIELD(movetype, ITEMFL_CHANGED_FLAGS) EVALUATE_FIELD(flags, ITEMFL_CHANGED_FLAGS) + EVALUATE_FIELD(modelflags, ITEMFL_CHANGED_FLAGS) EVALUATE_FIELD(vv_flags, ITEMFL_CHANGED_FLAGS) EVALUATE_VECTOR(mins, 0, ITEMFL_CHANGED_SIZE) EVALUATE_VECTOR(mins, 1, ITEMFL_CHANGED_SIZE) @@ -388,8 +399,6 @@ NSItem::EvaluateEntity(void) EVALUATE_VECTOR(avelocity, 0, ITEMFL_CHANGED_ANGULARVELOCITY) EVALUATE_VECTOR(avelocity, 1, ITEMFL_CHANGED_ANGULARVELOCITY) EVALUATE_VECTOR(avelocity, 2, ITEMFL_CHANGED_ANGULARVELOCITY) - EVALUATE_FIELD(chain, ITEMFL_CHANGED_CHAIN) - EVALUATE_FIELD(owner, ITEMFL_CHANGED_CHAIN) } #endif @@ -397,17 +406,20 @@ NSItem::EvaluateEntity(void) void NSItem::ReceiveEntity(float flNew, float flChanged) { + READENTITY_ENTNUM(chain_entnum, ITEMFL_CHANGED_CHAIN) + READENTITY_ENTNUM(owner_entnum, ITEMFL_CHANGED_CHAIN) READENTITY_COORD(origin[0], ITEMFL_CHANGED_ORIGIN_X) READENTITY_COORD(origin[1], ITEMFL_CHANGED_ORIGIN_Y) READENTITY_COORD(origin[2], ITEMFL_CHANGED_ORIGIN_Z) READENTITY_ANGLE(angles[0], ITEMFL_CHANGED_ANGLES_X) READENTITY_ANGLE(angles[1], ITEMFL_CHANGED_ANGLES_Y) READENTITY_ANGLE(angles[2], ITEMFL_CHANGED_ANGLES_Z) - READENTITY_SHORT(entityDefID, ITEMFL_CHANGED_MODELINDEX) + READENTITY_FLOAT(entityDefID, ITEMFL_CHANGED_MODELINDEX) READENTITY_SHORT(modelindex, ITEMFL_CHANGED_MODELINDEX) READENTITY_BYTE(solid, ITEMFL_CHANGED_SOLID) READENTITY_BYTE(movetype, ITEMFL_CHANGED_FLAGS) READENTITY_INT(flags, ITEMFL_CHANGED_FLAGS) + READENTITY_INT(modelflags, ITEMFL_CHANGED_FLAGS) READENTITY_INT(vv_flags, ITEMFL_CHANGED_FLAGS) READENTITY_COORD(mins[0], ITEMFL_CHANGED_SIZE) READENTITY_COORD(mins[1], ITEMFL_CHANGED_SIZE) @@ -425,24 +437,25 @@ NSItem::ReceiveEntity(float flNew, float flChanged) READENTITY_COORD(avelocity[0], ITEMFL_CHANGED_ANGULARVELOCITY) READENTITY_COORD(avelocity[1], ITEMFL_CHANGED_ANGULARVELOCITY) READENTITY_COORD(avelocity[2], ITEMFL_CHANGED_ANGULARVELOCITY) - READENTITY_ENTNUM(chain_entnum, ITEMFL_CHANGED_CHAIN) - READENTITY_ENTNUM(owner_entnum, ITEMFL_CHANGED_CHAIN) if (flChanged & ITEMFL_CHANGED_MODELINDEX) { - classname = EntityDef_NameFromID(entityDefID); + classname = EntityDef_NameFromNetID(entityDefID); + declclass = classname; } drawmask = (modelindex != 0) ? MASK_ENGINE : 0; if (flChanged & ITEMFL_CHANGED_CHAIN) { - chain = __NULL__; + m_nextItem = __NULL__; } - if (scale == 0.0f) + if (scale == 0.0f) { scale = 1.0f; + } - if (flChanged & ITEMFL_CHANGED_SIZE) - setsize(this, mins, maxs); + if (flChanged & ITEMFL_CHANGED_SIZE || flChanged & ITEMFL_CHANGED_ORIGIN_X || flChanged & ITEMFL_CHANGED_ORIGIN_Y || flChanged & ITEMFL_CHANGED_ORIGIN_Z) { + Relink(); + } } void @@ -453,14 +466,18 @@ NSItem::ReceiveEvent(float eventType) void NSItem::PredictPreFrame(void) { + if (wasfreed(this)) { + return; + } + /* relink */ - if (chain == __NULL__ && chain_entnum) - chain = findentity(world, ::entnum, chain_entnum); + if (m_nextItem == __NULL__ && chain_entnum) + m_nextItem = findentity(world, ::entnum, chain_entnum); if (owner == __NULL__ && owner_entnum) { owner = findentity(world, ::entnum, owner_entnum); - if (owner) { + if (owner && owner == pSeat->m_ePlayer) { _AddedCallback(); } } @@ -477,7 +494,7 @@ NSItem::PredictPreFrame(void) SAVE_STATE(velocity) SAVE_STATE(avelocity) SAVE_STATE(owner) - SAVE_STATE(chain) + SAVE_STATE(m_nextItem) } void @@ -495,7 +512,7 @@ NSItem::PredictPostFrame(void) ROLL_BACK(velocity) ROLL_BACK(avelocity) ROLL_BACK(owner) - ROLL_BACK(chain) + ROLL_BACK(m_nextItem) } #endif @@ -507,9 +524,12 @@ NSItem::AddedToInventory(void) void NSItem::RemovedFromInventory(void) { -#ifdef SERVER - //BecomePickup(); -#endif +} + +bool +NSItem::InInventory(void) +{ + return (owner) ? (true) : (false); } bool @@ -522,36 +542,38 @@ NSItem::IsWeapon(void) void NSItem::_AddedCallback(void) { + NSActor ourOwner = (NSActor)owner; + #ifdef SERVER - NSActor pl = (NSActor)owner; if (m_iGiveHealth > 0i) { - if (pl.GetHealth() < 100) { + if (ourOwner.GetHealth() < 100) { //Damage_Apply(pl, this, -m_iGiveHealth, 0, DMG_GENERIC); - pl.health = bound(0, pl.health + m_iGiveHealth, pl.max_health); + ourOwner.health = bound(0, ourOwner.health + m_iGiveHealth, ourOwner.max_health); } } if (m_iGiveArmor > 0i) { - if (pl.armor < 100) { - pl.armor += (float)m_iGiveArmor; + if (ourOwner.armor < 100) { + ourOwner.armor += (float)m_iGiveArmor; - if (pl.armor > 100) { - pl.armor = 100; + if (ourOwner.armor > 100) { + ourOwner.armor = 100; } } } for (int i = 0; i < MAX_AMMO_TYPES; i++) { - pl.GiveAmmo(i, m_GiveAmmo[i]); + ourOwner.GiveAmmo(i, m_GiveAmmo[i]); } - Logging_Pickup(pl, this, __NULL__); - pl.StartSoundDef(m_sndAcquire, CHAN_ITEM, true); + Logging_Pickup(ourOwner, this, __NULL__); + ourOwner.StartSoundDef(m_sndAcquire, CHAN_ITEM, true); OnPickup(); Disappear(); #endif + ourOwner.AddedItemCallback(this); AddedToInventory(); } @@ -559,4 +581,8 @@ void NSItem::_RemovedCallback(void) { RemovedFromInventory(); + owner = __NULL__; + chain = __NULL__; + m_nextItem = __NULL__; + Destroy(); } diff --git a/src/shared/NSMonster.qc b/src/shared/NSMonster.qc index 7e89e856..32fec875 100644 --- a/src/shared/NSMonster.qc +++ b/src/shared/NSMonster.qc @@ -508,7 +508,7 @@ NSMonster::Gib(void) { vector vecDir = vectorToAngles(GetOrigin() - g_dmg_vecLocation); SetState(MONSTER_DEAD); - SetTakedamage(DAMAGE_NO); + MakeInvulnerable(); string breakModel = GetPropData(PROPINFO_BREAKMODEL); BreakModel_Spawn(absmin, absmax, vecDir, g_dmg_iDamage * 2.5f, vlen(size) / 10, breakModel); @@ -1805,7 +1805,8 @@ NSMonster::Respawn(void) RestoreAngles(); v_angle = fixAngle(GetAngles()); AddFlags(FL_MONSTER); - SetTakedamage(DAMAGE_AIM); + MakeVulnerable(); + EnableAimAssist(); SetState(MONSTER_IDLE); SetHealth(GetSpawnFloat("health")); m_eEnemy = __NULL__; diff --git a/src/shared/NSNavAI.h b/src/shared/NSNavAI.h index a7af6e3a..bf9b86b8 100644 --- a/src/shared/NSNavAI.h +++ b/src/shared/NSNavAI.h @@ -124,11 +124,15 @@ public: /** Retrieve the 'last' weapon they had chosen. If not valid, returns the next best. */ nonvirtual NSWeapon GetLastWeapon(void); + virtual void AddedItemCallback(NSItem); + #ifdef SERVER /* overrides */ virtual void Save(float); virtual void Restore(string,string); virtual void RestoreComplete(void); + virtual void Spawned(void); + virtual void Input(entity, string, string); virtual void DebugDraw(void); /* methods we'd like others to override */ @@ -180,12 +184,15 @@ private: /* These are defined in side defs\*.def, ammo_types and ammo_names */ int m_iAmmoTypes[MAX_AMMO_TYPES]; - NSItem m_itemList; - NSWeapon m_activeWeapon; NSWeapon m_activeWeapon_net; float activeweapon; - float m_flFirstInventoryItem; + NETWORKED_FLOAT(m_flFirstInventoryItem) }; +/* for now here to make debugging easier */ +.NSItem m_itemList; +.NSWeapon m_activeWeapon; +.NSWeapon m_firstWeapon; + void NSActor_ListInventory(NSActor); diff --git a/src/shared/NSNavAI.qc b/src/shared/NSNavAI.qc index eadcbc5c..10851148 100644 --- a/src/shared/NSNavAI.qc +++ b/src/shared/NSNavAI.qc @@ -24,10 +24,12 @@ NSActor::NSActor(void) m_vecLastNode = [0,0,0]; m_vecTurnAngle = [0,0,0]; m_flMoveSpeedKey = 0.0f; - + _m_flRouteGiveUp = 0.0f; #endif + m_itemList = __NULL__; + for (int i = 0; i < MAX_AMMO_TYPES; i++) { m_iAmmoTypes[i] = 0; } @@ -142,6 +144,63 @@ NSActor::Restore(string strKey, string strValue) } } +void +NSActor::Spawned(void) +{ + super::Spawned(); + + /* let's not waste time and resources */ + if (wasfreed(this)) { + return; + } + + /* start ammo */ + for (int i = 0; i < MAX_AMMO_TYPES; i++) { + string defKey = ammoNameForNum(i); + + if (defKey != "") { + int defValue = GetDefInt(defKey); + EntLog("Giving %S some %i units of %S", classname, defValue, defKey); + GiveAmmo(i, defValue); + } + } + + /* give them their inventory */ + string weaponList = GetDefString("weapon"); + string itemList = GetDefString("item"); + int desiredWeapon = GetDefInt("current_weapon"); + string switchTo = ""; + int weaponCount = tokenizebyseparator(weaponList, ","); + + /* append items to the end */ + if (itemList != "") { + weaponList = sprintf("%s,%s", weaponList, itemList); + } + + for (int i = 0; i < weaponCount; i++) { + string itemName = argv(i); + GiveItem(itemName); + + if (i == desiredWeapon) { + switchTo = itemName; + } + + /* re-calculate because GiveItem may overwrite argv() */ + weaponCount = tokenizebyseparator(weaponList, ","); + } + + if (switchTo != "") { + SwitchToWeapon(switchTo); + } + + /* give them their desired appearance */ + string spawnModel = GetSpawnString("model"); + + if (spawnModel != "") { + SetModel(GetSpawnString("model")); + } +} + void NSActor::RestoreComplete(void) { @@ -152,6 +211,27 @@ NSActor::RestoreComplete(void) /* re-plot our route */ RouteToPosition(m_vecLastNode); } + +void +NSActor::Input(entity eAct, string strInput, string strData) +{ + switch (strInput) { + case "GiveItem": + GiveItem(strData); + break; + case "GiveAmmo": + tokenize_console(strData); + int ammoNum = ammoNumForName(argv(0)); + int ammoCount = stoi(argv(1)); + + if (ammoNum != -1i) { + GiveAmmo(ammoNum, ammoCount); + } + break; + default: + super::Input(eAct, strInput, strData); + } +} #endif @@ -518,6 +598,7 @@ NSActor::LaunchProjectile(string defName, bool thrown, float timeOfs) throwingStrength = bound(0, (90 - throwDirection[0]) * 5.0f, 1000); + nade.SetWeaponOwner(m_activeWeapon); nade.Launch(GetEyePos(), GetViewAngle(), time - timeOfs, 0.0f, 0.0f); makevectors(throwDirection); nade.SetVelocity((v_forward * throwingStrength) + GetVelocity()); @@ -584,7 +665,13 @@ NSActor::GiveAmmo(int ammoType, int ammoAmount) if (ammoType <= 0i || ammoType >= MAX_AMMO_TYPES) return (false); - maxAmmo = ammoMaxForNum(ammoType); + /* read max ammo from entityDef decl first */ + maxAmmo = GetDefInt(sprintf("max_%s", ammoNameForNum(ammoType))); + + /* default when above is 0 */ + if (!maxAmmo) { + maxAmmo = ammoMaxForNum(ammoType); + } /* already at max-ammo? */ if (m_iAmmoTypes[ammoType] >= maxAmmo) @@ -652,7 +739,7 @@ NSActor::HasExactItem(NSItem itemEntity) return (true); } - linkedList = (NSItem)linkedList.chain; + linkedList = (NSItem)linkedList.m_nextItem; } return (false); @@ -679,12 +766,24 @@ NSActor::HasItem(string itemName) return (true); } - linkedList = (NSItem)linkedList.chain; + linkedList = (NSItem)linkedList.m_nextItem; } return (false); } +void +NSActor::AddedItemCallback(NSItem itemAdded) +{ +#ifdef SERVER + if (!m_activeWeapon) { + if (itemAdded.IsWeapon()) { + SwitchToExactWeapon(itemAdded); + } + } +#endif +} + bool NSActor::GiveItem(string itemName) { @@ -707,11 +806,6 @@ NSActor::GiveItem(string itemName) m_itemList._AddedCallback(); //NSLog("First Item %S", m_itemList.classname); - /* we have no active weapon, and this is our pick */ - if (!m_activeWeapon) { - SwitchToExactWeapon((NSWeapon)m_itemList); - } - return (true); } @@ -727,7 +821,7 @@ NSActor::GiveItem(string itemName) } lastItem = linkedList; - linkedList = (NSItem)linkedList.chain; + linkedList = (NSItem)linkedList.m_nextItem; } /* add it to the back of the chain, so it's part of our inventory. */ @@ -740,7 +834,7 @@ NSActor::GiveItem(string itemName) } newItem.SetOwner(this); - lastItem.chain = newItem; + lastItem.m_nextItem = newItem; linkedList = newItem; newItem._AddedCallback(); } @@ -787,7 +881,7 @@ NSActor::SwitchToBestWeapon(bool ignoreActive) float weight; if (toIgnore == weaponName) { - linkedList = (NSItem)linkedList.chain; + linkedList = (NSItem)linkedList.m_nextItem; continue; } @@ -799,11 +893,13 @@ NSActor::SwitchToBestWeapon(bool ignoreActive) } } - linkedList = (NSItem)linkedList.chain; + linkedList = (NSItem)linkedList.m_nextItem; } if (bestWeapon) { - SwitchToExactWeapon((NSWeapon)bestWeapon); + if (bestWeapon != m_activeWeapon) { + SwitchToExactWeapon((NSWeapon)bestWeapon); + } } } @@ -837,24 +933,30 @@ NSActor::RemoveItem(string itemName) removeItem = true; frontItem = lastItem; /* the one before the current one */ itemToRemove = linkedList; /* the item to destroy */ + break; } lastItem = linkedList; - linkedList = (NSItem)linkedList.chain; + linkedList = (NSItem)linkedList.m_nextItem; } /* successfully remove the last item */ if (removeItem == true) { /* we had an item in front, bridge across the removed item. */ if (frontItem) { - frontItem.chain = (NSItem)itemToRemove.chain; + frontItem.m_nextItem = (NSItem)itemToRemove.m_nextItem; } else { /* this was the first item. set to chain (can be NULL) */ - m_itemList = (NSItem)itemToRemove.chain; + m_itemList = (NSItem)itemToRemove.m_nextItem; + } + + /* is this our active weapon? */ + if (m_activeWeapon == linkedList) { + m_activeWeapon._SwitchedFromCallback(); + m_activeWeapon = __NULL__; } itemToRemove._RemovedCallback(); - //itemToRemove.Destroy(); return (true); } #endif @@ -877,19 +979,18 @@ NSActor::RemoveAllItems(bool ignoreWeapons) /* iterate through the inventory, then figure out if we already have it*/ while (linkedList) { - NSItem nextItem = (NSItem)linkedList.chain; + NSItem nextItem = (NSItem)linkedList.m_nextItem; /* respect weapon filter */ if (!(ignoreWeapons && linkedList.IsWeapon() == true)) { - linkedList._RemovedCallback(); - linkedList.Destroy(); - - /* is this our active weapon? */ + /* is this our active weapon? give it a chance to do work first */ if (m_activeWeapon == linkedList) { m_activeWeapon._SwitchedFromCallback(); m_activeWeapon = __NULL__; } + RemoveItem(linkedList.classname); + linkedList = nextItem; continue; } @@ -914,19 +1015,16 @@ NSActor::RemoveAllWeapons(void) /* iterate through the inventory, then figure out if we already have it*/ while (linkedList) { - NSItem nextItem = (NSItem)linkedList.chain; + NSItem nextItem = (NSItem)linkedList.m_nextItem; - /* respect weapon filter */ if (linkedList.IsWeapon() == true) { - linkedList._RemovedCallback(); - linkedList.Destroy(); - - /* is this our active weapon? */ + /* is this our active weapon? give it a chance to do work first */ if (m_activeWeapon == linkedList) { m_activeWeapon._SwitchedFromCallback(); m_activeWeapon = __NULL__; } + linkedList._RemovedCallback(); continue; } @@ -966,7 +1064,7 @@ NSActor::SwitchToWeapon(string weaponName) SwitchToExactWeapon((NSWeapon)linkedList); } - linkedList = (NSItem)linkedList.chain; + linkedList = (NSItem)linkedList.m_nextItem; } } @@ -1005,9 +1103,18 @@ NSActor::SortWeaponChain(void) /* first we determine the range of our hud buckets. */ while (itemChain) { + + /* no longer in inventory */ + if (itemChain.owner != this) { + itemChain = (NSWeapon)itemChain.m_nextItem; + continue; + } + if (itemChain.IsWeapon() == true) { hudSlot = itemChain.GetDefInt("hudSlot"); hudPos = itemChain.GetDefInt("hudSlotPos"); + itemChain.m_nextWeapon = __NULL__; + itemChain.m_prevWeapon = __NULL__; if (hudSlot > heighestSlot) { heighestSlot = hudSlot; @@ -1017,7 +1124,7 @@ NSActor::SortWeaponChain(void) } } - itemChain = (NSWeapon)itemChain.chain; + itemChain = (NSWeapon)itemChain.m_nextItem; } for (int hS = 0i; hS <= heighestSlot; hS++) { @@ -1025,6 +1132,12 @@ NSActor::SortWeaponChain(void) itemChain = (NSWeapon)m_itemList; while (itemChain) { + /* no longer in inventory */ + if (itemChain.owner != this) { + itemChain = (NSWeapon)itemChain.m_nextItem; + continue; + } + if (itemChain.IsWeapon() == true) { hudSlot = itemChain.GetDefInt("hudSlot"); hudPos = itemChain.GetDefInt("hudSlotPos"); @@ -1043,7 +1156,7 @@ NSActor::SortWeaponChain(void) } } - itemChain = (NSWeapon)itemChain.chain; + itemChain = (NSWeapon)itemChain.m_nextItem; } } } @@ -1054,7 +1167,10 @@ NSActor::SortWeaponChain(void) weaponTest = weaponTest.m_nextWeapon; } - firstWeapon.m_prevWeapon = lastWeapon; + if (firstWeapon) { + firstWeapon.m_prevWeapon = lastWeapon; + m_firstWeapon = firstWeapon; + } return (firstWeapon); } @@ -1062,8 +1178,9 @@ NSActor::SortWeaponChain(void) bool NSWeapon_CanSwitch(NSActor pl) { - if (!pl.m_activeWeapon) + if (!pl.m_activeWeapon) { return false; + } return true; } @@ -1071,36 +1188,28 @@ NSWeapon_CanSwitch(NSActor pl) NSWeapon NSActor::GetNextWeapon(void) { - NSWeapon firstWeapon; - if (NSWeapon_CanSwitch(this) == false) { return (__NULL__); } - firstWeapon = SortWeaponChain(); - if (m_activeWeapon.m_nextWeapon) { return (m_activeWeapon.m_nextWeapon); } else { - return (firstWeapon); + return (m_firstWeapon); } } NSWeapon NSActor::GetPreviousWeapon(void) { - NSWeapon firstWeapon; - if (NSWeapon_CanSwitch(this) == false) { return (__NULL__); } - firstWeapon = SortWeaponChain(); - if (m_activeWeapon.m_prevWeapon) { return (m_activeWeapon.m_prevWeapon); } else { - return (firstWeapon); + return (m_firstWeapon); } } @@ -1121,8 +1230,8 @@ NSActor_ListInventory(NSActor targetEntity) printf("active weapon: %s (%d)\n", activeWeapon.classname, num_for_edict(activeWeapon)); while (itemEntry) { - printf("%i %s (%d) (owner: %d); next: %d\n", i, itemEntry.classname, num_for_edict(itemEntry), num_for_edict(itemEntry.owner), num_for_edict(itemEntry.chain)); - itemEntry = (NSItem)itemEntry.chain; + printf("%i %s (%d) (owner: %d); next: %d\n", i, itemEntry.classname, num_for_edict(itemEntry), num_for_edict(itemEntry.owner), num_for_edict(itemEntry.m_nextItem)); + itemEntry = (NSItem)itemEntry.m_nextItem; i += 1i; } } diff --git a/src/shared/NSPhysicsEntity.qc b/src/shared/NSPhysicsEntity.qc index 542281a5..680f3fb2 100644 --- a/src/shared/NSPhysicsEntity.qc +++ b/src/shared/NSPhysicsEntity.qc @@ -455,7 +455,7 @@ NSPhysicsEntity::_TouchThink(void) } } -#if 0 +#if 1 if (m_flCheckTime < time) { bool should if (vlen(m_vecPrevAngles - angles) < 1) { @@ -571,7 +571,7 @@ NSPhysicsEntity::Respawn(void) SetSolid(SOLID_BSP); #ifdef SERVER - SetTakedamage(DAMAGE_YES); + MakeVulnerable(); #endif Sleep(); diff --git a/src/shared/NSProjectile.h b/src/shared/NSProjectile.h index 948de82e..8125c495 100644 --- a/src/shared/NSProjectile.h +++ b/src/shared/NSProjectile.h @@ -87,6 +87,9 @@ public: nonvirtual void SetLightColor(vector); nonvirtual void SetLightRadius(float); + nonvirtual void SetWeaponOwner(NSWeapon); + nonvirtual NSWeapon GetWeaponOwner(void); + nonvirtual void EnableDetonateOnFuse(bool); nonvirtual void EnableDetonateOnDeath(bool); nonvirtual void EnableDetonateOnWorld(bool); @@ -154,6 +157,7 @@ private: vector m_vecSpawnMaxs; float m_flSpawnFrame; vector m_vecSpawnOrigin; + NSWeapon m_weaponOwner; /* ETQW-additions */ bool m_bIsBullet; @@ -186,7 +190,7 @@ private: }; #ifdef SERVER -NSProjectile NSProjectile_SpawnDef(string entityDef, NSEntity theOwner); -NSProjectile NSProjectile_SpawnDefAtPosition(string entityDef, NSEntity theOwner, vector vecOrigin, vector vecAngles); -NSProjectile NSProjectile_SpawnDefAttachment(string entityDef, NSEntity theOwner, int attachmentID); +NSProjectile NSProjectile_SpawnDef(string entityDef, NSActor theOwner); +NSProjectile NSProjectile_SpawnDefAtPosition(string entityDef, NSActor theOwner, vector vecOrigin, vector vecAngles); +NSProjectile NSProjectile_SpawnDefAttachment(string entityDef, NSActor theOwner, int attachmentID); #endif diff --git a/src/shared/NSProjectile.qc b/src/shared/NSProjectile.qc index 585398f8..ab5cc22d 100644 --- a/src/shared/NSProjectile.qc +++ b/src/shared/NSProjectile.qc @@ -508,7 +508,7 @@ NSProjectile::Touch(entity eToucher) NSSurfacePropEntity toucher = (NSSurfacePropEntity)eToucher; NSDict damageDecl = spawn(NSDict); damageDecl.AddKey("damage", GetSubDefString(m_defDamage, "damage")); - toucher.Damage(this, owner, damageDecl, m_flDmgMultiplier, vectorNormalize(angles), trace_endpos); + toucher.Damage(this, owner, damageDecl, m_flDmgMultiplier, vectorNormalize(angles), m_vecImpactPos); remove(damageDecl); } @@ -567,6 +567,18 @@ NSProjectile::SetLightRadius(float newRadius) m_flLightRadius = newRadius; } +void +NSProjectile::SetWeaponOwner(NSWeapon weaponOwner) +{ + m_weaponOwner = weaponOwner; +} + +NSWeapon +NSProjectile::GetWeaponOwner(void) +{ + return (m_weaponOwner); +} + void NSProjectile::EnableDetonateOnFuse(bool enabled) { @@ -724,12 +736,13 @@ NSProjectile::_Explode(entity explodedOn) float flDamage = GetSubDefFloat(m_defSplashDamage, "damage"); float flRadius = GetSubDefFloat(m_defSplashDamage, "radius"); - if (m_flDmgMultiplier >= 0.0) + if (m_flDmgMultiplier >= 0.0) { flDamage *= m_flDmgMultiplier; + } //print(sprintf("Damage: %d; Radius: %d\n", flDamage, flRadius)); //Damage_Radius(origin, owner, flDamage, flRadius, TRUE, 0); - radiusDamage(origin, flRadius, 0i, (int)flDamage, owner); + radiusDamage(GetOrigin(), flRadius, 0i, (int)flDamage, owner); } /* another def that'll be spawned when this one detonates */ @@ -796,10 +809,11 @@ NSProjectile::_ApplyDamage(void) trace_surface_id = m_iMultiBody; g_dmg_vecLocation = trace_endpos; NSDict damageDecl = spawn(NSDict); + damageDecl.AddKey("hitbody", itos(trace_surface_id)); damageDecl.AddKey("damage", itos(m_iMultiValue)); vector dmgDir = dirFromTarget(GetOrigin(), m_eMultiTarget.origin); - entityDamage(m_eMultiTarget, owner, owner, damageDecl.GetDeclBody(), classname, GetOrigin(), dmgDir, trace_endpos); + entityDamage(m_eMultiTarget, owner, owner, damageDecl.GetDeclBody(), GetWeaponOwner().classname, GetOrigin(), dmgDir, trace_endpos); remove(damageDecl); m_eMultiTarget = __NULL__; @@ -859,41 +873,13 @@ NSProjectile::_FireSingle(vector vecPos, vector vecAngles, float flDamage, float if (trace_ent.takedamage != DAMAGE_NO && trace_ent.iBleeds) { Sound_Play(trace_ent, CHAN_BODY, "damage_bullet.hit"); -#ifdef CSTRIKE - NSClientPlayer pl = (NSClientPlayer)trace_ent; - /* modify the damage based on the location */ - switch (trace_surface_id) { - case BODY_HEAD: - /* the helmet is one power house */ - if (pl.g_items & ITEM_HELMET) { - flDamage = 0; - Sound_Play(trace_ent, CHAN_BODY, "player.headshotarmor"); - pl.g_items &= ~ITEM_HELMET; - return; - } else { - flDamage *= 4; - Sound_Play(trace_ent, CHAN_BODY, "player.headshot"); - } - break; - case BODY_STOMACH: - flDamage *= 0.9; - if (pl.armor > 0) - Sound_Play(trace_ent, CHAN_BODY, "player.hitarmor"); - break; - case BODY_LEGLEFT: - case BODY_LEGRIGHT: - flDamage *= 0.4; - break; - } -#else /* only headshots count in HL */ if (trace_surface_id == BODY_HEAD) flDamage *= 3; -#endif } #ifdef WASTES - TWPlayer pl1 = (TWPlayer)self; + TWPlayer pl1 = (TWPlayer)owner; if (pl1.m_iWillpowerValue > 0) { FX_Crit(endPos, vectoangles(endPos - pl1.origin), 0); } @@ -1024,9 +1010,9 @@ NSProjectile::Launch(vector startPos, vector launchDir, float fuseOffset, float } if (GetHealth() > 0) { - SetTakedamage(DAMAGE_YES); + MakeVulnerable(); } else { - SetTakedamage(DAMAGE_NO); + MakeInvulnerable(); } if (m_flFuse > 0) { @@ -1151,7 +1137,7 @@ NSProjectile::predraw(void) #ifdef SERVER NSProjectile -NSProjectile_SpawnDef(string entityDef, NSEntity theOwner) +NSProjectile_SpawnDef(string entityDef, NSActor theOwner) { entity oldself = self; @@ -1160,13 +1146,13 @@ NSProjectile_SpawnDef(string entityDef, NSEntity theOwner) self = rocket; EntityDef_SpawnClassname(entityDef); self = oldself; - + rocket.SetWeaponOwner(theOwner.m_activeWeapon); rocket.Launch(theOwner.GetEyePos(), theOwner.GetViewAngle(), 0.0f, 0.0f, 0.0f); return rocket; } NSProjectile -NSProjectile_SpawnDefAtPosition(string entityDef, NSEntity theOwner, vector vecOrigin, vector vecAngles) +NSProjectile_SpawnDefAtPosition(string entityDef, NSActor theOwner, vector vecOrigin, vector vecAngles) { entity oldself = self; NSProjectile rocket = spawn(NSProjectile); @@ -1174,12 +1160,13 @@ NSProjectile_SpawnDefAtPosition(string entityDef, NSEntity theOwner, vector vecO self = rocket; EntityDef_SpawnClassname(entityDef); self = oldself; + rocket.SetWeaponOwner(theOwner.m_activeWeapon); rocket.Launch(vecOrigin, vecAngles, 0.0f, 0.0f, 0.0f); return rocket; } NSProjectile -NSProjectile_SpawnDefAttachment(string entityDef, NSEntity theOwner, int attachmentID) +NSProjectile_SpawnDefAttachment(string entityDef, NSActor theOwner, int attachmentID) { entity oldself = self; float skeletonIndex = skel_create(theOwner.modelindex); @@ -1191,6 +1178,7 @@ NSProjectile_SpawnDefAttachment(string entityDef, NSEntity theOwner, int attachm self = rocket; EntityDef_SpawnClassname(entityDef); self = oldself; + rocket.SetWeaponOwner(theOwner.m_activeWeapon); rocket.Launch(attachmentPos, theOwner.GetViewAngle(), 0.0f, 0.0f, 0.0f); return rocket; } diff --git a/src/shared/NSRenderableEntity.qc b/src/shared/NSRenderableEntity.qc index 1d4f7891..dbe54bf4 100644 --- a/src/shared/NSRenderableEntity.qc +++ b/src/shared/NSRenderableEntity.qc @@ -67,6 +67,10 @@ void NSRenderableEntity::_UpdateGeomset(void) void NSRenderableEntity::_UpdateBoneCount(void) { + if (!modelindex) { + return; + } + skeletonindex = skel_create(modelindex); m_iNumBones = skel_get_numbones(skeletonindex) + 1; //print(sprintf("UPDATED GEOMSET FOR MODELINDEX %d, %d BONES\n", modelindex, m_iNumBones)); @@ -163,10 +167,7 @@ NSRenderableEntity::EvaluateEntity(void) float NSRenderableEntity::SendEntity(entity ePEnt, float flChanged) { - if (!modelindex) - return (0); - - if (clienttype(ePEnt) != CLIENTTYPE_REAL) + if (!modelindex && solid == SOLID_NOT) return (0); WriteByte(MSG_ENTITY, ENT_ENTITYRENDERABLE); @@ -215,7 +216,7 @@ NSRenderableEntity::SendEntity(entity ePEnt, float flChanged) SENDENTITY_COORD(maxs[0], RDENT_CHANGED_SIZE) SENDENTITY_COORD(maxs[1], RDENT_CHANGED_SIZE) SENDENTITY_COORD(maxs[2], RDENT_CHANGED_SIZE) - SENDENTITY_BYTE(frame, RDENT_CHANGED_FRAME) + SENDENTITY_FLOAT(frame, RDENT_CHANGED_FRAME) SENDENTITY_FLOAT(frame1time, RDENT_CHANGED_FRAME) SENDENTITY_FLOAT(skin, RDENT_CHANGED_SKIN) SENDENTITY_FLOAT(effects, RDENT_CHANGED_EFFECTS) @@ -275,7 +276,7 @@ NSRenderableEntity::ReceiveEntity(float flNew, float flChanged) READENTITY_COORD(maxs[0], RDENT_CHANGED_SIZE) READENTITY_COORD(maxs[1], RDENT_CHANGED_SIZE) READENTITY_COORD(maxs[2], RDENT_CHANGED_SIZE) - READENTITY_BYTE(frame, RDENT_CHANGED_FRAME) + READENTITY_FLOAT(frame, RDENT_CHANGED_FRAME) READENTITY_FLOAT(frame1time, RDENT_CHANGED_FRAME) READENTITY_FLOAT(skin, RDENT_CHANGED_SKIN) READENTITY_FLOAT(effects, RDENT_CHANGED_EFFECTS) @@ -1026,7 +1027,7 @@ NSRenderableEntity::HandleAnimEvent(float flTimeStamp, int iCode, string strData tokenize(m_strModelEventCB); /* ensure argv() is 'rewound'... */ } } - + //print(sprintf("Received: %f %i %S\n", flTimeStamp, iCode, strData)); EntWarning("Unknown server model event: %f %i %S", flTimeStamp, iCode, strData); #else diff --git a/src/shared/NSSoundScape.qc b/src/shared/NSSoundScape.qc index 940abdd0..03966ca6 100644 --- a/src/shared/NSSoundScape.qc +++ b/src/shared/NSSoundScape.qc @@ -846,7 +846,7 @@ EFX_UpdateSoundScape(NSSoundScape scape) scape.SetupEFXReverb(&reverbInfo); setup_reverb(12, &reverbInfo, sizeof(reverbinfo_t)); - NSError("Updated sound scape (expensive) %f", reverbInfo.flDensity); + //NSError("Updated sound scape (expensive) %f", reverbInfo.flDensity); } void @@ -906,7 +906,7 @@ EFX_UpdateListener(NSView playerView) return; } - NSError("Soundscape changed to %v", bestScape.GetOrigin()); + //NSError("Soundscape changed to %v", bestScape.GetOrigin()); playerView.SetSoundScape(bestScape); EFX_UpdateSoundScape(bestScape); lastScape = bestScape; diff --git a/src/shared/NSSurfacePropEntity.h b/src/shared/NSSurfacePropEntity.h index a46859e1..f3b88b5e 100644 --- a/src/shared/NSSurfacePropEntity.h +++ b/src/shared/NSSurfacePropEntity.h @@ -114,8 +114,6 @@ public: nonvirtual void MakeVulnerable(void); /** Makes the entity invulnerable if it wasn't already. */ nonvirtual void MakeInvulnerable(void); - /** Deprecated: Sets whether the entity can take damage */ - nonvirtual void SetTakedamage(float); /** Sets the current health of the entity. */ nonvirtual void SetHealth(float); /** Sets the maximum amount of health the entity can have */ diff --git a/src/shared/NSSurfacePropEntity.qc b/src/shared/NSSurfacePropEntity.qc index 489834ac..9c66a9a6 100644 --- a/src/shared/NSSurfacePropEntity.qc +++ b/src/shared/NSSurfacePropEntity.qc @@ -77,9 +77,9 @@ NSSurfacePropEntity::IsAlive(void) } bool -NSSurfacePropEntity:: IsVulnerable(void) +NSSurfacePropEntity::IsVulnerable(void) { - return m_bTakesDamage; + return (m_bTakesDamage); } void @@ -142,12 +142,6 @@ NSSurfacePropEntity::CanBleed(void) return (iBleeds); } -void -NSSurfacePropEntity::SetTakedamage(float type) -{ - takedamage = type; -} - void NSSurfacePropEntity::SetHealth(float new_health) { @@ -437,6 +431,13 @@ NSSurfacePropEntity::Input(entity entityActivator, string inputName, string data case "Extinguish": Extinguish(); break; + case "Damage": + NSDict damageDecl = spawn(NSDict); + float damagePoints = stof(dataField); + damageDecl.AddKey("damage", dataField); + Damage(this, this, damageDecl, 1.0, g_vec_null, GetOrigin()); + remove(damageDecl); + break; default: super::Input(entityActivator, inputName, dataField); } @@ -831,6 +832,7 @@ entityDamage(entity targetEnt, entity inflictingEnt, entity attackingEnt, string } NSDict damageDecl = NSDict::InitWithSpawnData(damageDef); + damageDecl.AddKey("weapon", weaponDef); theTarget.Damage(inflictingEnt, attackingEnt, damageDecl, 1.0, damageDir, hitLocation); remove(damageDecl); #endif diff --git a/src/shared/NSTrigger.qc b/src/shared/NSTrigger.qc index 9e12dda1..7ee25365 100644 --- a/src/shared/NSTrigger.qc +++ b/src/shared/NSTrigger.qc @@ -325,6 +325,9 @@ NSTrigger::Input(entity eAct, string strInput, string strData) case "Toggle": m_bEnabled = (m_bEnabled) ? false : true; break; + case "SetTeam": + SetTeam(stof(strData)); + break; default: super:: Input(eAct, strInput, strData); } @@ -336,7 +339,7 @@ NSTrigger::SetTeam(float new_team) team = new_team; /* update the InfoKey too if it's a client entity */ - if (flags & FL_CLIENT) { + if (isClient(this)) { NSClient client = (NSClient)this; client.SetInfoKey("*team", sprintf("%d", new_team)); } diff --git a/src/shared/NSWeapon.h b/src/shared/NSWeapon.h index d39e0724..838dc9e9 100644 --- a/src/shared/NSWeapon.h +++ b/src/shared/NSWeapon.h @@ -19,9 +19,7 @@ typedef enumflags WEAPONFL_CHANGED_MODELINDEX, WEAPONFL_CHANGED_ORIGIN, WEAPONFL_CHANGED_ANGLES, - WEAPONFL_CHANGED_VELOCITY_X, - WEAPONFL_CHANGED_VELOCITY_Y, - WEAPONFL_CHANGED_VELOCITY_Z, + WEAPONFL_CHANGED_VELOCITY, WEAPONFL_CHANGED_ANGULARVELOCITY, WEAPONFL_CHANGED_SIZE, WEAPONFL_CHANGED_FLAGS, @@ -35,7 +33,9 @@ typedef enumflags WEAPONFL_CHANGED_ENTITYDEF, WEAPONFL_CHANGED_CLIP, WEAPONFL_CHANGED_CHAIN, - WEAPONFL_CHANGED_STATE + WEAPONFL_CHANGED_STATE, + WEAPONFL_CHANGED_NEXTWEAPON, + WEAPONFL_CHANGED_PREVWEAPON, } nsweapon_changed_t; typedef enum @@ -190,6 +190,7 @@ public: virtual void ReceiveEvent(float); #endif + virtual bool IsEmpty(void); virtual bool IsWeapon(void); virtual bool HasReserveAmmo(void); @@ -317,14 +318,17 @@ private: float m_flSpeedMod; bool m_bAltModeSwitch; - NSWeapon m_nextWeapon; - NSWeapon m_prevWeapon; + float m_nextWeapon_entnum; + float m_prevWeapon_entnum; + NSWeapon m_nextWeapon_net; + NSWeapon m_prevWeapon_net; /* cached fireInfo */ string m_fiDetonateOnFire; float m_fiMeleeRange; vector m_fiPunchAngle; string m_fiSndFire; + string m_fiSndFireLast; string m_fiSndRelease; string m_fiSndEmpty; int m_fiAmmoType; @@ -359,6 +363,9 @@ private: NETWORKED_BOOL(m_flOverheating) }; +.NSWeapon m_nextWeapon; +.NSWeapon m_prevWeapon; + /* Helper functions for plugins, the rest of the codebase etc. These are, according to IW, common operations. Makes sense to diff --git a/src/shared/NSWeapon.qc b/src/shared/NSWeapon.qc index 06ab61c0..abace5d5 100644 --- a/src/shared/NSWeapon.qc +++ b/src/shared/NSWeapon.qc @@ -33,7 +33,7 @@ NSWeapon::NSWeapon(void) m_bSmokeContinous = false; m_iClip = 0i; m_iClipSize = 0i; - m_iMode = 0i; + m_iMode = 0; m_viewModel = 0; m_worldModel = 0; m_playerModel = 0.0f; @@ -42,6 +42,8 @@ NSWeapon::NSWeapon(void) m_strLastFireInfo = __NULL__; m_flSpeedMod = 1.0f; m_flReloadSpeed = -1.0f; + m_nextWeapon = __NULL__; + m_prevWeapon = __NULL__; } void @@ -54,9 +56,16 @@ NSWeapon::_AddedCallback(void) return; } + _CacheWeaponDefVariables(); + /* after being stored in someones inventory, re-sort our inventory according to their logic */ ourOwner.SortWeaponChain(); + + /* we have no active weapon, and this is our pick */ + if (!ourOwner.m_activeWeapon) { + ourOwner.SwitchToExactWeapon(this); + } } void @@ -65,7 +74,9 @@ NSWeapon::_RemovedCallback(void) if (owner) { /* give the weapon a chance to clean up the owners inventory */ NSActor ourOwner = (NSActor)owner; + owner = __NULL__; ourOwner.SortWeaponChain(); + owner = ourOwner; } super::_RemovedCallback(); @@ -120,6 +131,7 @@ NSWeapon::UpdateFireInfoCache(void) m_fiMeleeRange = GetSubDefFloat(m_strLastFireInfo, "melee_distance"); m_fiPunchAngle = GetSubDefVector(m_strLastFireInfo, "punchAngle"); m_fiSndFire = GetSubDefString(m_strLastFireInfo, "snd_fire"); + m_fiSndFireLast = GetSubDefString(m_strLastFireInfo, "snd_fireLast"); m_fiSndRelease = GetSubDefString(m_strLastFireInfo, "snd_release"); m_fiSndEmpty = GetSubDefString(m_strLastFireInfo, "snd_empty"); m_fiAmmoType = ammoNumForName(GetSubDefString(m_strLastFireInfo, "ammoType")); @@ -154,14 +166,17 @@ NSWeapon::UpdateFireInfoCache(void) } #ifdef CLIENT - string viewGeomset = GetSubDefString(m_strLastFireInfo, "view_geomset"); - - if (viewGeomset) { - setcustomskin(pSeat->m_eViewModel, "", viewGeomset); - setcustomskin(pSeat->m_eViewModelL, "", viewGeomset); - } else { - setcustomskin(pSeat->m_eViewModel, "", ""); - setcustomskin(pSeat->m_eViewModelL, "", ""); + if (pSeat != __NULL__) { + string viewGeomset = GetSubDefString(m_strLastFireInfo, "view_geomset"); + if (pSeat->m_eViewModel) { + if (viewGeomset) { + setcustomskin(pSeat->m_eViewModel, "", viewGeomset); + setcustomskin(pSeat->m_eViewModelL, "", viewGeomset); + } else { + setcustomskin(pSeat->m_eViewModel, "", ""); + setcustomskin(pSeat->m_eViewModelL, "", ""); + } + } } #endif @@ -173,6 +188,15 @@ NSWeapon::UpdateFireInfoCache(void) NSError("m_flReloadSpeed: %f", m_flReloadSpeed); #endif + NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); + float zoomFov = GetSubDefFloat(m_strLastFireInfo, "zoomFov"); + + if (zoomFov > 0) { + ourOwner.viewzoom = zoomFov / cvar("fov"); + } else { + ourOwner.viewzoom = 1.0f; + } + /* validate */ if (ammoPerShot != __NULL__) { m_fiAmmoPerShot = (int)stoi(ammoPerShot); @@ -347,61 +371,68 @@ NSWeapon::Restore(string strKey, string strValue) float NSWeapon::SendEntity(entity ePEnt, float flChanged) { + /* item is in somebody elses inventory. */ + if (InInventory() == true && ePEnt != GetOwner()) { + return (false); + } + WriteByte(MSG_ENTITY, ENT_WEAPON); /* broadcast how much data is expected to be read */ WriteFloat(MSG_ENTITY, flChanged); + SENDENTITY_SHORT(modelindex, WEAPONFL_CHANGED_MODELINDEX) - - if (1) { - SENDENTITY_COORD(origin[0], WEAPONFL_CHANGED_ORIGIN) - SENDENTITY_COORD(origin[1], WEAPONFL_CHANGED_ORIGIN) - SENDENTITY_COORD(origin[2], WEAPONFL_CHANGED_ORIGIN) - SENDENTITY_ANGLE(angles[0], WEAPONFL_CHANGED_ANGLES) - SENDENTITY_ANGLE(angles[1], WEAPONFL_CHANGED_ANGLES) - SENDENTITY_ANGLE(angles[2], WEAPONFL_CHANGED_ANGLES) - SENDENTITY_SHORT(entityDefID, WEAPONFL_CHANGED_MODELINDEX) - SENDENTITY_SHORT(m_viewModel, WEAPONFL_CHANGED_MODELINDEX) - SENDENTITY_FLOAT(m_flFireRate, WEAPONFL_CHANGED_MODELINDEX) - SENDENTITY_BYTE(solid, WEAPONFL_CHANGED_SOLID) - SENDENTITY_BYTE(movetype, WEAPONFL_CHANGED_FLAGS) - SENDENTITY_INT(flags, WEAPONFL_CHANGED_FLAGS) - SENDENTITY_INT(vv_flags, WEAPONFL_CHANGED_FLAGS) - SENDENTITY_COORD(mins[0], WEAPONFL_CHANGED_SIZE) - SENDENTITY_COORD(mins[1], WEAPONFL_CHANGED_SIZE) - SENDENTITY_COORD(mins[2], WEAPONFL_CHANGED_SIZE) - SENDENTITY_COORD(maxs[0], WEAPONFL_CHANGED_SIZE) - SENDENTITY_COORD(maxs[1], WEAPONFL_CHANGED_SIZE) - SENDENTITY_COORD(maxs[2], WEAPONFL_CHANGED_SIZE) - SENDENTITY_BYTE(frame, WEAPONFL_CHANGED_FRAME) - SENDENTITY_FLOAT(skin, WEAPONFL_CHANGED_SKIN) - SENDENTITY_FLOAT(effects, WEAPONFL_CHANGED_EFFECTS) - SENDENTITY_SHORT(m_iBody, WEAPONFL_CHANGED_BODY) - SENDENTITY_FLOAT(scale, WEAPONFL_CHANGED_SCALE) - SENDENTITY_COORD(velocity[0], WEAPONFL_CHANGED_VELOCITY_X) - SENDENTITY_COORD(velocity[1], WEAPONFL_CHANGED_VELOCITY_Y) - SENDENTITY_COORD(velocity[2], WEAPONFL_CHANGED_VELOCITY_Z) - SENDENTITY_COORD(avelocity[0], WEAPONFL_CHANGED_ANGULARVELOCITY) - SENDENTITY_COORD(avelocity[1], WEAPONFL_CHANGED_ANGULARVELOCITY) - SENDENTITY_COORD(avelocity[2], WEAPONFL_CHANGED_ANGULARVELOCITY) - SENDENTITY_BYTE(m_iClip, WEAPONFL_CHANGED_CLIP) - SENDENTITY_BYTE(m_iClipSize, WEAPONFL_CHANGED_CLIP) - SENDENTITY_BYTE(m_iMode, WEAPONFL_CHANGED_CLIP) - SENDENTITY_ENTITY(chain, WEAPONFL_CHANGED_CHAIN) - SENDENTITY_ENTITY(owner, WEAPONFL_CHANGED_CHAIN) - SENDENTITY_BYTE(m_dState, WEAPONFL_CHANGED_STATE) - SENDENTITY_BYTE(m_bFiring, WEAPONFL_CHANGED_STATE) - SENDENTITY_FLOAT(m_flOverheating, WEAPONFL_CHANGED_STATE) - } else { - /* the item is in the inventory */ - } - + SENDENTITY_ENTITY(m_nextItem, WEAPONFL_CHANGED_CHAIN) + SENDENTITY_ENTITY(owner, WEAPONFL_CHANGED_CHAIN) + SENDENTITY_ENTITY(m_nextWeapon, WEAPONFL_CHANGED_NEXTWEAPON) + SENDENTITY_ENTITY(m_prevWeapon, WEAPONFL_CHANGED_PREVWEAPON) + SENDENTITY_COORD(origin[0], WEAPONFL_CHANGED_ORIGIN) + SENDENTITY_COORD(origin[1], WEAPONFL_CHANGED_ORIGIN) + SENDENTITY_COORD(origin[2], WEAPONFL_CHANGED_ORIGIN) + SENDENTITY_ANGLE(angles[0], WEAPONFL_CHANGED_ANGLES) + SENDENTITY_ANGLE(angles[1], WEAPONFL_CHANGED_ANGLES) + SENDENTITY_ANGLE(angles[2], WEAPONFL_CHANGED_ANGLES) + SENDENTITY_FLOAT(entityDefID, WEAPONFL_CHANGED_MODELINDEX) + SENDENTITY_SHORT(m_viewModel, WEAPONFL_CHANGED_MODELINDEX) + SENDENTITY_FLOAT(m_flFireRate, WEAPONFL_CHANGED_MODELINDEX) + SENDENTITY_BYTE(solid, WEAPONFL_CHANGED_SOLID) + SENDENTITY_BYTE(movetype, WEAPONFL_CHANGED_FLAGS) + SENDENTITY_INT(flags, WEAPONFL_CHANGED_FLAGS) + SENDENTITY_INT(modelflags, WEAPONFL_CHANGED_FLAGS) + SENDENTITY_INT(vv_flags, WEAPONFL_CHANGED_FLAGS) + SENDENTITY_COORD(mins[0], WEAPONFL_CHANGED_SIZE) + SENDENTITY_COORD(mins[1], WEAPONFL_CHANGED_SIZE) + SENDENTITY_COORD(mins[2], WEAPONFL_CHANGED_SIZE) + SENDENTITY_COORD(maxs[0], WEAPONFL_CHANGED_SIZE) + SENDENTITY_COORD(maxs[1], WEAPONFL_CHANGED_SIZE) + SENDENTITY_COORD(maxs[2], WEAPONFL_CHANGED_SIZE) + SENDENTITY_BYTE(frame, WEAPONFL_CHANGED_FRAME) + SENDENTITY_FLOAT(skin, WEAPONFL_CHANGED_SKIN) + SENDENTITY_FLOAT(effects, WEAPONFL_CHANGED_EFFECTS) + SENDENTITY_SHORT(m_iBody, WEAPONFL_CHANGED_BODY) + SENDENTITY_FLOAT(scale, WEAPONFL_CHANGED_SCALE) + SENDENTITY_COORD(velocity[0], WEAPONFL_CHANGED_VELOCITY) + SENDENTITY_COORD(velocity[1], WEAPONFL_CHANGED_VELOCITY) + SENDENTITY_COORD(velocity[2], WEAPONFL_CHANGED_VELOCITY) + SENDENTITY_COORD(avelocity[0], WEAPONFL_CHANGED_ANGULARVELOCITY) + SENDENTITY_COORD(avelocity[1], WEAPONFL_CHANGED_ANGULARVELOCITY) + SENDENTITY_COORD(avelocity[2], WEAPONFL_CHANGED_ANGULARVELOCITY) + SENDENTITY_BYTE(m_iClip, WEAPONFL_CHANGED_CLIP) + SENDENTITY_BYTE(m_iClipSize, WEAPONFL_CHANGED_CLIP) + SENDENTITY_BYTE(m_iMode, WEAPONFL_CHANGED_CLIP) + SENDENTITY_BYTE(m_dState, WEAPONFL_CHANGED_STATE) + SENDENTITY_BYTE(m_bFiring, WEAPONFL_CHANGED_STATE) + SENDENTITY_FLOAT(m_flOverheating, WEAPONFL_CHANGED_STATE) return (1); } void NSWeapon::EvaluateEntity(void) { + EVALUATE_FIELD(m_nextItem, WEAPONFL_CHANGED_CHAIN) + EVALUATE_FIELD(owner, WEAPONFL_CHANGED_CHAIN) + EVALUATE_FIELD(m_nextWeapon, WEAPONFL_CHANGED_NEXTWEAPON) + EVALUATE_FIELD(m_prevWeapon, WEAPONFL_CHANGED_PREVWEAPON) EVALUATE_VECTOR(origin, 0, WEAPONFL_CHANGED_ORIGIN) EVALUATE_VECTOR(origin, 1, WEAPONFL_CHANGED_ORIGIN) EVALUATE_VECTOR(origin, 2, WEAPONFL_CHANGED_ORIGIN) @@ -415,6 +446,7 @@ NSWeapon::EvaluateEntity(void) EVALUATE_FIELD(solid, WEAPONFL_CHANGED_SOLID) EVALUATE_FIELD(movetype, WEAPONFL_CHANGED_FLAGS) EVALUATE_FIELD(flags, WEAPONFL_CHANGED_FLAGS) + EVALUATE_FIELD(modelflags, WEAPONFL_CHANGED_FLAGS) EVALUATE_FIELD(vv_flags, WEAPONFL_CHANGED_FLAGS) EVALUATE_VECTOR(mins, 0, WEAPONFL_CHANGED_SIZE) EVALUATE_VECTOR(mins, 1, WEAPONFL_CHANGED_SIZE) @@ -427,17 +459,15 @@ NSWeapon::EvaluateEntity(void) EVALUATE_FIELD(effects, WEAPONFL_CHANGED_EFFECTS) EVALUATE_FIELD(m_iBody, WEAPONFL_CHANGED_BODY) EVALUATE_FIELD(scale, WEAPONFL_CHANGED_SCALE) - EVALUATE_VECTOR(velocity, 0, WEAPONFL_CHANGED_VELOCITY_X) - EVALUATE_VECTOR(velocity, 1, WEAPONFL_CHANGED_VELOCITY_Y) - EVALUATE_VECTOR(velocity, 2, WEAPONFL_CHANGED_VELOCITY_Z) + EVALUATE_VECTOR(velocity, 0, WEAPONFL_CHANGED_VELOCITY) + EVALUATE_VECTOR(velocity, 1, WEAPONFL_CHANGED_VELOCITY) + EVALUATE_VECTOR(velocity, 2, WEAPONFL_CHANGED_VELOCITY) EVALUATE_VECTOR(avelocity, 0, WEAPONFL_CHANGED_ANGULARVELOCITY) EVALUATE_VECTOR(avelocity, 1, WEAPONFL_CHANGED_ANGULARVELOCITY) EVALUATE_VECTOR(avelocity, 2, WEAPONFL_CHANGED_ANGULARVELOCITY) EVALUATE_FIELD(m_iClip, WEAPONFL_CHANGED_CLIP) EVALUATE_FIELD(m_iClipSize, WEAPONFL_CHANGED_CLIP) EVALUATE_FIELD(m_iMode, WEAPONFL_CHANGED_CLIP) - EVALUATE_FIELD(chain, WEAPONFL_CHANGED_CHAIN) - EVALUATE_FIELD(owner, WEAPONFL_CHANGED_CHAIN) EVALUATE_FIELD(m_dState, WEAPONFL_CHANGED_STATE) EVALUATE_FIELD(m_bFiring, WEAPONFL_CHANGED_STATE) EVALUATE_FIELD(m_flOverheating, WEAPONFL_CHANGED_STATE) @@ -474,50 +504,66 @@ void NSWeapon::ReceiveEntity(float flNew, float flChanged) { READENTITY_SHORT(modelindex, WEAPONFL_CHANGED_MODELINDEX) + READENTITY_ENTNUM(chain_entnum, WEAPONFL_CHANGED_CHAIN) + READENTITY_ENTNUM(owner_entnum, WEAPONFL_CHANGED_CHAIN) + READENTITY_ENTNUM(m_nextWeapon_entnum, WEAPONFL_CHANGED_NEXTWEAPON) + READENTITY_ENTNUM(m_prevWeapon_entnum, WEAPONFL_CHANGED_PREVWEAPON) + + READENTITY_COORD(origin[0], WEAPONFL_CHANGED_ORIGIN) + READENTITY_COORD(origin[1], WEAPONFL_CHANGED_ORIGIN) + READENTITY_COORD(origin[2], WEAPONFL_CHANGED_ORIGIN) + READENTITY_ANGLE(angles[0], WEAPONFL_CHANGED_ANGLES) + READENTITY_ANGLE(angles[1], WEAPONFL_CHANGED_ANGLES) + READENTITY_ANGLE(angles[2], WEAPONFL_CHANGED_ANGLES) + READENTITY_FLOAT(entityDefID, WEAPONFL_CHANGED_MODELINDEX) + READENTITY_SHORT(m_viewModel, WEAPONFL_CHANGED_MODELINDEX) + READENTITY_FLOAT(m_flFireRate, WEAPONFL_CHANGED_MODELINDEX) + READENTITY_BYTE(solid, WEAPONFL_CHANGED_SOLID) + READENTITY_BYTE(movetype, WEAPONFL_CHANGED_FLAGS) + READENTITY_INT(flags, WEAPONFL_CHANGED_FLAGS) + READENTITY_INT(modelflags, WEAPONFL_CHANGED_FLAGS) + READENTITY_INT(vv_flags, WEAPONFL_CHANGED_FLAGS) + READENTITY_COORD(mins[0], WEAPONFL_CHANGED_SIZE) + READENTITY_COORD(mins[1], WEAPONFL_CHANGED_SIZE) + READENTITY_COORD(mins[2], WEAPONFL_CHANGED_SIZE) + READENTITY_COORD(maxs[0], WEAPONFL_CHANGED_SIZE) + READENTITY_COORD(maxs[1], WEAPONFL_CHANGED_SIZE) + READENTITY_COORD(maxs[2], WEAPONFL_CHANGED_SIZE) + READENTITY_BYTE(frame, WEAPONFL_CHANGED_FRAME) + READENTITY_FLOAT(skin, WEAPONFL_CHANGED_SKIN) + READENTITY_FLOAT(effects, WEAPONFL_CHANGED_EFFECTS) + READENTITY_SHORT(m_iBody, WEAPONFL_CHANGED_BODY) + READENTITY_FLOAT(scale, WEAPONFL_CHANGED_SCALE) + READENTITY_COORD(velocity[0], WEAPONFL_CHANGED_VELOCITY) + READENTITY_COORD(velocity[1], WEAPONFL_CHANGED_VELOCITY) + READENTITY_COORD(velocity[2], WEAPONFL_CHANGED_VELOCITY) + READENTITY_COORD(avelocity[0], WEAPONFL_CHANGED_ANGULARVELOCITY) + READENTITY_COORD(avelocity[1], WEAPONFL_CHANGED_ANGULARVELOCITY) + READENTITY_COORD(avelocity[2], WEAPONFL_CHANGED_ANGULARVELOCITY) + READENTITY_BYTE(m_iClip, WEAPONFL_CHANGED_CLIP) + READENTITY_BYTE(m_iClipSize, WEAPONFL_CHANGED_CLIP) + READENTITY_BYTE(m_iMode, WEAPONFL_CHANGED_CLIP) + READENTITY_BYTE(m_dState, WEAPONFL_CHANGED_STATE) + READENTITY_BYTE(m_bFiring, WEAPONFL_CHANGED_STATE) + READENTITY_FLOAT(m_flOverheating, WEAPONFL_CHANGED_STATE) - if (1) { - READENTITY_COORD(origin[0], WEAPONFL_CHANGED_ORIGIN) - READENTITY_COORD(origin[1], WEAPONFL_CHANGED_ORIGIN) - READENTITY_COORD(origin[2], WEAPONFL_CHANGED_ORIGIN) - READENTITY_ANGLE(angles[0], WEAPONFL_CHANGED_ANGLES) - READENTITY_ANGLE(angles[1], WEAPONFL_CHANGED_ANGLES) - READENTITY_ANGLE(angles[2], WEAPONFL_CHANGED_ANGLES) - READENTITY_SHORT(entityDefID, WEAPONFL_CHANGED_MODELINDEX) - READENTITY_SHORT(m_viewModel, WEAPONFL_CHANGED_MODELINDEX) - READENTITY_FLOAT(m_flFireRate, WEAPONFL_CHANGED_MODELINDEX) - READENTITY_BYTE(solid, WEAPONFL_CHANGED_SOLID) - READENTITY_BYTE(movetype, WEAPONFL_CHANGED_FLAGS) - READENTITY_INT(flags, WEAPONFL_CHANGED_FLAGS) - READENTITY_INT(vv_flags, WEAPONFL_CHANGED_FLAGS) - READENTITY_COORD(mins[0], WEAPONFL_CHANGED_SIZE) - READENTITY_COORD(mins[1], WEAPONFL_CHANGED_SIZE) - READENTITY_COORD(mins[2], WEAPONFL_CHANGED_SIZE) - READENTITY_COORD(maxs[0], WEAPONFL_CHANGED_SIZE) - READENTITY_COORD(maxs[1], WEAPONFL_CHANGED_SIZE) - READENTITY_COORD(maxs[2], WEAPONFL_CHANGED_SIZE) - READENTITY_BYTE(frame, WEAPONFL_CHANGED_FRAME) - READENTITY_FLOAT(skin, WEAPONFL_CHANGED_SKIN) - READENTITY_FLOAT(effects, WEAPONFL_CHANGED_EFFECTS) - READENTITY_SHORT(m_iBody, MONFL_CHANGED_BODY) - READENTITY_FLOAT(scale, WEAPONFL_CHANGED_SCALE) - READENTITY_COORD(velocity[0], WEAPONFL_CHANGED_VELOCITY_X) - READENTITY_COORD(velocity[1], WEAPONFL_CHANGED_VELOCITY_Y) - READENTITY_COORD(velocity[2], WEAPONFL_CHANGED_VELOCITY_Z) - READENTITY_COORD(avelocity[0], WEAPONFL_CHANGED_ANGULARVELOCITY) - READENTITY_COORD(avelocity[1], WEAPONFL_CHANGED_ANGULARVELOCITY) - READENTITY_COORD(avelocity[2], WEAPONFL_CHANGED_ANGULARVELOCITY) - READENTITY_BYTE(m_iClip, WEAPONFL_CHANGED_CLIP) - READENTITY_BYTE(m_iClipSize, WEAPONFL_CHANGED_CLIP) - READENTITY_BYTE(m_iMode, WEAPONFL_CHANGED_CLIP) - READENTITY_ENTNUM(chain_entnum, WEAPONFL_CHANGED_CHAIN) - READENTITY_ENTNUM(owner_entnum, WEAPONFL_CHANGED_CHAIN) - READENTITY_BYTE(m_dState, WEAPONFL_CHANGED_STATE) - READENTITY_BYTE(m_bFiring, WEAPONFL_CHANGED_STATE) - READENTITY_FLOAT(m_flOverheating, WEAPONFL_CHANGED_STATE) + /* weapon view model update */ + NSActor ourOwner = (NSActor)findfloat(world, ::entnum, owner_entnum); + + if (ourOwner.m_activeWeapon == this) { + NSRenderableEntity viewModel = (NSRenderableEntity)pSeat->m_eViewModel; + + if (viewModel) { + if (viewModel.modelindex != m_viewModel) { + viewModel.modelindex = m_viewModel; + viewModel._UpdateBoneCount(); + } + } } if (flChanged & WEAPONFL_CHANGED_MODELINDEX) { - classname = EntityDef_NameFromID(entityDefID); + classname = EntityDef_NameFromNetID(entityDefID); + declclass = classname; } if (flChanged & WEAPONFL_CHANGED_BODY) @@ -526,7 +572,15 @@ NSWeapon::ReceiveEntity(float flNew, float flChanged) drawmask = (modelindex != 0) ? MASK_ENGINE : 0; if (flChanged & WEAPONFL_CHANGED_CHAIN) { - chain = __NULL__; + m_nextItem = __NULL__; + } + + if (flChanged & WEAPONFL_CHANGED_NEXTWEAPON) { + m_nextWeapon = __NULL__; + } + + if (flChanged & WEAPONFL_CHANGED_PREVWEAPON) { + m_prevWeapon = __NULL__; } if (scale == 0.0f) @@ -553,11 +607,38 @@ NSWeapon::PredictPreFrame(void) { super::PredictPreFrame(); + if (m_nextWeapon == __NULL__ && m_nextWeapon_entnum) { + m_nextWeapon = (NSWeapon)findentity(world, ::entnum, m_nextWeapon_entnum); + } + + if (m_prevWeapon == __NULL__ && m_prevWeapon_entnum) { + m_prevWeapon = (NSWeapon)findentity(world, ::entnum, m_prevWeapon_entnum); + } + + SAVE_STATE(m_nextWeapon) + SAVE_STATE(m_prevWeapon) + SAVE_STATE(modelindex) + SAVE_STATE(origin) + SAVE_STATE(angles) + SAVE_STATE(entityDefID) + SAVE_STATE(m_viewModel) + SAVE_STATE(m_flFireRate) + SAVE_STATE(solid) + SAVE_STATE(movetype) + SAVE_STATE(flags) + SAVE_STATE(vv_flags) + SAVE_STATE(mins) + SAVE_STATE(maxs) +// SAVE_STATE(frame) +// SAVE_STATE(skin) +// SAVE_STATE(effects) + SAVE_STATE(m_iBody) + SAVE_STATE(scale) + SAVE_STATE(velocity) + SAVE_STATE(avelocity) SAVE_STATE(m_iClip) SAVE_STATE(m_iClipSize) SAVE_STATE(m_iMode) - SAVE_STATE(m_viewModel) - SAVE_STATE(m_flFireRate) SAVE_STATE(m_dState) SAVE_STATE(m_bFiring) SAVE_STATE(m_flOverheating) @@ -568,11 +649,30 @@ NSWeapon::PredictPostFrame(void) { super::PredictPostFrame(); + ROLL_BACK(m_nextWeapon) + ROLL_BACK(m_prevWeapon) + ROLL_BACK(modelindex) + ROLL_BACK(origin) + ROLL_BACK(angles) + ROLL_BACK(entityDefID) + ROLL_BACK(m_viewModel) + ROLL_BACK(m_flFireRate) + ROLL_BACK(solid) + ROLL_BACK(movetype) + ROLL_BACK(flags) + ROLL_BACK(vv_flags) + ROLL_BACK(mins) + ROLL_BACK(maxs) +// ROLL_BACK(frame) +// ROLL_BACK(skin) +// ROLL_BACK(effects) + ROLL_BACK(m_iBody) + ROLL_BACK(scale) + ROLL_BACK(velocity) + ROLL_BACK(avelocity) ROLL_BACK(m_iClip) ROLL_BACK(m_iClipSize) ROLL_BACK(m_iMode) - ROLL_BACK(m_viewModel) - ROLL_BACK(m_flFireRate) ROLL_BACK(m_dState) ROLL_BACK(m_bFiring) ROLL_BACK(m_flOverheating) @@ -599,10 +699,12 @@ NSWeapon::_CacheWeaponDefVariables(void) big in the game state changes. like a save/load. */ m_primaryFireInfo = GetDefString("def_fireInfo"); m_secondaryFireInfo = GetDefString("def_altFireInfo"); + /* MIGRATE INTO FIREINFO */ m_meleeDef = GetDefString("def_melee"); - if (!m_primaryFireInfo) + if (!m_primaryFireInfo) { m_primaryFireInfo = classname; + } firstType = GetSubDefString(m_primaryFireInfo, "ammoType"); @@ -610,7 +712,6 @@ NSWeapon::_CacheWeaponDefVariables(void) ammoRequired = GetSubDefString(m_primaryFireInfo, "ammoRequired"); m_bAmmoRequired = stof(ammoRequired); m_primaryAmmoType = ammoNumForName(firstType); - muzzleModel = GetSubDefString(m_primaryFireInfo, "model_flash"); m_muzzleModelIndex = getmodelindex(muzzleModel, false); m_flPrimedFuse = GetDefFloat("primed_fuse"); @@ -618,10 +719,8 @@ NSWeapon::_CacheWeaponDefVariables(void) m_bPowerAmmo = GetDefBool("powerAmmo"); m_bRemoveOnEmpty = GetDefBool("removeOnEmpty"); m_fxTrail = particleeffectnum(GetDefString("fx_trail")); - m_viewModel = getmodelindex(GetDefString("model_view")); m_worldModel = getmodelindex(GetDefString("model")); - m_bAltModeSwitch = GetDefBool("altMode"); /* gettagindex takes the silliest of parameters to determine which model to query */ @@ -641,7 +740,6 @@ NSWeapon::_CacheWeaponDefVariables(void) secondType = GetSubDefString(m_secondaryFireInfo, "ammoType"); m_secondaryAmmoType = ammoNumForName(secondType); - muzzleModel = GetSubDefString(m_secondaryFireInfo, "model_flash"); m_altMuzzleModelIndex = getmodelindex(muzzleModel, false); } @@ -649,12 +747,14 @@ NSWeapon::_CacheWeaponDefVariables(void) void NSWeapon::_SwitchedToCallback(void) { - _CacheWeaponDefVariables(); SwitchFireInfo(m_primaryFireInfo); SetAttackNext(0.0f); SetIdleNext(0.0f); - Draw(); + +#ifdef CLIENT + PredictPreFrame(); +#endif } void @@ -670,30 +770,78 @@ NSWeapon::IsWeapon(void) return (true); } +bool +NSWeapon::IsEmpty(void) +{ + NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); + + if (autocvar_g_infiniteAmmo == true) { + return (false); + } + + if (m_fiAmmoRequired) { + /* this weapon uses a clip/magazine */ + if (m_iClipSize && m_fiAmmoType == m_primaryAmmoType) { + /* no more ammo in clip? */ + if (m_iClip <= 0i || (m_iClip - m_fiAmmoPerShot) < 0i) { + /* possible to reload? */ + if (ourOwner.HasAmmo(m_fiAmmoType, 1) == true) { + return (false); + } + return (true); + } + + } else if (ourOwner.HasAmmo(m_fiAmmoType, m_fiAmmoPerShot) == false) { + return (true); + } + } + + return (false); +} + void NSWeapon::Draw(void) { #ifdef CLIENT - NSRenderableEntity viewModel = (NSRenderableEntity)pSeat->m_eViewModel; - viewModel.modelindex = m_viewModel; - viewModel._UpdateBoneCount(); + if (pSeat != __NULL__) { + NSRenderableEntity viewModel = (NSRenderableEntity)pSeat->m_eViewModel; + + if (viewModel && viewModel.classname == "vm") { + viewModel.modelindex = m_viewModel; + if (m_viewModel) { + viewModel._UpdateBoneCount(); + } + } + } #endif - float drawAnimation = 0; - float drawTime; + float drawAnimation = -1; + float drawTime = 0.0f; if (m_iClipSize > 0 && m_iClip == 0) { - drawAnimation = GetSubDefAct(m_strLastFireInfo, "actDrawEmpty"); + drawAnimation = GetSubDefAct(m_primaryFireInfo, "actDrawEmpty"); } - if (!drawAnimation) { - drawAnimation = GetSubDefAct(m_strLastFireInfo, "actDraw"); + /* no empty draw anim exists */ + if (drawAnimation < 0) { + drawAnimation = GetSubDefAct(m_primaryFireInfo, "actDraw"); } - drawTime = frameduration(m_viewModel, drawAnimation); - SetWeaponFrame(drawAnimation); + /* no draw anim exists at all... */ + if (drawAnimation >= 0) { + drawTime = frameduration(m_viewModel, drawAnimation); + SetWeaponFrame(drawAnimation); + } + +#ifdef SERVER + PlaySound(GetDefString("snd_draw"), false); +#endif + SetAttackNext(drawTime); - SetIdleNext(drawTime + 1.0f); + SetIdleNext(drawTime); + + NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); + ourOwner.viewzoom = 1.0f; } void @@ -800,8 +948,15 @@ void NSWeapon::Attack(string fireInfo) { NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); - float shotAnim = 0; + float shotAnim = -1; float fireRate = 1.0f; + + if (GetWeaponState() == WEAPONSTATE_RELOAD) { + _SetWeaponState(WEAPONSTATE_RELOAD_END); + SetIdleNext(0.0f); + Idle(); + return; + } if (m_fiSemiAuto == true) { ourOwner.gflags |= GF_SEMI_TOGGLED; @@ -812,7 +967,12 @@ NSWeapon::Attack(string fireInfo) /* no real attack, detonate named satchels, pipe bombs, etc. */ if (m_fiDetonateOnFire != __NULL__) { if (DetonateDef(m_fiDetonateOnFire) == true) { - SetWeaponFrame(GetSubDefAct(fireInfo, "actDetonate")); + float detonateAct = GetSubDefAct(fireInfo, "actDetonate"); + + if (detonateAct >= 0) { + SetWeaponFrame(GetSubDefAct(fireInfo, "actDetonate")); + } + return; } } @@ -849,16 +1009,18 @@ NSWeapon::Attack(string fireInfo) hitLoc = trace_endpos; ourOwner.hitcontentsmaski = oldhitcontents; + float meleeAnim; if (trace_fraction >= 1.0) { - SetWeaponFrame(GetSubDefAct(fireInfo, "actMeleeMiss")); - meleeRate = GetDefFloat("meleeRateMiss"); + meleeAnim = GetSubDefAct(fireInfo, "actMeleeMiss"); + meleeRate = GetSubDefFloat(fireInfo, "meleeRateMiss"); } else { - SetWeaponFrame(GetSubDefAct(fireInfo, "actMeleeHit")); - meleeRate = GetDefFloat("meleeRateHit"); + meleeAnim = GetSubDefAct(fireInfo, "actMeleeHit"); + meleeRate = GetSubDefFloat(fireInfo, "meleeRateHit"); } + SetWeaponFrame(meleeAnim); SetAttackNext(meleeRate); - SetIdleNext(meleeRate + 1.0f); + SetIdleNext(frameduration(m_viewModel, meleeAnim)); #ifdef SERVER PlaySound(GetSubDefString(m_meleeDef, "snd_miss"), false); @@ -927,10 +1089,17 @@ NSWeapon::Attack(string fireInfo) ourOwner.punchangle += m_fiPunchAngle; #ifdef SERVER + string fireSound = m_fiSndFire; v_angle = input_angles; - if (m_fiSndFire) { - ourOwner.StartSoundDef(m_fiSndFire, CHAN_WEAPON, true); + if (m_iClipSize > 0 && m_iClip == 0) { + if (m_fiSndFireLast != "") { + fireSound = m_fiSndFireLast; + } + } + + if (fireSound) { + ourOwner.StartSoundDef(fireSound, CHAN_WEAPON, true); } #endif @@ -940,8 +1109,8 @@ NSWeapon::Attack(string fireInfo) if (m_iClipSize > 0 && m_iClip == 0) { shotAnim = GetSubDefAct(fireInfo, "actFireLast"); } - - if (!shotAnim) { + + if (shotAnim <= 0) { shotAnim = GetSubDefAct(fireInfo, "actFire"); } @@ -976,6 +1145,7 @@ NSWeapon::Attack(string fireInfo) } else { SetAttackNext(animTime); } + SetIdleNext(animTime); m_bFiring = true; } @@ -990,14 +1160,18 @@ NSWeapon::_PrimaryAttack(void) void NSWeapon::_SecondaryAttack(void) { - _WeaponStartedFiring(); - SecondaryAttack(); + if (GetDefBool("altAlternates") == true) { + return; + } else { + _WeaponStartedFiring(); + SecondaryAttack(); + } } void NSWeapon::_SwitchedWeaponMode(void) { - float animMode; + float animMode = -1; if (m_iMode) { animMode = GetSubDefAct(m_strLastFireInfo, "actModeOn"); @@ -1007,9 +1181,11 @@ NSWeapon::_SwitchedWeaponMode(void) animMode = GetSubDefAct(m_strLastFireInfo, "actModeOff"); } - SetWeaponFrame(animMode); - SetAttackNext(frameduration(m_viewModel, animMode)); - SetIdleNext(frameduration(m_viewModel, animMode)); + if (animMode >= 0) { + SetWeaponFrame(animMode); + SetAttackNext(frameduration(m_viewModel, animMode)); + SetIdleNext(frameduration(m_viewModel, animMode)); + } } void @@ -1032,7 +1208,7 @@ void NSWeapon::Idle(void) { NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); - float idleAnim = 0; + float idleAnim = -1; m_flOverheating = max(0.0f, m_flOverheating - input_timelength); @@ -1045,7 +1221,10 @@ NSWeapon::Idle(void) case WEAPONSTATE_RELOAD_START: idleAnim = GetSubDefAct(m_strLastFireInfo, "actReloadStart"); _SetWeaponState(WEAPONSTATE_RELOAD); +#ifdef SERVER PlaySound(GetDefString("snd_reload_start"), false); +#endif + SetAttackNext(frameduration(m_viewModel, idleAnim)); break; case WEAPONSTATE_RELOAD: float reloadTime; @@ -1057,18 +1236,17 @@ NSWeapon::Idle(void) _SetWeaponState(WEAPONSTATE_RELOAD_END); } -#ifdef SERVER - PlaySound(GetDefString("snd_reload"), false); -#endif - if (m_flReloadSpeed == -1.0f) { reloadTime = frameduration(m_viewModel, idleAnim); } else { reloadTime = m_flReloadSpeed; } - +#ifdef SERVER + PlaySound(GetDefString("snd_reload"), false); +#endif SetWeaponFrame(idleAnim); SetIdleNext(reloadTime); + /* SetAttackNext(reloadTime); */ /* people like instant feedback, hence commented out */ return; break; case WEAPONSTATE_RELOAD_END: @@ -1077,6 +1255,7 @@ NSWeapon::Idle(void) #ifdef SERVER PlaySound(GetDefString("snd_reload_end"), false); #endif + SetAttackNext(frameduration(m_viewModel, idleAnim)); break; case WEAPONSTATE_FIRELOOP: idleAnim = GetSubDefAct(m_strLastFireInfo, "actLoop"); @@ -1094,19 +1273,29 @@ NSWeapon::Idle(void) _SetWeaponState(WEAPONSTATE_IDLE); SetAttackNext(m_fiOverheatLength); SetReloadNext(0.1f); - break; + /* prevent anything else. */ + return; case WEAPONSTATE_IDLE: default: if (m_iClipSize > 0 && m_iClip == 0) { idleAnim = GetSubDefAct(m_strLastFireInfo, "actIdleEmpty"); - - /* this will mess with us otherwise */ - if (!idleAnim) + + /* TODO: may want this? hard to say. */ + /*if (idleAnim < 0) { + SetIdleNext(5.0f); return; + }*/ } - if (!idleAnim) + if (idleAnim < 0) { idleAnim = GetSubDefAct(m_strLastFireInfo, "actIdle"); + } + } + + /* no anim, so delay it by a bit more so we don't constantly query decl */ + if (idleAnim < 0) { + SetIdleNext(5.0f); + return; } SetWeaponFrame(idleAnim); @@ -1139,6 +1328,10 @@ NSWeapon::PrimaryAttack(void) } } + if (GetDefBool("altAlternates") == true) { + m_iMode = 1 - m_iMode; + } + if (m_iMode) { Attack(m_secondaryFireInfo); return; @@ -1214,9 +1407,11 @@ NSWeapon::_ReloadFinished(void) /* not enough ammo. assign whatever is left. */ if (ourOwner.HasAmmo(m_primaryAmmoType, ammoToDeduct) == false) { ammoToDeduct = ourOwner.m_iAmmoTypes[m_primaryAmmoType]; + m_iClip += ammoToDeduct; + } else { + m_iClip = m_iClipSize; } - m_iClip = m_iClipSize; ourOwner.UseAmmo(m_primaryAmmoType, ammoToDeduct); } #endif @@ -1225,11 +1420,11 @@ void NSWeapon::Reload(void) { NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); - float reloadAnimation = 0; + float reloadAnimation = -1; float reloadTime; string ammoType; int ammoTypeID; - float reloadStartAct; + float reloadStartAct = -1; /* already in a reload? */ if (m_dState >= WEAPONSTATE_RELOAD_START && m_dState <= WEAPONSTATE_RELOAD_END) { @@ -1247,7 +1442,8 @@ NSWeapon::Reload(void) return; } - ammoType = GetSubDefString(m_strLastFireInfo, "ammoType"); + /* NOTE: this affects our clip, so primary fireInfo only */ + ammoType = GetSubDefString(m_primaryFireInfo, "ammoType"); ammoTypeID = ammoNumForName(ammoType); if (m_iClip == m_iClipSize) { @@ -1261,8 +1457,9 @@ NSWeapon::Reload(void) } /* we have a start-reload, so this is a shotgun styled weapon reload */ - if (reloadStartAct) { + if (reloadStartAct >= 0) { _SetWeaponState(WEAPONSTATE_RELOAD_START); + SetIdleNext(0.0); Release(); return; } @@ -1270,8 +1467,8 @@ NSWeapon::Reload(void) if (m_iClipSize > 0 && m_iClip == 0) { reloadAnimation = GetSubDefAct(m_strLastFireInfo, "actReloadEmpty"); } - - if (!reloadAnimation) { + + if (reloadAnimation < 0) { reloadAnimation = GetSubDefAct(m_strLastFireInfo, "actReload"); } @@ -1281,9 +1478,19 @@ NSWeapon::Reload(void) reloadTime = m_flReloadSpeed; } - PlaySound(GetDefString("snd_reload"), false); - #ifdef SERVER + + string reloadSound = GetDefString("snd_reload"); + + if (m_iClipSize > 0 && m_iClip == 0) { + string emptyReload = GetDefString("snd_reloadEmpty"); + + if (emptyReload != "") { + reloadSound = emptyReload; + } + } + + ourOwner.StartSoundDef(reloadSound, CHAN_AUTO, true); ScheduleThink(_ReloadFinished, reloadTime - 0.1f); #endif @@ -1332,13 +1539,13 @@ NSWeapon::_WeaponStartedFiring(void) } if (m_fiSndFireLoop) { - //ourOwner.StartSoundDef(m_fiSndFireLoop, CHAN_LOOP, true); + ourOwner.StartSoundDef(m_fiSndFireLoop, CHAN_LOOP, true); } //printf("actFireStart %d %S\n", actFireStart, m_strLastFireInfo); #endif - if (actFireStart) { + if (actFireStart >= 0) { SetWeaponFrame(actFireStart); SetAttackNext(frameduration(m_viewModel, actFireStart)); SetIdleNext(frameduration(m_viewModel, actFireStart)); @@ -1363,7 +1570,7 @@ NSWeapon::_WeaponStoppedFiring(void) if (owner.vv_flags & VFL_FIRING) { float actFireStop = GetSubDefAct(m_strLastFireInfo, "actFireStop"); - if (actFireStop) { + if (actFireStop >= 0) { SetWeaponFrame(actFireStop); SetAttackNext(frameduration(m_viewModel, actFireStop)); SetIdleNext(frameduration(m_viewModel, actFireStop)); @@ -1395,7 +1602,7 @@ NSWeapon::WeaponStoppedFiring(void) void NSWeapon::Release(void) { - float idleAnim = 0; + float idleAnim = -1; NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); ourOwner.gflags &= ~GF_SEMI_TOGGLED; @@ -1425,7 +1632,11 @@ NSWeapon::Release(void) ReleasedWeaponAttack(m_strLastFireInfo); m_fiWillRelease = false; - SetWeaponFrame(idleAnim); + + if (idleAnim >= 0) { + SetWeaponFrame(idleAnim); + } + SetAttackNext(1.0f); SetIdleNext(1.0f); ourOwner.vv_flags &= ~VFL_PRIMEDFUSE; @@ -1458,21 +1669,40 @@ NSWeapon::Release(void) #endif m_bFiring = false; - -#if 0 - if (ourOwner.vv_flags & VFL_REDRAW) { - Draw(); - ourOwner.vv_flags &= ~VFL_REDRAW; - return; - } -#endif - Idle(); } void NSWeapon::UpdateGUI(void) { +#ifdef CLIENT + NSClientPlayer ourOwner = __NULL__; + static float baseIconSize = 32.0f; + static float baseIconPadding = 16.0f; + + if (m_bAmmoRequired == false) { + return; + } + + ourOwner = (NSClientPlayer)GetOwner(); + + vector hudSize = g_view.GetHUDCanvasSize(); + vector iconPos = g_view.GetHUDCanvasPos() + (hudSize / 2); + iconPos[0] = (hudSize[0] - baseIconSize) - baseIconPadding; + iconPos[1] = (hudSize[1] - baseIconSize) - baseIconPadding; + drawpic(iconPos, "gfx/hud/armor", [baseIconSize, baseIconSize], [1,1,1], 1.0f); + + ourOwner.a_ammo2 = ourOwner.GetReserveAmmo(m_primaryAmmoType); + iconPos[0] -= baseIconSize + baseIconPadding; + Font_DrawRText(iconPos, itos(ourOwner.a_ammo2), FONT_16); + + iconPos[0] -= baseIconSize + baseIconPadding; + + if (m_iClipSize > 0i) { + ourOwner.a_ammo1 = m_iClip; + Font_DrawRText(iconPos, itos(ourOwner.a_ammo1), FONT_16); + } +#endif } void @@ -1544,14 +1774,15 @@ void NSWeapon::SetIdleNext(float newDelay) { NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); - ourOwner.w_idle_next = newDelay; + /* HACK: RT2 requires this as their anims have junk at the end :/ */ + ourOwner.w_idle_next = bound(0.0, newDelay - 0.05f, newDelay); } bool NSWeapon::CanIdle(void) { NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); - + if (ourOwner.w_idle_next > 0.0f) { return (false); } @@ -1563,7 +1794,7 @@ bool NSWeapon::CanFire(void) { NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); - + if (ourOwner.w_attack_next > 0.0f) { return (false); } @@ -1584,7 +1815,7 @@ bool NSWeapon::CanReload(void) { NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); - + if (ourOwner.w_reload_next > 0.0f) { return (false); } @@ -1694,136 +1925,3 @@ isWeaponDetonationTimed(string weaponDef) return (isFused); } -NSWeapon -NSWeapon_SortWeaponChain(NSActor targetPlayer) -{ - NSWeapon itemChain = (NSWeapon)targetPlayer.m_itemList; - int heighestSlot = -1i; - int heighestPos = -1i; - NSWeapon firstWeapon, lastWeapon; - int hudSlot, hudPos; - - firstWeapon = lastWeapon = __NULL__; - - if (!targetPlayer.m_itemList) { - return __NULL__; - } - - /* first we determine the range of our hud buckets. */ - while (itemChain) { - if (itemChain.IsWeapon() == true) { - hudSlot = itemChain.GetDefInt("hudSlot"); - hudPos = itemChain.GetDefInt("hudSlotPos"); - - if (hudSlot > heighestSlot) { - heighestSlot = hudSlot; - } - if (hudPos > heighestPos) { - heighestPos = hudPos; - } - } - - itemChain = (NSWeapon)itemChain.chain; - } - - for (int hS = 0i; hS <= heighestSlot; hS++) { - for (int hP = 0i; hP <= heighestPos; hP++) { - itemChain = (NSWeapon)targetPlayer.m_itemList; - - while (itemChain) { - if (itemChain.IsWeapon() == true) { - hudSlot = itemChain.GetDefInt("hudSlot"); - hudPos = itemChain.GetDefInt("hudSlotPos"); - - if (hudSlot == hS && hudPos == hP) { - /* first weapon in the chain? */ - if (!lastWeapon) { - firstWeapon = itemChain; - lastWeapon = firstWeapon; - } else { - /* assign this weapon to the last weapon of our chain. */ - lastWeapon.m_nextWeapon = itemChain; - itemChain.m_prevWeapon = lastWeapon; - lastWeapon = itemChain; - } - } - } - - itemChain = (NSWeapon)itemChain.chain; - } - } - } - - /* test */ - NSWeapon weaponTest = firstWeapon; - while (weaponTest) { - weaponTest = weaponTest.m_nextWeapon; - } - - firstWeapon.m_prevWeapon = lastWeapon; - - return (firstWeapon); -} - -/** Select the next item in the list. */ -void -NSWeapon_NextWeapon(NSActor pl) -{ -#ifdef CLIENT - NSWeapon firstWeapon; - - if (NSWeapon_CanSwitch(pl) == false) { - return; - } - - firstWeapon = NSWeapon_SortWeaponChain(pl); - - if (pl.m_activeWeapon.m_nextWeapon) { - NSWeapon_SelectWeapon(pl.m_activeWeapon.m_nextWeapon); - } else { - NSWeapon_SelectWeapon(firstWeapon); - } -#endif -} - -/** Select the previous item in the list. */ -void -NSWeapon_PrevWeapon(NSActor pl) -{ -#ifdef CLIENT - NSWeapon firstWeapon; - - if (NSWeapon_CanSwitch(pl) == false) { - return; - } - - firstWeapon = NSWeapon_SortWeaponChain(pl); - - if (pl.m_activeWeapon.m_prevWeapon) { - NSWeapon_SelectWeapon(pl.m_activeWeapon.m_prevWeapon); - } else { - NSWeapon_SelectWeapon(firstWeapon); - } -#endif -} - -/** Select the previous item in the list. */ -void -NSWeapon_LastWeapon(NSActor pl) -{ -#ifdef CLIENT - NSWeapon firstWeapon; - - if (NSWeapon_CanSwitch(pl) == false) { - return; - } - - firstWeapon = NSWeapon_SortWeaponChain(pl); - - if (pl.m_activeWeapon.m_prevWeapon) { - NSWeapon_SelectWeapon(pl.m_activeWeapon.m_prevWeapon); - } else { - NSWeapon_SelectWeapon(firstWeapon); - } -#endif -} diff --git a/src/shared/NSWeapon_NSNavAI.h b/src/shared/NSWeapon_NSNavAI.h deleted file mode 100644 index e4bf71b2..00000000 --- a/src/shared/NSWeapon_NSNavAI.h +++ /dev/null @@ -1,4 +0,0 @@ - -void NSWeapon_NextWeapon(NSActor); -void NSWeapon_PrevWeapon(NSActor); -void NSWeapon_LastWeapon(NSActor); \ No newline at end of file diff --git a/src/shared/ammo.qc b/src/shared/ammo.qc index ea2941e8..bb53c02f 100644 --- a/src/shared/ammo.qc +++ b/src/shared/ammo.qc @@ -65,7 +65,9 @@ Ammo_Init(void) int ammoIndex = stoi(argv(c+1)); g_ammoInfo[ammoIndex].m_strName = ammoName; g_ammoInfo[ammoIndex].m_strTitle = EntityDef_GetKeyValue("ammo_names", ammoName); - g_ammoInfo[ammoIndex].m_iMax = (int)stof(EntityDef_GetKeyValue("ammo_max", ammoName)); + string maxString = EntityDef_GetKeyValue("ammo_max", ammoName); + string unpackedString = unpackStringCommand(maxString); + g_ammoInfo[ammoIndex].m_iMax = (int)stof(unpackedString); numKeys = tokenize_console(ammoTypeData); } } @@ -78,4 +80,4 @@ Ammo_DebugList(void) printf("%i %S: %S\n", i, g_ammoInfo[i].m_strName, g_ammoInfo[i].m_strTitle); } -} \ No newline at end of file +} diff --git a/src/shared/defs.h b/src/shared/defs.h index 9de3530d..20e3fa41 100644 --- a/src/shared/defs.h +++ b/src/shared/defs.h @@ -107,7 +107,6 @@ string __fullspawndata; #include "NSItem.h" #include "NSWeapon.h" #include "NSNavAI.h" -#include "NSWeapon_NSNavAI.h" #include "NSMonster.h" #include "NSSquadMonster.h" #include "NSTalkMonster.h" @@ -415,6 +414,23 @@ setorigin_safe(entity target, vector testorg) setorigin(target, testorg); } +#ifdef SERVER +string Skill_GetStringValue(string, string); +#endif + +string +unpackStringCommand(string commandString) +{ +#ifdef SERVER + /* is this supposed to be read from a skill cvar? */ + if (substring(commandString, 0, 6) == "skill:") { + return Skill_GetStringValue(substring(commandString, 6, -1), ""); + } +#endif + + return Constants_LookUp(commandString, commandString); +} + #ifdef NO_LEGACY void readcmd(string foo) @@ -591,7 +607,7 @@ Route_GetJumpVelocity(vector vecFrom, vector vecTo, float flGravMod) } bool -FileExists(string filePath) +fileExists(string filePath) { if (filePath != "") /* not empty */ if not(whichpack(filePath)) /* not present on disk */ @@ -759,4 +775,4 @@ If not available, most new features will be unavailable. * size and volume, unlike [brush-based entities](@ref brushentity). * Generally used for moving, or non moving objects * that interact with the world. - */ \ No newline at end of file + */ diff --git a/src/shared/entities.h b/src/shared/entities.h index 8a960c37..df24f028 100644 --- a/src/shared/entities.h +++ b/src/shared/entities.h @@ -14,6 +14,9 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/* used to keep track of decl across different classnames */ +.string declclass; + /** @defgroup entities Entities @brief Objects within the game world, serving various functions. diff --git a/src/shared/entityDef.h b/src/shared/entityDef.h index 1f6bc495..7de60fb8 100644 --- a/src/shared/entityDef.h +++ b/src/shared/entityDef.h @@ -120,14 +120,15 @@ typedef struct void EntityDef_Init(void); void EntityDef_DebugList(void); string EntityDef_GetKeyValue(string, string); - +float EntityDef_NetIDFromName(string); +string EntityDef_NameFromNetID(float); int EntityDef_IDFromName(string); -string EntityDef_NameFromID(int); string EntityDef_GetSpawnData(int); bool EntityDef_HasSpawnClass(string className); #ifdef SERVER bool EntityDef_Precache(string); +NSEntity EntityDef_SwitchClass(NSEntity target, string className); NSEntity Entity_CreateClass(string className); #endif diff --git a/src/shared/entityDef.qc b/src/shared/entityDef.qc index d2080ce4..ef29d364 100644 --- a/src/shared/entityDef.qc +++ b/src/shared/entityDef.qc @@ -195,7 +195,7 @@ EntityDef_Init(void) } /* load the map specific def file */ - if (FileExists(mapDef)) { + if (fileExists(mapDef)) { EntityDef_ReadFile(mapDef); } @@ -220,9 +220,9 @@ EntityDef_Init(void) } static bool -EntityDef_CheckCondition(int id, string keyWord, float tweakCondition, string keyValue) +EntityDef_CheckCondition(NSEntity target, int id, string keyWord, float tweakCondition, string keyValue) { - int spawnWords = tokenize_console(g_lastSpawnData); + int spawnWords = tokenize_console(target.m_strSpawnData); string key, value; float tmp1, tmp2; @@ -273,7 +273,7 @@ EntityDef_CheckCondition(int id, string keyWord, float tweakCondition, string ke } } - return false; + return (false); } @@ -337,6 +337,8 @@ EntityDef_PrepareEntity(entity target, int id) targetEnt = spawn(NSEntity); } + targetEnt.declclass = g_entDefTable[id].entClass; + /* check if the spawnclass is an entityDef */ for (int i = 0i; i < g_entDefCount; i++) { if (g_entDefTable[id].spawnClass == g_entDefTable[i].entClass) { @@ -356,8 +358,8 @@ EntityDef_PrepareEntity(entity target, int id) if (!isfunction(spawnClass)) { NSError("Unable to find entityDef spawnclass %S", spawnClass); - targetEnt.Destroy(); - return __NULL__; + remove(targetEnt); + return (__NULL__); } /* init */ @@ -405,7 +407,7 @@ EntityDef_PrepareEntity(entity target, int id) string keyValue = argv(2); /* iterate through a bunch of different data to check our condition */ - if (EntityDef_CheckCondition(id, keyWord, tweakCondition, keyValue)) { + if (EntityDef_CheckCondition(target, id, keyWord, tweakCondition, keyValue)) { int tweakGroups = tokenizebyseparator(g_entDefTable[id].tweakKeys, ";"); //print(sprintf("%S passed the check\n", keyWord)); @@ -420,30 +422,44 @@ EntityDef_PrepareEntity(entity target, int id) for (int y = 0; y < tweakSpawns; y+= 2) { //print(sprintf("applying %S and %S\n", argv(y), argv(y+1))); targetEnt.SpawnKey(argv(y), argv(y+1)); + targetEnt.m_strSpawnData = sprintf("%s TWEAK %S %S }", targetEnt.m_strSpawnData, argv(y), argv(y+1)); } } /* retokenize */ tweakGroups = tokenizebyseparator(g_entDefTable[id].tweakKeys, ";"); } + + print("\n"); + print("\n"); + print("\n"); + print("\n"); + print(targetEnt.m_strSpawnData); + print("\n"); + print("\n"); + print("\n"); + print("\n"); } /* retokenize our condition */ spawnWords = tokenizebyseparator(g_entDefTable[id].tweakDefs, ";"); } - targetEnt.m_strModelEventCB = g_entDefTable[id].eventList; /* pass over the event listing */ + /* now that that all methods have been called, we're ready to decide whether to continue this spawn */ + if (wasfreed(targetEnt) == false) { + targetEnt.m_strModelEventCB = g_entDefTable[id].eventList; /* pass over the event listing */ - /* now we rename the classname for better visibility, - but also because some classes need to know. */ - targetEnt.classname = g_entDefTable[id].entClass; - targetEnt.entityDefID = EntityDef_IDFromName(targetEnt.classname); + /* now we rename the classname for better visibility, + but also because some classes need to know. */ + targetEnt.classname = g_entDefTable[id].entClass; + targetEnt.entityDefID = EntityDef_NetIDFromName(targetEnt.classname); - targetEnt.Spawned(); - targetEnt.Respawn(); + targetEnt.Spawned(); + targetEnt.Respawn(); + } g_lastSpawnData = ""; - return targetEnt; + return (targetEnt); } /* precache resources inside an entityDef */ @@ -514,6 +530,10 @@ EntityDef_SpawnClassname(string className) { g_lastSpawnData = __fullspawndata; + if not (className) { + return (__NULL__); + } + for (int i = 0i; i < g_entDefCount; i++) { if (className == g_entDefTable[i].entClass) { if (time < 5.0) { @@ -525,7 +545,30 @@ EntityDef_SpawnClassname(string className) } } - return __NULL__; + return (__NULL__); +} + +NSEntity +EntityDef_SwitchClass(NSEntity target, string className) +{ + NSEntity returnEntity = __NULL__; + float oldTeam = target.team; + g_lastSpawnData = target.m_strSpawnData; + + for (int i = 0i; i < g_entDefCount; i++) { + if (className == g_entDefTable[i].entClass) { + if (time < 5.0) { + EntityDef_Precaches(i); + } + + NSLog("Spawning eDef %S", className); + returnEntity = EntityDef_PrepareEntity(target, i); + returnEntity.team = oldTeam; + return (returnEntity); + } + } + + return (returnEntity); } NSEntity @@ -541,10 +584,10 @@ EntityDef_CreateClassname(string className) /* Failure */ if (test == __NULL__) { new.Destroy(); - return __NULL__; + return (__NULL__); } - return new; + return (new); } static void @@ -603,6 +646,23 @@ EntityDef_DebugList(void) } } +float +EntityDef_NetIDFromName(string defName) +{ +#if 1 + return crc16(true, defName); +#else + if (defName) { + for (int i = 0i; i < g_entDefCount; i++) { + if (defName == g_entDefTable[i].entClass) { + return (i); + } + } + } + + return (-1i); +#endif +} int EntityDef_IDFromName(string defName) @@ -619,13 +679,17 @@ EntityDef_IDFromName(string defName) } string -EntityDef_NameFromID(int defNum) +EntityDef_NameFromNetID(float defNum) { - if (defNum == -1i) { - return ""; + for (int i = 0i; i < g_entDefCount; i++) { + int checkSum = crc16(true, g_entDefTable[i].entClass); + + if (checkSum == defNum) { + return (g_entDefTable[i].entClass); + } } - return g_entDefTable[defNum].entClass; + return ""; } diff --git a/src/shared/fteextensions.qc b/src/shared/fteextensions.qc index 7e4d0c82..6c03b4eb 100644 --- a/src/shared/fteextensions.qc +++ b/src/shared/fteextensions.qc @@ -3258,7 +3258,7 @@ void(entity e, string s) clientcommand = #440; /* Part of KRIMZON_SV_PARSECLIENT float(string s) tokenize = #441; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND*/ string(float n) argv = #442; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND*/ void(entity e, entity tagentity, string tagname) setattachment = #443; /* Part of DP_GFX_QUAKE3MODELTAGS*/ -searchhandle(string pattern, enumflags:float{SB_CASEINSENSITIVE=1<<0,SB_FULLPACKAGEPATH=1<<1,SB_ALLOWDUPES=1<<2,SB_FORCESEARCH=1<<3} flags, float quiet, optional string filterpackage) search_begin = #444; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE +searchhandle(string pattern, enumflags:float{SB_CASEINSENSITIVE=1<<0,SB_FULLPACKAGEPATH=1<<1,SB_ALLOWDUPES=1<<2,SB_FORCESEARCH=1<<3,SB_MULTISEARCH=1<<4,SB_NAMESORT=1<<5} flags, float quiet, optional string filterpackage) search_begin = #444; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE initiate a filesystem scan based upon filenames. Be sure to call search_end on the returned handle. SB_FULLPACKAGEPATH interprets the filterpackage arg as a full package path to avoid gamedir ambiguity, equivelent to whichpack's WP_FULLPACKAGEPATH flag. SB_ALLOWDUPES allows returning multiple entries with the same name (but different package, useful with search_fopen). SB_FORCESEARCH requires use of the filterpackage and SB_FULLPACKAGEPATH flag, initiating searches from gamedirs/packages which are not currently active. */ void(searchhandle handle) search_end = #445; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE*/ diff --git a/src/shared/materials.qc b/src/shared/materials.qc index 816e19eb..835f485d 100644 --- a/src/shared/materials.qc +++ b/src/shared/materials.qc @@ -443,11 +443,11 @@ Materials_Init(void) search_end(pm); /* the way TW did it back in '03 */ - if (FileExists(wastesName)) + if (fileExists(wastesName)) Materials_LoadFromLegacyText(wastesName); /* Trinity-Renderer does it this way */ - if (FileExists(svenName)) + if (fileExists(svenName)) Materials_LoadFromLegacyText(svenName); /* no longer needed! */ diff --git a/src/shared/surfaceproperties.qc b/src/shared/surfaceproperties.qc index a98da965..ab8e5443 100644 --- a/src/shared/surfaceproperties.qc +++ b/src/shared/surfaceproperties.qc @@ -323,6 +323,7 @@ SurfData_Init(void) /* it's OK for one to not exist... */ if (fh < 0) { NSError("missing scripts/surfaceproperties.txt!"); + InitEnd(); return; } @@ -334,6 +335,7 @@ SurfData_Init(void) /* we did not find 'default' as the first entry. */ if (g_spDefaultSet == false) { NSError("no 'default' defined at the top of scripts/surfaceproperties.txt!"); + InitEnd(); return; } diff --git a/src/vgui/ui.qc b/src/vgui/ui.qc index 5e9a5bbf..1d4ee70c 100644 --- a/src/vgui/ui.qc +++ b/src/vgui/ui.qc @@ -447,7 +447,7 @@ UISystem_Init(void) } fclose(fileUI); } else { - error(sprintf("[MENU] Cannot load UI file %s!", strUIFile)); + NSError(sprintf("[MENU] Cannot load UI file %s!", strUIFile)); } #endif