From 5457e8fc3be0ff95edcf72c82fe18c42c653349a Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Fri, 4 Oct 2024 19:29:43 +0200 Subject: [PATCH] Render sparkling trail for invincible players --- data/extras.png | Bin 4799 -> 6821 bytes datasrc/content.py | 1 + src/game/client/components/effects.cpp | 20 ++++++++++++++++++++ src/game/client/components/effects.h | 1 + src/game/client/components/particles.cpp | 12 ++++++++---- src/game/client/components/particles.h | 4 ++++ src/game/client/components/players.cpp | 6 ++++++ src/game/client/gameclient.cpp | 8 ++++++++ src/game/client/gameclient.h | 4 +++- src/game/client/render.h | 1 + 10 files changed, 52 insertions(+), 5 deletions(-) diff --git a/data/extras.png b/data/extras.png index b2c6deea1980885c9eae7c5fb003f4969901d86f..14d320e1e6c4a2a9504fd7e406eee7493591b82a 100644 GIT binary patch literal 6821 zcmeHL_gj-m+kJvjL{waLRlpTj6ELfYfD(EvEAUXl8U&=HG^vpi5D0{_tLs`f2_=N$ zD-fgzN(%u)5fwvK>7fKA^b!aJ2nop--~ZwJ?VVqqxt_V^J~Lz*^`!5?VzJ-bwP z0RXTEwD=tZ0CKXf9I$hT?6Z2eXA=Nag23M|UB8>TFcMAn_KQ{<x zJw2`GuWwvD@ksj(X<%UA?k5YLr}gxpR<|@p8+V8Xj_?x9ZY@7}uuXsYK|+FpLG>Gm z>YG!0eYN+#Kl1*O-k-2T9lJB!XD6SQ71h;lI`qEEUQC>c&kkR_CScO*d41DQ*O?q= zAJrZlbHc~LzG}i}Z&6z5Xze>+zk(X!?Kz|3S%YqrB5-~>2$yKLLuyCNtlTq!&c`j~ zxD8f(u+K^5_EaPL1;zB57$CCP-`$?xd;vT}GS2Pjz`0?gts1XmC2hKCuxKe)luB9* zqwYUUq!_X^hEP!8Xq~1FK*L)#oM8DdyVR`t^1*WhMX=}Yczev#ojo|O@lPmQJGsvb zA#W=JdTYv`UEdD?PwEN}B+!m~*!Na8Nr|uq-KF(j&@_X4GC1ev^{il0a?G;*ICi>a z6#OZv^&QenBkq?&*Jq|^y5SP%o0{<}T$e-apP_(Du{LDjBP7b6 zh=eg-e`9Zv#Az^FOX_Ea0?tjt%5HBS^%c?h40zVMikH;x>gqGGfU8B?NJ66EGmjQ_ z>1z$Gx0le!~}rWF{vM7WBGj6vhgPq?Q3IM8{j!Rw&N&A$?0@y)au>YK5M}ZI35jJqq4_ z;}cmE*piwPWrTkSfDTTM5gb~9h60dA<+pv{tW1HfT1T@AGtYx*IBn^vNx(yaG zuG2ZlwwyZM(@2;-66`fr^sGw%sfi$I{q3PhNuyAQFfn>&F-MH@l(g?VV17}OBC0f6@Sx}*#rNYWZ0H9S(SV7izo9CVc<4>}X@aXY$9#fY^ zR~Is1_tnYK^OH1Z7ilpl2@#Zm73+q&@cO5wha7kd4vI4l%CYSxu|c>N#J}4-?+-l5 zPcQ;a$y^5Fw0KV~!bi}+Ln|LXH{C~e0&I?Db5p=$X;tu;>W>4d35HItX;HhkvJ(R} zF2D|$m#H|eykqZ947fS`IM`nSc>Zc308#^E;SejE_qWAi_9xy%>SY?4u!=Fh+wr1Q zlabf7)PxTy-u}(YP4~h(notNkz+5fxQp4=oyjfrFo2h^LP*<%0AUH@Jq7P?X!A!28 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 pK6S$YB4{zA42?b1?;=gTV*xei`-Ce*t5m)W`q; diff --git a/datasrc/content.py b/datasrc/content.py index 52353c491..7cb5fbe1a 100644 --- a/datasrc/content.py +++ b/datasrc/content.py @@ -452,6 +452,7 @@ container.sprites.Add(Sprite("hud_lock_mode", set_hud, 10,6,2,2)) container.sprites.Add(Sprite("hud_team0_mode", set_hud, 12,6,2,2)) container.sprites.Add(Sprite("part_snowflake", set_extras, 0,0,2,2)) +container.sprites.Add(Sprite("part_sparkle", set_extras, 2,0,2,2)) anim = Animation("base") diff --git a/src/game/client/components/effects.cpp b/src/game/client/components/effects.cpp index d5c7fd608..ae2a1bdb4 100644 --- a/src/game/client/components/effects.cpp +++ b/src/game/client/components/effects.cpp @@ -103,6 +103,26 @@ void CEffects::FreezingFlakes(vec2 Pos, vec2 Size, float Alpha) m_pClient->m_Particles.Add(CParticles::GROUP_EXTRA, &p); } +void CEffects::SparkleTrail(vec2 Pos, float Alpha) +{ + if(!m_Add50hz) + return; + + CParticle p; + p.SetDefault(); + p.m_Spr = SPRITE_PART_SPARKLE; + p.m_Pos = Pos + random_direction() * random_float(40.0f); + p.m_Vel = vec2(0, 0); + p.m_LifeSpan = 0.5f; + p.m_StartSize = 0.0f; + p.m_EndSize = random_float(20.0f, 30.0f); + p.m_UseAlphaFading = true; + p.m_StartAlpha = Alpha; + p.m_EndAlpha = std::min(0.2f, Alpha); + p.m_Collides = false; + m_pClient->m_Particles.Add(CParticles::GROUP_TRAIL_EXTRA, &p); +} + void CEffects::SmokeTrail(vec2 Pos, vec2 Vel, float Alpha, float TimePassed) { if(!m_Add50hz && TimePassed < 0.001f) diff --git a/src/game/client/components/effects.h b/src/game/client/components/effects.h index de75e63c9..703eff397 100644 --- a/src/game/client/components/effects.h +++ b/src/game/client/components/effects.h @@ -30,6 +30,7 @@ public: void PlayerDeath(vec2 Pos, int ClientId, float Alpha = 1.0f); void PowerupShine(vec2 Pos, vec2 Size, float Alpha = 1.0f); void FreezingFlakes(vec2 Pos, vec2 Size, float Alpha = 1.0f); + void SparkleTrail(vec2 Pos, float Alpha = 1.0f); void Confetti(vec2 Pos, float Alpha = 1.0f); void Update(); diff --git a/src/game/client/components/particles.cpp b/src/game/client/components/particles.cpp index fef6e886d..21ef0ce35 100644 --- a/src/game/client/components/particles.cpp +++ b/src/game/client/components/particles.cpp @@ -14,6 +14,7 @@ CParticles::CParticles() { OnReset(); m_RenderTrail.m_pParts = this; + m_RenderTrailExtra.m_pParts = this; m_RenderExplosions.m_pParts = this; m_RenderExtra.m_pParts = this; m_RenderGeneral.m_pParts = this; @@ -181,9 +182,12 @@ void CParticles::OnInit() m_ExtraParticleQuadContainerIndex = Graphics()->CreateQuadContainer(false); - // TODO: Use a loop similar to the one for m_ParticleQuadContainerIndex if you add more additional particles - Graphics()->QuadsSetSubset(0, 0, 1, 1); - RenderTools()->QuadContainerAddSprite(m_ExtraParticleQuadContainerIndex, 1.f); + for(int i = 0; i <= (SPRITE_PART_SPARKLE - SPRITE_PART_SNOWFLAKE); ++i) + { + Graphics()->QuadsSetSubset(0, 0, 1, 1); + RenderTools()->QuadContainerAddSprite(m_ExtraParticleQuadContainerIndex, 1.f); + } + Graphics()->QuadContainerUpload(m_ExtraParticleQuadContainerIndex); } @@ -207,7 +211,7 @@ void CParticles::RenderGroup(int Group) IGraphics::CTextureHandle *aParticles = GameClient()->m_ParticlesSkin.m_aSpriteParticles; int FirstParticleOffset = SPRITE_PART_SLICE; int ParticleQuadContainerIndex = m_ParticleQuadContainerIndex; - if(Group == GROUP_EXTRA) + if(Group == GROUP_EXTRA || Group == GROUP_TRAIL_EXTRA) { aParticles = GameClient()->m_ExtrasSkin.m_aSpriteParticles; FirstParticleOffset = SPRITE_PART_SNOWFLAKE; diff --git a/src/game/client/components/particles.h b/src/game/client/components/particles.h index 0d2f4937d..16c06b5d9 100644 --- a/src/game/client/components/particles.h +++ b/src/game/client/components/particles.h @@ -68,6 +68,7 @@ public: enum { GROUP_PROJECTILE_TRAIL = 0, + GROUP_TRAIL_EXTRA, GROUP_EXPLOSIONS, GROUP_EXTRA, GROUP_GENERAL, @@ -111,7 +112,10 @@ private: virtual void OnRender() override { m_pParts->RenderGroup(TGROUP); } }; + // behind players CRenderGroup m_RenderTrail; + CRenderGroup m_RenderTrailExtra; + // in front of players CRenderGroup m_RenderExplosions; CRenderGroup m_RenderExtra; CRenderGroup m_RenderGeneral; diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp index 85ea937ba..92609c65f 100644 --- a/src/game/client/components/players.cpp +++ b/src/game/client/components/players.cpp @@ -742,6 +742,10 @@ void CPlayers::RenderPlayer( { GameClient()->m_Effects.FreezingFlakes(BodyPos, vec2(32, 32), Alpha); } + if(RenderInfo.m_TeeRenderFlags & TEE_EFFECT_SPARKLE) + { + GameClient()->m_Effects.SparkleTrail(BodyPos, Alpha); + } if(ClientId < 0) return; @@ -833,6 +837,8 @@ void CPlayers::OnRender() aRenderInfo[i].m_TeeRenderFlags |= TEE_EFFECT_FROZEN | TEE_NO_WEAPON; if(m_pClient->m_aClients[i].m_LiveFrozen) aRenderInfo[i].m_TeeRenderFlags |= TEE_EFFECT_FROZEN; + if(m_pClient->m_aClients[i].m_Invincible) + aRenderInfo[i].m_TeeRenderFlags |= TEE_EFFECT_SPARKLE; const CGameClient::CSnapState::CCharacterInfo &CharacterInfo = m_pClient->m_Snap.m_aCharacters[i]; const bool Frozen = CharacterInfo.m_HasExtendedData && CharacterInfo.m_ExtendedData.m_FreezeEnd != 0; diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 9aa732795..396ffcebd 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -128,6 +128,7 @@ void CGameClient::OnConsoleInit() &m_Background, // render instead of m_MapLayersBackground when g_Config.m_ClOverlayEntities == 100 &m_MapLayersBackground, // first to render &m_Particles.m_RenderTrail, + &m_Particles.m_RenderTrailExtra, &m_Items, &m_Ghost, &m_Players, @@ -1683,6 +1684,7 @@ void CGameClient::OnNewSnapshot() pClient->m_ShotgunHitDisabled = pCharacterData->m_Flags & CHARACTERFLAG_SHOTGUN_HIT_DISABLED; pClient->m_HookHitDisabled = pCharacterData->m_Flags & CHARACTERFLAG_HOOK_HIT_DISABLED; pClient->m_Super = pCharacterData->m_Flags & CHARACTERFLAG_SUPER; + pClient->m_Invincible = pCharacterData->m_Flags & CHARACTERFLAG_INVINCIBLE; // Endless pClient->m_EndlessHook = pCharacterData->m_Flags & CHARACTERFLAG_ENDLESS_HOOK; @@ -2457,6 +2459,7 @@ void CGameClient::CClientData::Reset() m_ShotgunHitDisabled = false; m_HookHitDisabled = false; m_Super = false; + m_Invincible = false; m_HasTelegunGun = false; m_HasTelegunGrenade = false; m_HasTelegunLaser = false; @@ -3697,6 +3700,7 @@ void CGameClient::LoadExtrasSkin(const char *pPath, bool AsDir) if(m_ExtrasSkinLoaded) { Graphics()->UnloadTexture(&m_ExtrasSkin.m_SpriteParticleSnowflake); + Graphics()->UnloadTexture(&m_ExtrasSkin.m_SpriteParticleSparkle); for(auto &SpriteParticle : m_ExtrasSkin.m_aSpriteParticles) SpriteParticle = IGraphics::CTextureHandle(); @@ -3731,7 +3735,11 @@ void CGameClient::LoadExtrasSkin(const char *pPath, bool AsDir) else if(PngLoaded && Graphics()->CheckImageDivisibility(aPath, ImgInfo, g_pData->m_aSprites[SPRITE_PART_SNOWFLAKE].m_pSet->m_Gridx, g_pData->m_aSprites[SPRITE_PART_SNOWFLAKE].m_pSet->m_Gridy, true) && Graphics()->IsImageFormatRgba(aPath, ImgInfo)) { m_ExtrasSkin.m_SpriteParticleSnowflake = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_SNOWFLAKE]); + m_ExtrasSkin.m_SpriteParticleSparkle = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_SPARKLE]); + m_ExtrasSkin.m_aSpriteParticles[0] = m_ExtrasSkin.m_SpriteParticleSnowflake; + m_ExtrasSkin.m_aSpriteParticles[1] = m_ExtrasSkin.m_SpriteParticleSparkle; + m_ExtrasSkinLoaded = true; } ImgInfo.Free(); diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index bf0f9071d..ebaca0dd4 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -394,6 +394,7 @@ public: bool m_ShotgunHitDisabled; bool m_HookHitDisabled; bool m_Super; + bool m_Invincible; bool m_HasTelegunGun; bool m_HasTelegunGrenade; bool m_HasTelegunLaser; @@ -768,7 +769,8 @@ public: struct SClientExtrasSkin { IGraphics::CTextureHandle m_SpriteParticleSnowflake; - IGraphics::CTextureHandle m_aSpriteParticles[1]; + IGraphics::CTextureHandle m_SpriteParticleSparkle; + IGraphics::CTextureHandle m_aSpriteParticles[2]; }; SClientExtrasSkin m_ExtrasSkin; diff --git a/src/game/client/render.h b/src/game/client/render.h index 17d8ccfa7..11b7255b9 100644 --- a/src/game/client/render.h +++ b/src/game/client/render.h @@ -123,6 +123,7 @@ enum { TEE_EFFECT_FROZEN = 1, TEE_NO_WEAPON = 2, + TEE_EFFECT_SPARKLE = 4, }; // sprite renderings