mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 05:30:05 +01:00
Refactors exports and pirate loot gathering. (#39749)
* Pirate export * Stuff * ATTEMPT TWO * Vault area was removed look for control terminal here. * Fixes and improvments * cb stuff
This commit is contained in:
committed by
vuonojenmustaturska
parent
0038c9cafd
commit
bd72eb3371
+500
-554
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
#define EXPORT_CARGO 1
|
||||
#define EXPORT_EMAG 2
|
||||
#define EXPORT_CONTRABAND 4
|
||||
#define EXPORT_PIRATE 8
|
||||
@@ -229,12 +229,14 @@
|
||||
var/answer = text2num(href_list["answer"])
|
||||
if(!currmsg || !answer || currmsg.possible_answers.len < answer)
|
||||
state = STATE_MESSAGELIST
|
||||
currmsg.answered = answer
|
||||
log_game("[key_name(usr)] answered [currmsg.title] comm message. Answer : [currmsg.answered]")
|
||||
if(currmsg)
|
||||
currmsg.answer_callback.Invoke()
|
||||
|
||||
state = STATE_VIEWMESSAGE
|
||||
else
|
||||
if(!currmsg.answered)
|
||||
currmsg.answered = answer
|
||||
log_game("[key_name(usr)] answered [currmsg.title] comm message. Answer : [currmsg.answered]")
|
||||
if(currmsg)
|
||||
currmsg.answer_callback.InvokeAsync()
|
||||
state = STATE_VIEWMESSAGE
|
||||
updateDialog()
|
||||
if("status")
|
||||
state = STATE_STATUSDISPLAY
|
||||
if("securitylevel")
|
||||
@@ -365,11 +367,13 @@
|
||||
var/answer = text2num(href_list["answer"])
|
||||
if(!aicurrmsg || !answer || aicurrmsg.possible_answers.len < answer)
|
||||
aistate = STATE_MESSAGELIST
|
||||
aicurrmsg.answered = answer
|
||||
log_game("[key_name(usr)] answered [aicurrmsg.title] comm message. Answer : [aicurrmsg.answered]")
|
||||
if(aicurrmsg.answer_callback)
|
||||
aicurrmsg.answer_callback.Invoke()
|
||||
aistate = STATE_VIEWMESSAGE
|
||||
else
|
||||
if(!aicurrmsg.answered)
|
||||
aicurrmsg.answered = answer
|
||||
log_game("[key_name(usr)] answered [aicurrmsg.title] comm message. Answer : [aicurrmsg.answered]")
|
||||
if(aicurrmsg.answer_callback)
|
||||
aicurrmsg.answer_callback.InvokeAsync()
|
||||
aistate = STATE_VIEWMESSAGE
|
||||
if("ai-status")
|
||||
aistate = STATE_STATUSDISPLAY
|
||||
if("ai-announce")
|
||||
|
||||
@@ -45,65 +45,43 @@
|
||||
/datum/team/pirate/proc/forge_objectives()
|
||||
var/datum/objective/loot/getbooty = new()
|
||||
getbooty.team = src
|
||||
getbooty.storage_area = locate(/area/shuttle/pirate/vault) in GLOB.sortedAreas
|
||||
getbooty.update_initial_value()
|
||||
for(var/obj/machinery/computer/piratepad_control/P in GLOB.machines)
|
||||
var/area/A = get_area(P)
|
||||
if(istype(A,/area/shuttle/pirate))
|
||||
getbooty.cargo_hold = P
|
||||
break
|
||||
getbooty.update_explanation_text()
|
||||
objectives += getbooty
|
||||
for(var/datum/mind/M in members)
|
||||
M.objectives |= objectives
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(pirate_loot_cache, typecacheof(list(
|
||||
/obj/structure/reagent_dispensers/beerkeg,
|
||||
/mob/living/simple_animal/parrot,
|
||||
/obj/item/stack/sheet/mineral/gold,
|
||||
/obj/item/stack/sheet/mineral/diamond,
|
||||
/obj/item/stack/spacecash,
|
||||
/obj/item/melee/sabre,)))
|
||||
|
||||
/datum/objective/loot
|
||||
var/area/storage_area //Place where we we will look for the loot.
|
||||
var/obj/machinery/computer/piratepad_control/cargo_hold
|
||||
explanation_text = "Acquire valuable loot and store it in designated area."
|
||||
var/target_value = 50000
|
||||
var/initial_value = 0 //Things in the vault at spawn time do not count
|
||||
|
||||
|
||||
/datum/objective/loot/update_explanation_text()
|
||||
if(storage_area)
|
||||
explanation_text = "Acquire loot and store [target_value] of credits worth in [storage_area.name]."
|
||||
if(cargo_hold)
|
||||
var/area/storage_area = get_area(cargo_hold)
|
||||
explanation_text = "Acquire loot and store [target_value] of credits worth in [storage_area.name] cargo hold."
|
||||
|
||||
/datum/objective/loot/proc/loot_listing()
|
||||
//Lists notable loot.
|
||||
if(!storage_area)
|
||||
if(!cargo_hold || !cargo_hold.total_report)
|
||||
return "Nothing"
|
||||
var/list/loot_table = list()
|
||||
for(var/atom/movable/AM in storage_area.GetAllContents())
|
||||
if(is_type_in_typecache(AM,GLOB.pirate_loot_cache))
|
||||
var/lootname = AM.name
|
||||
var/count = 1
|
||||
if(istype(AM,/obj/item/stack)) //Ugh.
|
||||
var/obj/item/stack/S = AM
|
||||
lootname = S.singular_name
|
||||
count = S.amount
|
||||
if(!loot_table[lootname])
|
||||
loot_table[lootname] = count
|
||||
else
|
||||
loot_table[lootname] += count
|
||||
cargo_hold.total_report.total_value = sortTim(cargo_hold.total_report.total_value, cmp = /proc/cmp_numeric_dsc, associative = TRUE)
|
||||
var/count = 0
|
||||
var/list/loot_texts = list()
|
||||
for(var/key in loot_table)
|
||||
var/amount = loot_table[key]
|
||||
loot_texts += "[amount] [key][amount > 1 ? "s":""]"
|
||||
for(var/datum/export/E in cargo_hold.total_report.total_value)
|
||||
if(++count > 5)
|
||||
break
|
||||
loot_texts += E.total_printout(cargo_hold.total_report,notes = FALSE)
|
||||
return loot_texts.Join(", ")
|
||||
|
||||
/datum/objective/loot/proc/get_loot_value()
|
||||
if(!storage_area)
|
||||
return 0
|
||||
var/value = 0
|
||||
for(var/turf/T in storage_area.contents)
|
||||
value += export_item_and_contents(T,TRUE, TRUE, dry_run = TRUE)
|
||||
return value - initial_value
|
||||
|
||||
/datum/objective/loot/proc/update_initial_value()
|
||||
initial_value = get_loot_value()
|
||||
return cargo_hold.points
|
||||
|
||||
/datum/objective/loot/check_completion()
|
||||
return ..() || get_loot_value() >= target_value
|
||||
|
||||
@@ -28,6 +28,13 @@
|
||||
else
|
||||
obj_flags &= ~EMAGGED
|
||||
|
||||
/obj/machinery/computer/cargo/proc/get_export_categories()
|
||||
var/cat = EXPORT_CARGO
|
||||
if(contraband)
|
||||
cat |= EXPORT_CONTRABAND
|
||||
if(obj_flags & EMAGGED)
|
||||
cat |= EXPORT_EMAG
|
||||
|
||||
/obj/machinery/computer/cargo/emag_act(mob/user)
|
||||
if(obj_flags & EMAGGED)
|
||||
return
|
||||
@@ -115,11 +122,7 @@
|
||||
say(blockade_warning)
|
||||
return
|
||||
if(SSshuttle.supply.getDockedId() == "supply_home")
|
||||
if (obj_flags & EMAGGED)
|
||||
SSshuttle.supply.obj_flags |= EMAGGED
|
||||
else
|
||||
SSshuttle.supply.obj_flags = (SSshuttle.supply.obj_flags & ~EMAGGED)
|
||||
SSshuttle.supply.contraband = contraband
|
||||
SSshuttle.supply.export_categories = get_export_categories()
|
||||
SSshuttle.moveShuttle("supply", "supply_away", TRUE)
|
||||
say("The supply shuttle is departing.")
|
||||
investigate_log("[key_name(usr)] sent the supply shuttle away.", INVESTIGATE_CARGO)
|
||||
|
||||
@@ -31,7 +31,12 @@
|
||||
else
|
||||
// Before you fix it:
|
||||
// yes, checking manifests is a part of intended functionality.
|
||||
var/price = export_item_and_contents(O, cargo_console.contraband, (cargo_console.obj_flags & EMAGGED), dry_run=TRUE)
|
||||
|
||||
var/datum/export_report/ex = export_item_and_contents(O, cargo_console.get_export_categories(), dry_run=TRUE)
|
||||
var/price = 0
|
||||
for(var/x in ex.total_amount)
|
||||
price += ex.total_value[x]
|
||||
|
||||
if(price)
|
||||
to_chat(user, "<span class='notice'>Scanned [O], value: <b>[price]</b> credits[O.contents.len ? " (contents included)" : ""].</span>")
|
||||
else
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
/* How it works:
|
||||
The shuttle arrives at CentCom dock and calls sell(), which recursively loops through all the shuttle contents that are unanchored.
|
||||
The loop only checks contents of storage types, see supply.dm shuttle code.
|
||||
|
||||
|
||||
Each object in the loop is checked for applies_to() of various export datums, except the invalid ones.
|
||||
Objects on shutlle floor are checked only against shuttle_floor = TRUE exports.
|
||||
|
||||
If applies_to() returns TRUE, sell_object() is called on object and checks against exports are stopped for this object.
|
||||
sell_object() must add object amount and cost to export's total_cost and total_amount.
|
||||
|
||||
When all the shuttle objects are looped, export cycle is over. The shuttle calls total_printout() for each valid export.
|
||||
If total_printout() returns something, the export datum's total_cost is added to cargo credits, then export_end() is called to reset total_cost and total_amount.
|
||||
*/
|
||||
|
||||
/* The rule in figuring out item export cost:
|
||||
@@ -26,52 +18,57 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
|
||||
|
||||
then the player gets the profit from selling his own wasted time.
|
||||
*/
|
||||
/proc/export_item_and_contents(atom/movable/AM, contraband, emagged, dry_run=FALSE)
|
||||
|
||||
// Simple holder datum to pass export results around
|
||||
/datum/export_report
|
||||
var/list/exported_atoms = list() //names of atoms sold/deleted by export
|
||||
var/list/total_amount = list() //export instance => total count of sold objects of its type, only exists if any were sold
|
||||
var/list/total_value = list() //export instance => total value of sold objects
|
||||
|
||||
// external_report works as "transaction" object, pass same one in if you're doing more than one export in single go
|
||||
/proc/export_item_and_contents(atom/movable/AM, allowed_categories = EXPORT_CARGO, apply_elastic = TRUE, delete_unsold = TRUE, dry_run=FALSE, datum/export_report/external_report)
|
||||
if(!GLOB.exports_list.len)
|
||||
setupExports()
|
||||
|
||||
var/sold_str = ""
|
||||
var/cost = 0
|
||||
|
||||
var/list/contents = AM.GetAllContents()
|
||||
|
||||
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
|
||||
for(var/i in reverseRange(contents))
|
||||
var/atom/movable/thing = i
|
||||
var/sold = FALSE
|
||||
for(var/datum/export/E in GLOB.exports_list)
|
||||
if(!E)
|
||||
continue
|
||||
if(E.applies_to(thing, contraband, emagged))
|
||||
if(dry_run)
|
||||
cost += E.get_cost(thing, contraband, emagged)
|
||||
else
|
||||
E.sell_object(thing, contraband, emagged)
|
||||
sold_str += " [thing.name]"
|
||||
if(E.applies_to(thing, allowed_categories, apply_elastic))
|
||||
sold = E.sell_object(thing, report, dry_run, allowed_categories , apply_elastic)
|
||||
report.exported_atoms += " [thing.name]"
|
||||
break
|
||||
if(!dry_run)
|
||||
if(!dry_run && (sold || delete_unsold))
|
||||
if(ismob(thing))
|
||||
thing.investigate_log("deleted through cargo export",INVESTIGATE_CARGO)
|
||||
qdel(thing)
|
||||
|
||||
if(dry_run)
|
||||
return cost
|
||||
else
|
||||
return sold_str
|
||||
return report
|
||||
|
||||
/datum/export
|
||||
var/unit_name = "" // Unit name. Only used in "Received [total_amount] [name]s [message]." message
|
||||
var/message = ""
|
||||
var/cost = 100 // Cost of item, in cargo credits. Must not alow for infinite price dupes, see above.
|
||||
var/k_elasticity = 1/30 //coefficient used in marginal price calculation that roughly corresponds to the inverse of price elasticity, or "quantity elasticity"
|
||||
var/contraband = FALSE // Export must be unlocked with multitool.
|
||||
var/emagged = FALSE // Export must be unlocked with emag.
|
||||
var/list/export_types = list() // Type of the exported object. If none, the export datum is considered base type.
|
||||
var/include_subtypes = TRUE // Set to FALSE to make the datum apply only to a strict type.
|
||||
var/list/exclude_types = list() // Types excluded from export
|
||||
|
||||
// Used by print-out
|
||||
var/total_cost = 0
|
||||
var/total_amount = 0
|
||||
//cost includes elasticity, this does not.
|
||||
var/init_cost
|
||||
|
||||
//All these need to be present in export call parameter for this to apply.
|
||||
var/export_category = EXPORT_CARGO
|
||||
|
||||
/datum/export/New()
|
||||
..()
|
||||
SSprocessing.processing += src
|
||||
@@ -79,7 +76,6 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
|
||||
export_types = typecacheof(export_types)
|
||||
exclude_types = typecacheof(exclude_types)
|
||||
|
||||
|
||||
/datum/export/Destroy()
|
||||
SSprocessing.processing -= src
|
||||
return ..()
|
||||
@@ -91,29 +87,30 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
|
||||
cost = init_cost
|
||||
|
||||
// Checks the cost. 0 cost items are skipped in export.
|
||||
/datum/export/proc/get_cost(obj/O, contr = 0, emag = 0)
|
||||
var/amount = get_amount(O, contr, emag)
|
||||
if(k_elasticity!=0)
|
||||
return round((cost/k_elasticity) * (1 - NUM_E**(-1 * k_elasticity * amount))) //anti-derivative of the marginal cost function
|
||||
/datum/export/proc/get_cost(obj/O, allowed_categories = NONE, apply_elastic = TRUE)
|
||||
var/amount = get_amount(O)
|
||||
if(apply_elastic)
|
||||
if(k_elasticity!=0)
|
||||
return round((cost/k_elasticity) * (1 - NUM_E**(-1 * k_elasticity * amount))) //anti-derivative of the marginal cost function
|
||||
else
|
||||
return round(cost * amount) //alternative form derived from L'Hopital to avoid division by 0
|
||||
else
|
||||
return round(cost * amount) //alternative form derived from L'Hopital to avoid division by 0
|
||||
return round(init_cost * amount)
|
||||
|
||||
// Checks the amount of exportable in object. Credits in the bill, sheets in the stack, etc.
|
||||
// Usually acts as a multiplier for a cost, so item that has 0 amount will be skipped in export.
|
||||
/datum/export/proc/get_amount(obj/O, contr = 0, emag = 0)
|
||||
/datum/export/proc/get_amount(obj/O)
|
||||
return 1
|
||||
|
||||
// Checks if the item is fit for export datum.
|
||||
/datum/export/proc/applies_to(obj/O, contr = 0, emag = 0)
|
||||
if(contraband && !contr)
|
||||
return FALSE
|
||||
if(emagged && !emag)
|
||||
/datum/export/proc/applies_to(obj/O, allowed_categories = NONE, apply_elastic = TRUE)
|
||||
if((allowed_categories & export_category) != export_category)
|
||||
return FALSE
|
||||
if(!include_subtypes && !(O.type in export_types))
|
||||
return FALSE
|
||||
if(include_subtypes && (!is_type_in_typecache(O, export_types) || is_type_in_typecache(O, exclude_types)))
|
||||
return FALSE
|
||||
if(!get_cost(O, contr, emag))
|
||||
if(!get_cost(O, allowed_categories , apply_elastic))
|
||||
return FALSE
|
||||
if(O.flags_1 & HOLOGRAM_1)
|
||||
return FALSE
|
||||
@@ -122,26 +119,38 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
|
||||
// Called only once, when the object is actually sold by the datum.
|
||||
// Adds item's cost and amount to the current export cycle.
|
||||
// get_cost, get_amount and applies_to do not neccesary mean a successful sale.
|
||||
/datum/export/proc/sell_object(obj/O, contr = 0, emag = 0)
|
||||
var/the_cost = get_cost(O)
|
||||
/datum/export/proc/sell_object(obj/O, datum/export_report/report, dry_run = TRUE, allowed_categories = EXPORT_CARGO , apply_elastic = TRUE)
|
||||
var/the_cost = get_cost(O, allowed_categories , apply_elastic)
|
||||
var/amount = get_amount(O)
|
||||
total_cost += the_cost
|
||||
if(istype(O, /datum/export/material))
|
||||
total_amount += amount*MINERAL_MATERIAL_AMOUNT
|
||||
else
|
||||
total_amount += amount
|
||||
|
||||
cost *= NUM_E**(-1*k_elasticity*amount) //marginal cost modifier
|
||||
SSblackbox.record_feedback("nested tally", "export_sold_cost", 1, list("[O.type]", "[the_cost]"))
|
||||
if(amount <=0 || the_cost <=0)
|
||||
return FALSE
|
||||
|
||||
report.total_value[src] += the_cost
|
||||
|
||||
if(istype(O, /datum/export/material))
|
||||
report.total_amount[src] += amount*MINERAL_MATERIAL_AMOUNT
|
||||
else
|
||||
report.total_amount[src] += amount
|
||||
|
||||
if(!dry_run)
|
||||
if(apply_elastic)
|
||||
cost *= NUM_E**(-1*k_elasticity*amount) //marginal cost modifier
|
||||
SSblackbox.record_feedback("nested tally", "export_sold_cost", 1, list("[O.type]", "[the_cost]"))
|
||||
return TRUE
|
||||
|
||||
// Total printout for the cargo console.
|
||||
// Called before the end of current export cycle.
|
||||
// It must always return something if the datum adds or removes any credts.
|
||||
/datum/export/proc/total_printout(contr = 0, emag = 0)
|
||||
if(!total_cost && !total_amount)
|
||||
/datum/export/proc/total_printout(datum/export_report/ex, notes = TRUE)
|
||||
if(!ex.total_amount[src] || !ex.total_value[src])
|
||||
return ""
|
||||
var/msg = "[total_cost] credits: Received [total_amount] "
|
||||
if(total_cost > 0)
|
||||
|
||||
var/total_value = ex.total_value[src]
|
||||
var/total_amount = ex.total_amount[src]
|
||||
|
||||
var/msg = "[total_value] credits: Received [total_amount] "
|
||||
if(total_value > 0)
|
||||
msg = "+" + msg
|
||||
|
||||
if(unit_name)
|
||||
@@ -157,11 +166,6 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
|
||||
msg += "."
|
||||
return msg
|
||||
|
||||
// The current export cycle is over now. Reset all the export temporary vars.
|
||||
/datum/export/proc/export_end()
|
||||
total_cost = 0
|
||||
total_amount = 0
|
||||
|
||||
GLOBAL_LIST_EMPTY(exports_list)
|
||||
|
||||
/proc/setupExports()
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
export_types = list(/obj/structure/closet/crate)
|
||||
exclude_types = list(/obj/structure/closet/crate/large, /obj/structure/closet/crate/wooden)
|
||||
|
||||
/datum/export/large/crate/total_printout() // That's why a goddamn metal crate costs that much.
|
||||
/datum/export/large/crate/total_printout(datum/export_report/ex, notes = TRUE) // That's why a goddamn metal crate costs that much.
|
||||
. = ..()
|
||||
if(.)
|
||||
if(. && notes)
|
||||
. += " Thanks for participating in Nanotrasen Crates Recycling Program."
|
||||
|
||||
/datum/export/large/crate/wooden
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
return ..() * S.rarity // That's right, no bonus for potency. Send a crappy sample first to "show improvement" later.
|
||||
|
||||
/datum/export/seed/sell_object(obj/O)
|
||||
..()
|
||||
var/obj/item/seeds/S = O
|
||||
discoveredPlants[S.type] = S.potency
|
||||
. = ..()
|
||||
if(.)
|
||||
var/obj/item/seeds/S = O
|
||||
discoveredPlants[S.type] = S.potency
|
||||
|
||||
|
||||
/datum/export/seed/potency
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
/datum/export/stack/skin/human
|
||||
cost = 100
|
||||
contraband = TRUE
|
||||
export_category = EXPORT_CONTRABAND
|
||||
unit_name = "piece"
|
||||
message = "of human skin"
|
||||
export_types = list(/obj/item/stack/sheet/animalhide/human)
|
||||
@@ -28,13 +28,13 @@
|
||||
|
||||
/datum/export/stack/skin/cat
|
||||
cost = 150
|
||||
contraband = TRUE
|
||||
export_category = EXPORT_CONTRABAND
|
||||
unit_name = "cat hide"
|
||||
export_types = list(/obj/item/stack/sheet/animalhide/cat)
|
||||
|
||||
/datum/export/stack/skin/corgi
|
||||
cost = 200
|
||||
contraband = TRUE
|
||||
export_category = EXPORT_CONTRABAND
|
||||
unit_name = "corgi hide"
|
||||
export_types = list(/obj/item/stack/sheet/animalhide/corgi)
|
||||
|
||||
|
||||
@@ -117,16 +117,16 @@
|
||||
export_types = list(/obj/singularity)
|
||||
include_subtypes = FALSE
|
||||
|
||||
/datum/export/singulo/total_printout()
|
||||
/datum/export/singulo/total_printout(datum/export_report/ex, notes = TRUE)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(. && notes)
|
||||
. += " ERROR: Invalid object detected."
|
||||
|
||||
/datum/export/singulo/tesla //see above
|
||||
unit_name = "energy ball"
|
||||
export_types = list(/obj/singularity/energy_ball)
|
||||
|
||||
/datum/export/singulo/tesla/total_printout()
|
||||
/datum/export/singulo/tesla/total_printout(datum/export_report/ex, notes = TRUE)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(. && notes)
|
||||
. += " ERROR: Unscheduled energy ball delivery detected."
|
||||
|
||||
+220
-32
@@ -1,5 +1,3 @@
|
||||
#define LOOT_LOCATOR_COOLDOWN 150
|
||||
|
||||
/datum/round_event_control/pirates
|
||||
name = "Space Pirates"
|
||||
typepath = /datum/round_event/pirates
|
||||
@@ -26,10 +24,9 @@
|
||||
/datum/round_event/pirates/setup()
|
||||
ship_name = pick(strings(PIRATE_NAMES_FILE, "ship_names"))
|
||||
|
||||
/datum/round_event/pirates/announce()
|
||||
/datum/round_event/pirates/announce(fake)
|
||||
priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", 'sound/ai/commandreport.ogg')
|
||||
|
||||
if(!control) //Means this is false alarm, todo : explicit checks instead of using announceWhen
|
||||
if(fake)
|
||||
return
|
||||
threat = new
|
||||
payoff = round(SSshuttle.points * 0.80)
|
||||
@@ -227,43 +224,234 @@
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/oxygen
|
||||
|
||||
|
||||
/obj/machinery/loot_locator
|
||||
name = "Booty Locator"
|
||||
desc = "This sophisticated machine scans the nearby space for items of value."
|
||||
icon = 'icons/obj/machines/research.dmi'
|
||||
icon_state = "tdoppler"
|
||||
density = TRUE
|
||||
var/cooldown = 0
|
||||
var/result_count = 3 //Show X results.
|
||||
|
||||
/obj/machinery/proc/display_current_value()
|
||||
var/area/current = get_area(src)
|
||||
var/value = 0
|
||||
for(var/turf/T in current.contents)
|
||||
value += export_item_and_contents(T,TRUE, TRUE, dry_run = TRUE)
|
||||
say("Current vault value : [value] credits.")
|
||||
var/cooldown = 300
|
||||
var/next_use = 0
|
||||
|
||||
/obj/machinery/loot_locator/interact(mob/user)
|
||||
if(world.time <= cooldown)
|
||||
if(world.time <= next_use)
|
||||
to_chat(user,"<span class='warning'>[src] is recharging.</span>")
|
||||
return
|
||||
cooldown = world.time + LOOT_LOCATOR_COOLDOWN
|
||||
display_current_value()
|
||||
var/list/results = list()
|
||||
for(var/atom/movable/AM in world)
|
||||
if(is_type_in_typecache(AM,GLOB.pirate_loot_cache))
|
||||
if(is_station_level(AM.z))
|
||||
if(get_area(AM) == get_area(src)) //Should this be variable ?
|
||||
continue
|
||||
results += AM
|
||||
CHECK_TICK
|
||||
if(!results.len)
|
||||
next_use = world.time + cooldown
|
||||
var/atom/movable/AM = find_random_loot()
|
||||
if(!AM)
|
||||
say("No valuables located. Try again later.")
|
||||
else
|
||||
for(var/i in 1 to result_count)
|
||||
if(!results.len)
|
||||
return
|
||||
var/atom/movable/AM = pick_n_take(results)
|
||||
say("Located: [AM.name] at [get_area_name(AM)]")
|
||||
say("Located: [AM.name] at [get_area_name(AM)]")
|
||||
|
||||
#undef LOOT_LOCATOR_COOLDOWN
|
||||
/obj/machinery/loot_locator/proc/find_random_loot()
|
||||
if(!GLOB.exports_list.len)
|
||||
setupExports()
|
||||
var/list/possible_loot = list()
|
||||
for(var/datum/export/pirate/E in GLOB.exports_list)
|
||||
possible_loot += E
|
||||
var/datum/export/pirate/P
|
||||
var/atom/movable/AM
|
||||
while(!AM && possible_loot.len)
|
||||
P = pick_n_take(possible_loot)
|
||||
AM = P.find_loot()
|
||||
return AM
|
||||
|
||||
//Pad & Pad Terminal
|
||||
/obj/machinery/piratepad
|
||||
name = "cargo hold pad"
|
||||
icon = 'icons/obj/telescience.dmi'
|
||||
icon_state = "lpad-idle-o"
|
||||
var/idle_state = "lpad-idle-o"
|
||||
var/warmup_state = "lpad-idle"
|
||||
var/sending_state = "lpad-beam"
|
||||
var/cargo_hold_id
|
||||
|
||||
/obj/machinery/piratepad/multitool_act(mob/living/user, obj/item/multitool/I)
|
||||
if (istype(I))
|
||||
to_chat(user, "<span class='notice'>You register [src] in [I]s buffer.</span>")
|
||||
I.buffer = src
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/piratepad_control
|
||||
name = "cargo hold control terminal"
|
||||
var/status_report = "Idle"
|
||||
var/obj/machinery/piratepad/pad
|
||||
var/warmup_time = 100
|
||||
var/sending = FALSE
|
||||
var/points = 0
|
||||
var/datum/export_report/total_report
|
||||
var/sending_timer
|
||||
var/cargo_hold_id
|
||||
|
||||
/obj/machinery/computer/piratepad_control/Initialize()
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/machinery/computer/piratepad_control/multitool_act(mob/living/user, obj/item/multitool/I)
|
||||
if (istype(I) && istype(I.buffer,/obj/machinery/piratepad))
|
||||
to_chat(user, "<span class='notice'>You link [src] with [I.buffer] in [I] buffer.</span>")
|
||||
pad = I.buffer
|
||||
updateDialog()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/piratepad_control/LateInitialize()
|
||||
. = ..()
|
||||
if(cargo_hold_id)
|
||||
for(var/obj/machinery/piratepad/P in GLOB.machines)
|
||||
if(P.cargo_hold_id == cargo_hold_id)
|
||||
pad = P
|
||||
return
|
||||
else
|
||||
pad = locate() in range(4,src)
|
||||
|
||||
/obj/machinery/computer/piratepad_control/ui_interact(mob/user)
|
||||
. = ..()
|
||||
var/list/t = list()
|
||||
t += "<div class='statusDisplay'>Cargo Hold Control<br>"
|
||||
t += "Current cargo value : [points]"
|
||||
t += "</div>"
|
||||
if(!pad)
|
||||
t += "<div class='statusDisplay'>No pad located.</div><BR>"
|
||||
else
|
||||
t += "<br>[status_report]<br>"
|
||||
if(!sending)
|
||||
t += "<a href='?src=[REF(src)];recalc=1;'>Recalculate Value</a><a href='?src=[REF(src)];send=1'>Send</a>"
|
||||
else
|
||||
t += "<a href='?src=[REF(src)];stop=1'>Stop sending</a>"
|
||||
|
||||
var/datum/browser/popup = new(user, "piratepad", name, 300, 500)
|
||||
popup.set_content(t.Join())
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/computer/piratepad_control/proc/recalc()
|
||||
if(sending)
|
||||
return
|
||||
status_report = "Predicted value:<br>"
|
||||
var/datum/export_report/ex = new
|
||||
for(var/atom/movable/AM in get_turf(pad))
|
||||
if(AM == pad)
|
||||
continue
|
||||
export_item_and_contents(AM, EXPORT_PIRATE | EXPORT_CARGO | EXPORT_CONTRABAND | EXPORT_EMAG, apply_elastic = FALSE, dry_run = TRUE, external_report = ex)
|
||||
|
||||
for(var/datum/export/E in ex.total_amount)
|
||||
status_report += E.total_printout(ex,notes = FALSE) + "<br>"
|
||||
|
||||
/obj/machinery/computer/piratepad_control/proc/send()
|
||||
if(!sending)
|
||||
return
|
||||
|
||||
var/datum/export_report/ex = new
|
||||
|
||||
for(var/atom/movable/AM in get_turf(pad))
|
||||
if(AM == pad)
|
||||
continue
|
||||
export_item_and_contents(AM, EXPORT_PIRATE | EXPORT_CARGO | EXPORT_CONTRABAND | EXPORT_EMAG, apply_elastic = FALSE, delete_unsold = FALSE, external_report = ex)
|
||||
|
||||
status_report = "Sold:<br>"
|
||||
var/value = 0
|
||||
for(var/datum/export/E in ex.total_amount)
|
||||
var/export_text = E.total_printout(ex,notes = FALSE) //Don't want nanotrasen messages, makes no sense here.
|
||||
if(!export_text)
|
||||
continue
|
||||
|
||||
status_report += export_text + "<br>"
|
||||
value += ex.total_value[E]
|
||||
|
||||
if(!total_report)
|
||||
total_report = ex
|
||||
else
|
||||
total_report.exported_atoms += ex.exported_atoms
|
||||
for(var/datum/export/E in ex.total_amount)
|
||||
total_report.total_amount[E] += ex.total_amount[E]
|
||||
total_report.total_value[E] += ex.total_value[E]
|
||||
|
||||
points += value
|
||||
|
||||
pad.visible_message("<span class='notice'>[pad] activates!</span>")
|
||||
flick(pad.sending_state,pad)
|
||||
pad.icon_state = pad.idle_state
|
||||
sending = FALSE
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/computer/piratepad_control/proc/start_sending()
|
||||
if(sending)
|
||||
return
|
||||
sending = TRUE
|
||||
status_report = "Sending..."
|
||||
pad.visible_message("<span class='notice'>[pad] starts charging up.</span>")
|
||||
pad.icon_state = pad.warmup_state
|
||||
sending_timer = addtimer(CALLBACK(src,.proc/send),warmup_time, TIMER_STOPPABLE)
|
||||
|
||||
/obj/machinery/computer/piratepad_control/proc/stop_sending()
|
||||
if(!sending)
|
||||
return
|
||||
sending = FALSE
|
||||
status_report = "Idle"
|
||||
pad.icon_state = pad.idle_state
|
||||
deltimer(sending_timer)
|
||||
|
||||
/obj/machinery/computer/piratepad_control/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
if(pad)
|
||||
if(href_list["recalc"])
|
||||
recalc()
|
||||
if(href_list["send"])
|
||||
start_sending()
|
||||
if(href_list["stop"])
|
||||
stop_sending()
|
||||
updateDialog()
|
||||
else
|
||||
updateDialog()
|
||||
|
||||
/datum/export/pirate
|
||||
export_category = EXPORT_PIRATE
|
||||
|
||||
//Attempts to find the thing on station
|
||||
/datum/export/pirate/proc/find_loot()
|
||||
return
|
||||
|
||||
/datum/export/pirate/ransom
|
||||
cost = 3000
|
||||
unit_name = "hostage"
|
||||
export_types = list(/mob/living/carbon/human)
|
||||
|
||||
/datum/export/pirate/ransom/find_loot()
|
||||
var/list/head_minds = SSjob.get_living_heads()
|
||||
var/list/head_mobs = list()
|
||||
for(var/datum/mind/M in head_minds)
|
||||
head_mobs += M.current
|
||||
if(head_mobs.len)
|
||||
return pick(head_mobs)
|
||||
|
||||
/datum/export/pirate/ransom/get_cost(atom/movable/AM)
|
||||
var/mob/living/carbon/human/H = AM
|
||||
if(H.stat != CONSCIOUS || !H.mind || !H.mind.assigned_role) //mint condition only
|
||||
return 0
|
||||
else
|
||||
if(H.mind.assigned_role in GLOB.command_positions)
|
||||
return 3000
|
||||
else
|
||||
return 1000
|
||||
|
||||
/datum/export/pirate/parrot
|
||||
cost = 2000
|
||||
unit_name = "alive parrot"
|
||||
export_types = list(/mob/living/simple_animal/parrot)
|
||||
|
||||
/datum/export/pirate/parrot/find_loot()
|
||||
for(var/mob/living/simple_animal/parrot/P in GLOB.alive_mob_list)
|
||||
var/turf/T = get_turf(P)
|
||||
if(T && is_station_level(T.z))
|
||||
return P
|
||||
|
||||
/datum/export/pirate/cash
|
||||
cost = 1
|
||||
unit_name = "bills"
|
||||
export_types = list(/obj/item/stack/spacecash)
|
||||
|
||||
/datum/export/pirate/cash/get_amount(obj/O)
|
||||
var/obj/item/stack/spacecash/C = O
|
||||
return ..() * C.amount * C.value
|
||||
@@ -38,9 +38,9 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
|
||||
height = 7
|
||||
movement_force = list("KNOCKDOWN" = 0, "THROW" = 0)
|
||||
|
||||
// When TRUE, these vars allow exporting emagged/contraband items, and add some special interactions to existing exports.
|
||||
var/contraband = FALSE
|
||||
var/emagged = FALSE
|
||||
|
||||
//Export categories for this run, this is set by console sending the shuttle.
|
||||
var/export_categories = EXPORT_CARGO
|
||||
|
||||
/obj/docking_port/mobile/supply/register()
|
||||
. = ..()
|
||||
@@ -117,7 +117,8 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
|
||||
|
||||
var/msg = ""
|
||||
var/matched_bounty = FALSE
|
||||
var/sold_atoms = ""
|
||||
|
||||
var/datum/export_report/ex = new
|
||||
|
||||
for(var/place in shuttle_areas)
|
||||
var/area/shuttle/shuttle_area = place
|
||||
@@ -127,23 +128,21 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
|
||||
if(bounty_ship_item_and_contents(AM, dry_run = FALSE))
|
||||
matched_bounty = TRUE
|
||||
if(!AM.anchored || istype(AM, /obj/mecha))
|
||||
sold_atoms += export_item_and_contents(AM, contraband, emagged, dry_run = FALSE)
|
||||
export_item_and_contents(AM, export_categories , dry_run = FALSE, external_report = ex)
|
||||
|
||||
if(sold_atoms)
|
||||
sold_atoms += "."
|
||||
if(ex.exported_atoms)
|
||||
ex.exported_atoms += "." //ugh
|
||||
|
||||
if(matched_bounty)
|
||||
msg += "Bounty items received. An update has been sent to all bounty consoles. "
|
||||
|
||||
for(var/a in GLOB.exports_list)
|
||||
var/datum/export/E = a
|
||||
var/export_text = E.total_printout()
|
||||
for(var/datum/export/E in ex.total_amount)
|
||||
var/export_text = E.total_printout(ex)
|
||||
if(!export_text)
|
||||
continue
|
||||
|
||||
msg += export_text + "\n"
|
||||
SSshuttle.points += E.total_cost
|
||||
E.export_end()
|
||||
SSshuttle.points += ex.total_value[E]
|
||||
|
||||
SSshuttle.centcom_message = msg
|
||||
investigate_log("Shuttle contents sold for [SSshuttle.points - presale_points] credits. Contents: [sold_atoms || "none."] Message: [SSshuttle.centcom_message || "none."]", INVESTIGATE_CARGO)
|
||||
investigate_log("Shuttle contents sold for [SSshuttle.points - presale_points] credits. Contents: [ex.exported_atoms || "none."] Message: [SSshuttle.centcom_message || "none."]", INVESTIGATE_CARGO)
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "code\__DEFINES\diseases.dm"
|
||||
#include "code\__DEFINES\DNA.dm"
|
||||
#include "code\__DEFINES\events.dm"
|
||||
#include "code\__DEFINES\exports.dm"
|
||||
#include "code\__DEFINES\flags.dm"
|
||||
#include "code\__DEFINES\food.dm"
|
||||
#include "code\__DEFINES\forensics.dm"
|
||||
|
||||
Reference in New Issue
Block a user