From c156b3ce645e18aa2497b981f509729cb290fdf1 Mon Sep 17 00:00:00 2001 From: MrMelbert Date: Fri, 3 Nov 2023 17:06:37 -0500 Subject: [PATCH 1/3] Re-adds bat form, disallows vampires from entering rooms they have no permission to --- maplestation.dme | 1 + .../code/game/area/space_station_13_areas.dm | 143 +++++++++++++++ .../code/modules/events/solar_flare.dm | 45 +---- .../carbon/human/species_types/vampire.dm | 173 ++++++++++++++++++ 4 files changed, 324 insertions(+), 38 deletions(-) create mode 100644 maplestation_modules/code/modules/mob/living/carbon/human/species_types/vampire.dm diff --git a/maplestation.dme b/maplestation.dme index c98ea5f2821e..1c8f7d12c22f 100644 --- a/maplestation.dme +++ b/maplestation.dme @@ -5653,6 +5653,7 @@ #include "maplestation_modules\code\modules\mob\living\carbon\human\species_types\skrell.dm" #include "maplestation_modules\code\modules\mob\living\carbon\human\species_types\species.dm" #include "maplestation_modules\code\modules\mob\living\carbon\human\species_types\synths.dm" +#include "maplestation_modules\code\modules\mob\living\carbon\human\species_types\vampire.dm" #include "maplestation_modules\code\modules\mob\living\silicon\robot\robot_defines.dm" #include "maplestation_modules\code\modules\mob\living\simple_animal\corpse.dm" #include "maplestation_modules\code\modules\mod\mod_control.dm" diff --git a/maplestation_modules/code/game/area/space_station_13_areas.dm b/maplestation_modules/code/game/area/space_station_13_areas.dm index 9a5a19e61449..0eccb045ce10 100644 --- a/maplestation_modules/code/game/area/space_station_13_areas.dm +++ b/maplestation_modules/code/game/area/space_station_13_areas.dm @@ -11,6 +11,8 @@ name = "Bridge Officer's Office" icon = 'maplestation_modules/icons/turf/areas.dmi' icon_state = "bo_office" + associated_department_flags = DEPARTMENT_BITFLAG_COMMAND|DEPARTMENT_BITFLAG_SECURITY + associated_department = DEPARTMENT_COMMAND //AP Office, possibly going unused? We're adding it anyway, fuck you /area/station/command/ap_office @@ -20,6 +22,8 @@ /area/station/service/hydroponics/park name = "Park" + associated_department_flags = NONE + associated_department = null /area/station/service/bar/lower name = "Lower Bar" @@ -29,11 +33,15 @@ name = "\improper Abandoned Robotics" icon_state = "abandoned_sci" sound_environment = SOUND_AREA_SMALL_ENCLOSED + associated_department_flags = NONE + associated_department = null /area/station/service/kitchen/abandoned name = "\improper Abandoned Kitchen" icon_state = "kitchen" sound_environment = SOUND_AREA_SMALL_ENCLOSED + associated_department_flags = NONE + associated_department = null /area/station/maintenance/starboard/lower name = "Lower Starboard Maintenance" @@ -78,3 +86,138 @@ name = "\improper Baseball Locker Room" icon = 'maplestation_modules/icons/turf/areas.dmi' icon_state = "baseball_locker" + +/area/station + /// All department flags that are associated with this department + var/associated_department_flags = NONE + /// The PRIMARY department this area may be located in + var/associated_department + +/area/station/security + associated_department_flags = DEPARTMENT_BITFLAG_SECURITY + associated_department = DEPARTMENT_SECURITY + +/area/station/security/checkpoint/medical + associated_department_flags = DEPARTMENT_BITFLAG_SECURITY|DEPARTMENT_BITFLAG_MEDICAL + associated_department = DEPARTMENT_MEDICAL + +/area/station/security/checkpoint/medical/medsci + associated_department_flags = DEPARTMENT_BITFLAG_SECURITY|DEPARTMENT_BITFLAG_MEDICAL|DEPARTMENT_BITFLAG_SCIENCE + +/area/station/security/checkpoint/science + associated_department_flags = DEPARTMENT_BITFLAG_SECURITY|DEPARTMENT_BITFLAG_SCIENCE + associated_department = DEPARTMENT_SCIENCE + +/area/station/security/checkpoint/engineering + associated_department_flags = DEPARTMENT_BITFLAG_SECURITY|DEPARTMENT_BITFLAG_ENGINEERING + associated_department = DEPARTMENT_ENGINEERING + +/area/station/security/checkpoint/supply + associated_department_flags = DEPARTMENT_BITFLAG_SECURITY|DEPARTMENT_BITFLAG_COMMAND + associated_department = DEPARTMENT_COMMAND + +/area/station/medical + associated_department_flags = DEPARTMENT_BITFLAG_MEDICAL + associated_department = DEPARTMENT_MEDICAL + +/area/station/medical/abandoned + associated_department_flags = NONE + associated_department = null + +/area/station/science + associated_department_flags = DEPARTMENT_BITFLAG_SCIENCE + associated_department = DEPARTMENT_SCIENCE + +/area/station/science/research/abandoned + associated_department_flags = NONE + associated_department = null + +/area/station/service + associated_department_flags = DEPARTMENT_BITFLAG_SERVICE + associated_department = DEPARTMENT_SERVICE + +/area/station/service/electronic_marketing_den + associated_department_flags = NONE + associated_department = null + +/area/station/service/abandoned_gambling_den + associated_department_flags = NONE + associated_department = null + +/area/station/service/abandoned_gambling_den/gaming + associated_department_flags = NONE + associated_department = null + +/area/station/service/theater/abandoned + associated_department_flags = NONE + associated_department = null + +/area/station/service/library/abandoned + associated_department_flags = NONE + associated_department = null + +/area/station/service/hydroponics/garden/abandoned + associated_department_flags = NONE + associated_department = null + +/area/station/engineering + associated_department_flags = DEPARTMENT_BITFLAG_ENGINEERING + associated_department = DEPARTMENT_ENGINEERING + +/area/station/supply + associated_department_flags = DEPARTMENT_BITFLAG_CARGO + associated_department = DEPARTMENT_CARGO + +/area/station/command + associated_department_flags = DEPARTMENT_BITFLAG_COMMAND + associated_department = DEPARTMENT_COMMAND + +/area/station/command/heads_quarters/captain + associated_department_flags = DEPARTMENT_BITFLAG_CAPTAIN + +/area/station/command/heads_quarters/cmo + associated_department = DEPARTMENT_MEDICAL + +/area/station/command/heads_quarters/ce + associated_department = DEPARTMENT_ENGINEERING + +/area/station/command/heads_quarters/rd + associated_department = DEPARTMENT_SCIENCE + +/area/station/command/heads_quarters/hos + associated_department = DEPARTMENT_SECURITY + +/area/station/ai_monitored + associated_department_flags = DEPARTMENT_BITFLAG_SILICON + +/area/station/ai_monitored/command + associated_department_flags = DEPARTMENT_BITFLAG_COMMAND|DEPARTMENT_BITFLAG_SILICON + associated_department = DEPARTMENT_COMMAND + +/area/station/ai_monitored/security + associated_department_flags = DEPARTMENT_BITFLAG_COMMAND|DEPARTMENT_BITFLAG_SECURITY + associated_department = DEPARTMENT_BITFLAG_SECURITY + +/area/station/ai_monitored/aisat + associated_department_flags = DEPARTMENT_BITFLAG_COMMAND|DEPARTMENT_BITFLAG_SILICON + associated_department = DEPARTMENT_SILICON + +/area/station/ai_monitored/turret_protected/ai + associated_department_flags = DEPARTMENT_BITFLAG_COMMAND|DEPARTMENT_BITFLAG_SILICON + associated_department = DEPARTMENT_SILICON + +/area/station/ai_monitored/turret_protected/aisat + associated_department_flags = DEPARTMENT_BITFLAG_COMMAND|DEPARTMENT_BITFLAG_SILICON + associated_department = DEPARTMENT_SILICON + +/area/station/ai_monitored/turret_protected/aisat_interior + associated_department_flags = DEPARTMENT_BITFLAG_COMMAND|DEPARTMENT_BITFLAG_SILICON + associated_department = DEPARTMENT_SILICON + +/area/station/ai_monitored/turret_protected/ai_upload + associated_department_flags = DEPARTMENT_BITFLAG_COMMAND|DEPARTMENT_BITFLAG_SILICON + associated_department = DEPARTMENT_SILICON + +/area/station/ai_monitored/turret_protected/ai_upload_foyer + associated_department_flags = DEPARTMENT_BITFLAG_COMMAND|DEPARTMENT_BITFLAG_SILICON + associated_department = DEPARTMENT_SILICON diff --git a/maplestation_modules/code/modules/events/solar_flare.dm b/maplestation_modules/code/modules/events/solar_flare.dm index 5092eb5b4cbc..a35a9908ffed 100644 --- a/maplestation_modules/code/modules/events/solar_flare.dm +++ b/maplestation_modules/code/modules/events/solar_flare.dm @@ -99,45 +99,14 @@ /** * Get all areas associated with a department. */ -/datum/round_event/solar_flare/proc/get_areas(department, area_path) +/datum/round_event/solar_flare/proc/get_areas(department, area/station/area_path) RETURN_TYPE(/list) - . = subtypesof(area_path) - - // There's much more OOP ways to do this, but whatever - switch(department) - if(DEPARTMENT_SECURITY) - . -= typesof(/area/station/security/checkpoint) - . -= /area/station/security/detectives_office/bridge_officer_office - - if(DEPARTMENT_COMMAND) - . -= /area/station/command/gateway - . += /area/station/security/detectives_office/bridge_officer_office - - if(DEPARTMENT_SERVICE) - . -= /area/station/service/electronic_marketing_den - . -= /area/station/service/abandoned_gambling_den - . -= /area/station/service/abandoned_gambling_den/gaming - . -= /area/station/service/theater/abandoned - . -= /area/station/service/library/abandoned - . -= /area/station/service/hydroponics/garden/abandoned - - if(DEPARTMENT_CARGO) - . += /area/station/security/checkpoint/supply - - if(DEPARTMENT_ENGINEERING) - . -= /area/station/engineering/supermatter - . -= /area/station/engineering/supermatter/room - . -= /area/station/engineering/gravity_generator - . += /area/station/security/checkpoint/engineering - - if(DEPARTMENT_SCIENCE) - . -= /area/station/science/research/abandoned - . += /area/station/security/checkpoint/science - . += /area/station/security/checkpoint/science/research - - if(DEPARTMENT_MEDICAL) - . -= /area/station/medical/abandoned - . += /area/station/security/checkpoint/medical + var/list/area_pool = list() + for(var/area/station/area_type as anything in subtypesof(area_path)) + if(initial(area_type.associated_department) != department) + continue + area_pool += area_type + return area_pool // Solar flare. Causes a diamond of fire centered on the initial turf. /obj/effect/solar_flare diff --git a/maplestation_modules/code/modules/mob/living/carbon/human/species_types/vampire.dm b/maplestation_modules/code/modules/mob/living/carbon/human/species_types/vampire.dm new file mode 100644 index 000000000000..dedcf77d3bc1 --- /dev/null +++ b/maplestation_modules/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -0,0 +1,173 @@ +// Vampire Business + +// Heart gives you Bat Form, but with a downside +/obj/item/organ/internal/heart/vampire + actions_types = list(/datum/action/cooldown/spell/shapeshift/vampire) + +/obj/item/organ/internal/heart/vampire/on_insert(mob/living/carbon/receiver) + . = ..() + receiver.AddComponent(/datum/component/verbal_confirmation) + +/obj/item/organ/internal/heart/vampire/on_remove(mob/living/carbon/receiver) + . = ..() + qdel(receiver.GetComponent(/datum/component/verbal_confirmation)) + +// Bat Form transformation my beloved +/datum/action/cooldown/spell/shapeshift/vampire + name = "Bat Form" + desc = "Take on the shape a space bat." + invocation = "Squeak!" + cooldown_time = 5 SECONDS + possible_shapes = list(/mob/living/basic/bat) + button_icon = 'icons/mob/simple/animal.dmi' + button_icon_state = "bat" + antimagic_flags = MAGIC_RESISTANCE_HOLY + spell_requirements = SPELL_REQUIRES_NO_ANTIMAGIC + +/// Component which disallows the mob from entering areas they do not have access to, +/// without getting permission from someone who does +/datum/component/verbal_confirmation + can_transfer = TRUE + + /// Tracks if we've recently asked someone to allow us in + var/recently_asked = FALSE + /// Assoc List of all mobs which have given access (key to department bitflag) + var/list/prior_allowance = list() + /// Regexes for matching asking to be allowed in + var/static/regex/asking_regex + /// Regexes for responses indicating we're allowed in + var/static/regex/allowed_regex + /// Regexes for responses indicating we're explicitly not allowed in + var/static/regex/begone_regex + +/datum/component/verbal_confirmation/Initialize() + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE + + if(!asking_regex) + asking_regex = regex(@"((may|come|let|can|enter)[a-zA-z\s]*)", "i") + if(!allowed_regex) + allowed_regex = regex(@"(sure|okay|ye[sea]*|yes|ok[ay]*|fine|come.+in[a-zA-z\s]*)", "i") + if(!begone_regex) + begone_regex = regex(@"(no[ope]*|begone|go away|shoo|fuck off)", "i") + +/datum/component/verbal_confirmation/RegisterWithParent() + RegisterSignals(parent, list(COMSIG_LIVING_SHAPESHIFTED, COMSIG_LIVING_UNSHAPESHIFTED), PROC_REF(shapechanged)) + RegisterSignal(parent, COMSIG_MOB_SAY, PROC_REF(check_asking)) + RegisterSignal(parent, COMSIG_MOVABLE_HEAR, PROC_REF(check_allowed)) + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(entering_room)) + +/datum/component/verbal_confirmation/UnregisterFromParent() + UnregisterSignal(parent, list(COMSIG_LIVING_SHAPESHIFTED, COMSIG_LIVING_UNSHAPESHIFTED)) + UnregisterSignal(parent, COMSIG_MOB_SAY) + UnregisterSignal(parent, COMSIG_MOVABLE_HEAR) + UnregisterSignal(parent, COMSIG_MOVABLE_MOVED) + +/datum/component/verbal_confirmation/PostTransfer() + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE + +/datum/component/verbal_confirmation/proc/shapechanged(mob/living/source, mob/living/new_mob) + SIGNAL_HANDLER + new_mob.TakeComponent(src) + +/datum/component/verbal_confirmation/proc/get_bitflag_from_mob(mob/living/who) + var/obj/item/card/id/their_id = who.get_idcard() + if(!istype(their_id) || !istype(their_id.trim, /datum/id_trim/job)) + return NONE + + var/datum/id_trim/job/their_trim = their_id.trim + return their_trim.job.departments_bitflags + +/datum/component/verbal_confirmation/proc/is_allowed(mob/living/vampire, area/station/old_area, area/station/checked_area) + // Non-station areas are always allowed + if(!istype(checked_area) || isnull(checked_area.associated_department)) + return TRUE + // Comparing the same area is fine + if(old_area == checked_area) + return TRUE + // If we're going from station to station and it's the same department we can skip some checks + if(istype(old_area) && old_area.associated_department == checked_area.associated_department) + return TRUE + // Medbay is always a free space + if(vampire.stat != CONSCIOUS && (checked_area.associated_department_flags & DEPARTMENT_BITFLAG_MEDICAL)) + return TRUE + + var/all_allowed = get_bitflag_from_mob(vampire) + for(var/ref in prior_allowance) + all_allowed |= prior_allowance[ref] + + if(all_allowed & DEPARTMENT_BITFLAG_CAPTAIN) + return TRUE // Straight from the big dog + if(all_allowed & checked_area.associated_department_flags) + return TRUE + if(istype(checked_area, /area/station/service/chapel)) + return TRUE // Go ahead, try waltzing into the chapel + + return FALSE + +/datum/component/verbal_confirmation/proc/check_asking(mob/living/source, list/say_args) + SIGNAL_HANDLER + + var/spoken_message = say_args[SPEECH_MESSAGE] + if(!spoken_message || !asking_regex.Find(spoken_message)) + return + + recently_asked = TRUE + addtimer(VARSET_CALLBACK(src, recently_asked, FALSE), 20 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) + say_args[SPEECH_MESSAGE] = asking_regex.Replace(spoken_message, "[span_hierophant("$1")]") + +/datum/component/verbal_confirmation/proc/check_allowed(mob/living/source, list/hear_args) + SIGNAL_HANDLER + + if(!recently_asked && !hear_args[RADIO_EXTENSION]) + return + + var/mob/speaker = hear_args[HEARING_SPEAKER] + if(!ismob(speaker) || speaker == parent) + return + + var/spoken_message = hear_args[HEARING_RAW_MESSAGE] + if(!spoken_message) + return + + if(begone_regex.Find(spoken_message)) + hear_args[HEARING_RAW_MESSAGE] = begone_regex.Replace(spoken_message, "[span_red("$1")]") + recently_asked = FALSE + return + + if(allowed_regex.Find(spoken_message)) + var/speaker_key = REF(speaker) + prior_allowance[speaker_key] = get_bitflag_from_mob(speaker) + hear_args[HEARING_RAW_MESSAGE] = allowed_regex.Replace(spoken_message, "[span_green("$1")]") + addtimer(CALLBACK(src, PROC_REF(clear_allowed), speaker_key), 5 MINUTES, TIMER_UNIQUE|TIMER_OVERRIDE) + // Only give you a notice if you asked + if(recently_asked) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(to_chat), source, span_notice("[speaker] allows you into [speaker.p_their()] department. Joyous day.")), 0.2 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) + recently_asked = FALSE + return + +/datum/component/verbal_confirmation/proc/clear_allowed(speaker_key) + prior_allowance -= speaker_key + +/datum/component/verbal_confirmation/proc/entering_room(mob/living/source, turf/old_loc, movement_dir, forced) + SIGNAL_HANDLER + + if(isnull(old_loc) || forced) + return + if(source.pulledby || source.throwing || (source.buckled?.pulledby && source.buckled.pulledby != source)) + return + + var/area/station/old_area = get_area(old_loc) + var/area/station/checked_area = get_area(source) + if(is_allowed(source, old_area, checked_area)) + return + + to_chat(source, span_warning("You don't have permission to enter [checked_area].")) + source.Paralyze(1 SECONDS, ignore_canstun = TRUE) + source.throw_at( + target = get_edge_target_turf(source.loc, REVERSE_DIR(movement_dir)), + range = 3, + speed = 4, + gentle = TRUE, + ) From 79f0f8094f01dcf518087c5613c7ff8a064ae286 Mon Sep 17 00:00:00 2001 From: MrMelbert Date: Fri, 3 Nov 2023 19:55:40 -0500 Subject: [PATCH 2/3] Vented --- maplestation.dme | 1 + .../code/__DEFINES/signals.dm | 5 ++ .../code/modules/jobs/job_types/assistant.dm | 2 + .../code/modules/jobs/job_types/captain.dm | 2 + .../carbon/human/species_types/vampire.dm | 58 +++++++++++++------ 5 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 maplestation_modules/code/modules/jobs/job_types/captain.dm diff --git a/maplestation.dme b/maplestation.dme index 1c8f7d12c22f..a349d1ad3ffc 100644 --- a/maplestation.dme +++ b/maplestation.dme @@ -5558,6 +5558,7 @@ #include "maplestation_modules\code\modules\jobs\job_types\asset_protection.dm" #include "maplestation_modules\code\modules\jobs\job_types\assistant.dm" #include "maplestation_modules\code\modules\jobs\job_types\bridge_officer.dm" +#include "maplestation_modules\code\modules\jobs\job_types\captain.dm" #include "maplestation_modules\code\modules\jobs\job_types\lawyer.dm" #include "maplestation_modules\code\modules\jobs\job_types\ordnance_tech.dm" #include "maplestation_modules\code\modules\jobs\job_types\psychologist.dm" diff --git a/maplestation_modules/code/__DEFINES/signals.dm b/maplestation_modules/code/__DEFINES/signals.dm index c2aa40b7844e..facd85ed641b 100644 --- a/maplestation_modules/code/__DEFINES/signals.dm +++ b/maplestation_modules/code/__DEFINES/signals.dm @@ -5,3 +5,8 @@ /// Item generating their worn icon #define COMSIG_ITEM_WORN_ICON_MADE "item_worn_icon_made" + +/// Entering or exiting a vent. +#define COMSIG_HANDLE_VENTCRAWLING "handle_ventcrawl" + /// Return to block entrance / exit + #define COMPONENT_NO_VENT (1<<0) diff --git a/maplestation_modules/code/modules/jobs/job_types/assistant.dm b/maplestation_modules/code/modules/jobs/job_types/assistant.dm index 3d94b672520b..b335a0aa095d 100644 --- a/maplestation_modules/code/modules/jobs/job_types/assistant.dm +++ b/maplestation_modules/code/modules/jobs/job_types/assistant.dm @@ -1,4 +1,6 @@ // -- Assistant Changes -- +/datum/job/assistant + departments_bitflags = DEPARTMENT_BITFLAG_ASSISTANT // This is done for loadouts, otherwise unique uniforms would be deleted. /datum/outfit/job/assistant diff --git a/maplestation_modules/code/modules/jobs/job_types/captain.dm b/maplestation_modules/code/modules/jobs/job_types/captain.dm new file mode 100644 index 000000000000..2e2382cf9615 --- /dev/null +++ b/maplestation_modules/code/modules/jobs/job_types/captain.dm @@ -0,0 +1,2 @@ +/datum/job/captain + departments_bitflags = DEPARTMENT_BITFLAG_CAPTAIN diff --git a/maplestation_modules/code/modules/mob/living/carbon/human/species_types/vampire.dm b/maplestation_modules/code/modules/mob/living/carbon/human/species_types/vampire.dm index dedcf77d3bc1..7d4d9d787c3b 100644 --- a/maplestation_modules/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/maplestation_modules/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -24,6 +24,12 @@ antimagic_flags = MAGIC_RESISTANCE_HOLY spell_requirements = SPELL_REQUIRES_NO_ANTIMAGIC +// Override to add a signal to handle_ventcrawl +/mob/living/handle_ventcrawl(obj/machinery/atmospherics/components/ventcrawl_target) + if(SEND_SIGNAL(src, COMSIG_HANDLE_VENTCRAWLING, ventcrawl_target) & COMPONENT_NO_VENT) + return + return ..() + /// Component which disallows the mob from entering areas they do not have access to, /// without getting permission from someone who does /datum/component/verbal_confirmation @@ -39,6 +45,8 @@ var/static/regex/allowed_regex /// Regexes for responses indicating we're explicitly not allowed in var/static/regex/begone_regex + /// Weakref to the mob's ID card when shapechanging + var/datum/weakref/old_id_card /datum/component/verbal_confirmation/Initialize() if(!isliving(parent)) @@ -56,12 +64,16 @@ RegisterSignal(parent, COMSIG_MOB_SAY, PROC_REF(check_asking)) RegisterSignal(parent, COMSIG_MOVABLE_HEAR, PROC_REF(check_allowed)) RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(entering_room)) + RegisterSignal(parent, COMSIG_HANDLE_VENTCRAWLING, PROC_REF(entering_vent)) /datum/component/verbal_confirmation/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_LIVING_SHAPESHIFTED, COMSIG_LIVING_UNSHAPESHIFTED)) - UnregisterSignal(parent, COMSIG_MOB_SAY) - UnregisterSignal(parent, COMSIG_MOVABLE_HEAR) - UnregisterSignal(parent, COMSIG_MOVABLE_MOVED) + UnregisterSignal(parent, list( + COMSIG_LIVING_SHAPESHIFTED, COMSIG_LIVING_UNSHAPESHIFTED, + COMSIG_MOB_SAY, + COMSIG_MOVABLE_HEAR, + COMSIG_MOVABLE_MOVED, + COMSIG_HANDLE_VENTCRAWLING, + )) /datum/component/verbal_confirmation/PostTransfer() if(!isliving(parent)) @@ -70,26 +82,21 @@ /datum/component/verbal_confirmation/proc/shapechanged(mob/living/source, mob/living/new_mob) SIGNAL_HANDLER new_mob.TakeComponent(src) + old_id_card = WEAKREF(source.get_idcard()) /datum/component/verbal_confirmation/proc/get_bitflag_from_mob(mob/living/who) - var/obj/item/card/id/their_id = who.get_idcard() - if(!istype(their_id) || !istype(their_id.trim, /datum/id_trim/job)) + var/obj/item/card/id/their_id = who.get_idcard() || old_id_card?.resolve() + if(!istype(their_id) || !istype(their_id.trim, /datum/id_trim/job) || get(their_id, /mob/living) != who) return NONE var/datum/id_trim/job/their_trim = their_id.trim return their_trim.job.departments_bitflags -/datum/component/verbal_confirmation/proc/is_allowed(mob/living/vampire, area/station/old_area, area/station/checked_area) +/datum/component/verbal_confirmation/proc/is_allowed(mob/living/vampire, area/station/checked_area) // Non-station areas are always allowed if(!istype(checked_area) || isnull(checked_area.associated_department)) return TRUE - // Comparing the same area is fine - if(old_area == checked_area) - return TRUE - // If we're going from station to station and it's the same department we can skip some checks - if(istype(old_area) && old_area.associated_department == checked_area.associated_department) - return TRUE - // Medbay is always a free space + // Medbay is always free if you're hurt if(vampire.stat != CONSCIOUS && (checked_area.associated_department_flags & DEPARTMENT_BITFLAG_MEDICAL)) return TRUE @@ -97,9 +104,7 @@ for(var/ref in prior_allowance) all_allowed |= prior_allowance[ref] - if(all_allowed & DEPARTMENT_BITFLAG_CAPTAIN) - return TRUE // Straight from the big dog - if(all_allowed & checked_area.associated_department_flags) + if(all_allowed & (DEPARTMENT_BITFLAG_CAPTAIN|checked_area.associated_department_flags)) return TRUE if(istype(checked_area, /area/station/service/chapel)) return TRUE // Go ahead, try waltzing into the chapel @@ -160,7 +165,13 @@ var/area/station/old_area = get_area(old_loc) var/area/station/checked_area = get_area(source) - if(is_allowed(source, old_area, checked_area)) + // Comparing the same area is fine + if(old_area == checked_area) + return + // If we're going from station to station and it's the same department we can skip some checks + if(istype(old_area) && istype(checked_area) && old_area.associated_department == checked_area.associated_department) + return + if(is_allowed(source, checked_area)) return to_chat(source, span_warning("You don't have permission to enter [checked_area].")) @@ -171,3 +182,14 @@ speed = 4, gentle = TRUE, ) + +/datum/component/verbal_confirmation/proc/entering_vent(mob/living/source, obj/machinery/atmospherics/components/ventcrawl_target) + SIGNAL_HANDLER + + var/area/checked_area = get_area(ventcrawl_target) + if(is_allowed(source, checked_area)) + return NONE + + to_chat(source, span_warning("You don't have permission to crawl through that [initial(ventcrawl_target.name)] into [checked_area].")) + source.Immobilize(1 SECONDS, ignore_canstun = TRUE) + return COMPONENT_NO_VENT From 4df034ec70709ee7deafc8ab33e57f9590b8a0e4 Mon Sep 17 00:00:00 2001 From: MrMelbert Date: Sat, 4 Nov 2023 02:30:08 -0500 Subject: [PATCH 3/3] Adds some more shenanigans to vamps, night vision --- .../code/__DEFINES/signals.dm | 3 ++ .../carbon/human/species_types/vampire.dm | 45 +++++++++++++++++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/maplestation_modules/code/__DEFINES/signals.dm b/maplestation_modules/code/__DEFINES/signals.dm index facd85ed641b..cd988f205f15 100644 --- a/maplestation_modules/code/__DEFINES/signals.dm +++ b/maplestation_modules/code/__DEFINES/signals.dm @@ -10,3 +10,6 @@ #define COMSIG_HANDLE_VENTCRAWLING "handle_ventcrawl" /// Return to block entrance / exit #define COMPONENT_NO_VENT (1<<0) + +/// A carbon is being flashed - actually being blinded and taking (eye) damage +#define COMSIG_CARBON_FLASH_ACT "carbon_flash_act" diff --git a/maplestation_modules/code/modules/mob/living/carbon/human/species_types/vampire.dm b/maplestation_modules/code/modules/mob/living/carbon/human/species_types/vampire.dm index 7d4d9d787c3b..38ee4ca015ed 100644 --- a/maplestation_modules/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/maplestation_modules/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -1,16 +1,45 @@ // Vampire Business +/datum/species/vampire + mutanteyes = /obj/item/organ/internal/eyes/night_vision/vampire // Heart gives you Bat Form, but with a downside /obj/item/organ/internal/heart/vampire actions_types = list(/datum/action/cooldown/spell/shapeshift/vampire) -/obj/item/organ/internal/heart/vampire/on_insert(mob/living/carbon/receiver) +/obj/item/organ/internal/heart/vampire/on_insert(mob/living/carbon/organ_owner) . = ..() - receiver.AddComponent(/datum/component/verbal_confirmation) + organ_owner.AddComponent(/datum/component/verbal_confirmation) -/obj/item/organ/internal/heart/vampire/on_remove(mob/living/carbon/receiver) +/obj/item/organ/internal/heart/vampire/on_remove(mob/living/carbon/organ_owner) . = ..() - qdel(receiver.GetComponent(/datum/component/verbal_confirmation)) + qdel(organ_owner.GetComponent(/datum/component/verbal_confirmation)) + +// Vampire eyes, make you vulnerable to the light, but also has nightvision +/obj/item/organ/internal/eyes/night_vision/vampire + name = "blood red eyes" + desc = "A pair of blood red eyes." + flash_protect = FLASH_PROTECTION_SENSITIVE + low_light_cutoff = list(20, 0, 5) + medium_light_cutoff = list(30, 5, 10) + high_light_cutoff = list(40, 10, 20) + +/obj/item/organ/internal/eyes/night_vision/vampire/on_insert(mob/living/carbon/organ_owner, special) + . = ..() + RegisterSignal(organ_owner, COMSIG_CARBON_FLASH_ACT, PROC_REF(do_damage)) + +/obj/item/organ/internal/eyes/night_vision/vampire/on_remove(mob/living/carbon/organ_owner, special) + . = ..() + UnregisterSignal(organ_owner, COMSIG_CARBON_FLASH_ACT) + +/obj/item/organ/internal/eyes/night_vision/vampire/proc/do_damage(mob/living/carbon/source, intensity) + SIGNAL_HANDLER + + var/damage = 3 * (intensity - source.get_eye_protection()) + if(damage <= 0) + return + + source.apply_damage(damage, BURN, BODY_ZONE_HEAD, wound_bonus = -10) + source.visible_message(span_userdanger("The bright flash burns your skin!")) // Bat Form transformation my beloved /datum/action/cooldown/spell/shapeshift/vampire @@ -30,6 +59,14 @@ return return ..() +// Override to add a signal to flash act +/mob/living/carbon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/flash, length = 25) + . = ..() + if(!. || visual) + return + + SEND_SIGNAL(src, COMSIG_CARBON_FLASH_ACT, intensity) + /// Component which disallows the mob from entering areas they do not have access to, /// without getting permission from someone who does /datum/component/verbal_confirmation