diff --git a/code/datums/components/riding/mob/animal.dm b/code/datums/components/riding/mob/animal.dm index 8007e420a62..10f7eac42d0 100644 --- a/code/datums/components/riding/mob/animal.dm +++ b/code/datums/components/riding/mob/animal.dm @@ -4,3 +4,6 @@ /datum/component/riding_handler/mob/animal expected_typepath = /mob/living/simple_mob + +/datum/component/riding_handler/mob/animal/controllable + riding_handler_flags = CF_RIDING_HANDLER_IS_CONTROLLABLE diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm index 18c35b007f4..6edb757a149 100644 --- a/code/game/objects/structures/plasticflaps.dm +++ b/code/game/objects/structures/plasticflaps.dm @@ -13,6 +13,7 @@ var/list/mobs_can_pass = list( /mob/living/bot, /mob/living/simple_mob/slime/xenobio, + /mob/living/simple_mob/protean_blob, /mob/living/simple_mob/animal/passive/mouse, /mob/living/silicon/robot/drone ) diff --git a/code/modules/mob/living/carbon/human/human-interaction.dm b/code/modules/mob/living/carbon/human/human-interaction.dm index 38056a22035..8d761dd3fd8 100644 --- a/code/modules/mob/living/carbon/human/human-interaction.dm +++ b/code/modules/mob/living/carbon/human/human-interaction.dm @@ -75,13 +75,12 @@ return CLICKCHAIN_FULL_BLOCKED | CLICKCHAIN_DID_SOMETHING // mostly legacy code - var/mob/living/carbon/human/H = clickchain.performer - if(!istype(H)) - return NONE - if(legacy_unarmed_miss_hook(H)) - return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_ATTACK_MISSED - var/mob/living/L = H - add_attack_logs(H,src,"Disarmed") + var/mob/living/L = clickchain.performer + if(istype(L, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = L + if(legacy_unarmed_miss_hook(H)) + return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_ATTACK_MISSED + add_attack_logs(L,src,"Disarmed") L.do_attack_animation(src) if(w_uniform) @@ -154,13 +153,12 @@ return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_FULL_BLOCKED // mostly legacy code - var/mob/living/carbon/human/H = clickchain.performer - if(!istype(H)) - return NONE - if(legacy_unarmed_miss_hook(H)) - return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_ATTACK_MISSED - var/datum/gender/TT = GLOB.gender_datums[H.get_visible_gender()] - var/mob/living/L = H + var/mob/living/L = clickchain.performer + if(istype(L, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = L + if(legacy_unarmed_miss_hook(H)) + return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_ATTACK_MISSED + var/datum/gender/TT = GLOB.gender_datums[L.get_visible_gender()] if(L == src || anchored) return NONE for(var/obj/item/grab/G in src.grabbed_by) @@ -179,7 +177,7 @@ L.put_in_active_hand(G) LAssailant = L - H.do_attack_animation(src) + L.do_attack_animation(src) playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) visible_message("[L] has grabbed [src] [(L.zone_sel.selecting == BP_L_HAND || L.zone_sel.selecting == BP_R_HAND)? "by [(gender==FEMALE)? "her" : ((gender==MALE)? "his": "their")] hands": "passively"]!") diff --git a/code/modules/mob/living/simple_mob/on_click.dm b/code/modules/mob/living/simple_mob/on_click.dm index 16575a08907..6c236c220d9 100644 --- a/code/modules/mob/living/simple_mob/on_click.dm +++ b/code/modules/mob/living/simple_mob/on_click.dm @@ -28,13 +28,13 @@ if(INTENT_GRAB) if(has_hands()) - A.attack_hand(src) + A.attack_hand(src, default_clickchain_event_args(A)) else attack_target(A) if(INTENT_DISARM) if(has_hands()) - A.attack_hand(src) + A.attack_hand(src, default_clickchain_event_args(A)) else attack_target(A) diff --git a/code/modules/species/protean/protean_blob.dm b/code/modules/species/protean/protean_blob.dm index 5121e942faa..3cb80802dd1 100644 --- a/code/modules/species/protean/protean_blob.dm +++ b/code/modules/species/protean/protean_blob.dm @@ -18,6 +18,7 @@ say_list_type = /datum/say_list/protean_blob show_stat_health = FALSE //We will do it ourselves + pass_flags = ATOM_PASS_TABLE has_langs = list(LANGUAGE_GALCOM, LANGUAGE_EAL) response_help = "pats the" response_disarm = "gently pushes aside the" @@ -64,6 +65,11 @@ player_msg = "In this form, you can move a little faster and your health will regenerate as long as you have metal in you!" holder_type = /obj/item/holder/protoblob + buckle_lying = FALSE + buckle_max_mobs = 2 + buckle_allowed = TRUE + buckle_flags = BUCKLING_GROUND_HOIST //blobsurfing + /datum/say_list/protean_blob speak = list("Blrb?","Sqrsh.","Glrsh!") emote_hear = list("squishes softly","spluts quietly","makes wet noises") @@ -73,6 +79,7 @@ /mob/living/simple_mob/protean_blob/Initialize(mapload, mob/living/carbon/human/H) . = ..() access_card = new(src) + AddComponent(/datum/component/riding_filter/mob/animal/protean) if(H) humanform = H refactory = locate() in humanform.internal_organs @@ -83,6 +90,7 @@ add_verb(src, /mob/living/simple_mob/protean_blob/proc/chameleon_apperance) add_verb(src, /mob/living/simple_mob/protean_blob/proc/chameleon_color) add_verb(src, /mob/living/simple_mob/protean_blob/proc/chameleon_apperance_rig) + add_verb(src, /mob/living/simple_mob/protean_blob/proc/toggle_rider_control) add_verb(src, /mob/living/proc/usehardsuit) INVOKE_ASYNC(src, TYPE_PROC_REF(/mob, update_health)) else @@ -114,6 +122,17 @@ if(humanform && C.statpanel_tab("Species", TRUE)) . += humanform.species.statpanel_status(C, humanform) +/mob/living/simple_mob/protean_blob/resize(new_size, animate = FALSE, ignore_cooldown = FALSE) + . = ..() + var/new_buckmax = round(new_size * 2) + + if(has_buckled_mobs() && (new_buckmax < buckle_max_mobs)) + visible_message(SPAN_WARNING("[src] sloughs off its riders!")) + unbuckle_all_mobs(BUCKLE_OP_FORCE) + + buckle_max_mobs = new_buckmax + + /mob/living/simple_mob/protean_blob/update_health() if(humanform) //Set the max @@ -382,28 +401,6 @@ if(istype(I, /obj/item/holder)) I.forceMove(root.drop_location()) -/mob/living/simple_mob/protean_blob/strip_menu_act(mob/user, action) - return humanform.strip_menu_act(arglist(args)) - -/mob/living/simple_mob/protean_blob/strip_menu_options(mob/user) - return humanform.strip_menu_options(arglist(args)) - -/mob/living/simple_mob/protean_blob/strip_interaction_prechecks(mob/user, autoclose, allow_loc) - allow_loc = TRUE - return humanform.strip_interaction_prechecks(arglist(args)) - -/mob/living/simple_mob/protean_blob/open_strip_menu(mob/user) - return humanform.open_strip_menu(arglist(args)) - -/mob/living/simple_mob/protean_blob/close_strip_menu(mob/user) - return humanform.close_strip_menu(arglist(args)) - -/mob/living/simple_mob/protean_blob/request_strip_menu(mob/user) - return humanform.request_strip_menu(arglist(args)) - -/mob/living/simple_mob/protean_blob/render_strip_menu(mob/user) - return humanform.render_strip_menu(arglist(args)) - /mob/living/simple_mob/protean_blob/proc/rig_transform() set name = "Modify Form - Hardsuit" set desc = "Allows a protean blob to solidify its form into one extremely similar to a hardsuit." @@ -673,7 +670,7 @@ chosen_list = GLOB.clothing_ears if("headsets") chosen_list = GLOB.clothing_headsets - + var/picked = input(src,"What clothing would you like to mimic?","Mimic Clothes") as null|anything in chosen_list if(!ispath(chosen_list[picked])) @@ -747,6 +744,25 @@ colour_ui = new(src) colour_ui.ui_interact(usr) +/mob/living/simple_mob/protean_blob/proc/toggle_rider_control() + set name = "Give Reins" + set desc = "Give or take the person riding on you control of your movement." + set category = VERB_CATEGORY_IC + var/datum/component/riding_filter/mob/animal/protean/riding_filter = GetComponent(/datum/component/riding_filter/mob/animal/protean) + if(!riding_filter) + to_chat(src, "Your form is incompatible with being ridden! Somehow. This is a bug.") + return + if(riding_filter.handler_typepath == /datum/component/riding_handler/mob/protean) + riding_filter.handler_typepath = /datum/component/riding_handler/mob/protean/controllable + to_chat(src, "You can now be controlled!") + else + riding_filter.handler_typepath = /datum/component/riding_handler/mob/protean + to_chat(src, "You can no longer be controlled!") + var/datum/component/riding_handler/mob/protean/riding_handler = GetComponent(/datum/component/riding_handler/mob/protean) + if(!riding_handler) + //No need to update the handler if it doesn't exist. + return + riding_handler.riding_handler_flags ^= CF_RIDING_HANDLER_IS_CONTROLLABLE /mob/living/simple_mob/protean_blob/make_perspective() . = ..() @@ -785,3 +801,40 @@ // Fix internal damage if(O.damage > 0) O.heal_damage_i(3, can_revive = TRUE) + +/datum/component/riding_filter/mob/animal/protean + expected_typepath = /mob/living/simple_mob/protean_blob + handler_typepath = /datum/component/riding_handler/mob/protean + +/datum/component/riding_handler/mob/protean + expected_typepath = /mob/living/simple_mob/protean_blob + rider_offsets = list( + list( + list(0, 8, -0.1, null), + list(0, 8, -0.1, null), + list(0, 8, -0.1, null), + list(0, 8, -0.1, null) + ), + list( + list(3, 7, -0.2, null), + list(3, 7, -0.2, null), + list(3, 7, -0.2, null), + list(-4, 7, -0.2, null) + ), + list( + list(-3, 7, -0.2, null), + list(-3, 7, -0.2, null), + list(-3, 7, -0.2, null), + list(3, 7, -0.2, null) + ), + list( + list(0, 8, -0.2, null), + list(0, 8, -0.2, null), + list(-4, 8, -0.2, null), + list(4, 8, -0.2, null) + ) + ) + rider_offset_format = CF_RIDING_OFFSETS_ENUMERATED + +/datum/component/riding_handler/mob/protean/controllable + riding_handler_flags = CF_RIDING_HANDLER_IS_CONTROLLABLE diff --git a/code/modules/species/protean/protean_powers.dm b/code/modules/species/protean/protean_powers.dm index 06f8ea610c1..30330e2fc9e 100644 --- a/code/modules/species/protean/protean_powers.dm +++ b/code/modules/species/protean/protean_powers.dm @@ -315,9 +315,9 @@ to_chat(user,"You don't have a working refactory module!") return - var/nagmessage = "Adjust your mass to be a size between 75 to 200%. Up-sizing consumes metal, downsizing returns metal." + var/nagmessage = "Adjust your mass to be a size between 25 to 200%. Up-sizing consumes metal, downsizing returns metal." var/new_size = input(user, nagmessage, "Pick a Size", user.size_multiplier*100) as num|null - if(!new_size || !ISINRANGE(new_size, 75, 200)) + if(!new_size || !ISINRANGE(new_size, 25, 200)) return var/size_factor = new_size/100