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