@@ -11,6 +11,8 @@ import { Layer } from "./Layer";
1111// Parameters for the alert animation
1212const ALERT_SPEED = 1.6 ;
1313const ALERT_COUNT = 2 ;
14+ const RETALIATION_WINDOW_TICKS = 15 * 10 ; // 15 seconds
15+ const ALERT_COOLDOWN_TICKS = 15 * 10 ; // 15 seconds
1416
1517@customElement ( "alert-frame" )
1618export class AlertFrame extends LitElement implements Layer {
@@ -22,6 +24,9 @@ export class AlertFrame extends LitElement implements Layer {
2224
2325 private animationTimeout : number | null = null ;
2426 private seenAttackIds : Set < string > = new Set ( ) ;
27+ private lastAlertTick : number = - 1 ;
28+ // Map of player ID -> tick when we last attacked them
29+ private outgoingAttackTicks : Map < number , number > = new Map ( ) ;
2530
2631 static styles = css `
2732 .alert-border {
@@ -82,9 +87,14 @@ export class AlertFrame extends LitElement implements Layer {
8287 // Clear tracked attacks if player dies or doesn't exist
8388 if ( ! myPlayer || ! myPlayer . isAlive ( ) ) {
8489 this . seenAttackIds . clear ( ) ;
90+ this . outgoingAttackTicks . clear ( ) ;
91+ this . lastAlertTick = - 1 ;
8592 return ;
8693 }
8794
95+ // Track outgoing attacks to detect retaliation
96+ this . trackOutgoingAttacks ( ) ;
97+
8898 // Check for BrokeAllianceUpdate events
8999 this . game
90100 . updatesSinceLastTick ( )
@@ -116,24 +126,70 @@ export class AlertFrame extends LitElement implements Layer {
116126 private activateAlert ( ) {
117127 if ( this . userSettings . alertFrame ( ) ) {
118128 this . isActive = true ;
129+ this . lastAlertTick = this . game . ticks ( ) ;
119130 this . requestUpdate ( ) ;
120131 }
121132 }
122133
134+ private trackOutgoingAttacks ( ) {
135+ const myPlayer = this . game . myPlayer ( ) ;
136+ if ( ! myPlayer || ! myPlayer . isAlive ( ) ) {
137+ return ;
138+ }
139+
140+ const currentTick = this . game . ticks ( ) ;
141+ const outgoingAttacks = myPlayer . outgoingAttacks ( ) ;
142+
143+ // Track when we attack other players (not terra nullius)
144+ for ( const attack of outgoingAttacks ) {
145+ // Only track attacks on players (targetID !== 0 means it's a player, not unclaimed land)
146+ if ( attack . targetID !== 0 && ! attack . retreating ) {
147+ this . outgoingAttackTicks . set ( attack . targetID , currentTick ) ;
148+ }
149+ }
150+
151+ // Clean up old entries (older than retaliation window)
152+ for ( const [ playerID , tick ] of this . outgoingAttackTicks . entries ( ) ) {
153+ if ( currentTick - tick > RETALIATION_WINDOW_TICKS ) {
154+ this . outgoingAttackTicks . delete ( playerID ) ;
155+ }
156+ }
157+ }
158+
123159 private checkForNewAttacks ( ) {
124160 const myPlayer = this . game . myPlayer ( ) ;
125161 if ( ! myPlayer || ! myPlayer . isAlive ( ) ) {
126162 return ;
127163 }
128164
129165 const incomingAttacks = myPlayer . incomingAttacks ( ) ;
166+ const currentTick = this . game . ticks ( ) ;
167+
168+ // Check if we're in cooldown (within 10 seconds of last alert)
169+ const inCooldown =
170+ this . lastAlertTick !== - 1 &&
171+ currentTick - this . lastAlertTick < ALERT_COOLDOWN_TICKS ;
130172
131173 // Find new attacks that we haven't seen yet
132174 for ( const attack of incomingAttacks ) {
133175 // Only alert for non-retreating attacks
134176 if ( ! attack . retreating && ! this . seenAttackIds . has ( attack . id ) ) {
135- this . seenAttackIds . add ( attack . id ) ;
136- this . activateAlert ( ) ;
177+ // Check if this is a retaliation (we attacked them recently)
178+ const ourAttackTick = this . outgoingAttackTicks . get ( attack . attackerID ) ;
179+ const isRetaliation =
180+ ourAttackTick !== undefined &&
181+ currentTick - ourAttackTick < RETALIATION_WINDOW_TICKS ;
182+
183+ // Don't alert if:
184+ // 1. We're in cooldown from a recent alert
185+ // 2. This is a retaliation (we attacked them within 10 seconds)
186+ if ( ! inCooldown && ! isRetaliation ) {
187+ this . seenAttackIds . add ( attack . id ) ;
188+ this . activateAlert ( ) ;
189+ } else {
190+ // Still mark as seen so we don't alert later
191+ this . seenAttackIds . add ( attack . id ) ;
192+ }
137193 }
138194 }
139195
0 commit comments