@@ -52,6 +52,7 @@ const CARGO_SHIP_HARBOR_UNDOCKED_DISTANCE = 280;
5252const CARGO_SHIP_LEAVE_AFTER_HARBOR_NO_CRATES_MS = 2 * 60 * 1000 ; /* 2 min */
5353const CARGO_SHIP_LEAVE_AFTER_HARBOR_WITH_CRATES_MS = 19.5 * 60 * 1000 ; /* 19.5 min */
5454const PATROL_HELICOPTER_LEAVING_SPEED_MIN = 400 ;
55+ const TRAVELLING_VENDOR_ACTIVE_TIME_MS = 30 * 60 * 1000 ;
5556
5657export interface CargoShipMetaData {
5758 lockedCrateSpawnCounter : number ;
@@ -90,6 +91,7 @@ export class RustPlusMapMarkers {
9091 public cargoShipEgressAfterHarbor2TimeoutIds : { [ cargoShip : number ] : Timer } ;
9192 public cargoShipLockedCrateSpawnIntervalIds : { [ cargoShip : number ] : NodeJS . Timeout } ;
9293 public cargoShipUndockingNotificationTimeoutIds : { [ cargoShip : number ] : NodeJS . Timeout } ;
94+ public travellingVendorLeavingNotificationTimeoutIds : { [ travellingVendor : number ] : NodeJS . Timeout } ;
9395
9496 public timeSinceSmallOilRigWasTriggered : Date | null ;
9597 public timeSinceLargeOilRigWasTriggered : Date | null ;
@@ -124,6 +126,7 @@ export class RustPlusMapMarkers {
124126 this . cargoShipEgressAfterHarbor1TimeoutIds = { }
125127 this . cargoShipLockedCrateSpawnIntervalIds = { } ;
126128 this . cargoShipUndockingNotificationTimeoutIds = { } ;
129+ this . travellingVendorLeavingNotificationTimeoutIds = { } ;
127130
128131 /* Event dates */
129132 this . timeSinceSmallOilRigWasTriggered = null ;
@@ -715,9 +718,55 @@ export class RustPlusMapMarkers {
715718 }
716719 }
717720
718- /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
719721 private updateTravellingVendors ( mapMarkers : rp . AppMapMarkers ) {
722+ const type = rp . AppMarkerType . TravellingVendor ;
723+ const gInstance = gim . getGuildInstance ( this . rpInstance . guildId ) as GuildInstance ;
724+ const language = gInstance . generalSettings . language ;
725+
726+ const newMarkers = this . getNewMarkersById ( type , mapMarkers . markers ) ;
727+ const leftMarkers = this . getLeftMarkersById ( type , mapMarkers . markers ) ;
728+ const remainingMarkers = this . getRemainingMarkersById ( type , mapMarkers . markers ) ;
729+
730+ /* Markers that are new. */
731+ for ( const marker of newMarkers ) {
732+ const travellingVendorPos = getPos ( marker . x , marker . y , this . rpInstance ) as Position ;
733+ const travellingVendorPosString = getPosString ( travellingVendorPos , this . rpInstance , false , true ) ;
734+
735+ const phrase = 'inGameEvent-travellingVendorSpawned' + ( this . firstPoll ? '-located' : '' ) ;
736+ const eventText = lm . getIntl ( language , phrase , { location : travellingVendorPosString } ) ;
737+ this . rpInstance . sendEventNotification ( 'travellingVendorSpawned' , eventText ) ;
738+
739+ /* Notify 5 min before leaving */
740+ this . travellingVendorLeavingNotificationTimeoutIds [ marker . id ] = setTimeout (
741+ this . notifyTravellingVendorLeavingSoon . bind ( this , marker . id ) ,
742+ TRAVELLING_VENDOR_ACTIVE_TIME_MS - ( 5 * 60 * 1000 )
743+ ) ;
744+
745+ this . travellingVendors . push ( marker ) ;
746+ }
747+
748+ /* Markers that have left. */
749+ for ( const marker of leftMarkers ) {
750+ const travellingVendorPos = getPos ( marker . x , marker . y , this . rpInstance ) as Position ;
751+ const travellingVendorPosString = getPosString ( travellingVendorPos , this . rpInstance , false , true ) ;
720752
753+ const phrase = 'inGameEvent-travellingVendorDespawned' ;
754+ const eventText = lm . getIntl ( language , phrase , { location : travellingVendorPosString } ) ;
755+ this . rpInstance . sendEventNotification ( 'travellingVendorDespawned' , eventText ) ;
756+
757+ if ( Object . hasOwn ( this . travellingVendorLeavingNotificationTimeoutIds , marker . id ) ) {
758+ clearTimeout ( this . travellingVendorLeavingNotificationTimeoutIds [ marker . id ] ) ;
759+ delete this . travellingVendorLeavingNotificationTimeoutIds [ marker . id ] ;
760+ }
761+
762+ this . travellingVendors = this . travellingVendors . filter ( e => e . id !== marker . id ) ;
763+ }
764+
765+ /* Markers that still remains. */
766+ for ( const marker of remainingMarkers ) {
767+ const travellingVendor = this . travellingVendors . find ( e => e . id === marker . id ) as rp . AppMarker ;
768+ Object . assign ( travellingVendor , marker ) ;
769+ }
721770 }
722771
723772
@@ -901,4 +950,25 @@ export class RustPlusMapMarkers {
901950 delete this . cargoShipUndockingNotificationTimeoutIds [ cargoShipId ] ;
902951 }
903952 }
953+
954+ private notifyTravellingVendorLeavingSoon ( travellingVendorId : number ) {
955+ const gInstance = gim . getGuildInstance ( this . rpInstance . guildId ) as GuildInstance ;
956+ const language = gInstance . generalSettings . language ;
957+
958+ const travellingVendor = this . travellingVendors . find ( e => e . id === travellingVendorId ) ;
959+ if ( ! travellingVendor ) return ;
960+
961+ const travellingVendorPos = getPos ( travellingVendor . x , travellingVendor . y , this . rpInstance ) ;
962+ if ( travellingVendorPos ) {
963+ const travellingVendorPosString = getPosString ( travellingVendorPos , this . rpInstance , false , true ) ;
964+ const phrase = 'inGameEvent-travellingVendorDespawned-soon' ;
965+ const eventText = lm . getIntl ( language , phrase , { location : travellingVendorPosString } ) ;
966+ this . rpInstance . sendEventNotification ( 'travellingVendorDespawned' , eventText ) ;
967+ }
968+
969+ if ( Object . hasOwn ( this . travellingVendorLeavingNotificationTimeoutIds , travellingVendorId ) ) {
970+ clearTimeout ( this . travellingVendorLeavingNotificationTimeoutIds [ travellingVendorId ] ) ;
971+ delete this . travellingVendorLeavingNotificationTimeoutIds [ travellingVendorId ] ;
972+ }
973+ }
904974}
0 commit comments