From bf7abb778dc5ce44f4d91672f772dfac826d683d Mon Sep 17 00:00:00 2001 From: QuoteFox <49098813+quotefox@users.noreply.github.com> Date: Fri, 26 Mar 2021 06:00:13 +0000 Subject: [PATCH] Revert "Revert "Merge pull request #1055 from DragonTrance/apparition-antagonist"" This reverts commit 04d01ed8510d3820f2fd03cbdae2b125dc67a30c. --- code/__DEFINES/is_helpers.dm | 3 + code/__DEFINES/mobs.dm | 1 + hyperstation/code/__DEFINES/wendigo.dm | 1 + .../modules/antagonists/wendigo/datums_hud.dm | 277 +++++++++++++ .../wendigo/forest/structures/soul_storage.dm | 14 + .../antagonists/wendigo/mob/_on_click.dm | 11 + .../antagonists/wendigo/mob/defines_init.dm | 115 ++++++ .../antagonists/wendigo/mob/examine.dm | 86 ++++ .../antagonists/wendigo/mob/metabolization.dm | 55 +++ .../antagonists/wendigo/mob/mob_defense.dm | 125 ++++++ .../antagonists/wendigo/mob/mob_equip.dm | 100 +++++ .../wendigo/mob/organs_bodyparts.dm | 58 +++ .../antagonists/wendigo/mob/update_icons.dm | 370 ++++++++++++++++++ hyperstation/icons/mobs/wendigo.dmi | Bin 0 -> 1988 bytes .../chemistry/reagents/enlargement.dm | 8 + tgstation.dme | 11 + 16 files changed, 1235 insertions(+) create mode 100644 hyperstation/code/__DEFINES/wendigo.dm create mode 100644 hyperstation/code/modules/antagonists/wendigo/datums_hud.dm create mode 100644 hyperstation/code/modules/antagonists/wendigo/forest/structures/soul_storage.dm create mode 100644 hyperstation/code/modules/antagonists/wendigo/mob/_on_click.dm create mode 100644 hyperstation/code/modules/antagonists/wendigo/mob/defines_init.dm create mode 100644 hyperstation/code/modules/antagonists/wendigo/mob/examine.dm create mode 100644 hyperstation/code/modules/antagonists/wendigo/mob/metabolization.dm create mode 100644 hyperstation/code/modules/antagonists/wendigo/mob/mob_defense.dm create mode 100644 hyperstation/code/modules/antagonists/wendigo/mob/mob_equip.dm create mode 100644 hyperstation/code/modules/antagonists/wendigo/mob/organs_bodyparts.dm create mode 100644 hyperstation/code/modules/antagonists/wendigo/mob/update_icons.dm create mode 100644 hyperstation/icons/mobs/wendigo.dmi diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 5fd4ca88..6056129a 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -89,6 +89,9 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list( #define isxenoperson(A) (is_species(A, /datum/species/xeno)) #define isstartjelly(A) (is_species(A, /datum/species/jelly/roundstartslime)) +// Hyperstation Carbon Stuff +#define iswendigo(A) (istype(A, /mob/living/carbon/wendigo)) + //more carbon mobs #define ismonkey(A) (istype(A, /mob/living/carbon/monkey)) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 3e46a1e8..53119bfc 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -69,6 +69,7 @@ #define ALIEN_BODYPART "alien" #define LARVA_BODYPART "larva" #define DEVIL_BODYPART "devil" +#define WENDIGO_BODYPART "wendigo" /*see __DEFINES/inventory.dm for bodypart bitflag defines*/ // Health/damage defines for carbon mobs diff --git a/hyperstation/code/__DEFINES/wendigo.dm b/hyperstation/code/__DEFINES/wendigo.dm new file mode 100644 index 00000000..489db91e --- /dev/null +++ b/hyperstation/code/__DEFINES/wendigo.dm @@ -0,0 +1 @@ +GLOBAL_LIST_EMPTY(wendigo_soul_storages) diff --git a/hyperstation/code/modules/antagonists/wendigo/datums_hud.dm b/hyperstation/code/modules/antagonists/wendigo/datums_hud.dm new file mode 100644 index 00000000..ab6b6fda --- /dev/null +++ b/hyperstation/code/modules/antagonists/wendigo/datums_hud.dm @@ -0,0 +1,277 @@ +/* +Holds things like antag datums, game modes, abilities, and everything +related to the antag that could be a datum +*/ + +//ANTAGONIST +/datum/antagonist/wendigo + name = "wendigo" + antagpanel_category = "Wendigo" + +/datum/antagonist/wendigo/on_gain() + if(istype(owner.current, /mob/living/carbon/human)) + var/mob/living/carbon/wendigo/new_owner = new/mob/living/carbon/wendigo(get_turf(owner.current)) + var/mob/current_body = owner.current + current_body.transfer_ckey(new_owner) + current_body.Destroy() + owner = new_owner.mind + owner.current = new_owner + ..() + + +//HUD +//Contents: Intentions, Hands, Dropping/Throwing/Pulling, Inventory Equip +// Health + Souls on the bottom of screen +//TODO: Health doll, Soul counter (not devil) + +/datum/hud/wendigo/New(mob/living/carbon/wendigo/owner) + ..() + var/obj/screen/using + var/obj/screen/inventory/inv_box + + var/widescreenlayout = FALSE //adds support for different hud layouts depending on widescreen pref + if(owner.client && owner.client.prefs && owner.client.prefs.widescreenpref) + widescreenlayout = FALSE + + //CRAFTING + using = new /obj/screen/craft + using.icon = ui_style + if(!widescreenlayout) + using.screen_loc = ui_boxcraft + static_inventory += using + + //LANG MENU + using = new/obj/screen/language_menu + using.icon = ui_style + if(!widescreenlayout) + using.screen_loc = ui_boxlang + static_inventory += using + + //AREA EDITOR + using = new /obj/screen/area_creator + using.icon = ui_style + if(!widescreenlayout) + using.screen_loc = ui_boxarea + static_inventory += using + + using = new /obj/screen/voretoggle() + using.icon = tg_ui_icon_to_cit_ui(ui_style) + using.screen_loc = ui_voremode + if(!widescreenlayout) + using.screen_loc = ui_boxvore + static_inventory += using + + //INTENTS & ACTIONS + action_intent = new /obj/screen/act_intent/segmented + action_intent.icon_state = mymob.a_intent + static_inventory += action_intent + + using = new /obj/screen/human/equip() + using.icon = ui_style + using.screen_loc = ui_equip_position(mymob) + static_inventory += using + + using = new /obj/screen/mov_intent + using.icon = tg_ui_icon_to_cit_ui(ui_style) + using.icon_state = (mymob.m_intent == MOVE_INTENT_RUN ? "running" : "walking") + using.screen_loc = ui_movi + static_inventory += using + + using = new /obj/screen/resist() + using.icon = ui_style + using.screen_loc = ui_overridden_resist + hotkeybuttons += using + + using = new /obj/screen/restbutton() + using.icon = tg_ui_icon_to_cit_ui(ui_style) + using.screen_loc = ui_pull_resist + static_inventory += using + + using = new /obj/screen/combattoggle() + using.icon = tg_ui_icon_to_cit_ui(ui_style) + using.screen_loc = ui_combat_toggle + static_inventory += using + + using = new /obj/screen/drop() + using.icon = ui_style + using.screen_loc = ui_drop_throw + static_inventory += using + + pull_icon = new /obj/screen/pull() + pull_icon.icon = ui_style + pull_icon.update_icon(mymob) + pull_icon.screen_loc = ui_pull_resist + static_inventory += pull_icon + + throw_icon = new /obj/screen/throw_catch() + throw_icon.icon = ui_style + throw_icon.screen_loc = ui_drop_throw + hotkeybuttons += throw_icon + +////// + //INVENTORY +////// + build_hand_slots() + + using = new /obj/screen/human/toggle() + using.icon = ui_style + using.screen_loc = ui_inventory + static_inventory += using + + using = new /obj/screen/swap_hand() + using.icon = ui_style + using.icon_state = "swap_1" + using.screen_loc = ui_swaphand_position(owner,1) + static_inventory += using + + using = new /obj/screen/swap_hand() + using.icon = ui_style + using.icon_state = "swap_2" + using.screen_loc = ui_swaphand_position(owner,2) + static_inventory += using + + inv_box = new /obj/screen/inventory() + inv_box.name = "neck" + inv_box.icon = ui_style + inv_box.icon_state = "neck" + inv_box.screen_loc = ui_neck + inv_box.slot_id = SLOT_NECK + toggleable_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "back" + inv_box.icon = ui_style + inv_box.icon_state = "back" + inv_box.screen_loc = ui_back + inv_box.slot_id = SLOT_BACK + static_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "gloves" + inv_box.icon = ui_style + inv_box.icon_state = "gloves" + inv_box.screen_loc = ui_gloves + inv_box.slot_id = SLOT_GLOVES + toggleable_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "eyes" + inv_box.icon = ui_style + inv_box.icon_state = "glasses" + inv_box.screen_loc = ui_glasses + inv_box.slot_id = SLOT_GLASSES + toggleable_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "ears" + inv_box.icon = ui_style + inv_box.icon_state = "ears" + inv_box.screen_loc = ui_ears + inv_box.slot_id = SLOT_EARS + toggleable_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "head" + inv_box.icon = ui_style + inv_box.icon_state = "head" + inv_box.screen_loc = ui_head + inv_box.slot_id = SLOT_HEAD + toggleable_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "belt" + inv_box.icon = ui_style + inv_box.icon_state = "belt" + inv_box.screen_loc = ui_belt + inv_box.slot_id = SLOT_BELT + static_inventory += inv_box + + //INFO DISPLAY + + internals = new /obj/screen/internals() + infodisplay += internals + + healths = new /obj/screen/healths() + infodisplay += healths + + healthdoll = new /obj/screen/healthdoll() + infodisplay += healthdoll + + zone_select = new /obj/screen/zone_sel() + zone_select.icon = ui_style + zone_select.update_icon(mymob) + static_inventory += zone_select + + for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory)) + if(inv.slot_id) + inv.hud = src + inv_slots[inv.slot_id] = inv + inv.update_icon() + +/datum/hud/wendigo/hidden_inventory_update(mob/viewer) + if(!mymob) + return + var/mob/living/carbon/wendigo/W = mymob + + var/mob/screenmob = viewer || W + + if(screenmob.hud_used.inventory_shown && screenmob.hud_used.hud_shown) + if(W.gloves) + W.gloves.screen_loc = ui_gloves + screenmob.client.screen += W.gloves + if(W.ears) + W.ears.screen_loc = ui_ears + screenmob.client.screen += W.ears + if(W.glasses) + W.glasses.screen_loc = ui_glasses + screenmob.client.screen += W.glasses + if(W.wear_neck) + W.wear_neck.screen_loc = ui_neck + screenmob.client.screen += W.wear_neck + if(W.head) + W.head.screen_loc = ui_head + screenmob.client.screen += W.head + else + if(W.gloves) screenmob.client.screen -= W.gloves + if(W.ears) screenmob.client.screen -= W.ears + if(W.glasses) screenmob.client.screen -= W.glasses + if(W.wear_neck) screenmob.client.screen -= W.wear_neck + if(W.head) screenmob.client.screen -= W.head + +/datum/hud/wendigo/persistent_inventory_update(mob/viewer) + if(!mymob) + return + ..() + var/mob/living/carbon/wendigo/W = mymob + + var/mob/screenmob = viewer || W + + if(screenmob.hud_used) + if(screenmob.hud_used.hud_shown) + if(W.belt) + W.belt.screen_loc = ui_belt + screenmob.client.screen += W.belt + if(W.back) + W.back.screen_loc = ui_back + screenmob.client.screen += W.back + else + if(W.belt) + screenmob.client.screen -= W.belt + if(W.back) + screenmob.client.screen -= W.back + + if(hud_version != HUD_STYLE_NOHUD) + for(var/obj/item/I in W.held_items) + I.screen_loc = ui_hand_position(W.get_held_index_of_item(I)) + screenmob.client.screen += I + else + for(var/obj/item/I in W.held_items) + I.screen_loc = null + screenmob.client.screen -= I + +/datum/hud/wendigo/show_hud(version = 0,mob/viewmob) + . = ..() + if(!.) + return + var/mob/screenmob = viewmob || mymob + hidden_inventory_update(screenmob) diff --git a/hyperstation/code/modules/antagonists/wendigo/forest/structures/soul_storage.dm b/hyperstation/code/modules/antagonists/wendigo/forest/structures/soul_storage.dm new file mode 100644 index 00000000..49b097f5 --- /dev/null +++ b/hyperstation/code/modules/antagonists/wendigo/forest/structures/soul_storage.dm @@ -0,0 +1,14 @@ +/obj/structure/soul_storage + name = "soul storage" + desc = "Stores souls!" + var/list/souls = list() + +//This is a big WIP. I don't even want it having the name "soul storage" but it'll do for now + +/obj/structure/soul_storage/Initialize() + . = ..() + GLOB.wendigo_soul_storages += src + +/obj/structure/soul_storage/Destroy() + GLOB.wendigo_soul_storages -= src + return ..() diff --git a/hyperstation/code/modules/antagonists/wendigo/mob/_on_click.dm b/hyperstation/code/modules/antagonists/wendigo/mob/_on_click.dm new file mode 100644 index 00000000..13257de9 --- /dev/null +++ b/hyperstation/code/modules/antagonists/wendigo/mob/_on_click.dm @@ -0,0 +1,11 @@ +/mob/living/carbon/wendigo/UnarmedAttack(atom/A, proximity) + A.attack_hand(src) + +/mob/living/carbon/wendigo/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) + if(incapacitated() || lying) + to_chat(src, "You can't do that right now!") + return FALSE + if(be_close && !in_range(M, src)) + to_chat(src, "You are too far away!") + return FALSE + return TRUE diff --git a/hyperstation/code/modules/antagonists/wendigo/mob/defines_init.dm b/hyperstation/code/modules/antagonists/wendigo/mob/defines_init.dm new file mode 100644 index 00000000..a2424dc8 --- /dev/null +++ b/hyperstation/code/modules/antagonists/wendigo/mob/defines_init.dm @@ -0,0 +1,115 @@ +#define DEFAULT_MOVESPEED 1.5 +//The mob itself +/mob/living/carbon/wendigo + name = "wendigo" + gender = FEMALE + unique_name = FALSE + hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD, NANITE_HUD, DIAG_NANITE_FULL_HUD,ANTAG_HUD,GLAND_HUD,SENTIENT_DISEASE_HUD) + hud_type = /datum/hud/wendigo + possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM) + appearance_flags = TILE_BOUND|PIXEL_SCALE|LONG_GLIDE + status_flags = CANSTUN //cant be knocked down, unconscious, or be pushed + maxHealth = 200 + icon = 'hyperstation/icons/mobs/wendigo.dmi' + icon_state = "reference" + + bodyparts = list(/obj/item/bodypart/chest/wendigo, /obj/item/bodypart/head/wendigo, + /obj/item/bodypart/l_arm/wendigo, /obj/item/bodypart/r_arm/wendigo, + /obj/item/bodypart/l_leg/wendigo, /obj/item/bodypart/r_leg/wendigo) + var/obj/item/belt = null + var/datum/physiology/physiology + var/obj/structure/soul_storage/connected_link + var/fake_breast_size = 5 //She doesn't actually have the organ, but we cache her breast size for rp reasons + var/fake_penis_size = 8 + +/mob/living/carbon/wendigo/Initialize() + . = ..() + /* //TODO: Uncomment when objectives + forest get finished + if(!connected_link) + if(!GLOB.wendigo_soul_storages.len) + connected_link = new /obj/structure/soul_storage(get_turf(src)) + else + connected_link = pick(GLOB.wendigo_soul_storages) + gender = pick(FEMALE, MALE) + */ + if(gender == MALE) + fake_breast_size = 0 + else + fake_penis_size = 0 + real_name = name + //DAMAGE RESISTANCE + physiology = new() + physiology.brute_mod = 0.7 + physiology.burn_mod = 1.25 + physiology.tox_mod = -1 + physiology.oxy_mod = 1 + physiology.clone_mod = 0 + physiology.stamina_mod = 0 //Running and attacking, prods + physiology.heat_mod = 2 //IM MELTIIINNNGGGG-! + physiology.cold_mod = 0 + physiology.siemens_coeff = 0.2 + physiology.stun_mod = 0 //prods n aggressive grab + //physiology.bleed_mod = 2 + physiology.speed_mod = 0.9 //Should be faster than a normal person's walking speed + physiology.hunger_mod = 2 //We're gonna have a FEAST TONIGHT! + physiology.do_after_speed = 1 + + //Traits & Bodyparts + create_bodyparts() + create_internal_organs() + ADD_TRAIT(src, TRAIT_NOCLONE, "initialize") + add_verb(src, /mob/living/proc/mob_sleep) + add_verb(src, /mob/living/proc/lay_down) + add_movespeed_modifier("MOVESPEED_DEFAULT", multiplicative_slowdown=DEFAULT_MOVESPEED) + update_body_parts() + +/mob/living/carbon/wendigo/Destroy() + QDEL_NULL(physiology) + return ..() + +/mob/living/carbon/wendigo/update_body_parts() + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + BP.update_limb() + +/mob/living/carbon/wendigo/update_move_intent_slowdown() + var/mod = 0 + if(m_intent == MOVE_INTENT_WALK) + mod = (CONFIG_GET(number/movedelay/walk_delay) / 2) //complete copy besides this part + else + mod = 1.30 + if(!isnum(mod)) + mod = 1 + add_movespeed_modifier(MOVESPEED_ID_MOB_WALK_RUN_CONFIG_SPEED, TRUE, 100, override = TRUE, multiplicative_slowdown = mod) + +/mob/living/carbon/wendigo/update_movespeed(resort=TRUE) + return (..() * physiology.speed_mod) + +/mob/living/carbon/wendigo/can_hold_items() + return TRUE +/mob/living/carbon/wendigo/IsAdvancedToolUser() + return TRUE +/mob/living/carbon/wendigo/can_be_pulled() + return FALSE +/mob/living/carbon/wendigo/is_literate() + return TRUE +/mob/living/carbon/wendigo/canBeHandcuffed() + return TRUE +/mob/living/carbon/wendigo/update_inv_handcuffed() + return +/mob/living/carbon/wendigo/update_inv_legcuffed() + return + +// +//ORGANS +// +/mob/living/carbon/wendigo/create_internal_organs() + internal_organs += new /obj/item/organ/eyes/wendigo + internal_organs += new /obj/item/organ/liver/wendigo + + internal_organs += new /obj/item/organ/tongue + internal_organs += new /obj/item/organ/lungs + internal_organs += new /obj/item/organ/heart + internal_organs += new /obj/item/organ/stomach + internal_organs += new /obj/item/organ/ears + ..() diff --git a/hyperstation/code/modules/antagonists/wendigo/mob/examine.dm b/hyperstation/code/modules/antagonists/wendigo/mob/examine.dm new file mode 100644 index 00000000..f32f4eb9 --- /dev/null +++ b/hyperstation/code/modules/antagonists/wendigo/mob/examine.dm @@ -0,0 +1,86 @@ +/mob/living/carbon/wendigo/examine(mob/user) + var/t_He = p_they(TRUE) + var/t_His = p_their(TRUE) + var/t_his = p_their() + var/t_him = p_them() + + . = list("*---------*\nThis is [icon2html(src, user)] \a [src]!") + + if(handcuffed) + . += "[t_He] is [icon2html(handcuffed, user)] handcuffed!" + if(legcuffed) + . += "[t_He] has [icon2html(legcuffed, user)] leg cuffs!" + if(head) + . += "[t_He] is wearing [head.get_examine_string(user)] on [t_his] head." + if(wear_neck) + . += "[t_He] is wearing [wear_neck.get_examine_string(user)] around [t_his] neck." + + for(var/obj/item/I in held_items) + if(!(I.item_flags & ABSTRACT)) + . += "[t_He] is holding [I.get_examine_string(user)] in [t_his] [get_held_index_name(get_held_index_of_item(I))]." + + if(back) + . += "[t_He] has [back.get_examine_string(user)] on [t_his] back." + + if(stat == DEAD) + . += "[t_He] is limp and unresponsive, with no signs of life." + + var/list/msg = ("") + var/temp_hp = getBruteLoss() + if(!(user == src && src.hal_screwyhud == SCREWYHUD_HEALTHY)) + if(temp_hp) + if(temp_hp <= 25) msg += "[t_He] has minor bruising.\n" + else if(temp_hp <= 75) msg += "[t_He] has moderate bruising!\n" + else msg += "[t_He] has severe bruising!\n" + temp_hp = getFireLoss() + if(temp_hp) + if(temp_hp <= 25) msg += "[t_He] has minor burns.\n" + else if(temp_hp <= 50) msg += "[t_He] has moderate burns!\n" + else msg += "[t_He] has severe burns!\n" + if(fire_stacks > 0) + msg += "[t_He] is covered in something flammable.\n" + if(fire_stacks < 0) + msg += "[t_He] looks a little soaked.\n" + if(pulledby) + if(pulledby.grab_state) + msg += "[t_He] is restrained by [pulledby]'s grip.\n" + + msg += "" + . += msg + + if(stat == UNCONSCIOUS) + . += "[t_He] isn't responding to anything around [t_him] and seems to be asleep." + else if(InCritical()) + . += "[t_His] breathing is shallow and labored." + + + if(fake_breast_size < 16) + . += "You see a pair of breasts. You estimate them to be [ascii2text(round(fake_breast_size)+63)]-cups." + else if(!fake_breast_size && gender == FEMALE) + . += "You see a pair of breasts. They're small and flatchested, however." + else + . += "You see [pick("some serious honkers", "a real set of badonkers", "some dobonhonkeros", "massive dohoonkabhankoloos", "two big old tonhongerekoogers", "a couple of giant bonkhonagahoogs", "a pair of humongous hungolomghnonoloughongous")]. Their volume is way beyond cupsize now, measuring in about [round(fake_breast_size)]cm in diameter." + + if(fake_penis_size) + . += "You see a flaccid human penis. You estimate it's about [round(fake_penis_size, 0.25)] inch[round(fake_penis_size, 0.25) != 1 ? "es" : ""] long." //would put girth here but lazy + + if(connected_link) + if(connected_link.souls.len > 5) + . += "[t_His] eyes are glowing a deadly red." + else + var/A = "" + switch(connected_link.souls.len) + if(0) + A += "[t_He] looks malnourished and weak." + if(1) + A += "[t_He] looks hungry." + if(2 to 4) + A += "[t_He] is salivating." + if(5) + A += "[t_His] eyes are glowing red." + . += "[A]" + else + . += "[t_He] looks lost." + + SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, .) + . += "*---------*" diff --git a/hyperstation/code/modules/antagonists/wendigo/mob/metabolization.dm b/hyperstation/code/modules/antagonists/wendigo/mob/metabolization.dm new file mode 100644 index 00000000..691a15ce --- /dev/null +++ b/hyperstation/code/modules/antagonists/wendigo/mob/metabolization.dm @@ -0,0 +1,55 @@ +//Snowflake metabolization with naughty organ manipulation +/mob/living/carbon/wendigo/proc/metabolize_hunger() + if(HAS_TRAIT(src, TRAIT_NOHUNGER)) + return + + if(connected_link) + if(connected_link.souls.len > 3) + nutrition = min(800, nutrition + (HUNGER_FACTOR*connected_link.souls.len)) + nutrition = max(0, nutrition - (HUNGER_FACTOR / (physiology.hunger_mod / (connected_link.souls.len + 1)))) + else + nutrition = max(0, nutrition - (HUNGER_FACTOR / physiology.hunger_mod)) + + switch(nutrition) + if(NUTRITION_LEVEL_FULL to INFINITY) + throw_alert("nutrition", /obj/screen/alert/fat) + if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FULL) + clear_alert("nutrition") + if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_STARVING) + throw_alert("nutrition", /obj/screen/alert/hungry) + if(0 to NUTRITION_LEVEL_STARVING) + throw_alert("nutrition", /obj/screen/alert/starving) + +/mob/living/carbon/wendigo/reagent_check(datum/reagent/R) + if(istype(R, /datum/reagent/fermi)) + var/had_changed = FALSE + if(R.type == /datum/reagent/fermi/penis_enlarger) + fake_penis_size += 0.25 + had_changed = "penis_enlarger" + if(R.type == /datum/reagent/fermi/PEsmaller) + fake_penis_size = max(0, fake_penis_size - 0.25) + had_changed = "PEsmaller" + if(R.type == /datum/reagent/fermi/breast_enlarger) + fake_breast_size += 0.25 + had_changed = "breast_enlarger" + if(R.type == /datum/reagent/fermi/BEsmaller) + fake_breast_size = max(0, fake_breast_size - 0.25) + had_changed = "BEsmaller" + + if(had_changed) + R.volume -= R.metabolization_rate + if(round(fake_penis_size, 1) == fake_penis_size && fake_penis_size) + switch(had_changed) + if("penis_enlarger") + to_chat(src, "Your [pick(GLOB.gentlemans_organ_names)] [pick("swells up to", "flourishes into", "expands into", "bursts forth into", "grows eagerly into", "amplifys into")] a [fake_penis_size] inch penis.") + if("PEsmaller") + if(fake_penis_size > 0) + to_chat(src, "Your [pick(GLOB.gentlemans_organ_names)] [pick("shrinks down to", "decreases into", "diminishes into", "deflates into", "shrivels regretfully into", "contracts into")] a [fake_penis_size] inch penis.") + else if(round(fake_breast_size, 1) == fake_breast_size && fake_breast_size) + switch(had_changed) + if("breast_enlarger") + to_chat(src, "Your breasts [pick("swell up to", "flourish into", "expand into", "burst forth into", "grow eagerly into", "amplify into")] a [ascii2text(round(fake_breast_size)+63)]-cup.") + if("BEsmaller)") + if(fake_breast_size > 0) + to_chat(src, "Your breasts [pick("shrink down to", "decrease into", "diminish into", "deflate into", "shrivel regretfully into", "contracts into")] a [ascii2text(round(fake_breast_size)+63)]-cup.") + return TRUE diff --git a/hyperstation/code/modules/antagonists/wendigo/mob/mob_defense.dm b/hyperstation/code/modules/antagonists/wendigo/mob/mob_defense.dm new file mode 100644 index 00000000..d59e4bf4 --- /dev/null +++ b/hyperstation/code/modules/antagonists/wendigo/mob/mob_defense.dm @@ -0,0 +1,125 @@ +/mob/living/carbon/wendigo/handle_environment(datum/gas_mixture/environment) + if(!environment) + return + + var/loc_temp = get_temperature(environment) + + if(stat != DEAD) + adjust_bodytemperature(natural_bodytemperature_stabilization()) + + if(!on_fire) //If you're on fire, you do not heat up or cool down based on surrounding gases + if(loc_temp < bodytemperature) + adjust_bodytemperature(max((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR, BODYTEMP_COOLING_MAX)) + else + adjust_bodytemperature(min((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR, BODYTEMP_HEATING_MAX)) + + + if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !HAS_TRAIT(src, TRAIT_RESISTHEAT)) + switch(bodytemperature) + if(280 to 300) + throw_alert("temp", /obj/screen/alert/hot, 1) + apply_damage(HEAT_DAMAGE_LEVEL_1*physiology.heat_mod, BURN) + if(300 to 350) + throw_alert("temp", /obj/screen/alert/hot, 2) + apply_damage(HEAT_DAMAGE_LEVEL_2*physiology.heat_mod, BURN) + if(350 to INFINITY) + throw_alert("temp", /obj/screen/alert/hot, 3) + if(on_fire) + apply_damage(HEAT_DAMAGE_LEVEL_3*physiology.heat_mod, BURN) + else + apply_damage(HEAT_DAMAGE_LEVEL_2*physiology.heat_mod, BURN) + + else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(src, TRAIT_RESISTCOLD)) + if(!istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell)) + switch(bodytemperature) + if(200 to 260) + throw_alert("temp", /obj/screen/alert/cold, 1) + apply_damage(COLD_DAMAGE_LEVEL_1*physiology.cold_mod, BURN) + if(0 to 120) + throw_alert("temp", /obj/screen/alert/cold, 2) + apply_damage(COLD_DAMAGE_LEVEL_2*physiology.cold_mod, BURN) + if(-INFINITY to 0) + throw_alert("temp", /obj/screen/alert/cold, 3) + apply_damage(COLD_DAMAGE_LEVEL_3*physiology.cold_mod, BURN) + else + clear_alert("temp") + + else + clear_alert("temp") + + //Account for massive pressure differences + + var/pressure = environment.return_pressure() + var/adjusted_pressure = calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob. + switch(adjusted_pressure) + if(HAZARD_HIGH_PRESSURE to INFINITY) + adjustBruteLoss(min((((adjusted_pressure / HAZARD_HIGH_PRESSURE)-1)*PRESSURE_DAMAGE_COEFFICIENT)*physiology.pressure_mod, MAX_HIGH_PRESSURE_DAMAGE)) + throw_alert("pressure", /obj/screen/alert/highpressure, 2) + if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE) + throw_alert("pressure", /obj/screen/alert/highpressure, 1) + if(WARNING_LOW_PRESSURE to WARNING_HIGH_PRESSURE) + clear_alert("pressure") + if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE) + throw_alert("pressure", /obj/screen/alert/lowpressure, 1) + else + adjustBruteLoss( LOW_PRESSURE_DAMAGE*physiology.pressure_mod ) + throw_alert("pressure", /obj/screen/alert/lowpressure, 2) + + return + +/mob/living/carbon/wendigo/handle_breath_temperature(datum/gas_mixture/breath) + if(abs(BODYTEMP_NORMAL - breath.temperature) > 50) + switch(breath.temperature) + if(-INFINITY to 0) + adjustFireLoss(3) + if(0 to 120) //We flourish in a cold environment + adjustFireLoss(1.5) + if(298 to 350) //But hoo boy do we not like the heat + adjustFireLoss(2) + if(350 to 800) + adjustFireLoss(3) + if(800 to INFINITY) + adjustFireLoss(8) + +/mob/living/carbon/wendigo/handle_fire() + if(..()) + return + adjust_bodytemperature(BODYTEMP_HEATING_MAX*physiology.heat_mod) + return + +/mob/living/carbon/wendigo/adjustBruteLoss(amount, updating_health, forced) + return ..(amount*physiology.brute_mod, updating_health, forced) + +/mob/living/carbon/wendigo/adjustFireLoss(amount, updating_health, forced) + return ..(amount*physiology.burn_mod, updating_health, forced) + +/mob/living/carbon/wendigo/adjustToxLoss(amount, updating_health, forced) + return ..(amount*physiology.tox_mod, updating_health, forced) + +/mob/living/carbon/wendigo/adjustOxyLoss(amount, updating_health, forced) + return ..(amount*physiology.oxy_mod, updating_health, forced) + +/mob/living/carbon/wendigo/adjustCloneLoss(amount, updating_health, forced) + return ..(amount*physiology.clone_mod, updating_health, forced) + +/mob/living/carbon/wendigo/adjustStaminaLoss(amount, updating_health, forced) + return ..(amount*physiology.stamina_mod, updating_health, forced) + +/mob/living/carbon/wendigo/do_after_coefficent() + . = ..() + . *= physiology.do_after_speed + +/mob/living/carbon/wendigo/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE) + return ..(shock_damage, source, physiology.siemens_coeff, safety, override, tesla_shock, illusion, stun) + +/mob/living/carbon/wendigo/Stun(amount, updating, ignore_canstun) + return ..(amount*physiology.stun_mod, updating, ignore_canstun) + +/mob/living/carbon/wendigo/Knockdown(amount, updating, ignore_canknockdown, override_hardstun, override_stamdmg) + return ..(amount*physiology.stun_mod, updating, ignore_canknockdown, override_hardstun, override_stamdmg) + +/mob/living/carbon/wendigo/Unconscious(amount, updating, ignore_canunconscious) + return ..(amount*physiology.stun_mod, updating, ignore_canunconscious) + +/mob/living/carbon/wendigo/bleed(amt) + return ..(amt*physiology.bleed_mod) diff --git a/hyperstation/code/modules/antagonists/wendigo/mob/mob_equip.dm b/hyperstation/code/modules/antagonists/wendigo/mob/mob_equip.dm new file mode 100644 index 00000000..68c14659 --- /dev/null +++ b/hyperstation/code/modules/antagonists/wendigo/mob/mob_equip.dm @@ -0,0 +1,100 @@ +/mob/living/carbon/wendigo/can_equip(obj/item/I, slot, disable_warning) + switch(slot) + if(SLOT_HANDS) + if(get_empty_held_indexes()) + return TRUE + return FALSE + if(SLOT_GLASSES) + if(glasses) + return FALSE + if(!(I.slot_flags & ITEM_SLOT_EYES)) + return FALSE + return TRUE + if(SLOT_NECK) + if(wear_neck) + return FALSE + if(!(I.slot_flags & ITEM_SLOT_NECK)) + return FALSE + return TRUE + if(SLOT_EARS) + if(ears) + return FALSE + if(!(I.slot_flags & ITEM_SLOT_EARS)) + return FALSE + return TRUE + if(SLOT_GLOVES) + if(gloves) + return FALSE + if(!(I.slot_flags & ITEM_SLOT_GLOVES)) + return FALSE + return TRUE + if(SLOT_BACK) + if(back) + return FALSE + if(!(I.slot_flags & ITEM_SLOT_BACK)) + return FALSE + return TRUE + if(SLOT_IN_BACKPACK) + if(back) + if(SEND_SIGNAL(back, COMSIG_TRY_STORAGE_CAN_INSERT, I, src, TRUE)) + return TRUE + return FALSE + if(SLOT_HEAD) + if(head) + return FALSE + if(!(I.slot_flags & ITEM_SLOT_HEAD)) + return FALSE + return TRUE + if(SLOT_BELT) + if(belt) + return FALSE + if(!(I.slot_flags & ITEM_SLOT_BELT)) + return FALSE + return TRUE + return FALSE + +/mob/living/carbon/wendigo/equip_to_slot(obj/item/I, slot) + if(!..()) + return + switch(slot) + if(SLOT_GLASSES) + glasses = I + update_inv_glasses() + if(SLOT_EARS) + ears = I + update_inv_ears() + if(SLOT_GLOVES) + gloves = I + update_inv_gloves() + return TRUE + +/mob/living/carbon/wendigo/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE) + . = ..() + if(!. || !I) + return + + else if(I == gloves) + gloves = null + if(!QDELETED(src)) + update_inv_gloves() + else if(I == glasses) + glasses = null + var/obj/item/clothing/glasses/G = I + if(G.tint) + update_tint() + if(G.vision_correction) + if(HAS_TRAIT(src, TRAIT_NEARSIGHT)) + overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1) + adjust_eye_damage(0) + if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha)) + update_sight() + if(!QDELETED(src)) + update_inv_glasses() + else if(I == ears) + ears = null + if(!QDELETED(src)) + update_inv_ears() + else if(I == belt) + belt = null + if(!QDELETED(src)) + update_inv_belt() diff --git a/hyperstation/code/modules/antagonists/wendigo/mob/organs_bodyparts.dm b/hyperstation/code/modules/antagonists/wendigo/mob/organs_bodyparts.dm new file mode 100644 index 00000000..aa23dc1c --- /dev/null +++ b/hyperstation/code/modules/antagonists/wendigo/mob/organs_bodyparts.dm @@ -0,0 +1,58 @@ +/obj/item/organ/liver/wendigo + name = "rotten liver" + desc = "A liver from a wendigo. It looks like a spoiled tomato." + decay_factor = 0 + +/obj/item/organ/liver/wendigo/on_life() + var/mob/living/carbon/C = owner + if(istype(C)) + damage = initial(maxHealth) + + if(filterToxins && !HAS_TRAIT(owner, TRAIT_TOXINLOVER)) + //handle liver toxin filtration + for(var/datum/reagent/toxin/T in C.reagents.reagent_list) + var/thisamount = C.reagents.get_reagent_amount(T.type) + if (thisamount && thisamount <= toxTolerance) + C.reagents.remove_reagent(T.type, 1) + + C.reagents.metabolize(C, can_overdose=FALSE) + if(istype(C, /mob/living/carbon/wendigo)) + var/mob/living/carbon/wendigo/A = C + A.metabolize_hunger() + +/obj/item/organ/eyes/wendigo + sight_flags = SEE_MOBS + +/obj/item/bodypart/head/wendigo + dismemberable = FALSE + max_damage = INFINITY + animal_origin = WENDIGO_BODYPART + +/obj/item/bodypart/chest/wendigo + dismemberable = FALSE + max_damage = INFINITY + animal_origin = WENDIGO_BODYPART + +/obj/item/bodypart/l_arm/wendigo + dismemberable = FALSE + max_damage = INFINITY + attack_verb = list("slashed", "clawed", "mauled") + animal_origin = WENDIGO_BODYPART + +/obj/item/bodypart/r_arm/wendigo + dismemberable = FALSE + max_damage = INFINITY + attack_verb = list("slashed", "clawed", "mauled") + animal_origin = WENDIGO_BODYPART + +/obj/item/bodypart/l_leg/wendigo + dismemberable = FALSE + max_damage = INFINITY + attack_verb = list("pounded", "stomped", "stamped", "kicked") + animal_origin = WENDIGO_BODYPART + +/obj/item/bodypart/r_leg/wendigo + dismemberable = FALSE + max_damage = INFINITY + attack_verb = list("pounded", "stomped", "stamped", "kicked") + animal_origin = WENDIGO_BODYPART diff --git a/hyperstation/code/modules/antagonists/wendigo/mob/update_icons.dm b/hyperstation/code/modules/antagonists/wendigo/mob/update_icons.dm new file mode 100644 index 00000000..d588d745 --- /dev/null +++ b/hyperstation/code/modules/antagonists/wendigo/mob/update_icons.dm @@ -0,0 +1,370 @@ +#define HEAD_X_OFFSET_NORTH 2 +#define HEAD_Y_OFFSET_NORTH 8 +#define HEAD_X_OFFSET_EAST 2 +#define HEAD_Y_OFFSET_EAST 8 +#define HEAD_X_OFFSET_SOUTH 8 +#define HEAD_Y_OFFSET_SOUTH 2 +#define HEAD_X_OFFSET_WEST 8 +#define HEAD_Y_OFFSET_WEST -2 + +#define LHAND_X_OFFSET_NORTH -5 +#define LHAND_Y_OFFSET_NORTH 3 +#define LHAND_X_OFFSET_EAST -2 +#define LHAND_Y_OFFSET_EAST 3 +#define LHAND_X_OFFSET_SOUTH 8 +#define LHAND_Y_OFFSET_SOUTH 3 +#define LHAND_X_OFFSET_WEST -2 +#define LHAND_Y_OFFSET_WEST 3 + +#define RHAND_X_OFFSET_NORTH 8 +#define RHAND_Y_OFFSET_NORTH 3 +#define RHAND_X_OFFSET_EAST 2 +#define RHAND_Y_OFFSET_EAST 3 +#define RHAND_X_OFFSET_SOUTH -5 +#define RHAND_Y_OFFSET_SOUTH 3 +#define RHAND_X_OFFSET_WEST 2 +#define RHAND_Y_OFFSET_WEST 3 + +#define EARS_X_OFFSET_NORTH 0 +#define EARS_Y_OFFSET_NORTH 0 +#define EARS_X_OFFSET_EAST 0 +#define EARS_Y_OFFSET_EAST 0 +#define EARS_X_OFFSET_SOUTH 0 +#define EARS_Y_OFFSET_SOUTH 0 +#define EARS_X_OFFSET_WEST 0 +#define EARS_Y_OFFSET_WEST 0 + +#define GLASSES_X_OFFSET_NORTH 5 +#define GLASSES_Y_OFFSET_NORTH 10 +#define GLASSES_X_OFFSET_EAST 1 +#define GLASSES_Y_OFFSET_EAST 10 +#define GLASSES_X_OFFSET_SOUTH -2 +#define GLASSES_Y_OFFSET_SOUTH 10 +#define GLASSES_X_OFFSET_WEST -1 +#define GLASSES_Y_OFFSET_WEST 10 + +#define BELT_X_OFFSET_NORTH 0 +#define BELT_Y_OFFSET_NORTH 10 +#define BELT_X_OFFSET_EAST 0 +#define BELT_Y_OFFSET_EAST 0 +#define BELT_X_OFFSET_SOUTH 0 +#define BELT_Y_OFFSET_SOUTH 0 +#define BELT_X_OFFSET_WEST 0 +#define BELT_Y_OFFSET_WEST 0 + +#define BACK_X_OFFSET_NORTH 1 +#define BACK_Y_OFFSET_NORTH 8 +#define BACK_X_OFFSET_EAST 0 +#define BACK_Y_OFFSET_EAST 8 +#define BACK_X_OFFSET_SOUTH 1 +#define BACK_Y_OFFSET_SOUTH 8 +#define BACK_X_OFFSET_WEST 0 +#define BACK_Y_OFFSET_WEST 8 + +#define NECK_X_OFFSET_NORTH 2 +#define NECK_Y_OFFSET_NORTH 10 +#define NECK_X_OFFSET_EAST 0 +#define NECK_Y_OFFSET_EAST 10 +#define NECK_X_OFFSET_SOUTH 2 +#define NECK_Y_OFFSET_SOUTH 10 +#define NECK_X_OFFSET_WEST 0 +#define NECK_Y_OFFSET_WEST 10 + +/mob/living/carbon/wendigo/setDir(newdir, ismousemovement) + if(dir == newdir) + return //Don't spend time regenerating icons when we don't move + . = ..() + regenerate_icons() + +/mob/living/carbon/wendigo/regenerate_icons() + if(!..()) + update_inv_head() + update_inv_gloves() + update_inv_ears() + update_inv_glasses() + update_inv_belt() + update_inv_back() + update_inv_neck() + update_transform() + +/mob/living/carbon/wendigo/update_inv_gloves() + if(gloves) + gloves.screen_loc = ui_gloves + if(client && hud_used && hud_used.hud_shown) + if(hud_used.inventory_shown) + client.screen += gloves + +//GLASSES +/mob/living/carbon/wendigo/update_inv_glasses() + if(glasses) + glasses.screen_loc = ui_glasses + if(client && hud_used && hud_used.hud_shown) + if(hud_used.inventory_shown) + client.screen += glasses + +//EARS +/mob/living/carbon/wendigo/update_inv_ears() + remove_overlay(EARS_LAYER) + if(ears) + if(client && hud_used) + var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_EARS] + inv.update_icon() + ears.screen_loc = ui_ears //move the item to the appropriate screen loc + if(client && hud_used && hud_used.hud_shown) + if(hud_used.inventory_shown) + client.screen += ears + + overlays_standing[EARS_LAYER] = ears.build_worn_icon(state = ears.icon_state, default_layer = EARS_LAYER, default_icon_file = ((ears.alternate_worn_icon) ? ears.alternate_worn_icon : 'icons/mob/ears.dmi')) + var/mutable_appearance/ears_overlay = overlays_standing[EARS_LAYER] + switch(dir) + if(NORTH) + ears_overlay.pixel_x += EARS_X_OFFSET_NORTH + ears_overlay.pixel_y += EARS_Y_OFFSET_NORTH + if(EAST) + ears_overlay.pixel_x += EARS_X_OFFSET_EAST + ears_overlay.pixel_y += EARS_Y_OFFSET_EAST + if(SOUTH) + ears_overlay.pixel_x += EARS_X_OFFSET_SOUTH + ears_overlay.pixel_y += EARS_Y_OFFSET_SOUTH + if(WEST) + ears_overlay.pixel_x += EARS_X_OFFSET_WEST + ears_overlay.pixel_y += EARS_Y_OFFSET_WEST + overlays_standing[EARS_LAYER] = ears_overlay + apply_overlay(EARS_LAYER) + +//BELT +/mob/living/carbon/wendigo/update_inv_belt() + remove_overlay(BELT_LAYER) + + if(belt) + belt.screen_loc = ui_belt + if(client && hud_used && hud_used.hud_shown) + if(hud_used.inventory_shown) + client.screen += belt + + var/t_state = belt.item_state + if(!t_state) + t_state = belt.icon_state + + overlays_standing[BELT_LAYER] = belt.build_worn_icon(state = t_state, default_layer = BELT_LAYER, default_icon_file = ((belt.alternate_worn_icon) ? belt.alternate_worn_icon : 'icons/mob/belt.dmi')) + var/mutable_appearance/belt_overlay = overlays_standing[BELT_LAYER] + switch(dir) + if(NORTH) + belt_overlay.pixel_x += BELT_X_OFFSET_NORTH + belt_overlay.pixel_y += BELT_Y_OFFSET_NORTH + if(EAST) + belt_overlay.pixel_x += BELT_X_OFFSET_EAST + belt_overlay.pixel_y += BELT_Y_OFFSET_EAST + if(SOUTH) + belt_overlay.pixel_x += BELT_X_OFFSET_SOUTH + belt_overlay.pixel_y += BELT_Y_OFFSET_SOUTH + if(WEST) + belt_overlay.pixel_x += BELT_X_OFFSET_WEST + belt_overlay.pixel_y += BELT_Y_OFFSET_WEST + overlays_standing[BELT_LAYER] = belt_overlay + apply_overlay(BELT_LAYER) + +//BACK +/mob/living/carbon/wendigo/update_inv_back() + ..() + if(back) + back.screen_loc = ui_back + if(client && hud_used && hud_used.hud_shown) + if(hud_used.inventory_shown) + client.screen += back + var/mutable_appearance/back_overlay = overlays_standing[BACK_LAYER] + if(back_overlay) + remove_overlay(BACK_LAYER) + switch(dir) + if(NORTH) + back_overlay.pixel_x += BACK_X_OFFSET_NORTH + back_overlay.pixel_y += BACK_Y_OFFSET_NORTH + if(EAST) + back_overlay.pixel_x += BACK_X_OFFSET_EAST + back_overlay.pixel_y += BACK_Y_OFFSET_EAST + if(SOUTH) + back_overlay.pixel_x += BACK_X_OFFSET_SOUTH + back_overlay.pixel_y += BACK_Y_OFFSET_SOUTH + if(WEST) + back_overlay.pixel_x += BACK_X_OFFSET_WEST + back_overlay.pixel_y += BACK_Y_OFFSET_WEST + overlays_standing[BACK_LAYER] = back_overlay + apply_overlay(BACK_LAYER) + +//NECK +/mob/living/carbon/wendigo/update_inv_neck() + ..() + if(wear_neck) + wear_neck.screen_loc = ui_neck + if(client && hud_used && hud_used.hud_shown) + if(hud_used.inventory_shown) + client.screen += wear_neck + var/mutable_appearance/neck_overlay = overlays_standing[NECK_LAYER] + if(neck_overlay) + remove_overlay(NECK_LAYER) + switch(dir) + if(NORTH) + neck_overlay.pixel_x += NECK_X_OFFSET_NORTH + neck_overlay.pixel_y += NECK_Y_OFFSET_NORTH + if(EAST) + neck_overlay.pixel_x += NECK_X_OFFSET_EAST + neck_overlay.pixel_y += NECK_Y_OFFSET_EAST + if(SOUTH) + neck_overlay.pixel_x += NECK_X_OFFSET_SOUTH + neck_overlay.pixel_y += NECK_Y_OFFSET_SOUTH + if(WEST) + neck_overlay.pixel_x += NECK_X_OFFSET_WEST + neck_overlay.pixel_y += NECK_Y_OFFSET_WEST + overlays_standing[NECK_LAYER] = neck_overlay + apply_overlay(NECK_LAYER) + +//HANDS +/mob/living/carbon/update_inv_hands() + remove_overlay(HANDS_LAYER) + if (handcuffed) + drop_all_held_items() + 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 + var/righthand = 0 + if(get_held_index_of_item(I) % 2 == 0) + icon_file = I.righthand_file + righthand = 1 + + var/mutable_appearance/thing = I.build_worn_icon(state = t_state, default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE) + if(righthand) + switch(dir) + if(NORTH) + thing.pixel_x += RHAND_X_OFFSET_NORTH + thing.pixel_y += RHAND_Y_OFFSET_NORTH + if(EAST) + thing = null //ghetto + if(SOUTH) + thing.pixel_x += RHAND_X_OFFSET_SOUTH + thing.pixel_y += RHAND_Y_OFFSET_SOUTH + if(WEST) + thing.pixel_x += RHAND_X_OFFSET_WEST + thing.pixel_y += RHAND_Y_OFFSET_WEST + else + switch(dir) + if(NORTH) + thing.pixel_x += LHAND_X_OFFSET_NORTH + thing.pixel_y += LHAND_Y_OFFSET_NORTH + if(EAST) + thing.pixel_x += LHAND_X_OFFSET_EAST + thing.pixel_y += LHAND_Y_OFFSET_EAST + if(SOUTH) + thing.pixel_x += LHAND_X_OFFSET_SOUTH + thing.pixel_y += LHAND_Y_OFFSET_SOUTH + if(WEST) + thing = null //ghetto + + hands += thing + + overlays_standing[HANDS_LAYER] = hands + apply_overlay(HANDS_LAYER) + +//HEAD +/mob/living/carbon/wendigo/update_inv_head() + remove_overlay(HEAD_LAYER) + + if(head) + head.screen_loc = ui_head + if(client && hud_used && hud_used.hud_shown) + if(hud_used.inventory_shown) + client.screen += head + var/mutable_appearance/head_icon = head.build_worn_icon(state = head.icon_state, default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/head.dmi') + switch(dir) + if(NORTH) + head_icon.pixel_x += HEAD_X_OFFSET_NORTH + head_icon.pixel_y += HEAD_Y_OFFSET_NORTH + if(EAST) + head_icon.pixel_x += HEAD_X_OFFSET_EAST + head_icon.pixel_y += HEAD_Y_OFFSET_EAST + if(SOUTH) + head_icon.pixel_x += HEAD_X_OFFSET_SOUTH + head_icon.pixel_y += HEAD_Y_OFFSET_SOUTH + if(WEST) + head_icon.pixel_x += HEAD_X_OFFSET_WEST + head_icon.pixel_y += HEAD_Y_OFFSET_WEST + overlays_standing[SLOT_HEAD] = head_icon + update_hud_head(head) + + apply_overlay(HEAD_LAYER) + +#undef LHAND_X_OFFSET_NORTH +#undef LHAND_Y_OFFSET_NORTH +#undef LHAND_X_OFFSET_EAST +#undef LHAND_Y_OFFSET_EAST +#undef LHAND_X_OFFSET_SOUTH +#undef LHAND_Y_OFFSET_SOUTH +#undef LHAND_X_OFFSET_WEST +#undef LHAND_Y_OFFSET_WEST +#undef RHAND_X_OFFSET_NORTH +#undef RHAND_Y_OFFSET_NORTH +#undef RHAND_X_OFFSET_EAST +#undef RHAND_Y_OFFSET_EAST +#undef RHAND_X_OFFSET_SOUTH +#undef RHAND_Y_OFFSET_SOUTH +#undef RHAND_X_OFFSET_WEST +#undef RHAND_Y_OFFSET_WEST +#undef EARS_X_OFFSET_NORTH +#undef EARS_Y_OFFSET_NORTH +#undef EARS_X_OFFSET_EAST +#undef EARS_Y_OFFSET_EAST +#undef EARS_X_OFFSET_SOUTH +#undef EARS_Y_OFFSET_SOUTH +#undef EARS_X_OFFSET_WEST +#undef EARS_Y_OFFSET_WEST +#undef GLASSES_X_OFFSET_NORTH +#undef GLASSES_Y_OFFSET_NORTH +#undef GLASSES_X_OFFSET_EAST +#undef GLASSES_Y_OFFSET_EAST +#undef GLASSES_X_OFFSET_SOUTH +#undef GLASSES_Y_OFFSET_SOUTH +#undef GLASSES_X_OFFSET_WEST +#undef GLASSES_Y_OFFSET_WEST +#undef BELT_X_OFFSET_NORTH +#undef BELT_Y_OFFSET_NORTH +#undef BELT_X_OFFSET_EAST +#undef BELT_Y_OFFSET_EAST +#undef BELT_X_OFFSET_SOUTH +#undef BELT_Y_OFFSET_SOUTH +#undef BELT_X_OFFSET_WEST +#undef BELT_Y_OFFSET_WEST +#undef BACK_X_OFFSET_NORTH +#undef BACK_Y_OFFSET_NORTH +#undef BACK_X_OFFSET_EAST +#undef BACK_Y_OFFSET_EAST +#undef BACK_X_OFFSET_SOUTH +#undef BACK_Y_OFFSET_SOUTH +#undef BACK_X_OFFSET_WEST +#undef BACK_Y_OFFSET_WEST +#undef NECK_X_OFFSET_NORTH +#undef NECK_Y_OFFSET_NORTH +#undef NECK_X_OFFSET_EAST +#undef NECK_Y_OFFSET_EAST +#undef NECK_X_OFFSET_SOUTH +#undef NECK_Y_OFFSET_SOUTH +#undef NECK_X_OFFSET_WEST +#undef NECK_Y_OFFSET_WEST diff --git a/hyperstation/icons/mobs/wendigo.dmi b/hyperstation/icons/mobs/wendigo.dmi new file mode 100644 index 0000000000000000000000000000000000000000..7c8de1d121c8af6dfff31b28777dd2ac5d44188a GIT binary patch literal 1988 zcmaKtdpOe#8^?d!j5#b!apGN%$2kCmSAkVGN1 zgyy%yl-30Kfm0002)MI?}S zl(jSYFvt$qY&nrTLJIH+^x*M$SK`Sd9mUc$ASKyNDr%NWrEZ31d-m*s!{OfE-qOuw z1Oky98GDxKZiLd88UU7B`btVls;a8a2H5tZD!hvukx1Oh!|3X{Iyt|M(s{RIKnY|& z3V;)jM(vnO7XyP62q)ryW1OTXoQyjI02fLqR5~MZZIwb_{yuHuZEDi@RzTqfSqxYU z|HcY@_H_e{Tz0d)HQ9R5`Y_H)J+upR4O5M)B9l%XJ4HHmoKb_&h&~)evLqJeSl1a_ z+95k_WwWcq22}9vD~`A~l@EpUGvFq9APt5JfL(#a0)T9h7Xcr5q2y~Zn>uZ*lF5lF zLgBTeH7mYJ?_7$*zt7JfzMUu-d#b2AcP2Xk6$I4_b5wf4jN2oPy1Gv)mIMr$Cg}w` zxisASsk-dgcx+|VZfx&_{{#Q&%=(Q2O@6OM**iwYtW{O5Sv)9Z(Bg5TZc)YLUEfck zt3Ax5T$!bHB#Qb1PUbWd% z_hGZqcJLmh{aC?)w?i~}i|gyF4T+q!6?+8F;eJ)i^nM$kDVV8|jF;8*K~hn}a%5Z` zGD{2;&Xa6FWxH00KL+@ zz$y8;R&Zjz-121;Plui_`-@Vx3uv(*+|n1L=dEqFAnv(lc>HFex7gSmxXy^7Bj%gO z?apbw!jw)AA6O6MZkyPFXP+I3J6P8-x!GKEegJi==Ip=rfm#VYG2Ff*fw6G-A z@Gf^47}Ze#5<_bYAKZDb&gxy0F%d75`k%1N1Ja3@xUtK1pWjiHh1GnQwYDcR&=XxrAP zOnly#gLho~wLj4D9)@su0M*c(y8K$;X!46tEs9SZK>*LVmsduHQ>W)Y59=aXoE9`z zIMpb$PgVEuSC+Wv^@5SgXm>eqv&s9y)0w0EKeE!}6i-%b^X4K9(w!{9LDt7_9w=$f zc#Z{pw-Q`!y{^sVk1Mjc*blBrviZIBHzH?FWCO%Sq$dQ|x^QIYXmk?BGF6jtVyWE1 z?8RE@=Gg>iS>});z3#X)$zd6^*MT@KRat6x$Kl4{EUneErEm&S1J$mwrfa#GeL_LDaO_5Ww}(W-*XX zpn-+O5pw;7BY>uvU+Ty4tO6ix6+|N{%pNsSQB=M-vafsYu6vu@n}m12{X677S1zA4 zOPaqAj-kH--N8KGGys-|{P2ZFBaNU0ccqV&8}Bt~`H*G(#H6Ee)>NPC8(W8S*>q*r zvlp{>osyPRS!jQ``@jMNR`2VIwaSF>xQj*>s-+XfdN-!+u}gF4pbmfU{$XeemvJ z6K={b^h+n1?ZqxT=+)>ip$kTmU%-X%4j0z(wsK~CoA8U| ze*w1i6=n`E_E6{&1Q#qq}u}#<>D$$sjicXnuqkd8rg>%eD+j!>N?ZU~j zUJY$&yO6`|cr`A0A^q>?e`5a6wj_P4@e8V97WViPvE$iJSpr@jeuPKvw6y;K;@p@t literal 0 HcmV?d00001 diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm index 5766ae47..3e2d266b 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm @@ -32,6 +32,8 @@ /datum/reagent/fermi/breast_enlarger/on_mob_add(mob/living/carbon/M) . = ..() + if(iswendigo(M)) + return if(!ishuman(M)) //The monkey clause if(volume >= 15) //To prevent monkey breast farms var/turf/T = get_turf(M) @@ -164,6 +166,8 @@ /datum/reagent/fermi/BEsmaller_hypo/on_mob_add(mob/living/carbon/M) . = ..() + if(iswendigo(M)) + return if(!M.getorganslot("vagina")) if(M.dna.features["has_vag"]) var/obj/item/organ/genital/vagina/nV = new @@ -208,6 +212,8 @@ /datum/reagent/fermi/penis_enlarger/on_mob_add(mob/living/carbon/M) . = ..() + if(iswendigo(M)) + return if(!ishuman(M)) //Just monkeying around. if(volume >= 15) //to prevent monkey penis farms var/turf/T = get_turf(M) @@ -351,6 +357,8 @@ /datum/reagent/fermi/PEsmaller_hypo/on_mob_add(mob/living/carbon/M) . = ..() + if(iswendigo(M)) + return if(!M.getorganslot("testicles")) if(M.dna.features["has_balls"]) var/obj/item/organ/genital/testicles/nT = new diff --git a/tgstation.dme b/tgstation.dme index ce3d1809..7aa01f9c 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3029,6 +3029,7 @@ #include "code\modules\zombie\items.dm" #include "code\modules\zombie\organs.dm" #include "hyperstation\code\__DEFINES\economy.dm" +#include "hyperstation\code\__DEFINES\wendigo.dm" #include "hyperstation\code\controllers\subsystem\economy.dm" #include "hyperstation\code\datums\elements\holder_micro.dm" #include "hyperstation\code\datums\mood_events\events.dm" @@ -3046,6 +3047,16 @@ #include "hyperstation\code\modules\pen.dm" #include "hyperstation\code\modules\traits.dm" #include "hyperstation\code\modules\admin\verbs\hyperverbs.dm" +#include "hyperstation\code\modules\antagonists\wendigo\datums_hud.dm" +#include "hyperstation\code\modules\antagonists\wendigo\forest\structures\soul_storage.dm" +#include "hyperstation\code\modules\antagonists\wendigo\mob\_on_click.dm" +#include "hyperstation\code\modules\antagonists\wendigo\mob\defines_init.dm" +#include "hyperstation\code\modules\antagonists\wendigo\mob\examine.dm" +#include "hyperstation\code\modules\antagonists\wendigo\mob\metabolization.dm" +#include "hyperstation\code\modules\antagonists\wendigo\mob\mob_defense.dm" +#include "hyperstation\code\modules\antagonists\wendigo\mob\mob_equip.dm" +#include "hyperstation\code\modules\antagonists\wendigo\mob\organs_bodyparts.dm" +#include "hyperstation\code\modules\antagonists\wendigo\mob\update_icons.dm" #include "hyperstation\code\modules\antagonists\werewolf\werewolf.dm" #include "hyperstation\code\modules\arousal\arousalhud.dm" #include "hyperstation\code\modules\cargo\exports\sweatshop.dm"