From bba09c05cc780684e3b55430e5d18dae9187516e Mon Sep 17 00:00:00 2001 From: Weblure Date: Sun, 29 Sep 2019 18:03:12 -0700 Subject: [PATCH 1/7] Ports Xenobio Console Hotkeys from TG ## About The Pull Request This enables xenobiologists to perform all of the (unlocked) slime console functions by simply holding down a modifier key and primary-clicking a slime/monkey/empty floor space. This functionality has been ported from TG and modified to work for Cit. ## List of Changes * Button added to slime console that prints out the hotkey commands to the user. [NEEDS BUTTON ICON] * Shift-click a slime to pick it up, or the floor to drop all held slimes. (Requires Basic Slime Console upgrade) * Ctrl-click a slime to scan it. * Alt-click a slime to feed it a potion. (Requires Advanced Slime Console upgrade) * Ctrl-click on a dead monkey to recycle it, or the floor to place a new monkey. (Requires Monkey Console upgrade) * If the console does not have the required upgrade, an error message will print to the user. * When recycling monkeys, the console will now report how many monkeys it has (will not report decimal increases). * Console now alerts you when you're out of monkeys and reports your current decimal amount. * Console messages are now styled consistently. * You can now pick up a single slime from a pile, instead of all of them at once. ## Why It's Good For The Game Adds QoL features for Xenobiologists and increases department efficiency. Removes the frustration of trying to line up a hyper-sensitive camera reticle on a moving slime with your keyboard, especially for users with laggy clients. ## Notes This PR may contain bugs and poor coding practices. TG allows for consoles to be linked to a physical monkey recycler, sharing its contents across all 3 machines. This PR does NOT port that functionality because I'm lazy and don't know what I'm doing. Special thanks to everyone in #development-discussions-main for helping me with my dumb mistakes and to @Studious Cirno#4894 for suggesting this PR. --- components.dm | 284 ++++++++++++++++++++++++++++ xenobio_camera.dm | 458 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 742 insertions(+) create mode 100644 components.dm create mode 100644 xenobio_camera.dm diff --git a/components.dm b/components.dm new file mode 100644 index 0000000000..8e8c7dc55b --- /dev/null +++ b/components.dm @@ -0,0 +1,284 @@ +#define SEND_SIGNAL(target, sigtype, arguments...) ( !target.comp_lookup || !target.comp_lookup[sigtype] ? NONE : target._SendSignal(sigtype, list(target, ##arguments)) ) + +#define SEND_GLOBAL_SIGNAL(sigtype, arguments...) ( SEND_SIGNAL(SSdcs, sigtype, ##arguments) ) + +//shorthand +#define GET_COMPONENT_FROM(varname, path, target) var##path/##varname = ##target.GetComponent(##path) +#define GET_COMPONENT(varname, path) GET_COMPONENT_FROM(varname, path, src) + +#define COMPONENT_INCOMPATIBLE 1 + +// How multiple components of the exact same type are handled in the same datum + +#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default) +#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed +#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted +#define COMPONENT_DUPE_UNIQUE_PASSARGS 4 //old component is given the initialization args of the new + +// All signals. Format: +// When the signal is called: (signal arguments) +// All signals send the source datum of the signal as the first argument + +// global signals +// These are signals which can be listened to by any component on any parent +// start global signals with "!", this used to be necessary but now it's just a formatting choice +#define COMSIG_GLOB_NEW_Z "!new_z" //from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args) +#define COMSIG_GLOB_VAR_EDIT "!var_edit" //called after a successful var edit somewhere in the world: (list/args) +#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special" //global living say plug - use sparingly: (mob/speaker , message) +////////////////////////////////////////////////////////////////// + +// /datum signals +#define COMSIG_COMPONENT_ADDED "component_added" //when a component is added to a datum: (/datum/component) +#define COMSIG_COMPONENT_REMOVING "component_removing" //before a component is removed from a datum because of RemoveComponent: (/datum/component) +#define COMSIG_PARENT_PREQDELETED "parent_preqdeleted" //before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation +#define COMSIG_PARENT_QDELETED "parent_qdeleted" //after a datum's Destroy() is called: (force, qdel_hint), at this point none of the other components chose to interrupt qdel and Destroy has been called + +// /atom signals +#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params) + #define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called +#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human) +#define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob) +#define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name" //from base of atom/get_examine_name(): (/mob, list/overrides) + //Positions for overrides list + #define EXAMINE_POSITION_ARTICLE 1 + #define EXAMINE_POSITION_BEFORE 2 + //End positions + #define COMPONENT_EXNAME_CHANGED 1 +#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable/entering, /atom) +#define COMSIG_ATOM_EXIT "atom_exit" //from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc) + #define COMPONENT_ATOM_BLOCK_EXIT 1 +#define COMSIG_ATOM_EXITED "atom_exited" //from base of atom/Exited(): (atom/movable/exiting, atom/newloc) +#define COMSIG_ATOM_EX_ACT "atom_ex_act" //from base of atom/ex_act(): (severity, target) +#define COMSIG_ATOM_EMP_ACT "atom_emp_act" //from base of atom/emp_act(): (severity) +#define COMSIG_ATOM_FIRE_ACT "atom_fire_act" //from base of atom/fire_act(): (exposed_temperature, exposed_volume) +#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act" //from base of atom/bullet_act(): (/obj/item/projectile, def_zone) +#define COMSIG_ATOM_BLOB_ACT "atom_blob_act" //from base of atom/blob_act(): (/obj/structure/blob) +#define COMSIG_ATOM_ACID_ACT "atom_acid_act" //from base of atom/acid_act(): (acidpwr, acid_volume) +#define COMSIG_ATOM_EMAG_ACT "atom_emag_act" //from base of atom/emag_act(): () +#define COMSIG_ATOM_RAD_ACT "atom_rad_act" //from base of atom/rad_act(intensity) +#define COMSIG_ATOM_NARSIE_ACT "atom_narsie_act" //from base of atom/narsie_act(): () +#define COMSIG_ATOM_RATVAR_ACT "atom_ratvar_act" //from base of atom/ratvar_act(): () +#define COMSIG_ATOM_RCD_ACT "atom_rcd_act" //from base of atom/rcd_act(): (/mob, /obj/item/construction/rcd, passed_mode) +#define COMSIG_ATOM_SING_PULL "atom_sing_pull" //from base of atom/singularity_pull(): (S, current_size) +#define COMSIG_ATOM_SET_LIGHT "atom_set_light" //from base of atom/set_light(): (l_range, l_power, l_color) +#define COMSIG_ATOM_DIR_CHANGE "atom_dir_change" //from base of atom/setDir(): (old_dir, new_dir) +#define COMSIG_ATOM_CONTENTS_DEL "atom_contents_del" //from base of atom/handle_atom_del(): (atom/deleted) +#define COMSIG_ATOM_HAS_GRAVITY "atom_has_gravity" //from base of atom/has_gravity(): (turf/location, list/forced_gravities) +#define COMSIG_ATOM_RAD_PROBE "atom_rad_probe" //from proc/get_rad_contents(): () + #define COMPONENT_BLOCK_RADIATION 1 +#define COMSIG_ATOM_RAD_CONTAMINATING "atom_rad_contam" //from base of datum/radiation_wave/radiate(): (strength) + #define COMPONENT_BLOCK_CONTAMINATION 1 +#define COMSIG_ATOM_RAD_WAVE_PASSING "atom_rad_wave_pass" //from base of datum/radiation_wave/check_obstructions(): (datum/radiation_wave, width) + #define COMPONENT_RAD_WAVE_HANDLED 1 +#define COMSIG_ATOM_CANREACH "atom_can_reach" //from internal loop in atom/movable/proc/CanReach(): (list/next) + #define COMPONENT_BLOCK_REACH 1 +#define COMSIG_ATOM_SCREWDRIVER_ACT "atom_screwdriver_act" //from base of atom/screwdriver_act(): (mob/living/user, obj/item/I) +#define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport" //called when teleporting into a protected turf: (channel, turf/origin) + #define COMPONENT_BLOCK_TELEPORT 1 +///////////////// +#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" //from base of atom/attack_ghost(): (mob/dead/observer/ghost) +#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" //from base of atom/attack_hand(): (mob/user) +#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw" //from base of atom/attack_paw(): (mob/user) + #define COMPONENT_NO_ATTACK_HAND 1 //works on all 3. +///////////////// + +#define COMSIG_ENTER_AREA "enter_area" //from base of area/Entered(): (/area) +#define COMSIG_EXIT_AREA "exit_area" //from base of area/Exited(): (/area) + +#define COMSIG_CLICK "atom_click" //from base of atom/Click(): (location, control, params, mob/user) +#define COMSIG_CLICK_SHIFT "shift_click" //from base of atom/ShiftClick(): (/mob) +#define COMSIG_CLICK_CTRL "ctrl_click" //from base of atom/CtrlClickOn(): (/mob) +#define COMSIG_CLICK_ALT "alt_click" //from base of atom/AltClick(): (/mob) +#define COMSIG_CLICK_CTRL_SHIFT "ctrl_shift_click" //from base of atom/CtrlShiftClick(/mob) +#define COMSIG_MOUSEDROP_ONTO "mousedrop_onto" //from base of atom/MouseDrop(): (/atom/over, /mob/user) + #define COMPONENT_NO_MOUSEDROP 1 +#define COMSIG_MOUSEDROPPED_ONTO "mousedropped_onto" //from base of atom/MouseDrop_T: (/atom/from, /mob/user) + +// /area signals +#define COMSIG_AREA_ENTERED "area_entered" //from base of area/Entered(): (atom/movable/M) +#define COMSIG_AREA_EXITED "area_exited" //from base of area/Exited(): (atom/movable/M) + +// /turf signals +#define COMSIG_TURF_CHANGE "turf_change" //from base of turf/ChangeTurf(): (path, list/new_baseturfs, flags, list/transferring_comps) +#define COMSIG_TURF_HAS_GRAVITY "turf_has_gravity" //from base of atom/has_gravity(): (atom/asker, list/forced_gravities) + +// /atom/movable signals +#define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir) +#define COMSIG_MOVABLE_CROSS "movable_cross" //from base of atom/movable/Cross(): (/atom/movable) +#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable) +#define COMSIG_MOVABLE_UNCROSS "movable_uncross" //from base of atom/movable/Uncross(): (/atom/movable) + #define COMPONENT_MOVABLE_BLOCK_UNCROSS 1 +#define COMSIG_MOVABLE_UNCROSSED "movable_uncrossed" //from base of atom/movable/Uncrossed(): (/atom/movable) +#define COMSIG_MOVABLE_BUMP "movable_bump" //from base of atom/movable/Bump(): (/atom) +#define COMSIG_MOVABLE_IMPACT "movable_impact" //from base of atom/movable/throw_impact(): (/atom/hit_atom, /datum/thrownthing/throwingdatum) +#define COMSIG_MOVABLE_IMPACT_ZONE "item_impact_zone" //from base of mob/living/hitby(): (mob/living/target, hit_zone) +#define COMSIG_MOVABLE_BUCKLE "buckle" //from base of atom/movable/buckle_mob(): (mob, force) +#define COMSIG_MOVABLE_UNBUCKLE "unbuckle" //from base of atom/movable/unbuckle_mob(): (mob, force) +#define COMSIG_MOVABLE_PRE_THROW "movable_pre_throw" //from base of atom/movable/throw_at(): (list/args) + #define COMPONENT_CANCEL_THROW 1 +#define COMSIG_MOVABLE_POST_THROW "movable_post_throw" //from base of atom/movable/throw_at(): (datum/thrownthing, spin) +#define COMSIG_MOVABLE_Z_CHANGED "movable_ztransit" //from base of atom/movable/onTransitZ(): (old_z, new_z) +#define COMSIG_MOVABLE_HEAR "movable_hear" //from base of atom/movable/Hear(): (message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode) +#define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source) + +// /mob signals +#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed) +#define COMSIG_MOB_ALLOWED "mob_allowed" //from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj +#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (magic, holy, protection_sources) + #define COMPONENT_BLOCK_MAGIC 1 +#define COMSIG_MOB_HUD_CREATED "mob_hud_created" //from base of mob/create_mob_hud(): () +#define COMSIG_MOB_ATTACK_HAND "mob_attack_hand" //from base of +#define COMSIG_MOB_ITEM_ATTACK "mob_item_attack" //from base of /obj/item/attack(): (mob/M, mob/user) +#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters) +#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params) +#define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target) +#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): () +#define COMSIG_MOB_SAY "mob_say" // from /mob/living/say(): (proc args list) + #define COMPONENT_UPPERCASE_SPEECH 1 + // used to access COMSIG_MOB_SAY argslist + #define SPEECH_MESSAGE 1 + // #define SPEECH_BUBBLE_TYPE 2 + #define SPEECH_SPANS 3 + /* #define SPEECH_SANITIZE 4 + #define SPEECH_LANGUAGE 5 + #define SPEECH_IGNORE_SPAM 6 + #define SPEECH_FORCED 7 */ + +// /mob/living signals +#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living) +#define COMSIG_LIVING_IGNITED "living_ignite" //from base of mob/living/IgniteMob() (/mob/living) +#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living) +#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage) +#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: () + +// /mob/living/carbon signals +#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity)) + +// /obj signals +#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct" //from base of obj/deconstruct(): (disassembled) +#define COMSIG_OBJ_BREAK "obj_break" //from base of /obj/obj_break(): (damage_flag) +#define COMSIG_OBJ_SETANCHORED "obj_setanchored" //called in /obj/structure/setAnchored(): (value) + + +// /obj/item signals +#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user) +#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob) + #define COMPONENT_NO_INTERACT 1 +#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob) + #define COMPONENT_NO_ATTACK_OBJ 1 +#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack" //from base of obj/item/pre_attack(): (atom/target, mob/user, params) + #define COMPONENT_NO_ATTACK 1 +#define COMSIG_ITEM_AFTERATTACK "item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, params) +#define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot) +#define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (mob/user) +#define COMSIG_ITEM_PICKUP "item_pickup" //from base of obj/item/pickup(): (/mob/taker) +#define COMSIG_ITEM_ATTACK_ZONE "item_attack_zone" //from base of mob/living/carbon/attacked_by(): (mob/living/carbon/target, mob/living/user, hit_zone) +#define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul" //return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/targeted/lichdom/cast(): (mob/user) +#define COMSIG_ITEM_HIT_REACT "item_hit_react" //from base of obj/item/hit_reaction(): (list/args) + +// /obj/item/clothing signals +#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): () + +// /obj/item/implant signals +#define COMSIG_IMPLANT_ACTIVATED "implant_activated" //from base of /obj/item/implant/proc/activate(): () +#define COMSIG_IMPLANT_IMPLANTING "implant_implanting" //from base of /obj/item/implant/proc/implant(): (list/args) + #define COMPONENT_STOP_IMPLANTING 1 +#define COMSIG_IMPLANT_OTHER "implant_other" //called on already installed implants when a new one is being added in /obj/item/implant/proc/implant(): (list/args, obj/item/implant/new_implant) + //#define COMPONENT_STOP_IMPLANTING 1 //The name makes sense for both + #define COMPONENT_DELETE_NEW_IMPLANT 2 + #define COMPONENT_DELETE_OLD_IMPLANT 4 +#define COMSIG_IMPLANT_EXISTING_UPLINK "implant_uplink_exists" //called on implants being implanted into someone with an uplink implant: (datum/component/uplink) + //This uses all return values of COMSIG_IMPLANT_OTHER + +// /obj/item/pda signals +#define COMSIG_PDA_CHANGE_RINGTONE "pda_change_ringtone" //called on pda when the user changes the ringtone: (mob/living/user, new_ringtone) + #define COMPONENT_STOP_RINGTONE_CHANGE 1 + +// /obj/item/radio signals +#define COMSIG_RADIO_NEW_FREQUENCY "radio_new_frequency" //called from base of /obj/item/radio/proc/set_frequency(): (list/args) + +// /obj/item/pen signals +#define COMSIG_PEN_ROTATED "pen_rotated" //called after rotation in /obj/item/pen/attack_self(): (rotation, mob/living/carbon/user) + + +// /mob/living/carbon/human signals +#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target) +#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker) +#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit" //Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted) + +// /datum/species signals +#define COMSIG_SPECIES_GAIN "species_gain" //from datum/species/on_species_gain(): (datum/species/new_species, datum/species/old_species) +#define COMSIG_SPECIES_LOSS "species_loss" //from datum/species/on_species_loss(): (datum/species/lost_species) + +/*******Component Specific Signals*******/ +//Janitor +#define COMSIG_TURF_IS_WET "check_turf_wet" //(): Returns bitflags of wet values. +#define COMSIG_TURF_MAKE_DRY "make_turf_try" //(max_strength, immediate, duration_decrease = INFINITY): Returns bool. +#define COMSIG_COMPONENT_CLEAN_ACT "clean_act" //called on an object to clean it of cleanables. Usualy with soap: (num/strength) + +//Food +#define COMSIG_FOOD_EATEN "food_eaten" //from base of obj/item/reagent_containers/food/snacks/attack(): (mob/living/eater, mob/feeder) + +//Mood +#define COMSIG_ADD_MOOD_EVENT "add_mood" //Called when you send a mood event from anywhere in the code. +#define COMSIG_CLEAR_MOOD_EVENT "clear_mood" //Called when you clear a mood event from anywhere in the code. + +//NTnet +#define COMSIG_COMPONENT_NTNET_RECEIVE "ntnet_receive" //called on an object by its NTNET connection component on receive. (sending_id(number), sending_netname(text), data(datum/netdata)) + +//Nanites +#define COMSIG_HAS_NANITES "has_nanites" //() returns TRUE if nanites are found +#define COMSIG_NANITE_GET_PROGRAMS "nanite_get_programs" //(list/nanite_programs) - makes the input list a copy the nanites' program list +#define COMSIG_NANITE_SET_VOLUME "nanite_set_volume" //(amount) Sets current nanite volume to the given amount +#define COMSIG_NANITE_ADJUST_VOLUME "nanite_adjust" //(amount) Adjusts nanite volume by the given amount +#define COMSIG_NANITE_SET_MAX_VOLUME "nanite_set_max_volume" //(amount) Sets maximum nanite volume to the given amount +#define COMSIG_NANITE_SET_CLOUD "nanite_set_cloud" //(amount(0-100)) Sets cloud ID to the given amount +#define COMSIG_NANITE_SET_SAFETY "nanite_set_safety" //(amount) Sets safety threshold to the given amount +#define COMSIG_NANITE_SET_REGEN "nanite_set_regen" //(amount) Sets regeneration rate to the given amount +#define COMSIG_NANITE_SIGNAL "nanite_signal" //(code(1-9999)) Called when sending a nanite signal to a mob. +#define COMSIG_NANITE_SCAN "nanite_scan" //(mob/user, full_scan) - sends to chat a scan of the nanites to the user, returns TRUE if nanites are detected +#define COMSIG_NANITE_UI_DATA "nanite_ui_data" //(list/data, scan_level) - adds nanite data to the given data list - made for ui_data procs +#define COMSIG_NANITE_ADD_PROGRAM "nanite_add_program" //(datum/nanite_program/new_program, datum/nanite_program/source_program) Called when adding a program to a nanite component + #define COMPONENT_PROGRAM_INSTALLED 1 //Installation successful + #define COMPONENT_PROGRAM_NOT_INSTALLED 2 //Installation failed, but there are still nanites +#define COMSIG_NANITE_SYNC "nanite_sync" //(datum/component/nanites, full_overwrite, copy_activation) Called to sync the target's nanites to a given nanite component + +// /datum/component/storage signals +#define COMSIG_CONTAINS_STORAGE "is_storage" //() - returns bool. +#define COMSIG_TRY_STORAGE_INSERT "storage_try_insert" //(obj/item/inserting, mob/user, silent, force) - returns bool +#define COMSIG_TRY_STORAGE_SHOW "storage_show_to" //(mob/show_to, force) - returns bool. +#define COMSIG_TRY_STORAGE_HIDE_FROM "storage_hide_from" //(mob/hide_from) - returns bool +#define COMSIG_TRY_STORAGE_HIDE_ALL "storage_hide_all" //returns bool +#define COMSIG_TRY_STORAGE_SET_LOCKSTATE "storage_lock_set_state" //(newstate) +#define COMSIG_IS_STORAGE_LOCKED "storage_get_lockstate" //() - returns bool. MUST CHECK IF STORAGE IS THERE FIRST! +#define COMSIG_TRY_STORAGE_TAKE_TYPE "storage_take_type" //(type, atom/destination, amount = INFINITY, check_adjacent, force, mob/user, list/inserted) - returns bool - type can be a list of types. +#define COMSIG_TRY_STORAGE_FILL_TYPE "storage_fill_type" //(type, amount = INFINITY, force = FALSE) //don't fuck this up. Force will ignore max_items, and amount is normally clamped to max_items. +#define COMSIG_TRY_STORAGE_TAKE "storage_take_obj" //(obj, new_loc, force = FALSE) - returns bool +#define COMSIG_TRY_STORAGE_QUICK_EMPTY "storage_quick_empty" //(loc) - returns bool - if loc is null it will dump at parent location. +#define COMSIG_TRY_STORAGE_RETURN_INVENTORY "storage_return_inventory" //(list/list_to_inject_results_into, recursively_search_inside_storages = TRUE) +#define COMSIG_TRY_STORAGE_CAN_INSERT "storage_can_equip" //(obj/item/insertion_candidate, mob/user, silent) - returns bool + +// /datum/action signals +#define COMSIG_ACTION_TRIGGER "action_trigger" //from base of datum/action/proc/Trigger(): (datum/action) + #define COMPONENT_ACTION_BLOCK_TRIGGER 1 + +/*******Non-Signal Component Related Defines*******/ + +//Redirection component init flags +#define REDIRECT_TRANSFER_WITH_TURF 1 + +//Arch +#define ARCH_PROB "probability" //Probability for each item +#define ARCH_MAXDROP "max_drop_amount" //each item's max drop amount + +//Ouch my toes! +#define CALTROP_BYPASS_SHOES 1 +#define CALTROP_IGNORE_WALKERS 2 + +//Xenobio hotkeys +#define COMSIG_XENO_SLIME_CLICK_CTRL "xeno_slime_click_ctrl" //from slime CtrlClickOn(): (/mob) +#define COMSIG_XENO_SLIME_CLICK_ALT "xeno_slime_click_alt" //from slime AltClickOn(): (/mob) +#define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift" //from slime ShiftClickOn(): (/mob) +#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift" //from turf ShiftClickOn(): (/mob) +#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob) +#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob) diff --git a/xenobio_camera.dm b/xenobio_camera.dm new file mode 100644 index 0000000000..07b25c6de8 --- /dev/null +++ b/xenobio_camera.dm @@ -0,0 +1,458 @@ +//Xenobio control console +/mob/camera/aiEye/remote/xenobio + visible_icon = 1 + icon = 'icons/obj/abductor.dmi' + icon_state = "camera_target" + var/allowed_area = null + +/mob/camera/aiEye/remote/xenobio/Initialize() + var/area/A = get_area(loc) + allowed_area = A.name + . = ..() + +/mob/camera/aiEye/remote/xenobio/setLoc(var/t) + var/area/new_area = get_area(t) + if(new_area && new_area.name == allowed_area || new_area && new_area.xenobiology_compatible) + return ..() + else + return + +/obj/machinery/computer/camera_advanced/xenobio + name = "Slime management console" + desc = "A computer used for remotely handling slimes." + networks = list("ss13") + circuit = /obj/item/circuitboard/computer/xenobiology + var/datum/action/innate/slime_place/slime_place_action + var/datum/action/innate/slime_pick_up/slime_up_action + var/datum/action/innate/feed_slime/feed_slime_action + var/datum/action/innate/monkey_recycle/monkey_recycle_action + var/datum/action/innate/slime_scan/scan_action + var/datum/action/innate/feed_potion/potion_action + var/datum/action/innate/hotkey_help/hotkey_help + + var/datum/component/redirect/listener + + var/list/stored_slimes + var/obj/item/slimepotion/slime/current_potion + var/max_slimes = 5 + var/monkeys = 0 + + icon_screen = "slime_comp" + icon_keyboard = "rd_key" + + light_color = LIGHT_COLOR_PINK + +/obj/machinery/computer/camera_advanced/xenobio/Initialize() + . = ..() + slime_place_action = new + slime_up_action = new + feed_slime_action = new + monkey_recycle_action = new + scan_action = new + potion_action = new + hotkey_help = new + stored_slimes = list() + listener = AddComponent(/datum/component/redirect, list(COMSIG_ATOM_CONTENTS_DEL = CALLBACK(src, .proc/on_contents_del))) + +/obj/machinery/computer/camera_advanced/xenobio/Destroy() + stored_slimes = null + QDEL_NULL(current_potion) + for(var/i in contents) + var/mob/living/simple_animal/slime/S = i + if(istype(S)) + S.forceMove(drop_location()) + return ..() + +/obj/machinery/computer/camera_advanced/xenobio/CreateEye() + eyeobj = new /mob/camera/aiEye/remote/xenobio(get_turf(src)) + eyeobj.origin = src + eyeobj.visible_icon = 1 + eyeobj.icon = 'icons/obj/abductor.dmi' + eyeobj.icon_state = "camera_target" + +/obj/machinery/computer/camera_advanced/xenobio/GrantActions(mob/living/user) + ..() + + if(slime_up_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC + slime_up_action.target = src + slime_up_action.Grant(user) + actions += slime_up_action + + if(slime_place_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC + slime_place_action.target = src + slime_place_action.Grant(user) + actions += slime_place_action + + if(feed_slime_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS + feed_slime_action.target = src + feed_slime_action.Grant(user) + actions += feed_slime_action + + if(monkey_recycle_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS + monkey_recycle_action.target = src + monkey_recycle_action.Grant(user) + actions += monkey_recycle_action + + if(scan_action) + scan_action.target = src + scan_action.Grant(user) + actions += scan_action + + if(potion_action && (upgradetier & XENOBIO_UPGRADE_SLIMEADV)) // CIT CHANGE - makes giving slimes potions via console require XENOBIO_UPGRADE_SLIMEADV + potion_action.target = src + potion_action.Grant(user) + actions += potion_action + + if(hotkey_help) + hotkey_help.target = src + hotkey_help.Grant(user) + actions += hotkey_help + + RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL, .proc/XenoSlimeClickCtrl) + RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT, .proc/XenoSlimeClickAlt) + RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT, .proc/XenoSlimeClickShift) + RegisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT, .proc/XenoTurfClickShift) + RegisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL, .proc/XenoTurfClickCtrl) + RegisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL, .proc/XenoMonkeyClickCtrl) + +/obj/machinery/computer/camera_advanced/xenobio/remove_eye_control(mob/living/user) + UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL) + UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT) + UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT) + UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT) + UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL) + UnregisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL) + ..() + +/obj/machinery/computer/camera_advanced/xenobio/proc/on_contents_del(atom/deleted) + if(current_potion == deleted) + current_potion = null + if(deleted in stored_slimes) + stored_slimes -= deleted + +/obj/machinery/computer/camera_advanced/xenobio/attackby(obj/item/O, mob/user, params) + if(istype(O, /obj/item/reagent_containers/food/snacks/monkeycube) && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS + monkeys++ + to_chat(user, "You feed [O] to [src]. It now has [monkeys] monkey cubes stored.") + qdel(O) + return + else if(istype(O, /obj/item/storage/bag) && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS + var/obj/item/storage/P = O + var/loaded = FALSE + for(var/obj/G in P.contents) + if(istype(G, /obj/item/reagent_containers/food/snacks/monkeycube)) + loaded = TRUE + monkeys++ + qdel(G) + if(loaded) + to_chat(user, "You fill [src] with the monkey cubes stored in [O]. [src] now has [monkeys] monkey cubes stored.") + return + else if(istype(O, /obj/item/slimepotion/slime) && (upgradetier & XENOBIO_UPGRADE_SLIMEADV)) // CIT CHANGE - makes giving slimes potions via console require XENOBIO_UPGRADE_SLIMEADV + var/replaced = FALSE + if(user && !user.transferItemToLoc(O, src)) + return + if(!QDELETED(current_potion)) + current_potion.forceMove(drop_location()) + replaced = TRUE + current_potion = O + to_chat(user, "You load [O] in the console's potion slot[replaced ? ", replacing the one that was there before" : ""].") + return + ..() + +/datum/action/innate/slime_place + name = "Place Slimes" + icon_icon = 'icons/mob/actions/actions_silicon.dmi' + button_icon_state = "slime_down" + +/datum/action/innate/slime_place/Activate() + if(!target || !isliving(owner)) + return + var/mob/living/C = owner + var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control + var/obj/machinery/computer/camera_advanced/xenobio/X = target + + if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) + for(var/mob/living/simple_animal/slime/S in X.stored_slimes) + S.forceMove(remote_eye.loc) + S.visible_message("[S] warps in!") + X.stored_slimes -= S + else + to_chat(owner, "Target is not near a camera. Cannot proceed.") + +/datum/action/innate/slime_pick_up + name = "Pick up Slime" + icon_icon = 'icons/mob/actions/actions_silicon.dmi' + button_icon_state = "slime_up" + +/datum/action/innate/slime_pick_up/Activate() + if(!target || !isliving(owner)) + return + var/mob/living/C = owner + var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control + var/obj/machinery/computer/camera_advanced/xenobio/X = target + + if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) + for(var/mob/living/simple_animal/slime/S in remote_eye.loc) + if(X.stored_slimes.len >= X.max_slimes) + break + if(!S.ckey) + if(S.buckled) + S.Feedstop(silent = TRUE) + S.visible_message("[S] vanishes in a flash of light!") + S.forceMove(X) + X.stored_slimes += S + else + to_chat(owner, "Target is not near a camera. Cannot proceed.") + + +/datum/action/innate/feed_slime + name = "Feed Slimes" + icon_icon = 'icons/mob/actions/actions_silicon.dmi' + button_icon_state = "monkey_down" + +/datum/action/innate/feed_slime/Activate() + if(!target || !isliving(owner)) + return + var/mob/living/C = owner + var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control + var/obj/machinery/computer/camera_advanced/xenobio/X = target + + if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) + if(X.monkeys >= 1) + var/mob/living/carbon/monkey/food = new /mob/living/carbon/monkey(remote_eye.loc, TRUE, owner) + if (!QDELETED(food)) + food.LAssailant = C + X.monkeys -- + to_chat(owner, "[X] now has [X.monkeys] monkey(s) left.") + else + to_chat(owner, "[X] needs to have at least 1 monkey stored. Currently has [X.monkeys] monkeys stored.") + else + to_chat(owner, "Target is not near a camera. Cannot proceed.") + + +/datum/action/innate/monkey_recycle + name = "Recycle Monkeys" + icon_icon = 'icons/mob/actions/actions_silicon.dmi' + button_icon_state = "monkey_up" + +/datum/action/innate/monkey_recycle/Activate() + if(!target || !isliving(owner)) + return + var/mob/living/C = owner + var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control + var/obj/machinery/computer/camera_advanced/xenobio/X = target + + if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) + for(var/mob/living/carbon/monkey/M in remote_eye.loc) + if(M.stat) + M.visible_message("[M] vanishes as [p_theyre()] reclaimed for recycling!") + X.monkeys = round(X.monkeys + 0.2,0.1) + qdel(M) + if (X.monkeys == (round(X.monkeys,1))) + to_chat(C, "[X] now has [X.monkeys] monkey(s) available.") + else + to_chat(owner, "Target is not near a camera. Cannot proceed.") + +/datum/action/innate/slime_scan + name = "Scan Slime" + icon_icon = 'icons/mob/actions/actions_silicon.dmi' + button_icon_state = "slime_scan" + +/datum/action/innate/slime_scan/Activate() + if(!target || !isliving(owner)) + return + var/mob/living/C = owner + var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control + + if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) + for(var/mob/living/simple_animal/slime/S in remote_eye.loc) + slime_scan(S, C) + else + to_chat(owner, "Target is not near a camera. Cannot proceed.") + +/datum/action/innate/feed_potion + name = "Apply Potion" + icon_icon = 'icons/mob/actions/actions_silicon.dmi' + button_icon_state = "slime_potion" + +/datum/action/innate/feed_potion/Activate() + if(!target || !isliving(owner)) + return + + var/mob/living/C = owner + var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control + var/obj/machinery/computer/camera_advanced/xenobio/X = target + + if(QDELETED(X.current_potion)) + to_chat(owner, "No potion loaded.") + return + + if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) + for(var/mob/living/simple_animal/slime/S in remote_eye.loc) + X.current_potion.attack(S, C) + break + else + to_chat(owner, "Target is not near a camera. Cannot proceed.") + +/datum/action/innate/hotkey_help + name = "Hotkey Help" + icon_icon = 'icons/mob/actions/actions_silicon.dmi' + button_icon_state = "hotkey_help" + +/datum/action/innate/hotkey_help/Activate() + if(!target || !isliving(owner)) + return + to_chat(owner, "Click shortcuts:") + to_chat(owner, "Shift-click a slime to pick it up, or the floor to drop all held slimes. (Requires Basic Slime Console upgrade)") + to_chat(owner, "Ctrl-click a slime to scan it.") + to_chat(owner, "Alt-click a slime to feed it a potion. (Requires Advanced Slime Console upgrade)") + to_chat(owner, "Ctrl-click on a dead monkey to recycle it, or the floor to place a new monkey. (Requires Monkey Console upgrade)") + +// +// Alternate clicks for slime, monkey and open turf if using a xenobio console + +// Scans slime +/mob/living/simple_animal/slime/CtrlClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_CTRL, src) + ..() + +//Feeds a potion to slime +/mob/living/simple_animal/slime/AltClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_ALT, src) + ..() + +//Picks up slime +/mob/living/simple_animal/slime/ShiftClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_SHIFT, src) + ..() + +//Place slimes +/turf/open/ShiftClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_TURF_CLICK_SHIFT, src) + ..() + +//Place monkey +/turf/open/CtrlClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_TURF_CLICK_CTRL, src) + ..() + +//Pick up monkey +/mob/living/carbon/monkey/CtrlClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_MONKEY_CLICK_CTRL, src) + ..() + +// Scans slime +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickCtrl(mob/living/user, mob/living/simple_animal/slime/S) + if(!GLOB.cameranet.checkTurfVis(S.loc)) + to_chat(user, "Target is not near a camera. Cannot proceed.") + return + var/mob/living/C = user + var/mob/camera/aiEye/remote/xenobio/E = C.remote_control + var/area/mobarea = get_area(S.loc) + if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible) + slime_scan(S, C) + +//Feeds a potion to slime +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickAlt(mob/living/user, mob/living/simple_animal/slime/S) + if(!(upgradetier & XENOBIO_UPGRADE_SLIMEADV)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEADV + to_chat(user, "This console does not have the advanced slime upgrade.") + return + if(!GLOB.cameranet.checkTurfVis(S.loc)) + to_chat(user, "Target is not near a camera. Cannot proceed.") + return + var/mob/living/C = user + var/mob/camera/aiEye/remote/xenobio/E = C.remote_control + var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin + var/area/mobarea = get_area(S.loc) + if(QDELETED(X.current_potion)) + to_chat(C, "No potion loaded.") + return + if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible) + X.current_potion.attack(S, C) + +//Picks up slime +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickShift(mob/living/user, mob/living/simple_animal/slime/S) + if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC + to_chat(user, "This console does not have the basic slime upgrade.") + return + if(!GLOB.cameranet.checkTurfVis(S.loc)) + to_chat(user, "Target is not near a camera. Cannot proceed.") + return + var/mob/living/C = user + var/mob/camera/aiEye/remote/xenobio/E = C.remote_control + var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin + var/area/mobarea = get_area(S.loc) + if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible) + if(X.stored_slimes.len >= X.max_slimes) + to_chat(C, "Slime storage is full.") + return + if(S.ckey) + to_chat(C, "The slime wiggled free!") + return + if(S.buckled) + S.Feedstop(silent = TRUE) + S.visible_message("[S] vanishes in a flash of light!") + S.forceMove(X) + X.stored_slimes += S + +//Place slimes +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickShift(mob/living/user, turf/open/T) + if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC + to_chat(user, "This console does not have the basic slime upgrade.") + return + if(!GLOB.cameranet.checkTurfVis(T)) + to_chat(user, "Target is not near a camera. Cannot proceed.") + return + var/mob/living/C = user + var/mob/camera/aiEye/remote/xenobio/E = C.remote_control + var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin + var/area/turfarea = get_area(T) + if(turfarea.name == E.allowed_area || turfarea.xenobiology_compatible) + for(var/mob/living/simple_animal/slime/S in X.stored_slimes) + S.forceMove(T) + S.visible_message("[S] warps in!") + X.stored_slimes -= S + +//Place monkey +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickCtrl(mob/living/user, turf/open/T) + if(!(upgradetier & XENOBIO_UPGRADE_MONKEYS)) // CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS + to_chat(user, "This console does not have the monkey upgrade.") + return + if(!GLOB.cameranet.checkTurfVis(T)) + to_chat(user, "Target is not near a camera. Cannot proceed.") + return + var/mob/living/C = user + var/mob/camera/aiEye/remote/xenobio/E = C.remote_control + var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin + var/area/turfarea = get_area(T) + if(turfarea.name == E.allowed_area || turfarea.xenobiology_compatible) + if(X.monkeys >= 1) + var/mob/living/carbon/monkey/food = new /mob/living/carbon/monkey(T, TRUE, C) + if (!QDELETED(food)) + food.LAssailant = C + X.monkeys-- + X.monkeys = round(X.monkeys, 0.1) //Prevents rounding errors + to_chat(C, "[X] now has [X.monkeys] monkey(s) stored.") + else + to_chat(C, "[X] needs to have at least 1 monkey stored. Currently has [X.monkeys] monkeys stored.") + +//Pick up monkey +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoMonkeyClickCtrl(mob/living/user, mob/living/carbon/monkey/M) + if(!(upgradetier & XENOBIO_UPGRADE_MONKEYS)) // CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS + to_chat(user, "This console does not have the monkey upgrade.") + return + if(!GLOB.cameranet.checkTurfVis(M.loc)) + to_chat(user, "Target is not near a camera. Cannot proceed.") + return + var/mob/living/C = user + var/mob/camera/aiEye/remote/xenobio/E = C.remote_control + var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin + var/area/mobarea = get_area(M.loc) + if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible) + if(!M.stat) + return + M.visible_message("[M] vanishes as [p_theyre()] reclaimed for recycling!") + X.monkeys = round(X.monkeys + 0.2,0.1) + qdel(M) + if (X.monkeys == (round(X.monkeys,1))) + to_chat(C, "[X] now has [X.monkeys] monkey(s) available.") From 4f7c2279e629feb70f7ca13e3d0cc62c6390e971 Mon Sep 17 00:00:00 2001 From: Weblure Date: Sun, 29 Sep 2019 18:19:43 -0700 Subject: [PATCH 2/7] Delete xenobio_camera.dm --- xenobio_camera.dm | 458 ---------------------------------------------- 1 file changed, 458 deletions(-) delete mode 100644 xenobio_camera.dm diff --git a/xenobio_camera.dm b/xenobio_camera.dm deleted file mode 100644 index 07b25c6de8..0000000000 --- a/xenobio_camera.dm +++ /dev/null @@ -1,458 +0,0 @@ -//Xenobio control console -/mob/camera/aiEye/remote/xenobio - visible_icon = 1 - icon = 'icons/obj/abductor.dmi' - icon_state = "camera_target" - var/allowed_area = null - -/mob/camera/aiEye/remote/xenobio/Initialize() - var/area/A = get_area(loc) - allowed_area = A.name - . = ..() - -/mob/camera/aiEye/remote/xenobio/setLoc(var/t) - var/area/new_area = get_area(t) - if(new_area && new_area.name == allowed_area || new_area && new_area.xenobiology_compatible) - return ..() - else - return - -/obj/machinery/computer/camera_advanced/xenobio - name = "Slime management console" - desc = "A computer used for remotely handling slimes." - networks = list("ss13") - circuit = /obj/item/circuitboard/computer/xenobiology - var/datum/action/innate/slime_place/slime_place_action - var/datum/action/innate/slime_pick_up/slime_up_action - var/datum/action/innate/feed_slime/feed_slime_action - var/datum/action/innate/monkey_recycle/monkey_recycle_action - var/datum/action/innate/slime_scan/scan_action - var/datum/action/innate/feed_potion/potion_action - var/datum/action/innate/hotkey_help/hotkey_help - - var/datum/component/redirect/listener - - var/list/stored_slimes - var/obj/item/slimepotion/slime/current_potion - var/max_slimes = 5 - var/monkeys = 0 - - icon_screen = "slime_comp" - icon_keyboard = "rd_key" - - light_color = LIGHT_COLOR_PINK - -/obj/machinery/computer/camera_advanced/xenobio/Initialize() - . = ..() - slime_place_action = new - slime_up_action = new - feed_slime_action = new - monkey_recycle_action = new - scan_action = new - potion_action = new - hotkey_help = new - stored_slimes = list() - listener = AddComponent(/datum/component/redirect, list(COMSIG_ATOM_CONTENTS_DEL = CALLBACK(src, .proc/on_contents_del))) - -/obj/machinery/computer/camera_advanced/xenobio/Destroy() - stored_slimes = null - QDEL_NULL(current_potion) - for(var/i in contents) - var/mob/living/simple_animal/slime/S = i - if(istype(S)) - S.forceMove(drop_location()) - return ..() - -/obj/machinery/computer/camera_advanced/xenobio/CreateEye() - eyeobj = new /mob/camera/aiEye/remote/xenobio(get_turf(src)) - eyeobj.origin = src - eyeobj.visible_icon = 1 - eyeobj.icon = 'icons/obj/abductor.dmi' - eyeobj.icon_state = "camera_target" - -/obj/machinery/computer/camera_advanced/xenobio/GrantActions(mob/living/user) - ..() - - if(slime_up_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC - slime_up_action.target = src - slime_up_action.Grant(user) - actions += slime_up_action - - if(slime_place_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC - slime_place_action.target = src - slime_place_action.Grant(user) - actions += slime_place_action - - if(feed_slime_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS - feed_slime_action.target = src - feed_slime_action.Grant(user) - actions += feed_slime_action - - if(monkey_recycle_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS - monkey_recycle_action.target = src - monkey_recycle_action.Grant(user) - actions += monkey_recycle_action - - if(scan_action) - scan_action.target = src - scan_action.Grant(user) - actions += scan_action - - if(potion_action && (upgradetier & XENOBIO_UPGRADE_SLIMEADV)) // CIT CHANGE - makes giving slimes potions via console require XENOBIO_UPGRADE_SLIMEADV - potion_action.target = src - potion_action.Grant(user) - actions += potion_action - - if(hotkey_help) - hotkey_help.target = src - hotkey_help.Grant(user) - actions += hotkey_help - - RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL, .proc/XenoSlimeClickCtrl) - RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT, .proc/XenoSlimeClickAlt) - RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT, .proc/XenoSlimeClickShift) - RegisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT, .proc/XenoTurfClickShift) - RegisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL, .proc/XenoTurfClickCtrl) - RegisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL, .proc/XenoMonkeyClickCtrl) - -/obj/machinery/computer/camera_advanced/xenobio/remove_eye_control(mob/living/user) - UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL) - UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT) - UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT) - UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT) - UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL) - UnregisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL) - ..() - -/obj/machinery/computer/camera_advanced/xenobio/proc/on_contents_del(atom/deleted) - if(current_potion == deleted) - current_potion = null - if(deleted in stored_slimes) - stored_slimes -= deleted - -/obj/machinery/computer/camera_advanced/xenobio/attackby(obj/item/O, mob/user, params) - if(istype(O, /obj/item/reagent_containers/food/snacks/monkeycube) && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS - monkeys++ - to_chat(user, "You feed [O] to [src]. It now has [monkeys] monkey cubes stored.") - qdel(O) - return - else if(istype(O, /obj/item/storage/bag) && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS - var/obj/item/storage/P = O - var/loaded = FALSE - for(var/obj/G in P.contents) - if(istype(G, /obj/item/reagent_containers/food/snacks/monkeycube)) - loaded = TRUE - monkeys++ - qdel(G) - if(loaded) - to_chat(user, "You fill [src] with the monkey cubes stored in [O]. [src] now has [monkeys] monkey cubes stored.") - return - else if(istype(O, /obj/item/slimepotion/slime) && (upgradetier & XENOBIO_UPGRADE_SLIMEADV)) // CIT CHANGE - makes giving slimes potions via console require XENOBIO_UPGRADE_SLIMEADV - var/replaced = FALSE - if(user && !user.transferItemToLoc(O, src)) - return - if(!QDELETED(current_potion)) - current_potion.forceMove(drop_location()) - replaced = TRUE - current_potion = O - to_chat(user, "You load [O] in the console's potion slot[replaced ? ", replacing the one that was there before" : ""].") - return - ..() - -/datum/action/innate/slime_place - name = "Place Slimes" - icon_icon = 'icons/mob/actions/actions_silicon.dmi' - button_icon_state = "slime_down" - -/datum/action/innate/slime_place/Activate() - if(!target || !isliving(owner)) - return - var/mob/living/C = owner - var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/X = target - - if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) - for(var/mob/living/simple_animal/slime/S in X.stored_slimes) - S.forceMove(remote_eye.loc) - S.visible_message("[S] warps in!") - X.stored_slimes -= S - else - to_chat(owner, "Target is not near a camera. Cannot proceed.") - -/datum/action/innate/slime_pick_up - name = "Pick up Slime" - icon_icon = 'icons/mob/actions/actions_silicon.dmi' - button_icon_state = "slime_up" - -/datum/action/innate/slime_pick_up/Activate() - if(!target || !isliving(owner)) - return - var/mob/living/C = owner - var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/X = target - - if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) - for(var/mob/living/simple_animal/slime/S in remote_eye.loc) - if(X.stored_slimes.len >= X.max_slimes) - break - if(!S.ckey) - if(S.buckled) - S.Feedstop(silent = TRUE) - S.visible_message("[S] vanishes in a flash of light!") - S.forceMove(X) - X.stored_slimes += S - else - to_chat(owner, "Target is not near a camera. Cannot proceed.") - - -/datum/action/innate/feed_slime - name = "Feed Slimes" - icon_icon = 'icons/mob/actions/actions_silicon.dmi' - button_icon_state = "monkey_down" - -/datum/action/innate/feed_slime/Activate() - if(!target || !isliving(owner)) - return - var/mob/living/C = owner - var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/X = target - - if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) - if(X.monkeys >= 1) - var/mob/living/carbon/monkey/food = new /mob/living/carbon/monkey(remote_eye.loc, TRUE, owner) - if (!QDELETED(food)) - food.LAssailant = C - X.monkeys -- - to_chat(owner, "[X] now has [X.monkeys] monkey(s) left.") - else - to_chat(owner, "[X] needs to have at least 1 monkey stored. Currently has [X.monkeys] monkeys stored.") - else - to_chat(owner, "Target is not near a camera. Cannot proceed.") - - -/datum/action/innate/monkey_recycle - name = "Recycle Monkeys" - icon_icon = 'icons/mob/actions/actions_silicon.dmi' - button_icon_state = "monkey_up" - -/datum/action/innate/monkey_recycle/Activate() - if(!target || !isliving(owner)) - return - var/mob/living/C = owner - var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/X = target - - if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) - for(var/mob/living/carbon/monkey/M in remote_eye.loc) - if(M.stat) - M.visible_message("[M] vanishes as [p_theyre()] reclaimed for recycling!") - X.monkeys = round(X.monkeys + 0.2,0.1) - qdel(M) - if (X.monkeys == (round(X.monkeys,1))) - to_chat(C, "[X] now has [X.monkeys] monkey(s) available.") - else - to_chat(owner, "Target is not near a camera. Cannot proceed.") - -/datum/action/innate/slime_scan - name = "Scan Slime" - icon_icon = 'icons/mob/actions/actions_silicon.dmi' - button_icon_state = "slime_scan" - -/datum/action/innate/slime_scan/Activate() - if(!target || !isliving(owner)) - return - var/mob/living/C = owner - var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control - - if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) - for(var/mob/living/simple_animal/slime/S in remote_eye.loc) - slime_scan(S, C) - else - to_chat(owner, "Target is not near a camera. Cannot proceed.") - -/datum/action/innate/feed_potion - name = "Apply Potion" - icon_icon = 'icons/mob/actions/actions_silicon.dmi' - button_icon_state = "slime_potion" - -/datum/action/innate/feed_potion/Activate() - if(!target || !isliving(owner)) - return - - var/mob/living/C = owner - var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/X = target - - if(QDELETED(X.current_potion)) - to_chat(owner, "No potion loaded.") - return - - if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) - for(var/mob/living/simple_animal/slime/S in remote_eye.loc) - X.current_potion.attack(S, C) - break - else - to_chat(owner, "Target is not near a camera. Cannot proceed.") - -/datum/action/innate/hotkey_help - name = "Hotkey Help" - icon_icon = 'icons/mob/actions/actions_silicon.dmi' - button_icon_state = "hotkey_help" - -/datum/action/innate/hotkey_help/Activate() - if(!target || !isliving(owner)) - return - to_chat(owner, "Click shortcuts:") - to_chat(owner, "Shift-click a slime to pick it up, or the floor to drop all held slimes. (Requires Basic Slime Console upgrade)") - to_chat(owner, "Ctrl-click a slime to scan it.") - to_chat(owner, "Alt-click a slime to feed it a potion. (Requires Advanced Slime Console upgrade)") - to_chat(owner, "Ctrl-click on a dead monkey to recycle it, or the floor to place a new monkey. (Requires Monkey Console upgrade)") - -// -// Alternate clicks for slime, monkey and open turf if using a xenobio console - -// Scans slime -/mob/living/simple_animal/slime/CtrlClick(mob/user) - SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_CTRL, src) - ..() - -//Feeds a potion to slime -/mob/living/simple_animal/slime/AltClick(mob/user) - SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_ALT, src) - ..() - -//Picks up slime -/mob/living/simple_animal/slime/ShiftClick(mob/user) - SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_SHIFT, src) - ..() - -//Place slimes -/turf/open/ShiftClick(mob/user) - SEND_SIGNAL(user, COMSIG_XENO_TURF_CLICK_SHIFT, src) - ..() - -//Place monkey -/turf/open/CtrlClick(mob/user) - SEND_SIGNAL(user, COMSIG_XENO_TURF_CLICK_CTRL, src) - ..() - -//Pick up monkey -/mob/living/carbon/monkey/CtrlClick(mob/user) - SEND_SIGNAL(user, COMSIG_XENO_MONKEY_CLICK_CTRL, src) - ..() - -// Scans slime -/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickCtrl(mob/living/user, mob/living/simple_animal/slime/S) - if(!GLOB.cameranet.checkTurfVis(S.loc)) - to_chat(user, "Target is not near a camera. Cannot proceed.") - return - var/mob/living/C = user - var/mob/camera/aiEye/remote/xenobio/E = C.remote_control - var/area/mobarea = get_area(S.loc) - if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible) - slime_scan(S, C) - -//Feeds a potion to slime -/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickAlt(mob/living/user, mob/living/simple_animal/slime/S) - if(!(upgradetier & XENOBIO_UPGRADE_SLIMEADV)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEADV - to_chat(user, "This console does not have the advanced slime upgrade.") - return - if(!GLOB.cameranet.checkTurfVis(S.loc)) - to_chat(user, "Target is not near a camera. Cannot proceed.") - return - var/mob/living/C = user - var/mob/camera/aiEye/remote/xenobio/E = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin - var/area/mobarea = get_area(S.loc) - if(QDELETED(X.current_potion)) - to_chat(C, "No potion loaded.") - return - if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible) - X.current_potion.attack(S, C) - -//Picks up slime -/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickShift(mob/living/user, mob/living/simple_animal/slime/S) - if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC - to_chat(user, "This console does not have the basic slime upgrade.") - return - if(!GLOB.cameranet.checkTurfVis(S.loc)) - to_chat(user, "Target is not near a camera. Cannot proceed.") - return - var/mob/living/C = user - var/mob/camera/aiEye/remote/xenobio/E = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin - var/area/mobarea = get_area(S.loc) - if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible) - if(X.stored_slimes.len >= X.max_slimes) - to_chat(C, "Slime storage is full.") - return - if(S.ckey) - to_chat(C, "The slime wiggled free!") - return - if(S.buckled) - S.Feedstop(silent = TRUE) - S.visible_message("[S] vanishes in a flash of light!") - S.forceMove(X) - X.stored_slimes += S - -//Place slimes -/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickShift(mob/living/user, turf/open/T) - if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC - to_chat(user, "This console does not have the basic slime upgrade.") - return - if(!GLOB.cameranet.checkTurfVis(T)) - to_chat(user, "Target is not near a camera. Cannot proceed.") - return - var/mob/living/C = user - var/mob/camera/aiEye/remote/xenobio/E = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin - var/area/turfarea = get_area(T) - if(turfarea.name == E.allowed_area || turfarea.xenobiology_compatible) - for(var/mob/living/simple_animal/slime/S in X.stored_slimes) - S.forceMove(T) - S.visible_message("[S] warps in!") - X.stored_slimes -= S - -//Place monkey -/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickCtrl(mob/living/user, turf/open/T) - if(!(upgradetier & XENOBIO_UPGRADE_MONKEYS)) // CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS - to_chat(user, "This console does not have the monkey upgrade.") - return - if(!GLOB.cameranet.checkTurfVis(T)) - to_chat(user, "Target is not near a camera. Cannot proceed.") - return - var/mob/living/C = user - var/mob/camera/aiEye/remote/xenobio/E = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin - var/area/turfarea = get_area(T) - if(turfarea.name == E.allowed_area || turfarea.xenobiology_compatible) - if(X.monkeys >= 1) - var/mob/living/carbon/monkey/food = new /mob/living/carbon/monkey(T, TRUE, C) - if (!QDELETED(food)) - food.LAssailant = C - X.monkeys-- - X.monkeys = round(X.monkeys, 0.1) //Prevents rounding errors - to_chat(C, "[X] now has [X.monkeys] monkey(s) stored.") - else - to_chat(C, "[X] needs to have at least 1 monkey stored. Currently has [X.monkeys] monkeys stored.") - -//Pick up monkey -/obj/machinery/computer/camera_advanced/xenobio/proc/XenoMonkeyClickCtrl(mob/living/user, mob/living/carbon/monkey/M) - if(!(upgradetier & XENOBIO_UPGRADE_MONKEYS)) // CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS - to_chat(user, "This console does not have the monkey upgrade.") - return - if(!GLOB.cameranet.checkTurfVis(M.loc)) - to_chat(user, "Target is not near a camera. Cannot proceed.") - return - var/mob/living/C = user - var/mob/camera/aiEye/remote/xenobio/E = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin - var/area/mobarea = get_area(M.loc) - if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible) - if(!M.stat) - return - M.visible_message("[M] vanishes as [p_theyre()] reclaimed for recycling!") - X.monkeys = round(X.monkeys + 0.2,0.1) - qdel(M) - if (X.monkeys == (round(X.monkeys,1))) - to_chat(C, "[X] now has [X.monkeys] monkey(s) available.") From 1c937f74d6fadbfb51929acf7f0dc8f1fb33fa68 Mon Sep 17 00:00:00 2001 From: Weblure Date: Sun, 29 Sep 2019 18:20:18 -0700 Subject: [PATCH 3/7] Delete components.dm --- components.dm | 284 -------------------------------------------------- 1 file changed, 284 deletions(-) delete mode 100644 components.dm diff --git a/components.dm b/components.dm deleted file mode 100644 index 8e8c7dc55b..0000000000 --- a/components.dm +++ /dev/null @@ -1,284 +0,0 @@ -#define SEND_SIGNAL(target, sigtype, arguments...) ( !target.comp_lookup || !target.comp_lookup[sigtype] ? NONE : target._SendSignal(sigtype, list(target, ##arguments)) ) - -#define SEND_GLOBAL_SIGNAL(sigtype, arguments...) ( SEND_SIGNAL(SSdcs, sigtype, ##arguments) ) - -//shorthand -#define GET_COMPONENT_FROM(varname, path, target) var##path/##varname = ##target.GetComponent(##path) -#define GET_COMPONENT(varname, path) GET_COMPONENT_FROM(varname, path, src) - -#define COMPONENT_INCOMPATIBLE 1 - -// How multiple components of the exact same type are handled in the same datum - -#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default) -#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed -#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted -#define COMPONENT_DUPE_UNIQUE_PASSARGS 4 //old component is given the initialization args of the new - -// All signals. Format: -// When the signal is called: (signal arguments) -// All signals send the source datum of the signal as the first argument - -// global signals -// These are signals which can be listened to by any component on any parent -// start global signals with "!", this used to be necessary but now it's just a formatting choice -#define COMSIG_GLOB_NEW_Z "!new_z" //from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args) -#define COMSIG_GLOB_VAR_EDIT "!var_edit" //called after a successful var edit somewhere in the world: (list/args) -#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special" //global living say plug - use sparingly: (mob/speaker , message) -////////////////////////////////////////////////////////////////// - -// /datum signals -#define COMSIG_COMPONENT_ADDED "component_added" //when a component is added to a datum: (/datum/component) -#define COMSIG_COMPONENT_REMOVING "component_removing" //before a component is removed from a datum because of RemoveComponent: (/datum/component) -#define COMSIG_PARENT_PREQDELETED "parent_preqdeleted" //before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation -#define COMSIG_PARENT_QDELETED "parent_qdeleted" //after a datum's Destroy() is called: (force, qdel_hint), at this point none of the other components chose to interrupt qdel and Destroy has been called - -// /atom signals -#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params) - #define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called -#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human) -#define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob) -#define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name" //from base of atom/get_examine_name(): (/mob, list/overrides) - //Positions for overrides list - #define EXAMINE_POSITION_ARTICLE 1 - #define EXAMINE_POSITION_BEFORE 2 - //End positions - #define COMPONENT_EXNAME_CHANGED 1 -#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable/entering, /atom) -#define COMSIG_ATOM_EXIT "atom_exit" //from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc) - #define COMPONENT_ATOM_BLOCK_EXIT 1 -#define COMSIG_ATOM_EXITED "atom_exited" //from base of atom/Exited(): (atom/movable/exiting, atom/newloc) -#define COMSIG_ATOM_EX_ACT "atom_ex_act" //from base of atom/ex_act(): (severity, target) -#define COMSIG_ATOM_EMP_ACT "atom_emp_act" //from base of atom/emp_act(): (severity) -#define COMSIG_ATOM_FIRE_ACT "atom_fire_act" //from base of atom/fire_act(): (exposed_temperature, exposed_volume) -#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act" //from base of atom/bullet_act(): (/obj/item/projectile, def_zone) -#define COMSIG_ATOM_BLOB_ACT "atom_blob_act" //from base of atom/blob_act(): (/obj/structure/blob) -#define COMSIG_ATOM_ACID_ACT "atom_acid_act" //from base of atom/acid_act(): (acidpwr, acid_volume) -#define COMSIG_ATOM_EMAG_ACT "atom_emag_act" //from base of atom/emag_act(): () -#define COMSIG_ATOM_RAD_ACT "atom_rad_act" //from base of atom/rad_act(intensity) -#define COMSIG_ATOM_NARSIE_ACT "atom_narsie_act" //from base of atom/narsie_act(): () -#define COMSIG_ATOM_RATVAR_ACT "atom_ratvar_act" //from base of atom/ratvar_act(): () -#define COMSIG_ATOM_RCD_ACT "atom_rcd_act" //from base of atom/rcd_act(): (/mob, /obj/item/construction/rcd, passed_mode) -#define COMSIG_ATOM_SING_PULL "atom_sing_pull" //from base of atom/singularity_pull(): (S, current_size) -#define COMSIG_ATOM_SET_LIGHT "atom_set_light" //from base of atom/set_light(): (l_range, l_power, l_color) -#define COMSIG_ATOM_DIR_CHANGE "atom_dir_change" //from base of atom/setDir(): (old_dir, new_dir) -#define COMSIG_ATOM_CONTENTS_DEL "atom_contents_del" //from base of atom/handle_atom_del(): (atom/deleted) -#define COMSIG_ATOM_HAS_GRAVITY "atom_has_gravity" //from base of atom/has_gravity(): (turf/location, list/forced_gravities) -#define COMSIG_ATOM_RAD_PROBE "atom_rad_probe" //from proc/get_rad_contents(): () - #define COMPONENT_BLOCK_RADIATION 1 -#define COMSIG_ATOM_RAD_CONTAMINATING "atom_rad_contam" //from base of datum/radiation_wave/radiate(): (strength) - #define COMPONENT_BLOCK_CONTAMINATION 1 -#define COMSIG_ATOM_RAD_WAVE_PASSING "atom_rad_wave_pass" //from base of datum/radiation_wave/check_obstructions(): (datum/radiation_wave, width) - #define COMPONENT_RAD_WAVE_HANDLED 1 -#define COMSIG_ATOM_CANREACH "atom_can_reach" //from internal loop in atom/movable/proc/CanReach(): (list/next) - #define COMPONENT_BLOCK_REACH 1 -#define COMSIG_ATOM_SCREWDRIVER_ACT "atom_screwdriver_act" //from base of atom/screwdriver_act(): (mob/living/user, obj/item/I) -#define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport" //called when teleporting into a protected turf: (channel, turf/origin) - #define COMPONENT_BLOCK_TELEPORT 1 -///////////////// -#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" //from base of atom/attack_ghost(): (mob/dead/observer/ghost) -#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" //from base of atom/attack_hand(): (mob/user) -#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw" //from base of atom/attack_paw(): (mob/user) - #define COMPONENT_NO_ATTACK_HAND 1 //works on all 3. -///////////////// - -#define COMSIG_ENTER_AREA "enter_area" //from base of area/Entered(): (/area) -#define COMSIG_EXIT_AREA "exit_area" //from base of area/Exited(): (/area) - -#define COMSIG_CLICK "atom_click" //from base of atom/Click(): (location, control, params, mob/user) -#define COMSIG_CLICK_SHIFT "shift_click" //from base of atom/ShiftClick(): (/mob) -#define COMSIG_CLICK_CTRL "ctrl_click" //from base of atom/CtrlClickOn(): (/mob) -#define COMSIG_CLICK_ALT "alt_click" //from base of atom/AltClick(): (/mob) -#define COMSIG_CLICK_CTRL_SHIFT "ctrl_shift_click" //from base of atom/CtrlShiftClick(/mob) -#define COMSIG_MOUSEDROP_ONTO "mousedrop_onto" //from base of atom/MouseDrop(): (/atom/over, /mob/user) - #define COMPONENT_NO_MOUSEDROP 1 -#define COMSIG_MOUSEDROPPED_ONTO "mousedropped_onto" //from base of atom/MouseDrop_T: (/atom/from, /mob/user) - -// /area signals -#define COMSIG_AREA_ENTERED "area_entered" //from base of area/Entered(): (atom/movable/M) -#define COMSIG_AREA_EXITED "area_exited" //from base of area/Exited(): (atom/movable/M) - -// /turf signals -#define COMSIG_TURF_CHANGE "turf_change" //from base of turf/ChangeTurf(): (path, list/new_baseturfs, flags, list/transferring_comps) -#define COMSIG_TURF_HAS_GRAVITY "turf_has_gravity" //from base of atom/has_gravity(): (atom/asker, list/forced_gravities) - -// /atom/movable signals -#define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir) -#define COMSIG_MOVABLE_CROSS "movable_cross" //from base of atom/movable/Cross(): (/atom/movable) -#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable) -#define COMSIG_MOVABLE_UNCROSS "movable_uncross" //from base of atom/movable/Uncross(): (/atom/movable) - #define COMPONENT_MOVABLE_BLOCK_UNCROSS 1 -#define COMSIG_MOVABLE_UNCROSSED "movable_uncrossed" //from base of atom/movable/Uncrossed(): (/atom/movable) -#define COMSIG_MOVABLE_BUMP "movable_bump" //from base of atom/movable/Bump(): (/atom) -#define COMSIG_MOVABLE_IMPACT "movable_impact" //from base of atom/movable/throw_impact(): (/atom/hit_atom, /datum/thrownthing/throwingdatum) -#define COMSIG_MOVABLE_IMPACT_ZONE "item_impact_zone" //from base of mob/living/hitby(): (mob/living/target, hit_zone) -#define COMSIG_MOVABLE_BUCKLE "buckle" //from base of atom/movable/buckle_mob(): (mob, force) -#define COMSIG_MOVABLE_UNBUCKLE "unbuckle" //from base of atom/movable/unbuckle_mob(): (mob, force) -#define COMSIG_MOVABLE_PRE_THROW "movable_pre_throw" //from base of atom/movable/throw_at(): (list/args) - #define COMPONENT_CANCEL_THROW 1 -#define COMSIG_MOVABLE_POST_THROW "movable_post_throw" //from base of atom/movable/throw_at(): (datum/thrownthing, spin) -#define COMSIG_MOVABLE_Z_CHANGED "movable_ztransit" //from base of atom/movable/onTransitZ(): (old_z, new_z) -#define COMSIG_MOVABLE_HEAR "movable_hear" //from base of atom/movable/Hear(): (message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode) -#define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source) - -// /mob signals -#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed) -#define COMSIG_MOB_ALLOWED "mob_allowed" //from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj -#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (magic, holy, protection_sources) - #define COMPONENT_BLOCK_MAGIC 1 -#define COMSIG_MOB_HUD_CREATED "mob_hud_created" //from base of mob/create_mob_hud(): () -#define COMSIG_MOB_ATTACK_HAND "mob_attack_hand" //from base of -#define COMSIG_MOB_ITEM_ATTACK "mob_item_attack" //from base of /obj/item/attack(): (mob/M, mob/user) -#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters) -#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params) -#define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target) -#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): () -#define COMSIG_MOB_SAY "mob_say" // from /mob/living/say(): (proc args list) - #define COMPONENT_UPPERCASE_SPEECH 1 - // used to access COMSIG_MOB_SAY argslist - #define SPEECH_MESSAGE 1 - // #define SPEECH_BUBBLE_TYPE 2 - #define SPEECH_SPANS 3 - /* #define SPEECH_SANITIZE 4 - #define SPEECH_LANGUAGE 5 - #define SPEECH_IGNORE_SPAM 6 - #define SPEECH_FORCED 7 */ - -// /mob/living signals -#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living) -#define COMSIG_LIVING_IGNITED "living_ignite" //from base of mob/living/IgniteMob() (/mob/living) -#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living) -#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage) -#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: () - -// /mob/living/carbon signals -#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity)) - -// /obj signals -#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct" //from base of obj/deconstruct(): (disassembled) -#define COMSIG_OBJ_BREAK "obj_break" //from base of /obj/obj_break(): (damage_flag) -#define COMSIG_OBJ_SETANCHORED "obj_setanchored" //called in /obj/structure/setAnchored(): (value) - - -// /obj/item signals -#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user) -#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob) - #define COMPONENT_NO_INTERACT 1 -#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob) - #define COMPONENT_NO_ATTACK_OBJ 1 -#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack" //from base of obj/item/pre_attack(): (atom/target, mob/user, params) - #define COMPONENT_NO_ATTACK 1 -#define COMSIG_ITEM_AFTERATTACK "item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, params) -#define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot) -#define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (mob/user) -#define COMSIG_ITEM_PICKUP "item_pickup" //from base of obj/item/pickup(): (/mob/taker) -#define COMSIG_ITEM_ATTACK_ZONE "item_attack_zone" //from base of mob/living/carbon/attacked_by(): (mob/living/carbon/target, mob/living/user, hit_zone) -#define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul" //return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/targeted/lichdom/cast(): (mob/user) -#define COMSIG_ITEM_HIT_REACT "item_hit_react" //from base of obj/item/hit_reaction(): (list/args) - -// /obj/item/clothing signals -#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): () - -// /obj/item/implant signals -#define COMSIG_IMPLANT_ACTIVATED "implant_activated" //from base of /obj/item/implant/proc/activate(): () -#define COMSIG_IMPLANT_IMPLANTING "implant_implanting" //from base of /obj/item/implant/proc/implant(): (list/args) - #define COMPONENT_STOP_IMPLANTING 1 -#define COMSIG_IMPLANT_OTHER "implant_other" //called on already installed implants when a new one is being added in /obj/item/implant/proc/implant(): (list/args, obj/item/implant/new_implant) - //#define COMPONENT_STOP_IMPLANTING 1 //The name makes sense for both - #define COMPONENT_DELETE_NEW_IMPLANT 2 - #define COMPONENT_DELETE_OLD_IMPLANT 4 -#define COMSIG_IMPLANT_EXISTING_UPLINK "implant_uplink_exists" //called on implants being implanted into someone with an uplink implant: (datum/component/uplink) - //This uses all return values of COMSIG_IMPLANT_OTHER - -// /obj/item/pda signals -#define COMSIG_PDA_CHANGE_RINGTONE "pda_change_ringtone" //called on pda when the user changes the ringtone: (mob/living/user, new_ringtone) - #define COMPONENT_STOP_RINGTONE_CHANGE 1 - -// /obj/item/radio signals -#define COMSIG_RADIO_NEW_FREQUENCY "radio_new_frequency" //called from base of /obj/item/radio/proc/set_frequency(): (list/args) - -// /obj/item/pen signals -#define COMSIG_PEN_ROTATED "pen_rotated" //called after rotation in /obj/item/pen/attack_self(): (rotation, mob/living/carbon/user) - - -// /mob/living/carbon/human signals -#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target) -#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker) -#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit" //Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted) - -// /datum/species signals -#define COMSIG_SPECIES_GAIN "species_gain" //from datum/species/on_species_gain(): (datum/species/new_species, datum/species/old_species) -#define COMSIG_SPECIES_LOSS "species_loss" //from datum/species/on_species_loss(): (datum/species/lost_species) - -/*******Component Specific Signals*******/ -//Janitor -#define COMSIG_TURF_IS_WET "check_turf_wet" //(): Returns bitflags of wet values. -#define COMSIG_TURF_MAKE_DRY "make_turf_try" //(max_strength, immediate, duration_decrease = INFINITY): Returns bool. -#define COMSIG_COMPONENT_CLEAN_ACT "clean_act" //called on an object to clean it of cleanables. Usualy with soap: (num/strength) - -//Food -#define COMSIG_FOOD_EATEN "food_eaten" //from base of obj/item/reagent_containers/food/snacks/attack(): (mob/living/eater, mob/feeder) - -//Mood -#define COMSIG_ADD_MOOD_EVENT "add_mood" //Called when you send a mood event from anywhere in the code. -#define COMSIG_CLEAR_MOOD_EVENT "clear_mood" //Called when you clear a mood event from anywhere in the code. - -//NTnet -#define COMSIG_COMPONENT_NTNET_RECEIVE "ntnet_receive" //called on an object by its NTNET connection component on receive. (sending_id(number), sending_netname(text), data(datum/netdata)) - -//Nanites -#define COMSIG_HAS_NANITES "has_nanites" //() returns TRUE if nanites are found -#define COMSIG_NANITE_GET_PROGRAMS "nanite_get_programs" //(list/nanite_programs) - makes the input list a copy the nanites' program list -#define COMSIG_NANITE_SET_VOLUME "nanite_set_volume" //(amount) Sets current nanite volume to the given amount -#define COMSIG_NANITE_ADJUST_VOLUME "nanite_adjust" //(amount) Adjusts nanite volume by the given amount -#define COMSIG_NANITE_SET_MAX_VOLUME "nanite_set_max_volume" //(amount) Sets maximum nanite volume to the given amount -#define COMSIG_NANITE_SET_CLOUD "nanite_set_cloud" //(amount(0-100)) Sets cloud ID to the given amount -#define COMSIG_NANITE_SET_SAFETY "nanite_set_safety" //(amount) Sets safety threshold to the given amount -#define COMSIG_NANITE_SET_REGEN "nanite_set_regen" //(amount) Sets regeneration rate to the given amount -#define COMSIG_NANITE_SIGNAL "nanite_signal" //(code(1-9999)) Called when sending a nanite signal to a mob. -#define COMSIG_NANITE_SCAN "nanite_scan" //(mob/user, full_scan) - sends to chat a scan of the nanites to the user, returns TRUE if nanites are detected -#define COMSIG_NANITE_UI_DATA "nanite_ui_data" //(list/data, scan_level) - adds nanite data to the given data list - made for ui_data procs -#define COMSIG_NANITE_ADD_PROGRAM "nanite_add_program" //(datum/nanite_program/new_program, datum/nanite_program/source_program) Called when adding a program to a nanite component - #define COMPONENT_PROGRAM_INSTALLED 1 //Installation successful - #define COMPONENT_PROGRAM_NOT_INSTALLED 2 //Installation failed, but there are still nanites -#define COMSIG_NANITE_SYNC "nanite_sync" //(datum/component/nanites, full_overwrite, copy_activation) Called to sync the target's nanites to a given nanite component - -// /datum/component/storage signals -#define COMSIG_CONTAINS_STORAGE "is_storage" //() - returns bool. -#define COMSIG_TRY_STORAGE_INSERT "storage_try_insert" //(obj/item/inserting, mob/user, silent, force) - returns bool -#define COMSIG_TRY_STORAGE_SHOW "storage_show_to" //(mob/show_to, force) - returns bool. -#define COMSIG_TRY_STORAGE_HIDE_FROM "storage_hide_from" //(mob/hide_from) - returns bool -#define COMSIG_TRY_STORAGE_HIDE_ALL "storage_hide_all" //returns bool -#define COMSIG_TRY_STORAGE_SET_LOCKSTATE "storage_lock_set_state" //(newstate) -#define COMSIG_IS_STORAGE_LOCKED "storage_get_lockstate" //() - returns bool. MUST CHECK IF STORAGE IS THERE FIRST! -#define COMSIG_TRY_STORAGE_TAKE_TYPE "storage_take_type" //(type, atom/destination, amount = INFINITY, check_adjacent, force, mob/user, list/inserted) - returns bool - type can be a list of types. -#define COMSIG_TRY_STORAGE_FILL_TYPE "storage_fill_type" //(type, amount = INFINITY, force = FALSE) //don't fuck this up. Force will ignore max_items, and amount is normally clamped to max_items. -#define COMSIG_TRY_STORAGE_TAKE "storage_take_obj" //(obj, new_loc, force = FALSE) - returns bool -#define COMSIG_TRY_STORAGE_QUICK_EMPTY "storage_quick_empty" //(loc) - returns bool - if loc is null it will dump at parent location. -#define COMSIG_TRY_STORAGE_RETURN_INVENTORY "storage_return_inventory" //(list/list_to_inject_results_into, recursively_search_inside_storages = TRUE) -#define COMSIG_TRY_STORAGE_CAN_INSERT "storage_can_equip" //(obj/item/insertion_candidate, mob/user, silent) - returns bool - -// /datum/action signals -#define COMSIG_ACTION_TRIGGER "action_trigger" //from base of datum/action/proc/Trigger(): (datum/action) - #define COMPONENT_ACTION_BLOCK_TRIGGER 1 - -/*******Non-Signal Component Related Defines*******/ - -//Redirection component init flags -#define REDIRECT_TRANSFER_WITH_TURF 1 - -//Arch -#define ARCH_PROB "probability" //Probability for each item -#define ARCH_MAXDROP "max_drop_amount" //each item's max drop amount - -//Ouch my toes! -#define CALTROP_BYPASS_SHOES 1 -#define CALTROP_IGNORE_WALKERS 2 - -//Xenobio hotkeys -#define COMSIG_XENO_SLIME_CLICK_CTRL "xeno_slime_click_ctrl" //from slime CtrlClickOn(): (/mob) -#define COMSIG_XENO_SLIME_CLICK_ALT "xeno_slime_click_alt" //from slime AltClickOn(): (/mob) -#define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift" //from slime ShiftClickOn(): (/mob) -#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift" //from turf ShiftClickOn(): (/mob) -#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob) -#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob) From ef6db36e4cda5dbd1ad767a1a2911d392843bebf Mon Sep 17 00:00:00 2001 From: Weblure Date: Sun, 29 Sep 2019 18:21:41 -0700 Subject: [PATCH 4/7] Adds Xenobio Hotkeys --- code/__DEFINES/components.dm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 40aea24105..8e8c7dc55b 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -274,3 +274,11 @@ //Ouch my toes! #define CALTROP_BYPASS_SHOES 1 #define CALTROP_IGNORE_WALKERS 2 + +//Xenobio hotkeys +#define COMSIG_XENO_SLIME_CLICK_CTRL "xeno_slime_click_ctrl" //from slime CtrlClickOn(): (/mob) +#define COMSIG_XENO_SLIME_CLICK_ALT "xeno_slime_click_alt" //from slime AltClickOn(): (/mob) +#define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift" //from slime ShiftClickOn(): (/mob) +#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift" //from turf ShiftClickOn(): (/mob) +#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob) +#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob) From da1209cc8bb20927145d1a7d55c19a54f74a4e35 Mon Sep 17 00:00:00 2001 From: Weblure Date: Sun, 29 Sep 2019 18:23:19 -0700 Subject: [PATCH 5/7] Adds Xenobio Console hotkeys Includes some minor tweaks to existing coding --- .../research/xenobiology/xenobio_camera.dm | 208 +++++++++++++++++- 1 file changed, 199 insertions(+), 9 deletions(-) diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 5aebd1bafa..07b25c6de8 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -28,6 +28,7 @@ var/datum/action/innate/monkey_recycle/monkey_recycle_action var/datum/action/innate/slime_scan/scan_action var/datum/action/innate/feed_potion/potion_action + var/datum/action/innate/hotkey_help/hotkey_help var/datum/component/redirect/listener @@ -49,6 +50,7 @@ monkey_recycle_action = new scan_action = new potion_action = new + hotkey_help = new stored_slimes = list() listener = AddComponent(/datum/component/redirect, list(COMSIG_ATOM_CONTENTS_DEL = CALLBACK(src, .proc/on_contents_del))) @@ -101,6 +103,27 @@ potion_action.Grant(user) actions += potion_action + if(hotkey_help) + hotkey_help.target = src + hotkey_help.Grant(user) + actions += hotkey_help + + RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL, .proc/XenoSlimeClickCtrl) + RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT, .proc/XenoSlimeClickAlt) + RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT, .proc/XenoSlimeClickShift) + RegisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT, .proc/XenoTurfClickShift) + RegisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL, .proc/XenoTurfClickCtrl) + RegisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL, .proc/XenoMonkeyClickCtrl) + +/obj/machinery/computer/camera_advanced/xenobio/remove_eye_control(mob/living/user) + UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL) + UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT) + UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT) + UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT) + UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL) + UnregisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL) + ..() + /obj/machinery/computer/camera_advanced/xenobio/proc/on_contents_del(atom/deleted) if(current_potion == deleted) current_potion = null @@ -154,7 +177,7 @@ S.visible_message("[S] warps in!") X.stored_slimes -= S else - to_chat(owner, "Target is not near a camera. Cannot proceed.") + to_chat(owner, "Target is not near a camera. Cannot proceed.") /datum/action/innate/slime_pick_up name = "Pick up Slime" @@ -179,7 +202,7 @@ S.forceMove(X) X.stored_slimes += S else - to_chat(owner, "Target is not near a camera. Cannot proceed.") + to_chat(owner, "Target is not near a camera. Cannot proceed.") /datum/action/innate/feed_slime @@ -200,9 +223,11 @@ if (!QDELETED(food)) food.LAssailant = C X.monkeys -- - to_chat(owner, "[X] now has [X.monkeys] monkeys left.") + to_chat(owner, "[X] now has [X.monkeys] monkey(s) left.") + else + to_chat(owner, "[X] needs to have at least 1 monkey stored. Currently has [X.monkeys] monkeys stored.") else - to_chat(owner, "Target is not near a camera. Cannot proceed.") + to_chat(owner, "Target is not near a camera. Cannot proceed.") /datum/action/innate/monkey_recycle @@ -220,11 +245,13 @@ if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) for(var/mob/living/carbon/monkey/M in remote_eye.loc) if(M.stat) - M.visible_message("[M] vanishes as [M.p_theyre()] reclaimed for recycling!") + M.visible_message("[M] vanishes as [p_theyre()] reclaimed for recycling!") X.monkeys = round(X.monkeys + 0.2,0.1) qdel(M) + if (X.monkeys == (round(X.monkeys,1))) + to_chat(C, "[X] now has [X.monkeys] monkey(s) available.") else - to_chat(owner, "Target is not near a camera. Cannot proceed.") + to_chat(owner, "Target is not near a camera. Cannot proceed.") /datum/action/innate/slime_scan name = "Scan Slime" @@ -241,7 +268,7 @@ for(var/mob/living/simple_animal/slime/S in remote_eye.loc) slime_scan(S, C) else - to_chat(owner, "Target is not near a camera. Cannot proceed.") + to_chat(owner, "Target is not near a camera. Cannot proceed.") /datum/action/innate/feed_potion name = "Apply Potion" @@ -257,7 +284,7 @@ var/obj/machinery/computer/camera_advanced/xenobio/X = target if(QDELETED(X.current_potion)) - to_chat(owner, "No potion loaded.") + to_chat(owner, "No potion loaded.") return if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) @@ -265,4 +292,167 @@ X.current_potion.attack(S, C) break else - to_chat(owner, "Target is not near a camera. Cannot proceed.") + to_chat(owner, "Target is not near a camera. Cannot proceed.") + +/datum/action/innate/hotkey_help + name = "Hotkey Help" + icon_icon = 'icons/mob/actions/actions_silicon.dmi' + button_icon_state = "hotkey_help" + +/datum/action/innate/hotkey_help/Activate() + if(!target || !isliving(owner)) + return + to_chat(owner, "Click shortcuts:") + to_chat(owner, "Shift-click a slime to pick it up, or the floor to drop all held slimes. (Requires Basic Slime Console upgrade)") + to_chat(owner, "Ctrl-click a slime to scan it.") + to_chat(owner, "Alt-click a slime to feed it a potion. (Requires Advanced Slime Console upgrade)") + to_chat(owner, "Ctrl-click on a dead monkey to recycle it, or the floor to place a new monkey. (Requires Monkey Console upgrade)") + +// +// Alternate clicks for slime, monkey and open turf if using a xenobio console + +// Scans slime +/mob/living/simple_animal/slime/CtrlClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_CTRL, src) + ..() + +//Feeds a potion to slime +/mob/living/simple_animal/slime/AltClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_ALT, src) + ..() + +//Picks up slime +/mob/living/simple_animal/slime/ShiftClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_SHIFT, src) + ..() + +//Place slimes +/turf/open/ShiftClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_TURF_CLICK_SHIFT, src) + ..() + +//Place monkey +/turf/open/CtrlClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_TURF_CLICK_CTRL, src) + ..() + +//Pick up monkey +/mob/living/carbon/monkey/CtrlClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_MONKEY_CLICK_CTRL, src) + ..() + +// Scans slime +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickCtrl(mob/living/user, mob/living/simple_animal/slime/S) + if(!GLOB.cameranet.checkTurfVis(S.loc)) + to_chat(user, "Target is not near a camera. Cannot proceed.") + return + var/mob/living/C = user + var/mob/camera/aiEye/remote/xenobio/E = C.remote_control + var/area/mobarea = get_area(S.loc) + if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible) + slime_scan(S, C) + +//Feeds a potion to slime +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickAlt(mob/living/user, mob/living/simple_animal/slime/S) + if(!(upgradetier & XENOBIO_UPGRADE_SLIMEADV)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEADV + to_chat(user, "This console does not have the advanced slime upgrade.") + return + if(!GLOB.cameranet.checkTurfVis(S.loc)) + to_chat(user, "Target is not near a camera. Cannot proceed.") + return + var/mob/living/C = user + var/mob/camera/aiEye/remote/xenobio/E = C.remote_control + var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin + var/area/mobarea = get_area(S.loc) + if(QDELETED(X.current_potion)) + to_chat(C, "No potion loaded.") + return + if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible) + X.current_potion.attack(S, C) + +//Picks up slime +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickShift(mob/living/user, mob/living/simple_animal/slime/S) + if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC + to_chat(user, "This console does not have the basic slime upgrade.") + return + if(!GLOB.cameranet.checkTurfVis(S.loc)) + to_chat(user, "Target is not near a camera. Cannot proceed.") + return + var/mob/living/C = user + var/mob/camera/aiEye/remote/xenobio/E = C.remote_control + var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin + var/area/mobarea = get_area(S.loc) + if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible) + if(X.stored_slimes.len >= X.max_slimes) + to_chat(C, "Slime storage is full.") + return + if(S.ckey) + to_chat(C, "The slime wiggled free!") + return + if(S.buckled) + S.Feedstop(silent = TRUE) + S.visible_message("[S] vanishes in a flash of light!") + S.forceMove(X) + X.stored_slimes += S + +//Place slimes +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickShift(mob/living/user, turf/open/T) + if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC + to_chat(user, "This console does not have the basic slime upgrade.") + return + if(!GLOB.cameranet.checkTurfVis(T)) + to_chat(user, "Target is not near a camera. Cannot proceed.") + return + var/mob/living/C = user + var/mob/camera/aiEye/remote/xenobio/E = C.remote_control + var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin + var/area/turfarea = get_area(T) + if(turfarea.name == E.allowed_area || turfarea.xenobiology_compatible) + for(var/mob/living/simple_animal/slime/S in X.stored_slimes) + S.forceMove(T) + S.visible_message("[S] warps in!") + X.stored_slimes -= S + +//Place monkey +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickCtrl(mob/living/user, turf/open/T) + if(!(upgradetier & XENOBIO_UPGRADE_MONKEYS)) // CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS + to_chat(user, "This console does not have the monkey upgrade.") + return + if(!GLOB.cameranet.checkTurfVis(T)) + to_chat(user, "Target is not near a camera. Cannot proceed.") + return + var/mob/living/C = user + var/mob/camera/aiEye/remote/xenobio/E = C.remote_control + var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin + var/area/turfarea = get_area(T) + if(turfarea.name == E.allowed_area || turfarea.xenobiology_compatible) + if(X.monkeys >= 1) + var/mob/living/carbon/monkey/food = new /mob/living/carbon/monkey(T, TRUE, C) + if (!QDELETED(food)) + food.LAssailant = C + X.monkeys-- + X.monkeys = round(X.monkeys, 0.1) //Prevents rounding errors + to_chat(C, "[X] now has [X.monkeys] monkey(s) stored.") + else + to_chat(C, "[X] needs to have at least 1 monkey stored. Currently has [X.monkeys] monkeys stored.") + +//Pick up monkey +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoMonkeyClickCtrl(mob/living/user, mob/living/carbon/monkey/M) + if(!(upgradetier & XENOBIO_UPGRADE_MONKEYS)) // CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS + to_chat(user, "This console does not have the monkey upgrade.") + return + if(!GLOB.cameranet.checkTurfVis(M.loc)) + to_chat(user, "Target is not near a camera. Cannot proceed.") + return + var/mob/living/C = user + var/mob/camera/aiEye/remote/xenobio/E = C.remote_control + var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin + var/area/mobarea = get_area(M.loc) + if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible) + if(!M.stat) + return + M.visible_message("[M] vanishes as [p_theyre()] reclaimed for recycling!") + X.monkeys = round(X.monkeys + 0.2,0.1) + qdel(M) + if (X.monkeys == (round(X.monkeys,1))) + to_chat(C, "[X] now has [X.monkeys] monkey(s) available.") From 0a793754a2c22f0c560ed032a9c8d74c7779afd2 Mon Sep 17 00:00:00 2001 From: Weblure Date: Tue, 1 Oct 2019 22:30:36 -0700 Subject: [PATCH 6/7] Updates actions_silicon.dmi to include hotkey_help Adds icon for the hotkey_help button added to the xenobio console. --- icons/mob/actions/actions_silicon.dmi | Bin 7018 -> 7695 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/mob/actions/actions_silicon.dmi b/icons/mob/actions/actions_silicon.dmi index cd997a25ac12f7c89d0e2f80a277d2de33d9c8a3..cf3d7a2a95607a98715bb7aeb0de9c7fd47d1530 100644 GIT binary patch literal 7695 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 XR$WbwN9^~gKfHi4OijK*)-2?IXm7G+ literal 7018 zcmW+*1zc3m6MsiH+`-Y^N{R5JBu+Y|L%O@WIgoBdN>Wm!QA%1$KuSQ6=I9oIqv3!4 zKcBa6K5yUb&g|^$erI;$G+rqX;!)!P06?guD655{MW_PD!9u+gtt@F!WHV65z+2YF z%gWQi-P^&<6#)G6GSc{6`<@ZV+3k_ZHd4#c*vx8);E1#8li(yI&lr?5J;n9BB`7c? zYxO zlw_p5?)es@Co?Fka!-2ywJab*P26N}&vmwRXXwkw2qo!kHm`X`#e{fTyFy$C(FCOl zg9fWIG*@ZlWX+UIokg-Y!a>!F`pksNe>2?c6P0#=RZ1LR z=#Lve#D?IDrGL>6}PCUl0el#*wI;3RJIz?T~dJs9J-LO3bb=Q z*#dfX*-f4g%+kkFg(L)EtkEYTw+}=K=5{_34PWe=-f@^M(5z#Opl9OUh3)4BPqZK; zOBBJZ-ZFPCQu87=4-sga@q>$INfpfASuk9_pa+keVGd%81M0OMT{-8Q7ePcHbV@#S zUzg+XSQ+`xnV%eWoQ4+66AO)ZJtn$R1~rg?0=z(7A~9T{7i&~cN#uAhx3$%6(SVN} z0;gx6n4L}f4hu(-AxR(g+>1KqtBX77&V_%l->bctTnSyBcXM)T|2;Q16e^TE_AE!0 z^XXG%pG#wLkQixB3-ftXEHSM}Pv8s!fq>sX+y7$t38l-{n7b*G~myH7>EVFe}k4}ZwzeuU^GaGh{R@Q zk`oXSG4t`Mpa18tQYkM(VS^@@bLah*eMT(*=>J_x-X4C&!N+Go9Q>D~+6e?ciQg~d z{6qn(`|TY4+j+3oq}}~+z9H9g{0RAZEr~{GEnQuTFdk?{pu>k4!t$1hFv_S2JADW@ zT)1)XLNYPfLk_4P=&fokleJ^m7Jg+M^}%-kGysfBe| z9}li7^{MpIQJdwey`VIEItV!IA6iaE&hTwHvttJ?`+(BfbX z7)IPU#qBV3JwSl^S=*R-S7&EgQ&ak`d!!K=8Cg+L5r7hT_q0o8M79qZVXwPjxz*Xr-oPXMfJU$RPIz5cpp>gu^ zmTMRjl*r3mq8r@rRZ#vIwMsC#MO?o05htP*Svzyhsd0iA->H&;{7*|#cEeu$7GRm+ z3%gbcKBJ!&Z^}cubSpkPJh%uhD0sc1&a<5>E! z$Zsm(kkDgyZvBw(RZ`H$4LZD@-=ZBM5b1c|u(%T~o^C{!rSPL6->l;aU()~vfA_|QiK8$*PdmYQ0* zE#y{cyg(wsq}{iH?x*zXYK?2Q7mbhzw6OaL%0hQMU8vs4+5)5_IA`tcRnW9qLrpcq zTbuEMQKZHxdnBw<{%SksYluR%NxRU+=5YF^m9mZwnS-(HZyta)VFD};`WmRkBo8Ey z^XFm-xJ%%Gd&>+7$DsXbpH;2Q2V8k{D`vG6#>eSyktAT$G%o_$9p$oeat))ClNuwa zqHJepH?rOrBbPw@2l2XIz;r|@bxn!|)4o07I!!(MA;d3+(5i`Mhu--)*Qhc>fVJbZQleeA+ukl>=~c5y z^c!VCFQs6N<0K9T>)U+8$Dj)H#moOt`>I*2U2WWi?$%0HMwr<`OE+<8GCkhqpaa)@ z?z*;@TJUE&PX-yKV0f&2Y$uM4kLA}$tEIM>@WHKq@1W92+Rs@U+!;&cMUjzwX~kAb z7*HiRNLC{agA=U73R1>^b`!||dAH$KZQJhu@O;b)hTC$%*U@h#>S0? z2f`ZEbvvL8qA`5qEbC^{wK&Kodsc9?5EBP1?lvLy6FQo}fh)v|CIw@6^vWH{9rmX{ zf5>m;{mv1aA_hqd#%>C#HgDG-xJ?l(sjM8X+3@u8ntG_x71$4ct3c=?i$7_0x*loo z=qRnOP8=8*2mr}gs`i4^0L;*k`u+R&Bs-Nar8Eo-6d5D}bsRx$Fddfu!qauysp)C- z8odLJU|{}U_Txj5`6#|?`()w$q1`!RAOZAD`utjMjL8^pauvn=Vb<~Gw4kApk*205 zC`rCAP@ESEg}##8C&V-|Ez06n^HYg5YH=-lGD%5E3A3$<^HQ&ao6CJWRL{g!lNL0oy-apqeVFb&N?%R%0l$OZfrqEGbO(Uto+&UP@A z>7-)#S3myNthEyYzqtd(!J`_DQfa`l*Lsc>fsOFk`AJuyuP$Ki zL*XCNA7%l;we`=oWAssTqCU7JV_A%si!Jn0==ptn)1Vp?zb2;B5*Zd&HkN|5H7jY) zEhK%&UJ%hoEcNaN0~2MFBWW)Ws|R_HUz)xSl+@JHc6J>5`}<2odNL&Yp5XK>?>QY^ z-4CBWjgU@rYvN%xyDZ927*P^kBNPoD)1t)$Fe|wzEQWu2m)06%_}JndcM0O6$hY+D z)z2v4o2O&>VJol_bRsdLeH!o+dw5`4@_Pgi-{i^yxznl*OaDK2NXyLJu0KhEAuGzt zPJeoNd4YP4h60e^w>(jgIAu^ zC}1A?1@cR2qR=Vm|1!qiE%h@}cV~%V)ghWmB)K?lE3F>rb=?nvcs*y)tpVwK4ou(B z*D|hvwX!TzPcA7ijec-jTbsyVxu(y3w8c74`NhQW+Kk6%Ruf^Z;nHn>^+42F*>ZFNN+go0)lrIPh1@UUJA(jd|EW3~BMHA|Z9kjKBLP z`Yw0K`}@txtM6(CBz1_gQF$A9ux%)_B(IfUqH9x8ND`k|UmV5xW>9R?3DTY0jG)a^ z{$rx)hi}%gNl8%WPBF)+ry0u4&_jH22hl~pXcn-u-POO%5OOQ)X7Vb!?r?JD0(vmict!#^YkZI!%ur{-dPC&MQ%E2g9J z?%`y;$AcBQd3mM4WOLJ^e~>tZYsh$x-I+p_K5rH}mhB7VhJh+2$DcnDHa!u0;(Zc* zvG*e6ekV&&&a4FJ>EH6##qx=|A1>;aZ^AIXh4$DEfTyAigT?GANTl|f!?d&@fQRX`Nuqg2U*kSZ zUyS;EHErv}VFQh$#nxkCVa-RS=I0Xvii(ObUtgj2SE{O!6)Vq}nSVYP6N|5`d}4aj z5%2{KXmmHj;EL>6Uo%fFz*M=4 z4i5(<@-6VT*4YujSU)FIiyUUqA?~f4Kj>PlYsXhtbMM~Vf`AHU*Qv(F?hQJxPdD9r zKKDfcBNrF`&P1WUs#ZjHY;EN_v@c&>?^?KO+M(=f@|;9VI<(vM+1_J+Gss#0w;hC*&e5 zCk2xNC|oU=-|STgn(h*7Rw<<=RqZsT378z?+JFH1 zpE!;Jn4{xU_iX~X?G*Q~mgY?(suIBR?@S}*~krB%Qzl}k{FU`$} zww;1ET9wuV3V%H(tX3P@73opD0-c#ZW@eXb0C?%9HSi-ng+>^4+;LJFTieZGvb1MWH&8CUH56I{aLO&T-l9}3 zy2+S#85vWxm7|D8h6|&F+#i@irL}9#_pQ+4%Rv z7Z#K;fy0%~Io2;~?wQR&m!_nEd&`l>JRXr=u-L7WqM~X9$K3j8*1*inj0QF_{l5f? zh+Z70(=;VqSew5{WuPaw5+!Ht_|h(|TCb`h@WS!qtYfdu#r~}6;#wf=!_ocizUuAe zY)<4)AZA}fKza3k;Jt;%`IL3mhi`7|>%_Od@IjZd&!a0P}CG7AQ8#=}{n$dJi@pWcSC$;oG6$0q9h{Cth7S$hWu3koxw6d1L>bOC|+ zzJKW}VR1`yDX(e8uD^ft@!nX>tS>@PG4m7`-r?o-felaZm%{XP89Qrh^N>)C3Z z(>gm@Z23f#EiCGM|5ZMJ{ydmhvPMtEq|FmEBqZeU=g*%JNi@QZD6GYId(7a{7k^KR zrW(|au0P^b?J%aGTVj`+J!U~Ng%#NVX1R)>-X=9k$m_=`6_;lS)wDa-rjya{cFr+5c*mH2eecxq`$b!&5T@+p+G zzN5T6+R@&=2xLB#OsDhuHP!OuBy0}l&!xNhE{M+x_7An)BxH=jlC(fSGdcbaUw^DC zMl=rk<&jeM7gcEx=DA5=fB&-!GzbIHpTi)G#V!)$z*C1kPs}Ip+?w4H{SDVl;P)G$ z3F;h~|MWbV{SL#p1>qvES@Q&B;G1#i!jgG>9&B)PRMb^9#pmVYohX$SL5fM`w-P5z zktQ#zf&n#UVWrH_h`XiHgNG*)w>W6`X0uA;_Pi8UW!&gn=CgJZJa-P1lPk(*g7KfO z_cOCg=2g6V_ihrtN-&A^Bo{MBDs+m)5%1u#v9Wn8C}0ET zTO%2QfS{n@+VOHb=aVNN*udlT7?_-73`Bsuf{!y?`md!eDuuB|CmS4OA0sI)IW<4l z($bPHyk9;+!GwaA=W|q0Uw_vy1OWQArgA1G`K;ewM-~A`8-1Xj&3AGQ+!A!6ZEd@U zhh*Zvx#~J1w#(VQef+q-^=+~P?oftty4Wk6v9Yo0E5R@!bd8Psk6rNCKi;!grs@F? z1?p_QL2y)OLnp-hZd`x}lmYPe^=0M|ra4<28@C(gnS8|e7+Y8PNt8zr`-O3dC2FF|-ot7e%6$2!50ZmhNV0W3ZPSyonKl?lxl9aOgS=a)zQ^se!(&1LIdfQ zd529qvx)`W>6G*qKAy012?qVl8mLDwq?R>rAg$G6fGR7-)2g|D459qeTDef-M3;-Y(s`zy~(`L9$k< z{b-}6sMu)zsrJdj#c8?fY-+IygIjzYh#>mq0Q)O21!=lD8vN7IqQAPlr6ojlXX23< z?*ES+C_*u!d4~oJ(%KhD{vnWXb7QSGQ%9XAGkpJZ9&WeGmr#~j-!4*#PQ;}BUumnW ziKQXQP&vM&qt`nk)HwK?DVbL;&>`~C`C03=$RK?E;Pa!s3OOAu)N&+tH^8Qq?@-g} z+8aHC@^#)l*LeNJU?!P>c%v-K3~3~s$Z`q-Ae4;cZYrmObKTKWm?>U&O`@C53D&Mk2>5(x&mE)Zmv$w}S zD9W-ASMIC#CO_Rk&e^+Pzx1jNoA7FCP=SqZm0kmaWuT!u9>JIJ2$L`w7Jr0Vr&7_% z9F#LcyAd8D^duz7=o~syWXdcJTc4^{pJ!y9==2W`-jovI0NvMfS!oyU;8YOu%T4BtE&Q6ifqm4pBIC*#obK;a_t!2I6UfF(& z-p0`j7ExzJCym5`o_Y*#V`P4zSiPrzFH?_0baCDOf%CcDzk3luJ_AZqcjhO83TtWN mjMz$)kZ}39 From 4ca5841828ea9c2661b009688af447402bf27dc9 Mon Sep 17 00:00:00 2001 From: Weblure Date: Tue, 29 Oct 2019 21:45:36 -0700 Subject: [PATCH 7/7] Fixed an invalid variable call in a string [p_theyre()] to [M.p_theyre()] --- code/modules/research/xenobiology/xenobio_camera.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 07b25c6de8..35d2a3577a 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -245,7 +245,7 @@ if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) for(var/mob/living/carbon/monkey/M in remote_eye.loc) if(M.stat) - M.visible_message("[M] vanishes as [p_theyre()] reclaimed for recycling!") + M.visible_message("[M] vanishes as [M.p_theyre()] reclaimed for recycling!") X.monkeys = round(X.monkeys + 0.2,0.1) qdel(M) if (X.monkeys == (round(X.monkeys,1)))