1717
1818namespace OpenRA . Mods . Common . Effects
1919{
20- public class LinkedProducerSourceIndicator : IEffect , IEffectAboveShroud , IEffectAnnotation
20+ public class LinkedProducerIndicator : IEffect , IEffectAboveShroud , IEffectAnnotation
2121 {
2222 readonly Actor building ;
2323 readonly LinkedProducerTarget lpt ;
24+ readonly LinkedProducerSource lps ;
2425
2526 readonly List < WPos > targetLineNodes = new ( ) { } ;
2627 List < WPos > cachedNodes ;
2728
28- public LinkedProducerSourceIndicator ( Actor building , LinkedProducerTarget lpt )
29+ public LinkedProducerIndicator ( Actor building , LinkedProducerTarget lpt )
2930 {
3031 this . building = building ;
3132 this . lpt = lpt ;
33+ this . lps = null ;
34+ UpdateTargetLineNodes ( building . World ) ;
35+ }
36+
37+ public LinkedProducerIndicator ( Actor building , LinkedProducerSource lps )
38+ {
39+ this . building = building ;
40+ this . lpt = null ;
41+ this . lps = lps ;
3242 UpdateTargetLineNodes ( building . World ) ;
3343 }
3444
3545 void IEffect . Tick ( World world )
3646 {
37- if ( cachedNodes == null || ! cachedNodes . SequenceEqual ( lpt . LinkNodes ) )
47+ if ( lpt != null )
3848 {
49+ if ( cachedNodes == null || ! cachedNodes . SequenceEqual ( lpt . LinkNodes ) )
50+ {
51+ UpdateTargetLineNodes ( world ) ;
52+ }
53+ }
54+ else if ( lps != null )
55+ {
56+ // For sources, we need to update if the target changes
3957 UpdateTargetLineNodes ( world ) ;
4058 }
4159
@@ -45,15 +63,30 @@ void IEffect.Tick(World world)
4563
4664 void UpdateTargetLineNodes ( World world )
4765 {
48- cachedNodes = new List < WPos > ( lpt . LinkNodes ) ;
4966 targetLineNodes . Clear ( ) ;
50- foreach ( var n in cachedNodes )
51- targetLineNodes . Add ( n ) ;
5267
53- if ( targetLineNodes . Count == 0 )
54- return ;
68+ if ( lpt != null )
69+ {
70+ // Target mode: show connections to all sources
71+ cachedNodes = new List < WPos > ( lpt . LinkNodes ) ;
5572
56- targetLineNodes . Insert ( 0 , building . CenterPosition ) ;
73+ // Add the building position first
74+ targetLineNodes . Add ( building . CenterPosition ) ;
75+
76+ // Add all source positions
77+ foreach ( var n in cachedNodes )
78+ targetLineNodes . Add ( n ) ;
79+ }
80+ else if ( lps != null )
81+ {
82+ // Source mode: show connection to target
83+ targetLineNodes . Add ( building . CenterPosition ) ;
84+
85+ if ( lps . HasTarget )
86+ {
87+ targetLineNodes . Add ( lps . Target . Actor . CenterPosition ) ;
88+ }
89+ }
5790 }
5891
5992 IEnumerable < IRenderable > IEffect . Render ( WorldRenderer wr ) { return SpriteRenderable . None ; }
@@ -66,9 +99,7 @@ IEnumerable<IRenderable> IEffectAboveShroud.RenderAboveShroud(WorldRenderer wr)
6699 if ( ! building . World . Selection . Contains ( building ) )
67100 return SpriteRenderable . None ;
68101
69- var renderables = SpriteRenderable . None ;
70-
71- return renderables ;
102+ return SpriteRenderable . None ;
72103 }
73104
74105 IEnumerable < IRenderable > IEffectAnnotation . RenderAnnotation ( WorldRenderer wr )
@@ -90,11 +121,15 @@ IEnumerable<IRenderable> IEffectAnnotation.RenderAnnotation(WorldRenderer wr)
90121
91122 IEnumerable < IRenderable > RenderInner ( )
92123 {
93- var prev = targetLineNodes [ 0 ] ;
94- foreach ( var pos in targetLineNodes . Skip ( 1 ) )
124+ if ( targetLineNodes . Count < 2 )
125+ yield break ;
126+
127+ var targetPos = targetLineNodes [ 0 ] ; // Building position
128+
129+ // Draw lines from target to each source
130+ foreach ( var sourcePos in targetLineNodes . Skip ( 1 ) )
95131 {
96- var targetLine = new [ ] { prev , pos } ;
97- prev = pos ;
132+ var targetLine = new [ ] { targetPos , sourcePos } ;
98133 yield return new TargetLineRenderable ( targetLine , Color . DarkGreen , 4 , 7 ) ;
99134 yield return new TargetLineRenderable ( targetLine , Color . Lime , 2 , 5 ) ;
100135 }
0 commit comments