mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 20:48:56 +01:00
Revises and adds several new bounties for assistants, roboticists, and medical doctors. (#89772)
## About The Pull Request This pull request makes several balance adjustments to older bounties, primarily for the roboticist and assistant. Additionally, this adds a new type of medical doctor bounty as well. ### Bounty Modifications: **Assistant**: Toolbox bounty The toolbox bounty now requests 1 toolbox instead of 6. However, the toolbox bounty now requires a fully packed mechanical toolbox worth of contents. That means any toolbox, containing a screwdriver, wrench, welding tool, crowbar, analyzer, and wire cutters. When shipped, non-toolbox contents are dropped. Why It's Good For The Game (**WIGFTG**): This bounty follows bad design principles, being a bounty that can be solved entirely from a lathe. For any of these cases, we want to either replace them or recontexualize them into an activity that forces players to either learn more about the mechanics in and around that area as a form of played tutorial, give them a toe-dip into the mechanics required to complete the activity, or perform an activity that makes the station better for having completed it. For the toolbox bounty, this goes all in on teaching players about the full set of toolbox equipment, instead of just needing one printable item, it takes them through the full autolathe menu and gives them plausible deniability for getting a full set of tools. **Assistant:** Potted Plants. The potted plant bounty now requires 3 potted plants as opposed to 8. Most stations are going to be completely devoid of potted plants after collecting 8 of these, where lowering the quantity to 3 allows for a larger amount of competition for this type of bounty. This also disallows using plastic potted plants from being used in the bounty as a trade off, as real potted plants are available through other means. **WIGFTG**: Removes a lathe-solved bounty, and adjusts the quantity to compensate for the fact that previously you would loot the entire station of all of it's potted plants in order to complete this bounty one time. **Assistant:** Action Figures -> Toys Action figures and their general availability widely varies by maps. At best, you can snag one per office on (I think) delta, and at worse you'll need to fish them out of arcade machines across the station. Considering how often new toys are added to the vending machine, this can be a very raw deal where you might be spending 10s of minutes just for maybe one or two action figures. Instead, it feels like a wider and better solution is to just make this touch the whole toys category. WIGFTG: For the toys bounty, it's far too scarce to complete regularly, but instead now it gives makes players interact with the arcade machine wholistically, which in turn requires players to have to play an arcade machine just enough that they're likely to gains a level in the gamer skill, and serve as a primer to interact with how skills interact with the round at large. Granted, it's the gamer skill, so it's not the end of the world if players are getting skill increases here as opposed to other skills that may have more of an effect on the round at large. **Assistant:** Pens. Fuck this bounty. I have removed it. **WIGFTG**: Allow me to elaborate. So the pens bounty requires 10 pens. However, it requires specifically `/obj/item/pen`, no subtypes. `/obj/item/pen` is not printable. It is not found at quantities that make it easy to specifically complete. You cannot use red pens. Or fountain pens. Or blue pens. Or Crayons. Just standard black pens that spawn in your PDA and on paper bins. And you need 10. There is **A** printable pen, however, `/obj/item/pen/red/security`, which is however printable from autolathes, leading many players and myself to think that this is another easy printable bounty. But EVEN THEN, even if those pens WERE ACCEPTABLE, having to manually carry 10 tiny objects to complete a bounty worth not even 200 credits to the bounty holder? This just sucks. It's Bleem. Get it outta here. **Robotics**: All current mech bounties (MK 2 Ripley, Clarke, Odysseus, Gygax, and Durand) Robotics bounties have been reworked. Now, mecha bounties require that a new mecha of that type be built, and that a holodiagnostic scan be completed of the mech. This can be done once-per mech, which will print out a holodiagnostic sheet onto the floor. This sheet is what is turned in for the bounty. As a result, the value of these bounties have been roughly halved. For those looking to collect the rest of the previous value, all 5 of these mechs can now be sold on the cargo shuttle for the remaining value of the old bounties. **WIGFTG**: The biggest hurdle for roboticists when it comes to economy is twofold: Roboticist need resources far more than most other jobs in the game. No metal means no cyborgs, or mechs, or cool equipment for robotics. But, if a roboticist needs credits, they have to trade away a new mech in exchange for some of the largest credit pool bounties in the game. If they can't spend those credits, or can't receive anything using those credits, that's effort wasted. There's a tremendous amount of uncertainty when it comes to robotics being able to meaningfully interact with the credit economy as it currently stands, or being able to leverage the credit economy to solve any of their issues. If the player really does just want to sell their mech for credits, this also provides them with a method of doing so that will still reward them even further if they feel they truly do not need it. Side note, the cargo loader mech "old bess" has the trait provided by generating a diagnostic already, preventing them from just scanning that for an easy minute 1 bounty. Ultimately, having to sell a mech for credits as opposed to getting to use it is not *fun*. Getting to get paid for doing your job, and getting the benefits of something you'll have spend a reasonable amount of time and the station's resources on is *fun*. It's a better pay off. It's why we're here.  **Medical:** Crew Scan Bounties. Medical staff are now given the chance to perform routine medical scan bounties. These require a medical doctor to scan another crew member who is above 90% health, and then print the reports to submit. Some stipulations: * The report cannot be of the bounty holder. * A scanned crewmate must be scanned above 90% heath. * When the report is printed, the target is given a trait for 5 minutes, `TRAIT_RECENTLY_TREATED`, which disqualifies them being the target of a submitted medical report. This is to encourage the doctor to check up on several members of the crew when submitting this bounty. **WIGFTG**: Medical bounties are in an awkward place, honestly. They are possible to become purely printable bounties using either advanced organs, or through the organ grower. However, both of these outcomes are research locked, and will require a more through look down the line, don't get me wrong. In the meantime, this falls squarely under that area of "getting medical doctor bounties to be more closely aligned with doing what they're already supposed to be doing". I also floated the idea of making medical bounties pick a random crewmate for a check-up as opposed to a few different members of the crew from anyone. I might follow up on that at a later date, but this PR was already getting a bit overloaded.  ### Some other things tacked on here: I swear I'll be fast. The `/obj/item/paper/medical_report` created is a new subtype of paper as opposed to the old type that was used by health analyzers, which holds the last scanned mob as a weakref as opposed to just creating a snowflaked paper as we were doing before. The bounty pad, when it generates it's list of bounties, now works slightly differently so that there's no chance of getting a list of three "random" bounties that are all exactly the same thing, called in a new proc, `generate_bounty_list()`. I've added a new debug item, called the `/obj/item/bounty_voucher`. This item allows you to use it in-hand and it gives the activating player a new bounty from a list of all possible bounties. This makes my life, just specifically just me and nobody else, easier when testing bounties. As mentioned above, the mecha UI required adding a new button to it in order to create holoscans. It's fairly innocuous if I do say so myself, but I can make further tweaks if it's an issue. ## Why It's Good For The Game I've sprinkled a good bit of this in above, but in general, bounties needed some more TLC to make sure they align with their place as a tertiary source of making money in the game. I've talked about this before in some now-ancient design documents, but in summary, there's three forms of credit sources in the game: * Primary sources: This is regular payroll, earned by playing the game when the economy SS fires. In theory, this is how much money you can spend without needing to think about making a purchase most of the time. * Secondary sources: This is from sources like tourist bots. Ignore the design decisions they inhabit, they're gameplay loops that allow you to make additional credits while still performing the functions of your job for the station, which in tourist bot's case, is making food and drinks and serving people, making up for any costs incurred by their presence. * Tertiary sources: This is bounties. These are activities that exist as a fallback from the secondary sources, where you may not be performing the duties of your job in order to get credits, should they be more critical as a resource than the service you provide to the station as a result. ...Everyone has been fairly clear that doing bounties is not very good. If you're playing medical doctor and want a shiny medical doctor thing, you would hope that the majority of your time is spent still playing medical doctor, or scientist, or whatever. However, of all the jobs that have fairly sub-par bounties, the one job that I've heard time and again that I actually got *right* was surprisingly, security officer. Their sets of bounties, (Which aren't just looting the locker room mind you...) between the contraband bounty and the n-spect scanner bounties, actually encourages players to basically do tasks that are already part of their job obligations, without needing to run to the nearest lathe or to _steal 8 boar tusks that drop from the barrens_. The bounties are basically, "Go on patrol to this area", "look for suspicious items on the station", etc. In effect, those are *secondary credit sources*. Which is fantastic! It gave me the idea to revisit a few of these job bounties to try and make them a bit less exhausting to have to deal with, and as usual I got a bit distracted and the scope got a bit too big and now it's march. God damnit. But yeah if this goes well, I'd love to see about adjust a few of the bounty methodologies to be in-line with the changes I've implemented here. More bounties that encourage players to be doing what they're already doing, bounties that encourage players to learn more about the game when it comes to assistant bounties or that encourage them to get a toe-dip report on mechanics that they may not be introduced to yet, and get rid of some of the CBT bounties that nobody in their god damn mind wants to do. ## Changelog 🆑 add: New Medical bounty! Scan crewmates who have been healed or currently have a clean bill of health, and ship the medical report to prove that you're not accidently letting them die on your watch. Most of the time. balance: Assistant bounties for toolboxes now only require 1, but the toolbox must be fully stocked like standard mechanical toolboxes. balance: Potted plant bounties no longer accept plastic plants. They only require 3 plants now, however. balance: The action figure bounty now only requires toys instead. del: Removed the pens bounty. balance: The robotics mech bounty now requires a diagnostic scan of a newly completed mech as opposed to sending the whole mech itself. Diagnostic scans can now be generated by riding in a mech and completing the action from the UI menu. Mech bounties are worth about half as much. add: Mechs can be sold on the cargo shuttle for the remaining half of the value from previous mech bounties. fix: You can now no longer roll duplicates of the same bounties when generating a new bounty from the civilian bounty console. /🆑 --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
This commit is contained in:
@@ -25,3 +25,9 @@
|
||||
MENTAL_UNSTABLE, \
|
||||
MENTAL_INSANE, \
|
||||
)
|
||||
|
||||
/// The percentage amount of health required for a mob to be considered to be
|
||||
#define CLEAN_BILL_OF_HEALTH_RATIO 0.9
|
||||
|
||||
///Cooldown for being on the recently treated trait for the purposes for bounty submission
|
||||
#define RECENTLY_HEALED_COOLDOWN 5 MINUTES
|
||||
|
||||
@@ -212,6 +212,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_ANTIMAGIC_NO_SELFBLOCK "anti_magic_no_selfblock"
|
||||
/// This mob recently blocked magic with some form of antimagic
|
||||
#define TRAIT_RECENTLY_BLOCKED_MAGIC "recently_blocked_magic"
|
||||
/// This mob was recently treated and scanned by a medical scanner.
|
||||
#define TRAIT_RECENTLY_TREATED "recently_treated"
|
||||
/// The user can do things like use magic staffs without penalty
|
||||
#define TRAIT_MAGICALLY_GIFTED "magically_gifted"
|
||||
/// This object innately spawns with fantasy variables already applied (the magical component is given to it on initialize), and thus we never want to give it the component again.
|
||||
@@ -1029,6 +1031,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
///A trait for mechs that were created through the normal construction process, and not spawned by map or other effects.
|
||||
#define TRAIT_MECHA_CREATED_NORMALLY "trait_mecha_created_normally"
|
||||
|
||||
/// Trait to apply to mechs after a diagnostic scan has been created, to prevent you from generating duplicates of a scan on the same machine.
|
||||
#define TRAIT_MECHA_DIAGNOSTIC_CREATED "trait_mecha_diagnostic_created"
|
||||
|
||||
/// Stops a movable from being removed from the mob it's in by the content_barfer component.
|
||||
#define TRAIT_NOT_BARFABLE "not_barfable"
|
||||
|
||||
|
||||
@@ -461,6 +461,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_RDS_SUPPRESSED" = TRAIT_RDS_SUPPRESSED,
|
||||
"TRAIT_REAGENT_SCANNER" = TRAIT_REAGENT_SCANNER,
|
||||
"TRAIT_RECENTLY_BLOCKED_MAGIC" = TRAIT_RECENTLY_BLOCKED_MAGIC,
|
||||
"TRAIT_RECENTLY_TREATED" = TRAIT_RECENTLY_TREATED,
|
||||
"TRAIT_REGEN_SHIELD" = TRAIT_REGEN_SHIELD,
|
||||
"TRAIT_RELAYING_ATTACKER" = TRAIT_RELAYING_ATTACKER,
|
||||
"TRAIT_REMOTE_TASTING" = TRAIT_REMOTE_TASTING,
|
||||
@@ -739,7 +740,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_OREBOX_FUNCTIONAL" = TRAIT_OREBOX_FUNCTIONAL,
|
||||
),
|
||||
/obj/vehicle/sealed/mecha = list(
|
||||
"TRAIT_MECHA_CREATED_NORMALLY" = TRAIT_MECHA_CREATED_NORMALLY
|
||||
"TRAIT_MECHA_CREATED_NORMALLY" = TRAIT_MECHA_CREATED_NORMALLY,
|
||||
"TRAIT_MECHA_DIAGNOSTIC_CREATED" = TRAIT_MECHA_DIAGNOSTIC_CREATED,
|
||||
),
|
||||
/turf = list(
|
||||
"TRAIT_CHASM_STOPPED" = TRAIT_CHASM_STOPPED,
|
||||
|
||||
@@ -160,12 +160,33 @@
|
||||
if(!id_account.account_job)
|
||||
say("Requesting ID card has no job assignment registered!")
|
||||
return FALSE
|
||||
var/list/datum/bounty/crumbs = list(random_bounty(id_account.account_job.bounty_types), // We want to offer 2 bounties from their appropriate job catagories
|
||||
random_bounty(id_account.account_job.bounty_types), // and 1 guaranteed assistant bounty if the other 2 suck.
|
||||
random_bounty(CIV_JOB_BASIC))
|
||||
|
||||
var/list/datum/bounty/crumbs = generate_bounty_list(id_account.account_job.bounty_types)
|
||||
COOLDOWN_START(id_account, bounty_timer, (5 MINUTES) - cooldown_reduction)
|
||||
id_account.bounties = crumbs
|
||||
|
||||
/**
|
||||
* Generates a list of bounties for use with the civilian bounty pad.
|
||||
* @param bounty_types the define taken from a job for selection of a random_bounty() proc.
|
||||
* @param bounty_rolls the number of bounties to be selected from.
|
||||
* @param assistant_failsafe Do we guarentee one assistant bounty per generated list? Used for non-assistant jobs to give an easier alternative to that job's default bounties.
|
||||
*/
|
||||
/obj/machinery/computer/piratepad_control/civilian/proc/generate_bounty_list(bounty_types, bounty_rolls = 3, assistant_failsafe = TRUE)
|
||||
var/list/rolling_list = list()
|
||||
if(assistant_failsafe)
|
||||
rolling_list += random_bounty(CIV_JOB_BASIC)
|
||||
while(bounty_rolls > 1)
|
||||
var/datum/bounty/potential_bounty = random_bounty(bounty_types)
|
||||
var/repeats_bool = FALSE
|
||||
for(var/datum/iterator in rolling_list)
|
||||
if(iterator.type == potential_bounty.type)
|
||||
repeats_bool = TRUE
|
||||
if(repeats_bool)
|
||||
continue
|
||||
rolling_list += potential_bounty
|
||||
bounty_rolls -= 1
|
||||
return rolling_list
|
||||
|
||||
/**
|
||||
* Proc that assigned a civilian bounty to an ID card, from the list of potential bounties that that bank account currently has available.
|
||||
* Available choices are assigned during add_bounties, and one is locked in here.
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
var/give_wound_treatment_bonus = FALSE
|
||||
var/last_scan_text
|
||||
var/scanner_busy = FALSE
|
||||
/// Weakref to the last mob scanned by a health analyzer. Used to generate official medical reports.
|
||||
var/datum/weakref/last_healthy_scanned
|
||||
|
||||
/obj/item/healthanalyzer/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -97,6 +99,10 @@
|
||||
switch (scanmode)
|
||||
if (SCANMODE_HEALTH)
|
||||
last_scan_text = healthscan(user, M, mode, advanced, tochat = readability_check)
|
||||
if((M.health / M.maxHealth) > CLEAN_BILL_OF_HEALTH_RATIO)
|
||||
last_healthy_scanned = WEAKREF(M)
|
||||
else
|
||||
last_healthy_scanned = null
|
||||
if (SCANMODE_WOUND)
|
||||
if(readability_check)
|
||||
woundscan(user, M, src)
|
||||
@@ -423,10 +429,10 @@
|
||||
return
|
||||
scanner_busy = TRUE
|
||||
balloon_alert(user, "printing report...")
|
||||
addtimer(CALLBACK(src, PROC_REF(print_report)), 2 SECONDS)
|
||||
addtimer(CALLBACK(src, PROC_REF(print_report), user), 2 SECONDS)
|
||||
|
||||
/obj/item/healthanalyzer/proc/print_report(mob/user)
|
||||
var/obj/item/paper/report_paper = new(get_turf(src))
|
||||
var/obj/item/paper/medical_report/report_paper = new(get_turf(src))
|
||||
|
||||
report_paper.color = "#99ccff"
|
||||
report_paper.name = "health scan report - [station_time_timestamp()]"
|
||||
@@ -436,14 +442,41 @@
|
||||
report_paper.add_raw_text(report_text)
|
||||
report_paper.update_appearance()
|
||||
|
||||
if(ismob(loc))
|
||||
var/mob/printer = loc
|
||||
printer.put_in_hands(report_paper)
|
||||
balloon_alert(printer, "logs cleared")
|
||||
user.put_in_hands(report_paper)
|
||||
balloon_alert(user, "logs cleared")
|
||||
|
||||
resolve_patient_eligibility(report_paper, user)
|
||||
report_text = list()
|
||||
scanner_busy = FALSE
|
||||
|
||||
/**
|
||||
* Checks the mob and the medical report that the scanner is trying to print, checks the traits and statuses of the mob, and then resolves by true or false.
|
||||
* Applies traits to the patient if the scanning is eligable to turn in for a bounty, with callbacks to remove after a cooldown.
|
||||
*/
|
||||
/obj/item/healthanalyzer/proc/resolve_patient_eligibility(obj/item/paper/medical_report/report_paper, mob/scanner)
|
||||
var/mob/living/patient = last_healthy_scanned?.resolve()
|
||||
if(!patient)
|
||||
return FALSE
|
||||
|
||||
if(scanner == patient)
|
||||
return FALSE //You can't just scan yourself.
|
||||
|
||||
if(HAS_TRAIT(patient, TRAIT_RECENTLY_TREATED))
|
||||
return FALSE
|
||||
|
||||
report_paper.last_healthy_scanned_mob = last_healthy_scanned
|
||||
ADD_TRAIT(patient, TRAIT_RECENTLY_TREATED, ANALYZER_TRAIT)
|
||||
addtimer(TRAIT_CALLBACK_REMOVE(patient, RECENTLY_HEALED_COOLDOWN, ANALYZER_TRAIT), RECENTLY_HEALED_COOLDOWN)
|
||||
return TRUE
|
||||
|
||||
/obj/item/healthanalyzer/proc/clear_treatment(mob/living/target)
|
||||
if(!target)
|
||||
return
|
||||
if(QDELETED(target))
|
||||
return
|
||||
REMOVE_TRAIT(target, TRAIT_RECENTLY_TREATED, ANALYZER_TRAIT)
|
||||
return TRUE
|
||||
|
||||
/proc/chemscan(mob/living/user, mob/living/target)
|
||||
if(user.incapacitated)
|
||||
return
|
||||
@@ -719,6 +752,18 @@
|
||||
scanner.emotion = AID_EMOTION_WARN
|
||||
playsound(scanner, 'sound/machines/beep/twobeep.ogg', 50, FALSE)
|
||||
|
||||
/obj/item/paper/medical_report
|
||||
color = "#99ccff"
|
||||
desc = "An official medical bill of health generated by a computerized medical scanner."
|
||||
/// A reference to a mob's weakref that was last scanned by the medical scanner.
|
||||
var/datum/weakref/last_healthy_scanned_mob
|
||||
|
||||
/obj/item/paper/medical_report/examine(mob/user)
|
||||
. = ..()
|
||||
if(last_healthy_scanned_mob)
|
||||
. += span_notice("This medical report is applicable for medical bounties.")
|
||||
|
||||
|
||||
#undef SCANMODE_HEALTH
|
||||
#undef SCANMODE_WOUND
|
||||
#undef SCANMODE_COUNT
|
||||
|
||||
@@ -41,11 +41,41 @@
|
||||
wanted_types = list(/obj/item/spear = TRUE)
|
||||
|
||||
/datum/bounty/item/assistant/toolbox
|
||||
name = "Toolboxes"
|
||||
description = "There's an absence of robustness at Central Command. Hurry up and ship some toolboxes as a solution."
|
||||
name = "Stocked Toolbox"
|
||||
description = "There's an absence of robustness at Central Command. Ship them a fully packed toolbox as a solution, containing a screwdriver, wrench, welding tool, crowbar, analyzer, and wirecutters."
|
||||
reward = CARGO_CRATE_VALUE * 4
|
||||
required_count = 6
|
||||
wanted_types = list(/obj/item/storage/toolbox = TRUE)
|
||||
/// Typecache of tools that we want to see sorted into a toolbox. Unpacked in New(), verified in applies_to(), and then contents are filtered out in ship().
|
||||
var/list/static_packing_list = list(
|
||||
/obj/item/screwdriver = TRUE,
|
||||
/obj/item/wrench = TRUE,
|
||||
/obj/item/weldingtool = TRUE,
|
||||
/obj/item/crowbar = TRUE,
|
||||
/obj/item/analyzer = TRUE,
|
||||
/obj/item/wirecutters = TRUE,
|
||||
)
|
||||
|
||||
/datum/bounty/item/assistant/toolbox/New()
|
||||
. = ..()
|
||||
static_packing_list = string_assoc_list(zebra_typecacheof(static_packing_list, only_root_path = FALSE))
|
||||
|
||||
/datum/bounty/item/assistant/toolbox/applies_to(obj/shipped)
|
||||
var/list/packing_list = static_packing_list.Copy()
|
||||
for(var/obj/item_contents as anything in shipped.contents)
|
||||
if(is_type_in_typecache(item_contents.type, packing_list))
|
||||
packing_list -= subtypesof(item_contents.type)
|
||||
packing_list -= item_contents.type
|
||||
if(!length(packing_list))
|
||||
return ..()
|
||||
|
||||
return FALSE
|
||||
|
||||
/datum/bounty/item/assistant/toolbox/ship(obj/shipped)
|
||||
. = ..()
|
||||
for(var/obj/object as anything in shipped.contents)
|
||||
if(!is_type_in_typecache(object.type, static_packing_list))
|
||||
object.forceMove(shipped.drop_location())
|
||||
|
||||
|
||||
/datum/bounty/item/assistant/statue
|
||||
name = "Statue"
|
||||
@@ -133,8 +163,11 @@
|
||||
name = "Potted Plants"
|
||||
description = "Central Command is looking to commission a new BirdBoat-class station. You've been ordered to supply the potted plants."
|
||||
reward = CARGO_CRATE_VALUE * 4
|
||||
required_count = 8
|
||||
wanted_types = list(/obj/item/kirbyplants = TRUE)
|
||||
required_count = 3
|
||||
wanted_types = list(
|
||||
/obj/item/kirbyplants = TRUE,
|
||||
/obj/item/kirbyplants/synthetic = FALSE
|
||||
)
|
||||
|
||||
/datum/bounty/item/assistant/monkey_cubes
|
||||
name = "Monkey Cubes"
|
||||
@@ -156,12 +189,12 @@
|
||||
reward = CARGO_CRATE_VALUE * 6
|
||||
wanted_types = list(/obj/item/food/meat/slab/corgi = TRUE)
|
||||
|
||||
/datum/bounty/item/assistant/action_figures
|
||||
name = "Action Figures"
|
||||
description = "The vice president's son saw an ad for action figures on the telescreen and now he won't shut up about them. Ship some to ease his complaints."
|
||||
/datum/bounty/item/assistant/toys
|
||||
name = "Arcade Toys"
|
||||
description = "The vice president's son saw an ad for new toys on the telescreen and now he won't shut up about them. Ship some arcade toys over to ease his complaints."
|
||||
reward = CARGO_CRATE_VALUE * 8
|
||||
required_count = 5
|
||||
wanted_types = list(/obj/item/toy/figure = TRUE)
|
||||
wanted_types = list(/obj/item/toy = TRUE)
|
||||
|
||||
/datum/bounty/item/assistant/paper_bin
|
||||
name = "Paper Bins"
|
||||
@@ -177,14 +210,6 @@
|
||||
required_count = 8
|
||||
wanted_types = list(/obj/item/toy/crayon = TRUE)
|
||||
|
||||
/datum/bounty/item/assistant/pens
|
||||
name = "Pens"
|
||||
description = "We are hosting the intergalactic pen balancing competition. We need you to send us some standardized black ballpoint pens."
|
||||
reward = CARGO_CRATE_VALUE * 4
|
||||
required_count = 10
|
||||
include_subtypes = FALSE
|
||||
wanted_types = list(/obj/item/pen = TRUE)
|
||||
|
||||
/datum/bounty/item/assistant/water_tank
|
||||
name = "Water Tank"
|
||||
description = "We need more water for our hydroponics bay. Find a water tank and ship it out to us."
|
||||
|
||||
@@ -35,3 +35,27 @@
|
||||
/// If the user can actually get this bounty as a selection.
|
||||
/datum/bounty/proc/can_get()
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Debug item because it took less time to code this than it did to roll ONE toolbox bounty.
|
||||
*/
|
||||
/obj/item/bounty_voucher
|
||||
name = "bounty voucher"
|
||||
desc = "A certificate for ONE FREE BOUNTY of your choice! Wow!"
|
||||
icon = 'icons/obj/service/bureaucracy.dmi'
|
||||
icon_state = "paperslip_words"
|
||||
|
||||
/obj/item/bounty_voucher/attack_self(mob/user, modifiers)
|
||||
. = ..()
|
||||
if(!isliving(user))
|
||||
return
|
||||
var/mob/living/living_user = user
|
||||
var/obj/item/card/id/id = living_user.get_idcard()
|
||||
if(!id?.registered_account)
|
||||
return
|
||||
var/choice = tgui_input_list(living_user, "Choose a bounty.", "New Bounty", subtypesof(/datum/bounty))
|
||||
var/datum/bounty/new_chore = text2path("[choice]")
|
||||
id.registered_account.civilian_bounty = new new_chore
|
||||
balloon_alert(user, "new bounty acquired!")
|
||||
playsound(src, 'sound/effects/coin2.ogg', 30, TRUE)
|
||||
qdel(src)
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/datum/bounty/item/mech/New()
|
||||
..()
|
||||
description = "Upper management has requested one [name] mech be sent as soon as possible. Ship it to receive a large payment."
|
||||
|
||||
/datum/bounty/item/mech/ship(obj/shipped)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
var/obj/vehicle/sealed/mecha/mecha = shipped
|
||||
mecha.wreckage = null // So the mech doesn't explode.
|
||||
|
||||
/datum/bounty/item/mech/ripleymk2
|
||||
name = "APLU MK-II \"Ripley\""
|
||||
reward = CARGO_CRATE_VALUE * 26
|
||||
wanted_types = list(/obj/vehicle/sealed/mecha/ripley/mk2 = TRUE)
|
||||
|
||||
/datum/bounty/item/mech/clarke
|
||||
name = "Clarke"
|
||||
reward = CARGO_CRATE_VALUE * 32
|
||||
wanted_types = list(/obj/vehicle/sealed/mecha/clarke = TRUE)
|
||||
|
||||
/datum/bounty/item/mech/odysseus
|
||||
name = "Odysseus"
|
||||
reward = CARGO_CRATE_VALUE * 22
|
||||
wanted_types = list(/obj/vehicle/sealed/mecha/odysseus = TRUE)
|
||||
|
||||
/datum/bounty/item/mech/gygax
|
||||
name = "Gygax"
|
||||
reward = CARGO_CRATE_VALUE * 56
|
||||
wanted_types = list(/obj/vehicle/sealed/mecha/gygax = TRUE)
|
||||
|
||||
/datum/bounty/item/mech/durand
|
||||
name = "Durand"
|
||||
reward = CARGO_CRATE_VALUE * 40
|
||||
wanted_types = list(/obj/vehicle/sealed/mecha/durand = TRUE)
|
||||
@@ -0,0 +1,45 @@
|
||||
/datum/bounty/item/mech
|
||||
wanted_types = list(/obj/item/mecha_diagnostic = TRUE)
|
||||
/// What mech do we need data of inside this mecha diagnostic?
|
||||
var/required_data = null
|
||||
|
||||
/datum/bounty/item/mech/New()
|
||||
..()
|
||||
description = "Upper management has requested holodiagnostic scans of \a [name] mech be sent as soon as possible. A diagnostic holoscan can be generated from inside a new mecha. Ship it to receive a large payment."
|
||||
|
||||
/datum/bounty/item/mech/applies_to(obj/shipped)
|
||||
. = ..()
|
||||
if(istype(shipped, /obj/vehicle/sealed/mecha))
|
||||
shipped.balloon_alert_to_viewers("make diagnostic from inside!")
|
||||
|
||||
var/obj/item/mecha_diagnostic/diagnostic_sheet = shipped
|
||||
if(!diagnostic_sheet.mech_data)
|
||||
CRASH("Diagnostic sheet submitted with no mech data contained!")
|
||||
if(istype(diagnostic_sheet.mech_data, required_data))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/bounty/item/mech/ripleymk2
|
||||
name = "APLU MK-II \"Ripley\""
|
||||
reward = CARGO_CRATE_VALUE * 6.5
|
||||
required_data = /obj/vehicle/sealed/mecha/ripley/mk2
|
||||
|
||||
/datum/bounty/item/mech/clarke
|
||||
name = "Clarke"
|
||||
reward = CARGO_CRATE_VALUE * 12
|
||||
required_data = /obj/vehicle/sealed/mecha/clarke
|
||||
|
||||
/datum/bounty/item/mech/odysseus
|
||||
name = "Odysseus"
|
||||
reward = CARGO_CRATE_VALUE * 5.5
|
||||
required_data = /obj/vehicle/sealed/mecha/odysseus
|
||||
|
||||
/datum/bounty/item/mech/gygax
|
||||
name = "Gygax"
|
||||
reward = CARGO_CRATE_VALUE * 28
|
||||
required_data = /obj/vehicle/sealed/mecha/gygax
|
||||
|
||||
/datum/bounty/item/mech/durand
|
||||
name = "Durand"
|
||||
reward = CARGO_CRATE_VALUE * 20
|
||||
required_data = /obj/vehicle/sealed/mecha/durand
|
||||
@@ -104,3 +104,23 @@
|
||||
description = "After a recent influx of infected crew members, we've seen that masks just aren't cutting it alone. Silver operating tables might just do the trick though, send us one to use."
|
||||
reward = CARGO_CRATE_VALUE * 6
|
||||
wanted_types = list(/obj/structure/table/optable = TRUE)
|
||||
|
||||
/datum/bounty/item/medical/scanning
|
||||
name = "Crew Medical Scanning"
|
||||
description = "Conduct a routine medical scan using any health analyzer of a crew member with with a near perfect bill of health or better to ensure the crew is taking their medical care seriously. Then, print the medical report and ship it back to us."
|
||||
reward = CARGO_CRATE_VALUE * 8
|
||||
required_count = 2
|
||||
wanted_types = list(/obj/item/paper/medical_report = TRUE)
|
||||
|
||||
/datum/bounty/item/medical/scanning/applies_to(obj/shipped)
|
||||
. = ..()
|
||||
if(!istype(shipped, /obj/item/paper/medical_report))
|
||||
return FALSE
|
||||
var/obj/item/paper/medical_report/report = shipped
|
||||
if(!report)
|
||||
return FALSE
|
||||
|
||||
var/mob/living/patient = report.last_healthy_scanned_mob?.resolve()
|
||||
if(patient)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -19,26 +19,26 @@
|
||||
D.adjust_money(reward * SSeconomy.bounty_modifier)
|
||||
claimed = TRUE
|
||||
|
||||
/// If an item sent in the cargo shuttle can satisfy the bounty.
|
||||
/// If an item in question can satisfy the bounty.
|
||||
/datum/bounty/proc/applies_to(obj/O)
|
||||
return FALSE
|
||||
|
||||
/// Called when an object is shipped on the cargo shuttle.
|
||||
/// Called when an object is sent on the bounty pad.
|
||||
/datum/bounty/proc/ship(obj/O)
|
||||
return
|
||||
|
||||
/** Returns a new bounty of random type, but does not add it to GLOB.bounties_list.
|
||||
*
|
||||
* *Guided determines what specific catagory of bounty should be chosen.
|
||||
* * Category determines what specific catagory of bounty should be chosen.
|
||||
*/
|
||||
/proc/random_bounty(guided = 0)
|
||||
/proc/random_bounty(category = 0)
|
||||
var/bounty_num
|
||||
var/chosen_type
|
||||
var/bounty_succeeded = FALSE
|
||||
var/datum/bounty/item/bounty_ref
|
||||
while(!bounty_succeeded)
|
||||
if(guided && (guided != CIV_JOB_RANDOM))
|
||||
bounty_num = guided
|
||||
if(category && (category != CIV_JOB_RANDOM))
|
||||
bounty_num = category
|
||||
else
|
||||
bounty_num = rand(1, MAXIMUM_BOUNTY_JOBS)
|
||||
switch(bounty_num)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/datum/export/mecha/ripley
|
||||
cost = CARGO_CRATE_VALUE * 13
|
||||
unit_name = "APLU MK-II Ripley"
|
||||
export_types = list(/obj/vehicle/sealed/mecha/ripley/mk2)
|
||||
|
||||
/datum/export/mecha/clarke
|
||||
cost = CARGO_CRATE_VALUE * 16
|
||||
unit_name = "Clarke"
|
||||
export_types = list(/obj/vehicle/sealed/mecha/clarke)
|
||||
|
||||
/datum/export/mecha/odysseus
|
||||
cost = CARGO_CRATE_VALUE * 11
|
||||
unit_name = "Odysseus"
|
||||
export_types = list(/obj/vehicle/sealed/mecha/odysseus)
|
||||
|
||||
/datum/export/mecha/gygax
|
||||
cost = CARGO_CRATE_VALUE * 28
|
||||
unit_name = "Gygax"
|
||||
export_types = list(/obj/vehicle/sealed/mecha/gygax)
|
||||
|
||||
/datum/export/mecha/durand
|
||||
cost = CARGO_CRATE_VALUE * 20
|
||||
unit_name = "Durand"
|
||||
export_types = list(/obj/vehicle/sealed/mecha/durand)
|
||||
@@ -0,0 +1,26 @@
|
||||
/obj/item/mecha_diagnostic
|
||||
name = "mecha holodiagnostic"
|
||||
desc = "A holographic datasheet of unique data related to the mecha's construction and any production differences between the published designs to increment improvements."
|
||||
icon = 'icons/obj/devices/scanner.dmi'
|
||||
icon_state = "holosheet"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
layer = ABOVE_MOB_LAYER
|
||||
light_system = OVERLAY_LIGHT
|
||||
light_range = 1
|
||||
light_power = 2
|
||||
light_color = "#79aeeb"
|
||||
/// What mech was this diagnostic sheet generated from? Used for applicability in bounties.
|
||||
var/obj/vehicle/sealed/mecha/mech_data
|
||||
|
||||
/obj/item/mecha_diagnostic/Initialize(mapload)
|
||||
. = ..()
|
||||
set_light_on(TRUE)
|
||||
|
||||
/obj/item/mecha_diagnostic/Destroy(force)
|
||||
. = ..()
|
||||
mech_data = null
|
||||
|
||||
/obj/item/mecha_diagnostic/examine(mob/user)
|
||||
. = ..()
|
||||
if(mech_data)
|
||||
. += "This holodata sheet consists of data from a <b>[initial(mech_data.name)]</b>."
|
||||
@@ -60,6 +60,7 @@
|
||||
"MECHA_INT_CONTROL_LOST" = MECHA_INT_CONTROL_LOST,
|
||||
"MECHA_INT_SHORT_CIRCUIT" = MECHA_INT_SHORT_CIRCUIT,
|
||||
)
|
||||
data["diagnostic_status"] = HAS_TRAIT(src, TRAIT_MECHA_DIAGNOSTIC_CREATED)
|
||||
|
||||
var/list/regions = list()
|
||||
var/list/tgui_region_data = SSid_access.all_region_access_tgui
|
||||
@@ -225,5 +226,12 @@
|
||||
if("equip_act")
|
||||
var/obj/item/mecha_parts/mecha_equipment/gear = locate(params["ref"]) in flat_equipment
|
||||
return gear?.ui_act(params["gear_action"], params, ui, state)
|
||||
if("diagnostic")
|
||||
if(HAS_TRAIT(src, TRAIT_MECHA_DIAGNOSTIC_CREATED))
|
||||
return FALSE
|
||||
var/obj/item/mecha_diagnostic/diagnostic = new /obj/item/mecha_diagnostic(get_turf(src))
|
||||
diagnostic.name = "mecha holodiagnostic ([src.name])"
|
||||
diagnostic.mech_data += src
|
||||
ADD_TRAIT(src, TRAIT_MECHA_DIAGNOSTIC_CREATED, REF(src))
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -276,6 +276,7 @@ GLOBAL_DATUM(cargo_ripley, /obj/vehicle/sealed/mecha/ripley/cargo)
|
||||
take_damage(max_integrity * 0.5, sound_effect=FALSE) //Low starting health
|
||||
if(!GLOB.cargo_ripley && mapload)
|
||||
GLOB.cargo_ripley = src
|
||||
ADD_TRAIT(src, TRAIT_MECHA_DIAGNOSTIC_CREATED, REF(src)) //It was built *long* before the shift started.
|
||||
|
||||
/obj/vehicle/sealed/mecha/ripley/cargo/Destroy()
|
||||
if(GLOB.cargo_ripley == src)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 29 KiB |
+3
-1
@@ -3760,7 +3760,7 @@
|
||||
#include "code\modules\cargo\bounties\chef.dm"
|
||||
#include "code\modules\cargo\bounties\engineering.dm"
|
||||
#include "code\modules\cargo\bounties\item.dm"
|
||||
#include "code\modules\cargo\bounties\mech.dm"
|
||||
#include "code\modules\cargo\bounties\mecha.dm"
|
||||
#include "code\modules\cargo\bounties\medical.dm"
|
||||
#include "code\modules\cargo\bounties\mining.dm"
|
||||
#include "code\modules\cargo\bounties\reagent.dm"
|
||||
@@ -3779,6 +3779,7 @@
|
||||
#include "code\modules\cargo\exports\lavaland.dm"
|
||||
#include "code\modules\cargo\exports\manifest.dm"
|
||||
#include "code\modules\cargo\exports\materials.dm"
|
||||
#include "code\modules\cargo\exports\mecha.dm"
|
||||
#include "code\modules\cargo\exports\organs.dm"
|
||||
#include "code\modules\cargo\exports\parts.dm"
|
||||
#include "code\modules\cargo\exports\seeds.dm"
|
||||
@@ -6368,6 +6369,7 @@
|
||||
#include "code\modules\vehicles\mecha\mecha_control_console.dm"
|
||||
#include "code\modules\vehicles\mecha\mecha_damage.dm"
|
||||
#include "code\modules\vehicles\mecha\mecha_defense.dm"
|
||||
#include "code\modules\vehicles\mecha\mecha_diagnostic.dm"
|
||||
#include "code\modules\vehicles\mecha\mecha_helpers.dm"
|
||||
#include "code\modules\vehicles\mecha\mecha_mob_interaction.dm"
|
||||
#include "code\modules\vehicles\mecha\mecha_movement.dm"
|
||||
|
||||
@@ -54,6 +54,7 @@ export type MainData = {
|
||||
modules: MechModule[];
|
||||
selected_module_index: number;
|
||||
sheet_material_amount: number;
|
||||
diagnostic_status: BooleanLike;
|
||||
};
|
||||
|
||||
export type MechModule = {
|
||||
|
||||
@@ -38,6 +38,7 @@ export const Content = (props) => {
|
||||
one_access,
|
||||
regions,
|
||||
accesses,
|
||||
diagnostic_status,
|
||||
} = data;
|
||||
const id_lock = mecha_flags & mechflag_keys['ID_LOCK_ON'];
|
||||
return (
|
||||
@@ -49,12 +50,23 @@ export const Content = (props) => {
|
||||
fill
|
||||
title={name}
|
||||
buttons={
|
||||
<Button
|
||||
icon="edit"
|
||||
tooltip="Rename"
|
||||
tooltipPosition="left"
|
||||
onClick={() => act('changename')}
|
||||
/>
|
||||
<>
|
||||
<Button
|
||||
icon="edit"
|
||||
tooltip="Rename"
|
||||
tooltipPosition="left"
|
||||
onClick={() => act('changename')}
|
||||
/>
|
||||
{!diagnostic_status && (
|
||||
<Button
|
||||
icon="tachograph-digital"
|
||||
color="violet"
|
||||
tooltip="Diagnostic"
|
||||
tooltipPosition="left"
|
||||
onClick={() => act('diagnostic')}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Stack fill vertical>
|
||||
|
||||
Reference in New Issue
Block a user