-
Notifications
You must be signed in to change notification settings - Fork 248
feat(client): Add SelectionCircle option drawing a ring under selected objects #3220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1732,6 +1732,10 @@ W3DModelDraw::W3DModelDraw(Thing *thing, const ModuleData* moduleData) : DrawMod | |
| m_shadow = nullptr; | ||
| m_shadowEnabled = TRUE; | ||
| m_terrainDecal = nullptr; | ||
| // TheSuperHackers @feature no selection ring until one is asked for | ||
| m_selectionDecal = nullptr; | ||
| m_selectionDecalWanted = FALSE; | ||
| m_selectionDecalRadius = 0.0f; | ||
| m_trackRenderObject = nullptr; | ||
| m_whichAnimInCurState = -1; | ||
| m_nextState = nullptr; | ||
|
|
@@ -1836,6 +1840,10 @@ void W3DModelDraw::setHidden(Bool hidden) | |
| if (m_terrainDecal) | ||
| m_terrainDecal->enableShadowRender(!hidden); | ||
|
|
||
| // TheSuperHackers @fix the ring must not keep rendering under a hidden drawable | ||
| if (m_selectionDecal) | ||
| m_selectionDecal->enableShadowRender(!hidden); | ||
|
|
||
| if (m_trackRenderObject && hidden) | ||
| { const Coord3D* pos = getDrawable()->getPosition(); | ||
| m_trackRenderObject->addCapEdgeToTrack(pos->x,pos->y); | ||
|
|
@@ -1949,6 +1957,9 @@ void W3DModelDraw::setFullyObscuredByShroud(Bool fullyObscured) | |
| m_shadow->enableShadowInvisible(m_fullyObscuredByShroud); | ||
| if (m_terrainDecal) | ||
| m_terrainDecal->enableShadowInvisible(m_fullyObscuredByShroud); | ||
| // TheSuperHackers @fix the ring must not expose a fully shrouded unit | ||
| if (m_selectionDecal) | ||
| m_selectionDecal->enableShadowInvisible(m_fullyObscuredByShroud); | ||
|
|
||
| doStartOrStopParticleSys(); | ||
| } | ||
|
|
@@ -2719,6 +2730,53 @@ Bool W3DModelDraw::updateBonesForClientParticleSystems() | |
|
|
||
|
|
||
|
|
||
| //------------------------------------------------------------------------------------------------- | ||
| // TheSuperHackers @feature Selection ring decal. | ||
| //------------------------------------------------------------------------------------------------- | ||
| /** Put a green ring on the ground under this object, or take it away. | ||
| * | ||
| * Uses the projected shadow system rather than screen space lines, so the ring is genuinely | ||
| * projected onto the terrain and the model draws over it. It lives in its own slot rather than | ||
| * sharing m_terrainDecal, so selecting a horde unit does not evict its horde ring. | ||
| * | ||
| * Expects a PlainRingSelection.tga in the mod's assets. The engine appends the extension, and | ||
| * the art is tinted green at runtime, so a plain white or greyscale ring works. */ | ||
| //------------------------------------------------------------------------------------------------- | ||
| void W3DModelDraw::setSelectionDecal(Bool enable, Real radius) | ||
| { | ||
| // remembered so the ring can be recreated after a model swap tears the render object down | ||
| m_selectionDecalWanted = enable; | ||
| m_selectionDecalRadius = radius; | ||
|
|
||
| if (m_selectionDecal) | ||
| { | ||
| m_selectionDecal->release(); | ||
| m_selectionDecal = nullptr; | ||
| } | ||
|
|
||
| if (!enable || m_renderObject == nullptr || TheProjectedShadowManager == nullptr) | ||
| return; | ||
|
|
||
| Shadow::ShadowTypeInfo decalInfo; | ||
| decalInfo.allowUpdates = FALSE; //the ring never needs regenerating | ||
| decalInfo.allowWorldAlign = TRUE; //wrap it around terrain and world objects | ||
| decalInfo.m_type = SHADOW_ALPHA_DECAL; | ||
| strlcpy(decalInfo.m_ShadowName, "PlainRingSelection", ARRAY_SIZE(decalInfo.m_ShadowName)); | ||
| decalInfo.m_sizeX = radius * 2.0f; | ||
| decalInfo.m_sizeY = radius * 2.0f; | ||
| decalInfo.m_offsetX = 0.0f; | ||
| decalInfo.m_offsetY = 0.0f; | ||
|
|
||
| m_selectionDecal = TheProjectedShadowManager->addDecal(m_renderObject, &decalInfo); | ||
| if (m_selectionDecal) | ||
| { | ||
| m_selectionDecal->enableShadowInvisible(m_fullyObscuredByShroud); | ||
| m_selectionDecal->enableShadowRender(TRUE); | ||
| //the art is a plain ring, so tint it to the selection green | ||
| m_selectionDecal->setColor(GameMakeColor(0, 255, 0, 255)); | ||
| } | ||
| } | ||
|
|
||
| //------------------------------------------------------------------------------------------------- | ||
| void W3DModelDraw::setTerrainDecal(TerrainDecalType type) | ||
| { | ||
|
|
@@ -2790,6 +2848,14 @@ void W3DModelDraw::nukeCurrentRender(Matrix3D* xform) | |
| m_terrainDecal->release(); | ||
| m_terrainDecal = nullptr; | ||
|
|
||
| // TheSuperHackers @fix The selection ring is bound to the render object about to be torn down | ||
| // here, exactly like the shadow and the terrain decal above, so it has to go with them. Left | ||
| // behind it stayed registered with the projected shadow manager while the render object it | ||
| // points at was freed, and the next renderShadows walked that dangling entry into the driver. | ||
| if (m_selectionDecal) | ||
| m_selectionDecal->release(); | ||
| m_selectionDecal = nullptr; | ||
|
greptile-apps[bot] marked this conversation as resolved.
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.
|
||
|
|
||
| // remove existing render object from the scene | ||
| if (m_renderObject) | ||
| { | ||
|
|
@@ -3078,6 +3144,11 @@ void W3DModelDraw::setModelState(const ModelConditionInfo* newState) | |
| } | ||
| } | ||
|
|
||
| // TheSuperHackers @fix The selection ring was bound to the render object that was just | ||
| // torn down; the object is still selected, so put the ring back on the new one. | ||
| if (m_selectionDecalWanted) | ||
| setSelectionDecal(TRUE, m_selectionDecalRadius); | ||
|
Comment on lines
+3147
to
+3150
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When a selected, effectively hidden drawable replaces its model, this block recreates the selection decal with rendering enabled, while the subsequent hidden-state restoration disables only the render object and normal shadow. The green ring therefore renders beneath the hidden drawable and reveals its location. Knowledge Base Used: Game client runtime Prompt To Fix With AIThis is a comment left during a code review.
Path: Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp
Line: 3147-3150
Comment:
**Hidden ring becomes visible**
When a selected, effectively hidden drawable replaces its model, this block recreates the selection decal with rendering enabled, while the subsequent hidden-state restoration disables only the render object and normal shadow. The green ring therefore renders beneath the hidden drawable and reveals its location.
**Knowledge Base Used:** [Game client runtime](https://app.greptile.com/thesuperhackers/-/custom-context/knowledge-base/thesuperhackers/generalsgamecode/-/docs/game-client-runtime.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time! |
||
|
|
||
| if( m_renderObject ) | ||
| { | ||
| // set collision type for render object. Used by WW3D2 collision code. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.