Skip to content

bugfix(contain): Route Helix attachment experience - #3282

Draft
tintinhamans wants to merge 1 commit into
TheSuperHackers:mainfrom
tintinhamans:arctic/fix/helix-attachment-experience
Draft

bugfix(contain): Route Helix attachment experience#3282
tintinhamans wants to merge 1 commit into
TheSuperHackers:mainfrom
tintinhamans:arctic/fix/helix-attachment-experience

Conversation

@tintinhamans

@tintinhamans tintinhamans commented Sep 13, 2026

Copy link
Copy Markdown

Closes #87


Helixes do not gain experience from kills made by their Gattling Cannon attachment.

This change routes experience from portable Helix attachments to the Helix while they are contained.

@tintinhamans
tintinhamans force-pushed the arctic/fix/helix-attachment-experience branch from e3e91c6 to 6be0d03 Compare September 13, 2026 05:39
@tintinhamans
tintinhamans marked this pull request as ready for review September 13, 2026 07:12
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 13, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review Completed 2026-09-13T07:17:24.045860Z 6be0d03 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Route Helix attachment experience to containing Helix

🐞 Bug fix 🕐 Less than 10 minutes

Grey Divider

AI Description

• Routes portable Helix attachment kill experience to the containing Helix.
• Limits corrected gameplay behavior to non-retail-compatible builds.
Diagram

sequenceDiagram
  participant C as Helix Contain
  participant A as Portable Attachment
  participant T as XP Tracker
  participant H as Helix
  C->>A: Detect containment
  C->>T: Set Helix sink
  A->>T: Report kill XP
  T->>H: Forward experience
Loading
High-Level Assessment

The scoped on-containment sink assignment is the appropriate approach and mirrors the established Overlord attachment experience-routing pattern. Moving attribution into generic transport or weapon logic would affect unrelated containers and introduce unnecessary gameplay risk.

Files changed (1) +6 / -0

Bug fix (1) +6 / -0
HelixContain.cppRedirect portable attachment experience to the Helix +6/-0

Redirect portable attachment experience to the Helix

• Includes the experience tracker API and assigns the containing Helix as the experience sink when a portable structure is contained. The behavior is excluded from retail-compatible CRC builds.

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Sep 13, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (1) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Detached cannons reward former Helixes 📎 Requirement gap ≡ Correctness
Description
onContaining assigns the portable structure's experience sink to the Helix, but onRemoving never
resets that sink. When the cannon is detached and later kills an eligible target,
ExperienceTracker::addExperiencePoints continues forwarding its experience to the former
container.
Code

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[R407-408]

+  if ( obj->isKindOf( KINDOF_PORTABLE_STRUCTURE ) && obj->getExperienceTracker() )
+    obj->getExperienceTracker()->setExperienceSink( getObject()->getID() );
Evidence
Rule 1 requires attachment experience to follow the owning Helix. The changed code establishes a
persistent sink, while the removal callback only restores weapon and disabled state;
ExperienceTracker retains and uses that object ID for later awards.

Award Helix XP for Gattling Cannon Attachment Kills
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[405-408]
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[428-435]
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/ExperienceTracker.cpp[91-99]
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/ExperienceTracker.cpp[162-177]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new experience routing persists after a portable structure is removed from its Helix, causing subsequent experience to be forwarded to the former container.
## Fix Focus Areas
- GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[407-408]
- GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[428-435]
## Recommended Fix
In `onRemoving`, detect portable structures with an experience tracker and clear the sink with `INVALID_ID` when it still points to the current Helix. Apply the same compatibility guard used when assigning the sink.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Helixes still lose attachment experience 🐞 Bug ≡ Correctness
Description
HelixContain::onContaining assigns the experience sink, but the portable-structure branch of
HelixContain::addToContain returns without reaching that callback. Initial Gattling Cannons and
other configured portable payloads take this branch, so their kills continue providing no experience
to the Helix.
Code

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[R407-408]

+  if ( obj->isKindOf( KINDOF_PORTABLE_STRUCTURE ) && obj->getExperienceTracker() )
+    obj->getExperienceTracker()->setExperienceSink( getObject()->getID() );
Evidence
createPayload sends configured attachments through the virtual addToContain call. The Helix
override handles the first portable attachment solely by storing its ID and setting containedBy,
whereas the base implementation is what invokes onContaining; therefore the changed sink
assignment is unreachable for the intended payload path.

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[109-112]
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[149-173]
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[266-282]
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp[362-382]
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[396-408]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Portable Helix attachments bypass `HelixContain::onContaining`, so the newly added experience-sink assignment never runs for the intended attachment creation path.
## Fix Focus Areas
- GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[246-283]
- GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[396-409]
## Recommended Fix
Move or share the experience-sink assignment with the portable-specific insertion branches in `addToContain` and `addToContainList`, ensuring it executes when the first portable structure is attached without changing Helix's specialized containment bookkeeping.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can start a comment with 'qodo' or '@qodo' to chat about any finding

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment on lines +407 to +408
if ( obj->isKindOf( KINDOF_PORTABLE_STRUCTURE ) && obj->getExperienceTracker() )
obj->getExperienceTracker()->setExperienceSink( getObject()->getID() );

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Detached cannons reward former helixes 📎 Requirement gap ≡ Correctness

onContaining assigns the portable structure's experience sink to the Helix, but onRemoving never
resets that sink. When the cannon is detached and later kills an eligible target,
ExperienceTracker::addExperiencePoints continues forwarding its experience to the former
container.
Agent Prompt
## Issue description
The new experience routing persists after a portable structure is removed from its Helix, causing subsequent experience to be forwarded to the former container.

## Fix Focus Areas
- GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[407-408]
- GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[428-435]

## Recommended Fix
In `onRemoving`, detect portable structures with an experience tracker and clear the sink with `INVALID_ID` when it still points to the current Helix. Apply the same compatibility guard used when assigning the sink.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +407 to +408
if ( obj->isKindOf( KINDOF_PORTABLE_STRUCTURE ) && obj->getExperienceTracker() )
obj->getExperienceTracker()->setExperienceSink( getObject()->getID() );

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Helixes still lose attachment experience 🐞 Bug ≡ Correctness

HelixContain::onContaining assigns the experience sink, but the portable-structure branch of
HelixContain::addToContain returns without reaching that callback. Initial Gattling Cannons and
other configured portable payloads take this branch, so their kills continue providing no experience
to the Helix.
Agent Prompt
## Issue description
Portable Helix attachments bypass `HelixContain::onContaining`, so the newly added experience-sink assignment never runs for the intended attachment creation path.

## Fix Focus Areas
- GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[246-283]
- GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp[396-409]

## Recommended Fix
Move or share the experience-sink assignment with the portable-specific insertion branches in `addToContain` and `addToContainList`, ensuring it executes when the first portable structure is attached without changing Helix's specialized containment bookkeeping.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@greptile-apps

greptile-apps Bot commented Sep 13, 2026

Copy link
Copy Markdown

Greptile Summary

This PR attempts to route experience earned by a portable Helix attachment to its containing Helix.

  • Adds the experience-tracker dependency.
  • Assigns the Helix as the attachment's experience sink from onContaining().
  • The assignment is currently unreachable for the normal portable-payload insertion path, so the intended fix remains ineffective.

Confidence Score: 4/5

The PR is not safe to merge as the intended experience-routing fix is bypassed during normal Helix attachment creation.

The sole changed behavior is placed in onContaining(), while HelixContain::addToContain() directly handles portable payloads without invoking that callback, leaving the reported experience bug unresolved.

Files Needing Attention: GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp

Important Files Changed

Filename Overview
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp Adds Helix experience-sink routing in a callback bypassed by the portable attachment's normal insertion path.

Sequence Diagram

sequenceDiagram
  participant Helix as HelixContain::createPayload
  participant HC as HelixContain::addToContain
  participant Callback as HelixContain::onContaining
  participant XP as ExperienceTracker
  Helix->>HC: addToContain(portable attachment)
  HC->>HC: Set m_portableStructureID
  Note over HC,Callback: Portable branch does not invoke onContaining
  Callback--xXP: setExperienceSink(Helix ID)
  Note over XP: Attachment XP remains unrouted
Loading
Prompt To Fix All With AI
### Issue 1
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp:407-408
**XP routing callback is bypassed**

The normal Helix payload path calls `HelixContain::addToContain()`, whose portable-structure branch records the attachment directly without invoking `OpenContain::addToContain()` or `onContaining()`. As a result, this new sink assignment never runs for the Gattling Cannon, so its kills still do not grant experience to the Helix.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "bugfix(contain): Route Helix attachment ..." | Re-trigger Greptile

Comment on lines +407 to +408
if ( obj->isKindOf( KINDOF_PORTABLE_STRUCTURE ) && obj->getExperienceTracker() )
obj->getExperienceTracker()->setExperienceSink( getObject()->getID() );

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 XP routing callback is bypassed

The normal Helix payload path calls HelixContain::addToContain(), whose portable-structure branch records the attachment directly without invoking OpenContain::addToContain() or onContaining(). As a result, this new sink assignment never runs for the Gattling Cannon, so its kills still do not grant experience to the Helix.

Prompt To Fix With AI
This is a comment left during a code review.
Path: GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/HelixContain.cpp
Line: 407-408

Comment:
**XP routing callback is bypassed**

The normal Helix payload path calls `HelixContain::addToContain()`, whose portable-structure branch records the attachment directly without invoking `OpenContain::addToContain()` or `onContaining()`. As a result, this new sink assignment never runs for the Gattling Cannon, so its kills still do not grant experience to the Helix.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@tintinhamans
tintinhamans marked this pull request as draft September 13, 2026 07:20
@tintinhamans
tintinhamans force-pushed the arctic/fix/helix-attachment-experience branch from 6be0d03 to 71706fb Compare September 13, 2026 07:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Helixes do not get XP for kills they make using the Gattling Cannon attachment

1 participant