diff --git a/code/game/machinery/portable_tag_turret.dm b/code/game/machinery/portable_tag_turret.dm index 12fe764fb6d..276c70c0d0c 100644 --- a/code/game/machinery/portable_tag_turret.dm +++ b/code/game/machinery/portable_tag_turret.dm @@ -1,26 +1,28 @@ /obj/machinery/porta_turret/tag - // Reasonable defaults, in case someone manually spawns us - var/lasercolor = "r" //Something to do with lasertag turrets, blame Sieve for not adding a comment. - installation = /obj/item/gun/energy/laser/tag/red targetting_is_configurable = FALSE lethal_is_configurable = FALSE - shot_delay = 30 - iconholder = 1 + shot_delay = 3 SECONDS + iconholder = TRUE has_cover = FALSE always_up = TRUE raised = TRUE req_access = list(ACCESS_MAINT_TUNNELS, ACCESS_THEATRE) - -/obj/machinery/porta_turret/tag/red - -/obj/machinery/porta_turret/tag/blue - lasercolor = "b" - installation = /obj/item/gun/energy/laser/tag/blue + /// Team that we are assigned to + var/team_color /obj/machinery/porta_turret/tag/Initialize(mapload) . = ..() - icon_state = "[lasercolor]grey_target_prism" + icon_state = "[team_color]_off" + base_icon_state = team_color + +/obj/machinery/porta_turret/tag/red + team_color = "red" + installation = /obj/item/gun/energy/laser/tag/red + +/obj/machinery/porta_turret/tag/blue + team_color = "blue" + installation = /obj/item/gun/energy/laser/tag/blue /obj/machinery/porta_turret/tag/weapon_setup(obj/item/gun/energy/E) return @@ -34,35 +36,15 @@ ) return data -/obj/machinery/porta_turret/tag/update_icon_state() - if(!anchored) - icon_state = "turretCover" - return - if(stat & BROKEN) - icon_state = "[lasercolor]destroyed_target_prism" - else - if(has_power()) - if(enabled) - if(iconholder) - //lasers have a orange icon - icon_state = "[lasercolor]orange_target_prism" - else - //almost everything has a blue icon - icon_state = "[lasercolor]target_prism" - else - icon_state = "[lasercolor]grey_target_prism" - else - icon_state = "[lasercolor]grey_target_prism" - /obj/machinery/porta_turret/tag/bullet_act(obj/item/projectile/P) ..() if(!disabled) - if(lasercolor == "b") + if(team_color == "blue") if(istype(P, /obj/item/projectile/beam/lasertag/redtag)) disabled = TRUE spawn(100) disabled = FALSE - else if(lasercolor == "r") + else if(team_color == "red") if(istype(P, /obj/item/projectile/beam/lasertag/bluetag)) disabled = TRUE spawn(100) @@ -77,15 +59,14 @@ var/target_suit var/target_weapon - switch(lasercolor) - if("b") + switch(team_color) + if("blue") target_suit = /obj/item/clothing/suit/redtag target_weapon = /obj/item/gun/energy/laser/tag/red - if("r") + if("red") target_suit = /obj/item/clothing/suit/bluetag target_weapon = /obj/item/gun/energy/laser/tag/blue - if(target_suit)//Lasertag turrets target the opposing team, how great is that? -Sieve if((istype(L.r_hand, target_weapon)) || (istype(L.l_hand, target_weapon))) return TURRET_PRIORITY_TARGET diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 1a7bdd34f25..90178417b60 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -3,10 +3,16 @@ This code is slightly more documented than normal, as requested by XSI on IRC. */ +// Be sure to change the icon animation at the same time or it'll look bad +// Animation is 0.5 seconds, but turret's popup/down lasts 1 second (balance reasons etc.), so we have to call for sleep() twice to keep that one second of (de)activation +#define POPUP_ANIM_TIME 0.5 SECONDS +#define POPDOWN_ANIM_TIME 0.5 SECONDS + /obj/machinery/porta_turret name = "turret" icon = 'icons/obj/turrets.dmi' - icon_state = "turretCover" + icon_state = "standard_off" + base_icon_state = "standard" anchored = TRUE density = FALSE idle_power_consumption = 50 //when inactive, this turret takes up constant 50 Equipment power @@ -68,6 +74,10 @@ var/scan_range = 7 var/always_up = FALSE //Will stay active var/has_cover = TRUE //Hides the cover + /// Turret's cover + var/obj/effect/overlay/turret/cover + /// Used when we end up with dir NE/NW and have a cover. We temporary set new dir so turret doesn't stick out of a cover + var/saved_direction /// Deployment override to allow turret popup on/under dense turfs/objects, for admin/CC turrets var/deployment_override = FALSE /// What lethal mode projectile with the turret start with? @@ -77,7 +87,6 @@ /// What lens is fitted to the turret/gun? var/obj/item/smithed_item/lens/fitted_lens - /obj/machinery/porta_turret/Initialize(mapload) . = ..() if(req_access && length(req_access)) @@ -91,10 +100,20 @@ spark_system.attach(src) setup() + if(has_cover) + // people can't damage us when we are covered anyways + layer = OBJ_LAYER + underlays += mutable_appearance(icon, "basedark", layer + 0.1) + cover = new + cover.icon = icon + cover.icon_state = "turret_cover" + vis_contents += cover + AddElement(/datum/element/hostile_machine) /obj/machinery/porta_turret/Destroy() QDEL_NULL(spark_system) + QDEL_NULL(cover) if(prob(35)) // Half chance of drops than proper deconstruction if(installation) var/obj/item/gun/energy/Gun = new installation(loc) @@ -172,29 +191,19 @@ if(initial_projectile) projectile = initial_projectile -GLOBAL_LIST_EMPTY(turret_icons) /obj/machinery/porta_turret/update_icon_state() - if(!GLOB.turret_icons) - GLOB.turret_icons = list() - GLOB.turret_icons["open"] = image(icon, "openTurretCover") - - underlays.Cut() - underlays += GLOB.turret_icons["open"] - if(stat & BROKEN) - icon_state = "destroyed_target_prism" - else if(raised || raising) - if(has_power() && enabled) - if(iconholder) - //lasers have a orange icon - icon_state = "orange_target_prism" - else - //almost everything has a blue icon - icon_state = "target_prism" - else - icon_state = "grey_target_prism" + icon_state = "[base_icon_state]_broken" else - icon_state = "turretCover" + if((raised || raising) && has_power() && enabled) + if(iconholder) + // lasers have orange icon + icon_state = "[base_icon_state]_lethal" + else + // almost everything has blue icon + icon_state = "[base_icon_state]_stun" + else + icon_state = "[base_icon_state]_off" /obj/machinery/porta_turret/proc/HasController() var/area/A = get_area(src) @@ -371,7 +380,6 @@ GLOBAL_LIST_EMPTY(turret_icons) //This code handles moving the turret around. After all, it's a portable turret! playsound(loc, I.usesound, 100, 1) anchored = !anchored - update_icon(UPDATE_ICON_STATE) to_chat(user, "You [anchored ? "" : "un"]secure the exterior bolts on the turret.") wrenching = FALSE @@ -514,7 +522,6 @@ GLOBAL_LIST_EMPTY(turret_icons) enabled = TRUE //turns it back on. The cover pop_up() pop_down() are automatically called in process(), no need to define it here return TRUE - /obj/machinery/porta_turret/take_damage(damage_amount, damage_type = BRUTE, damage_flag = "", sound_effect = TRUE, attack_dir, armour_penetration_flat = 0, armour_penetration_percentage = 0) damage_amount = run_obj_armor(damage_amount, damage_type, damage_flag, attack_dir, armour_penetration_flat, armour_penetration_percentage) if(!raised && !raising) @@ -741,9 +748,7 @@ GLOBAL_LIST_EMPTY(turret_icons) pop_up() // check if anything's preventing us from raising var/turf/T = get_turf(src) - for(var/atom/A in T) - if(A == src) - continue + for(var/atom/A in T.contents - src) if(A.density) if(is_type_in_typecache(A, deployment_whitelist)) continue @@ -752,17 +757,20 @@ GLOBAL_LIST_EMPTY(turret_icons) /obj/machinery/porta_turret/proc/pop_up() //pops the turret up set_raised_raising(raised, TRUE) - playsound(get_turf(src), 'sound/effects/turret/open.wav', 60, 1) - update_icon(UPDATE_ICON_STATE) - - var/atom/flick_holder = new /atom/movable/porta_turret_cover(loc) - flick_holder.layer = layer + 0.1 - flick("popup", flick_holder) - sleep(10) - qdel(flick_holder) + if(cover) + if(saved_direction) + setDir(saved_direction) + saved_direction = null + flick("popup", cover) + playsound(get_turf(src), 'sound/effects/turret/open.wav', 60, TRUE) + sleep(POPUP_ANIM_TIME) + if(cover) + layer = ABOVE_OBJ_LAYER + cover.icon_state = "open_turret_cover" + cover.layer = BELOW_OBJ_LAYER + sleep(POPUP_ANIM_TIME) set_raised_raising(TRUE, FALSE) - update_icon(UPDATE_ICON_STATE) /obj/machinery/porta_turret/proc/pop_down() //pops the turret down last_target = null @@ -773,18 +781,20 @@ GLOBAL_LIST_EMPTY(turret_icons) if(stat & BROKEN) return set_raised_raising(raised, TRUE) - playsound(get_turf(src), 'sound/effects/turret/open.wav', 60, 1) - update_icon(UPDATE_ICON_STATE) - - var/atom/flick_holder = new /atom/movable/porta_turret_cover(loc) - flick_holder.layer = layer + 0.1 - flick("popdown", flick_holder) - sleep(10) - qdel(flick_holder) + sleep(POPDOWN_ANIM_TIME) + if(cover) + layer = OBJ_LAYER + cover.layer = HIGH_OBJ_LAYER + flick("popdown", cover) + playsound(get_turf(src), 'sound/effects/turret/open.wav', 60, TRUE) + sleep(POPDOWN_ANIM_TIME) set_raised_raising(FALSE, FALSE) - set_angle(0) - update_icon(UPDATE_ICON_STATE) + if(cover) + if(dir in list(NORTHEAST, NORTHWEST)) + saved_direction = dir + setDir(SOUTH) + cover.icon_state = "turret_cover" /obj/machinery/porta_turret/on_assess_perp(mob/living/carbon/human/perp) if((check_access || attacked) && !allowed(perp)) @@ -805,8 +815,7 @@ GLOBAL_LIST_EMPTY(turret_icons) last_target = target if(has_cover) check_pop_up() //pop the turret up if it's not already up. - // Set angle - set_angle(get_angle(src, target)) + setDir(get_dir(src, target)) // even if you can't shoot, follow the target shootAt(target) return TRUE @@ -1116,12 +1125,10 @@ GLOBAL_LIST_EMPTY(turret_icons) /obj/machinery/porta_turret_construct/attack_ai() return -/atom/movable/porta_turret_cover - icon = 'icons/obj/turrets.dmi' - anchored = TRUE - // Syndicate turrets /obj/machinery/porta_turret/syndicate + icon_state = "syndie_off" + base_icon_state = "syndie" projectile = /obj/item/projectile/bullet eprojectile = /obj/item/projectile/bullet // Syndicate turrets *always* operate in lethal mode. @@ -1131,11 +1138,6 @@ GLOBAL_LIST_EMPTY(turret_icons) shot_sound = 'sound/weapons/gunshots/gunshot_mg.ogg' eshot_sound = 'sound/weapons/gunshots/gunshot_mg.ogg' - icon_state = "syndieturret0" - var/icon_state_initial = "syndieturret0" - var/icon_state_active = "syndieturret1" - var/icon_state_destroyed = "syndieturret2" - syndicate = TRUE installation = null always_up = TRUE @@ -1185,14 +1187,6 @@ GLOBAL_LIST_EMPTY(turret_icons) set_raised_raising(TRUE, FALSE) update_icon(UPDATE_ICON_STATE) -/obj/machinery/porta_turret/syndicate/update_icon_state() - if(stat & BROKEN) - icon_state = icon_state_destroyed - else if(enabled) - icon_state = icon_state_active - else - icon_state = icon_state_initial - /obj/machinery/porta_turret/syndicate/setup() return @@ -1241,9 +1235,10 @@ GLOBAL_LIST_EMPTY(turret_icons) /obj/machinery/porta_turret/inflatable_turret name = "Syndicate Pop-Up Turret" desc = "Looks cheaply made on the defensive side but the gun barrel still shoots." + icon_state = "syndie_off" + base_icon_state = "syndie" projectile = /obj/item/projectile/bullet/weakbullet3 eprojectile = /obj/item/projectile/bullet/weakbullet3 - icon_state = "syndieturret0" shot_sound = 'sound/weapons/gunshots/gunshot_mg.ogg' eshot_sound = 'sound/weapons/gunshots/gunshot_mg.ogg' health = 100 @@ -1270,9 +1265,6 @@ GLOBAL_LIST_EMPTY(turret_icons) check_synth = TRUE ailock = TRUE var/owner_uid - var/icon_state_initial = "syndieturret0" - var/icon_state_active = "syndieturret1" - var/icon_state_destroyed = "syndieturret2" /obj/machinery/porta_turret/inflatable_turret/assess_and_assign(atom/movable/AM, list/targets, list/secondarytargets) if(AM.UID() == owner_uid) @@ -1282,14 +1274,6 @@ GLOBAL_LIST_EMPTY(turret_icons) /obj/machinery/porta_turret/inflatable_turret/setup() return -/obj/machinery/porta_turret/inflatable_turret/update_icon_state() - if(stat & BROKEN) - icon_state = icon_state_destroyed - else if(enabled) - icon_state = icon_state_active - else - icon_state = icon_state_initial - /obj/machinery/porta_turret/inflatable_turret/CanPass(atom/A) return ((stat & BROKEN) || !isliving(A)) @@ -1301,3 +1285,6 @@ GLOBAL_LIST_EMPTY(turret_icons) name = "ship defense turret" lethal = TRUE check_synth = TRUE + +#undef POPUP_ANIM_TIME +#undef POPDOWN_ANIM_TIME diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 8e07c188bad..c426e614042 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -77,3 +77,9 @@ var/unused = 0 ///overlays which go unused for this amount of time get cleaned up var/cache_expiration = 2 MINUTES + +/// Cover overlay for portable turrets +/obj/effect/overlay/turret + layer = HIGH_OBJ_LAYER + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + vis_flags = VIS_INHERIT_ID diff --git a/code/modules/awaymissions/mission_code/ruins/telecomns.dm b/code/modules/awaymissions/mission_code/ruins/telecomns.dm index d9c683f26f3..aa608876071 100644 --- a/code/modules/awaymissions/mission_code/ruins/telecomns.dm +++ b/code/modules/awaymissions/mission_code/ruins/telecomns.dm @@ -1,5 +1,8 @@ // stuff for the telecomms sat (telecomms_returns.dmm) +/// Turrets pop up in 1 second, animation is for 0.5 seconds, so we have to call for sleep() twice in order to make it 1 second and not fuck up the flick +#define POPUP_ANIM_TIME 0.5 SECONDS + GLOBAL_LIST_EMPTY(telecomms_bots) GLOBAL_LIST_EMPTY(telecomms_doomsday_device) GLOBAL_LIST_EMPTY(telecomms_trap_tank) @@ -194,7 +197,8 @@ GLOBAL_LIST_EMPTY(telecomms_trap_tank) name = "turret" desc = "Looks like the cover to a turret. Not deploying, however?" icon = 'icons/obj/turrets.dmi' - icon_state = "turretCover" + icon_state = "turret_cover" + layer = /obj/machinery/syndicatebomb/doomsday::layer + 0.1 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF anchored = TRUE /// Has someone stolen loot from the ruins core room? If they try to leave without killing dvorak, they are punished. @@ -209,15 +213,13 @@ GLOBAL_LIST_EMPTY(telecomms_trap_tank) return ..() /obj/structure/telecomms_doomsday_device/proc/start_the_party(ruin_cheese_attempted = FALSE) - invisibility = 90 var/obj/machinery/syndicatebomb/doomsday/kaboom = new /obj/machinery/syndicatebomb/doomsday(get_turf(src)) kaboom.icon_state = "death-bomb-active" - var/atom/flick_holder = new /atom/movable/porta_turret_cover(loc) for(var/obj/structure/telecomms_trap_tank/TTT in GLOB.telecomms_trap_tank) TTT.explode() - flick_holder.layer = kaboom.layer + 0.1 - flick("popup", flick_holder) - sleep(1 SECONDS) + sleep(POPUP_ANIM_TIME) + flick("popup", src) + sleep(POPUP_ANIM_TIME) for(var/obj/structure/telecomms_shield_cover/shield in urange(15, get_turf(src))) shield.activate() if(ruin_cheese_attempted) @@ -237,7 +239,6 @@ GLOBAL_LIST_EMPTY(telecomms_trap_tank) qdel(CT) kaboom.activate() kaboom.icon_state = "death-bomb-active" // something funny goes on with icons here - qdel(flick_holder) qdel(src) /obj/machinery/syndicatebomb/doomsday @@ -300,19 +301,19 @@ GLOBAL_LIST_EMPTY(telecomms_trap_tank) name = "turret" desc = "Looks like the cover to a turret. Not deploying, however?" icon = 'icons/obj/turrets.dmi' - icon_state = "turretCover" + icon_state = "turret_cover" + layer = /obj/machinery/shieldgen/telecomms::layer + 0.1 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF anchored = TRUE + /// Trap we create on activation + var/obj/machinery/shieldgen/telecomms/trap /obj/structure/telecomms_shield_cover/proc/activate() - invisibility = 90 - var/obj/machinery/shieldgen/telecomms/trap = new /obj/machinery/shieldgen/telecomms(get_turf(src)) - var/atom/flick_holder = new /atom/movable/porta_turret_cover(loc) - flick_holder.layer = trap.layer + 0.1 - flick("popup", flick_holder) - sleep(1 SECONDS) + trap = new(get_turf(src)) + sleep(POPUP_ANIM_TIME) + flick("popup", src) + sleep(POPUP_ANIM_TIME) trap.shields_up() - qdel(flick_holder) qdel(src) /turf/simulated/floor/catwalk/airless @@ -607,3 +608,5 @@ GLOBAL_LIST_EMPTY(telecomms_trap_tank) /obj/structure/environmental_storytelling_holopad/core_room things_to_say = list("OKAY. TIME TO GO.", "GO MY SECURITY BORGS, WHAT TIDERS F-FEAR!", "I have a DOOMSDAY DEVICE AND I AM NOT AFRAID TO SHOVE IT UP YOUR-") soundblock = "core" + +#undef POPUP_ANIM_TIME diff --git a/icons/obj/turrets.dmi b/icons/obj/turrets.dmi index 79cd58115d6..1eb74c9dc95 100644 Binary files a/icons/obj/turrets.dmi and b/icons/obj/turrets.dmi differ diff --git a/paradise.dme b/paradise.dme index 97e08b1c93b..ded31d95ddc 100644 --- a/paradise.dme +++ b/paradise.dme @@ -455,8 +455,8 @@ #include "code\datums\ai\basic_mobs\basic_controller.dm" #include "code\datums\ai\basic_mobs\simple_controller.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\basic_attacking.dm" -#include "code\datums\ai\basic_mobs\basic_ai_behaviors\emote_with_target.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\befriend_target.dm" +#include "code\datums\ai\basic_mobs\basic_ai_behaviors\emote_with_target.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\interact_with_target.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\nearest_targeting.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\run_away_from_target.dm" @@ -473,8 +473,8 @@ #include "code\datums\ai\basic_mobs\basic_subtrees\ranged_skirmish.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\simple_attack_target.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\simple_find_nearest_target_to_flee.dm" -#include "code\datums\ai\basic_mobs\basic_subtrees\stare_at_thing.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\simple_find_target.dm" +#include "code\datums\ai\basic_mobs\basic_subtrees\stare_at_thing.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\target_retaliate.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\tip_reaction.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\use_mob_ability.dm"