diff --git a/cmdcolors_icexuick.txt b/cmdcolors_icexuick.txt index f4f65f20db..e72090b04f 100644 --- a/cmdcolors_icexuick.txt +++ b/cmdcolors_icexuick.txt @@ -81,7 +81,7 @@ selectedLineWidth 2.0 selectedBlendSrc src_alpha selectedBlendDst one_minus_src_alpha -rangeAttack 1.0 0.3 0.3 0.3 +rangeAttack 1.0 0.3 0.3 0.0 rangeBuild 0.3 1.0 0.3 0.3 rangeRadar 0.3 1.0 0.3 0.3 rangeSonar 0.3 0.3 1.0 0.3 diff --git a/luaui/Widgets/Shaders/attack_range_gl4.vert.glsl b/luaui/Widgets/Shaders/attack_range_gl4.vert.glsl index 1b84b8f84a..1929ba2976 100644 --- a/luaui/Widgets/Shaders/attack_range_gl4.vert.glsl +++ b/luaui/Widgets/Shaders/attack_range_gl4.vert.glsl @@ -19,6 +19,8 @@ uniform float lineAlphaUniform = 1.0; uniform float cannonmode = 0.0; uniform float fadeDistOffset = 0.0; uniform float drawMode = 0.0; +uniform float inMiniMap = 0.0; + uniform sampler2D heightmapTex; uniform sampler2D losTex; // hmm maybe? @@ -143,7 +145,7 @@ void main() { // rotate the circle into unit space, wierd that it has to be rotated on other direction float maxAngleDif = 1; float mainDirDegrees = 0; - if (MAXANGLEDIF != 0) { + if (MAXANGLEDIF > 0.0) { maxAngleDif = fract(MAXANGLEDIF);// goes from 0.0 to 1.0, where 0.25 would mean a 90 deg cone mainDirDegrees = MAXANGLEDIF - maxAngleDif;// Is the offset in degrees. } @@ -249,14 +251,22 @@ void main() { //--- DISTANCE FADE --- vec4 camPos = cameraViewInv[3]; + + // Note that this is not the same as the distance from the unit to the camera, but the distance from the circle to the camera float distToCam = length(modelWorldPos.xyz - camPos.xyz); //dist from cam // FadeStart, FadeEnd, StartAlpha, EndAlpha float fadeDist = visibility.y - visibility.x; + if (ISDGUN > 0.5) { FADEALPHA = clamp((visibility.y + fadeDistOffset + 1000 - distToCam)/(fadeDist),visibility.w,visibility.z); } else { FADEALPHA = clamp((visibility.y + fadeDistOffset - distToCam)/(fadeDist),visibility.w,visibility.z); } + + if (inMiniMap> 0.5){ + FADEALPHA = 1.0; + } + //FADEALPHA = clamp((visibility.y + fadeDistOffset - distToCam)/(fadeDist),visibility.w,visibility.z); //--- Optimize by anything faded out getting transformed back to origin with 0 range? @@ -297,7 +307,12 @@ void main() { //worldPos = circleWorldPos; //worldPos.a = RANGE; alphaControl.x = circlepointposition.z; // save circle progress here - gl_Position = cameraViewProj * vec4(circleWorldPos.xyz, 1.0); + + if (inMiniMap < 0.5) { + gl_Position = cameraViewProj * vec4(circleWorldPos.xyz, 1.0); + } else { + gl_Position = mmDrawViewProj * vec4(circleWorldPos.xyz, 1.0); + } //lets blend the alpha here, and save work in FS: float outalpha = OUTOFBOUNDSALPHA * (MOUSEALPHA + FADEALPHA * lineAlphaUniform); diff --git a/luaui/Widgets/Shaders/weapon_range_rings_unified_gl4.frag.glsl b/luaui/Widgets/Shaders/weapon_range_rings_unified_gl4.frag.glsl new file mode 100644 index 0000000000..167f29d969 --- /dev/null +++ b/luaui/Widgets/Shaders/weapon_range_rings_unified_gl4.frag.glsl @@ -0,0 +1,39 @@ +#version 330 + +#extension GL_ARB_uniform_buffer_object : require +#extension GL_ARB_shading_language_420pack: require +// This shader is (c) Beherith (mysterme@gmail.com), released under the MIT license + +//__DEFINES__ + +#line 20000 + +uniform float selUnitCount = 1.0; +uniform float selBuilderCount = 1.0; +uniform float drawAlpha = 1.0; +uniform float drawMode = 0.0; + +//_ENGINEUNIFORMBUFFERDEFS__ + +in DataVS { + flat vec4 v_blendedcolor; +}; + +out vec4 fragColor; + +void main() { + + fragColor = v_blendedcolor; + // For testing: + #if (DEBUG == 1) + if (fract(gl_FragCoord.x * 0.125) < 0.4) { + #if (STATICUNITS == 0) + fragColor.rgba *= 0.0; + #endif + }else{ + #if(STATICUNITS == 1) + fragColor.rgba *= 0.0; + #endif + } + #endif +} \ No newline at end of file diff --git a/luaui/Widgets/Shaders/weapon_range_rings_unified_gl4.vert.glsl b/luaui/Widgets/Shaders/weapon_range_rings_unified_gl4.vert.glsl new file mode 100644 index 0000000000..25afeec90e --- /dev/null +++ b/luaui/Widgets/Shaders/weapon_range_rings_unified_gl4.vert.glsl @@ -0,0 +1,457 @@ + +#version 420 +#extension GL_ARB_uniform_buffer_object : require +#extension GL_ARB_shader_storage_buffer_object : require +#extension GL_ARB_shading_language_420pack: require +// This shader is (c) Beherith (mysterme@gmail.com), released under the MIT license +#line 10000 + +//__DEFINES__ + +layout (location = 0) in vec4 circlepointposition; // x,y in range [-1,1], progress in range [0,1] +layout (location = 1) in vec4 posscale; // abs pos for static units, offset for dynamic units, scale is actual range, Y is turretheight +layout (location = 2) in vec4 color1; // Base color for the circle +layout (location = 3) in vec4 visibility; // FadeStart, FadeEnd, StartAlpha, EndAlpha +layout (location = 4) in vec4 projectileParams; // projectileSpeed, iscylinder!!!! , heightBoostFactor , heightMod +layout (location = 5) in vec4 additionalParams; // groupselectionfadescale, weaponType, ISDGUN, MAXANGLEDIF +layout (location = 6) in uvec4 instData; + +uniform float lineAlphaUniform = 1.0; +uniform float cannonmode = 0.0; +uniform float fadeDistOffset = 0.0; +uniform float inMiniMap = 0.0; + + +uniform float selUnitCount = 1.0; +uniform float selBuilderCount = 1.0; +uniform float drawAlpha = 1.0; +uniform float drawMode = 0.0; + + +uniform sampler2D heightmapTex; +uniform sampler2D losTex; // hmm maybe? +uniform sampler2D mapNormalTex; // hmm maybe? + +// Ease-of-use defines for the vertex shader outputs +#define V_CIRCLEPROGRESS v_params.x +#define V_GROUPSELECTIONFADESCALE v_params.y +#define V_WEAPONTYPE v_params.z + +out DataVS { + flat vec4 v_blendedcolor; +}; + +//__ENGINEUNIFORMBUFFERDEFS__ + +#if (STATICUNITS == 0) + struct SUniformsBuffer { + uint composite; // u8 drawFlag; u8 unused1; u16 id; + + uint unused2; + uint unused3; + uint unused4; + + float maxHealth; + float health; + float unused5; + float unused6; + + vec4 drawPos; // Note that this is map height at unit.xz + vec4 speed; + vec4[4] userDefined; //can't use float[16] because float in arrays occupies 4 * float space + }; + + layout(std140, binding=1) readonly buffer UniformsBuffer { + SUniformsBuffer uni[]; + }; + + #define UNITID (uni[instData.y].composite >> 16) +#endif + +#line 11000 + +vec2 inverseMapSize = 1.0 / mapSize.xy; + +float heightAtWorldPos(vec2 w){ + // Some texel magic to make the heightmap tex perfectly align: + const vec2 heightmaptexel = vec2(8.0, 8.0); + w += vec2(-8.0, -8.0) * (w * inverseMapSize) + vec2(4.0, 4.0) ; + + vec2 uvhm = clamp(w, heightmaptexel, mapSize.xy - heightmaptexel); + uvhm = uvhm * inverseMapSize; + + return textureLod(heightmapTex, uvhm, 0.0).x; +} + +vec4 normalsAndHeightAtWorldPos(vec2 w){ + // Some texel magic to make the heightmap tex perfectly align: + // Some texel magic to make the heightmap tex perfectly align: + const vec2 heightmaptexel = vec2(8.0, 8.0); + w += vec2(-8.0, -8.0) * (w * inverseMapSize) + vec2(4.0, 4.0) ; + + vec2 uvhm = clamp(w, heightmaptexel, mapSize.xy - heightmaptexel); + uvhm = uvhm * inverseMapSize; + vec4 heightAndNormal = vec4(0.0); + heightAndNormal.w = textureLod(mapNormalTex, uvhm, 0.0).x; + heightAndNormal.xz = textureLod(mapNormalTex, uvhm, 0.1).ra; + heightAndNormal.y = 1.0 - sqrt(1.0 - dot(heightAndNormal.xz, heightAndNormal.xz)); + return heightAndNormal; +} + +float GetRangeFactor(float projectileSpeed) { // returns >0 if weapon can shoot here, <0 if it cannot, 0 if just right + // on first run, with yDiff = 0, what do we get? + float speed2d = projectileSpeed * 0.707106; + float gravity = 120.0 * (0.001111111); + return ((speed2d * speed2d) * 2.0 ) / (gravity); +} + +float GetRange2DCannon(float yDiff,float projectileSpeed,float rangeFactor,float heightBoostFactor) { // returns >0 if weapon can shoot here, <0 if it cannot, 0 if just right + // on first run, with yDiff = 0, what do we get? + + //float factor = 0.707106; + float smoothHeight = 100.0; + float speed2d = projectileSpeed*0.707106; + float speed2dSq = speed2d * speed2d; + float gravity = -1.0* (120.0 /900); + + if (heightBoostFactor < 0){ + heightBoostFactor = (2.0 - rangeFactor) / sqrt(rangeFactor); + } + + if (yDiff < -100.0){ + yDiff = yDiff * heightBoostFactor; + }else { + if (yDiff < 0.0) { + yDiff = yDiff * (1.0 + (heightBoostFactor - 1.0 ) * (-1.0 * yDiff) * 0.01); + } + } + + float root1 = speed2dSq + 2 * gravity *yDiff; + if (root1 < 0.0 ){ + return 0.0; + }else{ + return rangeFactor * ( speed2dSq + speed2d * sqrt( root1 ) ) / (-1.0 * gravity); + } +} + +vec2 rotate2D(vec2 v, float a) { + float s = sin(a); + float c = cos(a); + mat2 m = mat2(c, s, -s, c); + return m * v; +} + +//float heightMod  default: 0.2 (0.8 for #Cannon, 1.0 for #BeamLaser and #LightningCannon) +//Changes the spherical weapon range into an ellipsoid. Values above 1.0 mean the weapon cannot target as high as it can far, values below 1.0 mean it can target higher than it can far. For example 0.5 would allow the weapon to target twice as high as far. + +//float heightBoostFactor default: -1.0 +//Controls the boost given to range by high terrain. Values > 1.0 result in increased range, 0.0 means the cannon has fixed range regardless of height difference to target. Any value < 0.0 (i.e. the default value) result in an automatically calculated value based on range and theoretical maximum range. + +// Ease of use defines for the vertex shader inputs: +#define RANGE posscale.w +#define TURRETHEIGHT posscale.y + +#define PROJECTILESPEED projectileParams.x +#define ISCYLINDER projectileParams.y +#define HEIGHTBOOSTFACTOR projectileParams.z +#define HEIGHTMOD projectileParams.w + +#define GROUPSELECTIONFADESCALE additionalParams.x +#define WEAPONTYPE additionalParams.y +#define ISDGUN additionalParams.z +#define MAXANGLEDIF additionalParams.w + +#define FADESTART visibility.x +#define FADEEND visibility.y +#define STARTALPHA visibility.z +#define ENDALPHA visibility.w + +#define UNUSEDALPHA alphaControl.x +#define OUTOFBOUNDSALPHA alphaControl.y +#define FADEALPHA alphaControl.z +#define MOUSEALPHA alphaControl.w + +#define SELECTEDNESS uni[instData.y].userDefined[1].z + +bool isSphereVisible(vec3 position, float radius) +{ + vec4 planes[6]; + mat4 m = cameraViewProj; + + // Extract the frustum planes from the combined view-projection matrix + planes[0] = m[3] + m[0]; // Left plane + planes[1] = m[3] - m[0]; // Right plane + planes[2] = m[3] + m[1]; // Bottom plane + planes[3] = m[3] - m[1]; // Top plane + planes[4] = m[3] + m[2]; // Near plane + planes[5] = m[3] - m[2]; // Far plane + + // Normalize the plane equations + for(int i = 0; i < 6; i++) + { + float length = length(planes[i].xyz); + planes[i] /= length; + } + + // Check if the sphere is outside any of the frustum planes + for(int i = 0; i < 6; i++) + { + float distance = dot(planes[i].xyz, position) + planes[i].w; + if(distance < -radius) + return false; // Sphere is completely outside this plane + } + + return true; // Sphere is at least partially inside the frustum +} + +void main() { + vec4 circleWorldPos = vec4(1.0); + vec3 modelWorldPos = vec3(0.0); + float maxAngleDif = 1; + float mainDirDegrees = 0; + vec4 circleprogress = vec4(0.0); + #if (STATICUNITS == 1) + modelWorldPos = posscale.xyz; + circleWorldPos.xz = circlepointposition.xy * RANGE + posscale.xz; + #else + // Get the center pos of the unit + modelWorldPos = uni[instData.y].drawPos.xyz; + + // The turret is a bit higher up than drawPos.y (which is the ground pos) + modelWorldPos.y += TURRETHEIGHT; + + // Get its heading + float unitHeading = uni[instData.y].drawPos.w ; + + circleprogress.xy = circlepointposition.xy; + // find angle between unit Heading and circleprogress.xy + //unitHeading is -pi to +pi, with zero on z+, and increasing towards x+ + //circleheading is -pi to +pi, with zero z-, and increasing towards x+ + + // rotate the circle into unit space, wierd that it has to be rotated on other direction + if (MAXANGLEDIF > 0.0) { + maxAngleDif = fract(MAXANGLEDIF);// goes from 0.0 to 1.0, where 0.25 would mean a 90 deg cone + mainDirDegrees = MAXANGLEDIF - maxAngleDif;// Is the offset in degrees. + } + circleprogress.xy = rotate2D(circleprogress.xy, (3.141592 -1.0*unitHeading + mainDirDegrees * 3.141592 / 180.0)); + if (ISDGUN > 0.5) { + circleWorldPos.xz = circleprogress.xy * RANGE * 1.05 + modelWorldPos.xz; + } else { + circleWorldPos.xz = circleprogress.xy * RANGE + modelWorldPos.xz; + } + #endif + + + + circleprogress.w = circlepointposition.z; + v_blendedcolor = color1; + + #if (STATICUNITS == 1) + //gl_Position = cameraViewProj * vec4(circleWorldPos.xyz, 1.0); return; + #endif + + vec4 alphaControl = vec4(1.0); + + // get heightmap + circleWorldPos.y = heightAtWorldPos(circleWorldPos.xz); + + + if (cannonmode > 0.5){ + + // BAR only has 3 distinct ballistic projectiles, heightBoostFactor is only a handful from -1 to 2.8 and 6 and 8 + // gravity we can assume to be linear + + float heightDiff = (circleWorldPos.y - modelWorldPos.y) * 0.5; + + float rangeFactor = RANGE / GetRangeFactor(PROJECTILESPEED); //correct + if (rangeFactor > 1.0 ) rangeFactor = 1.0; + if (rangeFactor <= 0.0 ) rangeFactor = 1.0; + float radius = RANGE;// - heightDiff; + float adjRadius = GetRange2DCannon(heightDiff * HEIGHTMOD, PROJECTILESPEED, rangeFactor, HEIGHTBOOSTFACTOR); + float adjustment = radius * 0.5; + float yDiff = 0; + float adds = 0; + //for (int i = 0; i < mod(timeInfo.x/8,16); i ++){ //i am a debugging god + for (int i = 0; i < 16; i ++){ + if (adjRadius > radius){ + radius = radius + adjustment; + adds = adds + 1; + }else{ + radius = radius - adjustment; + adds = adds - 1; + } + adjustment = adjustment * 0.5; + circleWorldPos.xz = circleprogress.xy * radius + modelWorldPos.xz; + float newY = heightAtWorldPos(circleWorldPos.xz ); + yDiff = abs(circleWorldPos.y - newY); + circleWorldPos.y = max(0, newY); + heightDiff = circleWorldPos.y - modelWorldPos.y; + adjRadius = GetRange2DCannon(heightDiff * HEIGHTMOD, PROJECTILESPEED, rangeFactor, HEIGHTBOOSTFACTOR); + } + }else{ + if (ISCYLINDER < 0.5){ // isCylinder + //simple implementation, 4 samples per point + //for (int i = 0; i -20) { // for submerged units, try to keep the ranges above the water for clarity + modelWorldPos.y = max(1, modelWorldPos.y); + circleWorldPos.y = max(1, circleWorldPos.y); + } + + + + // -- HANDLE MAXANGLEDIFF + // If the unit cant fire in that direction due to maxanglediff constraints, then put the point back to modelWorldPos + // Also, dont + // convert current circleprogress to relative heading: + float relheadingradians = abs(((circleprogress.w - 0.5)) * 2); + if (MAXANGLEDIF != 0.0) { + if(relheadingradians > maxAngleDif){ + circleWorldPos.xyz = modelWorldPos.xyz; + } + OUTOFBOUNDSALPHA = 1.0; + } + + circleWorldPos.y += 4; // lift it from the ground + + + //--- DISTANCE FADE --- + vec4 camPos = cameraViewInv[3]; + + // Note that this is not the same as the distance from the unit to the camera, but the distance from the circle to the camera + float distToCam = length(modelWorldPos.xyz - camPos.xyz) ; //dist from cam + // FadeStart, FadeEnd, StartAlpha, EndAlpha + float fadeDist = FADEEND - FADESTART; + + // TODO VALIDATE + if (ISDGUN > 0.5) { + FADEALPHA = clamp((FADEEND + fadeDistOffset + 1000 - distToCam)/(fadeDist), ENDALPHA, STARTALPHA); + } else { + FADEALPHA = clamp((FADEEND + fadeDistOffset - distToCam)/(fadeDist), ENDALPHA, STARTALPHA); + } + // -- IN-SHADER MOUSE-POS BASED HIGHLIGHTING + float disttomousefromunit = 1.0 - smoothstep(48, 64, length(modelWorldPos.xz - mouseWorldPos.xz)); + // this will be positive if in mouse, negative else + float highlightme = clamp( (disttomousefromunit ) + 0.0, 0.0, 1.0); + // Note that this doesnt really work well with boundary-only stenciling, due to random draw order. + MOUSEALPHA = (0.1 + 0.5 * step(0.5,drawMode)) * highlightme; + + + if (inMiniMap> 0.5){ + // No extra fade control when on the minimap + FADEALPHA = 1.0; + }else{ + // TODO if the sphere were to be completely faded out, dont draw it at all: + if (highlightme < 0.0 ){ + if (FADESTART < FADEEND) { + // Rings that fade out on distance + if ((distToCam + RANGE) > FADEEND) { + FADEALPHA = 0.0; + circleWorldPos.xz = modelWorldPos.xz; + } + }else { + // Rings that fade out when close to the camera + // TODO ANTINUKES! + if ((distToCam - RANGE) < FADEEND) { + FADEALPHA = 0.0; + //circleWorldPos.xz = modelWorldPos.xz; + } + } + + //--- Optimize by anything faded out getting transformed back to origin with 0 range? + //seems pretty ok! + + //if a sphere at modelworldpos.xyz, with range poscale.w is out of the viewport, set visible to false: + if (isSphereVisibleXY(vec4(modelWorldPos.xyz, 1.0), posscale.w * 3.0 )){ + //circleWorldPos.xz = modelWorldPos.xz; + } + } + } + + //FADEALPHA = clamp((FADEEND + fadeDistOffset - distToCam)/(fadeDist), ENDALPHA, STARTALPHA); + + + if (cannonmode > 0.5){ + // cannons should fade distance based on their range + //float cvmin = max(FADESTART + fadeDistOffset, 2* RANGE); + //float cvmax = max(FADEEND + fadeDistOffset, 4* RANGE); + //FADEALPHA = clamp((cvmin - distToCam)/(cvmax - cvmin + 1.0),STARTALPHA , ENDALPHA); + } + + v_blendedcolor = color1; + + // -- DARKEN OUT OF LOS + //vec4 losTexSample = texture(losTex, vec2(circleWorldPos.x / mapSize.z, circleWorldPos.z / mapSize.w)); // lostex is PO2 + //float inlos = dot(losTexSample.rgb,vec3(0.33)); + //inlos = clamp(inlos*5 -1.4 , 0.5,1.0); // fuck if i know why, but change this if LOSCOLORS are changed! + //v_blendedcolor.rgb *= inlos; + + // --- YES FOG + float fogDist = length((cameraView * vec4(circleWorldPos.xyz,1.0)).xyz); + float fogFactor = clamp((fogParams.y - fogDist) * fogParams.w, 0, 1); + v_blendedcolor.rgb = mix(fogColor.rgb, vec3(v_blendedcolor), fogFactor); + + + + + + // ------------ dump the stuff for FS -------------------- + //V_CIRCLEPROGRESS = circlepointposition.z; // save circle progress here + + + if (inMiniMap < 0.5) { + gl_Position = cameraViewProj * vec4(circleWorldPos.xyz, 1.0); + //pull 16 elmos forward in Z: + gl_Position.z = (gl_Position.z) - 128.0 / (gl_Position.w); // send 16 elmos forward in Z + } else { + gl_Position = mmDrawViewProj * vec4(circleWorldPos.xyz, 1.0); + } + + //lets blend the alpha here, and save work in FS: + float outalpha = OUTOFBOUNDSALPHA * (MOUSEALPHA + FADEALPHA * lineAlphaUniform); + v_blendedcolor.a *= outalpha ; + if (ISDGUN > 0.5) { + v_blendedcolor.a = clamp(v_blendedcolor.a * 3, 0.1, 1.0); + } + // Additional unituniform based selectedness metrics: + + float vs_selunitcount = selUnitCount; + // -- nano is 2 + if(WEAPONTYPE == 2.0) { + vs_selunitcount = selBuilderCount; + } + vs_selunitcount = clamp(selUnitCount, 1, 25); + + float innerRingDim = GROUPSELECTIONFADESCALE * 0.1 * vs_selunitcount; + float finalAlpha = drawAlpha; + if(drawMode == 2.0) { + finalAlpha = drawAlpha / pow(innerRingDim, 2); + } + finalAlpha = clamp(finalAlpha, 0.0, 1.0); + v_blendedcolor.a *= finalAlpha; + + //vec4 heightAndNormal = normalsAndHeightAtWorldPos(circleWorldPos.xz); + //v_blendedcolor.rgb = heightAndNormal.xyz * 0.5 + 0.5; + //v_blendedcolor.rgb = vec3(fract(distToCam/100)); +} \ No newline at end of file diff --git a/luaui/Widgets/gui_anti_ranges.lua b/luaui/Widgets/gui_anti_ranges.lua index 0d45816475..6c4db033fe 100644 --- a/luaui/Widgets/gui_anti_ranges.lua +++ b/luaui/Widgets/gui_anti_ranges.lua @@ -8,7 +8,7 @@ function widget:GetInfo() license = "GNU GPL, v2 or later", version = 4, layer = 5, - enabled = true + enabled = false } end diff --git a/luaui/Widgets/gui_attackrange_gl4.lua b/luaui/Widgets/gui_attackrange_gl4.lua index 16600f2cbd..19ff04260b 100644 --- a/luaui/Widgets/gui_attackrange_gl4.lua +++ b/luaui/Widgets/gui_attackrange_gl4.lua @@ -16,6 +16,9 @@ function widget:GetInfo() } end +------------------------------------- +local autoReload = false + --------------------------------------------------------------------------------------------------------------------------- -- Bindable action: cursor_range_toggle -- The widget's individual unit type's display setup is saved in LuaUI/config/AttackRangeConfig2.lua @@ -35,46 +38,63 @@ local buttonConfig = { local colorConfig = { drawStencil = true, -- whether to draw the outer, merged rings (quite expensive!) - cannon_separate_stencil = false, -- set to true to have cannon and ground be on different stencil mask + cannon_separate_stencil = true, -- set to true to have cannon and ground be on different stencil mask drawInnerRings = true, -- whether to draw inner, per attack rings (very cheap) externalalpha = 0.80, -- alpha of outer rings - internalalpha = 0.20, -- alpha of inner rings - fill_alpha = 0.10, -- this is the solid color in the middle of the stencil + internalalpha = 0.17, -- alpha of inner rings + fill_alpha = 0.12, -- this is the solid color in the middle of the stencil outer_fade_height_difference = 2500, -- this is the height difference at which the outer ring starts to fade out compared to inner rings ground = { color = { 1.0, 0.22, 0.05, 0.60 }, - fadeparams = { 1500, 2200, 1.0, 0.0 }, -- FadeStart, FadeEnd, StartAlpha, EndAlpha + fadeparams = { 1500, 3200, 1.0, 0.0 }, -- FadeStart, FadeEnd, StartAlpha, EndAlpha groupselectionfadescale = 0.75, externallinethickness = 3.0, - internallinethickness = 2.0, + internallinethickness = 1.8, + minimapexternallinethickness = 1.0, + minimapinternallinethickness = 0.5, }, nano = { - color = { 0.24, 1.0, 0.2, 0.40 }, + color = { 0.24, 1.0, 0.2, 0.60 }, fadeparams = { 2000, 4000, 1.0, 0.0 }, -- FadeStart, FadeEnd, StartAlpha, EndAlpha groupselectionfadescale = 0.05, externallinethickness = 3.0, internallinethickness = 2.0, + minimapexternallinethickness = 1.0, + minimapinternallinethickness = 0.5, }, AA = { color = { 0.8, 0.44, 2.0, 0.40 }, - fadeparams = { 1500, 2200, 1.0, 0.0 }, -- FadeStart, FadeEnd, StartAlpha, EndAlpha + fadeparams = { 1500, 3200, 1.0, 0.0 }, -- FadeStart, FadeEnd, StartAlpha, EndAlpha groupselectionfadescale = 0.75, - externallinethickness = 2.5, - internallinethickness = 2.0, + externallinethickness = 3.0, + internallinethickness = 1.8, + minimapexternallinethickness = 1.5, + minimapinternallinethickness = 0.5, }, cannon = { - color = { 1.0, 0.22, 0.05, 0.60 }, - fadeparams = { 1500, 2200, 1.0, 0.0 }, -- FadeStart, FadeEnd, StartAlpha, EndAlpha + color = {1.0, 0.22, 0.05, 0.60}, + fadeparams = { 1500, 3600, 1.0, 0.0 }, -- FadeStart, FadeEnd, StartAlpha, EndAlpha groupselectionfadescale = 0.75, externallinethickness = 3.0, internallinethickness = 2.0, + minimapexternallinethickness = 1.0, + minimapinternallinethickness = 0.5, + }, + lrpc = { + color = {1.0, 0.22, 0.05, 0.60}, + fadeparams = { 5000, 1000, 1.0, 0.5 }, -- FadeStart, FadeEnd, StartAlpha, EndAlpha + groupselectionfadescale = 0.75, + externallinethickness = 2.0, + internallinethickness = 2.0, -- Not used as LRPC is not stencilled + minimapexternallinethickness = 2.0, + minimapinternallinethickness = 0.5, }, } ---------------------------------- local show_selected_weapon_ranges = true -local weaponTypeMap = { 'ground', 'nano', 'AA', 'cannon' } +local weaponTypeMap = { 'ground', 'nano', 'AA', 'cannon', 'lrpc' } local unitDefRings = {} --each entry should be a unitdefIDkey to a table: @@ -180,11 +200,14 @@ local function initializeUnitDefRing(unitDefID) local color = colorConfig[weaponTypeMap[weaponType]].color local fadeparams = colorConfig[weaponTypeMap[weaponType]].fadeparams - local isCylinder = weaponDef.cylinderTargeting and 1 or 0 + local isCylinder = 0 + if (weaponDef.cylinderTargeting) and (weaponDef.cylinderTargeting > 0.0) then + isCylinder = 1 + end local isDgun = (weaponDef.type == "DGun") and 1 or 0 local wName = weaponDef.name - if (weaponDef.type == "AircraftBomb") or (wName:find("bogus")) then + if (weaponDef.type == "AircraftBomb") or (wName:find("bogus")) or weaponDef.customParams.bogus then range = 0 end --Spring.Echo("weaponNum: ".. weaponNum ..", name: " .. tableToString(weaponDef.name)) @@ -207,7 +230,11 @@ local function initializeUnitDefRing(unitDefID) -- maindir "0 1 0" is designed for shooting at feet prevention! local maxangledif = 0 - if weapons[weaponNum].maxAngleDif > -1 then + + -- customParams (note the case), is a table of strings always + if (weapons[weaponNum].maxAngleDif > -1) and + (not (weaponDef.customParams and weaponDef.customParams.noattackrangearc)) then + --Spring.Echo(weaponDef.customParams)--, weapons[weaponNum].customParams.noattackarc) local offsetdegrees = 0 local difffract = 0 @@ -237,7 +264,7 @@ local function initializeUnitDefRing(unitDefID) maxangledif = maxangledif + difffract else - end + end @@ -248,18 +275,18 @@ local function initializeUnitDefRing(unitDefID) --for k,v in pairs(weapons[weaponNum]) do Spring.Echo(k,v)end end - --if weapons[weaponNum].maxAngleDif then Spring.Echo(weapons[weaponNum].maxAngleDif,'for',weaponDef.name ) end - - local ringParams = { range, color[1], color[2], color[3], color[4], - fadeparams[1], fadeparams[2], fadeparams[3], fadeparams[4], - weaponDef.projectilespeed or 1, - isCylinder, - weaponDef.heightBoostFactor or 0, - weaponDef.heightMod or 0, - groupselectionfadescale, - weaponType, - isDgun, - maxangledif + --if weapons[weaponNum].maxAngleDif then Spring.Echo(weapons[weaponNum].maxAngleDif,'for',weaponDef.name, 'saved as',maxangledif ) end + + local ringParams = { range, color[1], color[2], color[3], color[4], --5 + fadeparams[1], fadeparams[2], fadeparams[3], fadeparams[4], --9 + weaponDef.projectilespeed or 1, --10 + isCylinder,-- and 1 or 0, (11) + weaponDef.heightBoostFactor or 0, --12 + weaponDef.heightMod or 0, --13 + groupselectionfadescale, --14 + weaponType, --15 + isDgun, --16 + maxangledif --17 } unitDefRings[unitDefID]['rings'][weaponNum] = ringParams end @@ -331,6 +358,11 @@ local GetActiveCommand = Spring.GetActiveCommand local GetSelectedUnits = Spring.GetSelectedUnits local chobbyInterface +local CMD_ATTACK = CMD.ATTACK +local CMD_FIGHT = CMD.FIGHT +local CMD_AREA_ATTACK = CMD.AREA_ATTACK +local CMD_MANUALFIRE = CMD.MANUALFIRE + function widget:TextCommand(command) local mycommand = false --buttonConfig["enemy"][tag] @@ -367,18 +399,18 @@ local largeCircleSegments = 512 local smallCircleVBO = nil local smallCircleSegments = 128 -local weaponTypeToString = { "ground", "nano", "AA", "cannon", } +local weaponTypeToString = { "ground", "nano", "AA", "cannon", 'lrpc' } local allyenemypairs = { "ally", "enemy" } local attackRangeClasses = { 'enemyground', 'enemyAA', 'enemynano', 'allyground', 'allyAA', 'enemycannon', 'allycannon', - 'allynano' } + 'allynano', 'allylrpc', 'enemylrpc' } local attackRangeVAOs = {} local circleInstanceVBOLayout = { - { id = 1, name = 'posscale', size = 4 }, -- a vec4 for pos + scale + { id = 1, name = 'posscale', size = 4 }, -- abs pos for static units, offset for dynamic units, scale is actual range, Y is turretheight { id = 2, name = 'color1', size = 4 }, -- vec4 the color of this new - { id = 3, name = 'visibility', size = 4 }, --- vec4 heightdrawstart, heightdrawend, fadefactorin, fadefactorout + { id = 3, name = 'visibility', size = 4 }, --- vec4 FadeStart, FadeEnd, StartAlpha, EndAlpha { id = 4, name = 'projectileParams', size = 4 }, --- heightboost gradient - { id = 5, name = 'additionalParams', size = 4 }, --- groupselectionfadescale, +3 additional reserved + { id = 5, name = 'additionalParams', size = 4 }, --- groupselectionfadescale, weaponType, ISDGUN, MAXANGLEDIF { id = 6, name = 'instData', size = 4, type = GL.UNSIGNED_INT }, } @@ -389,12 +421,17 @@ local attackRangeShader = nil local shaderSourceCache = { shaderName = 'Attack Range GL4', - vssrcpath = "LuaUI/Widgets/Shaders/attack_range_gl4.vert.glsl", - fssrcpath = "LuaUI/Widgets/Shaders/attack_range_gl4.frag.glsl", - shaderConfig = {MYGRAVITY = Game.gravity + 0.1,}, + vssrcpath = "LuaUI/Widgets/Shaders/weapon_range_rings_unified_gl4.vert.glsl", + fssrcpath = "LuaUI/Widgets/Shaders/weapon_range_rings_unified_gl4.frag.glsl", + shaderConfig = { + MYGRAVITY = Game.gravity + 0.1, + STATICUNITS = 0, + DEBUG = autoReload and 1 or 0, + }, uniformInt = { heightmapTex = 0, losTex = 1, + mapNormalTex = 2, }, uniformFloat = { lineAlphaUniform = 1, @@ -403,6 +440,7 @@ local shaderSourceCache = { drawMode = 0, selBuilderCount = 1.0, selUnitCount = 1.0, + inMiniMap = 0.0, }, } @@ -411,38 +449,11 @@ local function goodbye(reason) widgetHandler:RemoveWidget() end -local function makeCircleVBO(circleSegments) - circleSegments = circleSegments - 1 -- for po2 buffers - local circleVBO = gl.GetVBO(GL.ARRAY_BUFFER, true) - if circleVBO == nil then goodbye("Failed to create circleVBO") end - - local VBOLayout = { - { id = 0, name = "position", size = 4 }, - } - - local VBOData = {} - - for i = 0, circleSegments do -- this is +1 - VBOData[#VBOData + 1] = math.sin(math.pi * 2 * i / circleSegments) -- X - VBOData[#VBOData + 1] = math.cos(math.pi * 2 * i / circleSegments) -- Y - VBOData[#VBOData + 1] = i / circleSegments -- circumference [0-1] - VBOData[#VBOData + 1] = 0 - end - - circleVBO:Define( - circleSegments + 1, - VBOLayout - ) - circleVBO:Upload(VBOData) - return circleVBO -end - local cacheTable = {} for i = 1, 24 do cacheTable[i] = 0 end -- code for selected units start here - local selectedUnits = {} local selUnits = {} local updateSelection = false @@ -485,9 +496,19 @@ local function AddSelectedUnit(unitID, mouseover) if weapon.onlyTargets and weapon.onlyTargets.vtol then entry.weapons[weaponNum] = 3 -- weaponTypeMap[3] is "AA" elseif weaponDef.type == "Cannon" then - entry.weapons[weaponNum] = 4 -- weaponTypeMap[4] is "cannon" - else + if weaponDef.range > 2000 then + entry.weapons[weaponNum] = 5 -- weaponTypeMap[5] is "lrpc" + else + entry.weapons[weaponNum] = 4 -- weaponTypeMap[4] is "cannon" + end + elseif weaponDef.type == "Melee" then entry.weapons[weaponNum] = 1 -- weaponTypeMap[1] is "ground" + else + if weaponDef.range > 2000 then + entry.weapons[weaponNum] = 5 + else + entry.weapons[weaponNum] = 1 -- weaponTypeMap[1] is "ground" + end end end end @@ -503,7 +524,7 @@ local function AddSelectedUnit(unitID, mouseover) end - local x, y, z, mpx, mpy, mpz, apx, apy, apz = spGetUnitPosition(unitID, true, true) + --for weaponNum = 1, #weapons do local addedRings = 0 @@ -539,8 +560,25 @@ local function AddSelectedUnit(unitID, mouseover) local ringParams = unitDefRings[unitDefID]['rings'][j] if drawIt and ringParams[1] > 0 then + + local weaponID = j + -- TODO: + -- Weapons aim from their WPY positions, but that can change for e.g. popups! + -- This is quite important to pass in as posscale.y! + -- Need to cache weaponID of the respective weapon for this to work + -- also assumes that weapons are centered onto drawpos + local x, y, z, mpx, mpy, mpz, apx, apy, apz = spGetUnitPosition(unitID, true, true) + local wpx, wpy, wpz, wdx, wdy, wdz = Spring.GetUnitWeaponVectors(unitID, weaponID) + --Spring.Echo("unitID", unitID,"weaponID", weaponID, "y", y, "mpy", mpy,"wpy", wpy) + + -- Now this is a truly terrible hack, we cache each unitDefID's max weapon turret height at position 18 in the table + -- so it only goes up with popups + local turretHeight = math.max(ringParams[18] or 0, (wpy or mpy ) - y) + ringParams[18] = turretHeight + + cacheTable[1] = mpx - cacheTable[2] = mpy + cacheTable[2] = turretHeight cacheTable[3] = mpz local vaokey = allystring .. weaponTypeToString[weaponType] @@ -916,7 +954,7 @@ function widget:RecvLuaMsg(msg, playerID) end end -local drawcounts = {} +local drawcounts = {} local cameraHeightFactor = 0 @@ -925,6 +963,7 @@ local function GetCameraHeightFactor() end local groundnukeair = { "ground", "nano", "AA" } +local cannonlrpc = { "cannon", "lrpc" } local function DRAWRINGS(primitiveType, linethickness) if not show_selected_weapon_ranges and not isBuilding then return end local stencilMask @@ -948,29 +987,39 @@ local function DRAWRINGS(primitiveType, linethickness) attackRangeShader:SetUniform("cannonmode", 1) for i, allyState in ipairs(allyenemypairs) do - local atkRangeClass = allyState .. "cannon" - local iT = attackRangeVAOs[atkRangeClass] - local stencilOffset = colorConfig.cannon_separate_stencil and 3 or 0 - stencilMask = 2 ^ (4 * (i - 1) + stencilOffset) -- if 0 then it's on the same as "ground" - drawcounts[stencilMask] = iT.usedElements - if iT.usedElements > 0 then - if linethickness then - glLineWidth(colorConfig['cannon'][linethickness] * cameraHeightFactor) + for j, wt in ipairs(cannonlrpc) do + if linethickness or wt == 'cannon' then + local atkRangeClass = allyState .. wt + local iT = attackRangeVAOs[atkRangeClass] + local stencilOffset = colorConfig.cannon_separate_stencil and 3 or 0 + stencilMask = 2 ^ (4 * (i - 1) + stencilOffset) -- if 0 then it's on the same as "ground" + drawcounts[stencilMask] = iT.usedElements + if iT.usedElements > 0 then + if linethickness then + glLineWidth(colorConfig[wt][linethickness] * cameraHeightFactor) + end + glStencilMask(stencilMask) + glStencilFunc(GL_NOTEQUAL, stencilMask, stencilMask) + iT.VAO:DrawArrays(primitiveType, iT.numVertices, 0, iT.usedElements, 0) -- +1!!! + end end - glStencilMask(stencilMask) - glStencilFunc(GL_NOTEQUAL, stencilMask, stencilMask) - iT.VAO:DrawArrays(primitiveType, iT.numVertices, 0, iT.usedElements, 0) -- +1!!! end end end -function widget:DrawWorldPreUnit() +function widget:DrawWorld(inMiniMap) + + if autoReload then + attackRangeShader = LuaShader.CheckShaderUpdates(shaderSourceCache) or attackRangeShader + end + if chobbyInterface then return end if not Spring.IsGUIHidden() and (not WG['topbar'] or not WG['topbar'].showingQuit()) then cameraHeightFactor = GetCameraHeightFactor() * 0.5 + 0.5 glTexture(0, "$heightmap") glTexture(1, "$info") - + glTexture(2, '$normals') + -- Stencil Setup -- -- https://learnopengl.com/Advanced-OpenGL/Stencil-testing if colorConfig.drawStencil then @@ -981,17 +1030,18 @@ function widget:DrawWorldPreUnit() glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE) -- Set The Stencil Buffer To 1 Where Draw Any Polygon attackRangeShader:Activate() - + attackRangeShader:SetUniform("selUnitCount", selUnitCount) attackRangeShader:SetUniform("selBuilderCount", selBuilderCount) attackRangeShader:SetUniform("drawMode", 0.0) + attackRangeShader:SetUniform("inMiniMap", inMiniMap and 1.0 or 0.0) attackRangeShader:SetUniform("drawAlpha", colorConfig.fill_alpha) attackRangeShader:SetUniform("fadeDistOffset", colorConfig.outer_fade_height_difference) DRAWRINGS(GL_TRIANGLE_FAN) -- FILL THE CIRCLES glLineWidth(math.max(0.1, 4 + math.sin(gameFrame * 0.04) * 10)) glColorMask(true, true, true, true) -- re-enable color drawing - glStencilMask(0) + glStencilMask(0) attackRangeShader:SetUniform("lineAlphaUniform", colorConfig.externalalpha) @@ -999,20 +1049,20 @@ function widget:DrawWorldPreUnit() attackRangeShader:SetUniform("drawMode", 1.0) attackRangeShader:SetUniform("drawAlpha", 1.0) - DRAWRINGS(GL_LINE_LOOP, 'externallinethickness') -- DRAW THE OUTER RINGS + DRAWRINGS(GL_LINE_LOOP, inMiniMap and 'minimapexternallinethickness' or 'externallinethickness') -- DRAW THE OUTER RINGS -- This is the correct way to exit out of the stencil mode, to not break drawing of area commands: glStencilTest(false) glStencilMask(255) glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP) glClear(GL_STENCIL_BUFFER_BIT) - -- All the above are needed :( - end + -- All the above are needed :() + end if colorConfig.drawInnerRings then attackRangeShader:SetUniform("lineAlphaUniform", colorConfig.internalalpha) attackRangeShader:SetUniform("drawMode", 2.0) attackRangeShader:SetUniform("fadeDistOffset", 0) - DRAWRINGS(GL_LINE_LOOP, 'internallinethickness') -- DRAW THE INNER RINGS + DRAWRINGS(GL_LINE_LOOP, inMiniMap and 'minimapinternallinethickness' or 'internallinethickness') -- DRAW THE INNER RINGS end attackRangeShader:Deactivate() @@ -1023,6 +1073,13 @@ function widget:DrawWorldPreUnit() end end +function widget:DrawInMiniMap() + -- TODO: + -- do a sanity check and dont draw here if there are too many units selected... + widget:DrawWorld(true) +end + + -- Need to add all the callins for handling unit creation/destruction/gift of builders --[[ diff --git a/luaui/Widgets/gui_defenserange.lua b/luaui/Widgets/gui_defenserange.lua index cb54f1c4bc..12f2d17d88 100644 --- a/luaui/Widgets/gui_defenserange.lua +++ b/luaui/Widgets/gui_defenserange.lua @@ -10,7 +10,7 @@ function widget:GetInfo() date = "October 21, 2007", license = "GNU GPL v2", layer = -100, - enabled = true + enabled = false } end diff --git a/luaui/Widgets/gui_defenserange_gl4.lua b/luaui/Widgets/gui_defenserange_gl4.lua index 956f832be4..90d686d98b 100644 --- a/luaui/Widgets/gui_defenserange_gl4.lua +++ b/luaui/Widgets/gui_defenserange_gl4.lua @@ -8,7 +8,7 @@ function widget:GetInfo() date = "2021.04.26", license = "Lua: GPLv2, GLSL: (c) Beherith (mysterme@gmail.com)", layer = -100, - enabled = false + enabled = true } end @@ -66,41 +66,47 @@ end local enabledAsSpec = true local buttonConfig = { - ally = { ground = true, air = true, nuke = true }, + ally = { ground = false, air = false, nuke = true }, enemy = { ground = true, air = true, nuke = true } } local colorConfig = { --An array of R, G, B, Alpha drawStencil = true, -- wether to draw the outer, merged rings (quite expensive!) drawInnerRings = true, -- wether to draw inner, per defense rings (very cheap) - externalalpha = 0.70, -- alpha of outer rings - internalalpha = 0.0, -- alpha of inner rings + externalalpha = 0.80, -- alpha of outer rings + internalalpha = 0.17, -- alpha of inner rings distanceScaleStart = 2000, -- Linewidth is 100% up to this camera height - distanceScaleEnd = 4000, -- Linewidth becomes 50% above this camera height + distanceScaleEnd = 8000, -- Linewidth becomes 50% above this camera height ground = { - color = {1.0, 0.2, 0.0, 1.0}, - fadeparams = { 2000, 5000, 1.0, 0.0}, -- FadeStart, FadeEnd, StartAlpha, EndAlpha - externallinethickness = 4.0, - internallinethickness = 2.0, + color = {1.3, 0.18, 0.04, 0.5}, + fadeparams = { 2200, 5500, 1.0, 0.0}, -- FadeStart, FadeEnd, StartAlpha, EndAlpha + externallinethickness = 6.0, -- can be 2 or 3 if we can distiquish its looks from attackranges + internallinethickness = 2.0, -- can be 1.8 if we can distiquish its looks from attackranges }, air = { - color = {0.90, 0.45, 1.2, 1.0}, - fadeparams = { 2000, 5000, 0.4, 0.0}, -- FadeStart, FadeEnd, StartAlpha, EndAlpha - externallinethickness = 4.0, - internallinethickness = 2.0, + color = {0.8, 0.44, 1.6, 0.70}, + fadeparams = { 3200, 8000, 0.4, 0.0}, -- FadeStart, FadeEnd, StartAlpha, EndAlpha + externallinethickness = 6.0, + internallinethickness = 1.8, }, nuke = { - color = {0.7, 0.8, 1.0, 1.0}, - fadeparams = {5000, 4000, 0.6, 0.0}, -- FadeStart, FadeEnd, StartAlpha, EndAlpha + color = {1.2, 1.0, 0.3, 0.8}, + fadeparams = {6000, 3000, 0.6, 0.0}, -- FadeStart, FadeEnd, StartAlpha, EndAlpha externallinethickness = 4.0, - internallinethickness = 2.0, + internallinethickness = 1.0, }, cannon = { - color = {1.0, 0.6, 0.0, 1.0}, - fadeparams = {3000, 6000, 0.8, 0.0}, -- FadeStart, FadeEnd, StartAlpha, EndAlpha - externallinethickness = 4.0, - internallinethickness = 2.0, + color = {1.3, 0.18, 0.04, 0.74}, + fadeparams = {6000, 3000, 0.8, 0.0}, -- FadeStart, FadeEnd, StartAlpha, EndAlpha + externallinethickness = 6.0, + internallinethickness = 1.0, }, + -- lrpc = { + -- color = {1.3, 0.18, 0.04, 0.74}, + -- fadeparams = {6000, 3000, 0.8, 0.0}, -- FadeStart, FadeEnd, StartAlpha, EndAlpha + -- externallinethickness = 10.0, + -- internallinethickness = 1.0, + -- }, } @@ -109,7 +115,7 @@ local colorConfig = { --An array of R, G, B, Alpha ---------------------------------- -local buttonconfigmap ={'ground','air','nuke','ground'} +local buttonconfigmap ={'ground','air','nuke','cannon'} local DEBUG = false --generates debug message local weaponTypeMap = {'ground','air','nuke','cannon'} @@ -192,7 +198,7 @@ local function initUnitList() ['armllt'] = { weapons = { 1 } }, ['armbeamer'] = { weapons = { 1 } }, ['armhlt'] = { weapons = { 1 } }, - ['armguard'] = { weapons = { 4} }, + ['armguard'] = { weapons = { 3 } }, --4 ['armrl'] = { weapons = { 2 } }, --light aa ['armferret'] = { weapons = { 2 } }, ['armcir'] = { weapons = { 2 } }, --chainsaw @@ -204,16 +210,16 @@ local function initUnitList() ['armfflak'] = { weapons = { 2 } }, --floating flak AA ['armatl'] = { weapons = { 1 } }, --adv torpedo launcher - ['armamb'] = { weapons = { 4 } }, --ambusher - ['armpb'] = { weapons = { 4 } }, --pitbull + ['armamb'] = { weapons = { 4 } }, --ambusher 4 + ['armpb'] = { weapons = { 1 } }, --pitbull 4 ['armanni'] = { weapons = { 1 } }, ['armflak'] = { weapons = { 2 } }, ['armmercury'] = { weapons = { 2 } }, ['armemp'] = { weapons = { 1 } }, ['armamd'] = { weapons = { 3 } }, --antinuke - ['armbrtha'] = { weapons = { 4 } }, - ['armvulc'] = { weapons = { 4 } }, + --['armbrtha'] = { weapons = { 4 } }, --should be 5 (new lrpc) + --['armvulc'] = { weapons = { 4 } }, -- CORTEX ['cormaw'] = { weapons = { 1 } }, @@ -222,7 +228,7 @@ local function initUnitList() ['corllt'] = { weapons = { 1 } }, ['corhllt'] = { weapons = { 1 } }, ['corhlt'] = { weapons = { 1 } }, - ['corpun'] = { weapons = { 4} }, + ['corpun'] = { weapons = { 1} }, --4 ['corrl'] = { weapons = { 2 } }, ['cormadsam'] = { weapons = { 2 } }, ['corerad'] = { weapons = { 2 } }, @@ -235,15 +241,15 @@ local function initUnitList() ['corfrt'] = { weapons = { 2 } }, --floating rocket laucher ['corenaa'] = { weapons = { 2 } }, --floating flak AA - ['cortoast'] = { weapons = { 4 } }, + ['cortoast'] = { weapons = { 1 } }, --4 ['corvipe'] = { weapons = { 1 } }, ['cordoom'] = { weapons = { 1, 1, 1} }, ['corflak'] = { weapons = { 2 } }, ['corscreamer'] = { weapons = { 2 } }, - ['cortron'] = { weapons = { 1 } }, + ['cortron'] = { weapons = { 4 } }, ['corfmd'] = { weapons = { 3 } }, - ['corint'] = { weapons = { 4 } }, - ['corbuzz'] = { weapons = { 4 } }, + ['corint'] = { weapons = { 4 } }, + ['corbuzz'] = { weapons = { 4 } }, ['armscab'] = { weapons = { 3 } }, ['armcarry'] = { weapons = { 3 } }, @@ -254,7 +260,22 @@ local function initUnitList() -- LEGION ['legabm'] = { weapons = { 3 } }, --antinuke - ['legrampart'] = { weapons = { 3 } }, --rampart + ['legrampart'] = { weapons = { 3, 1 } }, --rampart + ['leglht'] = { weapons = { 0 } }, --llt + ['legcluster'] = { weapons = { 0 } }, --short range arty T1 + ['legacluster'] = { weapons = { 1 } }, --T2 arty + ['leghive'] = { weapons = { 1 } }, --Drone-defense + ['legmg'] = { weapons = { 1 } }, --ground-AA MG defense + ['legbombard'] = { weapons = { 1 } }, --Grenadier defense + ['legbastion'] = { weapons = { 1 } }, --T2 Heatray Tower + ['legrl'] = { weapons = { 2 } }, --T1 AA + ['leglupara'] = { weapons = { 2 } }, --T1.5 AA + ['legrhapsis'] = { weapons = { 2 } }, --T1.5 AA + ['legflak'] = { weapons = { 2 } }, --T2 AA FLAK + ['leglraa'] = { weapons = { 2 } }, --T2 LR-AA + ['legperdition'] = { weapons = { 4 } }, --T2 LR-AA + ['legstarfall'] = { weapons = { 4 } }, + ['leglrpc'] = { weapons = { 4 } }, -- SCAVENGERS ['scavbeacon_t1_scav'] = { weapons = { 1 } }, @@ -384,6 +405,10 @@ function widget:TextCommand(command) end ------ GL4 THINGS ----- +--- + +local autoReload = false + -- nukes and cannons: local largeCircleVBO = nil local largeCircleSegments = 512 @@ -398,10 +423,12 @@ local defenseRangeClasses = {'enemyair','enemyground','enemynuke','allyair','all local defenseRangeVAOs = {} local circleInstanceVBOLayout = { - {id = 1, name = 'posscale', size = 4}, -- a vec4 for pos + scale + {id = 1, name = 'posscale', size = 4}, -- abs pos for static units, offset for dynamic units, scale is actual range, Y is turretheight {id = 2, name = 'color1', size = 4}, -- vec4 the color of this new - {id = 3, name = 'visibility', size = 4}, --- vec4 heightdrawstart, heightdrawend, fadefactorin, fadefactorout + {id = 3, name = 'visibility', size = 4}, --- vec4 FadeStart, FadeEnd, StartAlpha, EndAlpha {id = 4, name = 'projectileParams', size = 4}, --- heightboost gradient + {id = 5, name = 'additionalParams', size = 4 }, --- groupselectionfadescale, weaponType, ISDGUN, MAXANGLEDIF + {id = 6, name = 'instData', size = 4, type = GL.UNSIGNED_INT }, -- Currently unused within defense ranges, as they are forced-static } local luaShaderDir = "LuaUI/Widgets/Include/" @@ -409,290 +436,40 @@ local LuaShader = VFS.Include(luaShaderDir.."LuaShader.lua") VFS.Include(luaShaderDir.."instancevbotable.lua") local defenseRangeShader = nil +local shaderSourceCache = { + shaderName = 'Defense Range GL4', + vssrcpath = "LuaUI/Widgets/Shaders/weapon_range_rings_unified_gl4.vert.glsl", + fssrcpath = "LuaUI/Widgets/Shaders/weapon_range_rings_unified_gl4.frag.glsl", + shaderConfig = { + MYGRAVITY = Game.gravity + 0.1, + STATICUNITS = 1, + DEBUG = autoReload and 1 or 0, + }, + uniformInt = { + heightmapTex = 0, + losTex = 1, + mapNormalTex = 2, + }, + uniformFloat = { + lineAlphaUniform = 1, + cannonmode = 0, + fadeDistOffset = 0, + drawMode = 0, + selBuilderCount = 1.0, + selUnitCount = 1.0, + inMiniMap = 0.0, + }, +} + local function goodbye(reason) Spring.Echo("DefenseRange GL4 widget exiting with reason: "..reason) widgetHandler:RemoveWidget() end -local function makeCircleVBO(circleSegments) - circleSegments = circleSegments -1 -- for po2 buffers - local circleVBO = gl.GetVBO(GL.ARRAY_BUFFER,true) - if circleVBO == nil then goodbye("Failed to create circleVBO") end - - local VBOLayout = { - {id = 0, name = "position", size = 4}, - } - - local VBOData = {} - - for i = 0, circleSegments do -- this is +1 - VBOData[#VBOData+1] = math.sin(math.pi*2* i / circleSegments) -- X - VBOData[#VBOData+1] = math.cos(math.pi*2* i / circleSegments) -- Y - VBOData[#VBOData+1] = i / circleSegments -- circumference [0-1] - VBOData[#VBOData+1] = 0 - end - - circleVBO:Define( - circleSegments + 1, - VBOLayout - ) - circleVBO:Upload(VBOData) - return circleVBO -end - -local vsSrc = [[ -#version 420 -#line 10000 - -//__DEFINES__ - -layout (location = 0) in vec4 circlepointposition; -layout (location = 1) in vec4 posscale; -layout (location = 2) in vec4 color1; -layout (location = 3) in vec4 visibility; // FadeStart, FadeEnd, StartAlpha, EndAlpha -layout (location = 4) in vec4 projectileParams; // projectileSpeed, iscylinder!!!! , heightBoostFactor , heightMod - -uniform float lineAlphaUniform = 1.0; -uniform float cannonmode = 0.0; - -uniform sampler2D heightmapTex; -uniform sampler2D losTex; // hmm maybe? - -out DataVS { - flat vec4 blendedcolor; -}; - -//__ENGINEUNIFORMBUFFERDEFS__ - -#line 11000 - -float heightAtWorldPos(vec2 w){ - vec2 uvhm = heightmapUVatWorldPos(w); - return textureLod(heightmapTex, uvhm, 0.0).x; -} - -float GetRangeFactor(float projectileSpeed) { // returns >0 if weapon can shoot here, <0 if it cannot, 0 if just right - // on first run, with yDiff = 0, what do we get? - float speed2d = projectileSpeed * 0.707106; - float gravity = 120.0 * (0.001111111); - return ((speed2d * speed2d) * 2.0 ) / (gravity); -} - -float GetRange2DCannon(float yDiff,float projectileSpeed,float rangeFactor,float heightBoostFactor) { // returns >0 if weapon can shoot here, <0 if it cannot, 0 if just right - // on first run, with yDiff = 0, what do we get? - - //float factor = 0.707106; - float smoothHeight = 100.0; - float speed2d = projectileSpeed*0.707106; - float speed2dSq = speed2d * speed2d; - float gravity = -1.0* (120.0 /900); - - if (heightBoostFactor < 0){ - heightBoostFactor = (2.0 - rangeFactor) / sqrt(rangeFactor); - } - - if (yDiff < -100.0){ - yDiff = yDiff * heightBoostFactor; - }else { - if (yDiff < 0.0) { - yDiff = yDiff * (1.0 + (heightBoostFactor - 1.0 ) * (-1.0 * yDiff) * 0.01); - } - } - - float root1 = speed2dSq + 2 * gravity *yDiff; - if (root1 < 0.0 ){ - return 0.0; - }else{ - return rangeFactor * ( speed2dSq + speed2d * sqrt( root1 ) ) / (-1.0 * gravity); - } -} - -//float heightMod  default: 0.2 (0.8 for #Cannon, 1.0 for #BeamLaser and #LightningCannon) -//Changes the spherical weapon range into an ellipsoid. Values above 1.0 mean the weapon cannot target as high as it can far, values below 1.0 mean it can target higher than it can far. For example 0.5 would allow the weapon to target twice as high as far. - -//float heightBoostFactor default: -1.0 -//Controls the boost given to range by high terrain. Values > 1.0 result in increased range, 0.0 means the cannon has fixed range regardless of height difference to target. Any value < 0.0 (i.e. the default value) result in an automatically calculated value based on range and theoretical maximum range. - -#define RANGE posscale.w -#define PROJECTILESPEED projectileParams.x -#define ISCYLINDER projectileParams.y -#define HEIGHTBOOSTFACTOR projectileParams.z -#define HEIGHTMOD projectileParams.w -#define YGROUND posscale.y - -#define OUTOFBOUNDSALPHA alphaControl.y -#define FADEALPHA alphaControl.z -#define MOUSEALPHA alphaControl.w - - -void main() { - // translate to world pos: - vec4 circleWorldPos = vec4(1.0); - circleWorldPos.xz = circlepointposition.xy * RANGE + posscale.xz; - - vec4 alphaControl = vec4(1.0); - - // get heightmap - circleWorldPos.y = heightAtWorldPos(circleWorldPos.xz); - - - if (cannonmode > 0.5){ - - // BAR only has 3 distinct ballistic projectiles, heightBoostFactor is only a handful from -1 to 2.8 and 6 and 8 - // gravity we can assume to be linear - - float heightDiff = (circleWorldPos.y - YGROUND) * 0.5; - - float rangeFactor = RANGE / GetRangeFactor(PROJECTILESPEED); //correct - if (rangeFactor > 1.0 ) rangeFactor = 1.0; - if (rangeFactor <= 0.0 ) rangeFactor = 1.0; - float radius = RANGE;// - heightDiff; - float adjRadius = GetRange2DCannon(heightDiff * HEIGHTMOD, PROJECTILESPEED, rangeFactor, HEIGHTBOOSTFACTOR); - float adjustment = radius * 0.5; - float yDiff = 0; - float adds = 0; - //for (int i = 0; i < mod(timeInfo.x/8,16); i ++){ //i am a debugging god - for (int i = 0; i < 16; i ++){ - if (adjRadius > radius){ - radius = radius + adjustment; - adds = adds + 1; - }else{ - radius = radius - adjustment; - adds = adds - 1; - } - adjustment = adjustment * 0.5; - circleWorldPos.xz = circlepointposition.xy * radius + posscale.xz; - float newY = heightAtWorldPos(circleWorldPos.xz ); - yDiff = abs(circleWorldPos.y - newY); - circleWorldPos.y = max(0, newY); - heightDiff = circleWorldPos.y - posscale.y; - adjRadius = GetRange2DCannon(heightDiff * HEIGHTMOD, PROJECTILESPEED, rangeFactor, HEIGHTBOOSTFACTOR); - } - }else{ - if (ISCYLINDER < 0.5){ // isCylinder - //simple implementation, 4 samples per point - //for (int i = 0; i 0.5){ - // cannons should fade distance based on their range - float cvmin = max(visibility.x, 2* RANGE); - float cvmax = max(visibility.y, 4* RANGE); - //FADEALPHA = clamp((cvmin - distToCam)/(cvmax - cvmin + 1.0),visibility.z,visibility.w); - } - - blendedcolor = color1; - - // -- DARKEN OUT OF LOS - vec4 losTexSample = texture(losTex, vec2(circleWorldPos.x / mapSize.z, circleWorldPos.z / mapSize.w)); // lostex is PO2 - float inlos = dot(losTexSample.rgb,vec3(0.33)); - inlos = clamp(inlos*5 -1.4 , 0.5,1.0); // fuck if i know why, but change this if LOSCOLORS are changed! - blendedcolor.rgb *= inlos; - - // --- YES FOG - float fogDist = length((cameraView * vec4(circleWorldPos.xyz,1.0)).xyz); - float fogFactor = clamp((fogParams.y - fogDist) * fogParams.w, 0, 1); - blendedcolor.rgb = mix(fogColor.rgb, vec3(blendedcolor), fogFactor); - - - // -- IN-SHADER MOUSE-POS BASED HIGHLIGHTING - float disttomousefromunit = 1.0 - smoothstep(48, 64, length(posscale.xz - mouseWorldPos.xz)); - // this will be positive if in mouse, negative else - float highightme = clamp( (disttomousefromunit ) + 0.0, 0.0, 1.0); - MOUSEALPHA = highightme; - - // ------------ dump the stuff for FS -------------------- - //worldPos = circleWorldPos; - //worldPos.a = RANGE; - alphaControl.x = circlepointposition.z; // save circle progress here - gl_Position = cameraViewProj * vec4(circleWorldPos.xyz, 1.0); - - - //lets blend the alpha here, and save work in FS: - float outalpha = OUTOFBOUNDSALPHA * (MOUSEALPHA + FADEALPHA * lineAlphaUniform); - blendedcolor.a *= outalpha ; - //blendedcolor.rgb = vec3(fract(distToCam/100)); -} -]] - -local fsSrc = [[ -#version 330 - -#extension GL_ARB_uniform_buffer_object : require -#extension GL_ARB_shading_language_420pack: require - -//_DEFINES__ - -#line 20000 - - -//_ENGINEUNIFORMBUFFERDEFS__ - -in DataVS { - flat vec4 blendedcolor; -}; - -out vec4 fragColor; - -void main() { - fragColor = blendedcolor; // now pared down to only this, all work is done in vertex shader now -} -]] - - local function makeShaders() - local engineUniformBufferDefs = LuaShader.GetEngineUniformBufferDefs() - vsSrc = vsSrc:gsub("//__ENGINEUNIFORMBUFFERDEFS__", engineUniformBufferDefs) - fsSrc = fsSrc:gsub("//__ENGINEUNIFORMBUFFERDEFS__", engineUniformBufferDefs) - defenseRangeShader = LuaShader( - { - vertex = vsSrc:gsub("//__DEFINES__", "#define MYGRAVITY "..tostring(Game.gravity+0.1)), - fragment = fsSrc, - --geometry = gsSrc, no geom shader for now - uniformInt = { - heightmapTex = 0, - losTex = 1, - }, - uniformFloat = { - lineAlphaUniform = 1, - cannonmode = 0, - }, - }, - "defenseRangeShader GL4" - ) - shaderCompiled = defenseRangeShader:Initialize() - if not shaderCompiled then + defenseRangeShader = LuaShader.CheckShaderUpdates(shaderSourceCache, 0) + if not defenseRangeShader then goodbye("Failed to compile defenseRangeShader GL4 ") return false end @@ -755,7 +532,7 @@ local function hashPos(x,z) end local cacheTable = {} -for i=1,16 do cacheTable[i] = 0 end +for i=1,24 do cacheTable[i] = 0 end local function UnitDetected(unitID, unitDefID, unitTeam, noUpload) if unitDefRings[unitDefID] == nil then return end -- no rings for this @@ -774,12 +551,24 @@ local function UnitDetected(unitID, unitDefID, unitTeam, noUpload) local allystring = alliedUnit and "ally" or "enemy" if buttonConfig[allystring][buttonconfigmap[weaponType]] then --local weaponType = unitDefRings[unitDefID]['weapons'][weaponNum] + + local weaponID = i + local ringParams = unitDefRings[unitDefID]['rings'][i] + local x, y, z, mpx, mpy, mpz, apx, apy, apz = spGetUnitPosition(unitID, true, true) + local wpx, wpy, wpz, wdx, wdy, wdz = Spring.GetUnitWeaponVectors(unitID, weaponID) + --Spring.Echo("Defranges: unitID", unitID,x,y,z,"weaponID", weaponID, "y", y, "mpy", mpy,"wpy", wpy) + + -- Now this is a truly terrible hack, we cache each unitDefID's max weapon turret height at position 18 in the table + -- so it only goes up with popups + local turretHeight = math.max(ringParams[18] or 0, (wpy or mpy ) - y) + ringParams[18] = turretHeight + + cacheTable[1] = mpx - cacheTable[2] = mpy + cacheTable[2] = turretHeight cacheTable[3] = mpz local vaokey = allystring .. weaponTypeToString[weaponType] - local ringParams = unitDefRings[unitDefID]['rings'][i] for i = 1,13 do cacheTable[i+3] = ringParams[i] end @@ -1064,6 +853,10 @@ local function DRAWRINGS(primitiveType, linethickness) end defenseRangeShader:SetUniform("cannonmode",1) + if not linethickness then + -- NOTE: THIS IS THE WORLDS NASTIEST HACK TO PREVENT THE CANNON RINGS FROM BEING DRAWN STENCILED! + return + end for i,allyState in ipairs(allyenemypairs) do local defRangeClass = allyState.."cannon" local iT = defenseRangeVAOs[defRangeClass] @@ -1071,7 +864,7 @@ local function DRAWRINGS(primitiveType, linethickness) drawcounts[stencilMask] = iT.usedElements if iT.usedElements > 0 and buttonConfig[allyState]["ground"] then if linethickness then - glLineWidth(colorConfig['cannon'][linethickness] * cameraHeightFactor) + glLineWidth(colorConfig['cannon'][linethickness] * cameraHeightFactor * 0.15) end glStencilMask(stencilMask) glStencilFunc(GL.NOTEQUAL, stencilMask, stencilMask) @@ -1080,10 +873,16 @@ local function DRAWRINGS(primitiveType, linethickness) end end -function widget:DrawWorldPreUnit() +function widget:DrawWorld() --if fullview and not enabledAsSpec then -- return --end + + if autoReload then + defenseRangeShader = LuaShader.CheckShaderUpdates(shaderSourceCache) or defenseRangeShader + end + + if chobbyInterface then return end if not Spring.IsGUIHidden() and (not WG['topbar'] or not WG['topbar'].showingQuit()) then cameraHeightFactor = GetCameraHeightFactor() * 0.5 + 0.5 @@ -1096,6 +895,7 @@ function widget:DrawWorldPreUnit() glClear(GL.STENCIL_BUFFER_BIT) -- clear prev stencil glDepthTest(false) -- always draw glColorMask(false, false, false, false) -- disable color drawing + glStencilTest(true) -- enable stencil test glStencilMask(255) -- all 8 bits glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE) -- Set The Stencil Buffer To 1 Where Draw Any Polygon @@ -1143,7 +943,6 @@ end - --SAVE / LOAD CONFIG FILE function widget:GetConfigData() local data = {} diff --git a/luaui/Widgets/gui_sensor_ranges_jammer.lua b/luaui/Widgets/gui_sensor_ranges_jammer.lua index ba2d587b42..4b80843dfa 100644 --- a/luaui/Widgets/gui_sensor_ranges_jammer.lua +++ b/luaui/Widgets/gui_sensor_ranges_jammer.lua @@ -358,7 +358,7 @@ function widget:DrawWorld() --if true then return end glColorMask(false, false, false, false) glStencilTest(true) - glDepthTest(GL.LEQUAL) + glDepthTest(false) --GL.LEQUAL gl.Texture(0, "$heightmap") circleShader:Activate() diff --git a/units/ArmBots/T2/armaak.lua b/units/ArmBots/T2/armaak.lua index f9eaa7e58a..704c4af5f9 100644 --- a/units/ArmBots/T2/armaak.lua +++ b/units/ArmBots/T2/armaak.lua @@ -142,6 +142,9 @@ return { [2] = 0.33, [3] = 0.7, }, + customparams = { + bogus = 1 + }, }, armaabot_missile1 = { areaofeffect = 64, diff --git a/units/ArmBuildings/LandUtil/armmine1.lua b/units/ArmBuildings/LandUtil/armmine1.lua index f84b6cc108..a3b2e4ccd3 100644 --- a/units/ArmBuildings/LandUtil/armmine1.lua +++ b/units/ArmBuildings/LandUtil/armmine1.lua @@ -78,6 +78,8 @@ return { weapondefs = { minerange = { areaofeffect = 0, + avoidfeature = false, + avoidground = false, craterareaofeffect = 0, craterboost = 0, cratermult = 0, @@ -87,7 +89,7 @@ return { impulsefactor = 0, name = "Crawlingbomb Dummy Weapon", range = 64, - reloadtime = 1, + reloadtime = 0.1, soundhitwet = "", soundhitwetvolume = 0, tolerance = 1000000, @@ -104,6 +106,7 @@ return { weapons = { [1] = { def = "MINERANGE", + onlytargetcategory = "SURFACE", }, }, }, diff --git a/units/ArmBuildings/LandUtil/armmine2.lua b/units/ArmBuildings/LandUtil/armmine2.lua index 866395f2b7..077a534e90 100644 --- a/units/ArmBuildings/LandUtil/armmine2.lua +++ b/units/ArmBuildings/LandUtil/armmine2.lua @@ -104,6 +104,7 @@ return { weapons = { [1] = { def = "MINERANGE", + onlytargetcategory = "SURFACE", }, }, }, diff --git a/units/ArmBuildings/LandUtil/armmine3.lua b/units/ArmBuildings/LandUtil/armmine3.lua index 3b8c19e84c..a53afece60 100644 --- a/units/ArmBuildings/LandUtil/armmine3.lua +++ b/units/ArmBuildings/LandUtil/armmine3.lua @@ -104,6 +104,7 @@ return { weapons = { [1] = { def = "MINERANGE", + onlytargetcategory = "SURFACE", }, }, }, diff --git a/units/ArmBuildings/SeaUtil/armfmine3.lua b/units/ArmBuildings/SeaUtil/armfmine3.lua index 101878c9ad..79f18c97d9 100644 --- a/units/ArmBuildings/SeaUtil/armfmine3.lua +++ b/units/ArmBuildings/SeaUtil/armfmine3.lua @@ -106,6 +106,7 @@ return { weapons = { [1] = { def = "MINERANGE", + onlytargetcategory = "SURFACE", }, }, }, diff --git a/units/ArmGantry/armthor.lua b/units/ArmGantry/armthor.lua index 93c814519e..e0132a678c 100644 --- a/units/ArmGantry/armthor.lua +++ b/units/ArmGantry/armthor.lua @@ -152,6 +152,10 @@ return { damage = { default = 300, }, + customparams = { + noattackrangearc= 1, + }, + }, }, empmissile = { areaofeffect = 196, @@ -241,6 +245,9 @@ return { default = 300, subs = 30, }, + customparams = { + noattackrangearc= 1, + }, }, }, weapons = { diff --git a/units/ArmShips/T2/armbats.lua b/units/ArmShips/T2/armbats.lua index 06d63c53c9..7a3cdb135f 100644 --- a/units/ArmShips/T2/armbats.lua +++ b/units/ArmShips/T2/armbats.lua @@ -128,6 +128,9 @@ return { default = 300, vtol = 65, }, + customparams = { + noattackrangearc= 1, + }, }, }, weapons = { diff --git a/units/ArmShips/T2/armepoch.lua b/units/ArmShips/T2/armepoch.lua index 8a67bb69d8..3eddfefc3c 100644 --- a/units/ArmShips/T2/armepoch.lua +++ b/units/ArmShips/T2/armepoch.lua @@ -161,6 +161,9 @@ return { commanders = 1, vtol = 150, }, + customparams = { + noattackrangearc= 1, + }, }, flak = { accuracy = 1000, @@ -198,6 +201,9 @@ return { [2] = 0.33, [3] = 0.7, }, + customparams = { + noattackrangearc= 1, + }, }, heavyplasma = { accuracy = 600, @@ -228,6 +234,9 @@ return { default = 437, vtol = 200, }, + customparams = { + noattackrangearc= 1, + }, }, mediumplasma = { accuracy = 350, @@ -255,6 +264,9 @@ return { default = 270, vtol = 65, }, + customparams = { + noattackrangearc= 1, + }, }, }, weapons = { diff --git a/units/ArmShips/T2/armlship.lua b/units/ArmShips/T2/armlship.lua index 4849418b84..fc5c134c43 100644 --- a/units/ArmShips/T2/armlship.lua +++ b/units/ArmShips/T2/armlship.lua @@ -188,6 +188,7 @@ return { spark_forkdamage = "0.5", spark_maxunits = "2", spark_range = "100", + noattackrangearc= 1, }, damage = { default = 35, diff --git a/units/ArmShips/T2/armmship.lua b/units/ArmShips/T2/armmship.lua index f66770b311..18fe614b3e 100644 --- a/units/ArmShips/T2/armmship.lua +++ b/units/ArmShips/T2/armmship.lua @@ -195,6 +195,7 @@ return { speceffect = "split", splitexplosionceg = "genericshellexplosion-medium", when = "yvel<0", + noattackrangearc= 1, }, damage = { commanders = 350, diff --git a/units/ArmShips/armpship.lua b/units/ArmShips/armpship.lua index 67646d4218..2ecc6fd1b7 100644 --- a/units/ArmShips/armpship.lua +++ b/units/ArmShips/armpship.lua @@ -128,6 +128,10 @@ return { subs = 70, vtol = 37, }, + customparams = { + noattackrangearc= 1, + }, + }, }, weapons = { diff --git a/units/CorAircraft/T2/corcrwh.lua b/units/CorAircraft/T2/corcrwh.lua index 4e231f9493..93ff6a9bb0 100644 --- a/units/CorAircraft/T2/corcrwh.lua +++ b/units/CorAircraft/T2/corcrwh.lua @@ -127,6 +127,9 @@ return { damage = { vtol = 76, }, + customparams = { + noattackrangearc= 1, + }, }, dragonmawh = { accuracy = 700, @@ -173,6 +176,9 @@ return { default = 6, subs = 3, }, + customparams = { + noattackrangearc= 1, + }, }, krowlaser2 = { areaofeffect = 32, diff --git a/units/CorBots/T2/coraak.lua b/units/CorBots/T2/coraak.lua index a409995d91..133680847e 100644 --- a/units/CorBots/T2/coraak.lua +++ b/units/CorBots/T2/coraak.lua @@ -141,6 +141,9 @@ return { [2] = 0.33, [3] = 0.7, }, + customparams = { + bogus = 1 + }, }, bogus_missile = { areaofeffect = 48, @@ -217,6 +220,9 @@ return { damage = { vtol = 80, }, + customparams = { + bogus = 1 + }, }, coraabot_missile2 = { areaofeffect = 24, @@ -264,6 +270,9 @@ return { damage = { vtol = 80, }, + customparams = { + bogus = 1 + }, }, coraabot_missile3 = { areaofeffect = 24, @@ -311,6 +320,9 @@ return { damage = { vtol = 80, }, + customparams = { + bogus = 1 + }, }, coraabot_missile4 = { areaofeffect = 64, diff --git a/units/CorBuildings/LandUtil/cormine1.lua b/units/CorBuildings/LandUtil/cormine1.lua index bcec924be0..458c9e320a 100644 --- a/units/CorBuildings/LandUtil/cormine1.lua +++ b/units/CorBuildings/LandUtil/cormine1.lua @@ -105,6 +105,7 @@ return { weapons = { [1] = { def = "MINERANGE", + onlytargetcategory = "SURFACE", }, }, }, diff --git a/units/CorBuildings/LandUtil/cormine2.lua b/units/CorBuildings/LandUtil/cormine2.lua index 2b7bb3b459..7a73dc82e9 100644 --- a/units/CorBuildings/LandUtil/cormine2.lua +++ b/units/CorBuildings/LandUtil/cormine2.lua @@ -104,6 +104,7 @@ return { weapons = { [1] = { def = "MINERANGE", + onlytargetcategory = "SURFACE", }, }, }, diff --git a/units/CorBuildings/LandUtil/cormine3.lua b/units/CorBuildings/LandUtil/cormine3.lua index 1384eafcb9..f701732a42 100644 --- a/units/CorBuildings/LandUtil/cormine3.lua +++ b/units/CorBuildings/LandUtil/cormine3.lua @@ -104,6 +104,7 @@ return { weapons = { [1] = { def = "MINERANGE", + onlytargetcategory = "SURFACE", }, }, }, diff --git a/units/CorBuildings/SeaUtil/corfmine3.lua b/units/CorBuildings/SeaUtil/corfmine3.lua index 9d2e585926..2836d5790b 100644 --- a/units/CorBuildings/SeaUtil/corfmine3.lua +++ b/units/CorBuildings/SeaUtil/corfmine3.lua @@ -106,6 +106,7 @@ return { weapons = { [1] = { def = "MINERANGE", + onlytargetcategory = "SURFACE", }, }, }, diff --git a/units/CorGantry/corjugg.lua b/units/CorGantry/corjugg.lua index b6c5a885e2..aa4b7207a4 100644 --- a/units/CorGantry/corjugg.lua +++ b/units/CorGantry/corjugg.lua @@ -139,6 +139,9 @@ return { damage = { default = 75, }, + customparams = { + noattackrangearc= 1, + }, }, juggernaut_fire = { areaofeffect = 65, @@ -209,6 +212,9 @@ return { damage = { default = 150, }, + customparams = { + noattackrangearc= 1, + }, }, }, weapons = { diff --git a/units/CorGantry/corkorg.lua b/units/CorGantry/corkorg.lua index da4b51671d..e80711c726 100644 --- a/units/CorGantry/corkorg.lua +++ b/units/CorGantry/corkorg.lua @@ -278,6 +278,7 @@ return { customparams = { lups_noshockwave = true, nofire = true, + noattackrangearc= 1, }, damage = { default = 150, diff --git a/units/CorShips/T2/corbats.lua b/units/CorShips/T2/corbats.lua index e53372cf0d..212b9b710b 100644 --- a/units/CorShips/T2/corbats.lua +++ b/units/CorShips/T2/corbats.lua @@ -162,6 +162,9 @@ return { default = 300, vtol = 65, }, + customparams = { + noattackrangearc= 1, + }, }, }, weapons = { diff --git a/units/CorShips/T2/corblackhy.lua b/units/CorShips/T2/corblackhy.lua index cfd775ee2d..cf0294fc5d 100644 --- a/units/CorShips/T2/corblackhy.lua +++ b/units/CorShips/T2/corblackhy.lua @@ -192,6 +192,10 @@ return { damage = { vtol = 150, }, + + customparams = { + noattackrangearc= 1, + }, }, heavylaser = { areaofeffect = 8, @@ -227,6 +231,9 @@ return { default = 270, vtol = 65, }, + customparams = { + noattackrangearc= 1, + }, }, heavyplasma = { accuracy = 500, diff --git a/units/CorShips/T2/cormship.lua b/units/CorShips/T2/cormship.lua index 83ff273b37..bbb44d9407 100644 --- a/units/CorShips/T2/cormship.lua +++ b/units/CorShips/T2/cormship.lua @@ -194,6 +194,7 @@ return { speceffect = "split", splitexplosionceg = "genericshellexplosion-medium", when = "yvel<0", + noattackrangearc= 1, }, damage = { commanders = 500, diff --git a/units/Legion/Air/T2 Air/legfort.lua b/units/Legion/Air/T2 Air/legfort.lua index 47ba633fb8..8cc11e1312 100644 --- a/units/Legion/Air/T2 Air/legfort.lua +++ b/units/Legion/Air/T2 Air/legfort.lua @@ -117,6 +117,9 @@ return { damage = { default = 36, }, + customparams = { + noattackrangearc= 1, + }, }, plasma = { accuracy = 960, @@ -145,6 +148,9 @@ return { subs = 50, vtol = 30, }, + customparams = { + noattackrangearc= 1, + }, }, aa_missiles = { areaofeffect = 16, diff --git a/units/Legion/Air/T2 Air/legheavydrone.lua b/units/Legion/Air/T2 Air/legheavydrone.lua index 648e983072..5b0d4e0c75 100644 --- a/units/Legion/Air/T2 Air/legheavydrone.lua +++ b/units/Legion/Air/T2 Air/legheavydrone.lua @@ -106,6 +106,9 @@ return { default = 10, vtol = 2, }, + customparams = { + noattackrangearc= 1, + }, }, }, weapons = { diff --git a/units/Legion/Air/T2 Air/legionnaire.lua b/units/Legion/Air/T2 Air/legionnaire.lua index cd9d33d0c5..2e278fe254 100644 --- a/units/Legion/Air/T2 Air/legionnaire.lua +++ b/units/Legion/Air/T2 Air/legionnaire.lua @@ -122,6 +122,9 @@ return { default = 2, vtol = 80, }, + customparams = { + noattackrangearc= 1, + }, }, }, diff --git a/units/Legion/Air/T2 Air/legvenator.lua b/units/Legion/Air/T2 Air/legvenator.lua index d8e6f27eb3..8e2506f6e3 100644 --- a/units/Legion/Air/T2 Air/legvenator.lua +++ b/units/Legion/Air/T2 Air/legvenator.lua @@ -111,6 +111,9 @@ return { default = 24, vtol = 480, }, + customparams = { + noattackrangearc= 1, + }, }, }, weapons = { diff --git a/units/Legion/Air/legdrone.lua b/units/Legion/Air/legdrone.lua index c67fdceead..b45dd85d31 100644 --- a/units/Legion/Air/legdrone.lua +++ b/units/Legion/Air/legdrone.lua @@ -137,6 +137,9 @@ return { default = 12, vtol = 4, }, + customparams = { + noattackrangearc= 1, + }, }, }, weapons = { diff --git a/units/Legion/Defenses/legbombard.lua b/units/Legion/Defenses/legbombard.lua index 408ba096fb..9c3d2440cb 100644 --- a/units/Legion/Defenses/legbombard.lua +++ b/units/Legion/Defenses/legbombard.lua @@ -186,6 +186,7 @@ return { subs = 300, }, customparams = { + noattackrangearc= 1, exclude_preaim = true } }, diff --git a/units/Legion/Ships/leghastatus.lua b/units/Legion/Ships/leghastatus.lua index d93b98b88a..e87ff3d9cb 100644 --- a/units/Legion/Ships/leghastatus.lua +++ b/units/Legion/Ships/leghastatus.lua @@ -127,6 +127,9 @@ return { default = 55, vtol = 30, }, + customparams = { + noattackrangearc= 1, + }, }, }, diff --git a/units/Legion/Ships/leghastatusalt.lua b/units/Legion/Ships/leghastatusalt.lua index 5e7bff0124..e9b9d61b94 100644 --- a/units/Legion/Ships/leghastatusalt.lua +++ b/units/Legion/Ships/leghastatusalt.lua @@ -139,6 +139,9 @@ return { hvyboats = 11, vtol = 2, }, + customparams = { + noattackrangearc= 1, + }, }, }, weapons = { diff --git a/units/Legion/Ships/legportent.lua b/units/Legion/Ships/legportent.lua index c968f930be..100ff55d5c 100644 --- a/units/Legion/Ships/legportent.lua +++ b/units/Legion/Ships/legportent.lua @@ -132,6 +132,9 @@ return { vtol = 30, sub = 30, }, + customparams = { + noattackrangearc= 1, + }, }, }, diff --git a/units/Legion/T3/legpede.lua b/units/Legion/T3/legpede.lua index d42db278fa..d48cc724cc 100644 --- a/units/Legion/T3/legpede.lua +++ b/units/Legion/T3/legpede.lua @@ -187,6 +187,9 @@ return { default = 21, vtol = 21, }, + customparams = { + noattackrangearc= 1, + }, }, railgunt2 = { areaofeffect = 16,