From ecabcc66607827dbcfd6f8ccd9ca59e5cab9b090 Mon Sep 17 00:00:00 2001 From: Arisaya <117544545+ArisayaDragon@users.noreply.github.com> Date: Tue, 31 Mar 2026 19:10:37 -0700 Subject: [PATCH 1/4] feat: 106504: partial implementation --- Transcendence/TransCore/HumanSpaceVol01.xml | 1 + Transcendence/TransCore/Salvagers.xml | 245 +++++++++++++++++++- 2 files changed, 245 insertions(+), 1 deletion(-) diff --git a/Transcendence/TransCore/HumanSpaceVol01.xml b/Transcendence/TransCore/HumanSpaceVol01.xml index f8e009a0e..70a60331c 100644 --- a/Transcendence/TransCore/HumanSpaceVol01.xml +++ b/Transcendence/TransCore/HumanSpaceVol01.xml @@ -1737,6 +1737,7 @@ + diff --git a/Transcendence/TransCore/Salvagers.xml b/Transcendence/TransCore/Salvagers.xml index 08919064d..d8748b3a1 100644 --- a/Transcendence/TransCore/Salvagers.xml +++ b/Transcendence/TransCore/Salvagers.xml @@ -59,7 +59,7 @@ - + @@ -212,6 +212,249 @@ /> + + + + + + + + (cat '001000C4_ sourceID '_marked) + + + 'search + + + + + + (block + ( + (statusVar '001000C4_status) + (sourceID (objGetID gSource)) + + ; salvager nomad clans dont coordinate so they + ; will waste time looking at wrecks other nomads + ; have looked at + + (lootedVar (@obj gSource 'lootedVar)) + + ; This is the number of wares at which they will set up shop + + (maxWares 50) + + ; state tracking vars + + (state (obj@ gSource statusVar)) + (setState (lambda (newState) (objSet@ gSource statusVar newState))) + (startNewSearch (lambda () (block () (setState 'initSearch) (shpOrder gSource ')))) + (dockedAt (shpGetDockObj gSource)) + + ; our loot for sale - we calculate this later if needed + + allLoot + ) + (switch + + ; if we are searching for lootable wrecks... + (eq status 'search) + (block + ( + (allWrecks (rpgFindWrecksToSalvage gSource lootedVar)) + ) + (if allWrecks + ; Begin salvaging nearby wrecks + (block + ( + (theWreck (random allWrecks)) + ) + ; Cancel current oreders + (shpCancelOrders gSource) + + ; We are now in the salvage state + ; Need to set the correct state and order + (obj@ gSource statusVar 'salvage) + (shpOrder gSource 'dock theWreck) + ) + ; Otherwise keep searching + (block + ( + (thePos (sysVectorRandom )) + ) + ) + ) + ) + + ; if we are actively salvaging something + (eq status 'salvage) + (switch + ; If we are docked with something that is lootable, loot it + (and dockedAt + (not (objMatches dockedAt gSource "sTA")) + (setq allLoot (objGetItems gSource "*~mf U")) + ) + (block () + (enum allLoot theItem (block () (objRemoveItem dockedAt theItem) (objAddItem gSource theItem))) + (setState 'search) + ) + ; If we are docked at an empty wreck or something that + ; we shouldnt be - this can potentially happen due to + ; other scripts or mods - we need to undock and go back to searching + dockedAt + ) + (block + ( + ; Get all item stacks + (currentWares (objGetItems gSource "U")) + (numWares (count currentWares)) + remainingWrecks + ) + (if (gr numWares maxWares)) + ) + + ; If we dont have a valid status, we need to re-initialize + (block () + (setState 'search) + (shp) + (shpOrderImmediate gSource 'wait 1) + ) + ) + + ; If we're docked at an object... + (if (and dockedAt + (objMatches dockedAt gSource "sTA +populated +salvagerBazaar") + + ; Compose a list of all loot on board that the station + ; might want to buy from us. + ) + + ; To do - implement shop code + + ; We loot wrecks and process the goods + (if (and (not (objMatches dockedAt "sTA")) + + ; Compose a list of all loot on board that the station + ; might want to buy from us. + + (setq allLoot (filter (objGetItems gSource "*~mf U") theItem + (objGetBuyPrice dockedAt theItem) + )) + ) + (block Nil + (enum allLoot theItem (objRemoveItem gSource theItem)) + (enum allLoot theItem (objAddItem dockedAt theItem)) + ) + + ; Otherwise we docked at something random + ; we dont loot non-wreck objects + () + ) + ) + + ; Figure out what to do next + (switch + (eq status 'enteredSystem) + (block Nil + (setq theTarget (random (sysFindObject gSource "T +arcology"))) + (shpOrder gSource 'orbit (sysFindObject Nil "TNV +stKatsArcology;") 35 (random 20 40)) + (shpOrder gSource 'dock theTarget) + (shpOrder gSource 'waitForThreat (random 10 60)) + (objSetData gSource statusVar 'dockedAtNewVictoria) + ) + + (eq status 'dockedAtNewVictoria) + (block (roll allWrecks) + ; When leaving new victoria, orbit around for a bit + (shpOrder gSource 'orbit (sysFindObject Nil "TNV +stKatsArcology;") 35 (random 20 40)) + + ; Randomly choose a path + (setq roll (random 1 100)) + (switch + ; Gate out + (leq roll 30) + (block Nil + (shpOrder gSource 'gate) + (objSetData gSource statusVar 'leavingSystem) + ) + + ; If there are wrecks in the area, loot them + (and (rpgFilterSalvager gSource) + + ; Compose a list of all wrecks in the area + + (setq allWrecks (rpgFindWrecksToSalvage gSource lootedVar)) + ) + (block () + (rpgInitSalvageAndScuttleOperation gSource allWrecks lootedVar) + (objSetData gSource statusVar 'dockedAtStation) + ) + + ; Dock at a random station in the system + (block (theTarget) + (setq theTarget (random (sysFindObject gSource "TAF +populated; -arcology; -occupation;"))) + (shpOrder gSource 'dock theTarget) + (shpOrder gSource 'waitForThreat (random 10 20)) + (objSetData gSource statusVar 'dockedAtStation) + ) + ) + ) + + (eq status 'dockedAtStation) + (block (roll allWrecks) + ; Randomly choose a path + (setq roll (random 1 100)) + (switch + ; Gate out + (leq roll 30) + (block Nil + (shpOrder gSource 'gate) + (objSetData gSource statusVar 'leavingSystem) + ) + + ; If there are wrecks in the area, loot them + (and (rpgFilterSalvager gSource) + + ; Compose a list of all wrecks in the area + + (setq allWrecks (rpgFindWrecksToSalvage gSource lootedVar)) + ) + (block () + (rpgInitSalvageAndScuttleOperation gSource allWrecks lootedVar) + (objSetData gSource statusVar 'dockedAtStation) + ) + + ; Dock at new victoria + (leq roll 80) + (block (theTarget) + (setq theTarget (random (sysFindObject gSource "T +arcology"))) + (shpOrder gSource 'orbit (sysFindObject Nil "TNV +stKatsArcology;") 35 (random 20 40)) + (shpOrder gSource 'dock theTarget) + (shpOrder gSource 'waitForThreat (random 10 60)) + (objSetData gSource statusVar 'dockedAtNewVictoria) + ) + + ; Dock at a random station in the system + (block (theTarget) + (setq theTarget (random (sysFindObject gSource "TAF +populated; -arcology; -occupation;"))) + (shpOrder gSource 'dock theTarget) + (shpOrder gSource 'waitForThreat (random 10 20)) + (objSetData gSource statusVar 'dockedAtStation) + ) + ) + ) + ) + + ; If we were docked at an object that we just looted, then destroy the object + (rpgImplementScuttleSalvagedWreck gSource dockedAt lootedVar) + ) + + + From 80c2708b75878af7c7942fe8483cd58d853996fc Mon Sep 17 00:00:00 2001 From: Arisaya <117544545+ArisayaDragon@users.noreply.github.com> Date: Wed, 1 Apr 2026 14:33:36 -0700 Subject: [PATCH 2/4] feat: 106504: additional implementation --- Transcendence/TransCore/Salvagers.xml | 45 +++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/Transcendence/TransCore/Salvagers.xml b/Transcendence/TransCore/Salvagers.xml index d8748b3a1..0c35b42e1 100644 --- a/Transcendence/TransCore/Salvagers.xml +++ b/Transcendence/TransCore/Salvagers.xml @@ -229,6 +229,19 @@ 'search + + + + (block + ( + (centerMarker (sysCreateMarker 'tempMeasuringMarker ())) + (farthestObject (sysFindObject centerMarker "t R")) + (farthestDistance (sysVectorDistance (objGetPos farthestObject) (objGetPos centerMarker))) + ) + (objRemove centerMarker) + farthestDistance + ) + @@ -284,8 +297,9 @@ ; Otherwise keep searching (block ( - (thePos (sysVectorRandom )) + (thePos (sysVectorRandom () (obj@ gSource 'farthestDistance))) ) + (shpOrder gSource 'gotoPos thePos) ) ) ) @@ -314,13 +328,38 @@ (numWares (count currentWares)) remainingWrecks ) - (if (gr numWares maxWares)) + (if (gr numWares maxWares) + ; If we have enough wares, we setup shop + ) + ) + + ; if we are currently a shop + (eq status 'shop) + (block + ( + (currentWares (objGetItems gSource "U")) + (numWares (count currentWares)) + (timeAsShop (- (unvGetTick) (obj@ gSource 'timeSetupShop))) + ) + (if (or (ls timeAsShop 0) (gr timeAsShop 1800) (= numWares 0)) + (if (gr numWares 0) + ; Send ships to cleanup + (block () + ) + ; otherwise just resume searching + (block () + ) + ) + ; otherwise we remain a shop + (block () + ) + ) ) ; If we dont have a valid status, we need to re-initialize (block () (setState 'search) - (shp) + (shpCancelOrders gSource) (shpOrderImmediate gSource 'wait 1) ) ) From 71405be89784aa0d916fb9ad459b9c4520c6989c Mon Sep 17 00:00:00 2001 From: Arisaya <117544545+ArisayaDragon@users.noreply.github.com> Date: Wed, 15 Apr 2026 13:34:53 -0700 Subject: [PATCH 3/4] feat: 106504: additional implementation of better salvagers including shop system --- Transcendence/TransCore/Salvagers.xml | 365 +++++++++++++++++++------- 1 file changed, 263 insertions(+), 102 deletions(-) diff --git a/Transcendence/TransCore/Salvagers.xml b/Transcendence/TransCore/Salvagers.xml index 0c35b42e1..50328b7e4 100644 --- a/Transcendence/TransCore/Salvagers.xml +++ b/Transcendence/TransCore/Salvagers.xml @@ -159,6 +159,157 @@ /> + + + + + + + + + + + + + + + + + + + +
+ + + + + (scrShowScreen gScreen &dsRPGCommoditiesExchangeBuy;) + + + + (scrShowScreen gScreen &dsRPGCommoditiesExchangeSell;) + + + + + + (rpgDockServices gPlayerShip) + + + + + + + + + + + + (block Nil + (objSetData gSource 'customIntroDone True) + (scrShowPane gScreen "Default") + (scrShowScreen gScreen &dsTinkerCustomWork; { + criteria: "* +hasComponents:true; +tinkers;" + }) + ) + + + + +
+ + + + + + (block ( + ; Figure out how much it would cost to make the ship immune to radiation + (cost (* 400 (shpGetArmorCount gPlayerShip))) + ) + + (if (geq (plyGetCredits gPlayer) cost) + (scrSetDescTranslate gScreen 'descDecon { cost:(fmtCurrency 'credit cost) }) + (scrSetDescTranslate gScreen 'descDeconCantAfford) + ) + (scrSetData gScreen 'deconCost cost) + (scrEnableAction gScreen 'actionDecon (geq (plyGetCredits gPlayer) cost)) + ) + + + + + (block ( + (cost (scrGetData gScreen 'deconCost)) + (armorEnhanced 0) + ) + ; Decontaminate + (plyCharge gPlayer cost) + (shpDecontaminate gPlayerShip) + + ; Make immune + (objEnumItems gPlayerShip "aI" theItem + (block (result) + (setq result (shpEnhanceItem gPlayerShip theItem { + enhancement: "+immunity:radiation" + type: &itRadiationImmuneCoating; + })) + + (switch + (or (eq result 0) (eq result 2) (eq result 6) (eq result 7)) + (setq armorEnhanced (add armorEnhanced 1)) + ) + ) + ) + + ; Compose the result + (switch + (= armorEnhanced (shpGetArmorCount gPlayerShip)) + (scrSetData gScreen 'deconResult 'descDeconImmune) + + (= armorEnhanced 0) + (scrSetData gScreen 'deconResult 'descDeconNotImmune) + + (scrSetData gScreen 'deconResult 'descDeconPartialImmune) + ) + + (scrShowPane gScreen "DeconDone") + ) + + + + (scrExitScreen gScreen 'forceUndock) + + + + + + + + (scrSetDescTranslate gScreen (scrGetData gScreen 'deconResult)) + + + + + (scrShowScreen gScreen "Main") + + + + + +
+ @@ -231,6 +382,8 @@ + + (block ( @@ -242,10 +395,45 @@ farthestDistance ) + + (random 5 15) + - - + + + (objFireEvent gSource 'ev.behavior) + + + (objFireEvent gSource 'ev.behavior) + + + (if (and (objGetData aObjDocked '001000C4_customer) (= aDockTarget gSource)) + (block + ( + (currentWares (objGetItems gSource "U")) + (numWares (count currentWares)) + (itemsMoved 0) + (targetPurchaseAmount (typ@ gType 'customerPurchaseQuantity)) + ) + (if currentWares + (enum currentWares (ls itemsMoved targetPurchaseAmount) theItem + (block + ( + (quantity (min (itmGetCount theItem) targetPurchaseAmount)) + ) + (objAddItem aObjDocked theItem quantity) + (objRemoveItem gSource theItem quantity) + (setq itemsMoved (+ itemsMoved quantity)) + ) + ) + ) + (shpOrder aObjDocked 'wait 180) + (shpOrder aObjDocked 'gate) + ) + ) + + (block ( (statusVar '001000C4_status) @@ -265,7 +453,7 @@ (state (obj@ gSource statusVar)) (setState (lambda (newState) (objSet@ gSource statusVar newState))) - (startNewSearch (lambda () (block () (setState 'initSearch) (shpOrder gSource ')))) + (checkBehaviorIn (lambda (ticks) (sysAddObjTimerEvent ticks gSource 'ev.behavior))) (dockedAt (shpGetDockObj gSource)) ; our loot for sale - we calculate this later if needed @@ -330,6 +518,20 @@ ) (if (gr numWares maxWares) ; If we have enough wares, we setup shop + (block () + ; Prepare for shop state + + (setState 'shop) + (checkBehaviorIn 1800) + + ; Clear any existing orders + + (shpCancelOrders gSource) + + ; Hold position to be a shop + + (shpOrder gSource 'hold ) + ) ) ) @@ -341,17 +543,68 @@ (numWares (count currentWares)) (timeAsShop (- (unvGetTick) (obj@ gSource 'timeSetupShop))) ) - (if (or (ls timeAsShop 0) (gr timeAsShop 1800) (= numWares 0)) + (if (or (ls timeAsShop 0) (gr timeAsShop 18000) (= numWares 0)) (if (gr numWares 0) - ; Send ships to cleanup - (block () + + ; Send ships to cleanup inventory + + (block + ( + (customerIds (obj@ gSource 'customers)) + (customers (map customerIds 'excludeNil customerId (objGetObjectByID customerId))) + (customersAlive (map customers 'excludeNil customer (if (objMatches customer "SA") customer))) + ) + (if customersAlive + ; we wait until they have been destroyed or left the system or bought all our goods + (checkBehaviorIn 1800) + ; Otherwise we need to create customers to buy our wares + (block + ( + (nearestGate (sysFindObject gSource "G N")) + (newCustomers (map (make 'sequence 5) 'excludeNil i (sysCreateShip &tbCommPrivateCrafts; nearestGate &svIndependent;))) + (newCustomerIds (map newCustomers newCustomer (objGetID newCustomer))) + ) + + ; Register for events so we can tell when they dock + + (objRegisterForEvents gSource newCustomers) + + ; setup the customers + + (enum newCustomers newCustomer + (block () + ; Clear any existing orders + (shpCancelOrders newCustomer) + + ; Tag them as a customer + + (objSetData newCustomer '001000C4_customer 1) + + ; First have them spread out a little bit + + (shpOrder newCustomer 'approach (sysVectorRandom (objGetPos newCustomer) 100 20)) + + ; Then have them go shop + + (shpOrder newCustomer 'dock gSource) + ) + ) + (objSet@ gSource 'customers newCustomerIds) + ) + ) ) - ; otherwise just resume searching + + ; otherwise resume searching for new wares + (block () + (setState 'search) + (shpCancelOrders gSource) + (shpOrder gSource 'wait 1) ) ) ; otherwise we remain a shop (block () + (checkBehaviorIn 1800) ) ) ) @@ -360,7 +613,8 @@ (block () (setState 'search) (shpCancelOrders gSource) - (shpOrderImmediate gSource 'wait 1) + (shpOrder gSource 'wait 1) + (objSet@ gSource 'timeSetupShop ()) ) ) @@ -394,104 +648,11 @@ () ) ) - - ; Figure out what to do next - (switch - (eq status 'enteredSystem) - (block Nil - (setq theTarget (random (sysFindObject gSource "T +arcology"))) - (shpOrder gSource 'orbit (sysFindObject Nil "TNV +stKatsArcology;") 35 (random 20 40)) - (shpOrder gSource 'dock theTarget) - (shpOrder gSource 'waitForThreat (random 10 60)) - (objSetData gSource statusVar 'dockedAtNewVictoria) - ) - - (eq status 'dockedAtNewVictoria) - (block (roll allWrecks) - ; When leaving new victoria, orbit around for a bit - (shpOrder gSource 'orbit (sysFindObject Nil "TNV +stKatsArcology;") 35 (random 20 40)) - - ; Randomly choose a path - (setq roll (random 1 100)) - (switch - ; Gate out - (leq roll 30) - (block Nil - (shpOrder gSource 'gate) - (objSetData gSource statusVar 'leavingSystem) - ) - - ; If there are wrecks in the area, loot them - (and (rpgFilterSalvager gSource) - - ; Compose a list of all wrecks in the area - - (setq allWrecks (rpgFindWrecksToSalvage gSource lootedVar)) - ) - (block () - (rpgInitSalvageAndScuttleOperation gSource allWrecks lootedVar) - (objSetData gSource statusVar 'dockedAtStation) - ) - - ; Dock at a random station in the system - (block (theTarget) - (setq theTarget (random (sysFindObject gSource "TAF +populated; -arcology; -occupation;"))) - (shpOrder gSource 'dock theTarget) - (shpOrder gSource 'waitForThreat (random 10 20)) - (objSetData gSource statusVar 'dockedAtStation) - ) - ) - ) - - (eq status 'dockedAtStation) - (block (roll allWrecks) - ; Randomly choose a path - (setq roll (random 1 100)) - (switch - ; Gate out - (leq roll 30) - (block Nil - (shpOrder gSource 'gate) - (objSetData gSource statusVar 'leavingSystem) - ) - - ; If there are wrecks in the area, loot them - (and (rpgFilterSalvager gSource) - - ; Compose a list of all wrecks in the area - - (setq allWrecks (rpgFindWrecksToSalvage gSource lootedVar)) - ) - (block () - (rpgInitSalvageAndScuttleOperation gSource allWrecks lootedVar) - (objSetData gSource statusVar 'dockedAtStation) - ) - - ; Dock at new victoria - (leq roll 80) - (block (theTarget) - (setq theTarget (random (sysFindObject gSource "T +arcology"))) - (shpOrder gSource 'orbit (sysFindObject Nil "TNV +stKatsArcology;") 35 (random 20 40)) - (shpOrder gSource 'dock theTarget) - (shpOrder gSource 'waitForThreat (random 10 60)) - (objSetData gSource statusVar 'dockedAtNewVictoria) - ) - - ; Dock at a random station in the system - (block (theTarget) - (setq theTarget (random (sysFindObject gSource "TAF +populated; -arcology; -occupation;"))) - (shpOrder gSource 'dock theTarget) - (shpOrder gSource 'waitForThreat (random 10 20)) - (objSetData gSource statusVar 'dockedAtStation) - ) - ) - ) - ) ; If we were docked at an object that we just looted, then destroy the object (rpgImplementScuttleSalvagedWreck gSource dockedAt lootedVar) ) - + From 9a3772521937292614670b2904d55afd1b37ba30 Mon Sep 17 00:00:00 2001 From: Arisaya <117544545+ArisayaDragon@users.noreply.github.com> Date: Wed, 22 Apr 2026 14:51:19 -0700 Subject: [PATCH 4/4] fix: 106504: additional fixes to salvager controller --- Transcendence/TransCore/Salvagers.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Transcendence/TransCore/Salvagers.xml b/Transcendence/TransCore/Salvagers.xml index 50328b7e4..a549ceacc 100644 --- a/Transcendence/TransCore/Salvagers.xml +++ b/Transcendence/TransCore/Salvagers.xml @@ -443,7 +443,7 @@ ; will waste time looking at wrecks other nomads ; have looked at - (lootedVar (@obj gSource 'lootedVar)) + (lootedVar (obj@ gSource 'lootedVar)) ; This is the number of wares at which they will set up shop @@ -463,7 +463,7 @@ (switch ; if we are searching for lootable wrecks... - (eq status 'search) + (eq state 'search) (block ( (allWrecks (rpgFindWrecksToSalvage gSource lootedVar)) @@ -493,7 +493,7 @@ ) ; if we are actively salvaging something - (eq status 'salvage) + (eq state 'salvage) (switch ; If we are docked with something that is lootable, loot it (and dockedAt @@ -536,7 +536,7 @@ ) ; if we are currently a shop - (eq status 'shop) + (eq state 'shop) (block ( (currentWares (objGetItems gSource "U"))