mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 13:10:02 +01:00
[MIRROR] Blackmarket refactor and balance, fixing spy bounties, plus a new category for people captured by pirates/tots/contractors. (#26869)
Blackmarket refactor and balance, fixing spy bounties, plus a new category for people captured by pirates/tots/contractors. (#81818) This PR aims to take care of a few potential hard dels and fix the fenced goods category first and foremost. The PR also adds a new one that enables you to buy mobs captured by antags in advance, before they're sent back to the station. Unlike other categories, it doesn't have "Launch" and "Teleport" as delivery methods, instead it uses a special "Supply Pod" delivery method that ships the chattel directly to your location. This method costs 400 credits, however, if you've built the LTSRBT, shipment will be free. Another thing, I always felt LTSRBT to be pretty fucking dumb as is. Way too overpriced for the benefits it offers: a slighty cheaper delivery method that, while definitely better than the other two, doesn't really pay off or honestly even remotely compensate the 4000 credits you just spent to get it, especially if you're only buying a couple items at most. So I decided to remove it from cargo and add it to the blackmarket as a 500 to 750 creds item, available every round. Human mobs sold by the pirate bounty pad are no longer deleted, instead they're properly ransomed and sent to the holding facility, much like for contractors and tots. This means they're also added to the black market. The blackmarket system has some issues to it that need to be fixed (otherwise the "Fenced Goods" and "Hostages" categories wouldn't work). The Pirate Pad deleting "ransomed" mobs instead of actually ransoming them is lame. The LTSRBT shouldn't suck as much. Also more market stuff. This will fix #81809. 🆑 fix: Fixed the "Fenced Goods" black market category. balance: Removed the LTSRBT from cargo and added it to the blackmarket, reduced the price from 4000 to 625 on average. balance: The time it takes for captured mobs to be automatically sent back to the station from the holding facility has been increased from 3-4 minutes to 6. add: You can buy mobs captured by contractors, traitors and pirates from the black market and have them sent back to the station in advance. For safety, they'll also be handcuffed (not always) upon delivery. add: Human mobs sold by pirates are not deleted anymore. Instead, they're now captured and sent to the holding facility. /🆑 Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
@@ -36,6 +36,9 @@
|
||||
///How long pirates will wait for a response before attacking
|
||||
#define RESPONSE_MAX_TIME 2 MINUTES
|
||||
|
||||
/// How long till a spessman should come back after being captured and sent to the holding facility (which some antags use)
|
||||
#define COME_BACK_FROM_CAPTURE_TIME 6 MINUTES
|
||||
|
||||
//ERT Types
|
||||
#define ERT_BLUE "Blue"
|
||||
#define ERT_RED "Red"
|
||||
|
||||
@@ -7,4 +7,5 @@
|
||||
#define SHIPPING_METHOD_TELEPORT "Teleport"
|
||||
// Throws the item from somewhere at the station.
|
||||
#define SHIPPING_METHOD_LAUNCH "Launch"
|
||||
|
||||
// Sends a supply pod to the buyer's location, showy.
|
||||
#define SHIPPING_METHOD_SUPPLYPOD "Supply Pod"
|
||||
|
||||
@@ -64,3 +64,10 @@
|
||||
#define SUPPLY_PACK_UNCOMMON_DISCOUNTABLE "uncommon_discount"
|
||||
///Discount category for the silly, overpriced, joke content, sometimes useful or plain bad.
|
||||
#define SUPPLY_PACK_RARE_DISCOUNTABLE "rare_discount"
|
||||
|
||||
///Standard export define for not selling the item.
|
||||
#define EXPORT_NOT_SOLD 0
|
||||
///Sell the item
|
||||
#define EXPORT_SOLD 1
|
||||
///Sell the item, but for the love of god, don't delete it, we're handling it in a fancier way.
|
||||
#define EXPORT_SOLD_DONT_DELETE 2
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
///From /datum/market_item/spawn_item(): (uplink, shipping_method, shipping_loc)
|
||||
#define COMSIG_MARKET_ITEM_SPAWNED "market_item_spawned"
|
||||
@@ -174,6 +174,9 @@
|
||||
///From obj/item/toy/crayon/spraycan
|
||||
#define COMSIG_LIVING_MOB_PAINTED "living_mob_painted"
|
||||
|
||||
///From obj/closet/supplypod/return_victim: (turf/destination)
|
||||
#define COMSIG_LIVING_RETURN_FROM_CAPTURE "living_return_from_capture"
|
||||
|
||||
///From mob/living/proc/wabbajack(): (randomize_type)
|
||||
#define COMSIG_LIVING_PRE_WABBAJACKED "living_mob_wabbajacked"
|
||||
/// Return to stop the rest of the wabbajack from triggering.
|
||||
|
||||
@@ -5,9 +5,10 @@ SUBSYSTEM_DEF(blackmarket)
|
||||
|
||||
/// Descriptions for each shipping methods.
|
||||
var/shipping_method_descriptions = list(
|
||||
SHIPPING_METHOD_LAUNCH="Launches the item at the station from space, cheap but you might not receive your item at all.",
|
||||
SHIPPING_METHOD_LTSRBT="Long-To-Short-Range-Bluespace-Transceiver, a machine that receives items outside the station and then teleports them to the location of the uplink.",
|
||||
SHIPPING_METHOD_TELEPORT="Teleports the item in a random area in the station, you get 60 seconds to get there first though."
|
||||
SHIPPING_METHOD_LAUNCH = "Launches the item at the station from space, cheap but you might not receive your item at all.",
|
||||
SHIPPING_METHOD_LTSRBT = "Long-To-Short-Range-Bluespace-Transceiver, a machine that receives items outside the station and then teleports them to the location of the uplink.",
|
||||
SHIPPING_METHOD_TELEPORT = "Teleports the item in a random area in the station, you get 60 seconds to get there first though.",
|
||||
SHIPPING_METHOD_SUPPLYPOD = "Ships the item inside a supply pod at your exact location. Showy, speedy and expensive.",
|
||||
)
|
||||
|
||||
/// List of all existing markets.
|
||||
@@ -42,11 +43,7 @@ SUBSYSTEM_DEF(blackmarket)
|
||||
var/datum/market_purchase/purchase = queued_purchases[1]
|
||||
queued_purchases.Cut(1,2)
|
||||
|
||||
// Uh oh, uplink is gone. We will just keep the money and you will not get your order.
|
||||
if(!purchase.uplink || QDELETED(purchase.uplink))
|
||||
queued_purchases -= purchase
|
||||
qdel(purchase)
|
||||
continue
|
||||
var/mob/buyer = recursive_loc_check(purchase.uplink.loc, /mob)
|
||||
|
||||
switch(purchase.method)
|
||||
// Find a ltsrbt pad and make it handle the shipping.
|
||||
@@ -54,65 +51,71 @@ SUBSYSTEM_DEF(blackmarket)
|
||||
if(!telepads.len)
|
||||
continue
|
||||
// Prioritize pads that don't have a cooldown active.
|
||||
var/free_pad_found = FALSE
|
||||
for(var/obj/machinery/ltsrbt/pad in telepads)
|
||||
var/obj/machinery/ltsrbt/free_pad_found
|
||||
for(var/obj/machinery/ltsrbt/pad as anything in telepads)
|
||||
if(pad.recharge_cooldown)
|
||||
continue
|
||||
pad.add_to_queue(purchase)
|
||||
queued_purchases -= purchase
|
||||
free_pad_found = TRUE
|
||||
free_pad_found = pad
|
||||
break
|
||||
|
||||
if(free_pad_found)
|
||||
if(isnull(free_pad_found))
|
||||
continue
|
||||
|
||||
var/obj/machinery/ltsrbt/pad = pick(telepads)
|
||||
to_chat(buyer, span_notice("[purchase.uplink] flashes a message noting that the order is being processed by [free_pad_found]."))
|
||||
|
||||
to_chat(recursive_loc_check(purchase.uplink.loc, /mob), span_notice("[purchase.uplink] flashes a message noting that the order is being processed by [pad]."))
|
||||
|
||||
queued_purchases -= purchase
|
||||
pad.add_to_queue(purchase)
|
||||
// Get random area, throw it somewhere there.
|
||||
if(SHIPPING_METHOD_TELEPORT)
|
||||
var/turf/targetturf = get_safe_random_station_turf()
|
||||
// This shouldn't happen.
|
||||
if (!targetturf)
|
||||
continue
|
||||
queued_purchases -= purchase
|
||||
|
||||
to_chat(recursive_loc_check(purchase.uplink.loc, /mob), span_notice("[purchase.uplink] flashes a message noting that the order is being teleported to [get_area(targetturf)] in 60 seconds."))
|
||||
to_chat(buyer, span_notice("[purchase.uplink] flashes a message noting that the order is being teleported to [get_area(targetturf)] in 60 seconds."))
|
||||
|
||||
// do_teleport does not want to teleport items from nullspace, so it just forceMoves and does sparks.
|
||||
addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/controller/subsystem/blackmarket,fake_teleport), purchase.entry.spawn_item(), targetturf), 60 SECONDS)
|
||||
queued_purchases -= purchase
|
||||
qdel(purchase)
|
||||
addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/controller/subsystem/blackmarket,fake_teleport), purchase, targetturf), 60 SECONDS)
|
||||
|
||||
// Get the current location of the uplink if it exists, then throws the item from space at the station from a random direction.
|
||||
if(SHIPPING_METHOD_LAUNCH)
|
||||
var/startSide = pick(GLOB.cardinals)
|
||||
var/turf/T = get_turf(purchase.uplink)
|
||||
var/pickedloc = spaceDebrisStartLoc(startSide, T.z)
|
||||
|
||||
var/atom/movable/item = purchase.entry.spawn_item(pickedloc)
|
||||
var/atom/movable/item = purchase.entry.spawn_item(pickedloc, purchase)
|
||||
item.throw_at(purchase.uplink, 3, 3, spin = FALSE)
|
||||
|
||||
to_chat(recursive_loc_check(purchase.uplink.loc, /mob), span_notice("[purchase.uplink] flashes a message noting the order is being launched at the station from [dir2text(startSide)]."))
|
||||
to_chat(buyer, span_notice("[purchase.uplink] flashes a message noting the order is being launched at the station from [dir2text(startSide)]."))
|
||||
qdel(purchase)
|
||||
|
||||
queued_purchases -= purchase
|
||||
if(SHIPPING_METHOD_SUPPLYPOD)
|
||||
var/obj/structure/closet/supplypod/back_to_station/pod = new()
|
||||
purchase.entry.spawn_item(pod, purchase)
|
||||
new /obj/effect/pod_landingzone(get_turf(purchase.uplink), pod)
|
||||
|
||||
to_chat(buyer, span_notice("[purchase.uplink] flashes a message noting the order is being launched at your location. Right here, right now!"))
|
||||
qdel(purchase)
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
break
|
||||
|
||||
/// Used to make a teleportation effect as do_teleport does not like moving items from nullspace.
|
||||
/datum/controller/subsystem/blackmarket/proc/fake_teleport(atom/movable/item, turf/target)
|
||||
item.forceMove(target)
|
||||
/datum/controller/subsystem/blackmarket/proc/fake_teleport(datum/market_purchase/purchase, turf/target)
|
||||
// Oopsie, whoopsie, the item is gone. So long, and thanks for all the money.
|
||||
if(QDELETED(purchase))
|
||||
return
|
||||
var/atom/movable/thing = purchase.entry.spawn_item(target, purchase)
|
||||
var/datum/effect_system/spark_spread/sparks = new
|
||||
sparks.set_up(5, 1, target)
|
||||
sparks.attach(item)
|
||||
sparks.attach(thing)
|
||||
sparks.start()
|
||||
qdel(purchase)
|
||||
|
||||
/// Used to add /datum/market_purchase to queued_purchases var. Returns TRUE when queued.
|
||||
/datum/controller/subsystem/blackmarket/proc/queue_item(datum/market_purchase/P)
|
||||
if(P.method == SHIPPING_METHOD_LTSRBT && !telepads.len)
|
||||
/datum/controller/subsystem/blackmarket/proc/queue_item(datum/market_purchase/purchase)
|
||||
if((purchase.method == SHIPPING_METHOD_LTSRBT && !telepads.len) || isnull(purchase.uplink))
|
||||
qdel(purchase)
|
||||
return FALSE
|
||||
queued_purchases += P
|
||||
queued_purchases += purchase
|
||||
return TRUE
|
||||
|
||||
@@ -1017,6 +1017,11 @@ GLOBAL_LIST_EMPTY(possible_items)
|
||||
var/payout_bonus = 0
|
||||
var/area/dropoff = null
|
||||
|
||||
/datum/objective/contract/is_valid_target(datum/mind/possible_target)
|
||||
if(HAS_TRAIT(possible_target, TRAIT_HAS_BEEN_KIDNAPPED))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
// Generate a random valid area on the station that the dropoff will happen.
|
||||
/datum/objective/contract/proc/generate_dropoff()
|
||||
var/found = FALSE
|
||||
|
||||
@@ -271,6 +271,10 @@
|
||||
. = TRUE
|
||||
if("send")
|
||||
start_sending()
|
||||
//We ensure that the holding facility is loaded in time in case we're selling mobs.
|
||||
//This isn't the prettiest place to put it, but 'start_sending()' is also used by civilian bounty computers
|
||||
//And we don't need them to also load the holding facility.
|
||||
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_NINJA_HOLDING_FACILITY)
|
||||
. = TRUE
|
||||
if("stop")
|
||||
stop_sending()
|
||||
@@ -283,12 +287,9 @@
|
||||
|
||||
status_report = "Predicted value: "
|
||||
var/value = 0
|
||||
var/datum/export_report/report = new
|
||||
|
||||
var/obj/machinery/piratepad/pad = pad_ref?.resolve()
|
||||
for(var/atom/movable/AM in get_turf(pad))
|
||||
if(AM == pad)
|
||||
continue
|
||||
export_item_and_contents(AM, apply_elastic = FALSE, dry_run = TRUE, external_report = report, ignore_typecache = nosell_typecache)
|
||||
var/datum/export_report/report = pirate_export_loop(pad)
|
||||
|
||||
for(var/datum/export/exported_datum in report.total_amount)
|
||||
status_report += exported_datum.total_printout(report,notes = FALSE)
|
||||
@@ -303,13 +304,8 @@
|
||||
if(!sending)
|
||||
return
|
||||
|
||||
var/datum/export_report/report = new
|
||||
var/obj/machinery/piratepad/pad = pad_ref?.resolve()
|
||||
|
||||
for(var/atom/movable/item_on_pad in get_turf(pad))
|
||||
if(item_on_pad == pad)
|
||||
continue
|
||||
export_item_and_contents(item_on_pad, apply_elastic = FALSE, delete_unsold = FALSE, external_report = report, ignore_typecache = nosell_typecache)
|
||||
var/datum/export_report/report = pirate_export_loop(pad, dry_run = FALSE)
|
||||
|
||||
status_report = "Sold: "
|
||||
var/value = 0
|
||||
@@ -341,6 +337,33 @@
|
||||
pad.icon_state = pad.idle_state
|
||||
sending = FALSE
|
||||
|
||||
///The loop that calculates the value of stuff on a pirate pad, or plain sell them if dry_run is FALSE.
|
||||
/obj/machinery/computer/piratepad_control/proc/pirate_export_loop(obj/machinery/piratepad/pad, dry_run = TRUE)
|
||||
var/datum/export_report/report = new
|
||||
for(var/atom/movable/item_on_pad as anything in get_turf(pad))
|
||||
if(item_on_pad == pad)
|
||||
continue
|
||||
var/list/hidden_mobs = list()
|
||||
var/skip_movable = FALSE
|
||||
var/list/item_contents = item_on_pad.get_all_contents()
|
||||
for(var/atom/movable/thing in reverse_range(item_contents))
|
||||
///Don't destroy/sell stuff like the captain's laser gun, or borgs.
|
||||
if(thing.resistance_flags & INDESTRUCTIBLE || is_type_in_typecache(thing, nosell_typecache))
|
||||
skip_movable = TRUE
|
||||
break
|
||||
if(isliving(thing))
|
||||
hidden_mobs += thing
|
||||
if(skip_movable)
|
||||
continue
|
||||
for(var/mob/living/hidden as anything in hidden_mobs)
|
||||
///Sell mobs, but leave their contents intact.
|
||||
export_single_item(hidden, apply_elastic = FALSE, dry_run = dry_run, external_report = report)
|
||||
///there are still licing mobs inside that item. Stop, don't sell it ffs.
|
||||
if(locate(/mob/living) in item_on_pad.get_all_contents())
|
||||
continue
|
||||
export_item_and_contents(item_on_pad, apply_elastic = FALSE, dry_run = dry_run, delete_unsold = FALSE, external_report = report, ignore_typecache = nosell_typecache)
|
||||
return report
|
||||
|
||||
/// Prepares to sell the items on the pad
|
||||
/obj/machinery/computer/piratepad_control/proc/start_sending()
|
||||
var/obj/machinery/piratepad/pad = pad_ref?.resolve()
|
||||
@@ -391,7 +414,7 @@
|
||||
|
||||
/datum/export/pirate/ransom/get_cost(atom/movable/exported_item)
|
||||
var/mob/living/carbon/human/ransomee = exported_item
|
||||
if(ransomee.stat != CONSCIOUS || !ransomee.mind) //mint condition only
|
||||
if(ransomee.stat != CONSCIOUS || !ransomee.mind || HAS_TRAIT(ransomee.mind, TRAIT_HAS_BEEN_KIDNAPPED)) //mint condition only
|
||||
return 0
|
||||
else if(FACTION_PIRATE in ransomee.faction) //can't ransom your fellow pirates to CentCom!
|
||||
return 0
|
||||
@@ -400,6 +423,33 @@
|
||||
else
|
||||
return 1000
|
||||
|
||||
/datum/export/pirate/ransom/sell_object(mob/living/carbon/human/sold_item, datum/export_report/report, dry_run = TRUE, apply_elastic = TRUE)
|
||||
. = ..()
|
||||
if(. == EXPORT_NOT_SOLD)
|
||||
return
|
||||
var/turf/picked_turf = pick(GLOB.holdingfacility)
|
||||
sold_item.forceMove(picked_turf)
|
||||
var/mob_cost = get_cost(sold_item)
|
||||
sold_item.process_capture(mob_cost, mob_cost * 1.2)
|
||||
do_sparks(8, FALSE, sold_item)
|
||||
playsound(picked_turf, 'sound/weapons/emitter2.ogg', 25, TRUE)
|
||||
sold_item.flash_act()
|
||||
sold_item.adjust_confusion(10 SECONDS)
|
||||
sold_item.adjust_dizzy(10 SECONDS)
|
||||
addtimer(src, CALLBACK(src, PROC_REF(send_back_to_station), sold_item), COME_BACK_FROM_CAPTURE_TIME)
|
||||
to_chat(sold_item, span_hypnophrase("A million voices echo in your head... <i>\"Yaarrr, thanks for the booty, landlubber. \
|
||||
You will be ransomed back to your station, so it's only a matter of time before we ship you back...</i>"))
|
||||
|
||||
return EXPORT_SOLD_DONT_DELETE
|
||||
|
||||
///Send them back to the station after a while.
|
||||
/datum/export/pirate/ransom/proc/send_back_to_station(mob/living/prisoner)
|
||||
///Deleted or already bailed out of the place.
|
||||
if(QDELETED(prisoner) || !istype(get_area(prisoner), /area/centcom/central_command_areas/holding))
|
||||
return
|
||||
var/obj/structure/closet/supplypod/back_to_station/return_pod = new()
|
||||
return_pod.return_from_capture(prisoner)
|
||||
|
||||
/datum/export/pirate/parrot
|
||||
cost = 2000
|
||||
unit_name = "alive parrot"
|
||||
|
||||
@@ -133,13 +133,15 @@
|
||||
do_sparks(3, FALSE, stealing)
|
||||
|
||||
// Don't mess with it while it's going away
|
||||
var/had_attack_hand_interaction = stealing.interaction_flags_atom & INTERACT_ATOM_ATTACK_HAND
|
||||
stealing.interaction_flags_atom &= ~INTERACT_ATOM_ATTACK_HAND
|
||||
var/was_anchored = stealing.anchored
|
||||
stealing.anchored = TRUE
|
||||
// Add some pizzazz
|
||||
animate(stealing, time = 0.5 SECONDS, transform = matrix(stealing.transform).Scale(0.01), easing = CUBIC_EASING)
|
||||
animate(stealing, time = 0.5 SECONDS, transform = stealing.transform.Scale(0.01), easing = CUBIC_EASING)
|
||||
|
||||
if(isitem(stealing) && ((stealing.resistance_flags & INDESTRUCTIBLE) || prob(black_market_prob)))
|
||||
addtimer(CALLBACK(src, PROC_REF(send_to_black_market), stealing), 0.5 SECONDS)
|
||||
addtimer(CALLBACK(src, PROC_REF(send_to_black_market), stealing, had_attack_hand_interaction, was_anchored), 0.5 SECONDS)
|
||||
else
|
||||
addtimer(CALLBACK(src, PROC_REF(finish_cleanup), stealing), 0.5 SECONDS)
|
||||
|
||||
@@ -158,33 +160,31 @@
|
||||
*
|
||||
* * thing - The item to put up on the black market.
|
||||
*/
|
||||
/datum/spy_bounty/proc/send_to_black_market(atom/movable/thing)
|
||||
/datum/spy_bounty/proc/send_to_black_market(atom/movable/thing, had_attack_hand_interaction, was_anchored)
|
||||
if(QDELETED(thing)) // Just in case anything does anything weird
|
||||
return FALSE
|
||||
|
||||
thing.interaction_flags_atom = initial(thing.interaction_flags_atom)
|
||||
thing.anchored = initial(thing.anchored)
|
||||
///reset the appearance and all.
|
||||
if(had_attack_hand_interaction)
|
||||
thing.interaction_flags_atom |= INTERACT_ATOM_ATTACK_HAND
|
||||
thing.anchored = was_anchored
|
||||
thing.transform = thing.transform.Scale(10)
|
||||
thing.moveToNullspace()
|
||||
|
||||
var/datum/market_item/new_item = new()
|
||||
new_item.item = thing
|
||||
new_item.name = "Stolen [thing.name]"
|
||||
new_item.desc = "A [thing.name], stolen from somewhere on the station. Whoever owned it probably wouldn't be happy to see it here."
|
||||
new_item.category = "Fenced Goods"
|
||||
new_item.stock = 1
|
||||
new_item.availability_prob = 100
|
||||
|
||||
var/item_price
|
||||
switch(difficulty)
|
||||
if(SPY_DIFFICULTY_EASY)
|
||||
new_item.price = PAYCHECK_COMMAND * 2.5
|
||||
item_price = PAYCHECK_COMMAND * 2.5
|
||||
if(SPY_DIFFICULTY_MEDIUM)
|
||||
new_item.price = PAYCHECK_COMMAND * 5
|
||||
item_price = PAYCHECK_COMMAND * 5
|
||||
if(SPY_DIFFICULTY_HARD)
|
||||
new_item.price = PAYCHECK_COMMAND * 10
|
||||
item_price = PAYCHECK_COMMAND * 10
|
||||
|
||||
new_item.price += rand(0, PAYCHECK_COMMAND * 5)
|
||||
item_price += rand(0, PAYCHECK_COMMAND * 5)
|
||||
if(thing.resistance_flags & INDESTRUCTIBLE)
|
||||
new_item.price *= 2
|
||||
item_price *= 2
|
||||
|
||||
var/datum/market_item/stolen_good/new_item = new(thing, item_price)
|
||||
|
||||
return SSblackmarket.markets[/datum/market/blackmarket].add_item(new_item)
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
var/wanted_message
|
||||
///List of everything found on the victim at the time of contracting, used to return their stuff afterwards.
|
||||
var/list/victim_belongings = list()
|
||||
///timerid for stuff that handles victim chat messages, effects and returnal
|
||||
var/victim_timerid
|
||||
|
||||
/datum/syndicate_contract/New(contract_owner, blacklist, type=CONTRACT_PAYOUT_SMALL)
|
||||
contract = new(src)
|
||||
@@ -122,20 +124,8 @@
|
||||
//we'll start the effects in a few seconds since it takes a moment for the pod to leave.
|
||||
addtimer(CALLBACK(src, PROC_REF(handle_victim_experience), person_sent), 3 SECONDS)
|
||||
|
||||
// This is slightly delayed because of the sleep calls above to handle the narrative.
|
||||
// We don't want to tell the station instantly.
|
||||
var/points_to_check
|
||||
var/datum/bank_account/cargo_account = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
if(cargo_account)
|
||||
points_to_check = cargo_account.account_balance
|
||||
if(points_to_check >= ransom)
|
||||
cargo_account.adjust_money(-ransom)
|
||||
else
|
||||
cargo_account.adjust_money(-points_to_check)
|
||||
priority_announce(
|
||||
text = "One of your crew was captured by a rival organisation - we've needed to pay their ransom to bring them back. \
|
||||
As is policy we've taken a portion of the station's funds to offset the overall cost.",
|
||||
sender_override = "Nanotrasen Asset Protection")
|
||||
var/datum/market_item/hostage/market_item = person_sent.process_capture(ransom * (rand(11, 13)/10))
|
||||
RegisterSignal(market_item, COMSIG_MARKET_ITEM_SPAWNED, PROC_REF(on_victim_shipped))
|
||||
|
||||
addtimer(CALLBACK(src, PROC_REF(finish_enter)), 3 SECONDS)
|
||||
|
||||
@@ -166,10 +156,10 @@
|
||||
* level - The current stage of harassement they are facing. This increases by itself, looping until finished.
|
||||
*/
|
||||
/datum/syndicate_contract/proc/handle_victim_experience(mob/living/victim, level = VICTIM_EXPERIENCE_START)
|
||||
// Ship 'em back - dead or alive, 4 minutes wait.
|
||||
// Ship 'em back - dead or alive
|
||||
// Even if they weren't the target, we're still treating them the same.
|
||||
if(!level)
|
||||
addtimer(CALLBACK(src, PROC_REF(return_victim), victim), (60 * 10) * 4)
|
||||
victim_timerid = addtimer(CALLBACK(src, PROC_REF(return_victim), victim), COME_BACK_FROM_CAPTURE_TIME, TIMER_STOPPABLE)
|
||||
if(victim.stat == DEAD)
|
||||
return
|
||||
|
||||
@@ -209,7 +199,7 @@
|
||||
|
||||
level++ //move onto the next level.
|
||||
if(time_until_next)
|
||||
addtimer(CALLBACK(src, PROC_REF(handle_victim_experience), victim, level), time_until_next)
|
||||
victim_timerid = addtimer(CALLBACK(src, PROC_REF(handle_victim_experience), victim, level), time_until_next, TIMER_STOPPABLE)
|
||||
|
||||
#undef VICTIM_EXPERIENCE_START
|
||||
#undef VICTIM_EXPERIENCE_FIRST_HIT
|
||||
@@ -217,34 +207,30 @@
|
||||
#undef VICTIM_EXPERIENCE_THIRD_HIT
|
||||
#undef VICTIM_EXPERIENCE_LAST_HIT
|
||||
|
||||
// We're returning the victim
|
||||
/// We're returning the victim to the station
|
||||
/datum/syndicate_contract/proc/return_victim(mob/living/victim)
|
||||
var/list/possible_drop_loc = list()
|
||||
|
||||
for(var/turf/possible_drop in contract.dropoff.contents)
|
||||
for(var/turf/possible_drop in shuffle(contract.dropoff.contents))
|
||||
if(!isspaceturf(possible_drop) && !isclosedturf(possible_drop))
|
||||
if(!possible_drop.is_blocked_turf())
|
||||
possible_drop_loc.Add(possible_drop)
|
||||
|
||||
if(!possible_drop_loc.len)
|
||||
to_chat(victim, span_hypnophrase("A million voices echo in your head... \"Seems where you got sent here from won't \
|
||||
be able to handle our pod... if we wanted the occupant to survive. Brace yourself, corporate dog.\""))
|
||||
for(var/turf/possible_drop in contract.dropoff.contents)
|
||||
possible_drop_loc.Add(possible_drop)
|
||||
if(iscarbon(victim))
|
||||
var/mob/living/carbon/carbon_victim = victim
|
||||
if(carbon_victim.can_heartattack())
|
||||
carbon_victim.set_heartattack(TRUE)
|
||||
var/turf/destination
|
||||
if(length(possible_drop_loc))
|
||||
destination = pick(possible_drop_loc)
|
||||
|
||||
var/pod_rand_loc = rand(1, possible_drop_loc.len)
|
||||
var/obj/structure/closet/supplypod/return_pod = new()
|
||||
return_pod.bluespace = TRUE
|
||||
return_pod.explosionSize = list(0,0,0,0)
|
||||
return_pod.style = STYLE_SYNDICATE
|
||||
var/obj/structure/closet/supplypod/back_to_station/return_pod = new()
|
||||
return_pod.return_from_capture(victim, destination)
|
||||
returnal_side_effects(return_pod, victim)
|
||||
|
||||
do_sparks(8, FALSE, victim)
|
||||
victim.visible_message(span_notice("[victim] vanishes..."))
|
||||
///Called if the victim is being returned to the station early, when from the black market.
|
||||
/datum/syndicate_contract/proc/on_victim_shipped(datum/market_item/source, obj/item/market_uplink/uplink, shipping_method, turf/shipping_loc)
|
||||
SIGNAL_HANDLER
|
||||
deltimer(victim_timerid)
|
||||
returnal_side_effects(shipping_loc, source.item)
|
||||
|
||||
///The annoying negative effects applied to the victim when returned to the station.
|
||||
/datum/syndicate_contract/proc/returnal_side_effects(atom/dropoff_location, mob/living/victim)
|
||||
for(var/datum/weakref/belonging_ref in victim_belongings)
|
||||
var/obj/item/belonging = belonging_ref.resolve()
|
||||
if(!belonging)
|
||||
@@ -256,16 +242,12 @@
|
||||
continue
|
||||
if(belonging == human_victim.shoes)
|
||||
continue
|
||||
belonging.forceMove(return_pod)
|
||||
belonging.forceMove(dropoff_location)
|
||||
|
||||
for(var/obj/item/W in victim_belongings)
|
||||
W.forceMove(return_pod)
|
||||
|
||||
victim.forceMove(return_pod)
|
||||
for(var/obj/item/item in victim_belongings)
|
||||
item.forceMove(dropoff_location)
|
||||
|
||||
victim.flash_act()
|
||||
victim.adjust_eye_blur(3 SECONDS)
|
||||
victim.adjust_dizzy(3.5 SECONDS)
|
||||
victim.adjust_confusion(2 SECONDS)
|
||||
|
||||
new /obj/effect/pod_landingzone(possible_drop_loc[pod_rand_loc], return_pod)
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
var/alive_bonus = 0
|
||||
/// All stripped targets belongings (weakrefs)
|
||||
var/list/target_belongings = list()
|
||||
/// The ID of the stoppable timer for returning the captured crew
|
||||
var/list/victim_timerid
|
||||
|
||||
duplicate_type = /datum/traitor_objective/target_player
|
||||
|
||||
@@ -216,6 +218,7 @@
|
||||
new /obj/effect/pod_landingzone(get_turf(user), new_pod)
|
||||
|
||||
/datum/traitor_objective/target_player/kidnapping/proc/enter_check(obj/structure/closet/supplypod/extractionpod/source, entered_atom)
|
||||
SIGNAL_HANDLER
|
||||
if(!istype(source))
|
||||
CRASH("Kidnapping objective's enter_check called with source being not an extraction pod: [source ? source.type : "N/A"]")
|
||||
|
||||
@@ -224,9 +227,6 @@
|
||||
|
||||
var/mob/living/carbon/human/sent_mob = entered_atom
|
||||
|
||||
if(sent_mob.mind)
|
||||
ADD_TRAIT(sent_mob.mind, TRAIT_HAS_BEEN_KIDNAPPED, TRAIT_GENERIC)
|
||||
|
||||
for(var/obj/item/belonging in sent_mob.gather_belongings())
|
||||
if(belonging == sent_mob.get_item_by_slot(ITEM_SLOT_ICLOTHING) || belonging == sent_mob.get_item_by_slot(ITEM_SLOT_FEET))
|
||||
continue
|
||||
@@ -236,12 +236,8 @@
|
||||
continue
|
||||
target_belongings.Add(WEAKREF(belonging))
|
||||
|
||||
var/datum/bank_account/cargo_account = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
|
||||
if(cargo_account) //Just in case
|
||||
cargo_account.adjust_money(-min(rand(1000, 3000), cargo_account.account_balance)) //Not so much, especially for competent cargo. Plus this can't be mass-triggered like it has been done with contractors
|
||||
|
||||
priority_announce("One of your crew was captured by a rival organisation - we've needed to pay their ransom to bring them back. As is policy we've taken a portion of the station's funds to offset the overall cost.", "Nanotrasen Asset Protection", has_important_message = TRUE)
|
||||
var/datum/market_item/hostage/market_item = sent_mob.process_capture(rand(1000, 3000))
|
||||
RegisterSignal(market_item, COMSIG_MARKET_ITEM_SPAWNED, PROC_REF(on_victim_shipped))
|
||||
|
||||
addtimer(CALLBACK(src, PROC_REF(handle_target), sent_mob), 1.5 SECONDS)
|
||||
|
||||
@@ -257,7 +253,7 @@
|
||||
source.startExitSequence(source)
|
||||
|
||||
/datum/traitor_objective/target_player/kidnapping/proc/handle_target(mob/living/carbon/human/sent_mob)
|
||||
addtimer(CALLBACK(src, PROC_REF(return_target), sent_mob), 3 MINUTES)
|
||||
victim_timerid = addtimer(CALLBACK(src, PROC_REF(return_target), sent_mob), COME_BACK_FROM_CAPTURE_TIME, TIMER_STOPPABLE)
|
||||
if(sent_mob.stat == DEAD)
|
||||
return
|
||||
|
||||
@@ -266,29 +262,24 @@
|
||||
sent_mob.adjust_dizzy(10 SECONDS)
|
||||
sent_mob.set_eye_blur_if_lower(100 SECONDS)
|
||||
sent_mob.dna.species.give_important_for_life(sent_mob) // so plasmamen do not get left for dead
|
||||
to_chat(sent_mob, span_hypnophrase(span_reallybig("A million voices echo in your head... <i>\"Your mind held many valuable secrets - \
|
||||
to_chat(sent_mob, span_hypnophrase("A million voices echo in your head... <i>\"Your mind held many valuable secrets - \
|
||||
we thank you for providing them. Your value is expended, and you will be ransomed back to your station. We always get paid, \
|
||||
so it's only a matter of time before we ship you back...\"</i>")))
|
||||
so it's only a matter of time before we ship you back...\"</i>"))
|
||||
|
||||
/datum/traitor_objective/target_player/kidnapping/proc/return_target(mob/living/carbon/human/sent_mob)
|
||||
if(!sent_mob || QDELETED(sent_mob)) //suicided and qdeleted themselves
|
||||
return
|
||||
|
||||
var/turf/return_turf = get_safe_random_station_turf()
|
||||
if(!return_turf) //SOMEHOW
|
||||
to_chat(sent_mob, span_hypnophrase(span_reallybig("A million voices echo in your head... <i>\"Seems where you got sent here from won't \
|
||||
be able to handle our pod... You will die here instead.\"</i></span>")))
|
||||
if (sent_mob.can_heartattack())
|
||||
sent_mob.set_heartattack(TRUE)
|
||||
return
|
||||
var/obj/structure/closet/supplypod/back_to_station/return_pod = new()
|
||||
return_pod.return_from_capture(sent_mob)
|
||||
returnal_side_effects(return_pod, sent_mob)
|
||||
|
||||
var/obj/structure/closet/supplypod/return_pod = new()
|
||||
return_pod.bluespace = TRUE
|
||||
return_pod.explosionSize = list(0,0,0,0)
|
||||
return_pod.style = STYLE_SYNDICATE
|
||||
/datum/traitor_objective/target_player/kidnapping/proc/on_victim_shipped(datum/market_item/source, obj/item/market_uplink/uplink, shipping_method, turf/shipping_loc)
|
||||
SIGNAL_HANDLER
|
||||
deltimer(victim_timerid)
|
||||
returnal_side_effects(shipping_loc, source.item)
|
||||
|
||||
do_sparks(8, FALSE, sent_mob)
|
||||
sent_mob.visible_message(span_notice("[sent_mob] vanishes!"))
|
||||
/datum/traitor_objective/target_player/kidnapping/proc/returnal_side_effects(atom/dropoff_location, mob/living/carbon/human/sent_mob)
|
||||
for(var/obj/item/belonging in sent_mob.gather_belongings())
|
||||
if(belonging == sent_mob.get_item_by_slot(ITEM_SLOT_ICLOTHING) || belonging == sent_mob.get_item_by_slot(ITEM_SLOT_FEET))
|
||||
continue
|
||||
@@ -298,13 +289,10 @@
|
||||
var/obj/item/belonging = belonging_ref.resolve()
|
||||
if(!belonging)
|
||||
continue
|
||||
belonging.forceMove(return_pod)
|
||||
belonging.forceMove(dropoff_location)
|
||||
|
||||
sent_mob.forceMove(return_pod)
|
||||
sent_mob.flash_act()
|
||||
sent_mob.adjust_confusion(10 SECONDS)
|
||||
sent_mob.adjust_dizzy(10 SECONDS)
|
||||
sent_mob.set_eye_blur_if_lower(100 SECONDS)
|
||||
sent_mob.dna.species.give_important_for_life(sent_mob) // so plasmamen do not get left for dead
|
||||
|
||||
new /obj/effect/pod_landingzone(return_turf, return_pod)
|
||||
|
||||
@@ -30,6 +30,14 @@ Then the player gets the profit from selling his own wasted time.
|
||||
///set to false if any objects in a dry run were unscannable
|
||||
var/all_contents_scannable = TRUE
|
||||
|
||||
/// Makes sure the exports list is populated and that the report isn't null.
|
||||
/proc/init_export(datum/export_report/external_report)
|
||||
if(!length(GLOB.exports_list))
|
||||
setupExports()
|
||||
if(isnull(external_report))
|
||||
external_report = new
|
||||
return external_report
|
||||
|
||||
/*
|
||||
* Handles exporting a movable atom and its contents
|
||||
* Arguments:
|
||||
@@ -40,32 +48,15 @@ Then the player gets the profit from selling his own wasted time.
|
||||
** ignore_typecache: typecache containing types that should be completely ignored
|
||||
*/
|
||||
/proc/export_item_and_contents(atom/movable/exported_atom, apply_elastic = TRUE, delete_unsold = TRUE, dry_run = FALSE, datum/export_report/external_report, list/ignore_typecache)
|
||||
if(!GLOB.exports_list.len)
|
||||
setupExports()
|
||||
external_report = init_export()
|
||||
|
||||
var/list/contents = exported_atom.get_all_contents_ignoring(ignore_typecache)
|
||||
|
||||
var/datum/export_report/report = external_report
|
||||
|
||||
if(!report) //If we don't have any longer transaction going on
|
||||
report = new
|
||||
|
||||
// We go backwards, so it'll be innermost objects sold first. We also make sure nothing is accidentally delete before everything is sold.
|
||||
var/list/to_delete = list()
|
||||
for(var/atom/movable/thing as anything in reverse_range(contents))
|
||||
var/sold = FALSE
|
||||
for(var/datum/export/export as anything in GLOB.exports_list)
|
||||
if(export.applies_to(thing, apply_elastic))
|
||||
if(!dry_run && (SEND_SIGNAL(thing, COMSIG_ITEM_PRE_EXPORT) & COMPONENT_STOP_EXPORT))
|
||||
break
|
||||
//Don't add value of unscannable items for a dry run report
|
||||
if(dry_run && !export.scannable)
|
||||
report.all_contents_scannable = FALSE
|
||||
break
|
||||
sold = export.sell_object(thing, report, dry_run, apply_elastic)
|
||||
report.exported_atoms += " [thing.name]"
|
||||
break
|
||||
if(!dry_run && (sold || delete_unsold))
|
||||
var/sold = _export_loop(thing, apply_elastic, dry_run, external_report)
|
||||
if(!dry_run && (sold || delete_unsold) && sold != EXPORT_SOLD_DONT_DELETE)
|
||||
if(ismob(thing))
|
||||
thing.investigate_log("deleted through cargo export", INVESTIGATE_CARGO)
|
||||
to_delete += thing
|
||||
@@ -74,7 +65,35 @@ Then the player gets the profit from selling his own wasted time.
|
||||
if(!QDELETED(thing))
|
||||
qdel(thing)
|
||||
|
||||
return report
|
||||
return external_report
|
||||
|
||||
/// It works like export_item_and_contents(), however it ignores the contents. Meaning only `exported_atom` will be valued.
|
||||
/proc/export_single_item(atom/movable/exported_atom, apply_elastic = TRUE, delete_unsold = TRUE, dry_run = FALSE, datum/export_report/external_report)
|
||||
external_report = init_export()
|
||||
|
||||
var/sold = _export_loop(exported_atom, apply_elastic, dry_run, external_report)
|
||||
if(!dry_run && (sold || delete_unsold) && sold != EXPORT_SOLD_DONT_DELETE)
|
||||
if(ismob(exported_atom))
|
||||
exported_atom.investigate_log("deleted through cargo export", INVESTIGATE_CARGO)
|
||||
qdel(exported_atom)
|
||||
|
||||
return external_report
|
||||
|
||||
/// The main bit responsible for selling the item. Shared by export_single_item() and export_item_and_contents()
|
||||
/proc/_export_loop(atom/movable/exported_atom, apply_elastic = TRUE, dry_run = FALSE, datum/export_report/external_report)
|
||||
var/sold = EXPORT_NOT_SOLD
|
||||
for(var/datum/export/export as anything in GLOB.exports_list)
|
||||
if(export.applies_to(exported_atom, apply_elastic))
|
||||
if(!dry_run && (SEND_SIGNAL(exported_atom, COMSIG_ITEM_PRE_EXPORT) & COMPONENT_STOP_EXPORT))
|
||||
break
|
||||
//Don't add value of unscannable items for a dry run report
|
||||
if(dry_run && !export.scannable)
|
||||
external_report.all_contents_scannable = FALSE
|
||||
break
|
||||
sold = export.sell_object(exported_atom, exported_atom, dry_run, apply_elastic)
|
||||
external_report.exported_atoms += " [exported_atom.name]"
|
||||
break
|
||||
return sold
|
||||
|
||||
/datum/export
|
||||
/// Unit name. Only used in "Received [total_amount] [name]s [message]."
|
||||
@@ -164,7 +183,7 @@ Then the player gets the profit from selling his own wasted time.
|
||||
var/export_amount = get_amount(sold_item)
|
||||
|
||||
if(export_amount <= 0 || (export_value <= 0 && !allow_negative_cost))
|
||||
return FALSE
|
||||
return EXPORT_NOT_SOLD
|
||||
|
||||
// If we're not doing a dry run, send COMSIG_ITEM_EXPORTED to the sold item
|
||||
var/export_result
|
||||
@@ -180,7 +199,7 @@ Then the player gets the profit from selling his own wasted time.
|
||||
if(apply_elastic)
|
||||
cost *= NUM_E**(-1 * k_elasticity * export_amount) //marginal cost modifier
|
||||
SSblackbox.record_feedback("nested tally", "export_sold_cost", 1, list("[sold_item.type]", "[export_value]"))
|
||||
return TRUE
|
||||
return EXPORT_SOLD
|
||||
|
||||
/*
|
||||
* Total printout for the cargo console.
|
||||
|
||||
@@ -20,39 +20,53 @@
|
||||
categories += item.category
|
||||
available_items[item.category] = list()
|
||||
|
||||
available_items[item.category] += item
|
||||
available_items[item.category][item.identifier] = item
|
||||
RegisterSignal(item, COMSIG_QDELETING, PROC_REF(on_item_del))
|
||||
return TRUE
|
||||
|
||||
/datum/market/proc/on_item_del(datum/market_item/item)
|
||||
SIGNAL_HANDLER
|
||||
available_items[item.category] -= item.identifier
|
||||
if(!length(available_items[item.category]))
|
||||
available_items -= item.category
|
||||
|
||||
/// Handles buying the item, this is mainly for future use and moving the code away from the uplink.
|
||||
/datum/market/proc/purchase(item, category, method, obj/item/market_uplink/uplink, user)
|
||||
if(!istype(uplink) || !(method in shipping))
|
||||
/datum/market/proc/purchase(identifier, category, method, obj/item/market_uplink/uplink, user)
|
||||
var/datum/market_item/item = available_items[category][identifier]
|
||||
if(isnull(item))
|
||||
return FALSE
|
||||
|
||||
for(var/datum/market_item/I in available_items[category])
|
||||
if(I.type != item)
|
||||
continue
|
||||
var/price = I.price + shipping[method]
|
||||
|
||||
if(!uplink.current_user)///There is no ID card on the user, or the ID card has no account
|
||||
to_chat(user, span_warning("The uplink sparks, as it can't identify an ID card with a bank account on you."))
|
||||
return FALSE
|
||||
var/balance = uplink?.current_user.account_balance
|
||||
|
||||
// I can't get the price of the item and shipping in a clean way to the UI, so I have to do this.
|
||||
if(balance < price)
|
||||
to_chat(user, span_warning("You don't have enough credits in [uplink] for [I] with [method] shipping."))
|
||||
return FALSE
|
||||
|
||||
if(I.buy(uplink, user, method))
|
||||
uplink.current_user.adjust_money(-price, "Other: Third Party Transaction")
|
||||
if(ismob(user))
|
||||
var/mob/m_user = user
|
||||
m_user.playsound_local(get_turf(m_user), 'sound/machines/twobeep_high.ogg', 50, TRUE)
|
||||
return TRUE
|
||||
if(!istype(uplink) || !((method in shipping) || (method in item.shipping_override)))
|
||||
return FALSE
|
||||
|
||||
var/shipment_fee = item.shipping_override?[method]
|
||||
if(isnull(shipment_fee))
|
||||
shipment_fee = shipping[method]
|
||||
var/price = item.price + shipment_fee
|
||||
|
||||
if(!uplink.current_user)///There is no ID card on the user, or the ID card has no account
|
||||
to_chat(user, span_warning("The uplink sparks, as it can't identify an ID card with a bank account on you."))
|
||||
return FALSE
|
||||
var/balance = uplink?.current_user.account_balance
|
||||
|
||||
// I can't get the price of the item and shipping in a clean way to the UI, so I have to do this.
|
||||
if(balance < price)
|
||||
to_chat(user, span_warning("You don't have enough credits in [uplink] for [item] with [method] shipping."))
|
||||
return FALSE
|
||||
|
||||
if(item.buy(uplink, user, method))
|
||||
uplink.current_user.adjust_money(-price, "Other: Third Party Transaction")
|
||||
if(ismob(user))
|
||||
var/mob/m_user = user
|
||||
m_user.playsound_local(get_turf(m_user), 'sound/machines/twobeep_high.ogg', 50, TRUE)
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/datum/market/blackmarket
|
||||
name = "Black Market"
|
||||
shipping = list(SHIPPING_METHOD_LTSRBT =50,
|
||||
SHIPPING_METHOD_LAUNCH =10,
|
||||
SHIPPING_METHOD_TELEPORT=75)
|
||||
shipping = list(
|
||||
SHIPPING_METHOD_LTSRBT = 40,
|
||||
SHIPPING_METHOD_LAUNCH = 10,
|
||||
SHIPPING_METHOD_TELEPORT= 75,
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
var/stock
|
||||
|
||||
/// Path to or the item itself what this entry is for, this should be set even if you override spawn_item to spawn your item.
|
||||
var/obj/item/item
|
||||
var/atom/movable/item
|
||||
|
||||
/// Minimum price for the item if generated randomly.
|
||||
var/price_min = 0
|
||||
@@ -27,27 +27,60 @@
|
||||
/// Probability for this item to be available. Used by SSblackmarket on init.
|
||||
var/availability_prob = 0
|
||||
|
||||
///The identifier for the market item, generated on runtime and used to access them in the market categories.
|
||||
var/identifier
|
||||
|
||||
///If set, these will override the shipment methods set by the market
|
||||
var/list/shipping_override
|
||||
|
||||
/datum/market_item/New()
|
||||
if(isnull(price))
|
||||
price = rand(price_min, price_max)
|
||||
if(isnull(stock))
|
||||
stock = rand(stock_min, stock_max)
|
||||
identifier = "[type]"
|
||||
|
||||
///For 'dynamic' market items generated on runtime, this proc is to be used to properly sets the item, especially if it's a hardref.
|
||||
/datum/market_item/proc/set_item(path_or_ref)
|
||||
//we're replacing the item to sell, and the old item is an instance!
|
||||
if(ismovable(item))
|
||||
UnregisterSignal(item, COMSIG_QDELETING)
|
||||
item = path_or_ref
|
||||
identifier = "[path_or_ref]"
|
||||
if(ismovable(path_or_ref))
|
||||
RegisterSignal(item, COMSIG_QDELETING, PROC_REF(on_item_del))
|
||||
identifier = "[REF(src)]"
|
||||
|
||||
/datum/market_item/Destroy()
|
||||
item = null
|
||||
return ..()
|
||||
|
||||
/datum/market_item/proc/on_item_del(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
qdel(src)
|
||||
|
||||
/// Used for spawning the wanted item, override if you need to do something special with the item.
|
||||
/datum/market_item/proc/spawn_item(loc)
|
||||
/datum/market_item/proc/spawn_item(loc, datum/market_purchase/purchase)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SEND_SIGNAL(src, COMSIG_MARKET_ITEM_SPAWNED, purchase.uplink, purchase.method, loc)
|
||||
if(ismovable(item))
|
||||
item.forceMove(loc)
|
||||
return item
|
||||
var/atom/movable/return_item = item
|
||||
UnregisterSignal(item, COMSIG_QDELETING)
|
||||
if(isnull(loc))
|
||||
item.moveToNullspace()
|
||||
else
|
||||
do_sparks(8, FALSE, item)
|
||||
item.visible_message(span_notice("[item] vanishes..."))
|
||||
item.forceMove(loc)
|
||||
item = null
|
||||
return return_item
|
||||
if(ispath(item))
|
||||
return new item(loc)
|
||||
CRASH("Invalid item type for market item [item || "null"]")
|
||||
|
||||
/// Buys the item and makes SSblackmarket handle it.
|
||||
/datum/market_item/proc/buy(obj/item/market_uplink/uplink, mob/buyer, shipping_method)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
// Sanity
|
||||
if(!istype(uplink) || !istype(buyer))
|
||||
return FALSE
|
||||
@@ -70,16 +103,34 @@
|
||||
/datum/market_purchase
|
||||
/// The entry being purchased.
|
||||
var/datum/market_item/entry
|
||||
/// Instance of the item being sent.
|
||||
var/item
|
||||
/// Instance of the item being sent, used by the market telepad
|
||||
var/atom/movable/item
|
||||
/// The uplink where this purchase was done from.
|
||||
var/obj/item/market_uplink/uplink
|
||||
/// Shipping method used to buy this item.
|
||||
var/method
|
||||
|
||||
/datum/market_purchase/New(_entry, _uplink, _method)
|
||||
entry = _entry
|
||||
if(!ispath(entry.item))
|
||||
/datum/market_purchase/New(datum/market_item/entry, obj/item/market_uplink/uplink, method)
|
||||
if(!uplink || !entry || !method)
|
||||
CRASH("[type] created with a false value arg: (entry: [entry] - uplink: [uplink] - method: [method])")
|
||||
src.entry = entry
|
||||
src.uplink = uplink
|
||||
src.method = method
|
||||
RegisterSignal(entry, COMSIG_QDELETING, PROC_REF(on_instance_del))
|
||||
RegisterSignal(uplink, COMSIG_QDELETING, PROC_REF(on_instance_del))
|
||||
if(ismovable(entry.item))
|
||||
item = entry.item
|
||||
uplink = _uplink
|
||||
method = _method
|
||||
RegisterSignal(entry.item, COMSIG_QDELETING, PROC_REF(on_instance_del))
|
||||
|
||||
/datum/market_purchase/Destroy()
|
||||
entry = null
|
||||
uplink = null
|
||||
SSblackmarket.queued_purchases -= src
|
||||
return ..()
|
||||
|
||||
/datum/market_purchase/proc/on_instance_del(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
if(QDELETED(src))
|
||||
return
|
||||
// Uh oh, uplink or item is gone. We will just keep the money and you will not get your order.
|
||||
qdel(src)
|
||||
|
||||
@@ -39,7 +39,8 @@
|
||||
/obj/item/storage/pill_bottle/lsd,
|
||||
/obj/item/storage/pill_bottle/aranesp,
|
||||
/obj/item/storage/pill_bottle/stimulant))
|
||||
return new pillbottle(loc)
|
||||
item = pillbottle
|
||||
return ..()
|
||||
|
||||
/datum/market_item/consumable/floor_pill
|
||||
name = "Strange Pill"
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
///A special category for mobs captured by pirates, tots and contractors, should someone ever want to get them back in advance.
|
||||
/datum/market_item/hostage
|
||||
category = "Hostages"
|
||||
stock = 1
|
||||
availability_prob = 100
|
||||
shipping_override = list(SHIPPING_METHOD_LTSRBT = 0, SHIPPING_METHOD_SUPPLYPOD = 350)
|
||||
/// temporary reference to the 4 in 7 chances of signaler and electropack.
|
||||
var/obj/item/assembly/signaler/signaler
|
||||
|
||||
/datum/market_item/hostage/New(mob/living/mob, new_price)
|
||||
..()
|
||||
set_item(mob)
|
||||
name = "[mob.real_name]"
|
||||
var/specimen = initial(mob.name)
|
||||
var/humie_mob = ishuman(mob)
|
||||
if(humie_mob)
|
||||
var/mob/living/carbon/human/humie = mob
|
||||
specimen = humie.dna.species.name
|
||||
desc = pick(list(
|
||||
"If you're looking for a recently stolen [specimen], you've come to the right place.",
|
||||
"we've recently aquired a fine [specimen] from a station around here, eheh...",
|
||||
"For a limited time, we're offering this [specimen] for you to buy (back).",
|
||||
))
|
||||
desc += " DISCLAIMER: The offer will expire once the creature is returned to the station."
|
||||
if(humie_mob)
|
||||
desc += "[mob.p_they(TRUE)] may be delivered handcuffed, for safety of course."
|
||||
|
||||
price = new_price
|
||||
RegisterSignal(mob, COMSIG_LIVING_RETURN_FROM_CAPTURE, PROC_REF(on_return_from_capture))
|
||||
|
||||
/datum/market_item/hostage/proc/on_return_from_capture(mob/living/source, turf/destination)
|
||||
SIGNAL_HANDLER
|
||||
qdel(src) //as if we never existed, our mentions we'll be removed from the market.
|
||||
|
||||
/datum/market_item/hostage/Destroy()
|
||||
signaler = null
|
||||
return ..()
|
||||
|
||||
/datum/market_item/hostage/buy(obj/item/market_uplink/uplink, mob/buyer, shipping_method)
|
||||
. = ..()
|
||||
var/mob/living/humie = item
|
||||
if(!. || !istype(humie) || !prob(57)) // 3 in 7 chance of the electropack set not spawning...
|
||||
return
|
||||
signaler = new(uplink.drop_location())
|
||||
RegisterSignal(signaler, COMSIG_QDELETING, PROC_REF(clear_signaler_ref))
|
||||
signaler.set_frequency(sanitize_frequency(rand(MIN_FREE_FREQ, MAX_FREE_FREQ)))
|
||||
signaler.code = rand(1, 100)
|
||||
buyer.put_in_hands(signaler)
|
||||
to_chat(buyer, span_notice("A [signaler] appears [buyer.is_holding(signaler) ? "in your hands" : "at your feet"]!"))
|
||||
|
||||
/datum/market_item/hostage/proc/clear_signaler_ref(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
signaler = null
|
||||
|
||||
/datum/market_item/hostage/spawn_item(loc, datum/market_purchase/purchase)
|
||||
var/mob/living/mob = item
|
||||
UnregisterSignal(mob, COMSIG_LIVING_RETURN_FROM_CAPTURE)
|
||||
if(!mob.IsUnconscious())
|
||||
to_chat(mob, span_boldnicegreen("You have been <u>bought</u> back to the station. Be grateful to whoever got you out of the holding facility early."))
|
||||
if(!ishuman(item))
|
||||
return ..()
|
||||
var/mob/living/carbon/human/humie = item
|
||||
if(signaler) //57% chance that the mob is equipped with electropack and cuffs
|
||||
humie.equip_to_slot_or_del(new /obj/item/restraints/handcuffs, ITEM_SLOT_HANDCUFFED, indirect_action = TRUE)
|
||||
if(humie.back) //try to remove the neck item if possible before we attempt to install the collar bomb
|
||||
humie.transferItemToLoc(humie.back, loc)
|
||||
var/obj/item/electropack/pack = new(loc)
|
||||
pack.set_frequency(signaler.frequency)
|
||||
pack.code = signaler.code
|
||||
humie.equip_to_slot_if_possible(pack, ITEM_SLOT_BACK, disable_warning = TRUE)
|
||||
UnregisterSignal(signaler, COMSIG_QDELETING)
|
||||
signaler = null
|
||||
else if(prob(66)) // 29% chance of just cuffs
|
||||
humie.equip_to_slot_or_del(new /obj/item/restraints/handcuffs, ITEM_SLOT_HANDCUFFED, indirect_action = TRUE)
|
||||
else // 14% chance of just a tee souvenir and pin, no cuffs and shit.
|
||||
var/obj/item/clothing/under/misc/syndicate_souvenir/souvenir = new(loc)
|
||||
humie.equip_to_slot_if_possible(souvenir, ITEM_SLOT_ICLOTHING, indirect_action = TRUE)
|
||||
var/obj/item/clothing/accessory/anti_sec_pin/pin = new(loc)
|
||||
pin.attach(souvenir)
|
||||
|
||||
if(isnull(humie.w_uniform))
|
||||
//FUCKING SLAVES, GET YOUR CLOTHES BACK ON!
|
||||
humie.equip_to_slot_or_del(new /obj/item/clothing/under/costume/jabroni(humie), ITEM_SLOT_ICLOTHING, indirect_action = TRUE)
|
||||
return ..()
|
||||
@@ -68,9 +68,11 @@
|
||||
stock_max = 3
|
||||
availability_prob = 40
|
||||
|
||||
/datum/market_item/misc/holywater/spawn_item(loc)
|
||||
/datum/market_item/misc/holywater/spawn_item(loc, datum/market_purchase/purchase)
|
||||
if (prob(6.66))
|
||||
return new /obj/item/reagent_containers/cup/beaker/unholywater(loc)
|
||||
item = /obj/item/reagent_containers/cup/beaker/unholywater
|
||||
else
|
||||
item = initial(item)
|
||||
return ..()
|
||||
|
||||
/datum/market_item/misc/strange_seed
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
///A special category for goods stolen by spies for their bounties.
|
||||
/datum/market_item/stolen_good
|
||||
category = "Fenced Goods"
|
||||
stock = 1
|
||||
availability_prob = 100
|
||||
|
||||
/datum/market_item/stolen_good/New(atom/movable/thing, thing_price)
|
||||
..()
|
||||
set_item(thing)
|
||||
name = "Stolen [thing.name]"
|
||||
desc = "A [thing.name], stolen from somewhere on the station. Whoever owned it probably wouldn't be happy to see it here."
|
||||
price = thing_price
|
||||
@@ -1,6 +1,18 @@
|
||||
/datum/market_item/tool
|
||||
category = "Tools"
|
||||
|
||||
/datum/market_item/tool/blackmarket_telepad
|
||||
name = "Black Market LTSRBT"
|
||||
desc = "Need a faster and better way of transporting your illegal goods from and to the \
|
||||
station? Fear not, the Long-To-Short-Range-Bluespace-Transceiver is here to help. \
|
||||
Contains a LTSRBT circuit. Bluespace crystals and ansible not included."
|
||||
item = /obj/item/circuitboard/machine/ltsrbt
|
||||
stock_min = 2
|
||||
stock_max = 4
|
||||
price_min = CARGO_CRATE_VALUE * 2.5
|
||||
price_max = CARGO_CRATE_VALUE * 3.75
|
||||
availability_prob = 100
|
||||
|
||||
/datum/market_item/tool/caravan_wrench
|
||||
name = "Experimental Wrench"
|
||||
desc = "The extra fast and handy wrench you always wanted!"
|
||||
|
||||
@@ -26,13 +26,13 @@
|
||||
/// The time it takes for the machine to recharge before being able to send or receive items.
|
||||
var/recharge_time = 0
|
||||
/// Current recharge progress.
|
||||
var/recharge_cooldown = 0
|
||||
COOLDOWN_DECLARE(recharge_cooldown)
|
||||
/// Base recharge time in seconds which is used to get recharge_time.
|
||||
var/base_recharge_time = 100
|
||||
/// Current /datum/market_purchase being received.
|
||||
var/receiving
|
||||
var/datum/market_purchase/receiving
|
||||
/// Current /datum/market_purchase being sent to the target uplink.
|
||||
var/transmitting
|
||||
var/datum/market_purchase/transmitting
|
||||
/// Queue for purchases that the machine should receive and send.
|
||||
var/list/datum/market_purchase/queue = list()
|
||||
|
||||
@@ -67,46 +67,48 @@
|
||||
/obj/machinery/ltsrbt/proc/add_to_queue(datum/market_purchase/purchase)
|
||||
if(!recharge_cooldown && !receiving && !transmitting)
|
||||
receiving = purchase
|
||||
return
|
||||
queue += purchase
|
||||
else
|
||||
queue += purchase
|
||||
RegisterSignal(receiving, COMSIG_QDELETING, PROC_REF(on_receiving_del))
|
||||
|
||||
/obj/machinery/ltsrbt/proc/on_receiving_del(datum/market_purchase/purchase)
|
||||
SIGNAL_HANDLER
|
||||
queue -= purchase
|
||||
if(receiving == purchase)
|
||||
receiving = null
|
||||
if(transmitting == purchase)
|
||||
transmitting = null
|
||||
|
||||
/obj/machinery/ltsrbt/process(seconds_per_tick)
|
||||
if(machine_stat & NOPOWER)
|
||||
return
|
||||
|
||||
if(recharge_cooldown > 0)
|
||||
recharge_cooldown -= seconds_per_tick
|
||||
if(!COOLDOWN_FINISHED(src, recharge_cooldown) && isnull(receiving) && isnull(transmitting))
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(receiving)
|
||||
var/datum/market_purchase/P = receiving
|
||||
COOLDOWN_START(src, recharge_cooldown, recharge_time)
|
||||
|
||||
P.item = P.entry.spawn_item(T)
|
||||
var/turf/turf = get_turf(src)
|
||||
if(receiving)
|
||||
|
||||
receiving.item = receiving.entry.spawn_item(turf, receiving)
|
||||
|
||||
use_power(power_usage_per_teleport / power_efficiency)
|
||||
var/datum/effect_system/spark_spread/sparks = new
|
||||
sparks.set_up(5, 1, get_turf(src))
|
||||
sparks.attach(P.item)
|
||||
sparks.attach(receiving.item)
|
||||
sparks.start()
|
||||
|
||||
transmitting = receiving
|
||||
receiving = null
|
||||
transmitting = P
|
||||
|
||||
recharge_cooldown = recharge_time
|
||||
return
|
||||
else if(transmitting)
|
||||
var/datum/market_purchase/P = transmitting
|
||||
if(!P.item)
|
||||
QDEL_NULL(transmitting)
|
||||
if(!(P.item in T.contents))
|
||||
QDEL_NULL(transmitting)
|
||||
return
|
||||
do_teleport(P.item, get_turf(P.uplink))
|
||||
use_power(power_usage_per_teleport / power_efficiency)
|
||||
if(transmitting)
|
||||
if(transmitting.item.loc == turf)
|
||||
do_teleport(transmitting.item, get_turf(transmitting.uplink))
|
||||
use_power(power_usage_per_teleport / power_efficiency)
|
||||
QDEL_NULL(transmitting)
|
||||
|
||||
recharge_cooldown = recharge_time
|
||||
return
|
||||
|
||||
if(queue.len)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
var/viewing_category
|
||||
/// What market is currently being bought from by the uplink?
|
||||
var/viewing_market
|
||||
/// What item is the current uplink attempting to buy?
|
||||
/// the identifier of the item that the current uplink is attempting to buy
|
||||
var/selected_item
|
||||
/// Is the uplink in the process of buying the selected item?
|
||||
var/buying
|
||||
@@ -56,25 +56,31 @@
|
||||
current_user = null
|
||||
data["categories"] = market ? market.categories : null
|
||||
data["delivery_methods"] = list()
|
||||
if(market)
|
||||
for(var/delivery in market.shipping)
|
||||
data["delivery_methods"] += list(list("name" = delivery, "price" = market.shipping[delivery]))
|
||||
data["money"] = "N/A cr"
|
||||
if(current_user)
|
||||
data["money"] = current_user.account_balance
|
||||
data["buying"] = buying
|
||||
if(buying && market)
|
||||
var/datum/market_item/target_item = market.available_items[viewing_category][selected_item]
|
||||
var/list/shipping_list = market.shipping
|
||||
if(length(target_item?.shipping_override))
|
||||
shipping_list = target_item.shipping_override
|
||||
for(var/delivery in shipping_list)
|
||||
UNTYPED_LIST_ADD(data["delivery_methods"], list("name" = delivery, "price" = shipping_list[delivery]))
|
||||
data["items"] = list()
|
||||
data["viewing_category"] = viewing_category
|
||||
data["viewing_category"] = market.categories[viewing_category] ? viewing_category : null
|
||||
data["viewing_market"] = viewing_market
|
||||
if(viewing_category && market)
|
||||
if(market.available_items[viewing_category])
|
||||
for(var/datum/market_item/I in market.available_items[viewing_category])
|
||||
var/list/market_category = market.available_items[viewing_category]
|
||||
for(var/id in market_category)
|
||||
var/datum/market_item/item = market_category[id]
|
||||
data["items"] += list(list(
|
||||
"id" = I.type,
|
||||
"name" = I.name,
|
||||
"cost" = I.price,
|
||||
"amount" = I.stock,
|
||||
"desc" = I.desc || I.name
|
||||
"id" = id,
|
||||
"name" = item.name,
|
||||
"cost" = item.price,
|
||||
"amount" = item.stock,
|
||||
"desc" = item.desc || item.name
|
||||
))
|
||||
return data
|
||||
|
||||
@@ -123,8 +129,7 @@
|
||||
if("select")
|
||||
if(isnull(params["item"]))
|
||||
return
|
||||
var/item = text2path(params["item"])
|
||||
selected_item = item
|
||||
selected_item = params["item"]
|
||||
buying = TRUE
|
||||
. = TRUE
|
||||
if("cancel")
|
||||
|
||||
@@ -118,19 +118,6 @@
|
||||
if(prob(10)) //A little extra sugar every now and then to shake things up.
|
||||
new /obj/item/switchblade(our_crate)
|
||||
|
||||
/datum/supply_pack/imports/blackmarket_telepad
|
||||
name = "Black Market LTSRBT"
|
||||
desc = "Need a faster and better way of transporting your illegal goods from and to the \
|
||||
station? Fear not, the Long-To-Short-Range-Bluespace-Transceiver (LTSRBT for short) \
|
||||
is here to help. Contains a LTSRBT circuit, two bluespace crystals, and one ansible."
|
||||
cost = CARGO_CRATE_VALUE * 20
|
||||
contraband = TRUE
|
||||
contains = list(
|
||||
/obj/item/circuitboard/machine/ltsrbt,
|
||||
/obj/item/stack/ore/bluespace_crystal/artificial = 2,
|
||||
/obj/item/stock_parts/subspace/ansible,
|
||||
)
|
||||
|
||||
/datum/supply_pack/imports/contraband
|
||||
name = "'Contraband' Crate"
|
||||
desc = "Psst.. bud... want some contraband? I can get you a poster, some nice cigs, dank, even some \
|
||||
|
||||
@@ -241,6 +241,24 @@
|
||||
/obj/structure/closet/supplypod/open(mob/living/user, force = FALSE, special_effects = TRUE)
|
||||
return
|
||||
|
||||
///Called by the drop pods that return captured crewmembers from the ninja den.
|
||||
/obj/structure/closet/supplypod/proc/return_from_capture(mob/living/victim, turf/destination = get_safe_random_station_turf())
|
||||
if(isnull(destination)) //Uuuuh, something went wrong. This is gonna hurt.
|
||||
to_chat(victim, span_hypnophrase("A million voices echo in your head... \"Seems where you got sent won't \
|
||||
be able to handle our pod... as if we wanted the occupant to survive. Brace yourself, corporate dog.\""))
|
||||
flags_1 &= ~PREVENT_CONTENTS_EXPLOSION_1
|
||||
explosionSize = list(0,1,1,1)
|
||||
destination = get_random_station_turf()
|
||||
|
||||
do_sparks(8, FALSE, victim)
|
||||
victim.visible_message(span_notice("[victim] vanishes..."))
|
||||
|
||||
victim.forceMove(src)
|
||||
|
||||
new /obj/effect/pod_landingzone(destination, src)
|
||||
|
||||
SEND_SIGNAL(victim, COMSIG_LIVING_RETURN_FROM_CAPTURE, destination)
|
||||
|
||||
/obj/structure/closet/supplypod/proc/handleReturnAfterDeparting(atom/movable/holder = src)
|
||||
reversing = FALSE //Now that we're done reversing, we set this to false (otherwise we would get stuck in an infinite loop of calling the close proc at the bottom of open_pod() )
|
||||
bluespace = TRUE //Make it so that the pod doesn't stay in centcom forever
|
||||
|
||||
@@ -218,8 +218,8 @@ GLOBAL_LIST_INIT(pride_pin_reskins, list(
|
||||
|
||||
/obj/item/clothing/accessory/anti_sec_pin/attach(obj/item/clothing/under/attach_to, mob/living/attacher)
|
||||
. = ..()
|
||||
if (!.)
|
||||
return FALSE
|
||||
if (!. || isnull(attacher))
|
||||
return
|
||||
|
||||
var/target = ishuman(attach_to.loc) ? attach_to.loc : attach_to
|
||||
log_combat(attacher, target, "pinned an 'arrest me immediately' pin onto", src)
|
||||
|
||||
@@ -2615,6 +2615,26 @@ GLOBAL_LIST_EMPTY(fire_appearances)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_UNFRIENDED, old_friend)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Common proc used to deduct money from cargo, announce the kidnapping and add src to the black market.
|
||||
* Returns the black market item, for extra stuff like signals that need to be registered.
|
||||
*/
|
||||
/mob/living/proc/process_capture(ransom_price, black_market_price)
|
||||
if(ransom_price > 0)
|
||||
var/datum/bank_account/cargo_account = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
|
||||
if(cargo_account) //Just in case
|
||||
cargo_account.adjust_money(-min(ransom_price, cargo_account.account_balance)) //Not so much, especially for competent cargo. Plus this can't be mass-triggered like it has been done with contractors
|
||||
priority_announce("One of your crew was captured by a rival organisation - we've needed to pay their ransom to bring them back. As is policy we've taken a portion of the station's funds to offset the overall cost.", "Nanotrasen Asset Protection", has_important_message = TRUE)
|
||||
|
||||
///The price should be high enough that the contractor can't just buy 'em back with their cut alone.
|
||||
var/datum/market_item/hostage/market_item = new(src, black_market_price || ransom_price)
|
||||
SSblackmarket.markets[/datum/market/blackmarket].add_item(market_item)
|
||||
|
||||
if(mind)
|
||||
ADD_TRAIT(mind, TRAIT_HAS_BEEN_KIDNAPPED, TRAIT_GENERIC)
|
||||
return market_item
|
||||
|
||||
/// Admin only proc for making the mob hallucinate a certain thing
|
||||
/mob/living/proc/admin_give_hallucination(mob/admin)
|
||||
if(!admin || !check_rights(NONE))
|
||||
|
||||
@@ -293,6 +293,7 @@
|
||||
#include "code\__DEFINES\dcs\signals\signals_backpack.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_beam.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_bitrunning.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_blackmarket.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_blob.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_bot.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_camera.dm"
|
||||
@@ -3655,7 +3656,9 @@
|
||||
#include "code\modules\cargo\markets\market_uplink.dm"
|
||||
#include "code\modules\cargo\markets\market_items\clothing.dm"
|
||||
#include "code\modules\cargo\markets\market_items\consumables.dm"
|
||||
#include "code\modules\cargo\markets\market_items\hostages.dm"
|
||||
#include "code\modules\cargo\markets\market_items\misc.dm"
|
||||
#include "code\modules\cargo\markets\market_items\stolen_goods.dm"
|
||||
#include "code\modules\cargo\markets\market_items\tools.dm"
|
||||
#include "code\modules\cargo\markets\market_items\weapons.dm"
|
||||
#include "code\modules\cargo\packs\_packs.dm"
|
||||
|
||||
Reference in New Issue
Block a user