Skip to content

Commit 6275833

Browse files
committed
Tweak cloaker effect and try to make it fade in and out.
* Fade in works but still can be improved. * Code is in place for fade out, but the unit position is not updated so I've left lups enabled for now.
1 parent 16b9f91 commit 6275833

4 files changed

Lines changed: 119 additions & 48 deletions

File tree

LuaRules/Gadgets/cus_gl4.lua

Lines changed: 87 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,10 @@ local initiated = false
347347
local featuresDefsWithAlpha = {} -- featureDefIDs (ie trees) that should be drawn with alpha.
348348
local unitDefsUseSkinning = {} -- unitDefIDs that use the bones and stretchy skin system
349349

350+
local ENEMY_CLOAK_FRAMES = false -- 4 -- How many extra frames to show enemy units for.
351+
local cloakDeferFrame = {}
352+
local keepDrawFlagChecking = false -- a list of units that need draw flag checking
353+
350354
local spGetUnitIsCloaked = Spring.GetUnitIsCloaked
351355

352356
--------------------------------------------------------------------
@@ -1421,47 +1425,65 @@ local function RemoveObject(objectID, reason) -- we get pos/neg objectID here
14211425
end
14221426
end
14231427

1424-
local function ProcessUnits(units, drawFlags, reason)
1425-
for i = 1, #units do
1426-
local unitID = units[i]
1427-
local drawFlag = drawFlags[i]
1428-
if debugmode then Spring.Echo("ProcessUnits", unitID, drawFlag, reason) end
1428+
local function ProcessCusUnit(unitID, drawFlag, gameFrame, reason)
1429+
if debugmode then Spring.Echo("ProcessUnits", unitID, drawFlag, reason) end
14291430

1430-
if math_bit_and(drawFlag, 34) > 0 then -- has alpha (2) or alphashadow(32) flag
1431-
-- cloaked units get mapped to pure forward + deferred, no refl/refr either
1431+
if cloakDeferFrame[unitID] and ((not drawFlag) or drawFlag == 0) then
1432+
if cloakDeferFrame[unitID] < gameFrame then
1433+
cloakDeferFrame[unitID] = nil
1434+
end
1435+
if not Spring.ValidUnitID(unitID) then
1436+
return
1437+
end
1438+
if cloakDeferFrame[unitID] then
14321439
drawFlag = 1
1440+
keepDrawFlagChecking = keepDrawFlagChecking or {}
1441+
keepDrawFlagChecking[#keepDrawFlagChecking + 1] = unitID
14331442
end
1434-
1435-
if drawFlag % 4 > 1 then -- check if its at least in opaque or alpha pass
1436-
if not unitsInViewport[unitID] then
1437-
-- CALL the UnitViewportAPI
1438-
numUnitsInViewport = numUnitsInViewport + 1
1439-
end
1440-
unitsInViewport[unitID] = drawFlag
1441-
else
1442-
if unitsInViewport[unitID] then
1443-
-- CALL the UnitViewportAPI
1444-
numUnitsInViewport = numUnitsInViewport - 1
1445-
end
1446-
unitsInViewport[unitID] = nil
1443+
end
1444+
if not drawFlag then
1445+
drawFlag = Spring.GetUnitDrawFlag(unitID)
1446+
end
1447+
1448+
if math_bit_and(drawFlag, 34) > 0 then -- has alpha (2) or alphashadow(32) flag
1449+
-- cloaked units get mapped to pure forward + deferred, no refl/refr either
1450+
drawFlag = 1
1451+
end
1452+
1453+
if drawFlag % 4 > 1 then -- check if its at least in opaque or alpha pass
1454+
if not unitsInViewport[unitID] then
1455+
-- CALL the UnitViewportAPI
1456+
numUnitsInViewport = numUnitsInViewport + 1
14471457
end
1448-
1449-
if (drawFlag == 0) or (drawFlag >= 128) then
1450-
RemoveObject(unitID, reason)
1451-
else
1452-
if not cusUnitIDtoDrawFlag[unitID] then --object was not seen
1453-
if Spring.ValidUnitID(unitID) and (not spGetUnitIsCloaked(unitID)) then
1454-
uniformCache[1] = 0
1455-
gl.SetUnitBufferUniforms(unitID, uniformCache, 12) -- cloak
1456-
end
1457-
AddObject(unitID, drawFlag, reason)
1458-
elseif cusUnitIDtoDrawFlag[unitID] ~= drawFlag then --flags have changed
1459-
UpdateObject(unitID, drawFlag, reason)
1460-
end
1458+
unitsInViewport[unitID] = drawFlag
1459+
else
1460+
if unitsInViewport[unitID] then
1461+
-- CALL the UnitViewportAPI
1462+
numUnitsInViewport = numUnitsInViewport - 1
1463+
end
1464+
unitsInViewport[unitID] = nil
1465+
end
1466+
1467+
if (drawFlag == 0) or (drawFlag >= 128) then
1468+
RemoveObject(unitID, reason)
1469+
else
1470+
if not cusUnitIDtoDrawFlag[unitID] then --object was not seen
1471+
--if Spring.ValidUnitID(unitID) and (not spGetUnitIsCloaked(unitID)) then
1472+
-- uniformCache[1] = 0
1473+
-- gl.SetUnitBufferUniforms(unitID, uniformCache, 12) -- cloak
1474+
--end
1475+
AddObject(unitID, drawFlag, reason)
1476+
elseif cusUnitIDtoDrawFlag[unitID] ~= drawFlag then --flags have changed
1477+
UpdateObject(unitID, drawFlag, reason)
14611478
end
14621479
end
14631480
end
14641481

1482+
local function ProcessUnits(units, drawFlags, gameFrame, reason)
1483+
for i = 1, #units do
1484+
ProcessCusUnit(units[i], drawFlags and drawFlags[i], gameFrame, reason)
1485+
end
1486+
end
14651487

14661488
local function ProcessFeatures(features, drawFlags, reason)
14671489
for i = 1, #features do
@@ -2041,19 +2063,35 @@ function gadget:UnitGiven(unitID)
20412063
end
20422064

20432065
function gadget:UnitCloaked(unitID)
2044-
uniformCache[1] = Spring.GetGameFrame()
2045-
gl.SetUnitBufferUniforms(unitID, uniformCache, 12)
2046-
wantTranparent[unitID] = true
2066+
local frame = Spring.GetGameFrame()
2067+
if ENEMY_CLOAK_FRAMES then
2068+
local _, fullview = Spring.GetSpectatingState()
2069+
local allyUnit = fullview or Spring.IsUnitAllied(unitID)
2070+
uniformCache[1] = frame + (allyUnit and 0 or 1000000)
2071+
gl.SetUnitBufferUniforms(unitID, uniformCache, 12)
2072+
wantTranparent[unitID] = true
2073+
if not allyUnit then
2074+
keepDrawFlagChecking = keepDrawFlagChecking or {}
2075+
keepDrawFlagChecking[#keepDrawFlagChecking + 1] = unitID
2076+
cloakDeferFrame[unitID] = frame + ENEMY_CLOAK_FRAMES
2077+
end
2078+
else
2079+
uniformCache[1] = frame
2080+
gl.SetUnitBufferUniforms(unitID, uniformCache, 12)
2081+
wantTranparent[unitID] = true
2082+
end
20472083
UpdateUnit(unitID, Spring.GetUnitDrawFlag(unitID))
20482084
if debugmode then
20492085
Spring.Echo("UnitCloaked", unitID, Spring.GetUnitDrawFlag(unitID))
20502086
end
20512087
end
20522088

20532089
function gadget:UnitDecloaked(unitID)
2090+
local _, fullview = Spring.GetSpectatingState()
2091+
local allyUnit = fullview or Spring.IsUnitAllied(unitID)
20542092
wantTranparent[unitID] = false
20552093
UpdateUnit(unitID, Spring.GetUnitDrawFlag(unitID))
2056-
uniformCache[1] = -1 * Spring.GetGameFrame()
2094+
uniformCache[1] = -1 * Spring.GetGameFrame() - (allyUnit and 0 or 1000000)
20572095
gl.SetUnitBufferUniforms(unitID, uniformCache, 12)
20582096
if debugmode then
20592097
Spring.Echo("UnitDecloaked", unitID, Spring.GetUnitDrawFlag(unitID))
@@ -2074,6 +2112,7 @@ function gadget:DrawWorldPreUnit()
20742112
end
20752113

20762114
updateframe = (updateframe + 1) % updaterate
2115+
local gameFrame = Spring.GetGameFrame()
20772116
if updateframe == 0 then
20782117
local t0 = Spring.GetTimerMicros()
20792118
local units, drawFlagsUnits, features, drawFlagsFeatures
@@ -2106,12 +2145,15 @@ function gadget:DrawWorldPreUnit()
21062145
-- Spring.Echo(printDrawPassStats())
21072146
--end
21082147
local totalobjects = #units + #features + numdestroyedUnits + numdestroyedFeatures
2148+
if keepDrawFlagChecking then
2149+
totalobjects = totalobjects + #keepDrawFlagChecking
2150+
end
21092151

21102152
-- Why do we also do this processing round if #units > 0?
21112153
if debugmode and (#destroyedUnitIDs > 0 or #units > 0) then Spring.Echo("Processing destroyedUnitIDs", #units, #destroyedUnitIDs) end
21122154

21132155
if numdestroyedUnits > 0 then
2114-
ProcessUnits(destroyedUnitIDs, destroyedUnitDrawFlags, "destroyed")
2156+
ProcessUnits(destroyedUnitIDs, destroyedUnitDrawFlags, gameFrame, "destroyed")
21152157
for i = numdestroyedUnits, 1, -1 do
21162158
destroyedUnitIDs[i] = nil
21172159
destroyedUnitDrawFlags[i] = nil
@@ -2147,11 +2189,16 @@ function gadget:DrawWorldPreUnit()
21472189
for i, unitID in ipairs(firstunits) do
21482190
firstdrawFlagsUnits[i] = 1 + 4 + 16
21492191
end
2150-
ProcessUnits(firstunits, firstdrawFlagsUnits, "firstDraw")
2192+
ProcessUnits(firstunits, firstdrawFlagsUnits, gameFrame, "firstDraw")
21512193
firstDraw = false
21522194
end
21532195

2154-
ProcessUnits(units, drawFlagsUnits, "changed")
2196+
ProcessUnits(units, drawFlagsUnits, gameFrame, "changed")
2197+
if keepDrawFlagChecking then
2198+
local checkUnits = keepDrawFlagChecking
2199+
keepDrawFlagChecking = false
2200+
ProcessUnits(checkUnits, false, gameFrame, "changed")
2201+
end
21552202
ProcessFeatures(features, drawFlagsFeatures, "changed")
21562203

21572204
local deltat = Spring.DiffTimers(Spring.GetTimerMicros(), t0, nil) -- in ms

LuaRules/Gadgets/lups_cloak_fx.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ end
7777

7878
local CloakedHitEffect = { class='UnitJitter',options={ life=50, pos={0,0,0}, enemyHit=true, repeatEffect=false} }
7979
local CloakEffect = {
80-
{ class='UnitCloaker',options={ life=30 } },
80+
--{ class='UnitCloaker',options={ life=30 } },
8181
--{ class='UnitJitter',options={ delay=20, life=math.huge } },
8282
{ class='Sound',options={ file="sounds/cloak.wav",volume=0.9 } },
8383
}
@@ -88,11 +88,11 @@ local EnemyCloakEffect = {
8888

8989
local DecloakEffect = {
9090
-- { class='UnitCloaker',options={ inverse=true, life=16 } },
91-
{ class='UnitJitter',options={ life=8 } },
91+
--{ class='UnitJitter',options={ life=8 } },
9292
{ class='Sound',options={ file="sounds/cloak.wav",volume=0.9 } },
9393
}
9494
local EnemyDecloakEffect = {
95-
{ class='UnitCloaker',options={ inverse=true, life=16 } },
95+
--{ class='UnitCloaker',options={ inverse=true, life=16 } },
9696
{ class='Sound',options={ file="sounds/cloak.wav",volume=0.9 } },
9797
}
9898

ModelMaterials_GL4/templates/cus_gl4.frag.glsl

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,7 @@ void main(void){
775775

776776
vec3 worldBitangent = normalize(cross(worldNormal, worldTangent));
777777
mat3 worldTBN = mat3(worldTangent, worldBitangent, worldNormal);
778+
float outlineValue = 255.0;
778779

779780
// N - worldFragNormal
780781
vec3 N;
@@ -1296,29 +1297,50 @@ void main(void){
12961297
#if ENABLE_OPTION_HEALTH_TEXTURING
12971298
float cloakTime = worldVertexPos.w;
12981299
if (abs(cloakTime) > 0.5){
1300+
bool isEnemy = abs(cloakTime) > 1000000.0;
12991301
float cloakedness = 0.0;
13001302
if (cloakTime > 0){
1301-
cloakedness = clamp((timeInfo.x - cloakTime) / 15.0, 0.0, 1.0);
1303+
if (isEnemy) {
1304+
cloakTime = cloakTime - 1000000.0;
1305+
cloakedness = (timeInfo.x - cloakTime) / 4.0;
1306+
if (cloakedness > 2.0) {
1307+
// Enough time has passed to fully hide the unit, must be a spectator with a bad state
1308+
isEnemy = false;
1309+
} else {
1310+
outlineValue = 0.0;
1311+
}
1312+
cloakedness = clamp(cloakedness, 0.0, 1.0);
1313+
} else {
1314+
cloakedness = clamp((timeInfo.x - cloakTime) / 8.0, 0.0, 1.0);
1315+
}
13021316
//outColor.g = 1.0;
13031317
}
13041318
if (cloakTime < 0){
1319+
if (isEnemy) {
1320+
cloakTime = cloakTime + 1000000.0;
1321+
}
13051322
cloakedness = 1.0 - clamp((timeInfo.x + cloakTime) / 15.0, 0.0, 1.0);
13061323
//outColor.r = 1.0;
13071324
}
13081325
float sintime = fract(simFrame * 0.02); // pulses every 3 seconds
13091326
myPerlin.g = myPerlin.g * 0.5 + 0.5;
13101327
texColor2.a = 1.0 - clamp(cloakedness*0.49, 0.0, 0.49);
13111328
float perlinline1 = clamp(1.0 - 20* abs(myPerlin.g - fract(simFrame * 0.005)), 0.0, 1.0);
1312-
float perlinline2 = clamp(1.0 - 20* abs(myPerlin.g - fract(simFrame * 0.005 +0.5)), 0.0, 1.0);
1329+
float perlinline2 = clamp(1.0 - 20* abs(myPerlin.g - fract(simFrame * 0.005 + 0.5)), 0.0, 1.0);
13131330
float cloaknoise = cloakedness*perlinline1 + cloakedness*perlinline2;
1331+
if (isEnemy) {
1332+
texColor2.a = 1.0 - clamp(cloakedness * (1.0 + cloaknoise * 5.0), 0.0, 1.0);
1333+
} else {
1334+
outColor.rgb = mix(outColor.rgb, teamCol.rgb, cloakedness*0.5);
1335+
}
13141336
outColor.rgb += cloaknoise * 0.85;
13151337

13161338
#if 1
13171339
float dotcamera = dot(worldNormal, V);
13181340

1319-
float highLightOpacity = clamp(1.0 - dotcamera, 0, 1);
1341+
float highLightOpacity = clamp(1.0 - dotcamera, 0, 1)*0.8 + 0.2;
13201342
highLightOpacity = highLightOpacity * highLightOpacity;
1321-
outColor.rgb = mix(outColor.rgb, teamCol.rgb * 6.0, highLightOpacity * cloakedness);
1343+
outColor.rgb = mix(outColor.rgb * (1.0 - cloakedness*0.4), teamCol.rgb * 6.0, highLightOpacity * cloakedness);
13221344

13231345
//Add bloom to the perlin noise:
13241346
outSpecularColor.rgb+= vec3(clamp(cloaknoise * 0.75,0.0,1.0));
@@ -1364,7 +1386,7 @@ void main(void){
13641386
fragData[GBUFFER_EMITTEX_IDX] = vec4(vec3(albedoColor * emissiveness * 2.0) + outSpecularColor * 0.3, alphaBin);
13651387
#endif
13661388
#ifdef ENABLE_OPTION_HEALTH_TEXTURING
1367-
fragData[GBUFFER_MISCTEX_IDX] = vec4(float(materialIndex) / 255.0, 255.0, 0.0, alphaBin);
1389+
fragData[GBUFFER_MISCTEX_IDX] = vec4(float(materialIndex) / 255.0, outlineValue, 0.0, alphaBin);
13681390
#else
13691391
fragData[GBUFFER_MISCTEX_IDX] = vec4(float(materialIndex) / 255.0, 0.0, 0.0, alphaBin);
13701392
#endif

gamedata/unitdefs_post.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,7 @@ local TURNRATE_MULT_BOT = 1
467467
local TURNRATE_MULT_VEH = 1
468468
local ACCEL_MULT_BOT = 1
469469
local ACCEL_MULT_VEH = 1
470+
local TURN_ACCEL_FACTOR = 1
470471

471472
for name, ud in pairs(UnitDefs) do
472473
if ud.turnrate and ud.acceleration and ud.brakerate and ud.movementclass then
@@ -484,6 +485,7 @@ for name, ud in pairs(UnitDefs) do
484485
ud.brakerate = ud.brakerate * ACCEL_MULT_BOT
485486
ud.customparams.turn_accel_factor = ud.customparams.turn_accel_factor or 1.2
486487
end
488+
ud.customparams.turn_accel_factor = ud.customparams.turn_accel_factor * TURN_ACCEL_FACTOR
487489
end
488490
end
489491

0 commit comments

Comments
 (0)