diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm
index 757de996..d224c0f1 100644
--- a/code/__DEFINES/movespeed_modification.dm
+++ b/code/__DEFINES/movespeed_modification.dm
@@ -32,5 +32,10 @@
#define MOVESPEED_ID_SANITY "MOOD_SANITY"
+#define MOVESPEED_ID_TASED_STATUS "MOOD_SANITY"
+
+#define MOVESPEED_ID_PRONE_DRAGGING "PRONE_DRAG"
+#define MOVESPEED_ID_HUMAN_CARRYING "HUMAN_CARRY"
+
#define MOVESPEED_ID_SHRUNK "SHRINK_SPEED_MODIFIER"
-#define MOVESPEED_ID_GROW "GROWTH_SPEED_MODIFIER"
\ No newline at end of file
+#define MOVESPEED_ID_GROW "GROWTH_SPEED_MODIFIER"
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 3370acb7..bf843cad 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -865,47 +865,73 @@
return
. = ..()
-/mob/living/carbon/human/proc/piggyback_instant(mob/living/M)
- return buckle_mob(M, TRUE, TRUE, FALSE, TRUE)
+//src is the user that will be carrying, target is the mob to be carried
+/mob/living/carbon/human/proc/can_piggyback(mob/living/carbon/target)
+ return (istype(target) && target.stat == CONSCIOUS)
-//Can C try to piggyback at all.
-/mob/living/carbon/human/proc/can_piggyback(mob/living/carbon/C)
- if(istype(C) && C.stat == CONSCIOUS)
- return TRUE
- return FALSE
+/mob/living/carbon/human/proc/can_be_firemanned(mob/living/carbon/target)
+ return (ishuman(target) && target.lying)
-/mob/living/carbon/human/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE, bypass_piggybacking = FALSE, no_delay = FALSE)
+/mob/living/carbon/human/proc/fireman_carry(mob/living/carbon/target)
+ if(can_be_firemanned(target))
+ visible_message("[src] starts lifting [target] onto their back...",
+ "You start lifting [target] onto your back...")
+ if(do_after(src, 30, TRUE, target))
+ //Second check to make sure they're still valid to be carried
+ if(can_be_firemanned(target) && !incapacitated(FALSE, TRUE))
+ target.resting = FALSE
+ buckle_mob(target, TRUE, TRUE, 90, 1, 0)
+ return
+ visible_message("[src] fails to fireman carry [target]!")
+ else
+ to_chat(src, "You can't fireman carry [target] while they're standing!")
+
+/mob/living/carbon/human/proc/piggyback(mob/living/carbon/target)
+ if(can_piggyback(target))
+ visible_message("[target] starts to climb onto [src]...")
+ if(do_after(target, 15, target = src))
+ if(can_piggyback(target))
+ if(target.incapacitated(FALSE, TRUE) || incapacitated(FALSE, TRUE))
+ target.visible_message("[target] can't hang onto [src]!")
+ return
+ buckle_mob(target, TRUE, TRUE, FALSE, 0, 2)
+ else
+ visible_message("[target] fails to climb onto [src]!")
+ else
+ to_chat(target, "You can't piggyback ride [src] right now!")
+
+/mob/living/carbon/human/buckle_mob(mob/living/target, force = FALSE, check_loc = TRUE, lying_buckle = FALSE, hands_needed = 0, target_hands_needed = 0)
if(!force)//humans are only meant to be ridden through piggybacking and special cases
return
- if(bypass_piggybacking)
- return ..()
- if(!is_type_in_typecache(M, can_ride_typecache))
- M.visible_message("[M] really can't seem to mount [src]...")
+ if(!is_type_in_typecache(target, can_ride_typecache))
+ target.visible_message("[target] really can't seem to mount [src]...")
return
+ buckle_lying = lying_buckle
var/datum/component/riding/human/riding_datum = LoadComponent(/datum/component/riding/human)
- riding_datum.ride_check_rider_incapacitated = TRUE
- riding_datum.ride_check_rider_restrained = TRUE
- riding_datum.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(-6, 4), TEXT_WEST = list( 6, 4)))
- if(buckled_mobs && ((M in buckled_mobs) || (buckled_mobs.len >= max_buckled_mobs)) || buckled || (M.stat != CONSCIOUS))
+ if(target_hands_needed)
+ riding_datum.ride_check_rider_restrained = TRUE
+ if(buckled_mobs && ((target in buckled_mobs) || (buckled_mobs.len >= max_buckled_mobs)) || buckled)
return
- if(can_piggyback(M))
- riding_datum.ride_check_ridden_incapacitated = TRUE
- visible_message("[M] starts to climb onto [src]...")
- if(no_delay || do_after(M, 15, target = src))
- if(can_piggyback(M))
- if(M.incapacitated(FALSE, TRUE) || incapacitated(FALSE, TRUE))
- M.visible_message("[M] can't hang onto [src]!")
- return
- if(!riding_datum.equip_buckle_inhands(M, 2)) //MAKE SURE THIS IS LAST!!
- M.visible_message("[M] can't climb onto [src]!")
- return
- . = ..(M, force, check_loc)
- stop_pulling()
- else
- visible_message("[M] fails to climb onto [src]!")
- else
- . = ..(M,force,check_loc)
- stop_pulling()
+ var/equipped_hands_self
+ var/equipped_hands_target
+ if(hands_needed)
+ equipped_hands_self = riding_datum.equip_buckle_inhands(src, hands_needed, target)
+ if(target_hands_needed)
+ equipped_hands_target = riding_datum.equip_buckle_inhands(target, target_hands_needed)
+
+ if(hands_needed || target_hands_needed)
+ if(hands_needed && !equipped_hands_self)
+ src.visible_message("[src] can't get a grip on [target] because their hands are full!",
+ "You can't get a grip on [target] because your hands are full!")
+ return
+ else if(target_hands_needed && !equipped_hands_target)
+ target.visible_message("[target] can't get a grip on [src] because their hands are full!",
+ "You can't get a grip on [src] because your hands are full!")
+ return
+
+ stop_pulling()
+ riding_datum.handle_vehicle_layer()
+ . = ..(target, force, check_loc)
/mob/living/carbon/human/proc/is_shove_knockdown_blocked() //If you want to add more things that block shove knockdown, extend this
for(var/obj/item/clothing/C in get_equipped_items()) //doesn't include pockets
diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm
index 47a177f7..f8d05ec1 100644
--- a/code/modules/mob/living/carbon/monkey/monkey.dm
+++ b/code/modules/mob/living/carbon/monkey/monkey.dm
@@ -174,3 +174,15 @@
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/tumor
+ name = "living teratoma"
+ verb_say = "blabbers"
+ initial_language_holder = /datum/language_holder/monkey
+ icon = 'icons/mob/monkey.dmi'
+ icon_state = ""
+ butcher_results = list(/obj/effect/spawner/lootdrop/teratoma/minor = 5, /obj/effect/spawner/lootdrop/teratoma/major = 1)
+ type_of_meat = /obj/effect/spawner/lootdrop/teratoma/minor
+ aggressive = TRUE
+ bodyparts = list(/obj/item/bodypart/chest/monkey/teratoma, /obj/item/bodypart/head/monkey/teratoma, /obj/item/bodypart/l_arm/monkey/teratoma,
+ /obj/item/bodypart/r_arm/monkey/teratoma, /obj/item/bodypart/r_leg/monkey/teratoma, /obj/item/bodypart/l_leg/monkey/teratoma)
diff --git a/code/modules/mob/living/carbon/monkey/update_icons.dm b/code/modules/mob/living/carbon/monkey/update_icons.dm
index 75ec032c..8c3e905b 100644
--- a/code/modules/mob/living/carbon/monkey/update_icons.dm
+++ b/code/modules/mob/living/carbon/monkey/update_icons.dm
@@ -1,355 +1,79 @@
-//IMPORTANT: Multiple animate() calls do not stack well, so try to do them all at once if you can.
-/mob/living/carbon/update_transform()
- var/matrix/ntransform = matrix(transform) //aka transform.Copy()
- var/final_pixel_y = pixel_y
- var/final_dir = dir
- var/changed = 0
-
- if(lying != lying_prev && rotate_on_lying)
- changed++
- ntransform.TurnTo(lying_prev,lying)
- if(lying == 0) //Lying to standing
- final_pixel_y = get_standard_pixel_y_offset()
- if(size_multiplier >= 1) //if its bigger than normal
- ntransform.Translate(0,16 * (size_multiplier-1))
- else
- if(lying_prev == 90)
- ntransform.Translate(16 * (size_multiplier-1),16 * (size_multiplier-1))
-
- if(lying_prev == 270)
- ntransform.Translate(-16 * (size_multiplier-1),16 * (size_multiplier-1))
-
- else //if(lying != 0)
- if(lying_prev == 0) //Standing to lying
- pixel_y = get_standard_pixel_y_offset()
- final_pixel_y = get_standard_pixel_y_offset(lying)
- if(lying == 90) //Check the angle of the sprite to offset it accordingly.
- ntransform.Translate(-16 * (size_multiplier-1),0)
- if(size_multiplier < 1) //if its smaller than normal
- ntransform.Translate(0,16 * (size_multiplier-1)) //we additionally offset the sprite downwards
-
- if(lying == 270) //check the angle of the sprite to offset it accordingly
- ntransform.Translate(16 * (size_multiplier-1),0)
- if(size_multiplier < 1) //if its smaller than normal
- ntransform.Translate(0,16 * (size_multiplier-1)) //we additionally offset the sprite downwards
-
- if(dir & (EAST|WEST)) //Facing east or west
- final_dir = pick(NORTH, SOUTH) //So you fall on your side rather than your face or ass
-
- if(resize != RESIZE_DEFAULT_SIZE)
- changed++
- ntransform.Scale(resize)
- resize = RESIZE_DEFAULT_SIZE
-
- //Apply size multiplier, thank NeverExisted for this
- if(size_multiplier != previous_size)
- changed++
- //now we offset the sprite
- //Scaling affects offset. There's probably a smarter and easier way to do this, but this way it works for sure (?)
- //Just to be clear. All this bullshit is needed because someone wanted to store the old transform matrix instead of using a new one each iteration
- //Winfre is currently doing a great job at coating my nuts in slobber while i code this
- if(!lying) //when standing. People of all sizes are affected equally
- ntransform.Translate(0,-16 * (previous_size-1)) //reset the sprite
- ntransform.Scale(size_multiplier/previous_size) //scale the sprite accordingly.
- ntransform.Translate(0,16 * (size_multiplier-1)) //apply the new offset
- else //when lying. Macros dont get an offset, Micros do. We must also check the cases when a micro becomes a macro and viceversa
- if(previous_size <= 1 && size_multiplier <= 1) //micro stays a micro. We modify the side-offset
- ntransform.Translate(0,-16 * (previous_size-1)) //reset the sprite
- ntransform.Scale(size_multiplier/previous_size) //scale the sprite accordingly
- ntransform.Translate(0,16 * (size_multiplier-1)) //apply the new offset
-
- if(previous_size <= 1 && size_multiplier > 1) //micro becomes a macro. We remove the side-offset
- ntransform.Translate(0,-16 * (previous_size-1)) //reset the sprite
- ntransform.Scale(size_multiplier/previous_size) //scale the sprite accordingly
-
- if(previous_size > 1 && size_multiplier <= 1) //macro becomes a micro. We add an offset
- ntransform.Scale(size_multiplier/previous_size) //scale the sprite accordingly.
- ntransform.Translate(0,16 * (size_multiplier-1)) //apply the new offset
-
- if(previous_size > 1 && size_multiplier > 1) //macro stays a macro. We just scale the sprite with no offset changes
- ntransform.Scale(size_multiplier/previous_size) //scale the sprite accordingly
-
- previous_size = size_multiplier
-
- if(changed)
- animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, dir = final_dir, easing = EASE_IN|EASE_OUT)
- floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life().
+/mob/living/carbon/monkey/regenerate_icons()
+ if(!..())
+ update_body_parts()
+ update_hair()
+ update_inv_wear_mask()
+ update_inv_head()
+ update_inv_back()
+ update_transform()
-/mob/living/carbon
- var/list/overlays_standing[TOTAL_LAYERS]
-
-/mob/living/carbon/proc/apply_overlay(cache_index)
- if((. = overlays_standing[cache_index]))
- add_overlay(.)
-
-/mob/living/carbon/proc/remove_overlay(cache_index)
- var/I = overlays_standing[cache_index]
- if(I)
- cut_overlay(I)
- overlays_standing[cache_index] = null
-
-/mob/living/carbon/regenerate_icons()
- if(notransform)
- return 1
- update_inv_hands()
- update_inv_handcuffed()
- update_inv_legcuffed()
- update_fire()
+////////
-/mob/living/carbon/update_inv_hands()
- remove_overlay(HANDS_LAYER)
- if (handcuffed)
- drop_all_held_items()
+/mob/living/carbon/monkey/update_hair()
+ remove_overlay(HAIR_LAYER)
+
+ var/obj/item/bodypart/head/HD = get_bodypart(BODY_ZONE_HEAD)
+ if(!HD) //Decapitated
return
- var/list/hands = list()
- for(var/obj/item/I in held_items)
- if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD)
- I.screen_loc = ui_hand_position(get_held_index_of_item(I))
- client.screen += I
- if(observers && observers.len)
- for(var/M in observers)
- var/mob/dead/observe = M
- if(observe.client && observe.client.eye == src)
- observe.client.screen += I
- else
- observers -= observe
- if(!observers.len)
- observers = null
- break
-
- var/t_state = I.item_state
- if(!t_state)
- t_state = I.icon_state
-
- var/icon_file = I.lefthand_file
- if(get_held_index_of_item(I) % 2 == 0)
- icon_file = I.righthand_file
-
- hands += I.build_worn_icon(state = t_state, default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE)
-
- overlays_standing[HANDS_LAYER] = hands
- apply_overlay(HANDS_LAYER)
-
-
-/mob/living/carbon/update_fire(var/fire_icon = "Generic_mob_burning")
- remove_overlay(FIRE_LAYER)
- if(on_fire)
- var/mutable_appearance/new_fire_overlay = mutable_appearance('icons/mob/OnFire.dmi', fire_icon, -FIRE_LAYER)
- new_fire_overlay.appearance_flags = RESET_COLOR
- overlays_standing[FIRE_LAYER] = new_fire_overlay
-
- apply_overlay(FIRE_LAYER)
-
-
-
-/mob/living/carbon/update_damage_overlays()
- remove_overlay(DAMAGE_LAYER)
-
- var/mutable_appearance/damage_overlay = mutable_appearance('icons/mob/dam_mob.dmi', "blank", -DAMAGE_LAYER)
- overlays_standing[DAMAGE_LAYER] = damage_overlay
-
- for(var/X in bodyparts)
- var/obj/item/bodypart/BP = X
- if(BP.dmg_overlay_type)
- if(BP.brutestate)
- damage_overlay.add_overlay("[BP.dmg_overlay_type]_[BP.body_zone]_[BP.brutestate]0") //we're adding icon_states of the base image as overlays
- if(BP.burnstate)
- damage_overlay.add_overlay("[BP.dmg_overlay_type]_[BP.body_zone]_0[BP.burnstate]")
-
- apply_overlay(DAMAGE_LAYER)
-
-
-/mob/living/carbon/update_inv_wear_mask()
- remove_overlay(FACEMASK_LAYER)
-
- if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
+ if(HAS_TRAIT(src, TRAIT_HUSK))
return
- if(client && hud_used && hud_used.inv_slots[SLOT_WEAR_MASK])
- var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_MASK]
- inv.update_icon()
-
- if(wear_mask)
- if(!(head && (head.flags_inv & HIDEMASK)))
- overlays_standing[FACEMASK_LAYER] = wear_mask.build_worn_icon(state = wear_mask.icon_state, default_layer = FACEMASK_LAYER, default_icon_file = 'icons/mob/mask.dmi')
- update_hud_wear_mask(wear_mask)
-
- apply_overlay(FACEMASK_LAYER)
-
-/mob/living/carbon/update_inv_neck()
- remove_overlay(NECK_LAYER)
-
- if(client && hud_used && hud_used.inv_slots[SLOT_NECK])
- var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_NECK]
- inv.update_icon()
-
- if(wear_neck)
- if(!(head && (head.flags_inv & HIDENECK)))
- overlays_standing[NECK_LAYER] = wear_neck.build_worn_icon(state = wear_neck.icon_state, default_layer = NECK_LAYER, default_icon_file = 'icons/mob/neck.dmi')
- update_hud_neck(wear_neck)
-
- apply_overlay(NECK_LAYER)
-
-/mob/living/carbon/update_inv_back()
- remove_overlay(BACK_LAYER)
-
- if(client && hud_used && hud_used.inv_slots[SLOT_BACK])
- var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_BACK]
- inv.update_icon()
-
- if(back)
- overlays_standing[BACK_LAYER] = back.build_worn_icon(state = back.icon_state, default_layer = BACK_LAYER, default_icon_file = 'icons/mob/back.dmi')
- update_hud_back(back)
-
- apply_overlay(BACK_LAYER)
-
-/mob/living/carbon/update_inv_head()
- remove_overlay(HEAD_LAYER)
-
- if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
- return
-
- if(client && hud_used && hud_used.inv_slots[SLOT_BACK])
- var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD]
- inv.update_icon()
+ var/hair_hidden = 0
if(head)
- overlays_standing[HEAD_LAYER] = head.build_worn_icon(state = head.icon_state, default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/head.dmi')
- update_hud_head(head)
-
- apply_overlay(HEAD_LAYER)
+ var/obj/item/I = head
+ if(I.flags_inv & HIDEHAIR)
+ hair_hidden = 1
+ if(wear_mask)
+ var/obj/item/clothing/mask/M = wear_mask
+ if(M.flags_inv & HIDEHAIR)
+ hair_hidden = 1
+ if(!hair_hidden)
+ if(!getorgan(/obj/item/organ/brain)) //Applies the debrained overlay if there is no brain
+ overlays_standing[HAIR_LAYER] = mutable_appearance('icons/mob/human_face.dmi', "debrained", -HAIR_LAYER)
+ apply_overlay(HAIR_LAYER)
-/mob/living/carbon/update_inv_handcuffed()
- remove_overlay(HANDCUFF_LAYER)
- if(handcuffed)
- var/mutable_appearance/cuffs = mutable_appearance('icons/mob/restraints.dmi', handcuffed.item_state, -HANDCUFF_LAYER)
- cuffs.color = handcuffed.color
+/mob/living/carbon/monkey/update_fire()
+ ..("Monkey_burning")
- overlays_standing[HANDCUFF_LAYER] = cuffs
- apply_overlay(HANDCUFF_LAYER)
-
-/mob/living/carbon/update_inv_legcuffed()
+/mob/living/carbon/monkey/update_inv_legcuffed()
remove_overlay(LEGCUFF_LAYER)
clear_alert("legcuffed")
if(legcuffed)
var/mutable_appearance/legcuffs = mutable_appearance('icons/mob/restraints.dmi', legcuffed.item_state, -LEGCUFF_LAYER)
- legcuffs.color = legcuffed.color
+ legcuffs.color = handcuffed.color
+ legcuffs.pixel_y = 8
overlays_standing[HANDCUFF_LAYER] = legcuffs
apply_overlay(LEGCUFF_LAYER)
throw_alert("legcuffed", /obj/screen/alert/restrained/legcuffed, new_master = legcuffed)
-//mob HUD updates for items in our inventory
-
-//update whether handcuffs appears on our hud.
-/mob/living/carbon/proc/update_hud_handcuffed()
- if(hud_used)
- for(var/hand in hud_used.hand_slots)
- var/obj/screen/inventory/hand/H = hud_used.hand_slots[hand]
- if(H)
- H.update_icon()
+//monkey HUD updates for items in our inventory
//update whether our head item appears on our hud.
-/mob/living/carbon/proc/update_hud_head(obj/item/I)
- return
+/mob/living/carbon/monkey/update_hud_head(obj/item/I)
+ if(client && hud_used && hud_used.hud_shown)
+ I.screen_loc = ui_monkey_head
+ client.screen += I
//update whether our mask item appears on our hud.
-/mob/living/carbon/proc/update_hud_wear_mask(obj/item/I)
- return
+/mob/living/carbon/monkey/update_hud_wear_mask(obj/item/I)
+ if(client && hud_used && hud_used.hud_shown)
+ I.screen_loc = ui_monkey_mask
+ client.screen += I
//update whether our neck item appears on our hud.
-/mob/living/carbon/proc/update_hud_neck(obj/item/I)
- return
+/mob/living/carbon/monkey/update_hud_neck(obj/item/I)
+ if(client && hud_used && hud_used.hud_shown)
+ I.screen_loc = ui_monkey_neck
+ client.screen += I
//update whether our back item appears on our hud.
-/mob/living/carbon/proc/update_hud_back(obj/item/I)
- return
-
-
-
-//Overlays for the worn overlay so you can overlay while you overlay
-//eg: ammo counters, primed grenade flashing, etc.
-//"icon_file" is used automatically for inhands etc. to make sure it gets the right inhand file
-/obj/item/proc/worn_overlays(isinhands = FALSE, icon_file)
- . = list()
-
-
-/mob/living/carbon/update_body()
- update_body_parts()
-
-/mob/living/carbon/proc/update_body_parts()
- //CHECK FOR UPDATE
- var/oldkey = icon_render_key
- icon_render_key = generate_icon_render_key()
- if(oldkey == icon_render_key)
- return
-
- remove_overlay(BODYPARTS_LAYER)
-
- for(var/X in bodyparts)
- var/obj/item/bodypart/BP = X
- BP.update_limb()
-
- //LOAD ICONS
- if(limb_icon_cache[icon_render_key])
- load_limb_from_cache()
- return
-
- //GENERATE NEW LIMBS
- var/list/new_limbs = list()
- for(var/X in bodyparts)
- var/obj/item/bodypart/BP = X
- new_limbs += BP.get_limb_icon()
- if(new_limbs.len)
- overlays_standing[BODYPARTS_LAYER] = new_limbs
- limb_icon_cache[icon_render_key] = new_limbs
-
- apply_overlay(BODYPARTS_LAYER)
- update_damage_overlays()
-
-
-
-/////////////////////
-// Limb Icon Cache //
-/////////////////////
-/*
- Called from update_body_parts() these procs handle the limb icon cache.
- the limb icon cache adds an icon_render_key to a human mob, it represents:
- - skin_tone (if applicable)
- - gender
- - limbs (stores as the limb name and whether it is removed/fine, organic/robotic)
- These procs only store limbs as to increase the number of matching icon_render_keys
- This cache exists because drawing 6/7 icons for humans constantly is quite a waste
- See RemieRichards on irc.rizon.net #coderbus
-*/
-
-//produces a key based on the mob's limbs
-
-/mob/living/carbon/proc/generate_icon_render_key()
- for(var/X in bodyparts)
- var/obj/item/bodypart/BP = X
- . += "-[BP.body_zone]"
- if(BP.use_digitigrade)
- . += "-digitigrade[BP.use_digitigrade]"
- if(BP.animal_origin)
- . += "-[BP.animal_origin]"
- if(BP.status == BODYPART_ORGANIC)
- . += "-organic"
- else
- . += "-robotic"
-
- if(HAS_TRAIT(src, TRAIT_HUSK))
- . += "-husk"
-
-
-//change the mob's icon to the one matching its key
-/mob/living/carbon/proc/load_limb_from_cache()
- if(limb_icon_cache[icon_render_key])
- remove_overlay(BODYPARTS_LAYER)
- overlays_standing[BODYPARTS_LAYER] = limb_icon_cache[icon_render_key]
- apply_overlay(BODYPARTS_LAYER)
- update_damage_overlays()
+/mob/living/carbon/monkey/update_hud_back(obj/item/I)
+ if(client && hud_used && hud_used.hud_shown)
+ I.screen_loc = ui_monkey_back
+ client.screen += I
diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm
index aec1c86b..03df1cab 100644
--- a/code/modules/mob/living/carbon/update_icons.dm
+++ b/code/modules/mob/living/carbon/update_icons.dm
@@ -10,10 +10,29 @@
ntransform.TurnTo(lying_prev,lying)
if(lying == 0) //Lying to standing
final_pixel_y = get_standard_pixel_y_offset()
+ if(size_multiplier >= 1) //if its bigger than normal
+ ntransform.Translate(0,16 * (size_multiplier-1))
+ else
+ if(lying_prev == 90)
+ ntransform.Translate(16 * (size_multiplier-1),16 * (size_multiplier-1))
+
+ if(lying_prev == 270)
+ ntransform.Translate(-16 * (size_multiplier-1),16 * (size_multiplier-1))
+
else //if(lying != 0)
if(lying_prev == 0) //Standing to lying
pixel_y = get_standard_pixel_y_offset()
final_pixel_y = get_standard_pixel_y_offset(lying)
+ if(lying == 90) //Check the angle of the sprite to offset it accordingly.
+ ntransform.Translate(-16 * (size_multiplier-1),0)
+ if(size_multiplier < 1) //if its smaller than normal
+ ntransform.Translate(0,16 * (size_multiplier-1)) //we additionally offset the sprite downwards
+
+ if(lying == 270) //check the angle of the sprite to offset it accordingly
+ ntransform.Translate(16 * (size_multiplier-1),0)
+ if(size_multiplier < 1) //if its smaller than normal
+ ntransform.Translate(0,16 * (size_multiplier-1)) //we additionally offset the sprite downwards
+
if(dir & (EAST|WEST)) //Facing east or west
final_dir = pick(NORTH, SOUTH) //So you fall on your side rather than your face or ass
@@ -22,11 +41,40 @@
ntransform.Scale(resize)
resize = RESIZE_DEFAULT_SIZE
+ //Apply size multiplier, thank NeverExisted for this
+ if(size_multiplier != previous_size)
+ changed++
+ //now we offset the sprite
+ //Scaling affects offset. There's probably a smarter and easier way to do this, but this way it works for sure (?)
+ //Just to be clear. All this bullshit is needed because someone wanted to store the old transform matrix instead of using a new one each iteration
+ //Winfre is currently doing a great job at coating my nuts in slobber while i code this
+ if(!lying) //when standing. People of all sizes are affected equally
+ ntransform.Translate(0,-16 * (previous_size-1)) //reset the sprite
+ ntransform.Scale(size_multiplier/previous_size) //scale the sprite accordingly.
+ ntransform.Translate(0,16 * (size_multiplier-1)) //apply the new offset
+ else //when lying. Macros dont get an offset, Micros do. We must also check the cases when a micro becomes a macro and viceversa
+ if(previous_size <= 1 && size_multiplier <= 1) //micro stays a micro. We modify the side-offset
+ ntransform.Translate(0,-16 * (previous_size-1)) //reset the sprite
+ ntransform.Scale(size_multiplier/previous_size) //scale the sprite accordingly
+ ntransform.Translate(0,16 * (size_multiplier-1)) //apply the new offset
+
+ if(previous_size <= 1 && size_multiplier > 1) //micro becomes a macro. We remove the side-offset
+ ntransform.Translate(0,-16 * (previous_size-1)) //reset the sprite
+ ntransform.Scale(size_multiplier/previous_size) //scale the sprite accordingly
+
+ if(previous_size > 1 && size_multiplier <= 1) //macro becomes a micro. We add an offset
+ ntransform.Scale(size_multiplier/previous_size) //scale the sprite accordingly.
+ ntransform.Translate(0,16 * (size_multiplier-1)) //apply the new offset
+
+ if(previous_size > 1 && size_multiplier > 1) //macro stays a macro. We just scale the sprite with no offset changes
+ ntransform.Scale(size_multiplier/previous_size) //scale the sprite accordingly
+
+ previous_size = size_multiplier
+
if(changed)
animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, dir = final_dir, easing = EASE_IN|EASE_OUT)
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life().
-
/mob/living/carbon
var/list/overlays_standing[TOTAL_LAYERS]
diff --git a/tgstation.dme b/tgstation.dme
index 1344e502..ff3cd599 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2882,6 +2882,9 @@
#include "hyperstation\code\mobs\werewolf.dm"
#include "hyperstation\code\modules\antagonists\werewolf\werewolf.dm"
#include "hyperstation\code\modules\crafting\recipes.dm"
+#include "hyperstation\code\modules\resize\holder_micro.dm"
+#include "hyperstation\code\modules\resize\resizing.dm"
+#include "hyperstation\code\modules\resize\sizegun.dm"
#include "hyperstation\code\obj\decal.dm"
#include "hyperstation\code\obj\fluff.dm"
#include "hyperstation\code\obj\kinkyclothes.dm"