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.
This commit is contained in:
+284
@@ -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)
|
||||
@@ -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, "<span class='notice'>You feed [O] to [src]. It now has [monkeys] monkey cubes stored.</span>")
|
||||
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, "<span class='notice'>You fill [src] with the monkey cubes stored in [O]. [src] now has [monkeys] monkey cubes stored.</span>")
|
||||
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, "<span class='notice'>You load [O] in the console's potion slot[replaced ? ", replacing the one that was there before" : ""].</span>")
|
||||
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, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
/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, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
|
||||
/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, "<span class='notice'>[X] now has [X.monkeys] monkey(s) left.</span>")
|
||||
else
|
||||
to_chat(owner, "<span class='warning'>[X] needs to have at least 1 monkey stored. Currently has [X.monkeys] monkeys stored.</span>")
|
||||
else
|
||||
to_chat(owner, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
|
||||
/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, "<span class='notice'>[X] now has [X.monkeys] monkey(s) available.</span>")
|
||||
else
|
||||
to_chat(owner, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
/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, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
/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, "<span class='warning'>No potion loaded.</span>")
|
||||
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, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
/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, "<b>Click shortcuts:</b>")
|
||||
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, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
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, "<span class='warning'>This console does not have the advanced slime upgrade.</span>")
|
||||
return
|
||||
if(!GLOB.cameranet.checkTurfVis(S.loc))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
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, "<span class='warning'>No potion loaded.</span>")
|
||||
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, "<span class='warning'>This console does not have the basic slime upgrade.</span>")
|
||||
return
|
||||
if(!GLOB.cameranet.checkTurfVis(S.loc))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
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, "<span class='warning'>Slime storage is full.</span>")
|
||||
return
|
||||
if(S.ckey)
|
||||
to_chat(C, "<span class='warning'>The slime wiggled free!</span>")
|
||||
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, "<span class='warning'>This console does not have the basic slime upgrade.</span>")
|
||||
return
|
||||
if(!GLOB.cameranet.checkTurfVis(T))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
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, "<span class='warning'>This console does not have the monkey upgrade.</span>")
|
||||
return
|
||||
if(!GLOB.cameranet.checkTurfVis(T))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
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, "<span class='notice'>[X] now has [X.monkeys] monkey(s) stored.</span>")
|
||||
else
|
||||
to_chat(C, "<span class='warning'>[X] needs to have at least 1 monkey stored. Currently has [X.monkeys] monkeys stored.</span>")
|
||||
|
||||
//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, "<span class='warning'>This console does not have the monkey upgrade.</span>")
|
||||
return
|
||||
if(!GLOB.cameranet.checkTurfVis(M.loc))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
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, "<span class='notice'>[X] now has [X.monkeys] monkey(s) available.</span>")
|
||||
Reference in New Issue
Block a user