diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index bab1e65d..c16c95e0 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -31,16 +31,12 @@ #define COMSIG_ATOM_RATVAR_ACT "atom_ratvar_act" //from base of atom/ratvar_act(): () ///////////////// - - // /area signals // /turf signals // /atom/movable signals -// /mob signals - // /mob/living signals // /mob/living/carbon signals diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index fbee222f..4036bab9 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -180,21 +180,17 @@ ///from base of area/Exited(): (/area) #define COMSIG_EXIT_AREA "exit_area" ///from base of atom/Click(): (location, control, params, mob/user) -#define COMSIG_CLICK "atom_click" -///from base of atom/ShiftClick(): (/mob) -#define COMSIG_CLICK_SHIFT "shift_click" - #define COMPONENT_ALLOW_EXAMINATE (1<<0) //Allows the user to examinate regardless of client.eye. -///from base of atom/CtrlClickOn(): (/mob) -#define COMSIG_CLICK_CTRL "ctrl_click" -///from base of atom/AltClick(): (/mob) -#define COMSIG_CLICK_ALT "alt_click" -///from base of atom/CtrlShiftClick(/mob) -#define COMSIG_CLICK_CTRL_SHIFT "ctrl_shift_click" -///from base of atom/MouseDrop(): (/atom/over, /mob/user) -#define COMSIG_MOUSEDROP_ONTO "mousedrop_onto" - #define COMPONENT_NO_MOUSEDROP (1<<0) -///from base of atom/MouseDrop_T: (/atom/from, /mob/user) -#define COMSIG_MOUSEDROPPED_ONTO "mousedropped_onto" +#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 COMPONENT_ALLOW_EXAMINATE 1 + #define COMPONENT_DENY_EXAMINATE 2 //Higher priority compared to the above one + +#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" // /area signals @@ -264,13 +260,42 @@ #define COMSIG_MOVABLE_TELEPORTED "movable_teleported" //from base of do_teleport(): (channel, turf/origin, turf/destination) // /mob signals +// /mob signals +#define COMSIG_MOB_EXAMINATE "mob_examinate" //from base of /mob/verb/examinate(): (atom/A) +#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed) + #define COMPONENT_BLOCK_DEATH_BROADCAST 1 //stops the death from being broadcasted in deadchat. +#define COMSIG_MOB_GHOSTIZE "mob_ghostize" //from base of mob/Ghostize(): (can_reenter_corpse, special, penalize) + #define COMPONENT_BLOCK_GHOSTING 1 +#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(): (mob/user, magic, holy, tinfoil, chargecost, self, 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 COMPONENT_ITEM_NO_ATTACK 1 +#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_KEY_CHANGE "mob_key_change" //from base of /mob/transfer_ckey(): (new_character, old_character) +#define COMSIG_MOB_PRE_PLAYER_CHANGE "mob_pre_player_change" //sent to the target mob from base of /mob/transfer_ckey() and /mind/transfer_to(): (our_character, their_character) +// #define COMPONENT_STOP_MIND_TRANSFER 1 +#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): () +#define COMSIG_MOB_ON_NEW_MIND "mob_on_new_mind" //called when a new mind is assigned to a mob: () +#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 */ ///from base of /mob/Login(): () #define COMSIG_MOB_LOGIN "mob_login" ///from base of /mob/Logout(): () #define COMSIG_MOB_LOGOUT "mob_logout" -///from base of mob/death(): (gibbed) -#define COMSIG_MOB_DEATH "mob_death" ///from base of mob/set_stat(): (new_stat) #define COMSIG_MOB_STATCHANGE "mob_statchange" ///from base of mob/clickon(): (atom/A, params) @@ -280,50 +305,12 @@ ///from base of mob/AltClickOn(): (atom/A) #define COMSIG_MOB_ALTCLICKON "mob_altclickon" #define COMSIG_MOB_CANCEL_CLICKON (1<<0) - -///from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj -#define COMSIG_MOB_ALLOWED "mob_allowed" -///from base of mob/anti_magic_check(): (mob/user, magic, holy, tinfoil, chargecost, self, protection_sources) -#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" - #define COMPONENT_BLOCK_MAGIC (1<<0) -///from base of mob/create_mob_hud(): () -#define COMSIG_MOB_HUD_CREATED "mob_hud_created" -///from base of atom/attack_hand(): (mob/user) -#define COMSIG_MOB_ATTACK_HAND "mob_attack_hand" -///from base of /obj/item/attack(): (mob/M, mob/user) -#define COMSIG_MOB_ITEM_ATTACK "mob_item_attack" - #define COMPONENT_ITEM_NO_ATTACK (1<<0) ///from base of /mob/living/proc/apply_damage(): (damage, damagetype, def_zone) #define COMSIG_MOB_APPLY_DAMGE "mob_apply_damage" -///from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters) -#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" ///from base of obj/item/attack_qdeleted(): (atom/target, mob/user, proxiumity_flag, click_parameters) -#define COMSIG_MOB_ITEM_ATTACK_QDELETED "mob_item_attack_qdeleted" -///from base of mob/RangedAttack(): (atom/A, params) -#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" -///from base of /mob/throw_item(): (atom/target) -#define COMSIG_MOB_THROW "mob_throw" -#define COMSIG_MOB_KEY_CHANGE "mob_key_change" //from base of /mob/transfer_ckey(): (new_character, old_character) -#define COMSIG_MOB_PRE_PLAYER_CHANGE "mob_pre_player_change" //sent to the target mob from base of /mob/transfer_ckey() and /mind/transfer_to(): (our_character, their_character) -#define COMSIG_MOB_GHOSTIZE "mob_ghostize" //from base of mob/Ghostize(): (can_reenter_corpse, special, penalize) - #define COMPONENT_BLOCK_GHOSTING (1<<0) +#define COMSIG_MOB_ITEM_ATTACK_QDELETED "mob_item_attack_qdeleted" //from base of /mob/transfer_ckey(): (new_character, old_character) #define COMPONENT_DO_NOT_PENALIZE_GHOSTING (1<<1) #define COMPONENT_FREE_GHOSTING (1<<2) -///from base of /mob/verb/examinate(): (atom/target) -#define COMSIG_MOB_EXAMINATE "mob_examinate" -///from base of /mob/update_sight(): () -#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" -////from /mob/living/say(): () -#define COMSIG_MOB_SAY "mob_say" - #define COMPONENT_UPPERCASE_SPEECH (1<<0) - // 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 */ ///from /mob/say_dead(): (mob/speaker, message) #define COMSIG_MOB_DEADSAY "mob_deadsay" diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index e59aafda..8b5a754d 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -315,9 +315,10 @@ /mob/proc/ShiftClickOn(atom/A) A.ShiftClick(src) return + /atom/proc/ShiftClick(mob/user) - SEND_SIGNAL(src, COMSIG_CLICK_SHIFT, user) - if(user.client && user.client.eye == user || user.client.eye == user.loc) + var/flags = SEND_SIGNAL(src, COMSIG_CLICK_SHIFT, user) + if(!(flags & COMPONENT_DENY_EXAMINATE) && user.client && (user.client.eye == user || user.client.eye == user.loc || flags & COMPONENT_ALLOW_EXAMINATE)) user.examinate(src) return diff --git a/code/datums/elements/mob_holder.dm b/code/datums/elements/mob_holder.dm new file mode 100644 index 00000000..a63be406 --- /dev/null +++ b/code/datums/elements/mob_holder.dm @@ -0,0 +1,184 @@ +/datum/element/mob_holder + element_flags = ELEMENT_BESPOKE + id_arg_index = 2 + var/worn_state + var/alt_worn + var/right_hand + var/left_hand + var/inv_slots + var/proctype //if present, will be invoked on headwear generation. + +/datum/element/mob_holder/Attach(datum/target, _worn_state, _alt_worn, _right_hand, _left_hand, _inv_slots = NONE, _proctype) + . = ..() + + if(!isliving(target)) + return ELEMENT_INCOMPATIBLE + + worn_state = _worn_state + alt_worn = _alt_worn + right_hand = _right_hand + left_hand = _left_hand + inv_slots = _inv_slots + proctype = _proctype + + RegisterSignal(target, COMSIG_CLICK_ALT, .proc/mob_try_pickup) + RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_examine) + +/datum/element/mob_holder/Detach(datum/source, force) + . = ..() + UnregisterSignal(source, COMSIG_CLICK_ALT) + UnregisterSignal(source, COMSIG_PARENT_EXAMINE) + +/datum/element/mob_holder/proc/on_examine(mob/living/source, mob/user, list/examine_list) + if(ishuman(user) && !istype(source.loc, /obj/item/clothing/head/mob_holder)) + examine_list += "Looks like [source.p_they(TRUE)] can be picked up with Alt+Click!" + +/datum/element/mob_holder/proc/mob_try_pickup(mob/living/source, mob/user) + if(!ishuman(user) || !user.Adjacent(source) || user.incapacitated()) + return FALSE + if(user.get_active_held_item()) + to_chat(user, "Your hands are full!") + return FALSE + if(source.buckled) + to_chat(user, "[src] is buckled to something!") + return FALSE + if(source == user) + to_chat(user, "You can't pick yourself up.") + return FALSE + source.visible_message("[user] starts picking up [source].", \ + "[user] starts picking you up!") + if(!do_after(user, 20, target = source) || source.buckled) + return FALSE + + source.visible_message("[user] picks up [source]!", \ + "[user] picks you up!") + to_chat(user, "You pick [src] up.") + source.drop_all_held_items() + var/obj/item/clothing/head/mob_holder/holder = new(get_turf(source), source, worn_state, alt_worn, right_hand, left_hand, inv_slots) + if(proctype) + INVOKE_ASYNC(src, proctype, source, holder, user) + user.put_in_hands(holder) + return TRUE + +/datum/element/mob_holder/proc/drone_worn_icon(mob/living/simple_animal/drone/D, obj/item/clothing/head/mob_holder/holder, mob/user) + var/new_state = "[D.visualAppearence]_hat" + holder.item_state = new_state + holder.icon_state = new_state + + +//The item itself, +/obj/item/clothing/head/mob_holder + name = "bugged mob" + desc = "Yell at coderbrush." + icon = null + alternate_worn_icon = 'icons/mob/animals_held.dmi' + righthand_file = 'icons/mob/animals_held_rh.dmi' + lefthand_file = 'icons/mob/animals_held_lh.dmi' + icon_state = "" + w_class = WEIGHT_CLASS_BULKY + var/mob/living/held_mob + +/obj/item/clothing/head/mob_holder/Initialize(mapload, mob/living/target, worn_state, alt_worn, right_hand, left_hand, slots = NONE) + . = ..() + + if(target) + assimilate(target) + + if(alt_worn) + alternate_worn_icon = alt_worn + if(worn_state) + item_state = worn_state + icon_state = worn_state + if(left_hand) + lefthand_file = left_hand + if(right_hand) + righthand_file = right_hand + slot_flags = slots + +/obj/item/clothing/head/mob_holder/proc/assimilate(mob/living/target) + target.setDir(SOUTH) + held_mob = target + target.forceMove(src) + var/image/I = new //work around to retain the same appearance to the mob idependently from inhands/worn states. + I.appearance = target.appearance + I.override = TRUE + add_overlay(I) + name = target.name + desc = target.desc + switch(target.mob_size) + if(MOB_SIZE_TINY) + w_class = WEIGHT_CLASS_TINY + if(MOB_SIZE_SMALL) + w_class = WEIGHT_CLASS_NORMAL + if(MOB_SIZE_LARGE) + w_class = WEIGHT_CLASS_HUGE + RegisterSignal(src, COMSIG_CLICK_SHIFT, .proc/examine_held_mob) + +/obj/item/clothing/head/mob_holder/Destroy() + if(held_mob) + release() + return ..() + +/obj/item/clothing/head/mob_holder/proc/examine_held_mob(datum/source, mob/user) + held_mob.ShiftClick(user) + return COMPONENT_DENY_EXAMINATE + +/obj/item/clothing/head/mob_holder/Exited(atom/movable/AM, atom/newloc) + . = ..() + if(AM == held_mob) + held_mob.reset_perspective() + held_mob = null + qdel(src) + +/obj/item/clothing/head/mob_holder/Entered(atom/movable/AM, atom/newloc) + . = ..() + if(AM != held_mob) + var/destination = loc + if(isliving(loc)) //the mob is held or worn, drop things on the floor + destination = get_turf(loc) + AM.forceMove(destination) + +/obj/item/clothing/head/mob_holder/dropped() + . = ..() + if(held_mob && isturf(loc))//don't release on soft-drops + release() + +/obj/item/clothing/head/mob_holder/proc/release() + if(held_mob) + var/mob/living/L = held_mob + held_mob = null + L.forceMove(get_turf(L)) + L.reset_perspective() + L.setDir(SOUTH) + qdel(src) + +/obj/item/clothing/head/mob_holder/relaymove(mob/user) + return + +/obj/item/clothing/head/mob_holder/container_resist() + if(isliving(loc)) + var/mob/living/L = loc + L.visible_message("[src] escapes from [L]!", "[src] escapes your grip!") + release() + +/obj/item/clothing/head/mob_holder/assume_air(datum/gas_mixture/env) + var/atom/location = loc + if(!loc) + return //null + var/turf/T = get_turf(loc) + while(location != T) + location = location.loc + if(ismob(location)) + return location.loc.assume_air(env) + return loc.assume_air(env) + +/obj/item/clothing/head/mob_holder/remove_air(amount) + var/atom/location = loc + if(!loc) + return //null + var/turf/T = get_turf(loc) + while(location != T) + location = location.loc + if(ismob(location)) + return location.loc.remove_air(amount) + return loc.remove_air(amount) diff --git a/code/datums/elements/wuv.dm b/code/datums/elements/wuv.dm index bac7d1ff..55bc9baf 100644 --- a/code/datums/elements/wuv.dm +++ b/code/datums/elements/wuv.dm @@ -30,6 +30,10 @@ RegisterSignal(target, COMSIG_MOB_ATTACK_HAND, .proc/on_attack_hand) +/datum/element/wuv/Detach(datum/source, force) + . = ..() + UnregisterSignal(source, COMSIG_MOB_ATTACK_HAND) + /datum/element/wuv/proc/on_attack_hand(datum/source, mob/user) var/mob/living/L = source diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index b05b796c..b36a2b95 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -16,10 +16,6 @@ msg += "[t_He] [t_is] wearing [wear_mask.get_examine_string(user)] on [t_his] face.\n" if (wear_neck) msg += "[t_He] [t_is] wearing [wear_neck.get_examine_string(user)] around [t_his] neck.\n" - if(can_be_held) - msg += "[t_He] might be able to be picked up with Alt+Click!\n" - - for(var/obj/item/I in held_items) if(!(I.item_flags & ABSTRACT)) @@ -111,7 +107,7 @@ msg += "[t_He] look[p_s()] very happy.\n" if(MOOD_LEVEL_HAPPY4 to INFINITY) msg += "[t_He] look[p_s()] ecstatic.\n" + SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, msg) msg += "*---------*" - to_chat(user, msg) return msg diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index e017ec34..03259bd2 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -399,6 +399,7 @@ msg += "...?
" else msg += "[print_flavor_text()]\n" + SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, msg) msg += "*---------*" to_chat(user, msg) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index fbbfe1bc..65259212 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1110,7 +1110,8 @@ race = /datum/species/krokodil_addict //define holder_type on nerds we wanna commit scoop to -/mob/living/carbon/human +/* /mob/living/carbon/human var/holder_type = /obj/item/clothing/head/mob_holder/micro can_be_held = "micro" +*/ diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 47a177f7..54fddea2 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -1,176 +1,175 @@ -/mob/living/carbon/monkey - name = "monkey" - verb_say = "chimpers" - initial_language_holder = /datum/language_holder/monkey - icon = 'icons/mob/monkey.dmi' - icon_state = "" - gender = NEUTER - pass_flags = PASSTABLE - ventcrawler = VENTCRAWLER_NUDE - mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID) - butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1) - type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/monkey - gib_type = /obj/effect/decal/cleanable/blood/gibs - unique_name = TRUE - bodyparts = list(/obj/item/bodypart/chest/monkey, /obj/item/bodypart/head/monkey, /obj/item/bodypart/l_arm/monkey, - /obj/item/bodypart/r_arm/monkey, /obj/item/bodypart/r_leg/monkey, /obj/item/bodypart/l_leg/monkey) - hud_type = /datum/hud/monkey - can_be_held = "monkey" - -/mob/living/carbon/monkey/Initialize(mapload, cubespawned=FALSE, mob/spawner) - verbs += /mob/living/proc/mob_sleep - verbs += /mob/living/proc/lay_down - - if(unique_name) //used to exclude pun pun - gender = pick(MALE, FEMALE) - real_name = name - - //initialize limbs - create_bodyparts() - create_internal_organs() - - . = ..() - - if (cubespawned) - var/cap = CONFIG_GET(number/monkeycap) - if (LAZYLEN(SSmobs.cubemonkeys) > cap) - if (spawner) - to_chat(spawner, "Bluespace harmonics prevent the spawning of more than [cap] monkeys on the station at one time!") - return INITIALIZE_HINT_QDEL - SSmobs.cubemonkeys += src - - create_dna(src) - dna.initialize_dna(random_blood_type()) - -/mob/living/carbon/monkey/Destroy() - SSmobs.cubemonkeys -= src - return ..() - -/mob/living/carbon/monkey/generate_mob_holder() - var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, "monkey", 'icons/mob/animals_held.dmi', 'icons/mob/animals_held_lh.dmi', 'icons/mob/animals_held_rh.dmi', TRUE) - return holder - -/mob/living/carbon/monkey/create_internal_organs() - internal_organs += new /obj/item/organ/appendix - internal_organs += new /obj/item/organ/lungs - internal_organs += new /obj/item/organ/heart - internal_organs += new /obj/item/organ/brain - internal_organs += new /obj/item/organ/tongue - internal_organs += new /obj/item/organ/eyes - internal_organs += new /obj/item/organ/ears - internal_organs += new /obj/item/organ/liver - internal_organs += new /obj/item/organ/stomach - ..() - -/mob/living/carbon/monkey/on_reagent_change() - . = ..() - remove_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE) - var/amount - if(reagents.has_reagent("morphine")) - amount = -1 - if(reagents.has_reagent("nuka_cola")) - amount = -1 - if(amount) - add_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount) - -/mob/living/carbon/monkey/updatehealth() - . = ..() - var/slow = 0 - var/health_deficiency = (100 - health) - if(health_deficiency >= 45) - slow += (health_deficiency / 25) - add_movespeed_modifier(MOVESPEED_ID_MONKEY_HEALTH_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = slow) - -/mob/living/carbon/monkey/adjust_bodytemperature(amount) - . = ..() - var/slow = 0 - if (bodytemperature < 283.222) - slow += (283.222 - bodytemperature) / 10 * 1.75 - if(slow <= 0) - return - add_movespeed_modifier(MOVESPEED_ID_MONKEY_TEMPERATURE_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount) - -/mob/living/carbon/monkey/Stat() - ..() - if(statpanel("Status")) - stat(null, "Intent: [a_intent]") - stat(null, "Move Mode: [m_intent]") - if(client && mind) - var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling) - if(changeling) - stat("Chemical Storage", "[changeling.chem_charges]/[changeling.chem_storage]") - stat("Absorbed DNA", changeling.absorbedcount) - return - - -/mob/living/carbon/monkey/verb/removeinternal() - set name = "Remove Internals" - set category = "IC" - internal = null - return - - -/mob/living/carbon/monkey/IsAdvancedToolUser()//Unless its monkey mode monkeys cant use advanced tools - if(mind && is_monkey(mind)) - return TRUE - return FALSE - -/mob/living/carbon/monkey/reagent_check(datum/reagent/R) //can metabolize all reagents - return FALSE - -/mob/living/carbon/monkey/canBeHandcuffed() - return TRUE - -/mob/living/carbon/monkey/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) - if(judgement_criteria & JUDGE_EMAGGED) - return 10 //Everyone is a criminal! - - var/threatcount = 0 - - //Securitrons can't identify monkeys - if( !(judgement_criteria & JUDGE_IGNOREMONKEYS) && (judgement_criteria & JUDGE_IDCHECK) ) - threatcount += 4 - - //Lasertag bullshit - if(lasercolor) - if(lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve - if(is_holding_item_of_type(/obj/item/gun/energy/laser/redtag)) - threatcount += 4 - - if(lasercolor == "r") - if(is_holding_item_of_type(/obj/item/gun/energy/laser/bluetag)) - threatcount += 4 - - return threatcount - - //Check for weapons - if( (judgement_criteria & JUDGE_WEAPONCHECK) && weaponcheck ) - for(var/obj/item/I in held_items) //if they're holding a gun - if(weaponcheck.Invoke(I)) - threatcount += 4 - if(weaponcheck.Invoke(back)) //if a weapon is present in the back slot - threatcount += 4 //trigger look_for_perp() since they're nonhuman and very likely hostile - - //mindshield implants imply trustworthyness - if(HAS_TRAIT(src, TRAIT_MINDSHIELD)) - threatcount -= 1 - - return threatcount - -/mob/living/carbon/monkey/IsVocal() - if(!getorganslot(ORGAN_SLOT_LUNGS)) - return 0 - return 1 - -/mob/living/carbon/monkey/can_use_guns(obj/item/G) - return TRUE - -/mob/living/carbon/monkey/angry - aggressive = TRUE - -/mob/living/carbon/monkey/angry/Initialize() - . = ..() - if(prob(10)) - var/obj/item/clothing/head/helmet/justice/escape/helmet = new(src) - equip_to_slot_or_del(helmet,SLOT_HEAD) - helmet.attack_self(src) // todo encapsulate toggle +/mob/living/carbon/monkey + name = "monkey" + verb_say = "chimpers" + initial_language_holder = /datum/language_holder/monkey + icon = 'icons/mob/monkey.dmi' + icon_state = "" + gender = NEUTER + pass_flags = PASSTABLE + ventcrawler = VENTCRAWLER_NUDE + mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID) + butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1) + type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/monkey + gib_type = /obj/effect/decal/cleanable/blood/gibs + unique_name = TRUE + bodyparts = list(/obj/item/bodypart/chest/monkey, /obj/item/bodypart/head/monkey, /obj/item/bodypart/l_arm/monkey, + /obj/item/bodypart/r_arm/monkey, /obj/item/bodypart/r_leg/monkey, /obj/item/bodypart/l_leg/monkey) + hud_type = /datum/hud/monkey + +/mob/living/carbon/monkey/Initialize(mapload, cubespawned=FALSE, mob/spawner) + verbs += /mob/living/proc/mob_sleep + verbs += /mob/living/proc/lay_down + + if(unique_name) //used to exclude pun pun + gender = pick(MALE, FEMALE) + real_name = name + + //initialize limbs + create_bodyparts() + create_internal_organs() + + . = ..() + + if (cubespawned) + var/cap = CONFIG_GET(number/monkeycap) + if (LAZYLEN(SSmobs.cubemonkeys) > cap) + if (spawner) + to_chat(spawner, "Bluespace harmonics prevent the spawning of more than [cap] monkeys on the station at one time!") + return INITIALIZE_HINT_QDEL + SSmobs.cubemonkeys += src + + create_dna(src) + dna.initialize_dna(random_blood_type()) + +/mob/living/carbon/monkey/ComponentInitialize() + . = ..() + AddElement(/datum/element/mob_holder, "monkey", null, null, null, SLOT_HEAD) + +/mob/living/carbon/monkey/Destroy() + SSmobs.cubemonkeys -= src + return ..() + +/mob/living/carbon/monkey/create_internal_organs() + internal_organs += new /obj/item/organ/appendix + internal_organs += new /obj/item/organ/lungs + internal_organs += new /obj/item/organ/heart + internal_organs += new /obj/item/organ/brain + internal_organs += new /obj/item/organ/tongue + internal_organs += new /obj/item/organ/eyes + internal_organs += new /obj/item/organ/ears + internal_organs += new /obj/item/organ/liver + internal_organs += new /obj/item/organ/stomach + ..() + +/mob/living/carbon/monkey/on_reagent_change() + . = ..() + remove_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE) + var/amount + if(reagents.has_reagent("morphine")) + amount = -1 + if(reagents.has_reagent("nuka_cola")) + amount = -1 + if(amount) + add_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount) + +/mob/living/carbon/monkey/updatehealth() + . = ..() + var/slow = 0 + var/health_deficiency = (100 - health) + if(health_deficiency >= 45) + slow += (health_deficiency / 25) + add_movespeed_modifier(MOVESPEED_ID_MONKEY_HEALTH_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = slow) + +/mob/living/carbon/monkey/adjust_bodytemperature(amount) + . = ..() + var/slow = 0 + if (bodytemperature < 283.222) + slow += (283.222 - bodytemperature) / 10 * 1.75 + if(slow <= 0) + return + add_movespeed_modifier(MOVESPEED_ID_MONKEY_TEMPERATURE_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount) + +/mob/living/carbon/monkey/Stat() + ..() + if(statpanel("Status")) + stat(null, "Intent: [a_intent]") + stat(null, "Move Mode: [m_intent]") + if(client && mind) + var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling) + if(changeling) + stat("Chemical Storage", "[changeling.chem_charges]/[changeling.chem_storage]") + stat("Absorbed DNA", changeling.absorbedcount) + return + + +/mob/living/carbon/monkey/verb/removeinternal() + set name = "Remove Internals" + set category = "IC" + internal = null + return + + +/mob/living/carbon/monkey/IsAdvancedToolUser()//Unless its monkey mode monkeys cant use advanced tools + if(mind && is_monkey(mind)) + return TRUE + return FALSE + +/mob/living/carbon/monkey/reagent_check(datum/reagent/R) //can metabolize all reagents + return FALSE + +/mob/living/carbon/monkey/canBeHandcuffed() + return TRUE + +/mob/living/carbon/monkey/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) + if(judgement_criteria & JUDGE_EMAGGED) + return 10 //Everyone is a criminal! + + var/threatcount = 0 + + //Securitrons can't identify monkeys + if( !(judgement_criteria & JUDGE_IGNOREMONKEYS) && (judgement_criteria & JUDGE_IDCHECK) ) + threatcount += 4 + + //Lasertag bullshit + if(lasercolor) + if(lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve + if(is_holding_item_of_type(/obj/item/gun/energy/laser/redtag)) + threatcount += 4 + + if(lasercolor == "r") + if(is_holding_item_of_type(/obj/item/gun/energy/laser/bluetag)) + threatcount += 4 + + return threatcount + + //Check for weapons + if( (judgement_criteria & JUDGE_WEAPONCHECK) && weaponcheck ) + for(var/obj/item/I in held_items) //if they're holding a gun + if(weaponcheck.Invoke(I)) + threatcount += 4 + if(weaponcheck.Invoke(back)) //if a weapon is present in the back slot + threatcount += 4 //trigger look_for_perp() since they're nonhuman and very likely hostile + + //mindshield implants imply trustworthyness + if(HAS_TRAIT(src, TRAIT_MINDSHIELD)) + threatcount -= 1 + + return threatcount + +/mob/living/carbon/monkey/IsVocal() + if(!getorganslot(ORGAN_SLOT_LUNGS)) + return 0 + return 1 + +/mob/living/carbon/monkey/can_use_guns(obj/item/G) + return TRUE + +/mob/living/carbon/monkey/angry + aggressive = TRUE + +/mob/living/carbon/monkey/angry/Initialize() + . = ..() + if(prob(10)) + var/obj/item/clothing/head/helmet/justice/escape/helmet = new(src) + equip_to_slot_or_del(helmet,SLOT_HEAD) + helmet.attack_self(src) // todo encapsulate toggle diff --git a/code/modules/mob/living/inhand_holder.dm b/code/modules/mob/living/inhand_holder.dm deleted file mode 100644 index e68260de..00000000 --- a/code/modules/mob/living/inhand_holder.dm +++ /dev/null @@ -1,129 +0,0 @@ -//Generic system for picking up mobs. -//Currently works for head and hands. -/obj/item/clothing/head/mob_holder - name = "bugged mob" - desc = "Yell at coderbrush." - icon = null - icon_state = "" - var/mob/living/held_mob - var/can_head = FALSE - w_class = WEIGHT_CLASS_BULKY - -/obj/item/clothing/head/mob_holder/Initialize(mapload, mob/living/M, _worn_state, alt_worn, lh_icon, rh_icon, _can_head_override = FALSE) - . = ..() - - if(M) - M.setDir(SOUTH) - held_mob = M - M.forceMove(src) - appearance = M.appearance - name = M.name - desc = M.desc - - if(_can_head_override) - can_head = _can_head_override - if(alt_worn) - alternate_worn_icon = alt_worn - if(_worn_state) - item_state = _worn_state - icon_state = _worn_state - if(lh_icon) - lefthand_file = lh_icon - if(rh_icon) - righthand_file = rh_icon - if(!can_head) - slot_flags = NONE - -/obj/item/clothing/head/mob_holder/Destroy() - if(held_mob) - release() - return ..() - -/obj/item/clothing/head/mob_holder/dropped() - ..() - if(isturf(loc))//don't release on soft-drops - release() - -/obj/item/clothing/head/mob_holder/proc/release() - if(isliving(loc)) - var/mob/living/L = loc - L.dropItemToGround(src) - if(held_mob) - var/mob/living/m = held_mob - m.forceMove(get_turf(m)) - m.reset_perspective() - m.setDir(SOUTH) - held_mob = null - qdel(src) - -/obj/item/clothing/head/mob_holder/relaymove(mob/user) - return - -/obj/item/clothing/head/mob_holder/container_resist() - if(isliving(loc)) - var/mob/living/L = loc - visible_message("[src] escapes [L]!") - release() - -/mob/living/proc/mob_pickup(mob/living/L) - var/obj/item/clothing/head/mob_holder/holder = generate_mob_holder() - if(!holder) - return - drop_all_held_items() - L.put_in_hands(holder) - return - -/mob/living/proc/mob_try_pickup(mob/living/user) - if(!ishuman(user) || !src.Adjacent(user) || user.incapacitated() || !can_be_held) - return FALSE - if(src.can_be_held == "micro") - return FALSE - if(user.get_active_held_item()) - to_chat(user, "Your hands are full!") - return FALSE - if(buckled) - to_chat(user, "[src] is buckled to something!") - return FALSE - if(src == user) - to_chat(user, "You can't pick yourself up.") - return FALSE - visible_message("[user] starts picking up [src].", \ - "[user] starts picking you up!") - if(!do_after(user, 20, target = src)) - return FALSE - - if(user.get_active_held_item()||buckled) - return FALSE - - visible_message("[user] picks up [src]!", \ - "[user] picks you up!") - to_chat(user, "You pick [src] up.") - mob_pickup(user) - return TRUE - -/mob/living/AltClick(mob/user) - . = ..() - if(mob_try_pickup(user)) - return TRUE - -/obj/item/clothing/head/mob_holder/assume_air(datum/gas_mixture/env) - var/atom/location = loc - if(!loc) - return //null - var/turf/T = get_turf(loc) - while(location != T) - location = location.loc - if(ismob(location)) - return location.loc.assume_air(env) - return location.assume_air(env) - -/obj/item/clothing/head/mob_holder/remove_air(amount) - var/atom/location = loc - if(!loc) - return //null - var/turf/T = get_turf(loc) - while(location != T) - location = location.loc - if(ismob(location)) - return location.loc.remove_air(amount) - return location.remove_air(amount) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 2ba4be99..4c400ee4 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -40,14 +40,6 @@ QDEL_LIST(diseases) return ..() - -/mob/living/proc/generate_mob_holder() - if(ishuman(src)) - var/obj/item/clothing/head/mob_holder/micro/holder = new(get_turf(src), src, (istext(can_be_held) ? can_be_held : ""), 'icons/mob/animals_held.dmi', 'icons/mob/animals_held_lh.dmi', 'icons/mob/animals_held_rh.dmi') - return holder - var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, (istext(can_be_held) ? can_be_held : ""), 'icons/mob/animals_held.dmi', 'icons/mob/animals_held_lh.dmi', 'icons/mob/animals_held_rh.dmi') - return holder - /mob/living/onZImpact(turf/T, levels) if(!isgroundlessturf(T)) ZImpactDamage(T, levels) @@ -1153,8 +1145,6 @@ return if(!over.Adjacent(src) || (user != src) || !canUseTopic(over)) return - if(can_be_held) - mob_try_pickup(over) /mob/living/proc/get_static_viruses() //used when creating blood and other infective objects diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index d283a4fa..9d346a44 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -107,7 +107,7 @@ var/last_words //used for database logging var/list/obj/effect/proc_holder/abilities = list() - + var/can_be_held = FALSE var/radiation = 0 //If the mob is irradiated. diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 1601ccfe..c298d89c 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -11,7 +11,7 @@ health = 500 maxHealth = 500 layer = BELOW_MOB_LAYER - can_be_held = TRUE + var/datum/element/mob_holder/current_mob_holder //because only a few of their chassis can be actually held. var/network = "ss13" var/obj/machinery/camera/current = null @@ -58,10 +58,12 @@ var/canholo = TRUE var/obj/item/card/id/access_card = null var/chassis = "repairbot" + var/dynamic_chassis + var/dynamic_chassis_sit = FALSE //whether we're sitting instead of resting spritewise + var/dynamic_chassis_bellyup = FALSE //whether we're lying down bellyup var/list/possible_chassis = list("cat" = TRUE, "mouse" = TRUE, "monkey" = TRUE, "corgi" = FALSE, "fox" = FALSE, "repairbot" = TRUE, "rabbit" = TRUE, "operator" = TRUE) //assoc value is whether it can be picked up. - var/static/item_head_icon = 'icons/mob/pai_item_head.dmi' - var/static/item_lh_icon = 'icons/mob/pai_item_lh.dmi' - var/static/item_rh_icon = 'icons/mob/pai_item_rh.dmi' + var/list/dynamic_chassis_icons //ditto. + var/list/chassis_pixel_offsets_x //stupid dogborgs var/emitterhealth = 20 var/emittermaxhealth = 20 diff --git a/code/modules/mob/living/silicon/pai/pai_shell.dm b/code/modules/mob/living/silicon/pai/pai_shell.dm index 164a3e73..bf625f67 100644 --- a/code/modules/mob/living/silicon/pai/pai_shell.dm +++ b/code/modules/mob/living/silicon/pai/pai_shell.dm @@ -86,6 +86,12 @@ if(resting) icon_state = "[chassis]_rest" to_chat(src, "You switch your holochassis projection composite to [chassis]") + if(possible_chassis[chassis]) + current_mob_holder = AddElement(/datum/element/mob_holder, chassis, 'icons/mob/pai_item_head.dmi', 'icons/mob/pai_item_rh.dmi', 'icons/mob/pai_item_lh.dmi', SLOT_HEAD) + else + current_mob_holder?.Detach(src) + current_mob_holder = null + return /mob/living/silicon/pai/lay_down() ..() @@ -109,16 +115,3 @@ else set_light(0) to_chat(src, "You disable your integrated light.") - -/mob/living/silicon/pai/mob_pickup(mob/living/L) - var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, chassis, item_head_icon, item_lh_icon, item_rh_icon) - if(!L.put_in_hands(holder)) - qdel(holder) - else - L.visible_message("[L] scoops up [src]!") - -/mob/living/silicon/pai/mob_try_pickup(mob/living/user) - if(!possible_chassis[chassis]) - to_chat(user, "[src]'s current form isn't able to be carried!") - return FALSE - return ..() diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index b3cb4ec4..5ea3eed5 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -31,9 +31,9 @@ var/mob/living/simple_animal/mouse/movement_target gold_core_spawnable = FRIENDLY_SPAWN collar_type = "cat" - can_be_held = "cat2" size_multiplier = 0.5 + var/held_icon = "cat2" do_footstep = TRUE /mob/living/simple_animal/pet/cat/Initialize() @@ -43,6 +43,7 @@ /mob/living/simple_animal/pet/cat/ComponentInitialize() . = ..() AddElement(/datum/element/wuv, "purrs!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "hisses!", EMOTE_AUDIBLE) + AddElement(/datum/element/mob_holder, held_icon) /mob/living/simple_animal/pet/cat/update_canmove() ..() @@ -62,6 +63,7 @@ icon_state = "spacecat" icon_living = "spacecat" icon_dead = "spacecat_dead" + held_icon = "spacecat" unsuitable_atmos_damage = 0 minbodytemp = TCMB maxbodytemp = T0C + 40 @@ -73,6 +75,7 @@ icon_state = "original" icon_living = "original" icon_dead = "original_dead" + held_icon = "original" collar_type = null unique_pet = TRUE @@ -86,7 +89,7 @@ pass_flags = PASSMOB mob_size = MOB_SIZE_SMALL collar_type = "kitten" - can_be_held = "cat" + held_icon = "cat" //RUNTIME IS ALIVE! SQUEEEEEEEE~ /mob/living/simple_animal/pet/cat/Runtime @@ -251,7 +254,7 @@ attacked_sound = 'sound/items/eatfood.ogg' deathmessage = "loses its false life and collapses!" death_sound = "bodyfall" - can_be_held = "cak" + held_icon = "cak" /mob/living/simple_animal/pet/cat/cak/CheckParts(list/parts) ..() diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 1979f9aa..bf7eb05f 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -14,13 +14,14 @@ speak_chance = 1 turns_per_move = 10 size_multiplier = 0.5 + var/held_icon = "corgi" do_footstep = TRUE - can_be_held = TRUE /mob/living/simple_animal/pet/dog/ComponentInitialize() . = ..() AddElement(/datum/element/wuv, "yaps_happily!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "growls!", EMOTE_AUDIBLE) + AddElement(/datum/element/mob_holder, held_icon) //Corgis and pugs are now under one dog subtype @@ -35,13 +36,11 @@ childtype = list(/mob/living/simple_animal/pet/dog/corgi/puppy = 95, /mob/living/simple_animal/pet/dog/corgi/puppy/void = 5) animal_species = /mob/living/simple_animal/pet/dog gold_core_spawnable = FRIENDLY_SPAWN - can_be_held = TRUE collar_type = "corgi" var/obj/item/inventory_head var/obj/item/inventory_back var/shaved = FALSE var/nofur = FALSE //Corgis that have risen past the material plane of existence. - can_be_held = "corgi" /mob/living/simple_animal/pet/dog/corgi/Destroy() QDEL_NULL(inventory_head) @@ -70,7 +69,7 @@ butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/pug = 3) gold_core_spawnable = FRIENDLY_SPAWN collar_type = "pug" - can_be_held = "pug" + held_icon = "pug" /mob/living/simple_animal/pet/dog/corgi/exoticcorgi name = "Exotic Corgi" @@ -157,13 +156,6 @@ ..() update_corgi_fluff() -/mob/living/simple_animal/pet/dog/corgi/mob_pickup(mob/living/L) - var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, "corgi", null, 'icons/mob/pets_held_lh.dmi', 'icons/mob/pets_held_rh.dmi', FALSE) - if(!L.put_in_hands(holder)) - qdel(holder) - else - L.visible_message("[L] scoops up [src]!") - /mob/living/simple_animal/pet/dog/corgi/Topic(href, href_list) if(!(iscarbon(usr) || iscyborg(usr)) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) usr << browse(null, "window=mob[REF(src)]") @@ -368,7 +360,10 @@ icon_dead = "old_corgi_dead" desc = "At a ripe old age of [record_age] Ian's not as spry as he used to be, but he'll always be the HoP's beloved corgi." //RIP turns_per_move = 20 - can_be_held = "old_corgi" + var/datum/element/mob_holder/ele = SSdcs.GetElement(/datum/element/mob_holder, held_icon) + if(ele) + ele.Detach(src) + AddElement(/datum/element/mob_holder, "old_corgi") /mob/living/simple_animal/pet/dog/corgi/Ian/Life() if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved) @@ -591,7 +586,7 @@ unsuitable_atmos_damage = 0 minbodytemp = TCMB maxbodytemp = T0C + 40 - can_be_held = "void_puppy" + held_icon = "void_puppy" /mob/living/simple_animal/pet/dog/corgi/puppy/void/Process_Spacemove(movement_dir = 0) return 1 //Void puppies can navigate space. @@ -613,7 +608,7 @@ response_harm = "kicks" var/turns_since_scan = 0 var/puppies = 0 - can_be_held = "lisa" + held_icon = "lisa" //Lisa already has a cute bow! /mob/living/simple_animal/pet/dog/corgi/Lisa/Topic(href, href_list) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index f880adb7..c9ac7377 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -50,7 +50,8 @@ dextrous_hud_type = /datum/hud/dextrous/drone lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE see_in_dark = 7 - can_be_held = TRUE + blood_volume = 0 + can_be_held = TRUE //mob holder element. held_items = list(null, null) var/staticChoice = "static" var/list/staticChoices = list("static", "blank", "letter", "animal") @@ -100,6 +101,11 @@ for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) diag_hud.add_to_hud(src) +/mob/living/simple_animal/drone/ComponentInitialize() + . = ..() + if(can_be_held) + //icon/item state is defined in mob_holder/drone_worn_icon() + AddElement(/datum/element/mob_holder, null, 'icons/mob/head.dmi', 'icons/mob/inhands/clothing_righthand.dmi', 'icons/mob/inhands/clothing_lefthand.dmi', TRUE, /datum/element/mob_holder.proc/drone_worn_icon) /mob/living/simple_animal/drone/med_hud_set_health() var/image/holder = hud_list[DIAG_HUD] @@ -274,7 +280,3 @@ /mob/living/simple_animal/drone/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE) return 0 //So they don't die trying to fix wiring - -/mob/living/simple_animal/drone/generate_mob_holder() - var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, "[visualAppearence]_hat", null, null, null, TRUE) - return holder diff --git a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm index c9207fcf..0f97a4c4 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm @@ -29,12 +29,6 @@ if("Nothing") return -//picky up the drone c: -/mob/living/simple_animal/drone/attack_hand(mob/user) - if(user.a_intent != INTENT_HELP) - return ..() // TODO: convert picking up mobs into an element or component. - mob_try_pickup(user) - /mob/living/simple_animal/drone/proc/try_reactivate(mob/living/user) var/mob/dead/observer/G = get_ghost() if(!client && (!G || !G.client)) diff --git a/code/modules/mob/living/simple_animal/friendly/fox.dm b/code/modules/mob/living/simple_animal/friendly/fox.dm index 3f58ca59..95b082b7 100644 --- a/code/modules/mob/living/simple_animal/friendly/fox.dm +++ b/code/modules/mob/living/simple_animal/friendly/fox.dm @@ -18,9 +18,12 @@ response_disarm = "gently pushes aside" response_harm = "kicks" gold_core_spawnable = FRIENDLY_SPAWN - can_be_held = "fox" do_footstep = TRUE +/mob/living/simple_animal/pet/fox/ComponentInitialize() + . = ..() + AddElement(/datum/element/mob_holder, "fox") + //Captain fox /mob/living/simple_animal/pet/fox/Renault name = "Renault" diff --git a/code/modules/mob/living/simple_animal/friendly/lizard.dm b/code/modules/mob/living/simple_animal/friendly/lizard.dm index 6076e412..8d33d3a2 100644 --- a/code/modules/mob/living/simple_animal/friendly/lizard.dm +++ b/code/modules/mob/living/simple_animal/friendly/lizard.dm @@ -23,9 +23,12 @@ obj_damage = 0 environment_smash = ENVIRONMENT_SMASH_NONE var/static/list/edibles = typecacheof(list(/mob/living/simple_animal/butterfly, /mob/living/simple_animal/cockroach)) //list of atoms, however turfs won't affect AI, but will affect consumption. - can_be_held = "lizard" size_multiplier = 0.5 +/mob/living/simple_animal/hostile/lizard/ComponentInitialize() + . = ..() + AddElement(/datum/element/mob_holder, "lizard", null, null, null, SLOT_HEAD) //you can hold lizards now. + /mob/living/simple_animal/hostile/lizard/CanAttack(atom/the_target)//Can we actually attack a possible target? if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it return FALSE @@ -41,7 +44,3 @@ return TRUE else return ..() - -/mob/living/simple_animal/hostile/lizard/generate_mob_holder() - var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, "lizard", 'icons/mob/animals_held.dmi', 'icons/mob/animals_held_lh.dmi', 'icons/mob/animals_held_rh.dmi', TRUE) - return holder diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 028bada0..97db2047 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -25,18 +25,17 @@ var/body_color //brown, gray and white, leave blank for random gold_core_spawnable = FRIENDLY_SPAWN var/chew_probability = 1 - can_be_held = TRUE size_multiplier = 0.5 /mob/living/simple_animal/mouse/Initialize() . = ..() AddComponent(/datum/component/squeak, list('sound/effects/mousesqueek.ogg'=1), 100) if(!body_color) - body_color = pick( list("brown","gray","white") ) + body_color = pick(list("brown","gray","white")) + AddElement(/datum/element/mob_holder, "mouse_[body_color]") icon_state = "mouse_[body_color]" icon_living = "mouse_[body_color]" icon_dead = "mouse_[body_color]_dead" - can_be_held = "mouse_[body_color]" /mob/living/simple_animal/mouse/proc/splat() src.health = 0 @@ -89,17 +88,14 @@ /mob/living/simple_animal/mouse/white body_color = "white" icon_state = "mouse_white" - can_be_held = "mouse_white" /mob/living/simple_animal/mouse/gray body_color = "gray" icon_state = "mouse_gray" - can_be_held = "mouse_gray" /mob/living/simple_animal/mouse/brown body_color = "brown" icon_state = "mouse_brown" - can_be_held = "mouse_brown" //TOM IS ALIVE! SQUEEEEEEEE~K :) /mob/living/simple_animal/mouse/brown/Tom @@ -124,7 +120,3 @@ /obj/item/reagent_containers/food/snacks/deadmouse/on_grind() reagents.clear_reagents() -/mob/living/simple_animal/mouse/generate_mob_holder() - var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, (istext(can_be_held) ? can_be_held : ""), 'icons/mob/animals_held.dmi', 'icons/mob/animals_held_lh.dmi', 'icons/mob/animals_held_rh.dmi') - holder.w_class = WEIGHT_CLASS_TINY - return holder diff --git a/code/modules/mob/living/simple_animal/friendly/sloth.dm b/code/modules/mob/living/simple_animal/friendly/sloth.dm index fb114ace..f488e5ee 100644 --- a/code/modules/mob/living/simple_animal/friendly/sloth.dm +++ b/code/modules/mob/living/simple_animal/friendly/sloth.dm @@ -22,10 +22,12 @@ maxHealth = 50 speed = 10 glide_size = 2 - can_be_held = "sloth" //finally oranges can be held size_multiplier = 0.5 do_footstep = TRUE +/mob/living/simple_animal/pet/fox/ComponentInitialize() + . = ..() + AddElement(/datum/element/mob_holder, "sloth") //finally oranges can be held //Cargo Sloth /mob/living/simple_animal/sloth/paperwork diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 4e50551f..c7ce6577 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -314,11 +314,13 @@ return if(is_blind(src)) - to_chat(src, "Something is there but you can't see it.") + to_chat(src, "Something is there but you can't see it!") return face_atom(A) - A.examine(src) + var/list/result = A.examine(src) + to_chat(src, result.Join("\n")) + SEND_SIGNAL(src, COMSIG_MOB_EXAMINATE, A) //same as above //note: ghosts can point, this is intended diff --git a/hyperstation/code/modules/resize/resizing.dm b/hyperstation/code/modules/resize/resizing.dm index 647de2c9..d889b77c 100644 --- a/hyperstation/code/modules/resize/resizing.dm +++ b/hyperstation/code/modules/resize/resizing.dm @@ -162,10 +162,10 @@ mob/living/get_effective_size() else if(istype(H) && H.dna.features["taur"] == "Naga" || H.dna.features["taur"] == "Tentacle") tmob.visible_message("[src] snatches up [tmob] underneath their tail!", "[src]'s tail winds around you and snatches you in its coils!") - tmob.mob_pickup_micro_feet(H) + //tmob.mob_pickup_micro_feet(H) else tmob.visible_message("[src] stomps down on [tmob], curling their toes and picking them up!", "[src]'s toes pin you down and curl around you, picking you up!") - tmob.mob_pickup_micro_feet(H) + //tmob.mob_pickup_micro_feet(H) return 1 if(abs(tmob.get_effective_size()/get_effective_size()) >= 2) diff --git a/tgstation.dme b/tgstation.dme index d48447f7..45b3be68 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -457,6 +457,7 @@ #include "code\datums\elements\cleaning.dm" #include "code\datums\elements\earhealing.dm" #include "code\datums\elements\ghost_role_eligibility.dm" +#include "code\datums\elements\mob_holder.dm" #include "code\datums\elements\wuv.dm" #include "code\datums\helper_datums\events.dm" #include "code\datums\helper_datums\getrev.dm" @@ -1984,7 +1985,6 @@ #include "code\modules\mob\living\damage_procs.dm" #include "code\modules\mob\living\death.dm" #include "code\modules\mob\living\emote.dm" -#include "code\modules\mob\living\inhand_holder.dm" #include "code\modules\mob\living\life.dm" #include "code\modules\mob\living\living.dm" #include "code\modules\mob\living\living_defense.dm" @@ -2931,7 +2931,7 @@ #include "hyperstation\code\modules\crafting\recipes.dm" #include "hyperstation\code\modules\integrated_electronics\input.dm" #include "hyperstation\code\modules\patreon\patreon.dm" -#include "hyperstation\code\modules\resize\holder_micro.dm" +// #include "hyperstation\code\modules\resize\holder_micro.dm" #include "hyperstation\code\modules\resize\resizing.dm" #include "hyperstation\code\modules\resize\sizechems.dm" #include "hyperstation\code\modules\resize\sizegun.dm"