diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm b/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm new file mode 100644 index 00000000000..0aa1b700a6e --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm @@ -0,0 +1,171 @@ +#define MORPH_COOLDOWN 50 + +/mob/living/simple_mob/vore/hostile/morph + name = "morph" + real_name = "morph" + desc = "A revolting, pulsating pile of flesh." + tt_desc = "morphus shapeshiftus" + icon = 'icons/mob/animal_vr.dmi' + icon_state = "morph" + icon_living = "morph" + icon_dead = "morph_dead" + movement_cooldown = 1 + status_flags = CANPUSH + pass_flags = PASSTABLE + mob_bump_flag = 0 + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + + minbodytemp = 0 + maxHealth = 150 + health = 150 + melee_damage_lower = 20 + melee_damage_upper = 20 + see_in_dark = 8 + attacktext = "glomps" + attack_sound = 'sound/effects/blobattack.ogg' + + meat_amount = 2 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + showvoreprefs = 0 + vore_active = 1 + + var/morphed = FALSE + var/tooltip = TRUE + var/melee_damage_disguised = 0 + var/eat_while_disguised = FALSE + var/atom/movable/form = null + var/morph_time = 0 + var/our_size_multiplier = 1 + var/static/list/blacklist_typecache = typecacheof(list( + /obj/screen, + /obj/singularity, + /mob/living/simple_mob/vore/hostile/morph, + /obj/effect)) + +/mob/living/simple_mob/vore/hostile/morph/Initialize() + verbs += /mob/living/proc/ventcrawl + return ..() + +/mob/living/simple_mob/vore/hostile/morph/proc/allowed(atom/movable/A) + return !is_type_in_typecache(A, blacklist_typecache) && (isobj(A) || ismob(A)) + +/mob/living/simple_mob/vore/hostile/morph/examine(mob/user) + if(morphed) + form.examine(user) + if(get_dist(user,src)<=3) + to_chat(user, "It doesn't look quite right...") + else + ..() + return + +/mob/living/simple_mob/vore/hostile/morph/ShiftClickOn(atom/movable/A) + if(Adjacent(A)) + if(morph_time <= world.time && !stat) + if(A == src) + restore() + return + if(istype(A) && allowed(A)) + assume(A) + else + to_chat(src, "Your chameleon skin is still repairing itself!") + else + ..() + +/mob/living/simple_mob/vore/hostile/morph/proc/assume(atom/movable/target) + if(morphed) + to_chat(src, "You must restore to your original form first!") + return + morphed = TRUE + form = target + + visible_message("[src] suddenly twists and changes shape, becoming a copy of [target]!") + appearance = target.appearance + copy_overlays(target) + alpha = max(alpha, 150) //fucking chameleons + transform = initial(transform) + our_size_multiplier = size_multiplier + if(isobj(target)) + size_multiplier = 1 + icon_scale_x = target.icon_scale_x + icon_scale_y = target.icon_scale_y + update_transform() + else if(ismob(target)) + var/mob/living/M = target + resize(M.size_multiplier) + pixel_y = initial(pixel_y) + pixel_x = initial(pixel_x) + density = target.density + + //Morphed is weaker + melee_damage_lower = melee_damage_disguised + melee_damage_upper = melee_damage_disguised + movement_cooldown = 5 + + morph_time = world.time + MORPH_COOLDOWN + return + +/mob/living/simple_mob/vore/hostile/morph/proc/restore() + if(!morphed) + to_chat(src, "You're already in your normal form!") + return + morphed = FALSE + form = null + alpha = initial(alpha) + color = initial(color) + layer = initial(layer) + plane = initial(plane) + maptext = null + + visible_message("[src] suddenly collapses in on itself, dissolving into a pile of green flesh!") + name = initial(name) + desc = initial(desc) + icon = initial(icon) + icon_state = initial(icon_state) + size_multiplier = 0 + resize(our_size_multiplier) + overlays.Cut() + density = initial(density) + + //Baseline stats + melee_damage_lower = initial(melee_damage_lower) + melee_damage_upper = initial(melee_damage_upper) + movement_cooldown = initial(movement_cooldown) + + morph_time = world.time + MORPH_COOLDOWN + +/mob/living/simple_mob/vore/hostile/morph/death(gibbed) + if(morphed) + visible_message("[src] twists and dissolves into a pile of green flesh!") + restore() + ..() + +/mob/living/simple_mob/vore/hostile/morph/will_show_tooltip() + return (!morphed) + +/mob/living/simple_mob/vore/hostile/morph/resize(var/new_size, var/animate = TRUE) + if(morphed && !ismob(form)) + return + return ..() + +/mob/living/simple_mob/vore/hostile/morph/update_icons() + if(morphed) + return + return ..() + +/mob/living/simple_mob/vore/hostile/morph/update_transform() + if(morphed) + var/matrix/M = matrix() + M.Scale(icon_scale_x, icon_scale_y) + M.Turn(icon_rotation) + src.transform = M + else + ..() diff --git a/icons/mob/animal_vr.dmi b/icons/mob/animal_vr.dmi index 2d8cd7a6a1a..801f3ddf335 100644 Binary files a/icons/mob/animal_vr.dmi and b/icons/mob/animal_vr.dmi differ diff --git a/vorestation.dme b/vorestation.dme index a6a2bf17baf..76270609462 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -2491,6 +2491,7 @@ #include "code\modules\mob\living\simple_mob\subtypes\vore\wolf.dm" #include "code\modules\mob\living\simple_mob\subtypes\vore\wolfgirl.dm" #include "code\modules\mob\living\simple_mob\subtypes\vore\zz_vore_overrides.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\morph\morph.dm" #include "code\modules\mob\living\simple_mob\subtypes\vore\shadekin\_defines.dm" #include "code\modules\mob\living\simple_mob\subtypes\vore\shadekin\ability_objects.dm" #include "code\modules\mob\living\simple_mob\subtypes\vore\shadekin\ability_procs.dm"