diff --git a/_maps/shuttles/infiltrator_basic.dmm b/_maps/shuttles/infiltrator_basic.dmm index 263d6927..f7ec35c6 100644 --- a/_maps/shuttles/infiltrator_basic.dmm +++ b/_maps/shuttles/infiltrator_basic.dmm @@ -2,15 +2,21 @@ "aa" = ( /turf/template_noop, /area/template_noop) -"ac" = ( -/obj/machinery/porta_turret/syndicate{ +"ab" = ( +/obj/machinery/porta_turret/syndicate/shuttle{ dir = 9 }, -/turf/closed/wall/mineral/plastitanium, +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/syndicate/bridge) +"ac" = ( +/turf/closed/wall/r_wall/syndicate, /area/shuttle/syndicate/bridge) "ad" = ( -/turf/closed/wall/mineral/plastitanium, -/area/shuttle/syndicate/bridge) +/obj/machinery/porta_turret/syndicate/shuttle{ + dir = 10 + }, +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/syndicate/hallway) "ae" = ( /obj/structure/window/plastitanium, /obj/machinery/door/poddoor/shutters{ @@ -21,11 +27,8 @@ /turf/open/floor/plating, /area/shuttle/syndicate/bridge) "af" = ( -/obj/machinery/porta_turret/syndicate{ - dir = 5 - }, -/turf/closed/wall/mineral/plastitanium, -/area/shuttle/syndicate/bridge) +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/syndicate/hallway) "ag" = ( /obj/machinery/computer/med_data/syndie, /obj/effect/turf_decal/bot_white, @@ -144,7 +147,7 @@ /area/shuttle/syndicate/bridge) "au" = ( /obj/machinery/status_display/evac, -/turf/closed/wall/mineral/plastitanium, +/turf/closed/wall/r_wall/syndicate, /area/shuttle/syndicate/bridge) "av" = ( /obj/machinery/door/airlock/hatch{ @@ -164,14 +167,14 @@ /turf/open/floor/plasteel/dark, /area/shuttle/syndicate/bridge) "aw" = ( -/obj/machinery/porta_turret/syndicate{ - dir = 10 +/obj/machinery/porta_turret/syndicate/shuttle{ + dir = 9 }, -/turf/closed/wall/mineral/plastitanium, -/area/shuttle/syndicate/hallway) +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/syndicate/eva) "ax" = ( -/turf/closed/wall/mineral/plastitanium, -/area/shuttle/syndicate/hallway) +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/syndicate/eva) "ay" = ( /obj/structure/table/reinforced, /obj/item/stack/cable_coil/white, @@ -222,11 +225,8 @@ /turf/open/floor/plasteel/dark, /area/shuttle/syndicate/hallway) "aB" = ( -/obj/machinery/porta_turret/syndicate{ - dir = 6 - }, -/turf/closed/wall/mineral/plastitanium, -/area/shuttle/syndicate/hallway) +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/syndicate/airlock) "aC" = ( /obj/structure/chair/comfy/shuttle{ dir = 4; @@ -265,14 +265,17 @@ /turf/open/floor/plasteel/dark, /area/shuttle/syndicate/hallway) "aF" = ( -/obj/machinery/porta_turret/syndicate{ +/obj/machinery/porta_turret/syndicate/shuttle{ + dir = 5 + }, +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/syndicate/armory) +"aG" = ( +/obj/machinery/porta_turret/syndicate/shuttle{ dir = 9 }, -/turf/closed/wall/mineral/plastitanium, -/area/shuttle/syndicate/eva) -"aG" = ( -/turf/closed/wall/mineral/plastitanium, -/area/shuttle/syndicate/eva) +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/syndicate/medical) "aH" = ( /obj/structure/chair/comfy/shuttle{ dir = 4; @@ -314,14 +317,11 @@ /turf/open/floor/plasteel/dark, /area/shuttle/syndicate/hallway) "aJ" = ( -/turf/closed/wall/mineral/plastitanium, -/area/shuttle/syndicate/airlock) +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/syndicate/medical) "aK" = ( -/obj/machinery/porta_turret/syndicate{ - dir = 5 - }, -/turf/closed/wall/mineral/plastitanium, -/area/shuttle/syndicate/armory) +/turf/closed/wall/r_wall/syndicate/nodiagonal, +/area/shuttle/syndicate/medical) "aL" = ( /obj/machinery/suit_storage_unit/syndicate, /obj/effect/turf_decal/stripes/line{ @@ -508,7 +508,7 @@ /obj/structure/sign/warning/vacuum/external{ layer = 4 }, -/turf/closed/wall/mineral/plastitanium, +/turf/closed/wall/r_wall/syndicate, /area/shuttle/syndicate/airlock) "be" = ( /obj/machinery/suit_storage_unit/syndicate, @@ -517,11 +517,6 @@ }, /turf/open/floor/mineral/plastitanium, /area/shuttle/syndicate/eva) -"bf" = ( -/obj/structure/reagent_dispensers/fueltank, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/shuttle/syndicate/eva) "bg" = ( /obj/structure/grille, /obj/structure/window/plastitanium, @@ -543,31 +538,28 @@ /turf/open/floor/mineral/plastitanium/red, /area/shuttle/syndicate/airlock) "bj" = ( -/obj/machinery/porta_turret/syndicate{ - dir = 9 - }, -/turf/closed/wall/mineral/plastitanium, -/area/shuttle/syndicate/medical) +/turf/closed/wall/r_wall/syndicate/nodiagonal, +/area/shuttle/syndicate/armory) "bk" = ( -/turf/closed/wall/mineral/plastitanium, -/area/shuttle/syndicate/medical) -"bl" = ( /obj/machinery/status_display/ai, -/turf/closed/wall/mineral/plastitanium, +/turf/closed/wall/r_wall/syndicate, /area/shuttle/syndicate/medical) "bm" = ( -/turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/shuttle/syndicate/medical) +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/syndicate/armory) "bn" = ( -/turf/closed/wall/mineral/plastitanium/nodiagonal, +/obj/machinery/status_display/evac, +/turf/closed/wall/r_wall/syndicate, /area/shuttle/syndicate/armory) "bo" = ( -/turf/closed/wall/mineral/plastitanium, -/area/shuttle/syndicate/armory) -"bp" = ( -/obj/machinery/status_display/evac, -/turf/closed/wall/mineral/plastitanium, -/area/shuttle/syndicate/armory) +/obj/machinery/nuclearbomb/syndicate{ + anchored = 1 + }, +/obj/machinery/door/window{ + dir = 1 + }, +/turf/open/floor/circuit/red, +/area/shuttle/syndicate/hallway) "bq" = ( /obj/machinery/sleeper/syndie{ dir = 4 @@ -1043,14 +1035,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/shuttle/syndicate/hallway) -"cm" = ( -/obj/machinery/nuclearbomb/syndicate, -/obj/machinery/door/window{ - dir = 1; - name = "Theatre Stage" - }, -/turf/open/floor/circuit/red, -/area/shuttle/syndicate/hallway) "cn" = ( /obj/machinery/light{ dir = 4 @@ -1169,18 +1153,6 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/plating/airless, /area/shuttle/syndicate/medical) -"cC" = ( -/obj/machinery/porta_turret/syndicate{ - dir = 6 - }, -/turf/closed/wall/mineral/plastitanium, -/area/shuttle/syndicate/medical) -"cD" = ( -/obj/machinery/porta_turret/syndicate{ - dir = 10 - }, -/turf/closed/wall/mineral/plastitanium, -/area/shuttle/syndicate/armory) "cE" = ( /obj/structure/shuttle/engine/propulsion/left, /obj/effect/turf_decal/stripes/line, @@ -1196,6 +1168,35 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/plating/airless, /area/shuttle/syndicate/armory) +"dp" = ( +/obj/machinery/porta_turret/syndicate/shuttle{ + dir = 10 + }, +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/syndicate/armory) +"pd" = ( +/obj/machinery/porta_turret/syndicate/shuttle{ + dir = 5 + }, +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/syndicate/bridge) +"vv" = ( +/obj/structure/reagent_dispensers/fueltank, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/shuttle/syndicate/eva) +"In" = ( +/obj/machinery/porta_turret/syndicate/shuttle{ + dir = 6 + }, +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/syndicate/hallway) +"MJ" = ( +/obj/machinery/porta_turret/syndicate/shuttle{ + dir = 6 + }, +/turf/closed/wall/r_wall/syndicate, +/area/shuttle/syndicate/medical) (1,1,1) = {" aa @@ -1211,16 +1212,16 @@ aa aa aa aa -bj -bk -bk -bk -bk -bk -bk -bk -bk -bk +aG +aJ +aJ +aJ +aJ +aJ +aJ +aJ +aJ +aJ "} (2,1,1) = {" aa @@ -1230,13 +1231,13 @@ aa aa aa aa -aF -aG -aG -aG -aG -aG -bk +aw +ax +ax +ax +ax +ax +aJ bq bC bq @@ -1255,13 +1256,13 @@ aa aa aa aa -aG +ax aL aR aR aR be -bk +aJ br bD bH @@ -1280,13 +1281,13 @@ aa aa aa aa -aG +ax aM aM aM aM aM -bl +bk bs bD bI @@ -1298,51 +1299,51 @@ cu cB "} (5,1,1) = {" +ab +ac +ac +ac ac -ad -ad -ad -ad aa aa -aG +ax aM aM aM aM aM -bk +aJ bt bD bJ bT cb -bm -bk -bk -cC +aK +aJ +aJ +MJ "} (6,1,1) = {" -ad +ac ag an at +ac ad -aw aa -aG +ax aN aS aU aZ -bf -bk +vv +aJ bu bD bJ bT cc -bk +aJ aa aa aa @@ -1352,24 +1353,24 @@ ae ah ao at -ad +ac +af +af +ax +ax ax ax -aG -aG -aG -aG ba bg -bm +aK bv bv bK bv -bk -bk -ax -ax +aJ +aJ +af +af aa "} (8,1,1) = {" @@ -1417,7 +1418,7 @@ aD bL bU az -cm +bo cr cw aa @@ -1427,7 +1428,7 @@ ae ak ap at -ad +ac aA aE aI @@ -1452,75 +1453,75 @@ ae al ar at -ad -ax -ax -ax -ax -aJ -aJ +ac +af +af +af +af +aB +aB bb bh -bn +bj bw bw bM bw -bo -bo -ax -ax +bm +bm +af +af aa "} (12,1,1) = {" -ad +ac am as at -ad -aB +ac +In aa -aJ +aB aO aO aX bc aO -bo +bm bx bG bN bV ce -bo +bm aa aa aa "} (13,1,1) = {" -af -ad -ad -ad -ad +pd +ac +ac +ac +ac aa aa -aJ +aB aP aP aP aP aP -bo +bm by bG bN bV cf -bn -bo -bo -cD +bj +bm +bm +dp "} (14,1,1) = {" aa @@ -1530,13 +1531,13 @@ aa aa aa aa -aJ +aB aP aP aP aP aP -bp +bn bz bG bO @@ -1555,13 +1556,13 @@ aa aa aa aa -aJ +aB aQ aT aT aT bi -bo +bm bA bG bP @@ -1580,13 +1581,13 @@ aa aa aa aa -aK -aJ -aJ +aF +aB +aB aY bd -aJ -bo +aB +bm bB bG bQ @@ -1611,14 +1612,14 @@ aa aa aa aa -aK -bo -bo -bo -bo -bo -bo -bo -bo -bo +aF +bm +bm +bm +bm +bm +bm +bm +bm +bm "} diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index 1a9922d6..bdd42f62 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -1,1068 +1,1087 @@ -#define TURRET_STUN 0 -#define TURRET_LETHAL 1 - -#define POPUP_ANIM_TIME 5 -#define POPDOWN_ANIM_TIME 5 //Be sure to change the icon animation at the same time or it'll look bad - -/obj/machinery/porta_turret - name = "turret" - icon = 'icons/obj/turrets.dmi' - icon_state = "turretCover" - layer = OBJ_LAYER - invisibility = INVISIBILITY_OBSERVER //the turret is invisible if it's inside its cover - density = TRUE - desc = "A covered turret that shoots at its enemies." - use_power = IDLE_POWER_USE //this turret uses and requires power - idle_power_usage = 50 //when inactive, this turret takes up constant 50 Equipment power - active_power_usage = 300 //when active, this turret takes up constant 300 Equipment power - req_access = list(ACCESS_SEC_DOORS) - power_channel = EQUIP //drains power from the EQUIPMENT channel - - var/base_icon_state = "standard" - var/scan_range = 7 - var/atom/base = null //for turrets inside other objects - - var/raised = 0 //if the turret cover is "open" and the turret is raised - var/raising= 0 //if the turret is currently opening or closing its cover - - max_integrity = 160 //the turret's health - integrity_failure = 80 - armor = list("melee" = 50, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) - - var/locked = TRUE //if the turret's behaviour control access is locked - var/controllock = FALSE //if the turret responds to control panels - - var/installation = /obj/item/gun/energy/e_gun/turret //the type of weapon installed by default - var/obj/item/gun/stored_gun = null - var/gun_charge = 0 //the charge of the gun when retrieved from wreckage - - var/mode = TURRET_STUN - - var/stun_projectile = null //stun mode projectile type - var/stun_projectile_sound - var/nonlethal_projectile //projectile to use in stun mode when the target is resting, if any - var/nonlethal_projectile_sound - var/lethal_projectile = null //lethal mode projectile type - var/lethal_projectile_sound - - var/reqpower = 500 //power needed per shot - var/always_up = 0 //Will stay active - var/has_cover = 1 //Hides the cover - - var/obj/machinery/porta_turret_cover/cover = null //the cover that is covering this turret - - var/last_fired = 0 //world.time the turret last fired - var/shot_delay = 15 //ticks until next shot (1.5 ?) - - - var/check_records = 1 //checks if it can use the security records - var/criminals = 1 //checks if it can shoot people on arrest - var/auth_weapons = 0 //checks if it can shoot people that have a weapon they aren't authorized to have - var/stun_all = 0 //if this is active, the turret shoots everything that isn't security or head of staff - var/check_anomalies = 1 //checks if it can shoot at unidentified lifeforms (ie xenos) - var/shoot_unloyal = 0 //checks if it can shoot people that aren't loyalty implantd - - var/attacked = 0 //if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!) - - var/on = TRUE //determines if the turret is on - - var/list/faction = list("turret") // Same faction mobs will never be shot at, no matter the other settings - - var/datum/effect_system/spark_spread/spark_system //the spark system, used for generating... sparks? - - var/obj/machinery/turretid/cp = null - - var/wall_turret_direction //The turret will try to shoot from a turf in that direction when in a wall - - var/manual_control = FALSE // - var/datum/action/turret_quit/quit_action - var/datum/action/turret_toggle/toggle_action - var/mob/remote_controller - -/obj/machinery/porta_turret/Initialize() - . = ..() - if(!base) - base = src - update_icon() - //Sets up a spark system - spark_system = new /datum/effect_system/spark_spread - spark_system.set_up(5, 0, src) - spark_system.attach(src) - - setup() - if(has_cover) - cover = new /obj/machinery/porta_turret_cover(loc) - cover.parent_turret = src - var/mutable_appearance/base = mutable_appearance('icons/obj/turrets.dmi', "basedark") - base.layer = NOT_HIGH_OBJ_LAYER - underlays += base - if(!has_cover) - INVOKE_ASYNC(src, .proc/popUp) - -/obj/machinery/porta_turret/update_icon() - cut_overlays() - if(!anchored) - icon_state = "turretCover" - return - if(stat & BROKEN) - icon_state = "[base_icon_state]_broken" - else - if(powered()) - if(on && raised) - switch(mode) - if(TURRET_STUN) - icon_state = "[base_icon_state]_stun" - if(TURRET_LETHAL) - icon_state = "[base_icon_state]_lethal" - else - icon_state = "[base_icon_state]_off" - else - icon_state = "[base_icon_state]_unpowered" - - -/obj/machinery/porta_turret/proc/setup(obj/item/gun/turret_gun) - if(stored_gun) - qdel(stored_gun) - stored_gun = null - - if(installation && !turret_gun) - stored_gun = new installation(src) - else if (turret_gun) - stored_gun = turret_gun - - var/list/gun_properties = stored_gun.get_turret_properties() - - //required properties - stun_projectile = gun_properties["stun_projectile"] - stun_projectile_sound = gun_properties["stun_projectile_sound"] - lethal_projectile = gun_properties["lethal_projectile"] - lethal_projectile_sound = gun_properties["lethal_projectile_sound"] - base_icon_state = gun_properties["base_icon_state"] - - //optional properties - if(gun_properties["shot_delay"]) - shot_delay = gun_properties["shot_delay"] - if(gun_properties["reqpower"]) - reqpower = gun_properties["reqpower"] - - update_icon() - return gun_properties - -/obj/machinery/porta_turret/Destroy() - //deletes its own cover with it - QDEL_NULL(cover) - base = null - if(cp) - cp.turrets -= src - cp = null - QDEL_NULL(stored_gun) - QDEL_NULL(spark_system) - remove_control() - return ..() - -/obj/machinery/porta_turret/ui_interact(mob/user) - . = ..() - var/dat - dat += "Status: [on ? "On" : "Off"]
" - dat += "Behaviour controls are [locked ? "locked" : "unlocked"]
" - - if(!locked) - dat += "Check for Weapon Authorization: [auth_weapons ? "Yes" : "No"]
" - dat += "Check Security Records: [check_records ? "Yes" : "No"]
" - dat += "Neutralize Identified Criminals: [criminals ? "Yes" : "No"]
" - dat += "Neutralize All Non-Security and Non-Command Personnel: [stun_all ? "Yes" : "No"]
" - dat += "Neutralize All Unidentified Life Signs: [check_anomalies ? "Yes" : "No"]
" - dat += "Neutralize All Non-Loyalty Implanted Personnel: [shoot_unloyal ? "Yes" : "No"]
" - if(issilicon(user)) - if(!manual_control) - var/mob/living/silicon/S = user - if(S.hack_software) - dat += "Assume direct control : Manual Control
" - else - dat += "Warning! Remote control protocol enabled.
" - - - var/datum/browser/popup = new(user, "autosec", "Automatic Portable Turret Installation", 300, 300) - popup.set_content(dat) - popup.open() - -/obj/machinery/porta_turret/Topic(href, href_list) - if(..()) - return - usr.set_machine(src) - add_fingerprint(usr) - - if(href_list["power"] && !locked) - if(anchored) //you can't turn a turret on/off if it's not anchored/secured - on = !on //toggle on/off - else - to_chat(usr, "It has to be secured first!") - interact(usr) - return - - if(href_list["operation"]) - switch(href_list["operation"]) //toggles customizable behavioural protocols - if("authweapon") - auth_weapons = !auth_weapons - if("checkrecords") - check_records = !check_records - if("shootcrooks") - criminals = !criminals - if("shootall") - stun_all = !stun_all - if("checkxenos") - check_anomalies = !check_anomalies - if("checkloyal") - shoot_unloyal = !shoot_unloyal - if("manual") - if(issilicon(usr) && !manual_control) - give_control(usr) - interact(usr) - -/obj/machinery/porta_turret/power_change() - if(!anchored) - update_icon() - remove_control() - return - if(stat & BROKEN) - update_icon() - remove_control() - else - if( powered() ) - stat &= ~NOPOWER - update_icon() - else - spawn(rand(0, 15)) - stat |= NOPOWER - remove_control() - update_icon() - - -/obj/machinery/porta_turret/attackby(obj/item/I, mob/user, params) - if(stat & BROKEN) - if(istype(I, /obj/item/crowbar)) - //If the turret is destroyed, you can remove it with a crowbar to - //try and salvage its components - to_chat(user, "You begin prying the metal coverings off...") - if(I.use_tool(src, user, 20)) - if(prob(70)) - if(stored_gun) - stored_gun.forceMove(loc) - to_chat(user, "You remove the turret and salvage some components.") - if(prob(50)) - new /obj/item/stack/sheet/metal(loc, rand(1,4)) - if(prob(50)) - new /obj/item/assembly/prox_sensor(loc) - else - to_chat(user, "You remove the turret but did not manage to salvage anything.") - qdel(src) - - else if((istype(I, /obj/item/wrench)) && (!on)) - if(raised) - return - - //This code handles moving the turret around. After all, it's a portable turret! - if(!anchored && !isinspace()) - setAnchored(TRUE) - invisibility = INVISIBILITY_MAXIMUM - update_icon() - to_chat(user, "You secure the exterior bolts on the turret.") - if(has_cover) - cover = new /obj/machinery/porta_turret_cover(loc) //create a new turret. While this is handled in process(), this is to workaround a bug where the turret becomes invisible for a split second - cover.parent_turret = src //make the cover's parent src - else if(anchored) - setAnchored(FALSE) - to_chat(user, "You unsecure the exterior bolts on the turret.") - power_change() - invisibility = 0 - qdel(cover) //deletes the cover, and the turret instance itself becomes its own cover. - - else if(I.GetID()) - //Behavior lock/unlock mangement - if(allowed(user)) - locked = !locked - to_chat(user, "Controls are now [locked ? "locked" : "unlocked"].") - else - to_chat(user, "Access denied.") - else if(istype(I, /obj/item/multitool) && !locked) - var/obj/item/multitool/M = I - M.buffer = src - to_chat(user, "You add [src] to multitool buffer.") - else - return ..() - -/obj/machinery/porta_turret/emag_act(mob/user) - if(obj_flags & EMAGGED) - return - to_chat(user, "You short out [src]'s threat assessment circuits.") - visible_message("[src] hums oddly...") - obj_flags |= EMAGGED - controllock = TRUE - on = FALSE //turns off the turret temporarily - update_icon() - sleep(60) //6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit - on = TRUE //turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here - - -/obj/machinery/porta_turret/emp_act(severity) - . = ..() - if (. & EMP_PROTECT_SELF) - return - if(on) - //if the turret is on, the EMP no matter how severe disables the turret for a while - //and scrambles its settings, with a slight chance of having an emag effect - check_records = pick(0, 1) - criminals = pick(0, 1) - auth_weapons = pick(0, 1) - stun_all = pick(0, 0, 0, 0, 1) //stun_all is a pretty big deal, so it's least likely to get turned on - - on = FALSE - remove_control() - - spawn(rand(60,600)) - if(!on) - on = TRUE - -/obj/machinery/porta_turret/take_damage(damage, damage_type = BRUTE, damage_flag = 0, sound_effect = 1) - . = ..() - if(.) //damage received - if(prob(30)) - spark_system.start() - if(on && !attacked && !(obj_flags & EMAGGED)) - attacked = TRUE - addtimer(CALLBACK(src, .proc/reset_attacked), 60) - -/obj/machinery/porta_turret/proc/reset_attacked() - attacked = FALSE - -/obj/machinery/porta_turret/deconstruct(disassembled = TRUE) - qdel(src) - -/obj/machinery/porta_turret/obj_break(damage_flag) - if(!(flags_1 & NODECONSTRUCT_1) && !(stat & BROKEN)) - stat |= BROKEN //enables the BROKEN bit - power_change() - invisibility = 0 - spark_system.start() //creates some sparks because they look cool - qdel(cover) //deletes the cover - no need on keeping it there! - - - -/obj/machinery/porta_turret/process() - //the main machinery process - if(cover == null && anchored) //if it has no cover and is anchored - if(stat & BROKEN) //if the turret is borked - qdel(cover) //delete its cover, assuming it has one. Workaround for a pesky little bug - else - if(has_cover) - cover = new /obj/machinery/porta_turret_cover(loc) //if the turret has no cover and is anchored, give it a cover - cover.parent_turret = src //assign the cover its parent_turret, which would be this (src) - - if(!on || (stat & (NOPOWER|BROKEN)) || manual_control) - return - - var/list/targets = list() - for(var/mob/A in view(scan_range, base)) - if(A.invisibility > SEE_INVISIBLE_LIVING) - continue - - if(check_anomalies)//if it's set to check for simple animals - if(isanimal(A)) - var/mob/living/simple_animal/SA = A - if(SA.stat || in_faction(SA) || istype(SA, /mob/living/simple_animal/hostile/megafauna)) //don't target if dead or in faction - continue - targets += SA - if(issilicon(A)) - var/mob/living/silicon/sillycone = A - if(sillycone.stat || in_faction(sillycone)) - continue - - if(iscyborg(sillycone)) - var/mob/living/silicon/robot/sillyconerobot = A - if(LAZYLEN(faction) && (ROLE_SYNDICATE in faction) && sillyconerobot.emagged == TRUE) - continue - - targets += sillycone - - if(iscarbon(A)) - var/mob/living/carbon/C = A - //If not emagged, only target non downed carbons - if(mode != TURRET_LETHAL && (C.stat || C.handcuffed || C.recoveringstam))//CIT CHANGE - replaces check for lying with check for recoveringstam - continue - - //If emagged, target all but dead carbons - if(mode == TURRET_LETHAL && C.stat == DEAD) - continue - - //if the target is a human and not in our faction, analyze threat level - if(ishuman(C) && !in_faction(C)) - if(assess_perp(C) >= 4) - targets += C - - else if(check_anomalies) //non humans who are not simple animals (xenos etc) - if(!in_faction(C)) - targets += C - for(var/A in GLOB.mechas_list) - if((get_dist(A, base) < scan_range) && can_see(base, A, scan_range)) - var/obj/mecha/Mech = A - if(Mech.occupant && !in_faction(Mech.occupant)) //If there is a user and they're not in our faction - if(assess_perp(Mech.occupant) >= 4) - targets += Mech - - if(targets.len) - tryToShootAt(targets) - else if(!always_up) - popDown() // no valid targets, close the cover - -/obj/machinery/porta_turret/proc/tryToShootAt(list/atom/movable/targets) - while(targets.len > 0) - var/atom/movable/M = pick(targets) - targets -= M - if(target(M)) - return 1 - - -/obj/machinery/porta_turret/proc/popUp() //pops the turret up - if(!anchored) - return - if(raising || raised) - return - if(stat & BROKEN) - return - invisibility = 0 - raising = 1 - if(cover) - flick("popup", cover) - sleep(POPUP_ANIM_TIME) - raising = 0 - if(cover) - cover.icon_state = "openTurretCover" - raised = 1 - layer = MOB_LAYER - -/obj/machinery/porta_turret/proc/popDown() //pops the turret down - if(raising || !raised) - return - if(stat & BROKEN) - return - layer = OBJ_LAYER - raising = 1 - if(cover) - flick("popdown", cover) - sleep(POPDOWN_ANIM_TIME) - raising = 0 - if(cover) - cover.icon_state = "turretCover" - raised = 0 - invisibility = 2 - update_icon() - -/obj/machinery/porta_turret/proc/assess_perp(mob/living/carbon/human/perp) - var/threatcount = 0 //the integer returned - - if(obj_flags & EMAGGED) - return 10 //if emagged, always return 10. - - if((stun_all || attacked) && !allowed(perp)) - //if the turret has been attacked or is angry, target all non-sec people - if(!allowed(perp)) - return 10 - - if(auth_weapons) //check for weapon authorization - if(isnull(perp.wear_id) || istype(perp.wear_id.GetID(), /obj/item/card/id/syndicate)) - - if(allowed(perp)) //if the perp has security access, return 0 - return 0 - - if(perp.is_holding_item_of_type(/obj/item/gun) || perp.is_holding_item_of_type(/obj/item/melee/baton)) - threatcount += 4 - - if(istype(perp.belt, /obj/item/gun) || istype(perp.belt, /obj/item/melee/baton)) - threatcount += 2 - - if(check_records) //if the turret can check the records, check if they are set to *Arrest* on records - var/perpname = perp.get_face_name(perp.get_id_name()) - var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.security) - if(!R || (R.fields["criminal"] == "*Arrest*")) - threatcount += 4 - - if(shoot_unloyal) - if (!HAS_TRAIT(perp, TRAIT_MINDSHIELD)) - threatcount += 4 - - return threatcount - - -/obj/machinery/porta_turret/proc/in_faction(mob/target) - for(var/faction1 in faction) - if(faction1 in target.faction) - return TRUE - return FALSE - -/obj/machinery/porta_turret/proc/target(atom/movable/target) - if(target) - popUp() //pop the turret up if it's not already up. - setDir(get_dir(base, target))//even if you can't shoot, follow the target - shootAt(target) - return 1 - return - -/obj/machinery/porta_turret/proc/shootAt(atom/movable/target) - if(!raised) //the turret has to be raised in order to fire - makes sense, right? - return - - if(!(obj_flags & EMAGGED)) //if it hasn't been emagged, cooldown before shooting again - if(last_fired + shot_delay > world.time) - return - last_fired = world.time - - var/turf/T = get_turf(src) - var/turf/U = get_turf(target) - if(!istype(T) || !istype(U)) - return - - //Wall turrets will try to find adjacent empty turf to shoot from to cover full arc - if(T.density) - if(wall_turret_direction) - var/turf/closer = get_step(T,wall_turret_direction) - if(istype(closer) && !is_blocked_turf(closer) && T.Adjacent(closer)) - T = closer - else - var/target_dir = get_dir(T,target) - for(var/d in list(0,-45,45)) - var/turf/closer = get_step(T,turn(target_dir,d)) - if(istype(closer) && !is_blocked_turf(closer) && T.Adjacent(closer)) - T = closer - break - - var/mob/living/carbon/C - if(iscarbon(target)) - C = target - update_icon() - var/obj/item/projectile/A - //any emagged turrets drains 2x power and uses a different projectile? - if(mode == TURRET_STUN) - if(nonlethal_projectile && C && C.resting) - use_power(reqpower*0.5) - A = new nonlethal_projectile(T) - playsound(loc, nonlethal_projectile_sound, 75, 1) - else - use_power(reqpower) - A = new stun_projectile(T) - playsound(loc, stun_projectile_sound, 75, 1) - else - use_power(reqpower * 2) - A = new lethal_projectile(T) - playsound(loc, lethal_projectile_sound, 75, 1) - - - //Shooting Code: - A.preparePixelProjectile(target, T) - A.firer = src - A.fire() - return A - -/obj/machinery/porta_turret/proc/setState(on, mode) - if(controllock) - return - src.on = on - if(!on) - popDown() - src.mode = mode - power_change() - - -/datum/action/turret_toggle - name = "Toggle Mode" - icon_icon = 'icons/mob/actions/actions_mecha.dmi' - button_icon_state = "mech_cycle_equip_off" - -/datum/action/turret_toggle/Trigger() - var/obj/machinery/porta_turret/P = target - if(!istype(P)) - return - P.setState(P.on,!P.mode) - -/datum/action/turret_quit - name = "Release Control" - icon_icon = 'icons/mob/actions/actions_mecha.dmi' - button_icon_state = "mech_eject" - -/datum/action/turret_quit/Trigger() - var/obj/machinery/porta_turret/P = target - if(!istype(P)) - return - P.remove_control(FALSE) - -/obj/machinery/porta_turret/proc/give_control(mob/A) - if(manual_control || !can_interact(A)) - return FALSE - remote_controller = A - if(!quit_action) - quit_action = new(src) - quit_action.Grant(remote_controller) - if(!toggle_action) - toggle_action = new(src) - toggle_action.Grant(remote_controller) - remote_controller.reset_perspective(src) - remote_controller.click_intercept = src - manual_control = TRUE - always_up = TRUE - popUp() - return TRUE - -/obj/machinery/porta_turret/proc/remove_control(warning_message = TRUE) - if(!manual_control) - return FALSE - if(remote_controller) - if(warning_message) - to_chat(remote_controller, "Your uplink to [src] has been severed!") - quit_action.Remove(remote_controller) - toggle_action.Remove(remote_controller) - remote_controller.click_intercept = null - remote_controller.reset_perspective() - always_up = initial(always_up) - manual_control = FALSE - remote_controller = null - return TRUE - -/obj/machinery/porta_turret/proc/InterceptClickOn(mob/living/caller, params, atom/A) - if(!manual_control) - return FALSE - if(!can_interact(caller)) - remove_control() - return FALSE - log_combat(caller,A,"fired with manual turret control at") - target(A) - return TRUE - -/obj/machinery/porta_turret/syndicate - installation = null - always_up = 1 - use_power = NO_POWER_USE - has_cover = 0 - scan_range = 9 - req_access = list(ACCESS_SYNDICATE) - stun_projectile = /obj/item/projectile/bullet - lethal_projectile = /obj/item/projectile/bullet - lethal_projectile_sound = 'sound/weapons/gunshot.ogg' - stun_projectile_sound = 'sound/weapons/gunshot.ogg' - icon_state = "syndie_off" - base_icon_state = "syndie" - faction = list(ROLE_SYNDICATE) - desc = "A ballistic machine gun auto-turret." - -/obj/machinery/porta_turret/syndicate/ComponentInitialize() - . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) - -/obj/machinery/porta_turret/syndicate/energy - icon_state = "standard_stun" - base_icon_state = "standard" - stun_projectile = /obj/item/projectile/energy/electrode - stun_projectile_sound = 'sound/weapons/taser.ogg' - nonlethal_projectile = /obj/item/projectile/beam/disabler - nonlethal_projectile_sound = 'sound/weapons/taser2.ogg' - lethal_projectile = /obj/item/projectile/beam/laser - lethal_projectile_sound = 'sound/weapons/laser.ogg' - desc = "An energy blaster auto-turret." - -/obj/machinery/porta_turret/syndicate/energy/heavy - icon_state = "standard_stun" - base_icon_state = "standard" - stun_projectile = /obj/item/projectile/energy/electrode - stun_projectile_sound = 'sound/weapons/taser.ogg' - nonlethal_projectile = /obj/item/projectile/beam/disabler - nonlethal_projectile_sound = 'sound/weapons/taser2.ogg' - lethal_projectile = /obj/item/projectile/beam/laser/heavylaser - lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg' - desc = "An energy blaster auto-turret." - - -/obj/machinery/porta_turret/syndicate/setup() - return - -/obj/machinery/porta_turret/syndicate/assess_perp(mob/living/carbon/human/perp) - return 10 //Syndicate turrets shoot everything not in their faction - -/obj/machinery/porta_turret/syndicate/pod - integrity_failure = 20 - max_integrity = 40 - stun_projectile = /obj/item/projectile/bullet/syndicate_turret - lethal_projectile = /obj/item/projectile/bullet/syndicate_turret - -/obj/machinery/porta_turret/ai - faction = list("silicon") - nonlethal_projectile = /obj/item/projectile/beam/disabler - nonlethal_projectile_sound = 'sound/weapons/taser2.ogg' - -/obj/machinery/porta_turret/ai/assess_perp(mob/living/carbon/human/perp) - return 10 //AI turrets shoot at everything not in their faction - -/obj/machinery/porta_turret/aux_base - name = "perimeter defense turret" - desc = "A plasma beam turret calibrated to defend outposts against non-humanoid fauna. It is more effective when exposed to the environment." - installation = null - lethal_projectile = /obj/item/projectile/plasma/turret - lethal_projectile_sound = 'sound/weapons/plasma_cutter.ogg' - mode = TURRET_LETHAL //It would be useless in stun mode anyway - faction = list("neutral","silicon","turret") //Minebots, medibots, etc that should not be shot. - -/obj/machinery/porta_turret/aux_base/assess_perp(mob/living/carbon/human/perp) - return 0 //Never shoot humanoids. You are on your own if Ashwalkers or the like attack! - -/obj/machinery/porta_turret/aux_base/setup() - return - -/obj/machinery/porta_turret/aux_base/interact(mob/user) //Controlled solely from the base console. - return - -/obj/machinery/porta_turret/aux_base/Initialize() - . = ..() - cover.name = name - cover.desc = desc - -/obj/machinery/porta_turret/centcom_shuttle - installation = null - max_integrity = 260 - always_up = 1 - use_power = NO_POWER_USE - has_cover = 0 - scan_range = 9 - stun_projectile = /obj/item/projectile/beam/laser - lethal_projectile = /obj/item/projectile/beam/laser - lethal_projectile_sound = 'sound/weapons/plasma_cutter.ogg' - stun_projectile_sound = 'sound/weapons/plasma_cutter.ogg' - icon_state = "syndie_off" - base_icon_state = "syndie" - faction = list("neutral","silicon","turret") - mode = TURRET_LETHAL - -/obj/machinery/porta_turret/centcom_shuttle/ComponentInitialize() - . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) - -/obj/machinery/porta_turret/centcom_shuttle/assess_perp(mob/living/carbon/human/perp) - return 0 - -/obj/machinery/porta_turret/centcom_shuttle/setup() - return - -/obj/machinery/porta_turret/centcom_shuttle/weak - max_integrity = 120 - integrity_failure = 60 - name = "Old Laser Turret" - desc = "A turret built with substandard parts and run down further with age. Still capable of delivering lethal lasers to the odd space carp, but not much else." - stun_projectile = /obj/item/projectile/beam/weak/penetrator - lethal_projectile = /obj/item/projectile/beam/weak/penetrator - faction = list("neutral","silicon","turret") - -/obj/machinery/porta_turret/centcom_shuttle/ballistic - stun_projectile = /obj/item/projectile/bullet - lethal_projectile = /obj/item/projectile/bullet - lethal_projectile_sound = 'sound/weapons/gunshot.ogg' - stun_projectile_sound = 'sound/weapons/gunshot.ogg' - desc = "A ballistic machine gun auto-turret." - - -//////////////////////// -//Turret Control Panel// -//////////////////////// - -/obj/machinery/turretid - name = "turret control panel" - desc = "Used to control a room's automated defenses." - icon = 'icons/obj/machines/turret_control.dmi' - icon_state = "control_standby" - density = FALSE - var/enabled = 1 - var/lethal = 0 - var/locked = TRUE - var/control_area = null //can be area name, path or nothing. - var/ailock = 0 // AI cannot use this - req_access = list(ACCESS_AI_UPLOAD) - var/list/obj/machinery/porta_turret/turrets = list() - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - -/obj/machinery/turretid/Initialize(mapload, ndir = 0, built = 0) - . = ..() - if(built) - setDir(ndir) - locked = FALSE - pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) - pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0 - power_change() //Checks power and initial settings - -/obj/machinery/turretid/Destroy() - turrets.Cut() - return ..() - -/obj/machinery/turretid/Initialize(mapload) //map-placed turrets autolink turrets - . = ..() - if(!mapload) - return - - if(control_area) - control_area = get_area_instance_from_text(control_area) - if(control_area == null) - control_area = get_area(src) - stack_trace("Bad control_area path for [src], [src.control_area]") - else if(!control_area) - control_area = get_area(src) - - for(var/obj/machinery/porta_turret/T in control_area) - turrets |= T - T.cp = src - -/obj/machinery/turretid/examine(mob/user) - . = ..() - if(issilicon(user) && (!stat & BROKEN)) - . += "Ctrl-click [src] to [ enabled ? "disable" : "enable"] turrets." - . += "Alt-click [src] to set turrets to [ lethal ? "stun" : "kill"]." - -/obj/machinery/turretid/attackby(obj/item/I, mob/user, params) - if(stat & BROKEN) - return - - if (istype(I, /obj/item/multitool)) - var/obj/item/multitool/M = I - if(M.buffer && istype(M.buffer, /obj/machinery/porta_turret)) - turrets |= M.buffer - to_chat(user, "You link \the [M.buffer] with \the [src]") - return - - if (issilicon(user)) - return attack_hand(user) - - if ( get_dist(src, user) == 0 ) // trying to unlock the interface - if (allowed(usr)) - if(obj_flags & EMAGGED) - to_chat(user, "The turret control is unresponsive.") - return - - locked = !locked - to_chat(user, "You [ locked ? "lock" : "unlock"] the panel.") - if (locked) - if (user.machine==src) - user.unset_machine() - user << browse(null, "window=turretid") - else - if (user.machine==src) - attack_hand(user) - else - to_chat(user, "Access denied.") - -/obj/machinery/turretid/emag_act(mob/user) - if(obj_flags & EMAGGED) - return - to_chat(user, "You short out the turret controls' access analysis module.") - obj_flags |= EMAGGED - locked = FALSE - if(user && user.machine == src) - attack_hand(user) - -/obj/machinery/turretid/attack_ai(mob/user) - if(!ailock || IsAdminGhost(user)) - return attack_hand(user) - else - to_chat(user, "There seems to be a firewall preventing you from accessing this device.") - -/obj/machinery/turretid/ui_interact(mob/user) - . = ..() - if ( get_dist(src, user) > 0 ) - if ( !(issilicon(user) || IsAdminGhost(user)) ) - to_chat(user, "You are too far away.") - user.unset_machine() - user << browse(null, "window=turretid") - return - - var/t = "" - - if(locked && !(issilicon(user) || IsAdminGhost(user))) - t += "
Swipe ID card to unlock interface
" - else - if(!issilicon(user) && !IsAdminGhost(user)) - t += "
Swipe ID card to lock interface
" - t += "Turrets [enabled?"activated":"deactivated"] - [enabled?"Disable":"Enable"]?
" - t += "Currently set for [lethal?"lethal":"stun repeatedly"] - Change to [lethal?"Stun repeatedly":"Lethal"]?
" - - var/datum/browser/popup = new(user, "turretid", "Turret Control Panel ([get_area_name(src, TRUE)])") - popup.set_content(t) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - -/obj/machinery/turretid/Topic(href, href_list) - if(..()) - return - if (locked) - if(!(issilicon(usr) || IsAdminGhost(usr))) - to_chat(usr, "Control panel is locked!") - return - if (href_list["toggleOn"]) - toggle_on() - else if (href_list["toggleLethal"]) - toggle_lethal() - attack_hand(usr) - -/obj/machinery/turretid/proc/toggle_lethal() - lethal = !lethal - updateTurrets() - -/obj/machinery/turretid/proc/toggle_on() - enabled = !enabled - updateTurrets() - -/obj/machinery/turretid/proc/updateTurrets() - for (var/obj/machinery/porta_turret/aTurret in turrets) - aTurret.setState(enabled, lethal) - update_icon() - -/obj/machinery/turretid/power_change() - ..() - update_icon() - -/obj/machinery/turretid/update_icon() - ..() - if(stat & NOPOWER) - icon_state = "control_off" - else if (enabled) - if (lethal) - icon_state = "control_kill" - else - icon_state = "control_stun" - else - icon_state = "control_standby" - -/obj/item/wallframe/turret_control - name = "turret control frame" - desc = "Used for building turret control panels." - icon_state = "apc" - result_path = /obj/machinery/turretid - materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT) - -/obj/item/gun/proc/get_turret_properties() - . = list() - .["lethal_projectile"] = null - .["lethal_projectile_sound"] = null - .["stun_projectile"] = null - .["stun_projectile_sound"] = null - .["base_icon_state"] = "standard" - -/obj/item/gun/energy/get_turret_properties() - . = ..() - - var/obj/item/ammo_casing/primary_ammo = ammo_type[1] - - .["stun_projectile"] = initial(primary_ammo.projectile_type) - .["stun_projectile_sound"] = initial(primary_ammo.fire_sound) - - if(ammo_type.len > 1) - var/obj/item/ammo_casing/secondary_ammo = ammo_type[2] - .["lethal_projectile"] = initial(secondary_ammo.projectile_type) - .["lethal_projectile_sound"] = initial(secondary_ammo.fire_sound) - else - .["lethal_projectile"] = .["stun_projectile"] - .["lethal_projectile_sound"] = .["stun_projectile_sound"] - -/obj/item/gun/ballistic/get_turret_properties() - . = ..() - var/obj/item/ammo_box/mag = mag_type - var/obj/item/ammo_casing/primary_ammo = initial(mag.ammo_type) - - .["base_icon_state"] = "syndie" - .["stun_projectile"] = initial(primary_ammo.projectile_type) - .["stun_projectile_sound"] = initial(primary_ammo.fire_sound) - .["lethal_projectile"] = .["stun_projectile"] - .["lethal_projectile_sound"] = .["stun_projectile_sound"] - - -/obj/item/gun/energy/laser/bluetag/get_turret_properties() - . = ..() - .["stun_projectile"] = /obj/item/projectile/beam/lasertag/bluetag - .["lethal_projectile"] = /obj/item/projectile/beam/lasertag/bluetag - .["base_icon_state"] = "blue" - .["shot_delay"] = 30 - .["team_color"] = "blue" - -/obj/item/gun/energy/laser/redtag/get_turret_properties() - . = ..() - .["stun_projectile"] = /obj/item/projectile/beam/lasertag/redtag - .["lethal_projectile"] = /obj/item/projectile/beam/lasertag/redtag - .["base_icon_state"] = "red" - .["shot_delay"] = 30 - .["team_color"] = "red" - -/obj/item/gun/energy/e_gun/turret/get_turret_properties() - . = ..() - -/obj/machinery/porta_turret/lasertag - req_access = list(ACCESS_MAINT_TUNNELS, ACCESS_THEATRE) - check_records = 0 - criminals = 0 - auth_weapons = 1 - stun_all = 0 - check_anomalies = 0 - var/team_color - -/obj/machinery/porta_turret/lasertag/assess_perp(mob/living/carbon/human/perp) - . = 0 - if(team_color == "blue") //Lasertag turrets target the opposing team, how great is that? -Sieve - . = 0 //But does not target anyone else - if(istype(perp.wear_suit, /obj/item/clothing/suit/redtag)) - . += 4 - if(perp.is_holding_item_of_type(/obj/item/gun/energy/laser/redtag)) - . += 4 - if(istype(perp.belt, /obj/item/gun/energy/laser/redtag)) - . += 2 - - if(team_color == "red") - . = 0 - if(istype(perp.wear_suit, /obj/item/clothing/suit/bluetag)) - . += 4 - if(perp.is_holding_item_of_type(/obj/item/gun/energy/laser/bluetag)) - . += 4 - if(istype(perp.belt, /obj/item/gun/energy/laser/bluetag)) - . += 2 - -/obj/machinery/porta_turret/lasertag/setup(obj/item/gun/gun) - var/list/properties = ..() - if(properties["team_color"]) - team_color = properties["team_color"] - -/obj/machinery/porta_turret/lasertag/ui_interact(mob/user) - . = ..() - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(team_color == "blue" && istype(H.wear_suit, /obj/item/clothing/suit/redtag)) - return - if(team_color == "red" && istype(H.wear_suit, /obj/item/clothing/suit/bluetag)) - return - - var/dat = "Status: [on ? "On" : "Off"]" - - var/datum/browser/popup = new(user, "autosec", "Automatic Portable Turret Installation", 300, 300) - popup.set_content(dat) - popup.open() - -//lasertag presets -/obj/machinery/porta_turret/lasertag/red - installation = /obj/item/gun/energy/laser/redtag - team_color = "red" - -/obj/machinery/porta_turret/lasertag/blue - installation = /obj/item/gun/energy/laser/bluetag - team_color = "blue" - -/obj/machinery/porta_turret/lasertag/bullet_act(obj/item/projectile/P) - . = ..() - if(on) - if(team_color == "blue") - if(istype(P, /obj/item/projectile/beam/lasertag/redtag)) - on = FALSE - spawn(100) - on = TRUE - else if(team_color == "red") - if(istype(P, /obj/item/projectile/beam/lasertag/bluetag)) - on = FALSE - spawn(100) - on = TRUE +#define TURRET_STUN 0 +#define TURRET_LETHAL 1 + +#define POPUP_ANIM_TIME 5 +#define POPDOWN_ANIM_TIME 5 //Be sure to change the icon animation at the same time or it'll look bad + +/obj/machinery/porta_turret + name = "turret" + icon = 'icons/obj/turrets.dmi' + icon_state = "turretCover" + layer = OBJ_LAYER + invisibility = INVISIBILITY_OBSERVER //the turret is invisible if it's inside its cover + density = TRUE + desc = "A covered turret that shoots at its enemies." + use_power = IDLE_POWER_USE //this turret uses and requires power + idle_power_usage = 50 //when inactive, this turret takes up constant 50 Equipment power + active_power_usage = 300 //when active, this turret takes up constant 300 Equipment power + req_access = list(ACCESS_SEC_DOORS) + power_channel = EQUIP //drains power from the EQUIPMENT channel + + var/base_icon_state = "standard" + var/scan_range = 7 + var/atom/base = null //for turrets inside other objects + + var/raised = 0 //if the turret cover is "open" and the turret is raised + var/raising= 0 //if the turret is currently opening or closing its cover + + max_integrity = 160 //the turret's health + integrity_failure = 80 + armor = list("melee" = 50, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + + var/locked = TRUE //if the turret's behaviour control access is locked + var/controllock = FALSE //if the turret responds to control panels + + var/installation = /obj/item/gun/energy/e_gun/turret //the type of weapon installed by default + var/obj/item/gun/stored_gun = null + var/gun_charge = 0 //the charge of the gun when retrieved from wreckage + + var/mode = TURRET_STUN + + var/stun_projectile = null //stun mode projectile type + var/stun_projectile_sound + var/nonlethal_projectile //projectile to use in stun mode when the target is resting, if any + var/nonlethal_projectile_sound + var/lethal_projectile = null //lethal mode projectile type + var/lethal_projectile_sound + + var/reqpower = 500 //power needed per shot + var/always_up = 0 //Will stay active + var/has_cover = 1 //Hides the cover + + var/obj/machinery/porta_turret_cover/cover = null //the cover that is covering this turret + + var/last_fired = 0 //world.time the turret last fired + var/shot_delay = 15 //ticks until next shot (1.5 ?) + + + var/check_records = 1 //checks if it can use the security records + var/criminals = 1 //checks if it can shoot people on arrest + var/auth_weapons = 0 //checks if it can shoot people that have a weapon they aren't authorized to have + var/stun_all = 0 //if this is active, the turret shoots everything that isn't security or head of staff + var/check_anomalies = 1 //checks if it can shoot at unidentified lifeforms (ie xenos) + var/shoot_unloyal = 0 //checks if it can shoot people that aren't loyalty implantd + + var/attacked = 0 //if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!) + + var/on = TRUE //determines if the turret is on + + var/list/faction = list("turret") // Same faction mobs will never be shot at, no matter the other settings + + var/datum/effect_system/spark_spread/spark_system //the spark system, used for generating... sparks? + + var/obj/machinery/turretid/cp = null + + var/wall_turret_direction //The turret will try to shoot from a turf in that direction when in a wall + + var/manual_control = FALSE // + var/datum/action/turret_quit/quit_action + var/datum/action/turret_toggle/toggle_action + var/mob/remote_controller + +/obj/machinery/porta_turret/Initialize() + . = ..() + if(!base) + base = src + update_icon() + //Sets up a spark system + spark_system = new /datum/effect_system/spark_spread + spark_system.set_up(5, 0, src) + spark_system.attach(src) + + setup() + if(has_cover) + cover = new /obj/machinery/porta_turret_cover(loc) + cover.parent_turret = src + var/mutable_appearance/base = mutable_appearance('icons/obj/turrets.dmi', "basedark") + base.layer = NOT_HIGH_OBJ_LAYER + underlays += base + if(!has_cover) + INVOKE_ASYNC(src, .proc/popUp) + +/obj/machinery/porta_turret/update_icon() + cut_overlays() + if(!anchored) + icon_state = "turretCover" + return + if(stat & BROKEN) + icon_state = "[base_icon_state]_broken" + else + if(powered()) + if(on && raised) + switch(mode) + if(TURRET_STUN) + icon_state = "[base_icon_state]_stun" + if(TURRET_LETHAL) + icon_state = "[base_icon_state]_lethal" + else + icon_state = "[base_icon_state]_off" + else + icon_state = "[base_icon_state]_unpowered" + + +/obj/machinery/porta_turret/proc/setup(obj/item/gun/turret_gun) + if(stored_gun) + qdel(stored_gun) + stored_gun = null + + if(installation && !turret_gun) + stored_gun = new installation(src) + else if (turret_gun) + stored_gun = turret_gun + + var/list/gun_properties = stored_gun.get_turret_properties() + + //required properties + stun_projectile = gun_properties["stun_projectile"] + stun_projectile_sound = gun_properties["stun_projectile_sound"] + lethal_projectile = gun_properties["lethal_projectile"] + lethal_projectile_sound = gun_properties["lethal_projectile_sound"] + base_icon_state = gun_properties["base_icon_state"] + + //optional properties + if(gun_properties["shot_delay"]) + shot_delay = gun_properties["shot_delay"] + if(gun_properties["reqpower"]) + reqpower = gun_properties["reqpower"] + + update_icon() + return gun_properties + +/obj/machinery/porta_turret/Destroy() + //deletes its own cover with it + QDEL_NULL(cover) + base = null + if(cp) + cp.turrets -= src + cp = null + QDEL_NULL(stored_gun) + QDEL_NULL(spark_system) + remove_control() + return ..() + +/obj/machinery/porta_turret/ui_interact(mob/user) + . = ..() + var/dat + dat += "Status: [on ? "On" : "Off"]
" + dat += "Behaviour controls are [locked ? "locked" : "unlocked"]
" + + if(!locked) + dat += "Check for Weapon Authorization: [auth_weapons ? "Yes" : "No"]
" + dat += "Check Security Records: [check_records ? "Yes" : "No"]
" + dat += "Neutralize Identified Criminals: [criminals ? "Yes" : "No"]
" + dat += "Neutralize All Non-Security and Non-Command Personnel: [stun_all ? "Yes" : "No"]
" + dat += "Neutralize All Unidentified Life Signs: [check_anomalies ? "Yes" : "No"]
" + dat += "Neutralize All Non-Loyalty Implanted Personnel: [shoot_unloyal ? "Yes" : "No"]
" + if(issilicon(user)) + if(!manual_control) + var/mob/living/silicon/S = user + if(S.hack_software) + dat += "Assume direct control : Manual Control
" + else + dat += "Warning! Remote control protocol enabled.
" + + + var/datum/browser/popup = new(user, "autosec", "Automatic Portable Turret Installation", 300, 300) + popup.set_content(dat) + popup.open() + +/obj/machinery/porta_turret/Topic(href, href_list) + if(..()) + return + usr.set_machine(src) + add_fingerprint(usr) + + if(href_list["power"] && !locked) + if(anchored) //you can't turn a turret on/off if it's not anchored/secured + on = !on //toggle on/off + else + to_chat(usr, "It has to be secured first!") + interact(usr) + return + + if(href_list["operation"]) + switch(href_list["operation"]) //toggles customizable behavioural protocols + if("authweapon") + auth_weapons = !auth_weapons + if("checkrecords") + check_records = !check_records + if("shootcrooks") + criminals = !criminals + if("shootall") + stun_all = !stun_all + if("checkxenos") + check_anomalies = !check_anomalies + if("checkloyal") + shoot_unloyal = !shoot_unloyal + if("manual") + if(issilicon(usr) && !manual_control) + give_control(usr) + interact(usr) + +/obj/machinery/porta_turret/power_change() + if(!anchored) + update_icon() + remove_control() + return + if(stat & BROKEN) + update_icon() + remove_control() + else + if( powered() ) + stat &= ~NOPOWER + update_icon() + else + spawn(rand(0, 15)) + stat |= NOPOWER + remove_control() + update_icon() + + +/obj/machinery/porta_turret/attackby(obj/item/I, mob/user, params) + if(stat & BROKEN) + if(istype(I, /obj/item/crowbar)) + //If the turret is destroyed, you can remove it with a crowbar to + //try and salvage its components + to_chat(user, "You begin prying the metal coverings off...") + if(I.use_tool(src, user, 20)) + if(prob(70)) + if(stored_gun) + stored_gun.forceMove(loc) + to_chat(user, "You remove the turret and salvage some components.") + if(prob(50)) + new /obj/item/stack/sheet/metal(loc, rand(1,4)) + if(prob(50)) + new /obj/item/assembly/prox_sensor(loc) + else + to_chat(user, "You remove the turret but did not manage to salvage anything.") + qdel(src) + + else if((istype(I, /obj/item/wrench)) && (!on)) + if(raised) + return + + //This code handles moving the turret around. After all, it's a portable turret! + if(!anchored && !isinspace()) + setAnchored(TRUE) + invisibility = INVISIBILITY_MAXIMUM + update_icon() + to_chat(user, "You secure the exterior bolts on the turret.") + if(has_cover) + cover = new /obj/machinery/porta_turret_cover(loc) //create a new turret. While this is handled in process(), this is to workaround a bug where the turret becomes invisible for a split second + cover.parent_turret = src //make the cover's parent src + else if(anchored) + setAnchored(FALSE) + to_chat(user, "You unsecure the exterior bolts on the turret.") + power_change() + invisibility = 0 + qdel(cover) //deletes the cover, and the turret instance itself becomes its own cover. + + else if(I.GetID()) + //Behavior lock/unlock mangement + if(allowed(user)) + locked = !locked + to_chat(user, "Controls are now [locked ? "locked" : "unlocked"].") + else + to_chat(user, "Access denied.") + else if(istype(I, /obj/item/multitool) && !locked) + var/obj/item/multitool/M = I + M.buffer = src + to_chat(user, "You add [src] to multitool buffer.") + else + return ..() + +/obj/machinery/porta_turret/emag_act(mob/user) + if(obj_flags & EMAGGED) + return + to_chat(user, "You short out [src]'s threat assessment circuits.") + visible_message("[src] hums oddly...") + obj_flags |= EMAGGED + controllock = TRUE + on = FALSE //turns off the turret temporarily + update_icon() + sleep(60) //6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit + on = TRUE //turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here + + +/obj/machinery/porta_turret/emp_act(severity) + . = ..() + if (. & EMP_PROTECT_SELF) + return + if(on) + //if the turret is on, the EMP no matter how severe disables the turret for a while + //and scrambles its settings, with a slight chance of having an emag effect + check_records = pick(0, 1) + criminals = pick(0, 1) + auth_weapons = pick(0, 1) + stun_all = pick(0, 0, 0, 0, 1) //stun_all is a pretty big deal, so it's least likely to get turned on + + on = FALSE + remove_control() + + spawn(rand(60,600)) + if(!on) + on = TRUE + +/obj/machinery/porta_turret/take_damage(damage, damage_type = BRUTE, damage_flag = 0, sound_effect = 1) + . = ..() + if(.) //damage received + if(prob(30)) + spark_system.start() + if(on && !attacked && !(obj_flags & EMAGGED)) + attacked = TRUE + addtimer(CALLBACK(src, .proc/reset_attacked), 60) + +/obj/machinery/porta_turret/proc/reset_attacked() + attacked = FALSE + +/obj/machinery/porta_turret/deconstruct(disassembled = TRUE) + qdel(src) + +/obj/machinery/porta_turret/obj_break(damage_flag) + if(!(flags_1 & NODECONSTRUCT_1) && !(stat & BROKEN)) + stat |= BROKEN //enables the BROKEN bit + power_change() + invisibility = 0 + spark_system.start() //creates some sparks because they look cool + qdel(cover) //deletes the cover - no need on keeping it there! + + + +/obj/machinery/porta_turret/process() + //the main machinery process + if(cover == null && anchored) //if it has no cover and is anchored + if(stat & BROKEN) //if the turret is borked + qdel(cover) //delete its cover, assuming it has one. Workaround for a pesky little bug + else + if(has_cover) + cover = new /obj/machinery/porta_turret_cover(loc) //if the turret has no cover and is anchored, give it a cover + cover.parent_turret = src //assign the cover its parent_turret, which would be this (src) + + if(!on || (stat & (NOPOWER|BROKEN)) || manual_control) + return + + var/list/targets = list() + for(var/mob/A in view(scan_range, base)) + if(A.invisibility > SEE_INVISIBLE_LIVING) + continue + + if(check_anomalies)//if it's set to check for simple animals + if(isanimal(A)) + var/mob/living/simple_animal/SA = A + if(SA.stat || in_faction(SA) || istype(SA, /mob/living/simple_animal/hostile/megafauna)) //don't target if dead or in faction + continue + targets += SA + if(issilicon(A)) + var/mob/living/silicon/sillycone = A + if(sillycone.stat || in_faction(sillycone)) + continue + + if(iscyborg(sillycone)) + var/mob/living/silicon/robot/sillyconerobot = A + if(LAZYLEN(faction) && (ROLE_SYNDICATE in faction) && sillyconerobot.emagged == TRUE) + continue + + targets += sillycone + + if(iscarbon(A)) + var/mob/living/carbon/C = A + //If not emagged, only target non downed carbons + if(mode != TURRET_LETHAL && (C.stat || C.handcuffed || C.recoveringstam))//CIT CHANGE - replaces check for lying with check for recoveringstam + continue + + //If emagged, target all but dead carbons + if(mode == TURRET_LETHAL && C.stat == DEAD) + continue + + //if the target is a human and not in our faction, analyze threat level + if(ishuman(C) && !in_faction(C)) + if(assess_perp(C) >= 4) + targets += C + + else if(check_anomalies) //non humans who are not simple animals (xenos etc) + if(!in_faction(C)) + targets += C + for(var/A in GLOB.mechas_list) + if((get_dist(A, base) < scan_range) && can_see(base, A, scan_range)) + var/obj/mecha/Mech = A + if(Mech.occupant && !in_faction(Mech.occupant)) //If there is a user and they're not in our faction + if(assess_perp(Mech.occupant) >= 4) + targets += Mech + + if(targets.len) + tryToShootAt(targets) + else if(!always_up) + popDown() // no valid targets, close the cover + +/obj/machinery/porta_turret/proc/tryToShootAt(list/atom/movable/targets) + while(targets.len > 0) + var/atom/movable/M = pick(targets) + targets -= M + if(target(M)) + return 1 + + +/obj/machinery/porta_turret/proc/popUp() //pops the turret up + if(!anchored) + return + if(raising || raised) + return + if(stat & BROKEN) + return + invisibility = 0 + raising = 1 + if(cover) + flick("popup", cover) + sleep(POPUP_ANIM_TIME) + raising = 0 + if(cover) + cover.icon_state = "openTurretCover" + raised = 1 + layer = MOB_LAYER + +/obj/machinery/porta_turret/proc/popDown() //pops the turret down + if(raising || !raised) + return + if(stat & BROKEN) + return + layer = OBJ_LAYER + raising = 1 + if(cover) + flick("popdown", cover) + sleep(POPDOWN_ANIM_TIME) + raising = 0 + if(cover) + cover.icon_state = "turretCover" + raised = 0 + invisibility = 2 + update_icon() + +/obj/machinery/porta_turret/proc/assess_perp(mob/living/carbon/human/perp) + var/threatcount = 0 //the integer returned + + if(obj_flags & EMAGGED) + return 10 //if emagged, always return 10. + + if((stun_all || attacked) && !allowed(perp)) + //if the turret has been attacked or is angry, target all non-sec people + if(!allowed(perp)) + return 10 + + if(auth_weapons) //check for weapon authorization + if(isnull(perp.wear_id) || istype(perp.wear_id.GetID(), /obj/item/card/id/syndicate)) + + if(allowed(perp)) //if the perp has security access, return 0 + return 0 + + if(perp.is_holding_item_of_type(/obj/item/gun) || perp.is_holding_item_of_type(/obj/item/melee/baton)) + threatcount += 4 + + if(istype(perp.belt, /obj/item/gun) || istype(perp.belt, /obj/item/melee/baton)) + threatcount += 2 + + if(check_records) //if the turret can check the records, check if they are set to *Arrest* on records + var/perpname = perp.get_face_name(perp.get_id_name()) + var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.security) + if(!R || (R.fields["criminal"] == "*Arrest*")) + threatcount += 4 + + if(shoot_unloyal) + if (!HAS_TRAIT(perp, TRAIT_MINDSHIELD)) + threatcount += 4 + + return threatcount + + +/obj/machinery/porta_turret/proc/in_faction(mob/target) + for(var/faction1 in faction) + if(faction1 in target.faction) + return TRUE + return FALSE + +/obj/machinery/porta_turret/proc/target(atom/movable/target) + if(target) + popUp() //pop the turret up if it's not already up. + setDir(get_dir(base, target))//even if you can't shoot, follow the target + shootAt(target) + return 1 + return + +/obj/machinery/porta_turret/proc/shootAt(atom/movable/target) + if(!raised) //the turret has to be raised in order to fire - makes sense, right? + return + + if(!(obj_flags & EMAGGED)) //if it hasn't been emagged, cooldown before shooting again + if(last_fired + shot_delay > world.time) + return + last_fired = world.time + + var/turf/T = get_turf(src) + var/turf/U = get_turf(target) + if(!istype(T) || !istype(U)) + return + + //Wall turrets will try to find adjacent empty turf to shoot from to cover full arc + if(T.density) + if(wall_turret_direction) + var/turf/closer = get_step(T,wall_turret_direction) + if(istype(closer) && !is_blocked_turf(closer) && T.Adjacent(closer)) + T = closer + else + var/target_dir = get_dir(T,target) + for(var/d in list(0,-45,45)) + var/turf/closer = get_step(T,turn(target_dir,d)) + if(istype(closer) && !is_blocked_turf(closer) && T.Adjacent(closer)) + T = closer + break + + var/mob/living/carbon/C + if(iscarbon(target)) + C = target + update_icon() + var/obj/item/projectile/A + //any emagged turrets drains 2x power and uses a different projectile? + if(mode == TURRET_STUN) + if(nonlethal_projectile && C && C.resting) + use_power(reqpower*0.5) + A = new nonlethal_projectile(T) + playsound(loc, nonlethal_projectile_sound, 75, 1) + else + use_power(reqpower) + A = new stun_projectile(T) + playsound(loc, stun_projectile_sound, 75, 1) + else + use_power(reqpower * 2) + A = new lethal_projectile(T) + playsound(loc, lethal_projectile_sound, 75, 1) + + + //Shooting Code: + A.preparePixelProjectile(target, T) + A.firer = src + A.fire() + return A + +/obj/machinery/porta_turret/proc/setState(on, mode) + if(controllock) + return + src.on = on + if(!on) + popDown() + src.mode = mode + power_change() + + +/datum/action/turret_toggle + name = "Toggle Mode" + icon_icon = 'icons/mob/actions/actions_mecha.dmi' + button_icon_state = "mech_cycle_equip_off" + +/datum/action/turret_toggle/Trigger() + var/obj/machinery/porta_turret/P = target + if(!istype(P)) + return + P.setState(P.on,!P.mode) + +/datum/action/turret_quit + name = "Release Control" + icon_icon = 'icons/mob/actions/actions_mecha.dmi' + button_icon_state = "mech_eject" + +/datum/action/turret_quit/Trigger() + var/obj/machinery/porta_turret/P = target + if(!istype(P)) + return + P.remove_control(FALSE) + +/obj/machinery/porta_turret/proc/give_control(mob/A) + if(manual_control || !can_interact(A)) + return FALSE + remote_controller = A + if(!quit_action) + quit_action = new(src) + quit_action.Grant(remote_controller) + if(!toggle_action) + toggle_action = new(src) + toggle_action.Grant(remote_controller) + remote_controller.reset_perspective(src) + remote_controller.click_intercept = src + manual_control = TRUE + always_up = TRUE + popUp() + return TRUE + +/obj/machinery/porta_turret/proc/remove_control(warning_message = TRUE) + if(!manual_control) + return FALSE + if(remote_controller) + if(warning_message) + to_chat(remote_controller, "Your uplink to [src] has been severed!") + quit_action.Remove(remote_controller) + toggle_action.Remove(remote_controller) + remote_controller.click_intercept = null + remote_controller.reset_perspective() + always_up = initial(always_up) + manual_control = FALSE + remote_controller = null + return TRUE + +/obj/machinery/porta_turret/proc/InterceptClickOn(mob/living/caller, params, atom/A) + if(!manual_control) + return FALSE + if(!can_interact(caller)) + remove_control() + return FALSE + log_combat(caller,A,"fired with manual turret control at") + target(A) + return TRUE + +/obj/machinery/porta_turret/syndicate + installation = null + always_up = 1 + use_power = NO_POWER_USE + has_cover = 0 + scan_range = 9 + req_access = list(ACCESS_SYNDICATE) + mode = TURRET_LETHAL + stun_projectile = /obj/item/projectile/bullet + lethal_projectile = /obj/item/projectile/bullet + lethal_projectile_sound = 'sound/weapons/gunshot.ogg' + stun_projectile_sound = 'sound/weapons/gunshot.ogg' + icon_state = "syndie_off" + base_icon_state = "syndie" + faction = list(ROLE_SYNDICATE) + desc = "A ballistic machine gun auto-turret." + +/obj/machinery/porta_turret/syndicate/ComponentInitialize() + . = ..() + AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) + +/obj/machinery/porta_turret/syndicate/energy + icon_state = "standard_stun" + base_icon_state = "standard" + stun_projectile = /obj/item/projectile/energy/electrode + stun_projectile_sound = 'sound/weapons/taser.ogg' + nonlethal_projectile = /obj/item/projectile/beam/disabler + nonlethal_projectile_sound = 'sound/weapons/taser2.ogg' + lethal_projectile = /obj/item/projectile/beam/laser + lethal_projectile_sound = 'sound/weapons/laser.ogg' + desc = "An energy blaster auto-turret." + +/obj/machinery/porta_turret/syndicate/energy/heavy + icon_state = "standard_stun" + base_icon_state = "standard" + stun_projectile = /obj/item/projectile/energy/electrode + stun_projectile_sound = 'sound/weapons/taser.ogg' + nonlethal_projectile = /obj/item/projectile/beam/disabler + nonlethal_projectile_sound = 'sound/weapons/taser2.ogg' + lethal_projectile = /obj/item/projectile/beam/laser/heavylaser + lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg' + desc = "An energy blaster auto-turret." + + +/obj/machinery/porta_turret/syndicate/setup() + return + +/obj/machinery/porta_turret/syndicate/assess_perp(mob/living/carbon/human/perp) + return 10 //Syndicate turrets shoot everything not in their faction + +/obj/machinery/porta_turret/syndicate/pod + integrity_failure = 20 + max_integrity = 40 + stun_projectile = /obj/item/projectile/bullet/syndicate_turret + lethal_projectile = /obj/item/projectile/bullet/syndicate_turret + +/obj/machinery/porta_turret/syndicate/shuttle + scan_range = 9 + shot_delay = 3 + stun_projectile = /obj/item/projectile/bullet/p50/penetrator/shuttle + lethal_projectile = /obj/item/projectile/bullet/p50/penetrator/shuttle + lethal_projectile_sound = 'sound/weapons/gunshot_smg.ogg' + stun_projectile_sound = 'sound/weapons/gunshot_smg.ogg' + armor = list("melee" = 50, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 80, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + +/obj/machinery/porta_turret/syndicate/shuttle/target(atom/movable/target) + if(target) + setDir(get_dir(base, target))//even if you can't shoot, follow the target + shootAt(target) + addtimer(CALLBACK(src, .proc/shootAt, target), 5) + addtimer(CALLBACK(src, .proc/shootAt, target), 10) + addtimer(CALLBACK(src, .proc/shootAt, target), 15) + return TRUE + +/obj/machinery/porta_turret/ai + faction = list("silicon") + nonlethal_projectile = /obj/item/projectile/beam/disabler + nonlethal_projectile_sound = 'sound/weapons/taser2.ogg' + +/obj/machinery/porta_turret/ai/assess_perp(mob/living/carbon/human/perp) + return 10 //AI turrets shoot at everything not in their faction + +/obj/machinery/porta_turret/aux_base + name = "perimeter defense turret" + desc = "A plasma beam turret calibrated to defend outposts against non-humanoid fauna. It is more effective when exposed to the environment." + installation = null + lethal_projectile = /obj/item/projectile/plasma/turret + lethal_projectile_sound = 'sound/weapons/plasma_cutter.ogg' + mode = TURRET_LETHAL //It would be useless in stun mode anyway + faction = list("neutral","silicon","turret") //Minebots, medibots, etc that should not be shot. + +/obj/machinery/porta_turret/aux_base/assess_perp(mob/living/carbon/human/perp) + return 0 //Never shoot humanoids. You are on your own if Ashwalkers or the like attack! + +/obj/machinery/porta_turret/aux_base/setup() + return + +/obj/machinery/porta_turret/aux_base/interact(mob/user) //Controlled solely from the base console. + return + +/obj/machinery/porta_turret/aux_base/Initialize() + . = ..() + cover.name = name + cover.desc = desc + +/obj/machinery/porta_turret/centcom_shuttle + installation = null + max_integrity = 260 + always_up = 1 + use_power = NO_POWER_USE + has_cover = 0 + scan_range = 9 + stun_projectile = /obj/item/projectile/beam/laser + lethal_projectile = /obj/item/projectile/beam/laser + lethal_projectile_sound = 'sound/weapons/plasma_cutter.ogg' + stun_projectile_sound = 'sound/weapons/plasma_cutter.ogg' + icon_state = "syndie_off" + base_icon_state = "syndie" + faction = list("neutral","silicon","turret") + mode = TURRET_LETHAL + +/obj/machinery/porta_turret/centcom_shuttle/ComponentInitialize() + . = ..() + AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) + +/obj/machinery/porta_turret/centcom_shuttle/assess_perp(mob/living/carbon/human/perp) + return 0 + +/obj/machinery/porta_turret/centcom_shuttle/setup() + return + +/obj/machinery/porta_turret/centcom_shuttle/weak + max_integrity = 120 + integrity_failure = 60 + name = "Old Laser Turret" + desc = "A turret built with substandard parts and run down further with age. Still capable of delivering lethal lasers to the odd space carp, but not much else." + stun_projectile = /obj/item/projectile/beam/weak/penetrator + lethal_projectile = /obj/item/projectile/beam/weak/penetrator + faction = list("neutral","silicon","turret") + +/obj/machinery/porta_turret/centcom_shuttle/ballistic + stun_projectile = /obj/item/projectile/bullet + lethal_projectile = /obj/item/projectile/bullet + lethal_projectile_sound = 'sound/weapons/gunshot.ogg' + stun_projectile_sound = 'sound/weapons/gunshot.ogg' + desc = "A ballistic machine gun auto-turret." + + +//////////////////////// +//Turret Control Panel// +//////////////////////// + +/obj/machinery/turretid + name = "turret control panel" + desc = "Used to control a room's automated defenses." + icon = 'icons/obj/machines/turret_control.dmi' + icon_state = "control_standby" + density = FALSE + var/enabled = 1 + var/lethal = 0 + var/locked = TRUE + var/control_area = null //can be area name, path or nothing. + var/ailock = 0 // AI cannot use this + req_access = list(ACCESS_AI_UPLOAD) + var/list/obj/machinery/porta_turret/turrets = list() + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + +/obj/machinery/turretid/Initialize(mapload, ndir = 0, built = 0) + . = ..() + if(built) + setDir(ndir) + locked = FALSE + pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) + pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0 + power_change() //Checks power and initial settings + +/obj/machinery/turretid/Destroy() + turrets.Cut() + return ..() + +/obj/machinery/turretid/Initialize(mapload) //map-placed turrets autolink turrets + . = ..() + if(!mapload) + return + + if(control_area) + control_area = get_area_instance_from_text(control_area) + if(control_area == null) + control_area = get_area(src) + stack_trace("Bad control_area path for [src], [src.control_area]") + else if(!control_area) + control_area = get_area(src) + + for(var/obj/machinery/porta_turret/T in control_area) + turrets |= T + T.cp = src + +/obj/machinery/turretid/examine(mob/user) + . = ..() + if(issilicon(user) && (!stat & BROKEN)) + . += "Ctrl-click [src] to [ enabled ? "disable" : "enable"] turrets." + . += "Alt-click [src] to set turrets to [ lethal ? "stun" : "kill"]." + +/obj/machinery/turretid/attackby(obj/item/I, mob/user, params) + if(stat & BROKEN) + return + + if (istype(I, /obj/item/multitool)) + var/obj/item/multitool/M = I + if(M.buffer && istype(M.buffer, /obj/machinery/porta_turret)) + turrets |= M.buffer + to_chat(user, "You link \the [M.buffer] with \the [src]") + return + + if (issilicon(user)) + return attack_hand(user) + + if ( get_dist(src, user) == 0 ) // trying to unlock the interface + if (allowed(usr)) + if(obj_flags & EMAGGED) + to_chat(user, "The turret control is unresponsive.") + return + + locked = !locked + to_chat(user, "You [ locked ? "lock" : "unlock"] the panel.") + if (locked) + if (user.machine==src) + user.unset_machine() + user << browse(null, "window=turretid") + else + if (user.machine==src) + attack_hand(user) + else + to_chat(user, "Access denied.") + +/obj/machinery/turretid/emag_act(mob/user) + if(obj_flags & EMAGGED) + return + to_chat(user, "You short out the turret controls' access analysis module.") + obj_flags |= EMAGGED + locked = FALSE + if(user && user.machine == src) + attack_hand(user) + +/obj/machinery/turretid/attack_ai(mob/user) + if(!ailock || IsAdminGhost(user)) + return attack_hand(user) + else + to_chat(user, "There seems to be a firewall preventing you from accessing this device.") + +/obj/machinery/turretid/ui_interact(mob/user) + . = ..() + if ( get_dist(src, user) > 0 ) + if ( !(issilicon(user) || IsAdminGhost(user)) ) + to_chat(user, "You are too far away.") + user.unset_machine() + user << browse(null, "window=turretid") + return + + var/t = "" + + if(locked && !(issilicon(user) || IsAdminGhost(user))) + t += "
Swipe ID card to unlock interface
" + else + if(!issilicon(user) && !IsAdminGhost(user)) + t += "
Swipe ID card to lock interface
" + t += "Turrets [enabled?"activated":"deactivated"] - [enabled?"Disable":"Enable"]?
" + t += "Currently set for [lethal?"lethal":"stun repeatedly"] - Change to [lethal?"Stun repeatedly":"Lethal"]?
" + + var/datum/browser/popup = new(user, "turretid", "Turret Control Panel ([get_area_name(src, TRUE)])") + popup.set_content(t) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + +/obj/machinery/turretid/Topic(href, href_list) + if(..()) + return + if (locked) + if(!(issilicon(usr) || IsAdminGhost(usr))) + to_chat(usr, "Control panel is locked!") + return + if (href_list["toggleOn"]) + toggle_on() + else if (href_list["toggleLethal"]) + toggle_lethal() + attack_hand(usr) + +/obj/machinery/turretid/proc/toggle_lethal() + lethal = !lethal + updateTurrets() + +/obj/machinery/turretid/proc/toggle_on() + enabled = !enabled + updateTurrets() + +/obj/machinery/turretid/proc/updateTurrets() + for (var/obj/machinery/porta_turret/aTurret in turrets) + aTurret.setState(enabled, lethal) + update_icon() + +/obj/machinery/turretid/power_change() + ..() + update_icon() + +/obj/machinery/turretid/update_icon() + ..() + if(stat & NOPOWER) + icon_state = "control_off" + else if (enabled) + if (lethal) + icon_state = "control_kill" + else + icon_state = "control_stun" + else + icon_state = "control_standby" + +/obj/item/wallframe/turret_control + name = "turret control frame" + desc = "Used for building turret control panels." + icon_state = "apc" + result_path = /obj/machinery/turretid + materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT) + +/obj/item/gun/proc/get_turret_properties() + . = list() + .["lethal_projectile"] = null + .["lethal_projectile_sound"] = null + .["stun_projectile"] = null + .["stun_projectile_sound"] = null + .["base_icon_state"] = "standard" + +/obj/item/gun/energy/get_turret_properties() + . = ..() + + var/obj/item/ammo_casing/primary_ammo = ammo_type[1] + + .["stun_projectile"] = initial(primary_ammo.projectile_type) + .["stun_projectile_sound"] = initial(primary_ammo.fire_sound) + + if(ammo_type.len > 1) + var/obj/item/ammo_casing/secondary_ammo = ammo_type[2] + .["lethal_projectile"] = initial(secondary_ammo.projectile_type) + .["lethal_projectile_sound"] = initial(secondary_ammo.fire_sound) + else + .["lethal_projectile"] = .["stun_projectile"] + .["lethal_projectile_sound"] = .["stun_projectile_sound"] + +/obj/item/gun/ballistic/get_turret_properties() + . = ..() + var/obj/item/ammo_box/mag = mag_type + var/obj/item/ammo_casing/primary_ammo = initial(mag.ammo_type) + + .["base_icon_state"] = "syndie" + .["stun_projectile"] = initial(primary_ammo.projectile_type) + .["stun_projectile_sound"] = initial(primary_ammo.fire_sound) + .["lethal_projectile"] = .["stun_projectile"] + .["lethal_projectile_sound"] = .["stun_projectile_sound"] + + +/obj/item/gun/energy/laser/bluetag/get_turret_properties() + . = ..() + .["stun_projectile"] = /obj/item/projectile/beam/lasertag/bluetag + .["lethal_projectile"] = /obj/item/projectile/beam/lasertag/bluetag + .["base_icon_state"] = "blue" + .["shot_delay"] = 30 + .["team_color"] = "blue" + +/obj/item/gun/energy/laser/redtag/get_turret_properties() + . = ..() + .["stun_projectile"] = /obj/item/projectile/beam/lasertag/redtag + .["lethal_projectile"] = /obj/item/projectile/beam/lasertag/redtag + .["base_icon_state"] = "red" + .["shot_delay"] = 30 + .["team_color"] = "red" + +/obj/item/gun/energy/e_gun/turret/get_turret_properties() + . = ..() + +/obj/machinery/porta_turret/lasertag + req_access = list(ACCESS_MAINT_TUNNELS, ACCESS_THEATRE) + check_records = 0 + criminals = 0 + auth_weapons = 1 + stun_all = 0 + check_anomalies = 0 + var/team_color + +/obj/machinery/porta_turret/lasertag/assess_perp(mob/living/carbon/human/perp) + . = 0 + if(team_color == "blue") //Lasertag turrets target the opposing team, how great is that? -Sieve + . = 0 //But does not target anyone else + if(istype(perp.wear_suit, /obj/item/clothing/suit/redtag)) + . += 4 + if(perp.is_holding_item_of_type(/obj/item/gun/energy/laser/redtag)) + . += 4 + if(istype(perp.belt, /obj/item/gun/energy/laser/redtag)) + . += 2 + + if(team_color == "red") + . = 0 + if(istype(perp.wear_suit, /obj/item/clothing/suit/bluetag)) + . += 4 + if(perp.is_holding_item_of_type(/obj/item/gun/energy/laser/bluetag)) + . += 4 + if(istype(perp.belt, /obj/item/gun/energy/laser/bluetag)) + . += 2 + +/obj/machinery/porta_turret/lasertag/setup(obj/item/gun/gun) + var/list/properties = ..() + if(properties["team_color"]) + team_color = properties["team_color"] + +/obj/machinery/porta_turret/lasertag/ui_interact(mob/user) + . = ..() + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(team_color == "blue" && istype(H.wear_suit, /obj/item/clothing/suit/redtag)) + return + if(team_color == "red" && istype(H.wear_suit, /obj/item/clothing/suit/bluetag)) + return + + var/dat = "Status: [on ? "On" : "Off"]" + + var/datum/browser/popup = new(user, "autosec", "Automatic Portable Turret Installation", 300, 300) + popup.set_content(dat) + popup.open() + +//lasertag presets +/obj/machinery/porta_turret/lasertag/red + installation = /obj/item/gun/energy/laser/redtag + team_color = "red" + +/obj/machinery/porta_turret/lasertag/blue + installation = /obj/item/gun/energy/laser/bluetag + team_color = "blue" + +/obj/machinery/porta_turret/lasertag/bullet_act(obj/item/projectile/P) + . = ..() + if(on) + if(team_color == "blue") + if(istype(P, /obj/item/projectile/beam/lasertag/redtag)) + on = FALSE + spawn(100) + on = TRUE + else if(team_color == "red") + if(istype(P, /obj/item/projectile/beam/lasertag/bluetag)) + on = FALSE + spawn(100) + on = TRUE diff --git a/code/game/turfs/simulated/wall/reinf_walls.dm b/code/game/turfs/simulated/wall/reinf_walls.dm index 1b2e9801..39d2d9c5 100644 --- a/code/game/turfs/simulated/wall/reinf_walls.dm +++ b/code/game/turfs/simulated/wall/reinf_walls.dm @@ -227,3 +227,29 @@ /turf/closed/wall/r_wall/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) if(the_rcd.canRturf) return ..() + +/turf/closed/wall/r_wall/syndicate + name = "hull" + desc = "The armored hull of an ominous looking ship." + icon = 'icons/turf/walls/plastitanium_wall.dmi' + icon_state = "map-shuttle" + explosion_block = 20 + sheet_type = /obj/item/stack/sheet/mineral/plastitanium + smooth = SMOOTH_MORE|SMOOTH_DIAGONAL + canSmoothWith = list(/turf/closed/wall/r_wall/syndicate, /turf/closed/wall/mineral/plastitanium, /obj/machinery/door/airlock/shuttle, /obj/machinery/door/airlock, /obj/structure/window/plastitanium, /obj/structure/shuttle/engine, /obj/structure/falsewall/plastitanium) + +/turf/closed/wall/r_wall/syndicate/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) + return FALSE + +/turf/closed/wall/r_wall/syndicate/nodiagonal + smooth = SMOOTH_MORE + icon_state = "map-shuttle_nd" + +/turf/closed/wall/r_wall/syndicate/nosmooth + icon = 'icons/turf/shuttle.dmi' + icon_state = "wall" + smooth = SMOOTH_FALSE + +/turf/closed/wall/r_wall/syndicate/overspace + icon_state = "map-overspace" + fixed_underlay = list("space"=1) diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index 479a6ffe..3c9807c5 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -343,10 +343,10 @@ /obj/machinery/nuclearbomb/proc/set_anchor() - if(!isinspace()) - anchored = !anchored - else + if(isinspace() && !anchored) to_chat(usr, "There is nothing to anchor to!") + else + anchored = !anchored /obj/machinery/nuclearbomb/proc/set_safety() safety = !safety diff --git a/code/modules/projectiles/projectile/bullets/sniper.dm b/code/modules/projectiles/projectile/bullets/sniper.dm index 27f8f3b2..3ffac780 100644 --- a/code/modules/projectiles/projectile/bullets/sniper.dm +++ b/code/modules/projectiles/projectile/bullets/sniper.dm @@ -1,40 +1,46 @@ -// .50 (Sniper) - -/obj/item/projectile/bullet/p50 - name =".50 bullet" - speed = 0.4 - damage = 70 - knockdown = 100 - dismemberment = 50 - armour_penetration = 50 - var/breakthings = TRUE - -/obj/item/projectile/bullet/p50/on_hit(atom/target, blocked = 0) - if(isobj(target) && (blocked != 100) && breakthings) - var/obj/O = target - O.take_damage(80, BRUTE, "bullet", FALSE) - return ..() - -/obj/item/projectile/bullet/p50/soporific - name =".50 soporific bullet" - armour_penetration = 0 - damage = 0 - dismemberment = 0 - knockdown = 0 - breakthings = FALSE - -/obj/item/projectile/bullet/p50/soporific/on_hit(atom/target, blocked = FALSE) - if((blocked != 100) && isliving(target)) - var/mob/living/L = target - L.Sleeping(400) - return ..() - -/obj/item/projectile/bullet/p50/penetrator - name =".50 penetrator bullet" - icon_state = "gauss" - name = "penetrator round" - damage = 60 - forcedodge = TRUE - dismemberment = 0 //It goes through you cleanly. - knockdown = 0 - breakthings = FALSE +// .50 (Sniper) + +/obj/item/projectile/bullet/p50 + name =".50 bullet" + speed = 0.4 + damage = 70 + knockdown = 100 + dismemberment = 50 + armour_penetration = 50 + var/breakthings = TRUE + +/obj/item/projectile/bullet/p50/on_hit(atom/target, blocked = 0) + if(isobj(target) && (blocked != 100) && breakthings) + var/obj/O = target + O.take_damage(80, BRUTE, "bullet", FALSE) + return ..() + +/obj/item/projectile/bullet/p50/soporific + name =".50 soporific bullet" + armour_penetration = 0 + damage = 0 + dismemberment = 0 + knockdown = 0 + breakthings = FALSE + +/obj/item/projectile/bullet/p50/soporific/on_hit(atom/target, blocked = FALSE) + if((blocked != 100) && isliving(target)) + var/mob/living/L = target + L.Sleeping(400) + return ..() + +/obj/item/projectile/bullet/p50/penetrator + name =".50 penetrator bullet" + icon_state = "gauss" + name = "penetrator round" + damage = 60 + forcedodge = TRUE + dismemberment = 0 //It goes through you cleanly. + knockdown = 0 + breakthings = FALSE + +/obj/item/projectile/bullet/p50/penetrator/shuttle //Nukeop Shuttle Variety + icon_state = "gaussstrong" + damage = 25 + speed = 0.3 + range = 16 diff --git a/code/modules/shuttle/syndicate.dm b/code/modules/shuttle/syndicate.dm index d2a59a70..bffce9e7 100644 --- a/code/modules/shuttle/syndicate.dm +++ b/code/modules/shuttle/syndicate.dm @@ -1,62 +1,67 @@ -#define SYNDICATE_CHALLENGE_TIMER 12000 //20 minutes - -/obj/machinery/computer/shuttle/syndicate - name = "syndicate shuttle terminal" - desc = "The terminal used to control the syndicate transport shuttle." - circuit = /obj/item/circuitboard/computer/syndicate_shuttle - icon_screen = "syndishuttle" - icon_keyboard = "syndie_key" - light_color = LIGHT_COLOR_RED - req_access = list(ACCESS_SYNDICATE) - shuttleId = "syndicate" - possible_destinations = "syndicate_away;syndicate_z5;syndicate_ne;syndicate_nw;syndicate_n;syndicate_se;syndicate_sw;syndicate_s;syndicate_custom" - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF - -/obj/machinery/computer/shuttle/syndicate/recall - name = "syndicate shuttle recall terminal" - desc = "Use this if your friends left you behind." - possible_destinations = "syndicate_away" - - -/obj/machinery/computer/shuttle/syndicate/Topic(href, href_list) - if(href_list["move"]) - var/obj/item/circuitboard/computer/syndicate_shuttle/board = circuit - if(board.challenge && world.time < SYNDICATE_CHALLENGE_TIMER) - to_chat(usr, "You've issued a combat challenge to the station! You've got to give them at least [DisplayTimeText(SYNDICATE_CHALLENGE_TIMER - world.time)] more to allow them to prepare.") - return 0 - board.moved = TRUE - ..() - -/obj/machinery/computer/shuttle/syndicate/drop_pod - name = "syndicate assault pod control" - desc = "Controls the drop pod's launch system." - icon = 'icons/obj/terminals.dmi' - icon_state = "dorm_available" - light_color = LIGHT_COLOR_BLUE - req_access = list(ACCESS_SYNDICATE) - shuttleId = "steel_rain" - possible_destinations = null - clockwork = TRUE //it'd look weird - -/obj/machinery/computer/shuttle/syndicate/drop_pod/Topic(href, href_list) - if(href_list["move"]) - if(!is_centcom_level(z)) - to_chat(usr, "Pods are one way!") - return 0 - ..() - -/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate - name = "syndicate shuttle navigation computer" - desc = "Used to designate a precise transit location for the syndicate shuttle." - icon_screen = "syndishuttle" - icon_keyboard = "syndie_key" - shuttleId = "syndicate" - lock_override = CAMERA_LOCK_STATION - shuttlePortId = "syndicate_custom" - jumpto_ports = list("syndicate_ne" = 1, "syndicate_nw" = 1, "syndicate_n" = 1, "syndicate_se" = 1, "syndicate_sw" = 1, "syndicate_s" = 1) - view_range = 13 - x_offset = -7 - y_offset = -1 - see_hidden = TRUE - +#define SYNDICATE_CHALLENGE_TIMER 12000 //20 minutes + +/obj/machinery/computer/shuttle/syndicate + name = "syndicate shuttle terminal" + desc = "The terminal used to control the syndicate transport shuttle." + circuit = /obj/item/circuitboard/computer/syndicate_shuttle + icon_screen = "syndishuttle" + icon_keyboard = "syndie_key" + light_color = LIGHT_COLOR_RED + req_access = list(ACCESS_SYNDICATE) + shuttleId = "syndicate" + possible_destinations = "syndicate_away;syndicate_z5;syndicate_ne;syndicate_nw;syndicate_n;syndicate_se;syndicate_sw;syndicate_s;syndicate_custom" + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + +/obj/machinery/computer/shuttle/syndicate/recall + name = "syndicate shuttle recall terminal" + desc = "Use this if your friends left you behind." + possible_destinations = "syndicate_away" + + +/obj/machinery/computer/shuttle/syndicate/Topic(href, href_list) + if(href_list["move"]) + var/obj/item/circuitboard/computer/syndicate_shuttle/board = circuit + if(board.challenge && world.time < SYNDICATE_CHALLENGE_TIMER) + to_chat(usr, "You've issued a combat challenge to the station! You've got to give them at least [DisplayTimeText(SYNDICATE_CHALLENGE_TIMER - world.time)] more to allow them to prepare.") + return 0 + board.moved = TRUE + ..() + +/obj/machinery/computer/shuttle/syndicate/allowed(mob/M) + if(issilicon(M) && !(ROLE_SYNDICATE in M.faction)) + return FALSE + return ..() + +/obj/machinery/computer/shuttle/syndicate/drop_pod + name = "syndicate assault pod control" + desc = "Controls the drop pod's launch system." + icon = 'icons/obj/terminals.dmi' + icon_state = "dorm_available" + light_color = LIGHT_COLOR_BLUE + req_access = list(ACCESS_SYNDICATE) + shuttleId = "steel_rain" + possible_destinations = null + clockwork = TRUE //it'd look weird + +/obj/machinery/computer/shuttle/syndicate/drop_pod/Topic(href, href_list) + if(href_list["move"]) + if(!is_centcom_level(z)) + to_chat(usr, "Pods are one way!") + return 0 + ..() + +/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate + name = "syndicate shuttle navigation computer" + desc = "Used to designate a precise transit location for the syndicate shuttle." + icon_screen = "syndishuttle" + icon_keyboard = "syndie_key" + shuttleId = "syndicate" + lock_override = CAMERA_LOCK_STATION + shuttlePortId = "syndicate_custom" + jumpto_ports = list("syndicate_ne" = 1, "syndicate_nw" = 1, "syndicate_n" = 1, "syndicate_se" = 1, "syndicate_sw" = 1, "syndicate_s" = 1) + view_range = 13 + x_offset = -7 + y_offset = -1 + see_hidden = TRUE + #undef SYNDICATE_CHALLENGE_TIMER \ No newline at end of file diff --git a/icons/turf/walls/plastitanium_wall.dmi b/icons/turf/walls/plastitanium_wall.dmi index 3cd7332b..01dfdd12 100644 Binary files a/icons/turf/walls/plastitanium_wall.dmi and b/icons/turf/walls/plastitanium_wall.dmi differ