diff --git a/code/game/objects/items/holosign_creator.dm b/code/game/objects/items/holosign_creator.dm index 926131151e9..049ea8928fe 100644 --- a/code/game/objects/items/holosign_creator.dm +++ b/code/game/objects/items/holosign_creator.dm @@ -38,10 +38,11 @@ /obj/item/holosign_creator/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) if(!check_allowed_items(interacting_with, not_inside = TRUE)) return NONE + var/turf/target_turf = get_turf(interacting_with) var/obj/structure/holosign/target_holosign = locate(holosign_type) in target_turf + if(target_holosign) - qdel(target_holosign) return ITEM_INTERACT_BLOCKING if(target_turf.is_blocked_turf(TRUE)) //can't put holograms on a tile that has dense stuff return ITEM_INTERACT_BLOCKING @@ -51,7 +52,9 @@ if(LAZYLEN(signs) >= max_signs) balloon_alert(user, "max capacity!") return ITEM_INTERACT_BLOCKING + playsound(src, 'sound/machines/click.ogg', 20, TRUE) + if(creation_time) holocreator_busy = TRUE if(!do_after(user, creation_time, target = interacting_with)) @@ -62,6 +65,7 @@ return ITEM_INTERACT_BLOCKING if(target_turf.is_blocked_turf(TRUE)) //don't try to sneak dense stuff on our tile during the wait. return ITEM_INTERACT_BLOCKING + target_holosign = create_holosign(interacting_with, user) return ITEM_INTERACT_SUCCESS @@ -105,15 +109,15 @@ /obj/item/holosign_creator/security name = "security holobarrier projector" - desc = "A holographic projector that creates holographic security barriers." + desc = "A holographic projector that creates holographic security barriers. You can remotely open barriers with it." icon_state = "signmaker_sec" holosign_type = /obj/structure/holosign/barrier - creation_time = 3 SECONDS + creation_time = 2 SECONDS max_signs = 6 /obj/item/holosign_creator/engineering name = "engineering holobarrier projector" - desc = "A holographic projector that creates holographic engineering barriers." + desc = "A holographic projector that creates holographic engineering barriers. You can remotely open barriers with it." icon_state = "signmaker_engi" holosign_type = /obj/structure/holosign/barrier/engineering creation_time = 1 SECONDS diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm index 1d7fc470aff..30983c5088d 100644 --- a/code/game/objects/structures/holosign.dm +++ b/code/game/objects/structures/holosign.dm @@ -3,7 +3,7 @@ /obj/structure/holosign name = "holo sign" - icon = 'icons/effects/effects.dmi' + icon = 'icons/effects/holosigns.dmi' anchored = TRUE max_integrity = 1 armor_type = /datum/armor/structure_holosign @@ -21,10 +21,7 @@ /obj/structure/holosign/Initialize(mapload, source_projector) . = ..() - var/turf/our_turf = get_turf(src) - if(use_vis_overlay) - alpha = 0 - SSvis_overlays.add_vis_overlay(src, icon, icon_state, ABOVE_MOB_LAYER, MUTATE_PLANE(GAME_PLANE, our_turf), dir, add_appearance_flags = RESET_ALPHA) //you see mobs under it, but you hit them like they are above it + create_vis_overlay() if(source_projector) projector = source_projector LAZYADD(projector.signs, src) @@ -41,6 +38,11 @@ return attack_holosign(user, modifiers) +/obj/structure/holosign/CanAllowThrough(atom/movable/mover, border_dir) + . = ..() + if(!. && isprojectile(mover)) // Its short enough to be shot over + return TRUE + /obj/structure/holosign/proc/attack_holosign(mob/living/user, list/modifiers) user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) user.changeNext_move(CLICK_CD_MELEE) @@ -54,38 +56,100 @@ if(BURN) playsound(loc, 'sound/weapons/egloves.ogg', 80, TRUE) +/obj/structure/holosign/proc/create_vis_overlay() + var/turf/our_turf = get_turf(src) + if(use_vis_overlay) + alpha = 0 + SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) + SSvis_overlays.add_vis_overlay(src, icon, icon_state, ABOVE_MOB_LAYER, MUTATE_PLANE(GAME_PLANE, our_turf), dir, add_appearance_flags = RESET_ALPHA) //you see mobs under it, but you hit them like they are above it + /obj/structure/holosign/wetsign name = "wet floor sign" desc = "The words flicker as if they mean nothing." - icon = 'icons/effects/effects.dmi' icon_state = "holosign" /obj/structure/holosign/barrier - name = "holobarrier" - desc = "A short holographic barrier which can only be passed by walking." + name = "security holobarrier" + desc = "A strong short security holographic barrier used for crowd control and blocking crime scenes. Can only be passed by walking." icon_state = "holosign_sec" + base_icon_state = "holosign_sec" pass_flags_self = PASSTABLE | PASSGRILLE | PASSGLASS | LETPASSTHROW density = TRUE max_integrity = 20 - var/allow_walk = TRUE //can we pass through it on walk intent + COOLDOWN_DECLARE(cooldown_open) + ///Can we pass through it on walk intent? + var/allow_walk = TRUE + ///Can it be temporarily opened with the holosign projector? + var/openable = TRUE + ///Is it opened? + var/opened = FALSE + ///What is the icon of opened holobarrier? + var/pass_icon_state = "holosign_pass" /obj/structure/holosign/barrier/CanAllowThrough(atom/movable/mover, border_dir) . = ..() if(.) return + + if(opened) + return TRUE + if(iscarbon(mover)) - var/mob/living/carbon/C = mover - if(C.stat) // Lets not prevent dragging unconscious/dead people. + var/mob/living/carbon/moving_carbon = mover + if(moving_carbon.stat) // Lets not prevent dragging unconscious/dead people. return TRUE - if(allow_walk && C.move_intent == MOVE_INTENT_WALK) + if(allow_walk && moving_carbon.move_intent == MOVE_INTENT_WALK) return TRUE +/obj/structure/holosign/barrier/ranged_item_interaction(mob/living/user, obj/item/tool, list/modifiers) + . = ..() + if(tool != projector) + return + if(openable) + open(user) + +/obj/structure/holosign/barrier/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + . = ..() + if(tool != projector) + return + qdel(src) + +/obj/structure/holosign/barrier/update_icon_state() + if(!opened) + icon_state = base_icon_state + else + icon_state = pass_icon_state + + create_vis_overlay() + . = ..() + +/obj/structure/holosign/barrier/proc/open(user) + if(!openable) + balloon_alert(user, "unable!") + return + + if(!COOLDOWN_FINISHED(src, cooldown_open)) + balloon_alert(user, "on cooldown!") + return + + if(!opened) + density = FALSE + opened = TRUE + playsound(src, 'sound/machines/door_open.ogg', 50, TRUE) + else + density = TRUE + opened = FALSE + playsound(src, 'sound/machines/door_close.ogg', 50, TRUE) + + update_icon_state() + COOLDOWN_START(src, cooldown_open, 1 SECONDS) + /obj/structure/holosign/barrier/wetsign name = "wet floor holobarrier" - desc = "When it says walk it means walk." - icon = 'icons/effects/effects.dmi' - icon_state = "holosign" + desc = "When it says walk it means WALK!" + icon_state = "holosign_dense" max_integrity = 1 + openable = FALSE /obj/structure/holosign/barrier/wetsign/CanAllowThrough(atom/movable/mover, border_dir) . = ..() @@ -97,7 +161,10 @@ return FALSE /obj/structure/holosign/barrier/engineering + name = "engineering holobarrier" + desc = "A short engineering holographic barrier used for designating hazardous zones, slightly blocks radiation. Can only be passed by walking." icon_state = "holosign_engi" + base_icon_state = "holosign_engi" rad_insulation = RAD_LIGHT_INSULATION max_integrity = 1 @@ -105,6 +172,7 @@ name = "holofirelock" desc = "A holographic barrier resembling a firelock. Though it does not prevent solid objects from passing through, gas is kept out." icon_state = "holo_firelock" + openable = FALSE density = FALSE anchored = TRUE can_atmos_pass = ATMOS_PASS_NO @@ -129,11 +197,13 @@ /obj/structure/holosign/barrier/atmos/sturdy name = "sturdy holofirelock" max_integrity = 150 + openable = FALSE /obj/structure/holosign/barrier/atmos/tram name = "tram atmos barrier" max_integrity = 150 icon_state = "holo_tram" + openable = FALSE /obj/structure/holosign/barrier/atmos/Initialize(mapload) . = ..() @@ -166,9 +236,10 @@ name = "\improper PENLITE holobarrier" desc = "A holobarrier that uses biometrics to detect human viruses. Denies passing to personnel with easily-detected, malicious viruses. Good for quarantines." icon_state = "holo_medical" - alpha = 125 //lazy :) + base_icon_state = "holo_medical" max_integrity = 1 - var/buzzcd = 0 + openable = FALSE + COOLDOWN_DECLARE(virus_detected) /obj/structure/holosign/barrier/medical/CanAllowThrough(atom/movable/mover, border_dir) . = ..() @@ -183,12 +254,18 @@ /obj/structure/holosign/barrier/medical/Bumped(atom/movable/AM) . = ..() - icon_state = "holo_medical" - if(ishuman(AM) && !CheckHuman(AM)) - if(buzzcd < world.time) - playsound(get_turf(src),'sound/machines/buzz-sigh.ogg',65,TRUE,4) - buzzcd = (world.time + 60) - icon_state = "holo_medical-deny" + icon_state = base_icon_state + update_icon_state() + if(!ishuman(AM) && CheckHuman(AM)) + return + + if(!COOLDOWN_FINISHED(src, virus_detected)) + return + + playsound(get_turf(src),'sound/machines/buzz-sigh.ogg', 65, TRUE, 4) + COOLDOWN_START(src, virus_detected, 1 SECONDS) + icon_state = "holo_medical-deny" + update_icon_state() /obj/structure/holosign/barrier/medical/proc/CheckHuman(mob/living/carbon/human/sickboi) var/threat = sickboi.check_virus() diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm index 32ef86a302b..7bed3ccec06 100644 --- a/code/modules/vending/security.dm +++ b/code/modules/vending/security.dm @@ -17,6 +17,7 @@ /obj/item/flashlight/seclite = 4, /obj/item/restraints/legcuffs/bola/energy = 7, /obj/item/clothing/gloves/tackler = 5, + /obj/item/holosign_creator/security = 2, ) contraband = list( /obj/item/clothing/glasses/sunglasses = 2, diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 633004afaca..7923b4e9f1e 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/effects/holosigns.dmi b/icons/effects/holosigns.dmi new file mode 100644 index 00000000000..9d951114b77 Binary files /dev/null and b/icons/effects/holosigns.dmi differ