Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into ninjasarecum
# Conflicts: # code/modules/ninja/suit/ninjaDrainAct.dm
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -30,3 +30,7 @@
|
||||
var/obj/machinery/camera/cam = X
|
||||
cam.lostTargetRef(WEAKREF(O))
|
||||
return
|
||||
|
||||
/area/ai_monitored/turret_protected/ai/Initialize()
|
||||
. = ..()
|
||||
src.area_flags |= ABDUCTOR_PROOF
|
||||
|
||||
+50
-52
@@ -13,6 +13,8 @@
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
invisibility = INVISIBILITY_LIGHTING
|
||||
|
||||
var/area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA
|
||||
|
||||
var/fire = null
|
||||
///Whether there is an atmos alarm in this area
|
||||
var/atmosalm = FALSE
|
||||
@@ -60,7 +62,7 @@
|
||||
|
||||
|
||||
///This datum, if set, allows terrain generation behavior to be ran on Initialize()
|
||||
// var/datum/map_generator/map_generator
|
||||
var/datum/map_generator/map_generator
|
||||
|
||||
///Used to decide what kind of reverb the area makes sound have
|
||||
var/sound_environment = SOUND_ENVIRONMENT_NONE
|
||||
@@ -70,12 +72,8 @@
|
||||
/// Set in New(); preserves the name set by the map maker, even if renamed by the Blueprints.
|
||||
var/map_name
|
||||
|
||||
/// If it's valid territory for gangs/cults to summon
|
||||
var/valid_territory = TRUE
|
||||
/// malf ais can hack this
|
||||
var/valid_malf_hack = TRUE
|
||||
/// if blobs can spawn there and if it counts towards their score.
|
||||
var/blob_allowed = TRUE
|
||||
/// whether servants can warp into this area from Reebe
|
||||
var/clockwork_warp_allowed = TRUE
|
||||
/// Message to display when the clockwork warp fails
|
||||
@@ -107,14 +105,10 @@
|
||||
var/static_light = 0
|
||||
var/static_environ
|
||||
|
||||
/// Are you forbidden from teleporting to the area? (centcom, mobs, wizard, hand teleporter)
|
||||
var/noteleport = FALSE
|
||||
/// Hides area from player Teleport function.
|
||||
var/hidden = FALSE
|
||||
/// Is the area teleport-safe: no space / radiation / aggresive mobs / other dangers
|
||||
var/safe = FALSE
|
||||
/// If false, loading multiple maps with this area type will create multiple instances.
|
||||
var/unique = TRUE
|
||||
|
||||
var/no_air = null
|
||||
|
||||
@@ -157,7 +151,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
/proc/process_teleport_locs()
|
||||
for(var/V in GLOB.sortedAreas)
|
||||
var/area/AR = V
|
||||
if(istype(AR, /area/shuttle) || AR.noteleport)
|
||||
if(istype(AR, /area/shuttle) || (AR.area_flags & NOTELEPORT))
|
||||
continue
|
||||
if(GLOB.teleportlocs[AR.name])
|
||||
continue
|
||||
@@ -177,7 +171,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
/area/New()
|
||||
// This interacts with the map loader, so it needs to be set immediately
|
||||
// rather than waiting for atoms to initialize.
|
||||
if (unique)
|
||||
if (area_flags & UNIQUE_AREA)
|
||||
GLOB.areas_by_type[type] = src
|
||||
|
||||
if(!minimap_color) // goes in New() because otherwise it doesn't fucking work
|
||||
@@ -228,7 +222,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
reg_in_areas_in_z()
|
||||
|
||||
//so far I'm only implementing it on mapped unique areas, it's easier this way.
|
||||
if(unique && sub_areas)
|
||||
if((area_flags & UNIQUE_AREA) && sub_areas)
|
||||
if(type in sub_areas)
|
||||
WARNING("\"[src]\" typepath found inside its own sub-areas list, please make sure it doesn't share its parent type initial sub-areas value.")
|
||||
sub_areas = null
|
||||
@@ -261,21 +255,20 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
power_change() // all machines set to current power level, also updates icon
|
||||
update_beauty()
|
||||
|
||||
/// Soon ™
|
||||
/area/proc/RunGeneration()
|
||||
// if(map_generator)
|
||||
// map_generator = new map_generator()
|
||||
// var/list/turfs = list()
|
||||
// for(var/turf/T in contents)
|
||||
// turfs += T
|
||||
// map_generator.generate_terrain(turfs)
|
||||
if(map_generator)
|
||||
map_generator = new map_generator()
|
||||
var/list/turfs = list()
|
||||
for(var/turf/T in contents)
|
||||
turfs += T
|
||||
map_generator.generate_terrain(turfs)
|
||||
|
||||
/area/proc/test_gen()
|
||||
// if(map_generator)
|
||||
// var/list/turfs = list()
|
||||
// for(var/turf/T in contents)
|
||||
// turfs += T
|
||||
// map_generator.generate_terrain(turfs)
|
||||
if(map_generator)
|
||||
var/list/turfs = list()
|
||||
for(var/turf/T in contents)
|
||||
turfs += T
|
||||
map_generator.generate_terrain(turfs)
|
||||
|
||||
/**
|
||||
* Register this area as belonging to a z level
|
||||
@@ -327,6 +320,8 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
* Sends to all ai players, alert consoles, drones and alarm monitor programs in the world
|
||||
*/
|
||||
/area/proc/poweralert(state, obj/source)
|
||||
if (area_flags & NO_ALERTS)
|
||||
return
|
||||
if (state != poweralm)
|
||||
poweralm = state
|
||||
if(istype(source)) //Only report power alarms on the z-level where the source is located.
|
||||
@@ -358,6 +353,8 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
p.triggerAlarm("Power", src, cameras, source)
|
||||
|
||||
/area/proc/atmosalert(danger_level, obj/source)
|
||||
if (area_flags & NO_ALERTS)
|
||||
return
|
||||
if(danger_level != atmosalm)
|
||||
if (danger_level==2)
|
||||
|
||||
@@ -420,19 +417,19 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
if (!fire)
|
||||
set_fire_alarm_effects(TRUE)
|
||||
ModifyFiredoors(FALSE)
|
||||
|
||||
for (var/item in GLOB.alert_consoles)
|
||||
var/obj/machinery/computer/station_alert/a = item
|
||||
a.triggerAlarm("Fire", src, cameras, source)
|
||||
for (var/item in GLOB.silicon_mobs)
|
||||
var/mob/living/silicon/aiPlayer = item
|
||||
aiPlayer.triggerAlarm("Fire", src, cameras, source)
|
||||
for (var/item in GLOB.drones_list)
|
||||
var/mob/living/simple_animal/drone/D = item
|
||||
D.triggerAlarm("Fire", src, cameras, source)
|
||||
for(var/item in GLOB.alarmdisplay)
|
||||
var/datum/computer_file/program/alarm_monitor/p = item
|
||||
p.triggerAlarm("Fire", src, cameras, source)
|
||||
if (!(area_flags & NO_ALERTS)) //Check here instead at the start of the proc so that fire alarms can still work locally even in areas that don't send alerts
|
||||
for (var/item in GLOB.alert_consoles)
|
||||
var/obj/machinery/computer/station_alert/a = item
|
||||
a.triggerAlarm("Fire", src, cameras, source)
|
||||
for (var/item in GLOB.silicon_mobs)
|
||||
var/mob/living/silicon/aiPlayer = item
|
||||
aiPlayer.triggerAlarm("Fire", src, cameras, source)
|
||||
for (var/item in GLOB.drones_list)
|
||||
var/mob/living/simple_animal/drone/D = item
|
||||
D.triggerAlarm("Fire", src, cameras, source)
|
||||
for(var/item in GLOB.alarmdisplay)
|
||||
var/datum/computer_file/program/alarm_monitor/p = item
|
||||
p.triggerAlarm("Fire", src, cameras, source)
|
||||
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
@@ -441,18 +438,19 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
set_fire_alarm_effects(FALSE)
|
||||
ModifyFiredoors(TRUE)
|
||||
|
||||
for (var/item in GLOB.silicon_mobs)
|
||||
var/mob/living/silicon/aiPlayer = item
|
||||
aiPlayer.cancelAlarm("Fire", src, source)
|
||||
for (var/item in GLOB.alert_consoles)
|
||||
var/obj/machinery/computer/station_alert/a = item
|
||||
a.cancelAlarm("Fire", src, source)
|
||||
for (var/item in GLOB.drones_list)
|
||||
var/mob/living/simple_animal/drone/D = item
|
||||
D.cancelAlarm("Fire", src, source)
|
||||
for(var/item in GLOB.alarmdisplay)
|
||||
var/datum/computer_file/program/alarm_monitor/p = item
|
||||
p.cancelAlarm("Fire", src, source)
|
||||
if (!(area_flags & NO_ALERTS)) //Check here instead at the start of the proc so that fire alarms can still work locally even in areas that don't send alerts
|
||||
for (var/item in GLOB.silicon_mobs)
|
||||
var/mob/living/silicon/aiPlayer = item
|
||||
aiPlayer.cancelAlarm("Fire", src, source)
|
||||
for (var/item in GLOB.alert_consoles)
|
||||
var/obj/machinery/computer/station_alert/a = item
|
||||
a.cancelAlarm("Fire", src, source)
|
||||
for (var/item in GLOB.drones_list)
|
||||
var/mob/living/simple_animal/drone/D = item
|
||||
D.cancelAlarm("Fire", src, source)
|
||||
for(var/item in GLOB.alarmdisplay)
|
||||
var/datum/computer_file/program/alarm_monitor/p = item
|
||||
p.cancelAlarm("Fire", src, source)
|
||||
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
@@ -467,7 +465,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
DOOR.lock()
|
||||
|
||||
/area/proc/burglaralert(obj/trigger)
|
||||
if(always_unpowered) //no burglar alarms in space/asteroid
|
||||
if (area_flags & NO_ALERTS)
|
||||
return
|
||||
|
||||
//Trigger alarm effect
|
||||
@@ -675,9 +673,9 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
power_light = FALSE
|
||||
power_environ = FALSE
|
||||
always_unpowered = FALSE
|
||||
valid_territory = FALSE
|
||||
valid_malf_hack = FALSE
|
||||
blob_allowed = FALSE
|
||||
area_flags &= ~VALID_TERRITORY
|
||||
area_flags &= ~BLOBS_ALLOWED
|
||||
addSorted()
|
||||
|
||||
/area/proc/update_areasize()
|
||||
|
||||
@@ -8,6 +8,7 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
|
||||
name = "Strange Location"
|
||||
icon_state = "away"
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
// ambience_index = AMBIENCE_AWAY
|
||||
ambientsounds = AWAY_MISSION
|
||||
sound_environment = SOUND_ENVIRONMENT_ROOM
|
||||
|
||||
@@ -27,3 +28,8 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
|
||||
/area/awaymission/vr
|
||||
name = "Virtual Reality"
|
||||
icon_state = "awaycontent1"
|
||||
requires_power = FALSE
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
var/pacifist = TRUE // if when you enter this zone, you become a pacifist or not
|
||||
var/death = FALSE // if when you enter this zone, you die
|
||||
// network_root_id = "VR"
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
|
||||
// CENTCOM
|
||||
|
||||
// Side note, be sure to change the network_root_id of any areas that are not a part of centcom
|
||||
// and just using the z space as safe harbor. It shouldn't matter much as centcom z is isolated
|
||||
// from everything anyway
|
||||
|
||||
/area/centcom
|
||||
name = "CentCom"
|
||||
icon_state = "centcom"
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
|
||||
requires_power = FALSE
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
noteleport = TRUE
|
||||
blob_allowed = FALSE //Should go without saying, no blobs should take over centcom as a win condition.
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA | NOTELEPORT
|
||||
flags_1 = NONE
|
||||
|
||||
/area/centcom/control
|
||||
@@ -33,6 +36,7 @@
|
||||
name = "VIP Zone"
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
|
||||
// dear mappers who make winterball: THROW YOUR AREAS IN A DIFFERENT MAP, THIS IS DEFAULT GAME STUFF NOT EVENT STUFF
|
||||
/area/centcom/winterball
|
||||
name = "winterball Zone"
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
@@ -56,7 +60,7 @@
|
||||
var/loading_id = ""
|
||||
|
||||
/area/centcom/supplypod/loading/Initialize()
|
||||
. = ..()
|
||||
. = ..()
|
||||
if(!loading_id)
|
||||
CRASH("[type] created without a loading_id")
|
||||
if(GLOB.supplypod_loading_bays[loading_id])
|
||||
@@ -128,17 +132,19 @@
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
|
||||
requires_power = FALSE
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
noteleport = TRUE
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA | NOTELEPORT
|
||||
flags_1 = NONE
|
||||
// network_root_id = "MAGIC_NET"
|
||||
|
||||
//Abductors
|
||||
/area/abductor_ship
|
||||
name = "Abductor Ship"
|
||||
icon_state = "yellow"
|
||||
requires_power = FALSE
|
||||
noteleport = TRUE
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA | NOTELEPORT
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
flags_1 = NONE
|
||||
// network_root_id = "ALIENS"
|
||||
|
||||
//Syndicates
|
||||
/area/syndicate_mothership
|
||||
@@ -146,26 +152,28 @@
|
||||
icon_state = "syndie-ship"
|
||||
requires_power = FALSE
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
noteleport = TRUE
|
||||
blob_allowed = FALSE //Not... entirely sure this will ever come up... but if the bus makes blobs AND ops, it shouldn't aim for the ops to win.
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA | NOTELEPORT
|
||||
flags_1 = NONE
|
||||
// ambience_index = AMBIENCE_DANGER
|
||||
ambientsounds = HIGHSEC
|
||||
// network_root_id = SYNDICATE_NETWORK_ROOT
|
||||
|
||||
/area/syndicate_mothership/control
|
||||
name = "Syndicate Control Room"
|
||||
icon_state = "syndie-control"
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
|
||||
// network_root_id = SYNDICATE_NETWORK_ROOT
|
||||
|
||||
/area/syndicate_mothership/elite_squad
|
||||
name = "Syndicate Elite Squad"
|
||||
icon_state = "syndie-elite"
|
||||
// network_root_id = SYNDICATE_NETWORK_ROOT
|
||||
|
||||
/area/fabric_of_reality
|
||||
name = "Tear in the Fabric of Reality"
|
||||
requires_power = FALSE
|
||||
has_gravity = TRUE
|
||||
noteleport = TRUE
|
||||
blob_allowed = FALSE
|
||||
area_flags = UNIQUE_AREA | NOTELEPORT
|
||||
|
||||
//CAPTURE THE FLAG
|
||||
|
||||
@@ -174,6 +182,7 @@
|
||||
icon_state = "yellow"
|
||||
requires_power = FALSE
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
flags_1 = NONE
|
||||
|
||||
/area/ctf/control_room
|
||||
name = "Control Room A"
|
||||
@@ -209,11 +218,10 @@
|
||||
icon_state = "yellow"
|
||||
requires_power = FALSE
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
noteleport = TRUE
|
||||
hidden = TRUE
|
||||
area_flags = HIDDEN_AREA | NOTELEPORT | UNIQUE_AREA
|
||||
ambientsounds = REEBE
|
||||
|
||||
/area/reebe/city_of_cogs
|
||||
name = "City of Cogs"
|
||||
icon_state = "purple"
|
||||
hidden = FALSE
|
||||
area_flags = NOTELEPORT | UNIQUE_AREA
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
name = "Holodeck"
|
||||
icon_state = "Holodeck"
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
flags_1 = 0
|
||||
hidden = TRUE
|
||||
flags_1 = NONE
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA
|
||||
sound_environment = SOUND_ENVIRONMENT_PADDED_CELL
|
||||
|
||||
var/obj/machinery/computer/holodeck/linked
|
||||
var/restricted = 0 // if true, program goes on emag list
|
||||
var/restricted = FALSE // if true, program goes on emag list
|
||||
// network_root_id = "HOLODECK"
|
||||
|
||||
/*
|
||||
Power tracking: Use the holodeck computer's power grid
|
||||
|
||||
@@ -3,44 +3,49 @@
|
||||
/area/mine
|
||||
icon_state = "mining"
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
flora_allowed = TRUE
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA | FLORA_ALLOWED
|
||||
|
||||
/area/mine/explored
|
||||
name = "Mine"
|
||||
icon_state = "explored"
|
||||
music = null
|
||||
always_unpowered = TRUE
|
||||
requires_power = TRUE
|
||||
poweralm = FALSE
|
||||
power_environ = FALSE
|
||||
power_equip = FALSE
|
||||
power_light = FALSE
|
||||
outdoors = TRUE
|
||||
flags_1 = NONE
|
||||
// ambience_index = AMBIENCE_MINING
|
||||
ambientsounds = MINING
|
||||
flora_allowed = FALSE
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA | NO_ALERTS
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
// min_ambience_cooldown = 70 SECONDS
|
||||
// max_ambience_cooldown = 220 SECONDS
|
||||
|
||||
/area/mine/unexplored
|
||||
name = "Mine"
|
||||
icon_state = "unexplored"
|
||||
music = null
|
||||
always_unpowered = TRUE
|
||||
requires_power = TRUE
|
||||
poweralm = FALSE
|
||||
power_environ = FALSE
|
||||
power_equip = FALSE
|
||||
power_light = FALSE
|
||||
outdoors = TRUE
|
||||
flags_1 = NONE
|
||||
// ambience_index = AMBIENCE_MINING
|
||||
ambientsounds = MINING
|
||||
tunnel_allowed = TRUE
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA | NO_ALERTS | CAVES_ALLOWED | FLORA_ALLOWED | MOB_SPAWN_ALLOWED | MEGAFAUNA_SPAWN_ALLOWED
|
||||
map_generator = /datum/map_generator/cave_generator
|
||||
// min_ambience_cooldown = 70 SECONDS
|
||||
// max_ambience_cooldown = 220 SECONDS
|
||||
|
||||
/area/mine/lobby
|
||||
name = "Mining Station"
|
||||
icon_state = "mining_lobby"
|
||||
|
||||
/area/mine/storage
|
||||
name = "Mining Station Storage"
|
||||
icon_state = "mining_storage"
|
||||
|
||||
/area/mine/production
|
||||
name = "Mining Station Starboard Wing"
|
||||
@@ -62,19 +67,27 @@
|
||||
|
||||
/area/mine/cafeteria
|
||||
name = "Mining Station Cafeteria"
|
||||
icon_state = "mining_labor_cafe"
|
||||
|
||||
/area/mine/hydroponics
|
||||
name = "Mining Station Hydroponics"
|
||||
icon_state = "mining_labor_hydro"
|
||||
|
||||
/area/mine/sleeper
|
||||
name = "Mining Station Emergency Sleeper"
|
||||
|
||||
/area/mine/mechbay
|
||||
name = "Mining Station Mech Bay"
|
||||
icon_state = "mechbay"
|
||||
|
||||
/area/mine/laborcamp
|
||||
name = "Labor Camp"
|
||||
icon_state = "mining_labor"
|
||||
|
||||
/area/mine/laborcamp/security
|
||||
name = "Labor Camp Security"
|
||||
icon_state = "security"
|
||||
// ambience_index = AMBIENCE_DANGER
|
||||
ambientsounds = HIGHSEC
|
||||
|
||||
|
||||
@@ -86,33 +99,36 @@
|
||||
icon_state = "mining"
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
flags_1 = NONE
|
||||
flora_allowed = TRUE
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA | FLORA_ALLOWED
|
||||
sound_environment = SOUND_AREA_LAVALAND
|
||||
|
||||
/area/lavaland/surface
|
||||
name = "Lavaland"
|
||||
icon_state = "explored"
|
||||
music = null
|
||||
always_unpowered = TRUE
|
||||
poweralm = FALSE
|
||||
power_environ = FALSE
|
||||
power_equip = FALSE
|
||||
power_light = FALSE
|
||||
requires_power = TRUE
|
||||
// ambience_index = AMBIENCE_MINING
|
||||
ambientsounds = MINING
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA | FLORA_ALLOWED | NO_ALERTS
|
||||
// min_ambience_cooldown = 70 SECONDS
|
||||
// max_ambience_cooldown = 220 SECONDS
|
||||
|
||||
/area/lavaland/underground
|
||||
name = "Lavaland Caves"
|
||||
icon_state = "unexplored"
|
||||
music = null
|
||||
always_unpowered = TRUE
|
||||
requires_power = TRUE
|
||||
poweralm = FALSE
|
||||
power_environ = FALSE
|
||||
power_equip = FALSE
|
||||
power_light = FALSE
|
||||
// ambience_index = AMBIENCE_MINING
|
||||
ambientsounds = MINING
|
||||
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA | FLORA_ALLOWED | NO_ALERTS
|
||||
// min_ambience_cooldown = 70 SECONDS
|
||||
// max_ambience_cooldown = 220 SECONDS
|
||||
|
||||
/area/lavaland/surface/outdoors
|
||||
name = "Lavaland Wastes"
|
||||
@@ -120,16 +136,16 @@
|
||||
|
||||
/area/lavaland/surface/outdoors/unexplored //monsters and ruins spawn here
|
||||
icon_state = "unexplored"
|
||||
tunnel_allowed = TRUE
|
||||
mob_spawn_allowed = TRUE
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA | CAVES_ALLOWED | FLORA_ALLOWED | MOB_SPAWN_ALLOWED | NO_ALERTS
|
||||
map_generator = /datum/map_generator/cave_generator/lavaland
|
||||
|
||||
/area/lavaland/surface/outdoors/unexplored/danger //megafauna will also spawn here
|
||||
icon_state = "danger"
|
||||
megafauna_spawn_allowed = TRUE
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA | CAVES_ALLOWED | FLORA_ALLOWED | MOB_SPAWN_ALLOWED | MEGAFAUNA_SPAWN_ALLOWED | NO_ALERTS
|
||||
|
||||
/area/lavaland/surface/outdoors/explored
|
||||
name = "Lavaland Labor Camp"
|
||||
flora_allowed = FALSE
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA | NO_ALERTS
|
||||
|
||||
|
||||
|
||||
@@ -139,61 +155,68 @@
|
||||
icon_state = "mining"
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
flags_1 = NONE
|
||||
flora_allowed = TRUE
|
||||
blob_allowed = FALSE
|
||||
area_flags = UNIQUE_AREA | FLORA_ALLOWED
|
||||
sound_environment = SOUND_AREA_ICEMOON
|
||||
|
||||
/area/icemoon/surface
|
||||
name = "Icemoon"
|
||||
icon_state = "explored"
|
||||
always_unpowered = TRUE
|
||||
poweralm = FALSE
|
||||
power_environ = FALSE
|
||||
power_equip = FALSE
|
||||
power_light = FALSE
|
||||
requires_power = TRUE
|
||||
// ambience_index = AMBIENCE_MINING
|
||||
ambientsounds = MINING
|
||||
area_flags = UNIQUE_AREA | FLORA_ALLOWED | NO_ALERTS
|
||||
// min_ambience_cooldown = 70 SECONDS
|
||||
// max_ambience_cooldown = 220 SECONDS
|
||||
|
||||
/area/icemoon/surface/outdoors // weather happens here
|
||||
name = "Icemoon Wastes"
|
||||
outdoors = TRUE
|
||||
|
||||
/area/icemoon/surface/outdoors/labor_camp
|
||||
name = "Icemoon Labor Camp"
|
||||
area_flags = UNIQUE_AREA | NO_ALERTS
|
||||
|
||||
/area/icemoon/surface/outdoors/unexplored //monsters and ruins spawn here
|
||||
icon_state = "unexplored"
|
||||
area_flags = UNIQUE_AREA | FLORA_ALLOWED | MOB_SPAWN_ALLOWED | CAVES_ALLOWED | NO_ALERTS
|
||||
|
||||
/area/icemoon/surface/outdoors/unexplored/rivers // rivers spawn here
|
||||
icon_state = "danger"
|
||||
map_generator = /datum/map_generator/cave_generator/icemoon/surface
|
||||
|
||||
/area/icemoon/surface/outdoors/unexplored/rivers/no_monsters
|
||||
area_flags = UNIQUE_AREA | FLORA_ALLOWED | CAVES_ALLOWED | NO_ALERTS
|
||||
|
||||
/area/icemoon/underground
|
||||
name = "Icemoon Caves"
|
||||
outdoors = TRUE
|
||||
always_unpowered = TRUE
|
||||
requires_power = TRUE
|
||||
poweralm = FALSE
|
||||
power_environ = FALSE
|
||||
power_equip = FALSE
|
||||
power_light = FALSE
|
||||
// ambience_index = AMBIENCE_MINING
|
||||
ambientsounds = MINING
|
||||
area_flags = UNIQUE_AREA | FLORA_ALLOWED | NO_ALERTS
|
||||
// min_ambience_cooldown = 70 SECONDS
|
||||
// max_ambience_cooldown = 220 SECONDS
|
||||
|
||||
/area/icemoon/underground/unexplored // mobs and megafauna and ruins spawn here
|
||||
name = "Icemoon Caves"
|
||||
icon_state = "unexplored"
|
||||
tunnel_allowed = TRUE
|
||||
mob_spawn_allowed = TRUE
|
||||
megafauna_spawn_allowed = TRUE
|
||||
area_flags = CAVES_ALLOWED | FLORA_ALLOWED | MOB_SPAWN_ALLOWED | MEGAFAUNA_SPAWN_ALLOWED | NO_ALERTS
|
||||
|
||||
/area/icemoon/underground/unexplored/rivers // rivers spawn here
|
||||
icon_state = "danger"
|
||||
map_generator = /datum/map_generator/cave_generator/icemoon
|
||||
|
||||
/area/icemoon/underground/explored
|
||||
/area/icemoon/underground/unexplored/rivers/deep
|
||||
map_generator = /datum/map_generator/cave_generator/icemoon/deep
|
||||
|
||||
/area/icemoon/underground/explored // ruins can't spawn here
|
||||
name = "Icemoon Underground"
|
||||
flora_allowed = FALSE
|
||||
|
||||
/area/icemoon/surface/outdoors
|
||||
name = "Icemoon Wastes"
|
||||
outdoors = TRUE
|
||||
|
||||
/area/icemoon/surface/outdoors/labor_camp
|
||||
name = "Icemoon Labor Camp"
|
||||
flora_allowed = FALSE
|
||||
|
||||
/area/icemoon/surface/outdoors/unexplored //monsters and ruins spawn here
|
||||
icon_state = "unexplored"
|
||||
tunnel_allowed = TRUE
|
||||
mob_spawn_allowed = TRUE
|
||||
|
||||
/area/icemoon/surface/outdoors/unexplored/rivers // rivers spawn here
|
||||
icon_state = "danger"
|
||||
|
||||
/area/icemoon/surface/outdoors/unexplored/rivers/no_monsters
|
||||
mob_spawn_allowed = FALSE
|
||||
area_flags = UNIQUE_AREA | NO_ALERTS
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
/area/ruin/space
|
||||
has_gravity = FALSE
|
||||
blob_allowed = FALSE //Nope, no winning in space as a blob. Gotta eat the station.
|
||||
outdoors = TRUE
|
||||
ambientsounds = SPACE
|
||||
area_flags = UNIQUE_AREA
|
||||
|
||||
/area/ruin/space/has_grav
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
@@ -12,7 +10,6 @@
|
||||
/area/ruin/space/has_grav/powered
|
||||
requires_power = FALSE
|
||||
|
||||
|
||||
/area/ruin/fakespace
|
||||
icon_state = "space"
|
||||
requires_power = TRUE
|
||||
@@ -22,10 +19,8 @@
|
||||
power_light = FALSE
|
||||
power_equip = FALSE
|
||||
power_environ = FALSE
|
||||
valid_territory = FALSE
|
||||
outdoors = TRUE
|
||||
ambientsounds = SPACE
|
||||
blob_allowed = FALSE
|
||||
|
||||
/////////////
|
||||
|
||||
@@ -133,22 +128,20 @@
|
||||
|
||||
/area/ruin/space/diner
|
||||
name = "Space Diner"
|
||||
area_flags = UNIQUE_AREA
|
||||
|
||||
/area/ruin/space/diner/interior
|
||||
name = "Space Diner"
|
||||
icon_state = "maintbar"
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
blob_allowed = FALSE //Nope, no winning in the diner as a blob. Gotta eat the main station.
|
||||
|
||||
/area/ruin/space/diner/solars
|
||||
requires_power = FALSE
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_IFSTARLIGHT
|
||||
valid_territory = FALSE
|
||||
blob_allowed = FALSE
|
||||
flags_1 = NONE
|
||||
ambientsounds = ENGINEERING
|
||||
name = "Space Diner Solar Array"
|
||||
icon_state = "yellow"
|
||||
requires_power = FALSE
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_IFSTARLIGHT
|
||||
flags_1 = NONE
|
||||
ambientsounds = ENGINEERING
|
||||
|
||||
//Ruin of "Skelter" ship
|
||||
|
||||
@@ -257,7 +250,7 @@
|
||||
//Ruin of old teleporter
|
||||
|
||||
/area/ruin/space/oldteleporter
|
||||
name = "Old teleporter"
|
||||
name = "Old Teleporter"
|
||||
icon_state = "teleporter"
|
||||
|
||||
|
||||
@@ -301,7 +294,7 @@
|
||||
icon_state = "storage_wing"
|
||||
|
||||
/area/ruin/space/has_grav/deepstorage/dorm
|
||||
name = "Deep Storage Dormory"
|
||||
name = "Deep Storage Dormitory"
|
||||
icon_state = "crew_quarters"
|
||||
|
||||
/area/ruin/space/has_grav/deepstorage/kitchen
|
||||
@@ -339,7 +332,9 @@
|
||||
/area/ruin/space/has_grav/ancientstation/atmo
|
||||
name = "Beta Station Atmospherics"
|
||||
icon_state = "red"
|
||||
has_gravity = FALSE
|
||||
// ambience_index = AMBIENCE_ENGI
|
||||
ambientsounds = ENGINEERING
|
||||
has_gravity = TRUE
|
||||
|
||||
/area/ruin/space/has_grav/ancientstation/betanorth
|
||||
name = "Beta Station North Corridor"
|
||||
@@ -349,9 +344,15 @@
|
||||
name = "Station Solar Array"
|
||||
icon_state = "panelsAP"
|
||||
|
||||
/area/ruin/space/has_grav/ancientstation/betacorridor
|
||||
name = "Beta Station Main Corridor"
|
||||
icon_state = "bluenew"
|
||||
|
||||
/area/ruin/space/has_grav/ancientstation/engi
|
||||
name = "Charlie Station Engineering"
|
||||
icon_state = "engine"
|
||||
// ambience_index = AMBIENCE_ENGI
|
||||
ambientsounds = ENGINEERING
|
||||
|
||||
/area/ruin/space/has_grav/ancientstation/comm
|
||||
name = "Charlie Station Command"
|
||||
@@ -385,6 +386,27 @@
|
||||
name = "Hivebot Mothership"
|
||||
icon_state = "teleporter"
|
||||
|
||||
/area/ruin/space/has_grav/ancientstation/deltaai
|
||||
name = "Delta Station AI Core"
|
||||
icon_state = "ai"
|
||||
ambientsounds = list('sound/ambience/ambimalf.ogg', 'sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg')
|
||||
|
||||
/area/ruin/space/has_grav/ancientstation/mining
|
||||
name = "Beta Station Mining Equipment"
|
||||
icon_state = "mining"
|
||||
|
||||
/area/ruin/space/has_grav/ancientstation/medbay
|
||||
name = "Beta Station Medbay"
|
||||
icon_state = "medbay"
|
||||
|
||||
/area/ruin/space/has_grav/ancientstation/betastorage
|
||||
name = "Beta Station Storage"
|
||||
icon_state = "storage"
|
||||
|
||||
/area/solars/ancientstation
|
||||
name = "Charlie Station Solar Array"
|
||||
icon_state = "panelsP"
|
||||
|
||||
//DERELICT
|
||||
|
||||
/area/ruin/space/derelict
|
||||
@@ -469,11 +491,11 @@
|
||||
name = "Abandoned Ship"
|
||||
icon_state = "yellow"
|
||||
|
||||
/area/solar/derelict_starboard
|
||||
/area/solars/derelict_starboard
|
||||
name = "Derelict Starboard Solar Array"
|
||||
icon_state = "panelsS"
|
||||
|
||||
/area/solar/derelict_aft
|
||||
/area/solars/derelict_aft
|
||||
name = "Derelict Aft Solar Array"
|
||||
icon_state = "yellow"
|
||||
|
||||
@@ -496,28 +518,24 @@
|
||||
power_light = FALSE
|
||||
power_environ = FALSE
|
||||
|
||||
|
||||
//DJSTATION
|
||||
|
||||
/area/ruin/space/djstation
|
||||
name = "Ruskie DJ Station"
|
||||
icon_state = "DJ"
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
blob_allowed = FALSE //Nope, no winning on the DJ station as a blob. Gotta eat the main station.
|
||||
|
||||
/area/ruin/space/djstation/solars
|
||||
name = "DJ Station Solars"
|
||||
icon_state = "DJ"
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
|
||||
|
||||
//ABANDONED TELEPORTER
|
||||
|
||||
/area/ruin/space/abandoned_tele
|
||||
name = "Abandoned Teleporter"
|
||||
icon_state = "teleporter"
|
||||
music = "signal"
|
||||
ambientsounds = list('sound/ambience/ambimalf.ogg')
|
||||
ambientsounds = list('sound/ambience/ambimalf.ogg', 'sound/ambience/signal.ogg')
|
||||
|
||||
//OLD AI SAT
|
||||
|
||||
@@ -561,3 +579,13 @@
|
||||
/area/ruin/space/has_grav/powered/advancedlab
|
||||
name = "Abductor Replication Lab"
|
||||
icon_state = "yellow"
|
||||
|
||||
//HELL'S FACTORY OPERATING FACILITY
|
||||
// /area/ruin/space/has_grav/hellfactory
|
||||
// name = "Hell Factory"
|
||||
// icon_state = "yellow"
|
||||
|
||||
// /area/ruin/space/has_grav/hellfactoryoffice
|
||||
// name = "Hell Factory Office"
|
||||
// icon_state = "red"
|
||||
// area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA | NOTELEPORT
|
||||
|
||||
@@ -8,10 +8,11 @@
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
always_unpowered = FALSE
|
||||
valid_territory = FALSE
|
||||
icon_state = "shuttle"
|
||||
// Loading the same shuttle map at a different time will produce distinct area instances.
|
||||
unique = FALSE
|
||||
area_flags = NO_ALERTS
|
||||
icon_state = "shuttle"
|
||||
flags_1 = CAN_BE_DIRTY_1
|
||||
// area_limited_icon_smoothing = /area/shuttle
|
||||
sound_environment = SOUND_ENVIRONMENT_ROOM
|
||||
|
||||
/area/shuttle/Initialize()
|
||||
@@ -32,7 +33,8 @@
|
||||
|
||||
/area/shuttle/syndicate
|
||||
name = "Syndicate Infiltrator"
|
||||
blob_allowed = FALSE
|
||||
// ambience_index = AMBIENCE_DANGER
|
||||
// area_limited_icon_smoothing = /area/shuttle/syndicate
|
||||
ambientsounds = HIGHSEC
|
||||
canSmoothWithAreas = /area/shuttle/syndicate
|
||||
|
||||
@@ -57,7 +59,6 @@
|
||||
|
||||
/area/shuttle/pirate
|
||||
name = "Pirate Shuttle"
|
||||
blob_allowed = FALSE
|
||||
requires_power = TRUE
|
||||
canSmoothWithAreas = /area/shuttle/pirate
|
||||
|
||||
@@ -65,12 +66,22 @@
|
||||
name = "Pirate Shuttle Vault"
|
||||
requires_power = FALSE
|
||||
|
||||
/area/shuttle/pirate/flying_dutchman
|
||||
name = "Flying Dutchman"
|
||||
requires_power = FALSE
|
||||
|
||||
////////////////////////////Bounty Hunter Shuttles////////////////////////////
|
||||
|
||||
/area/shuttle/hunter
|
||||
name = "Hunter Shuttle"
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
|
||||
////////////////////////////White Ship////////////////////////////
|
||||
|
||||
/area/shuttle/abandoned
|
||||
name = "Abandoned Ship"
|
||||
blob_allowed = FALSE
|
||||
requires_power = TRUE
|
||||
// area_limited_icon_smoothing = /area/shuttle/abandoned
|
||||
canSmoothWithAreas = /area/shuttle/abandoned
|
||||
|
||||
/area/shuttle/abandoned/bridge
|
||||
@@ -94,13 +105,6 @@
|
||||
/area/shuttle/abandoned/pod
|
||||
name = "Abandoned Ship Pod"
|
||||
|
||||
////////////////////////////Bounty Hunter Shuttles////////////////////////////
|
||||
/area/shuttle/hunter
|
||||
name = "Hunter Shuttle"
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
blob_allowed = FALSE
|
||||
canSmoothWithAreas = /area/shuttle/hunter
|
||||
|
||||
////////////////////////////Single-area shuttles////////////////////////////
|
||||
|
||||
/area/shuttle/transit
|
||||
@@ -117,44 +121,67 @@
|
||||
|
||||
/area/shuttle/arrival
|
||||
name = "Arrival Shuttle"
|
||||
unique = TRUE // SSjob refers to this area for latejoiners
|
||||
area_flags = UNIQUE_AREA// SSjob refers to this area for latejoiners
|
||||
|
||||
/area/shuttle/pod_1
|
||||
name = "Escape Pod One"
|
||||
area_flags = BLOBS_ALLOWED
|
||||
|
||||
/area/shuttle/pod_2
|
||||
name = "Escape Pod Two"
|
||||
area_flags = BLOBS_ALLOWED
|
||||
|
||||
/area/shuttle/pod_3
|
||||
name = "Escape Pod Three"
|
||||
area_flags = BLOBS_ALLOWED
|
||||
|
||||
/area/shuttle/pod_4
|
||||
name = "Escape Pod Four"
|
||||
area_flags = BLOBS_ALLOWED
|
||||
|
||||
/area/shuttle/mining
|
||||
name = "Mining Shuttle"
|
||||
blob_allowed = FALSE
|
||||
area_flags = NONE //Set this so it doesn't inherit NO_ALERTS
|
||||
|
||||
/area/shuttle/mining/large
|
||||
name = "Mining Shuttle"
|
||||
requires_power = TRUE
|
||||
|
||||
/area/shuttle/labor
|
||||
name = "Labor Camp Shuttle"
|
||||
blob_allowed = FALSE
|
||||
area_flags = NONE //Set this so it doesn't inherit NO_ALERTS
|
||||
|
||||
/area/shuttle/supply
|
||||
name = "Supply Shuttle"
|
||||
blob_allowed = FALSE
|
||||
area_flags = NOTELEPORT
|
||||
|
||||
/area/shuttle/escape
|
||||
name = "Emergency Shuttle"
|
||||
area_flags = BLOBS_ALLOWED
|
||||
// area_limited_icon_smoothing = /area/shuttle/escape
|
||||
canSmoothWithAreas = /area/shuttle/escape
|
||||
flags_1 = CAN_BE_DIRTY_1 // | CULT_PERMITTED_1
|
||||
|
||||
/area/shuttle/escape/backup
|
||||
name = "Backup Emergency Shuttle"
|
||||
|
||||
/area/shuttle/escape/brig
|
||||
name = "Escape Shuttle Brig"
|
||||
icon_state = "shuttlered"
|
||||
|
||||
/area/shuttle/escape/luxury
|
||||
name = "Luxurious Emergency Shuttle"
|
||||
// area_flags = NOTELEPORT
|
||||
|
||||
/area/shuttle/escape/simulation
|
||||
name = "Medieval Reality Simulation Dome"
|
||||
icon_state = "shuttlectf"
|
||||
area_flags = NOTELEPORT
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
|
||||
/area/shuttle/escape/arena
|
||||
name = "The Arena"
|
||||
noteleport = TRUE
|
||||
area_flags = NOTELEPORT
|
||||
|
||||
/area/shuttle/escape/meteor
|
||||
name = "\proper a meteor with engines strapped to it"
|
||||
@@ -162,34 +189,26 @@
|
||||
|
||||
/area/shuttle/transport
|
||||
name = "Transport Shuttle"
|
||||
blob_allowed = FALSE
|
||||
|
||||
/area/shuttle/assault_pod
|
||||
name = "Steel Rain"
|
||||
blob_allowed = FALSE
|
||||
|
||||
/area/shuttle/sbc_starfury
|
||||
name = "SBC Starfury"
|
||||
blob_allowed = FALSE
|
||||
|
||||
/area/shuttle/sbc_fighter1
|
||||
name = "SBC Fighter 1"
|
||||
blob_allowed = FALSE
|
||||
|
||||
/area/shuttle/sbc_fighter2
|
||||
name = "SBC Fighter 2"
|
||||
blob_allowed = FALSE
|
||||
|
||||
/area/shuttle/sbc_corvette
|
||||
name = "SBC corvette"
|
||||
blob_allowed = FALSE
|
||||
|
||||
/area/shuttle/syndicate_scout
|
||||
name = "Syndicate Scout"
|
||||
blob_allowed = FALSE
|
||||
|
||||
/area/shuttle/caravan
|
||||
blob_allowed = FALSE
|
||||
requires_power = TRUE
|
||||
|
||||
/area/shuttle/caravan/syndicate1
|
||||
|
||||
@@ -58,14 +58,6 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
|
||||
var/threat_level = 0
|
||||
/// The current antag threat. Recalculated every time a ruletype starts or ends.
|
||||
var/threat = 0
|
||||
/// Threat average over the course of the round, for endgame logs.
|
||||
var/threat_average = 0
|
||||
/// Number of times threat average has been calculated, for calculating above.
|
||||
var/threat_average_weight = 0
|
||||
/// Last time a threat average sample was taken. Used for weighting the rolling average.
|
||||
var/last_threat_sample_time = 0
|
||||
/// Maximum threat recorded so far, for cross-round chaos adjustment.
|
||||
var/max_threat = 0
|
||||
/// Things that cause a rolling threat adjustment to be displayed at roundend.
|
||||
var/list/threat_tallies = list()
|
||||
/// Running information about the threat. Can store text or datum entries.
|
||||
@@ -745,17 +737,7 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
|
||||
continue
|
||||
if(!M.voluntary_ghosted)
|
||||
current_players[CURRENT_DEAD_PLAYERS].Add(M) // Players who actually died (and admins who ghosted, would be nice to avoid counting them somehow)
|
||||
threat = storyteller.calculate_threat() + added_threat
|
||||
max_threat = max(max_threat,threat)
|
||||
if(threat_average_weight)
|
||||
var/cur_sample_weight = world.time - last_threat_sample_time
|
||||
threat_average = ((threat_average * threat_average_weight) + (threat * cur_sample_weight)) / (threat_average_weight + cur_sample_weight)
|
||||
threat_average_weight += cur_sample_weight
|
||||
last_threat_sample_time = world.time
|
||||
else
|
||||
threat_average = threat
|
||||
threat_average_weight++
|
||||
last_threat_sample_time = world.time
|
||||
threat = (SSactivity.current_threat * 0.6 + SSactivity.get_max_threat() * 0.2 + SSactivity.get_average_threat() * 0.2) + added_threat
|
||||
|
||||
/// Removes type from the list
|
||||
/datum/game_mode/dynamic/proc/remove_from_list(list/type_list, type)
|
||||
|
||||
@@ -45,27 +45,6 @@ Property weights are added to the config weight of the ruleset. They are:
|
||||
var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_first_midround_delay_min + GLOB.dynamic_first_midround_delay_max)
|
||||
mode.midround_injection_cooldown = round(clamp(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_first_midround_delay_min, GLOB.dynamic_first_midround_delay_max)) + world.time
|
||||
|
||||
/datum/dynamic_storyteller/proc/calculate_threat()
|
||||
var/threat = 0
|
||||
for(var/datum/antagonist/A in GLOB.antagonists)
|
||||
if(A?.owner?.current && A.owner.current.stat != DEAD)
|
||||
threat += A.threat()
|
||||
for(var/r in SSevents.running)
|
||||
var/datum/round_event/R = r
|
||||
threat += R.threat()
|
||||
for(var/obj/item/phylactery/P in GLOB.poi_list)
|
||||
threat += 25 // can't be giving them too much of a break
|
||||
for (var/mob/M in mode.current_players[CURRENT_LIVING_PLAYERS])
|
||||
if (M?.mind?.assigned_role && M.stat != DEAD)
|
||||
var/datum/job/J = SSjob.GetJob(M.mind.assigned_role)
|
||||
if(J)
|
||||
if(length(M.mind.antag_datums))
|
||||
threat += J.GetThreat()
|
||||
else
|
||||
threat -= J.GetThreat()
|
||||
threat += (mode.current_players[CURRENT_DEAD_PLAYERS].len)*dead_player_weight
|
||||
return round(threat,0.1)
|
||||
|
||||
/datum/dynamic_storyteller/proc/do_process()
|
||||
return
|
||||
|
||||
@@ -95,7 +74,7 @@ Property weights are added to the config weight of the ruleset. They are:
|
||||
if(voters)
|
||||
GLOB.dynamic_curve_centre += (mean/voters)
|
||||
if(flags & USE_PREV_ROUND_WEIGHTS)
|
||||
GLOB.dynamic_curve_centre += (50 - SSpersistence.average_dynamic_threat) / 10
|
||||
GLOB.dynamic_curve_centre += (SSpersistence.average_threat) / 10
|
||||
GLOB.dynamic_forced_threat_level = forced_threat_level
|
||||
|
||||
/datum/dynamic_storyteller/proc/get_midround_cooldown()
|
||||
|
||||
@@ -5,28 +5,16 @@
|
||||
continue
|
||||
S.charge = 0
|
||||
S.output_level = 0
|
||||
S.output_attempt = 0
|
||||
S.output_attempt = FALSE
|
||||
S.update_icon()
|
||||
S.power_change()
|
||||
|
||||
var/list/skipped_areas = list(/area/engine/engineering, /area/engine/supermatter, /area/engine/atmospherics_engine, /area/ai_monitored/turret_protected/ai)
|
||||
|
||||
for(var/area/A in world)
|
||||
if( !A.requires_power || A.always_unpowered || A.base_area)
|
||||
for(var/area/A in GLOB.the_station_areas)
|
||||
if(!A.requires_power || A.always_unpowered )
|
||||
continue
|
||||
if(GLOB.typecache_powerfailure_safe_areas[A.type])
|
||||
continue
|
||||
|
||||
var/skip = 0
|
||||
for(var/area_type in skipped_areas)
|
||||
if(istype(A,area_type))
|
||||
skip = 1
|
||||
break
|
||||
if(A.contents)
|
||||
for(var/atom/AT in A.contents)
|
||||
if(!is_station_level(AT.z)) //Only check one, it's enough.
|
||||
skip = 1
|
||||
break
|
||||
if(skip)
|
||||
continue
|
||||
A.power_light = FALSE
|
||||
A.power_equip = FALSE
|
||||
A.power_environ = FALSE
|
||||
@@ -35,13 +23,7 @@
|
||||
for(var/obj/machinery/power/apc/C in GLOB.apcs_list)
|
||||
if(C.cell && is_station_level(C.z))
|
||||
var/area/A = C.area
|
||||
|
||||
var/skip = 0
|
||||
for(var/area_type in skipped_areas)
|
||||
if(istype(A,area_type))
|
||||
skip = 1
|
||||
break
|
||||
if(skip)
|
||||
if(GLOB.typecache_powerfailure_safe_areas[A.type])
|
||||
continue
|
||||
|
||||
C.cell.charge = 0
|
||||
|
||||
@@ -420,7 +420,7 @@
|
||||
|
||||
for(var/mob/dead/new_player/player in players)
|
||||
if(player.client && player.ready == PLAYER_READY_TO_PLAY)
|
||||
if((role in player.client.prefs.be_special) && (ROLE_SYNDICATE in player.client.prefs.be_special))
|
||||
if((role in player.client.prefs.be_special) && !(ROLE_NO_ANTAGONISM in player.client.prefs.be_special))
|
||||
if(!jobban_isbanned(player, ROLE_SYNDICATE) && !QDELETED(player) && !jobban_isbanned(player, role) && !QDELETED(player)) //Nodrak/Carn: Antag Job-bans
|
||||
if(age_check(player.client)) //Must be older than the minimum age
|
||||
candidates += player.mind // Get a list of all the people who want to be the antagonist for this round
|
||||
|
||||
@@ -413,7 +413,7 @@
|
||||
for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION)) //First, collect all area types on the station zlevel
|
||||
for(var/ar in SSmapping.areas_in_z["[z]"])
|
||||
var/area/A = ar
|
||||
if(!(A.type in valid_territories) && A.valid_territory)
|
||||
if(!(A.type in valid_territories) && (A.area_flags & VALID_TERRITORY))
|
||||
valid_territories |= A.type
|
||||
return valid_territories.len
|
||||
|
||||
|
||||
@@ -412,6 +412,24 @@ If not set, defaults to check_completion instead. Set it. It's used by cryo.
|
||||
counter++
|
||||
return counter >= 8
|
||||
|
||||
/datum/objective/freedom
|
||||
name = "freedom"
|
||||
explanation_text = "Don't get captured by nanotrasen."
|
||||
team_explanation_text = "Have all members of your team free of nanotrasen custody."
|
||||
|
||||
/datum/objective/freedom/check_completion()
|
||||
var/list/datum/mind/owners = get_owners()
|
||||
for(var/m in owners)
|
||||
var/datum/mind/M = m
|
||||
if(!considered_alive(M))
|
||||
return FALSE
|
||||
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
|
||||
return FALSE
|
||||
var/turf/location = get_turf(M.current)
|
||||
if(!location || istype(location, /turf/open/floor/plasteel/shuttle/red) || istype(location, /turf/open/floor/mineral/plastitanium/red/brig)) // Fails if they are in the shuttle brig
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/objective/escape
|
||||
name = "escape"
|
||||
explanation_text = "Escape on the shuttle or an escape pod alive and without being in custody."
|
||||
@@ -1240,7 +1258,7 @@ GLOBAL_LIST_EMPTY(possible_sabotages)
|
||||
var/payout_bonus = 0
|
||||
var/area/dropoff = null
|
||||
var/static/list/blacklisted_areas = typecacheof(list(/area/ai_monitored/turret_protected,
|
||||
/area/solar/,
|
||||
/area/solars/,
|
||||
/area/ruin/, //thank you station space ruins
|
||||
/area/science/test_area/,
|
||||
/area/shuttle/))
|
||||
|
||||
@@ -33,70 +33,6 @@
|
||||
/datum/sabotage_objective/processing/check_conditions()
|
||||
return won
|
||||
|
||||
/*
|
||||
/datum/sabotage_objective/processing/power_sink
|
||||
name = "Drain at least 100 megajoules of power using a power sink."
|
||||
sabotage_type = "powersink"
|
||||
special_equipment = list(/obj/item/sbeacondrop/powersink)
|
||||
var/sink_found = FALSE
|
||||
var/count = 0
|
||||
|
||||
/datum/sabotage_objective/processing/power_sink/check_condition_processing()
|
||||
for(var/s in GLOB.power_sinks)
|
||||
var/obj/item/powersink/sink = s
|
||||
won = max(won,sink.power_drained/1e8)
|
||||
*/
|
||||
|
||||
/obj/item/paper/guides/antag/supermatter_sabotage
|
||||
info = "Ways to sabotage a supermatter:<br>\
|
||||
<ul>\
|
||||
<li>Set the air alarm's operating mode to anything that isn't 'draught' (yes, anything, though 'off' works best). Or just smash the air alarm, that works too.</li>\
|
||||
<li>Wrench a pipe (the junction to the cold loop is most effective, but some setups will robust through this no issue; best to try for multiple)</li>\
|
||||
<li>Pump in as much carbon dioxide, oxygen, plasma or tritium as you can find (this will likely also cause a singularity or tesla delamination, so watch out!)</li>\
|
||||
<li>Unset the filters on the cooling loop, or, perhaps more insidious, set them to oxygen/plasma.</li>\
|
||||
<li>Deactivate the digital valve that sends the exhaust gases to space (note: only works on box station; others you must unwrench).</li>\
|
||||
<li>There are many other ways; be creative!</li>\
|
||||
</ul>"
|
||||
|
||||
/*/datum/sabotage_objective/processing/supermatter
|
||||
name = "Sabotage the supermatter so that it goes under 50% integrity. If it is delaminated, you will fail."
|
||||
sabotage_type = "supermatter"
|
||||
special_equipment = list(/obj/item/paper/guides/antag/supermatter_sabotage)
|
||||
var/list/supermatters = list()
|
||||
excludefromjob = list("Chief Engineer", "Station Engineer", "Atmospheric Technician")
|
||||
|
||||
/datum/sabotage_objective/processing/supermatter/check_condition_processing()
|
||||
if(!supermatters.len)
|
||||
supermatters = list()
|
||||
for(var/obj/machinery/power/supermatter_crystal/S in GLOB.machines)
|
||||
// Delaminating, not within coverage, not on a tile.
|
||||
if (!isturf(S.loc) || !(is_station_level(S.z) || is_mining_level(S.z)))
|
||||
continue
|
||||
supermatters.Add(S)
|
||||
for(var/obj/machinery/power/supermatter_crystal/S in supermatters) // you can win this with a wishgranter... lol.
|
||||
won = max(1-((S.get_integrity()-50)/50),won)
|
||||
return FALSE
|
||||
|
||||
/datum/sabotage_objective/processing/supermatter/can_run()
|
||||
return (locate(/obj/machinery/power/supermatter_crystal) in GLOB.machines)
|
||||
|
||||
/datum/sabotage_objective/station_integrity
|
||||
name = "Make sure the station is at less than 80% integrity by the end. Smash walls, windows etc. to reach this goal."
|
||||
sabotage_type = "integrity"
|
||||
|
||||
/datum/sabotage_objective/station_integrity/check_conditions()
|
||||
return 5-(max(SSticker.station_integrity*4,320)/80)
|
||||
*/
|
||||
/datum/sabotage_objective/cloner
|
||||
name = "Destroy all Nanotrasen cloning machines."
|
||||
sabotage_type = "cloner"
|
||||
|
||||
/datum/sabotage_objective/cloner/check_conditions()
|
||||
for(var/obj/machinery/clonepod/cloner in GLOB.machines)
|
||||
if(is_station_level(cloner.z))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/sabotage_objective/ai_law
|
||||
name = "Upload a hacked law to the AI."
|
||||
sabotage_type = "ailaw"
|
||||
|
||||
@@ -519,6 +519,8 @@ Class Procs:
|
||||
|
||||
//called on machinery construction (i.e from frame to machinery) but not on initialization
|
||||
/obj/machinery/proc/on_construction()
|
||||
for(var/obj/I in contents)
|
||||
I.moveToNullspace()
|
||||
return
|
||||
|
||||
//called on deconstruction before the final deletion
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
icon_state = "0"
|
||||
state = 0
|
||||
|
||||
/obj/structure/frame/computer/attackby(obj/item/P, mob/user, params)
|
||||
/obj/structure/frame/computer/attackby(obj/item/P, mob/living/user, params)
|
||||
add_fingerprint(user)
|
||||
switch(state)
|
||||
if(0)
|
||||
@@ -11,7 +11,7 @@
|
||||
to_chat(user, "<span class='notice'>You start wrenching the frame into place...</span>")
|
||||
if(P.use_tool(src, user, 20, volume=50))
|
||||
to_chat(user, "<span class='notice'>You wrench the frame into place.</span>")
|
||||
setAnchored(TRUE)
|
||||
set_anchored(TRUE)
|
||||
state = 1
|
||||
return
|
||||
if(P.tool_behaviour == TOOL_WELDER)
|
||||
@@ -19,7 +19,7 @@
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You start deconstructing the frame...</span>")
|
||||
if(P.use_tool(src, user, 20, volume=50) && state == 0)
|
||||
if(P.use_tool(src, user, 20, volume=50))
|
||||
to_chat(user, "<span class='notice'>You deconstruct the frame.</span>")
|
||||
var/obj/item/stack/sheet/metal/M = new (drop_location(), 5)
|
||||
M.add_fingerprint(user)
|
||||
@@ -28,15 +28,15 @@
|
||||
if(1)
|
||||
if(P.tool_behaviour == TOOL_WRENCH)
|
||||
to_chat(user, "<span class='notice'>You start to unfasten the frame...</span>")
|
||||
if(P.use_tool(src, user, 20, volume=50) && state == 1)
|
||||
if(P.use_tool(src, user, 20, volume=50))
|
||||
to_chat(user, "<span class='notice'>You unfasten the frame.</span>")
|
||||
setAnchored(FALSE)
|
||||
set_anchored(FALSE)
|
||||
state = 0
|
||||
return
|
||||
if(istype(P, /obj/item/circuitboard/computer) && !circuit)
|
||||
if(!user.transferItemToLoc(P, src))
|
||||
return
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
|
||||
to_chat(user, "<span class='notice'>You place [P] inside the frame.</span>")
|
||||
icon_state = "1"
|
||||
circuit = P
|
||||
@@ -71,8 +71,10 @@
|
||||
if(istype(P, /obj/item/stack/cable_coil))
|
||||
if(!P.tool_start_check(user, amount=5))
|
||||
return
|
||||
if(state != 2)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start adding cables to the frame...</span>")
|
||||
if(P.use_tool(src, user, 20, 5, 50, CALLBACK(src, .proc/check_state, 2)))
|
||||
if(P.use_tool(src, user, 20, volume=50, amount=5))
|
||||
to_chat(user, "<span class='notice'>You add cables to the frame.</span>")
|
||||
state = 3
|
||||
icon_state = "3"
|
||||
@@ -90,9 +92,11 @@
|
||||
if(istype(P, /obj/item/stack/sheet/glass))
|
||||
if(!P.tool_start_check(user, amount=2))
|
||||
return
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
if(state != 3)
|
||||
return
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
|
||||
to_chat(user, "<span class='notice'>You start to put in the glass panel...</span>")
|
||||
if(P.use_tool(src, user, 20, 2, 0, CALLBACK(src, .proc/check_state, 3)))
|
||||
if(P.use_tool(src, user, 20, amount=2))
|
||||
to_chat(user, "<span class='notice'>You put in the glass panel.</span>")
|
||||
state = 4
|
||||
src.icon_state = "4"
|
||||
@@ -109,14 +113,51 @@
|
||||
if(P.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
P.play_tool_sound(src)
|
||||
to_chat(user, "<span class='notice'>You connect the monitor.</span>")
|
||||
var/obj/B = new circuit.build_path (loc, circuit)
|
||||
B.setDir(dir)
|
||||
transfer_fingerprints_to(B)
|
||||
|
||||
var/obj/machinery/new_machine = new circuit.build_path(loc)
|
||||
new_machine.setDir(dir)
|
||||
transfer_fingerprints_to(new_machine)
|
||||
|
||||
if(istype(new_machine, /obj/machinery/computer))
|
||||
var/obj/machinery/computer/new_computer = new_machine
|
||||
|
||||
// Machines will init with a set of default components.
|
||||
// Triggering handle_atom_del will make the machine realise it has lost a component_parts and then deconstruct.
|
||||
// Move to nullspace so we don't trigger handle_atom_del, then qdel.
|
||||
// Finally, replace new machine's parts with this frame's parts.
|
||||
if(new_computer.circuit)
|
||||
// Move to nullspace and delete.
|
||||
new_computer.circuit.moveToNullspace()
|
||||
QDEL_NULL(new_computer.circuit)
|
||||
for(var/old_part in new_computer.component_parts)
|
||||
var/atom/movable/movable_part = old_part
|
||||
// Move to nullspace and delete.
|
||||
movable_part.moveToNullspace()
|
||||
qdel(movable_part)
|
||||
|
||||
// Set anchor state and move the frame's parts over to the new machine.
|
||||
// Then refresh parts and call on_construction().
|
||||
new_computer.set_anchored(anchored)
|
||||
new_computer.component_parts = list()
|
||||
|
||||
circuit.forceMove(new_computer)
|
||||
new_computer.component_parts += circuit
|
||||
new_computer.circuit = circuit
|
||||
|
||||
for(var/new_part in src)
|
||||
var/atom/movable/movable_part = new_part
|
||||
movable_part.forceMove(new_computer)
|
||||
new_computer.component_parts += movable_part
|
||||
|
||||
new_computer.RefreshParts()
|
||||
new_computer.on_construction()
|
||||
|
||||
qdel(src)
|
||||
return
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/frame/computer/deconstruct(disassembled = TRUE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
if(state == 4)
|
||||
@@ -127,13 +168,12 @@
|
||||
..()
|
||||
|
||||
/obj/structure/frame/computer/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
..()
|
||||
if(!user.canUseTopic(src, BE_CLOSE, TRUE, FALSE))
|
||||
return
|
||||
|
||||
if(anchored)
|
||||
to_chat(usr, "<span class='warning'>You must unwrench [src] before rotating it!</span>")
|
||||
return TRUE
|
||||
return
|
||||
|
||||
setDir(turn(dir, -90))
|
||||
return TRUE
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
var/temp = "Inactive"
|
||||
var/scantemp_ckey
|
||||
var/scantemp_name
|
||||
var/scantemp = "Ready to Scan"
|
||||
var/scantemp = "Inactive"
|
||||
var/menu = 1 //Which menu screen to display
|
||||
var/datum/data/record/active_record = null
|
||||
var/obj/item/disk/data/diskette = null //Mostly so the geneticist can steal everything.
|
||||
@@ -132,7 +132,6 @@
|
||||
src.diskette = W
|
||||
to_chat(user, "<span class='notice'>You insert [W].</span>")
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
|
||||
src.updateUsrDialog()
|
||||
else if(W.tool_behaviour == TOOL_MULTITOOL)
|
||||
if(istype(W.buffer, clonepod_type))
|
||||
if(get_area(W.buffer) != get_area(src))
|
||||
@@ -151,311 +150,233 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/cloning/ui_interact(mob/user)
|
||||
/obj/machinery/computer/cloning/AltClick(mob/user)
|
||||
. = ..()
|
||||
EjectDisk(user)
|
||||
|
||||
updatemodules(TRUE)
|
||||
/obj/machinery/computer/cloning/proc/EjectDisk(mob/user)
|
||||
if(diskette)
|
||||
scantemp = "Disk Ejected"
|
||||
diskette.forceMove(drop_location())
|
||||
usr.put_in_active_hand(diskette)
|
||||
diskette = null
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
|
||||
|
||||
var/dat = ""
|
||||
dat += "<a href='byond://?src=[REF(src)];refresh=1'>Refresh</a>"
|
||||
/obj/machinery/computer/cloning/proc/Save(mob/user, target)
|
||||
var/datum/data/record/GRAB = null
|
||||
for(var/datum/data/record/record in records)
|
||||
if(record.fields["id"] == target)
|
||||
GRAB = record
|
||||
break
|
||||
else
|
||||
continue
|
||||
if(!GRAB || !GRAB.fields)
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
scantemp = "Failed saving to disk: Data Corruption"
|
||||
return FALSE
|
||||
if(!diskette || diskette.read_only)
|
||||
scantemp = !diskette ? "Failed saving to disk: No disk." : "Failed saving to disk: Disk refuses override attempt."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
return
|
||||
diskette.fields = GRAB.fields.Copy()
|
||||
diskette.name = "data disk - '[src.diskette.fields["name"]]'"
|
||||
scantemp = "Saved to disk successfully."
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
|
||||
/obj/machinery/computer/cloning/proc/DeleteRecord(mob/user, target)
|
||||
var/datum/data/record/GRAB = null
|
||||
for(var/datum/data/record/record in records)
|
||||
if(record.fields["id"] == target)
|
||||
GRAB = record
|
||||
break
|
||||
else
|
||||
continue
|
||||
if(!GRAB)
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
scantemp = "Cannot delete: Data Corrupted."
|
||||
return FALSE
|
||||
var/obj/item/card/id/C = usr.get_idcard(hand_first = TRUE)
|
||||
if(istype(C) || istype(C, /obj/item/pda) || istype(C, /obj/item/modular_computer/tablet))
|
||||
if(check_access(C))
|
||||
scantemp = "[GRAB.fields["name"]] => Record deleted."
|
||||
records.Remove(GRAB)
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
var/obj/item/circuitboard/computer/cloning/board = circuit
|
||||
board.records = records
|
||||
return TRUE
|
||||
scantemp = "Cannot delete: Access Denied."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
|
||||
/obj/machinery/computer/cloning/proc/Load(mob/user)
|
||||
if(!diskette || !istype(diskette.fields) || !diskette.fields["name"] || !diskette.fields)
|
||||
scantemp = "Failed loading: Load error."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
return
|
||||
for(var/datum/data/record/R in records)
|
||||
if(R.fields["key"] == diskette.fields["key"])
|
||||
scantemp = "Failed loading: Data already exists!"
|
||||
return FALSE
|
||||
var/datum/data/record/R = new(src)
|
||||
for(var/key in diskette.fields)
|
||||
R.fields[key] = diskette.fields[key]
|
||||
records += R
|
||||
scantemp = "Loaded into internal storage successfully."
|
||||
var/obj/item/circuitboard/computer/cloning/board = circuit
|
||||
board.records = records
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
|
||||
/obj/machinery/computer/cloning/proc/Clone(mob/user, target)
|
||||
var/datum/data/record/C = find_record("id", target, records)
|
||||
//Look for that player! They better be dead!
|
||||
if(C)
|
||||
var/obj/machinery/clonepod/pod = GetAvailablePod()
|
||||
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
|
||||
if(!LAZYLEN(pods))
|
||||
temp = "Error: No Clonepods detected."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
else if(!pod)
|
||||
temp = "Error: No Clonepods available."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
else if(!CONFIG_GET(flag/revival_cloning))
|
||||
temp = "Error: Unable to initiate cloning cycle."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
else if(pod.occupant)
|
||||
temp = "Warning: Cloning cycle already in progress."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["blood_type"], C.fields["mrace"], C.fields["features"], C.fields["factions"], C.fields["quirks"], C.fields["bank_account"], C.fields["traumas"]))
|
||||
temp = "Notice: [C.fields["name"]] => Cloning cycle in progress..."
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
records.Remove(C)
|
||||
else
|
||||
temp = "Error: [C.fields["name"]] => Initialisation failure."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
|
||||
else
|
||||
temp = "Failed to clone: Data corrupted."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/computer/cloning/proc/Toggle_lock(mob/user)
|
||||
if(!scanner.is_operational())
|
||||
return
|
||||
if(!scanner.locked && !scanner.occupant) //I figured out that if you're fast enough, you can lock an open pod
|
||||
return
|
||||
scanner.locked = !scanner.locked
|
||||
playsound(src, scanner.locked ? 'sound/machines/terminal_prompt_deny.ogg' : 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/computer/cloning/proc/Scan(mob/user)
|
||||
if(!scanner.is_operational() || !scanner.occupant)
|
||||
return
|
||||
scantemp = "[scantemp_name] => Scanning..."
|
||||
loading = TRUE
|
||||
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
|
||||
say("Initiating scan...")
|
||||
var/prev_locked = scanner.locked
|
||||
scanner.locked = TRUE
|
||||
addtimer(CALLBACK(src, .proc/finish_scan, scanner.occupant, prev_locked), 2 SECONDS)
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/computer/cloning/proc/Toggle_autoprocess(mob/user)
|
||||
autoprocess = !autoprocess
|
||||
if(autoprocess)
|
||||
START_PROCESSING(SSmachines, src)
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
else
|
||||
STOP_PROCESSING(SSmachines, src)
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/computer/cloning/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["useRecords"] = use_records
|
||||
var/list/records_to_send = list()
|
||||
if(use_records)
|
||||
if(scanner && HasEfficientPod() && scanner.scan_level >= AUTOCLONING_MINIMAL_LEVEL)
|
||||
if(!autoprocess)
|
||||
dat += "<a href='byond://?src=[REF(src)];task=autoprocess'>Autoclone</a>"
|
||||
else
|
||||
dat += "<a href='byond://?src=[REF(src)];task=stopautoprocess'>Stop autoclone</a>"
|
||||
else
|
||||
dat += "<span class='linkOff'>Autoclone</span>"
|
||||
dat += "<h3>Cloning Pod Status</h3>"
|
||||
dat += "<div class='statusDisplay'>[temp] </div>"
|
||||
|
||||
switch(src.menu)
|
||||
if(1)
|
||||
// Modules
|
||||
if (isnull(src.scanner) || !LAZYLEN(pods))
|
||||
dat += "<h3>Modules</h3>"
|
||||
//dat += "<a href='byond://?src=[REF(src)];relmodules=1'>Reload Modules</a>"
|
||||
if (isnull(src.scanner))
|
||||
dat += "<font class='bad'>ERROR: No Scanner detected!</font><br>"
|
||||
if (!LAZYLEN(pods))
|
||||
dat += "<font class='bad'>ERROR: No Pod detected</font><br>"
|
||||
|
||||
// Scanner
|
||||
if (!isnull(src.scanner))
|
||||
var/mob/living/scanner_occupant = get_mob_or_brainmob(scanner.occupant)
|
||||
|
||||
dat += "<h3>Scanner Functions</h3>"
|
||||
|
||||
dat += "<div class='statusDisplay'>"
|
||||
if(!scanner_occupant)
|
||||
dat += "Scanner Unoccupied"
|
||||
else if(loading)
|
||||
dat += "[scanner_occupant] => Scanning..."
|
||||
else
|
||||
if(use_records)
|
||||
if(scanner_occupant.ckey != scantemp_ckey || scanner_occupant.name != scantemp_name)
|
||||
scantemp = "Ready to Scan"
|
||||
scantemp_ckey = scanner_occupant.ckey
|
||||
scantemp_name = scanner_occupant.name
|
||||
else
|
||||
scantemp = "Ready to Clone"
|
||||
dat += "[scanner_occupant] => [scantemp]"
|
||||
dat += "</div>"
|
||||
|
||||
if(scanner_occupant)
|
||||
dat += "<a href='byond://?src=[REF(src)];scan=1'>[use_records ? "Start Scan" : "Clone"]</a>"
|
||||
dat += "<br><a href='byond://?src=[REF(src)];lock=1'>[scanner.locked ? "Unlock Scanner" : "Lock Scanner"]</a>"
|
||||
else
|
||||
dat += "<span class='linkOff'>[use_records ? "Start Scan" : "Clone"]</span>"
|
||||
if(use_records)
|
||||
// Database
|
||||
dat += "<h3>Database Functions</h3>"
|
||||
if (src.records.len && src.records.len > 0)
|
||||
dat += "<a href='byond://?src=[REF(src)];menu=2'>View Records ([src.records.len])</a><br>"
|
||||
else
|
||||
dat += "<span class='linkOff'>View Records (0)</span><br>"
|
||||
if (src.diskette)
|
||||
dat += "<a href='byond://?src=[REF(src)];disk=eject'>Eject Disk</a><br>"
|
||||
|
||||
|
||||
|
||||
if(2)
|
||||
dat += "<h3>Current records</h3>"
|
||||
dat += "<a href='byond://?src=[REF(src)];menu=1'><< Back</a><br><br>"
|
||||
data["hasAutoprocess"] = TRUE
|
||||
if(length(records))
|
||||
for(var/datum/data/record/R in records)
|
||||
dat += "<h4>[R.fields["name"]]</h4>Scan ID [R.fields["id"]] <a href='byond://?src=[REF(src)];view_rec=[R.fields["id"]]'>View Record</a>"
|
||||
if(3)
|
||||
dat += "<h3>Selected Record</h3>"
|
||||
dat += "<a href='byond://?src=[REF(src)];menu=2'><< Back</a><br>"
|
||||
|
||||
if (!src.active_record)
|
||||
dat += "<font class='bad'>Record not found.</font>"
|
||||
else
|
||||
dat += "<h4>[src.active_record.fields["name"]]</h4>"
|
||||
dat += "Scan ID [src.active_record.fields["id"]] <a href='byond://?src=[REF(src)];clone=[active_record.fields["id"]]'>Clone</a><br>"
|
||||
|
||||
var/obj/item/implant/health/H = locate(active_record.fields["imp"])
|
||||
|
||||
if ((H) && (istype(H)))
|
||||
dat += "<b>Health Implant Data:</b><br />[H.sensehealth()]<br><br />"
|
||||
var/list/record_entry = list()
|
||||
record_entry["name"] = "[R.fields["name"]]"
|
||||
record_entry["id"] = "[R.fields["id"]]"
|
||||
var/obj/item/implant/health/H = locate(R.fields["imp"])
|
||||
if(H && istype(H))
|
||||
record_entry["damages"] = H.sensehealth(TRUE)
|
||||
else
|
||||
dat += "<font class='bad'>Unable to locate Health Implant.</font><br /><br />"
|
||||
record_entry["damages"] = FALSE
|
||||
record_entry["UI"] = "[R.fields["UI"]]"
|
||||
record_entry["UE"] = "[R.fields["UE"]]"
|
||||
record_entry["blood_type"] = "[R.fields["blood_type"]]"
|
||||
records_to_send += list(record_entry)
|
||||
data["records"] = records_to_send
|
||||
else
|
||||
data["records"] = list()
|
||||
if(diskette && diskette.fields)
|
||||
var/list/disk_data = list()
|
||||
disk_data["name"] = "[diskette.fields["name"]]"
|
||||
disk_data["id"] = "[diskette.fields["id"]]"
|
||||
disk_data["UI"] = "[diskette.fields["UI"]]"
|
||||
disk_data["UE"] = "[diskette.fields["UE"]]"
|
||||
disk_data["blood_type"] = "[diskette.fields["blood_type"]]"
|
||||
data["diskData"] = disk_data
|
||||
else
|
||||
data["diskData"] = list()
|
||||
else
|
||||
data["hasAutoprocess"] = FALSE
|
||||
data["autoprocess"] = autoprocess
|
||||
var/list/lack_machine = list()
|
||||
if(isnull(src.scanner))
|
||||
lack_machine += "ERROR: No Scanner Detected!"
|
||||
if(!LAZYLEN(pods))
|
||||
lack_machine += "ERROR: No Pod Detected!"
|
||||
data["lacksMachine"] = lack_machine
|
||||
data["temp"] = temp
|
||||
var/build_temp = null
|
||||
var/mob/living/scanner_occupant = get_mob_or_brainmob(scanner?.occupant)
|
||||
if(scanner_occupant?.ckey != scantemp_ckey || scanner_occupant?.name != scantemp_name)
|
||||
if(use_records)
|
||||
build_temp = "Ready to Scan"
|
||||
scantemp_ckey = scanner_occupant?.ckey
|
||||
scantemp_name = scanner_occupant?.name
|
||||
else
|
||||
build_temp = "Ready to Clone"
|
||||
scantemp = "[scanner_occupant] => [build_temp]"
|
||||
data["scanTemp"] = scantemp
|
||||
data["scannerLocked"] = scanner?.locked
|
||||
data["hasOccupant"] = scanner?.occupant
|
||||
data["recordsLength"] = "View Records ([length(records)])"
|
||||
|
||||
dat += "<b>Unique Identifier:</b><br /><span class='highlight'>[src.active_record.fields["UI"]]</span><br>"
|
||||
dat += "<b>Structural Enzymes:</b><br /><span class='highlight'>[src.active_record.fields["SE"]]</span><br>"
|
||||
return data
|
||||
|
||||
if(diskette && diskette.fields)
|
||||
dat += "<div class='block'>"
|
||||
dat += "<h4>Inserted Disk</h4>"
|
||||
dat += "<b>Contents:</b> "
|
||||
var/list/L = list()
|
||||
if(diskette.fields["UI"])
|
||||
L += "Unique Identifier"
|
||||
if(diskette.fields["UE"] && diskette.fields["name"] && diskette.fields["blood_type"])
|
||||
L += "Unique Enzymes"
|
||||
if(diskette.fields["SE"])
|
||||
L += "Structural Enzymes"
|
||||
dat += english_list(L, "Empty", " + ", " + ")
|
||||
dat += "<br /><a href='byond://?src=[REF(src)];disk=load'>Load from Disk</a>"
|
||||
|
||||
dat += "<br /><a href='byond://?src=[REF(src)];disk=save'>Save to Disk</a>"
|
||||
dat += "</div>"
|
||||
|
||||
dat += "<font size=1><a href='byond://?src=[REF(src)];del_rec=1'>Delete Record</a></font>"
|
||||
|
||||
if(4)
|
||||
if (!src.active_record)
|
||||
src.menu = 2
|
||||
dat = "[src.temp]<br>"
|
||||
dat += "<h3>Confirm Record Deletion</h3>"
|
||||
|
||||
dat += "<b><a href='byond://?src=[REF(src)];del_rec=1'>Scan card to confirm.</a></b><br>"
|
||||
dat += "<b><a href='byond://?src=[REF(src)];menu=3'>Cancel</a></b>"
|
||||
|
||||
|
||||
var/datum/browser/popup = new(user, "cloning", "Cloning System Control")
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/computer/cloning/Topic(href, href_list)
|
||||
/obj/machinery/computer/cloning/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("toggle_autoprocess")
|
||||
Toggle_autoprocess(usr)
|
||||
if("scan")
|
||||
Scan(usr)
|
||||
if("toggle_lock")
|
||||
Toggle_lock(usr)
|
||||
if("clone")
|
||||
Clone(usr, params["target"])
|
||||
if("delrecord")
|
||||
DeleteRecord(usr, params["target"])
|
||||
if("save")
|
||||
Save(usr, params["target"])
|
||||
if("load")
|
||||
Load(usr)
|
||||
if("eject")
|
||||
EjectDisk(usr)
|
||||
|
||||
if(loading)
|
||||
/obj/machinery/computer/cloning/ui_interact(mob/user, datum/tgui/ui)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(href_list["task"])
|
||||
switch(href_list["task"])
|
||||
if("autoprocess")
|
||||
if(scanner && HasEfficientPod() && scanner.scan_level >= AUTOCLONING_MINIMAL_LEVEL)
|
||||
autoprocess = TRUE
|
||||
START_PROCESSING(SSmachines, src)
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
if("stopautoprocess")
|
||||
autoprocess = FALSE
|
||||
STOP_PROCESSING(SSmachines, src)
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
src.updateUsrDialog()
|
||||
. = TRUE
|
||||
|
||||
else if ((href_list["scan"]) && !isnull(scanner) && scanner.is_operational())
|
||||
scantemp = ""
|
||||
|
||||
loading = TRUE
|
||||
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
|
||||
say("Initiating scan...")
|
||||
var/prev_locked = scanner.locked
|
||||
scanner.locked = TRUE
|
||||
src.updateUsrDialog()
|
||||
addtimer(CALLBACK(src, .proc/finish_scan, scanner.occupant, prev_locked), 2 SECONDS)
|
||||
. = TRUE
|
||||
|
||||
//No locking an open scanner.
|
||||
else if ((href_list["lock"]) && !isnull(scanner) && scanner.is_operational())
|
||||
if ((!scanner.locked) && (scanner.occupant))
|
||||
scanner.locked = TRUE
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
else
|
||||
scanner.locked = FALSE
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
src.updateUsrDialog()
|
||||
. = TRUE
|
||||
|
||||
|
||||
else if (href_list["refresh"])
|
||||
src.updateUsrDialog()
|
||||
playsound(src, "terminal_type", 25, 0)
|
||||
. = TRUE
|
||||
|
||||
if(. || !use_records)
|
||||
return
|
||||
if(href_list["view_rec"])
|
||||
playsound(src, "terminal_type", 25, 0)
|
||||
src.active_record = find_record("id", href_list["view_rec"], records)
|
||||
if(active_record)
|
||||
if(!active_record.fields["ckey"])
|
||||
records -= active_record
|
||||
active_record = null
|
||||
src.temp = "<font class='bad'>Record Corrupt</font>"
|
||||
else
|
||||
src.menu = 3
|
||||
else
|
||||
src.temp = "Record missing."
|
||||
src.updateUsrDialog()
|
||||
. = TRUE
|
||||
|
||||
else if (href_list["del_rec"])
|
||||
if ((!src.active_record) || (src.menu < 3))
|
||||
return
|
||||
if (src.menu == 3) //If we are viewing a record, confirm deletion
|
||||
src.temp = "Delete record?"
|
||||
src.menu = 4
|
||||
src.updateUsrDialog()
|
||||
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
|
||||
|
||||
else if (src.menu == 4)
|
||||
var/obj/item/card/id/C = usr.get_active_held_item()
|
||||
if (istype(C)||istype(C, /obj/item/pda))
|
||||
if(src.check_access(C))
|
||||
src.temp = "[src.active_record.fields["name"]] => Record deleted."
|
||||
src.records.Remove(active_record)
|
||||
active_record = null
|
||||
src.updateUsrDialog()
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
src.menu = 2
|
||||
var/obj/item/circuitboard/computer/cloning/board = circuit
|
||||
board.records = records
|
||||
else
|
||||
src.temp = "<font class='bad'>Access Denied.</font>"
|
||||
src.updateUsrDialog()
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
. = TRUE
|
||||
|
||||
else if (href_list["disk"] && use_records) //Load or eject.
|
||||
switch(href_list["disk"])
|
||||
if("load")
|
||||
if (!diskette || !istype(diskette.fields) || !diskette.fields["name"] || !diskette.fields)
|
||||
src.temp = "<font class='bad'>Load error.</font>"
|
||||
src.updateUsrDialog()
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
return
|
||||
if (!src.active_record)
|
||||
src.temp = "<font class='bad'>Record error.</font>"
|
||||
src.menu = 1
|
||||
src.updateUsrDialog()
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
return
|
||||
|
||||
for(var/key in diskette.fields)
|
||||
src.active_record.fields[key] = diskette.fields[key]
|
||||
src.temp = "Load successful."
|
||||
src.updateUsrDialog()
|
||||
var/obj/item/circuitboard/computer/cloning/board = circuit
|
||||
board.records = records
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
|
||||
if("eject")
|
||||
if(src.diskette)
|
||||
src.diskette.forceMove(drop_location())
|
||||
src.diskette = null
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
|
||||
if("save")
|
||||
if(!diskette || diskette.read_only || !active_record || !active_record.fields)
|
||||
src.temp = "<font class='bad'>Save error.</font>"
|
||||
src.updateUsrDialog()
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
return
|
||||
|
||||
diskette.fields = active_record.fields.Copy()
|
||||
diskette.name = "data disk - '[src.diskette.fields["name"]]'"
|
||||
src.temp = "Save successful."
|
||||
src.updateUsrDialog()
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
. = TRUE
|
||||
|
||||
else if (href_list["clone"])
|
||||
var/datum/data/record/C = find_record("id", href_list["clone"], records)
|
||||
//Look for that player! They better be dead!
|
||||
if(C)
|
||||
var/obj/machinery/clonepod/pod = GetAvailablePod()
|
||||
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
|
||||
if(!LAZYLEN(pods))
|
||||
temp = "<font class='bad'>No Clonepods detected.</font>"
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
else if(!pod)
|
||||
temp = "<font class='bad'>No Clonepods available.</font>"
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
else if(!CONFIG_GET(flag/revival_cloning))
|
||||
temp = "<font class='bad'>Unable to initiate cloning cycle.</font>"
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
else if(pod.occupant)
|
||||
temp = "<font class='bad'>Cloning cycle already in progress.</font>"
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["blood_type"], C.fields["mrace"], C.fields["features"], C.fields["factions"], C.fields["quirks"], C.fields["bank_account"], C.fields["traumas"]))
|
||||
temp = "[C.fields["name"]] => <font class='good'>Cloning cycle in progress...</font>"
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
records.Remove(C)
|
||||
if(active_record == C)
|
||||
active_record = null
|
||||
menu = 1
|
||||
src.updateUsrDialog()
|
||||
else
|
||||
temp = "[C.fields["name"]] => <font class='bad'>Initialisation failure.</font>"
|
||||
src.updateUsrDialog()
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
|
||||
else
|
||||
temp = "<font class='bad'>Data corruption.</font>"
|
||||
src.updateUsrDialog()
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
. = TRUE
|
||||
|
||||
else if (href_list["menu"] && use_records)
|
||||
menu = text2num(href_list["menu"])
|
||||
src.updateUsrDialog()
|
||||
playsound(src, "terminal_type", 25, 0)
|
||||
. = TRUE
|
||||
updatemodules(TRUE)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "CloningConsole", "Cloning System Control")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/cloning/proc/finish_scan(mob/living/L, prev_locked)
|
||||
if(!scanner || !L)
|
||||
@@ -469,7 +390,6 @@
|
||||
|
||||
loading = FALSE
|
||||
scanner.locked = prev_locked
|
||||
src.updateUsrDialog()
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
|
||||
|
||||
@@ -568,44 +488,44 @@
|
||||
var/obj/machinery/clonepod/pod = GetAvailablePod()
|
||||
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
|
||||
if(!LAZYLEN(pods))
|
||||
temp = "<font class='bad'>No Clonepods detected.</font>"
|
||||
temp = "No Clonepods detected."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
else if(!pod)
|
||||
temp = "<font class='bad'>No Clonepods available.</font>"
|
||||
temp = "No Clonepods available."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
else if(pod.occupant)
|
||||
temp = "<font class='bad'>Cloning cycle already in progress.</font>"
|
||||
temp = "Cloning cycle already in progress."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
else
|
||||
pod.growclone(null, mob_occupant.real_name, dna.uni_identity, dna.mutation_index, null, dna.blood_type, clone_species, dna.features, mob_occupant.faction)
|
||||
temp = "[mob_occupant.real_name] => <font class='good'>Cloning data sent to pod.</font>"
|
||||
temp = "[mob_occupant.real_name] => Cloning data sent to pod."
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
|
||||
/obj/machinery/computer/cloning/proc/can_scan(datum/dna/dna, mob/living/mob_occupant, experimental = FALSE, datum/bank_account/account)
|
||||
if(!istype(dna))
|
||||
scantemp = "<font class='bad'>Unable to locate valid genetic data.</font>"
|
||||
scantemp = "Unable to locate valid genetic data."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
return
|
||||
if(!experimental)
|
||||
if(mob_occupant.suiciding || mob_occupant.hellbound)
|
||||
scantemp = "<font class='bad'>Subject's brain is not responding to scanning stimuli.</font>"
|
||||
scantemp = "Subject's brain is not responding to scanning stimuli."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
return
|
||||
if((HAS_TRAIT(mob_occupant, TRAIT_NOCLONE)) && (src.scanner.scan_level < 2))
|
||||
scantemp = "<font class='bad'>Subject no longer contains the fundamental materials required to create a living clone.</font>"
|
||||
scantemp = "Subject no longer contains the fundamental materials required to create a living clone."
|
||||
playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
|
||||
return
|
||||
if (!experimental)
|
||||
if(!mob_occupant.ckey || !mob_occupant.client)
|
||||
scantemp = "<font class='bad'>Mental interface failure.</font>"
|
||||
scantemp = "Mental interface failure."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
return
|
||||
if (find_record("ckey", mob_occupant.ckey, records))
|
||||
scantemp = "<font class='average'>Subject already in database.</font>"
|
||||
scantemp = "Subject already in database."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
return
|
||||
if(SSeconomy.full_ancap && !account)
|
||||
scantemp = "<font class='average'>Subject is either missing an ID card with a bank account on it, or does not have an account to begin with. Please ensure the ID card is on the body before attempting to scan.</font>"
|
||||
scantemp = "Subject is either missing an ID card with a bank account on it, or does not have an account to begin with. Please ensure the ID card is on the body before attempting to scan."
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
return
|
||||
return TRUE
|
||||
@@ -618,3 +538,4 @@
|
||||
icon_keyboard = "med_key"
|
||||
circuit = /obj/item/circuitboard/computer/cloning/prototype
|
||||
clonepod_type = /obj/machinery/clonepod/experimental
|
||||
use_records = FALSE //Wait, so you tell me it lacks records but you never set it as false?
|
||||
|
||||
@@ -51,6 +51,11 @@
|
||||
return FALSE
|
||||
return ACCESS_CAPTAIN in authorize_access
|
||||
|
||||
/obj/machinery/computer/communications/proc/authenticated_as_non_silicon_command(mob/user)
|
||||
if (issilicon(user))
|
||||
return FALSE
|
||||
return ACCESS_HEADS in authorize_access //Should always be the case if authorized as it usually needs head access to log in, buut lets be sure.
|
||||
|
||||
/// Are we a silicon, OR we're logged in as the captain?
|
||||
/obj/machinery/computer/communications/proc/authenticated_as_silicon_or_captain(mob/user)
|
||||
if (issilicon(user))
|
||||
@@ -97,8 +102,14 @@
|
||||
if ("answerMessage")
|
||||
if (!authenticated(usr))
|
||||
return
|
||||
var/answer_index = text2num(params["answer"])
|
||||
var/message_index = text2num(params["message"])
|
||||
var/answer_index = params["answer"]
|
||||
var/message_index = params["message"]
|
||||
|
||||
// If either of these aren't numbers, then bad voodoo.
|
||||
if(!isnum(answer_index) || !isnum(message_index))
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] provided an invalid index type when replying to a message on [src] [ADMIN_JMP(src)]. This should not happen. Please check with a maintainer and/or consult tgui logs.")
|
||||
CRASH("Non-numeric index provided when answering comms console message.")
|
||||
|
||||
if (!answer_index || !message_index || answer_index < 1 || message_index < 1)
|
||||
return
|
||||
var/datum/comm_message/message = messages[message_index]
|
||||
@@ -151,7 +162,11 @@
|
||||
if ("deleteMessage")
|
||||
if (!authenticated(usr))
|
||||
return
|
||||
var/message_index = text2num(params["message"])
|
||||
var/message_index = params["message"]
|
||||
|
||||
if(!isnum(message_index))
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] provided an invalid index type when deleting a message on [src] [ADMIN_JMP(src)]. This should not happen. Please check with a maintainer and/or consult tgui logs.")
|
||||
CRASH("Non-numeric index provided when deleting comms console message.")
|
||||
if (!message_index)
|
||||
return
|
||||
LAZYREMOVE(messages, LAZYACCESS(messages, message_index))
|
||||
@@ -160,7 +175,7 @@
|
||||
return
|
||||
make_announcement(usr)
|
||||
if ("messageAssociates")
|
||||
if (!authenticated_as_non_silicon_captain(usr))
|
||||
if (!authenticated_as_non_silicon_command(usr))
|
||||
return
|
||||
if (!COOLDOWN_FINISHED(src, important_action_cooldown))
|
||||
return
|
||||
@@ -361,9 +376,9 @@
|
||||
data["shuttleCanEvacOrFailReason"] = SSshuttle.canEvac(user, TRUE)
|
||||
|
||||
if (authenticated_as_non_silicon_captain(user))
|
||||
data["canMessageAssociates"] = TRUE
|
||||
data["canRequestNuke"] = TRUE
|
||||
|
||||
if (authenticated_as_non_silicon_command(user))
|
||||
data["canMessageAssociates"] = TRUE
|
||||
if (can_send_messages_to_other_sectors(user))
|
||||
data["canSendToSectors"] = TRUE
|
||||
|
||||
|
||||
@@ -200,6 +200,6 @@
|
||||
if(is_centcom_level(T.z) || is_away_level(T.z))
|
||||
return FALSE
|
||||
var/area/A = get_area(T)
|
||||
if(!A || A.noteleport)
|
||||
if(!A || (A.area_flags & NOTELEPORT))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -217,6 +217,8 @@
|
||||
new_machine.RefreshParts()
|
||||
|
||||
new_machine.on_construction()
|
||||
// TODO: make sleepers not shit out parts PROPERLY THIS TIME.
|
||||
new_machine.circuit.moveToNullspace()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
|
||||
@@ -409,7 +409,10 @@
|
||||
visible_message("<span class='notice'>\The [src] hums and hisses as it moves [mob_occupant.real_name] into storage.</span>")
|
||||
|
||||
// Ghost and delete the mob.
|
||||
if(!mob_occupant.get_ghost(1))
|
||||
var/mob/dead/observer/G = mob_occupant.get_ghost(TRUE)
|
||||
if(G)
|
||||
G.voluntary_ghosted = TRUE
|
||||
else
|
||||
mob_occupant.ghostize(FALSE, penalize = TRUE, voluntary = TRUE, cryo = TRUE)
|
||||
|
||||
QDEL_NULL(occupant)
|
||||
|
||||
+235
-195
@@ -1,9 +1,5 @@
|
||||
#define LIMBGROWER_MAIN_MENU 1
|
||||
#define LIMBGROWER_CATEGORY_MENU 2
|
||||
#define LIMBGROWER_CHEMICAL_MENU 3
|
||||
//use these for the menu system
|
||||
|
||||
|
||||
/// The limbgrower. Makes organd and limbs with synthflesh and chems.
|
||||
/// See [limbgrower_designs.dm] for everything we can make.
|
||||
/obj/machinery/limbgrower
|
||||
name = "limb grower"
|
||||
desc = "It grows new limbs using Synthflesh."
|
||||
@@ -15,161 +11,235 @@
|
||||
active_power_usage = 100
|
||||
circuit = /obj/item/circuitboard/machine/limbgrower
|
||||
|
||||
var/operating = FALSE
|
||||
var/disabled = FALSE
|
||||
/// The category of limbs we're browing in our UI.
|
||||
var/selected_category = "human"
|
||||
/// If we're currently printing something.
|
||||
var/busy = FALSE
|
||||
var/prod_coeff = 1
|
||||
/// How efficient our machine is. Better parts = less chemicals used and less power used. Range of 1 to 0.25.
|
||||
var/production_coefficient = 1
|
||||
/// How long it takes for us to print a limb. Affected by production_coefficient.
|
||||
var/production_speed = 3 SECONDS
|
||||
/// The design we're printing currently.
|
||||
var/datum/design/being_built
|
||||
/// Our internal techweb for limbgrower designs.
|
||||
var/datum/techweb/stored_research
|
||||
var/selected_category
|
||||
var/screen = 1
|
||||
/// All the categories of organs we can print.
|
||||
var/list/categories = list(
|
||||
"human" = /datum/species/human,
|
||||
"lizard" = /datum/species/lizard,
|
||||
"mammal" = /datum/species/mammal,
|
||||
"insect" = /datum/species/insect,
|
||||
"fly" = /datum/species/fly,
|
||||
"plasmaman" = /datum/species/plasmaman,
|
||||
"xeno" = /datum/species/xeno,
|
||||
"other" = /datum/species,
|
||||
)
|
||||
var/list/stored_species = list()
|
||||
"human",
|
||||
"lizard",
|
||||
"mammal",
|
||||
"insect",
|
||||
"fly",
|
||||
"plasmaman",
|
||||
"xeno",
|
||||
"other",
|
||||
)
|
||||
var/obj/item/disk/data/dna_disk
|
||||
|
||||
/obj/machinery/limbgrower/Initialize()
|
||||
create_reagents(100, OPENCONTAINER)
|
||||
stored_research = new /datum/techweb/specialized/autounlocking/limbgrower
|
||||
for(var/i in categories)
|
||||
var/species = categories[i]
|
||||
stored_species[i] = new species()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/plumbing/simple_demand)
|
||||
AddComponent(/datum/component/simple_rotation, ROTATION_WRENCH | ROTATION_CLOCKWISE, null, CALLBACK(src, .proc/can_be_rotated))
|
||||
|
||||
/obj/machinery/limbgrower/ui_interact(mob/user)
|
||||
/obj/machinery/limbgrower/ui_interact(mob/user, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(!is_operational())
|
||||
return
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Limbgrower", src)
|
||||
ui.open()
|
||||
|
||||
var/dat = main_win(user)
|
||||
/obj/machinery/limbgrower/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
switch(screen)
|
||||
if(LIMBGROWER_MAIN_MENU)
|
||||
dat = main_win(user)
|
||||
if(LIMBGROWER_CATEGORY_MENU)
|
||||
dat = category_win(user,selected_category)
|
||||
if(LIMBGROWER_CHEMICAL_MENU)
|
||||
dat = chemical_win(user)
|
||||
for(var/datum/reagent/reagent_id in reagents.reagent_list)
|
||||
var/list/reagent_data = list(
|
||||
reagent_name = reagent_id.name,
|
||||
reagent_amount = reagent_id.volume,
|
||||
reagent_type = reagent_id.type
|
||||
)
|
||||
data["reagents"] += list(reagent_data)
|
||||
|
||||
var/datum/browser/popup = new(user, "Limb Grower", name, 400, 500)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
data["total_reagents"] = reagents.total_volume
|
||||
data["max_reagents"] = reagents.maximum_volume
|
||||
data["busy"] = busy
|
||||
var/list/disk_data = list()
|
||||
disk_data["disk"] = dna_disk //Do i, the machine, have a disk?
|
||||
disk_data["name"] = dna_disk?.fields["name"] //Name for the human saved if there is one
|
||||
data["disk"] = disk_data
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/limbgrower/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["categories"] = list()
|
||||
|
||||
var/species_categories = categories.Copy()
|
||||
for(var/species in species_categories)
|
||||
species_categories[species] = list()
|
||||
for(var/design_id in stored_research.researched_designs)
|
||||
var/datum/design/limb_design = SSresearch.techweb_design_by_id(design_id)
|
||||
for(var/found_category in species_categories)
|
||||
if(found_category in limb_design.category)
|
||||
species_categories[found_category] += limb_design
|
||||
|
||||
for(var/category in species_categories)
|
||||
var/list/category_data = list(
|
||||
name = category,
|
||||
designs = list(),
|
||||
)
|
||||
for(var/datum/design/found_design in species_categories[category])
|
||||
var/list/all_reagents = list()
|
||||
for(var/reagent_typepath in found_design.reagents_list)
|
||||
var/datum/reagent/reagent_id = find_reagent_object_from_type(reagent_typepath)
|
||||
var/list/reagent_data = list(
|
||||
name = reagent_id.name,
|
||||
amount = (found_design.reagents_list[reagent_typepath] * production_coefficient),
|
||||
)
|
||||
all_reagents += list(reagent_data)
|
||||
|
||||
category_data["designs"] += list(list(
|
||||
parent_category = category,
|
||||
name = found_design.name,
|
||||
id = found_design.id,
|
||||
needed_reagents = all_reagents,
|
||||
))
|
||||
|
||||
data["categories"] += list(category_data)
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/limbgrower/on_deconstruction()
|
||||
for(var/obj/item/reagent_containers/glass/G in component_parts)
|
||||
reagents.trans_to(G, G.reagents.maximum_volume)
|
||||
for(var/obj/item/reagent_containers/glass/our_beaker in component_parts)
|
||||
reagents.trans_to(our_beaker, our_beaker.reagents.maximum_volume)
|
||||
..()
|
||||
|
||||
/obj/machinery/limbgrower/attackby(obj/item/O, mob/user, params)
|
||||
if(busy)
|
||||
/obj/machinery/limbgrower/attackby(obj/item/user_item, mob/living/user, params)
|
||||
if (busy)
|
||||
to_chat(user, "<span class=\"alert\">\The [src] is busy. Please wait for completion of previous operation.</span>")
|
||||
return
|
||||
|
||||
if(default_deconstruction_screwdriver(user, "limbgrower_panelopen", "limbgrower_idleoff", O))
|
||||
updateUsrDialog()
|
||||
if(default_deconstruction_screwdriver(user, "limbgrower_panelopen", "limbgrower_idleoff", user_item))
|
||||
ui_close(user)
|
||||
return
|
||||
|
||||
if(panel_open && default_deconstruction_crowbar(O))
|
||||
return
|
||||
|
||||
if(user.a_intent == INTENT_HARM) //so we can hit the machine
|
||||
if(user_item.tool_behaviour == TOOL_WRENCH && panel_open)
|
||||
return ..()
|
||||
|
||||
if(istype(O, /obj/item/disk))
|
||||
if(panel_open && default_deconstruction_crowbar(user_item))
|
||||
return
|
||||
|
||||
if(istype(user_item, /obj/item/disk))
|
||||
if(dna_disk)
|
||||
to_chat(user, "<span class='warning'>\The [src] already has a dna disk, take it out first!</span>")
|
||||
return
|
||||
else
|
||||
O.forceMove(src)
|
||||
dna_disk = O
|
||||
to_chat(user, "<span class='notice'>You insert \the [O] into \the [src].</span>")
|
||||
user_item.forceMove(src)
|
||||
dna_disk = user_item
|
||||
to_chat(user, "<span class='notice'>You insert \the [user_item] into \the [src].</span>")
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
|
||||
return
|
||||
|
||||
/obj/machinery/limbgrower/Topic(href, href_list)
|
||||
if(..())
|
||||
if(user.a_intent != INTENT_HELP)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/limbgrower/proc/can_be_rotated()
|
||||
if(panel_open)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/limbgrower/ui_act(action, list/params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if (!busy)
|
||||
if(href_list["menu"])
|
||||
screen = text2num(href_list["menu"])
|
||||
|
||||
if(href_list["category"])
|
||||
selected_category = href_list["category"]
|
||||
if (busy)
|
||||
to_chat(usr, "<span class='danger'>\The [src] is busy. Please wait for completion of previous operation.</span>")
|
||||
return
|
||||
|
||||
if(href_list["disposeI"]) //Get rid of a reagent incase you add the wrong one by mistake
|
||||
reagents.del_reagent(text2path(href_list["disposeI"]))
|
||||
switch(action)
|
||||
|
||||
if(href_list["make"])
|
||||
if("empty_reagent")
|
||||
reagents.del_reagent(text2path(params["reagent_type"]))
|
||||
. = TRUE
|
||||
|
||||
/////////////////
|
||||
//href protection
|
||||
being_built = stored_research.isDesignResearchedID(href_list["make"]) //check if it's a valid design
|
||||
if("eject_disk")
|
||||
eject_disk(usr)
|
||||
|
||||
if("make_limb")
|
||||
being_built = stored_research.isDesignResearchedID(params["design_id"])
|
||||
if(!being_built)
|
||||
return
|
||||
CRASH("[src] was passed an invalid design id!")
|
||||
|
||||
/// All the reagents we're using to make our organ.
|
||||
var/list/consumed_reagents_list = being_built.reagents_list.Copy()
|
||||
/// The amount of power we're going to use, based on how much reagent we use.
|
||||
var/power = 0
|
||||
|
||||
var/synth_cost = being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff
|
||||
var/power = max(2000, synth_cost/5)
|
||||
for(var/reagent_id in consumed_reagents_list)
|
||||
consumed_reagents_list[reagent_id] *= production_coefficient
|
||||
if(!reagents.has_reagent(reagent_id, consumed_reagents_list[reagent_id]))
|
||||
audible_message("<span class='notice'>\The [src] buzzes.</span>")
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE)
|
||||
return
|
||||
|
||||
if(reagents.has_reagent(/datum/reagent/medicine/synthflesh, being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff))
|
||||
busy = TRUE
|
||||
use_power(power)
|
||||
flick("limbgrower_fill",src)
|
||||
icon_state = "limbgrower_idleon"
|
||||
addtimer(CALLBACK(src, .proc/build_item),32*prod_coeff)
|
||||
power = max(2000, (power + consumed_reagents_list[reagent_id]))
|
||||
|
||||
if(href_list["dna_disk"])
|
||||
var/mob/living/carbon/user = usr
|
||||
if(istype(user))
|
||||
if(!dna_disk)
|
||||
var/obj/item/disk/diskette = user.get_active_held_item()
|
||||
if(istype(diskette))
|
||||
diskette.forceMove(src)
|
||||
dna_disk = diskette
|
||||
to_chat(user, "<span class='notice'>You insert \the [diskette] into \the [src].</span>")
|
||||
else
|
||||
dna_disk.forceMove(src.loc)
|
||||
user.put_in_active_hand(dna_disk)
|
||||
to_chat(user, "<span class='notice'>You remove \the [dna_disk] from \the [src].</span>")
|
||||
dna_disk = null
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You are unable to grasp \the [dna_disk] disk from \the [src].</span>")
|
||||
else
|
||||
to_chat(usr, "<span class=\"alert\">\The [src] is busy. Please wait for completion of previous operation.</span>")
|
||||
busy = TRUE
|
||||
use_power(power)
|
||||
flick("limbgrower_fill",src)
|
||||
icon_state = "limbgrower_idleon"
|
||||
selected_category = params["active_tab"]
|
||||
addtimer(CALLBACK(src, .proc/build_item, consumed_reagents_list), production_speed * production_coefficient)
|
||||
. = TRUE
|
||||
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/limbgrower/proc/build_item()
|
||||
if(reagents.has_reagent(/datum/reagent/medicine/synthflesh, being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff)) //sanity check, if this happens we are in big trouble
|
||||
reagents.remove_reagent(/datum/reagent/medicine/synthflesh, being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff)
|
||||
var/buildpath = being_built.build_path
|
||||
if(ispath(buildpath, /obj/item/bodypart)) //This feels like spaghetti code, but i need to initiliaze a limb somehow
|
||||
build_limb(buildpath)
|
||||
else if(ispath(buildpath, /obj/item/organ/genital)) //genitals are uhh... customizable
|
||||
build_genital(buildpath)
|
||||
else
|
||||
//Just build whatever it is
|
||||
new buildpath(loc)
|
||||
else
|
||||
src.visible_message("<span class=\"error\"> Something went very wrong and there isnt enough synthflesh anymore!</span>")
|
||||
busy = FALSE
|
||||
flick("limbgrower_unfill",src)
|
||||
icon_state = "limbgrower_idleoff"
|
||||
updateUsrDialog()
|
||||
/*
|
||||
* The process of beginning to build a limb or organ.
|
||||
* Goes through and sanity checks that we actually have enough reagent to build our item.
|
||||
* Then, remove those reagents from our reagents datum.
|
||||
*
|
||||
* After the reagents are handled, we can proceede with making the limb or organ. (Limbs are handled in a separate proc)
|
||||
*
|
||||
* modified_consumed_reagents_list - the list of reagents we will consume on build, modified by the production coefficient.
|
||||
*/
|
||||
/obj/machinery/limbgrower/proc/build_item(list/modified_consumed_reagents_list)
|
||||
for(var/reagent_id in modified_consumed_reagents_list)
|
||||
if(!reagents.has_reagent(reagent_id, modified_consumed_reagents_list[reagent_id]))
|
||||
audible_message("<span class='notice'>\The [src] buzzes.</span>")
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE)
|
||||
break
|
||||
|
||||
/obj/machinery/limbgrower/proc/build_limb(buildpath)
|
||||
reagents.remove_reagent(reagent_id, modified_consumed_reagents_list[reagent_id])
|
||||
|
||||
var/built_typepath = being_built.build_path
|
||||
// If we have a bodypart, we need to initialize the limb on its own. Otherwise we can build it here.
|
||||
if(ispath(built_typepath, /obj/item/bodypart))
|
||||
build_limb(built_typepath)
|
||||
else if(ispath(built_typepath, /obj/item/organ/genital)) //genitals are uhh... customizable
|
||||
build_genital(built_typepath)
|
||||
else
|
||||
new built_typepath(loc)
|
||||
|
||||
busy = FALSE
|
||||
flick("limbgrower_unfill", src)
|
||||
icon_state = "limbgrower_idleoff"
|
||||
|
||||
/*
|
||||
* The process of putting together a limb.
|
||||
* This is called from after we remove the reagents, so this proc is just initializing the limb type.
|
||||
*
|
||||
* This proc handles skin / mutant color, greyscaling, names and descriptions, and various other limb creation steps.
|
||||
*
|
||||
* built_typepath - the path of the bodypart we're building.
|
||||
*/
|
||||
/obj/machinery/limbgrower/proc/build_limb(built_typepath)
|
||||
//i need to create a body part manually using a set icon (otherwise it doesnt appear)
|
||||
var/obj/item/bodypart/limb
|
||||
var/datum/species/selected = stored_species[selected_category]
|
||||
limb = new buildpath(loc)
|
||||
var/datum/species/selected = GLOB.species_datums[selected_category]
|
||||
limb = new built_typepath(loc)
|
||||
limb.base_bp_icon = selected.icon_limbs || DEFAULT_BODYPART_ICON_ORGANIC
|
||||
limb.species_id = selected.limbs_id
|
||||
limb.color_src = (MUTCOLORS in selected.species_traits ? MUTCOLORS : (selected.use_skintones ? SKINTONE : FALSE))
|
||||
@@ -178,6 +248,7 @@
|
||||
limb.update_icon_dropped()
|
||||
limb.name = "\improper synthetic [lowertext(selected.name)] [limb.name]"
|
||||
limb.desc = "A synthetic [selected_category] limb that will morph on its first use in surgery. This one is for the [parse_zone(limb.body_zone)]."
|
||||
limb.forcereplace = TRUE
|
||||
for(var/obj/item/bodypart/BP in limb)
|
||||
BP.base_bp_icon = selected.icon_limbs || DEFAULT_BODYPART_ICON_ORGANIC
|
||||
BP.species_id = selected.limbs_id
|
||||
@@ -188,135 +259,103 @@
|
||||
BP.name = "\improper synthetic [lowertext(selected.name)] [limb.name]"
|
||||
BP.desc = "A synthetic [selected_category] limb that will morph on its first use in surgery. This one is for the [parse_zone(limb.body_zone)]."
|
||||
|
||||
/obj/machinery/limbgrower/proc/build_genital(buildpath)
|
||||
/*
|
||||
* Builds genitals, modifies to be the same
|
||||
* as the person's cloning data on the data disk
|
||||
*/
|
||||
/obj/machinery/limbgrower/proc/build_genital(built_typepath)
|
||||
//i needed to create a way to customize gene tools using dna
|
||||
var/list/features = dna_disk?.fields["features"]
|
||||
if(length(features))
|
||||
switch(buildpath)
|
||||
switch(built_typepath)
|
||||
if(/obj/item/organ/genital/penis)
|
||||
var/obj/item/organ/genital/penis/penis = new(loc)
|
||||
if(features["has_cock"])
|
||||
penis.shape = features["cock_shape"]
|
||||
penis.length = features["cock_shape"]
|
||||
penis.diameter_ratio = features["cock_diameter_ratio"]
|
||||
penis.color = sanitize_hexcolor(features["cock_color"], 6)
|
||||
penis.update_icon()
|
||||
penis.color = sanitize_hexcolor(features["cock_color"], 6, TRUE)
|
||||
penis.update()
|
||||
if(/obj/item/organ/genital/testicles)
|
||||
var/obj/item/organ/genital/testicles/balls = new(loc)
|
||||
if(features["has_balls"])
|
||||
balls.color = sanitize_hexcolor(features["balls_color"], 6)
|
||||
balls.color = sanitize_hexcolor(features["balls_color"], 6, TRUE)
|
||||
balls.shape = features["balls_shape"]
|
||||
balls.size = features["balls_size"]
|
||||
balls.fluid_rate = features["balls_cum_rate"]
|
||||
balls.fluid_mult = features["balls_cum_mult"]
|
||||
balls.fluid_efficiency = features["balls_efficiency"]
|
||||
balls.update()
|
||||
if(/obj/item/organ/genital/vagina)
|
||||
var/obj/item/organ/genital/vagina/vegana = new(loc)
|
||||
if(features["has_vagina"])
|
||||
vegana.color = sanitize_hexcolor(features["vag_color"], 6)
|
||||
if(features["has_vag"])
|
||||
vegana.color = sanitize_hexcolor(features["vag_color"], 6, TRUE)
|
||||
vegana.shape = features["vag_shape"]
|
||||
vegana.update()
|
||||
if(/obj/item/organ/genital/breasts)
|
||||
var/obj/item/organ/genital/breasts/boobs = new(loc)
|
||||
if(features["has_breasts"])
|
||||
boobs.color = sanitize_hexcolor(features["breasts_color"], 6)
|
||||
boobs.color = sanitize_hexcolor(features["breasts_color"], 6, TRUE)
|
||||
boobs.size = features["breasts_size"]
|
||||
boobs.shape = features["breasts_shape"]
|
||||
if(!features["breasts_producing"])
|
||||
boobs.genital_flags &= ~(GENITAL_FUID_PRODUCTION|CAN_CLIMAX_WITH|CAN_MASTURBATE_WITH)
|
||||
boobs.update()
|
||||
else
|
||||
new buildpath(loc)
|
||||
new built_typepath(loc)
|
||||
else
|
||||
new buildpath(loc)
|
||||
new built_typepath(loc)
|
||||
|
||||
/obj/machinery/limbgrower/RefreshParts()
|
||||
reagents.maximum_volume = 0
|
||||
for(var/obj/item/reagent_containers/glass/G in component_parts)
|
||||
reagents.maximum_volume += G.volume
|
||||
G.reagents.trans_to(src, G.reagents.total_volume)
|
||||
var/T=1.2
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
T -= M.rating*0.2
|
||||
prod_coeff = min(1,max(0,T)) // Coeff going 1 -> 0,8 -> 0,6 -> 0,4
|
||||
for(var/obj/item/reagent_containers/glass/our_beaker in component_parts)
|
||||
reagents.maximum_volume += our_beaker.volume
|
||||
our_beaker.reagents.trans_to(src, our_beaker.reagents.total_volume)
|
||||
production_coefficient = 1.2
|
||||
for(var/obj/item/stock_parts/manipulator/our_manipulator in component_parts)
|
||||
production_coefficient -= our_manipulator.rating * 0.2
|
||||
production_coefficient = clamp(production_coefficient, 0, 1) // coefficient goes from 1 -> 0.8 -> 0.6 -> 0.4
|
||||
|
||||
/obj/machinery/limbgrower/examine(mob/user)
|
||||
. = ..()
|
||||
if(!panel_open)
|
||||
. += "<span class='notice'>It looks like as if the panel were open you could rotate it with a <b>wrench</b>.</span>"
|
||||
else
|
||||
. += "<span class='notice'>The panel is open.</span>"
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
. += "<span class='notice'>The status display reads: Storing up to <b>[reagents.maximum_volume]u</b> of synthflesh.<br>Synthflesh consumption at <b>[prod_coeff*100]%</b>.<span>"
|
||||
. += "<span class='notice'>The status display reads: Storing up to <b>[reagents.maximum_volume]u</b> of reagents.<br>Reagent consumption rate at <b>[production_coefficient * 100]%</b>.</span>"
|
||||
|
||||
/obj/machinery/limbgrower/proc/main_win(mob/user)
|
||||
var/dat = "<div class='statusDisplay'><h3>[src] Menu:</h3><br>"
|
||||
dat += "<A href='?src=[REF(src)];dna_disk=1'>[dna_disk ? "Remove" : "Insert"] cloning data disk</A>"
|
||||
dat += "<hr>"
|
||||
dat += "<A href='?src=[REF(src)];menu=[LIMBGROWER_CHEMICAL_MENU]'>Chemical Storage</A>"
|
||||
dat += materials_printout()
|
||||
dat += "<table style='width:100%' align='center'><tr>"
|
||||
|
||||
for(var/C in categories)
|
||||
dat += "<td><A href='?src=[REF(src)];category=[C];menu=[LIMBGROWER_CATEGORY_MENU]'>[C]</A></td>"
|
||||
dat += "</tr><tr>"
|
||||
//one category per line
|
||||
|
||||
dat += "</tr></table></div>"
|
||||
return dat
|
||||
|
||||
/obj/machinery/limbgrower/proc/category_win(mob/user,selected_category)
|
||||
var/dat = "<A href='?src=[REF(src)];menu=[LIMBGROWER_MAIN_MENU]'>Return to main menu</A>"
|
||||
dat += "<div class='statusDisplay'><h3>Browsing [selected_category]:</h3><br>"
|
||||
dat += materials_printout()
|
||||
|
||||
for(var/v in stored_research.researched_designs)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(v)
|
||||
if(!(selected_category in D.category))
|
||||
continue
|
||||
if(disabled || !can_build(D))
|
||||
dat += "<span class='linkOff'>[D.name]</span>"
|
||||
else
|
||||
dat += "<a href='?src=[REF(src)];make=[D.id];multiplier=1'>[D.name]</a>"
|
||||
dat += "[get_design_cost(D)]<br>"
|
||||
|
||||
dat += "</div>"
|
||||
return dat
|
||||
|
||||
|
||||
/obj/machinery/limbgrower/proc/chemical_win(mob/user)
|
||||
var/dat = "<A href='?src=[REF(src)];menu=[LIMBGROWER_MAIN_MENU]'>Return to main menu</A>"
|
||||
dat += "<div class='statusDisplay'><h3>Browsing Chemical Storage:</h3><br>"
|
||||
dat += materials_printout()
|
||||
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
dat += "[R.name]: [R.volume]"
|
||||
dat += "<A href='?src=[REF(src)];disposeI=[R]'>Purge</A><BR>"
|
||||
|
||||
dat += "</div>"
|
||||
return dat
|
||||
|
||||
/obj/machinery/limbgrower/proc/materials_printout()
|
||||
var/dat = "<b>Total amount:></b> [reagents.total_volume] / [reagents.maximum_volume] cm<sup>3</sup><br>"
|
||||
return dat
|
||||
|
||||
/obj/machinery/limbgrower/proc/can_build(datum/design/D)
|
||||
return (reagents.has_reagent(/datum/reagent/medicine/synthflesh, D.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff)) //Return whether the machine has enough synthflesh to produce the design
|
||||
|
||||
/obj/machinery/limbgrower/proc/get_design_cost(datum/design/D)
|
||||
var/dat
|
||||
if(D.reagents_list[/datum/reagent/medicine/synthflesh])
|
||||
dat += "[D.reagents_list[/datum/reagent/medicine/synthflesh] * prod_coeff] Synthetic flesh "
|
||||
return dat
|
||||
/*
|
||||
* Checks our reagent list to see if a design can be built.
|
||||
*
|
||||
* limb_design - the design we're checking for buildability.
|
||||
*
|
||||
* returns TRUE if we have enough reagent to build it. Returns FALSE if we do not.
|
||||
*/
|
||||
/obj/machinery/limbgrower/proc/can_build(datum/design/limb_design)
|
||||
for(var/datum/reagent/reagent_id in limb_design.reagents_list)
|
||||
if(!reagents.has_reagent(reagent_id, limb_design.reagents_list[reagent_id] * production_coefficient))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/// Emagging a limbgrower allows you to build synthetic armblades.
|
||||
/obj/machinery/limbgrower/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(obj_flags & EMAGGED)
|
||||
return
|
||||
for(var/id in SSresearch.techweb_designs)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(id)
|
||||
if((D.build_type & LIMBGROWER) && ("emagged" in D.category))
|
||||
stored_research.add_design(D)
|
||||
for(var/design_id in SSresearch.techweb_designs)
|
||||
var/datum/design/found_design = SSresearch.techweb_design_by_id(design_id)
|
||||
if((found_design.build_type & LIMBGROWER) && ("emagged" in found_design.category))
|
||||
stored_research.add_design(found_design)
|
||||
to_chat(user, "<span class='warning'>A warning flashes onto the screen, stating that safety overrides have been deactivated!</span>")
|
||||
obj_flags |= EMAGGED
|
||||
return TRUE
|
||||
update_static_data(user)
|
||||
|
||||
/obj/machinery/limbgrower/AltClick(mob/living/user)
|
||||
. = ..()
|
||||
eject_disk(user)
|
||||
|
||||
/obj/machinery/limbgrower/proc/eject_disk(mob/user)
|
||||
if(istype(user) && user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
if(busy)
|
||||
to_chat(user, "<span class=\"alert\">\The [src] is busy. Please wait for completion of previous operation.</span>")
|
||||
@@ -325,6 +364,7 @@
|
||||
dna_disk.forceMove(src.loc)
|
||||
user.put_in_active_hand(dna_disk)
|
||||
to_chat(user, "<span class='notice'>You remove \the [dna_disk] from \the [src].</span>")
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
|
||||
dna_disk = null
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src] has doesn't have a disk on it!")
|
||||
|
||||
@@ -21,6 +21,7 @@ Buildable meters
|
||||
level = 2
|
||||
var/piping_layer = PIPING_LAYER_DEFAULT
|
||||
var/RPD_type
|
||||
var/disposable = TRUE
|
||||
|
||||
/obj/item/pipe/directional
|
||||
RPD_type = PIPE_UNARY
|
||||
@@ -236,3 +237,22 @@ Buildable meters
|
||||
/obj/item/pipe_meter/proc/setAttachLayer(new_layer = PIPING_LAYER_DEFAULT)
|
||||
piping_layer = new_layer
|
||||
PIPING_LAYER_DOUBLE_SHIFT(src, piping_layer)
|
||||
|
||||
/obj/item/pipe/bluespace
|
||||
pipe_type = /obj/machinery/atmospherics/pipe/bluespace
|
||||
var/bluespace_network_name = "default"
|
||||
icon_state = "bluespace"
|
||||
disposable = FALSE
|
||||
|
||||
/obj/item/pipe/bluespace/attack_self(mob/user)
|
||||
var/new_name = input(user, "Enter identifier for bluespace pipe network", "bluespace pipe", bluespace_network_name) as text|null
|
||||
if(!isnull(new_name))
|
||||
bluespace_network_name = new_name
|
||||
|
||||
/obj/item/pipe/bluespace/make_from_existing(obj/machinery/atmospherics/pipe/bluespace/make_from)
|
||||
bluespace_network_name = make_from.bluespace_network_name
|
||||
return ..()
|
||||
|
||||
/obj/item/pipe/bluespace/build_pipe(obj/machinery/atmospherics/pipe/bluespace/A)
|
||||
A.bluespace_network_name = bluespace_network_name
|
||||
return ..()
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
if (. & EMP_PROTECT_SELF)
|
||||
return
|
||||
if(get_charge())
|
||||
use_power(cell.charge*severity/100)
|
||||
use_power((cell.charge/3)*(severity*0.005))
|
||||
take_damage(severity/3, BURN, "energy", 1)
|
||||
mecha_log_message("EMP detected", color="red")
|
||||
|
||||
|
||||
@@ -375,12 +375,14 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list(
|
||||
. = TRUE
|
||||
|
||||
if((mode & DESTROY_MODE) && istype(A, /obj/item/pipe) || istype(A, /obj/structure/disposalconstruct) || istype(A, /obj/structure/c_transit_tube) || istype(A, /obj/structure/c_transit_tube_pod) || istype(A, /obj/item/pipe_meter))
|
||||
to_chat(user, "<span class='notice'>You start destroying a pipe...</span>")
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
|
||||
if(do_after(user, destroy_speed, target = A))
|
||||
activate()
|
||||
qdel(A)
|
||||
return
|
||||
var/obj/item/pipe/P = A
|
||||
if(!istype(P) || P.disposable)
|
||||
to_chat(user, "<span class='notice'>You start destroying a pipe...</span>")
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
|
||||
if(do_after(user, destroy_speed, target = A))
|
||||
activate()
|
||||
qdel(A)
|
||||
return
|
||||
|
||||
if((mode & PAINT_MODE))
|
||||
if(istype(A, /obj/machinery/atmospherics/pipe) && !istype(A, /obj/machinery/atmospherics/pipe/layer_manifold))
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
to_chat(user, "<span class='notice'>You need to get closer!</span>")
|
||||
return
|
||||
if(use_paint(user) && isturf(F))
|
||||
F.AddElement(/datum/element/decal, 'icons/turf/decals.dmi', stored_decal_total, turn(stored_dir, -dir2angle(F.dir)), CLEAN_STRONG, color, null, null, alpha)
|
||||
F.AddElement(/datum/element/decal, 'icons/turf/decals.dmi', stored_decal_total, stored_dir, CLEAN_STRONG, color, null, null, alpha)
|
||||
|
||||
/obj/item/airlock_painter/decal/attack_self(mob/user)
|
||||
if((ink) && (ink.charges >= 1))
|
||||
@@ -180,6 +180,11 @@
|
||||
stored_decal_total = "[stored_decal][yellow_fix][stored_color]"
|
||||
return
|
||||
|
||||
/obj/item/airlock_painter/decal/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/spritesheet/decals)
|
||||
)
|
||||
|
||||
/obj/item/airlock_painter/decal/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
@@ -189,6 +194,7 @@
|
||||
/obj/item/airlock_painter/decal/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["decal_direction"] = stored_dir
|
||||
data["decal_dir_text"] = dir2text(stored_dir)
|
||||
data["decal_color"] = stored_color
|
||||
data["decal_style"] = stored_decal
|
||||
data["decal_list"] = list()
|
||||
|
||||
@@ -75,18 +75,3 @@
|
||||
desc = "A chromosome that reduces action based mutation cooldowns by by 50%."
|
||||
icon_state = "energy"
|
||||
energy_coeff = 0.5
|
||||
|
||||
/obj/item/chromosome/reinforcer
|
||||
name = "reinforcement chromosome"
|
||||
desc = "A chromosome that renders mutations immune to mutadone."
|
||||
icon_state = "reinforcer"
|
||||
weight = 3
|
||||
|
||||
/obj/item/chromosome/reinforcer/can_apply(datum/mutation/human/HM)
|
||||
if(!HM || !(HM.can_chromosome == CHROMOSOME_NONE))
|
||||
return FALSE
|
||||
return !HM.mutadone_proof
|
||||
|
||||
/obj/item/chromosome/reinforcer/apply(datum/mutation/human/HM)
|
||||
HM.mutadone_proof = TRUE
|
||||
..()
|
||||
|
||||
@@ -443,7 +443,7 @@
|
||||
// Check area validity.
|
||||
// Reject space, player-created areas, and non-station z-levels.
|
||||
var/area/A = get_base_area(target)
|
||||
if(!A || (!is_station_level(A.z)) || !A.valid_territory)
|
||||
if(!A || (!is_station_level(A.z)) || !(A.area_flags & VALID_TERRITORY))
|
||||
to_chat(user, "<span class='warning'>[A] is unsuitable for tagging.</span>")
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -69,8 +69,7 @@ effective or pretty fucking useless.
|
||||
*/
|
||||
|
||||
/obj/item/healthanalyzer/rad_laser
|
||||
custom_materials = list(/datum/material/iron=400)
|
||||
var/irradiate = 1
|
||||
var/irradiate = TRUE
|
||||
var/intensity = 10 // how much damage the radiation does
|
||||
var/wavelength = 10 // time it takes for the radiation to kick in, in seconds
|
||||
var/used = 0 // is it cooling down?
|
||||
@@ -92,16 +91,16 @@ effective or pretty fucking useless.
|
||||
addtimer(VARSET_CALLBACK(src, used, FALSE), cooldown)
|
||||
addtimer(VARSET_CALLBACK(src, icon_state, "health"), cooldown)
|
||||
to_chat(user, "<span class='warning'>Successfully irradiated [M].</span>")
|
||||
addtimer(CALLBACK(src, .proc/radiation_aftereffect, M), (wavelength+(intensity*4))*5)
|
||||
addtimer(CALLBACK(src, .proc/radiation_aftereffect, M, intensity), (wavelength+(intensity*4))*5)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The radioactive microlaser is still recharging.</span>")
|
||||
|
||||
/obj/item/healthanalyzer/rad_laser/proc/radiation_aftereffect(mob/living/M)
|
||||
if(QDELETED(M))
|
||||
/obj/item/healthanalyzer/rad_laser/proc/radiation_aftereffect(mob/living/M, passed_intensity)
|
||||
if(QDELETED(M) || !ishuman(M) || HAS_TRAIT(M, TRAIT_RADIMMUNE))
|
||||
return
|
||||
if(intensity >= 5)
|
||||
M.apply_effect(round(intensity/0.075), EFFECT_UNCONSCIOUS)
|
||||
M.rad_act(intensity*10)
|
||||
if(passed_intensity >= 5)
|
||||
M.apply_effect(round(passed_intensity/0.075), EFFECT_UNCONSCIOUS) //to save you some math, this is a round(intensity * (4/3)) second long knockout
|
||||
M.rad_act(passed_intensity*10)
|
||||
|
||||
/obj/item/healthanalyzer/rad_laser/proc/get_cooldown()
|
||||
return round(max(10, (stealth*30 + intensity*5 - wavelength/4)))
|
||||
|
||||
@@ -210,8 +210,7 @@
|
||||
target.apply_effect(EFFECT_STUTTER, stunforce)
|
||||
SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK)
|
||||
if(user)
|
||||
target.lastattacker = user.real_name
|
||||
target.lastattackerckey = user.ckey
|
||||
target.set_last_attacker(user)
|
||||
target.visible_message("<span class='danger'>[user] has shocked [target] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has shocked you with [src]!</span>")
|
||||
log_combat(user, target, "stunned with an electrostaff")
|
||||
@@ -237,8 +236,7 @@
|
||||
target.adjustFireLoss(lethal_force) //good against ointment spam
|
||||
SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK)
|
||||
if(user)
|
||||
target.lastattacker = user.real_name
|
||||
target.lastattackerckey = user.ckey
|
||||
target.set_last_attacker(user)
|
||||
target.visible_message("<span class='danger'>[user] has seared [target] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has seared you with [src]!</span>")
|
||||
log_combat(user, target, "burned with an electrostaff")
|
||||
|
||||
@@ -312,7 +312,7 @@
|
||||
trap_damage = 0
|
||||
item_flags = DROPDEL
|
||||
flags_1 = NONE
|
||||
breakouttime = 50
|
||||
breakouttime = 25
|
||||
|
||||
/obj/item/restraints/legcuffs/beartrap/energy/New()
|
||||
..()
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/datum/deathrattle_group
|
||||
var/name
|
||||
var/list/datum/weakref/implant_refs = list()
|
||||
|
||||
/datum/deathrattle_group/New()
|
||||
// Give the group a unique name for debugging, and possible future
|
||||
// use for making custom linked groups.
|
||||
name = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]"
|
||||
|
||||
/datum/deathrattle_group/proc/rattle(obj/item/implant/deathrattle/origin, mob/living/owner)
|
||||
var/name = owner.mind ? owner.mind.name : owner.real_name
|
||||
var/area = get_area_name(get_turf(owner))
|
||||
|
||||
for(var/r in implant_refs)
|
||||
var/datum/weakref/R = r
|
||||
|
||||
var/obj/item/implant/deathrattle/implant = R.resolve()
|
||||
if(!implant || implant == origin)
|
||||
continue
|
||||
|
||||
// Not all the implants may be actually implanted in people.
|
||||
if(!implant.imp_in)
|
||||
continue
|
||||
|
||||
// Deliberately the same message framing as nanite message + ghost deathrattle
|
||||
var/mob/living/recipient = implant.imp_in
|
||||
to_chat(recipient, "<i>You hear a strange, robotic voice in your head...</i> \"<span class='robot'><b>[name]</b> has died at <b>[area]</b>.</span>\"")
|
||||
SEND_SOUND(recipient, pick(
|
||||
'sound/items/knell1.ogg',
|
||||
'sound/items/knell2.ogg',
|
||||
'sound/items/knell3.ogg',
|
||||
'sound/items/knell4.ogg',
|
||||
))
|
||||
|
||||
/datum/deathrattle_group/proc/register(obj/item/implant/deathrattle/implant)
|
||||
implant.group = src
|
||||
implant_refs += WEAKREF(implant)
|
||||
|
||||
|
||||
/obj/item/implant/deathrattle
|
||||
name = "deathrattle implant"
|
||||
desc = "Hope no one else dies, prepare for when they do."
|
||||
|
||||
activated = FALSE
|
||||
|
||||
var/datum/deathrattle_group/group = null
|
||||
|
||||
/obj/item/implant/deathrattle/Destroy()
|
||||
group = null
|
||||
return ..()
|
||||
|
||||
/obj/item/implant/deathrattle/can_be_implanted_in(mob/living/target)
|
||||
// Can be implanted in anything that's a mob. Syndicate cyborgs, talking fish, humans...
|
||||
return TRUE
|
||||
|
||||
/obj/item/implant/deathrattle/proc/on_predeath(datum/source, gibbed)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(group)
|
||||
group.rattle(origin = src, owner = source)
|
||||
|
||||
/obj/item/implant/deathrattle/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
RegisterSignal(target, COMSIG_LIVING_PREDEATH, .proc/on_predeath)
|
||||
|
||||
if(!group)
|
||||
to_chat(target, "<i>You hear a strange, robotic voice in your head...</i> \"<span class='robot'>Warning: No other linked implants detected.</span>\"")
|
||||
|
||||
|
||||
/obj/item/implantcase/deathrattle
|
||||
name = "implant case - 'Deathrattle'"
|
||||
desc = "A glass case containing a deathrattle implant."
|
||||
imp_type = /obj/item/implant/deathrattle
|
||||
@@ -139,14 +139,25 @@
|
||||
name = "health implant"
|
||||
activated = 0
|
||||
var/healthstring = ""
|
||||
var/list/raw_data = list()
|
||||
|
||||
/obj/item/implant/health/proc/sensehealth()
|
||||
/obj/item/implant/health/proc/sensehealth(get_list = FALSE)
|
||||
if (!imp_in)
|
||||
return "ERROR"
|
||||
else
|
||||
if(isliving(imp_in))
|
||||
var/mob/living/L = imp_in
|
||||
healthstring = "<small>Oxygen Deprivation Damage => [round(L.getOxyLoss())]<br />Fire Damage => [round(L.getFireLoss())]<br />Toxin Damage => [round(L.getToxLoss())]<br />Brute Force Damage => [round(L.getBruteLoss())]</small>"
|
||||
if (!healthstring)
|
||||
raw_data = list() //Reset list
|
||||
raw_data["oxy"] = list("[round(L.getOxyLoss())]") //Suffocation
|
||||
raw_data["burn"] = list("[round(L.getFireLoss())]") //Burn
|
||||
raw_data["tox"] = list("[round(L.getToxLoss())]") //Tox
|
||||
raw_data["brute"] = list("[round(L.getBruteLoss())]") //Brute
|
||||
if(!healthstring) //I have no idea who made it go this order but okay.
|
||||
healthstring = "ERROR"
|
||||
return healthstring
|
||||
if(!length(raw_data))
|
||||
raw_data = list("ERROR")
|
||||
if(!get_list)
|
||||
return healthstring
|
||||
else
|
||||
return raw_data
|
||||
|
||||
@@ -271,11 +271,14 @@
|
||||
var/force_on // Damage when on - not stunning
|
||||
var/force_off // Damage when off - not stunning
|
||||
var/weight_class_on // What is the new size class when turned on
|
||||
var/sword_point = TRUE
|
||||
|
||||
wound_bonus = 15
|
||||
|
||||
/obj/item/melee/classic_baton/Initialize()
|
||||
. = ..()
|
||||
if(sword_point)
|
||||
AddElement(/datum/element/sword_point)
|
||||
|
||||
// Description for trying to stun when still on cooldown.
|
||||
/obj/item/melee/classic_baton/proc/get_wait_description()
|
||||
@@ -402,6 +405,8 @@
|
||||
weight_class_on = WEIGHT_CLASS_BULKY
|
||||
total_mass = TOTAL_MASS_NORMAL_ITEM
|
||||
bare_wound_bonus = 5
|
||||
sword_point = FALSE
|
||||
var/silent = FALSE
|
||||
|
||||
/obj/item/melee/classic_baton/telescopic/suicide_act(mob/user)
|
||||
var/mob/living/carbon/human/H = user
|
||||
@@ -431,6 +436,9 @@
|
||||
w_class = weight_class_on
|
||||
force = force_on
|
||||
attack_verb = list("smacked", "struck", "cracked", "beaten")
|
||||
AddElement(/datum/element/sword_point)
|
||||
if(!silent)
|
||||
user?.visible_message("<span class='warning'>[user] extends [src] with a flick of their wrist!</span>")
|
||||
else
|
||||
to_chat(user, desc["local_off"])
|
||||
icon_state = off_icon_state
|
||||
@@ -439,6 +447,9 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
force = force_off
|
||||
attack_verb = list("hit", "poked")
|
||||
RemoveElement(/datum/element/sword_point)
|
||||
if(!silent)
|
||||
user?.visible_message("<span class='warning'>[user] collapses [src] back down!</span>")
|
||||
playsound(src.loc, on_sound, 50, 1)
|
||||
add_fingerprint(user)
|
||||
|
||||
@@ -465,6 +476,7 @@
|
||||
force_on = 16
|
||||
force_off = 5
|
||||
weight_class_on = WEIGHT_CLASS_NORMAL
|
||||
silent = TRUE
|
||||
|
||||
/obj/item/melee/classic_baton/telescopic/contractor_baton/get_wait_description()
|
||||
return "<span class='danger'>The baton is still charging!</span>"
|
||||
|
||||
@@ -135,8 +135,8 @@
|
||||
/obj/item/organ/cyberimp/arm/toolset,
|
||||
/obj/item/organ/cyberimp/arm/surgery,
|
||||
/obj/item/organ/cyberimp/chest/thrusters,
|
||||
/obj/item/organ/lungs/cybernetic,
|
||||
/obj/item/organ/liver/cybernetic) //cyberimplants range from a nice bonus to fucking broken bullshit so no subtypesof
|
||||
/obj/item/organ/lungs/cybernetic/tier3,
|
||||
/obj/item/organ/liver/cybernetic/tier3) //cyberimplants range from a nice bonus to fucking broken bullshit so no subtypesof
|
||||
for(var/V in templist)
|
||||
var/atom/A = V
|
||||
augment_list[initial(A.name)] = A
|
||||
|
||||
@@ -174,6 +174,10 @@
|
||||
var/atom/movable/AM = object
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_TRANSPARENT) && (AM.pass_flags & PASSGLASS))
|
||||
return BLOCK_NONE
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_NO_RANGED) && (attack_type & ATTACK_TYPE_PROJECTILE))
|
||||
return BLOCK_NONE
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_NO_MELEE) && (attack_type & ATTACK_TYPE_MELEE))
|
||||
return BLOCK_NONE
|
||||
if(attack_type & ATTACK_TYPE_THROWN)
|
||||
final_block_chance += 30
|
||||
if(attack_type & ATTACK_TYPE_TACKLE)
|
||||
@@ -238,30 +242,75 @@
|
||||
new /obj/item/shard((get_turf(src)))
|
||||
|
||||
/obj/item/shield/riot/on_shield_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
var/final_damage = damage
|
||||
|
||||
if(attack_type & ATTACK_TYPE_MELEE)
|
||||
var/obj/hittingthing = object
|
||||
if(hittingthing.damtype == BURN)
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_WEAK))
|
||||
final_damage *= 2
|
||||
else if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_STRONG))
|
||||
final_damage *= 0.5
|
||||
|
||||
if(hittingthing.damtype == BRUTE)
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_WEAK))
|
||||
final_damage *= 2
|
||||
else if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_STRONG))
|
||||
final_damage *= 0.5
|
||||
|
||||
if(hittingthing.damtype == STAMINA || hittingthing.damtype == TOX || hittingthing.damtype == CLONE || hittingthing.damtype == BRAIN || hittingthing.damtype == OXY)
|
||||
final_damage = 0
|
||||
|
||||
if(attack_type & ATTACK_TYPE_PROJECTILE)
|
||||
var/obj/item/projectile/shootingthing = object
|
||||
if(is_energy_reflectable_projectile(shootingthing))
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_WEAK))
|
||||
final_damage *= 2
|
||||
else if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_STRONG))
|
||||
final_damage *= 0.5
|
||||
|
||||
if(!is_energy_reflectable_projectile(object))
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_WEAK))
|
||||
final_damage *= 2
|
||||
else if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_STRONG))
|
||||
final_damage *= 0.5
|
||||
|
||||
if(shootingthing.damage_type == STAMINA)
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_DISABLER_DISRUPTED))
|
||||
final_damage *= 3 //disablers melt these kinds of shields. Really meant more for holoshields.
|
||||
else
|
||||
final_damage = 0
|
||||
|
||||
if(shootingthing.damage_type == TOX || shootingthing.damage_type == CLONE || shootingthing.damage_type == BRAIN || shootingthing.damage_type == OXY)
|
||||
final_damage = 0
|
||||
|
||||
if(can_shatter && (obj_integrity <= damage))
|
||||
var/turf/T = get_turf(owner)
|
||||
T.visible_message("<span class='warning'>[attack_text] destroys [src]!</span>")
|
||||
shatter(owner)
|
||||
qdel(src)
|
||||
return FALSE
|
||||
take_damage(damage)
|
||||
take_damage(final_damage)
|
||||
return ..()
|
||||
|
||||
/obj/item/shield/riot/laser_proof
|
||||
name = "laser resistant shield"
|
||||
desc = "A far more frail shield made of dark glass meant to block lasers but suffers from being being weak to ballistic projectiles."
|
||||
/obj/item/shield/riot/energy_proof
|
||||
name = "energy resistant shield"
|
||||
desc = "An ablative shield designed to absorb and disperse energy attacks. This comes at significant cost to its ability to withstand ballistics and kinetics, breaking apart easily."
|
||||
armor = list("melee" = 30, "bullet" = -10, "laser" = 80, "energy" = 80, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
|
||||
icon_state = "riot_laser"
|
||||
item_state = "riot_laser"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_ENERGY_STRONG | SHIELD_KINETIC_WEAK
|
||||
max_integrity = 300
|
||||
|
||||
/obj/item/shield/riot/bullet_proof
|
||||
name = "bullet resistant shield"
|
||||
desc = "A far more frail shield made of resistant plastics and kevlar meant to block ballistics."
|
||||
/obj/item/shield/riot/kinetic_proof
|
||||
name = "kinetic resistant shield"
|
||||
desc = "A polymer and ceramic shield designed to absorb ballistic projectiles and kinetic force. It doesn't do very well into energy attacks, especially from weapons that inflict burns."
|
||||
armor = list("melee" = 30, "bullet" = 80, "laser" = 0, "energy" = 0, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
|
||||
icon_state = "riot_bullet"
|
||||
item_state = "riot_bullet"
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_KINETIC_STRONG | SHIELD_ENERGY_WEAK
|
||||
max_integrity = 300
|
||||
|
||||
/obj/item/shield/riot/roman
|
||||
@@ -277,8 +326,8 @@
|
||||
|
||||
/obj/item/shield/riot/roman/fake
|
||||
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>. It appears to be a bit flimsy."
|
||||
block_chance = 0
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
shield_flags = SHIELD_ENERGY_WEAK | SHIELD_KINETIC_WEAK | SHIELD_NO_RANGED
|
||||
max_integrity = 40
|
||||
|
||||
/obj/item/shield/riot/roman/shatter(mob/living/carbon/human/owner)
|
||||
@@ -295,14 +344,80 @@
|
||||
custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 10)
|
||||
resistance_flags = FLAMMABLE
|
||||
repair_material = /obj/item/stack/sheet/mineral/wood
|
||||
block_chance = 30
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_ENERGY_WEAK
|
||||
max_integrity = 150
|
||||
|
||||
/obj/item/shield/riot/buckler/shatter(mob/living/carbon/human/owner)
|
||||
playsound(owner, 'sound/effects/bang.ogg', 50)
|
||||
new /obj/item/stack/sheet/mineral/wood(get_turf(src))
|
||||
|
||||
/obj/item/shield/riot/flash
|
||||
name = "strobe shield"
|
||||
desc = "A shield with a built in, high intensity light capable of blinding and disorienting suspects. Takes regular handheld flashes as bulbs."
|
||||
icon_state = "flashshield"
|
||||
item_state = "flashshield"
|
||||
var/obj/item/assembly/flash/handheld/embedded_flash
|
||||
|
||||
/obj/item/shield/riot/flash/Initialize()
|
||||
. = ..()
|
||||
embedded_flash = new(src)
|
||||
|
||||
/obj/item/shield/riot/flash/ComponentInitialize()
|
||||
. = .. ()
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
|
||||
/obj/item/shield/riot/flash/attack(mob/living/M, mob/user)
|
||||
. = embedded_flash.attack(M, user)
|
||||
update_icon()
|
||||
|
||||
/obj/item/shield/riot/flash/attack_self(mob/living/carbon/user)
|
||||
. = embedded_flash.attack_self(user)
|
||||
update_icon()
|
||||
|
||||
/obj/item/shield/riot/flash/on_shield_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
. = ..()
|
||||
if (. && !embedded_flash.crit_fail)
|
||||
embedded_flash.activate()
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/shield/riot/flash/attackby(obj/item/W, mob/user)
|
||||
if(istype(W, /obj/item/assembly/flash/handheld))
|
||||
var/obj/item/assembly/flash/handheld/flash = W
|
||||
if(flash.crit_fail)
|
||||
to_chat(user, "<span class='warning'>No sense replacing it with a broken bulb!</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You begin to replace the bulb...</span>")
|
||||
if(do_after(user, 20, target = user))
|
||||
if(flash.crit_fail || !flash || QDELETED(flash))
|
||||
return
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
|
||||
qdel(embedded_flash)
|
||||
embedded_flash = flash
|
||||
flash.forceMove(src)
|
||||
update_icon()
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/shield/riot/flash/emp_act(severity)
|
||||
. = ..()
|
||||
embedded_flash.emp_act(severity)
|
||||
update_icon()
|
||||
|
||||
/obj/item/shield/riot/flash/update_icon_state()
|
||||
if(!embedded_flash || embedded_flash.crit_fail)
|
||||
icon_state = "riot"
|
||||
item_state = "riot"
|
||||
else
|
||||
icon_state = "flashshield"
|
||||
item_state = "flashshield"
|
||||
|
||||
/obj/item/shield/riot/flash/examine(mob/user)
|
||||
. = ..()
|
||||
if (embedded_flash?.crit_fail)
|
||||
. += "<span class='info'>The mounted bulb has burnt out. You can try replacing it with a new one.</span>"
|
||||
|
||||
/obj/item/shield/riot/tele
|
||||
name = "telescopic shield"
|
||||
desc = "An advanced riot shield made of lightweight materials that collapses for easy storage."
|
||||
@@ -348,7 +463,7 @@
|
||||
|
||||
/obj/item/shield/makeshift
|
||||
name = "metal shield"
|
||||
desc = "A large shield made of wired and welded sheets of metal. The handle is made of cloth and leather making it unwieldy."
|
||||
desc = "A large shield made of wired and welded sheets of metal. The handle is made of cloth and leather, making it unwieldy."
|
||||
armor = list("melee" = 25, "bullet" = 25, "laser" = 5, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 80)
|
||||
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
||||
@@ -362,33 +477,34 @@
|
||||
|
||||
/obj/item/shield/riot/tower
|
||||
name = "tower shield"
|
||||
desc = "A massive shield that can block a lot of attacks, can take a lot of abuse before braking."
|
||||
desc = "An immense tower shield. Designed to ensure maximum protection to the user, at the expense of mobility."
|
||||
armor = list("melee" = 95, "bullet" = 95, "laser" = 75, "energy" = 60, "bomb" = 90, "bio" = 90, "rad" = 0, "fire" = 90, "acid" = 10) //Armor for the item, dosnt transfer to user
|
||||
item_state = "metal"
|
||||
icon_state = "metal"
|
||||
force = 16
|
||||
slowdown = 2
|
||||
throwforce = 15 //Massive pice of metal
|
||||
throwforce = 15 //Massive piece of metal
|
||||
max_integrity = 600
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
item_flags = SLOWS_WHILE_IN_HAND
|
||||
item_flags = SLOWS_WHILE_IN_HAND | ITEM_CAN_BLOCK
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
|
||||
/obj/item/shield/riot/tower/swat
|
||||
name = "swat shield"
|
||||
desc = "A massive, heavy shield that can block a lot of attacks, can take a lot of abuse before breaking."
|
||||
max_integrity = 250
|
||||
|
||||
/obj/item/shield/riot/implant
|
||||
name = "telescoping shield implant"
|
||||
desc = "A compact, arm-mounted telescopic shield. While nigh-indestructible when powered by a host user, it will eventually overload from damage. Recharges while inside its implant."
|
||||
item_state = "metal"
|
||||
icon_state = "metal"
|
||||
name = "hardlight shield implant"
|
||||
desc = "A hardlight plane of force projected from the implant. While it is capable of withstanding immense amounts of abuse, it will eventually overload from sustained impacts, especially against energy attacks. Recharges while retracted."
|
||||
item_state = "holoshield"
|
||||
icon_state = "holoshield"
|
||||
slowdown = 1
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 100
|
||||
obj_integrity = 100
|
||||
can_shatter = FALSE
|
||||
item_flags = SLOWS_WHILE_IN_HAND | ITEM_CAN_BLOCK
|
||||
item_flags = ITEM_CAN_BLOCK
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_KINETIC_STRONG | SHIELD_DISABLER_DISRUPTED
|
||||
var/recharge_timerid
|
||||
var/recharge_delay = 15 SECONDS
|
||||
|
||||
@@ -400,7 +516,7 @@
|
||||
if(obj_integrity == 0)
|
||||
if(ismob(loc))
|
||||
var/mob/living/L = loc
|
||||
playsound(src, 'sound/effects/glassbr3.ogg', 100)
|
||||
playsound(src, "sparks", 100, TRUE)
|
||||
L.visible_message("<span class='boldwarning'>[src] overloads from the damage sustained!</span>")
|
||||
L.dropItemToGround(src) //implant component catch hook will grab it.
|
||||
|
||||
|
||||
@@ -272,7 +272,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
|
||||
. = ..()
|
||||
. += GLOB.plastitaniumglass_recipes
|
||||
|
||||
/obj/item/stack/sheet/titaniumglass/on_solar_construction(obj/machinery/power/solar/S)
|
||||
/obj/item/stack/sheet/plastitaniumglass/on_solar_construction(obj/machinery/power/solar/S)
|
||||
S.max_integrity *= 2
|
||||
S.efficiency *= 2
|
||||
|
||||
|
||||
@@ -117,8 +117,8 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \
|
||||
new/datum/stack_recipe("Captain Statue", /obj/structure/statue/diamond/captain, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("AI Hologram Statue", /obj/structure/statue/diamond/ai1, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("AI Core Statue", /obj/structure/statue/diamond/ai2, 5, one_per_turf = 1, on_floor = 1), \
|
||||
// new/datum/stack_recipe("diamond brick", /obj/item/ingot/diamond, 6, time = 100), \ not yet
|
||||
))
|
||||
new/datum/stack_recipe("diamond ingot", /obj/item/ingot/diamond, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/diamond/get_main_recipes()
|
||||
. = ..()
|
||||
|
||||
@@ -592,7 +592,7 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
|
||||
return
|
||||
var/turf/T = get_turf(user) //we may have moved. adjust as needed...
|
||||
var/area/A = get_area(user)
|
||||
if((!is_station_level(T.z) && !is_mining_level(T.z)) || (A && !A.blob_allowed))
|
||||
if((!is_station_level(T.z) && !is_mining_level(T.z)) || (A && !(A.flags_1 & CULT_PERMITTED_1)))
|
||||
to_chat(user, "<span class='warning'>The veil is not weak enough here.</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -351,6 +351,75 @@
|
||||
if(!contents.len)
|
||||
. += "[icon_state]_empty"
|
||||
|
||||
//Derringer "Cigarettes"//
|
||||
/obj/item/storage/fancy/cigarettes/derringer
|
||||
name = "\improper Robust packet"
|
||||
desc = "Smoked by the robust."
|
||||
icon_state = "robust"
|
||||
spawn_type = /obj/item/gun/ballistic/derringer/traitor
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/derringer/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
STR.can_hold = typecacheof(list(/obj/item/clothing/mask/cigarette, /obj/item/lighter, /obj/item/gun/ballistic/derringer, /obj/item/ammo_casing/c38, /obj/item/ammo_casing/a357, /obj/item/ammo_casing/g4570))
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/derringer/AltClick(mob/living/carbon/user)
|
||||
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
return
|
||||
var/obj/item/W = (locate(/obj/item/ammo_casing/a357) in contents) || (locate(/obj/item/clothing/mask/cigarette) in contents) || locate(/obj/item/ammo_casing/g4570) //Easy access smokes and bullets
|
||||
if(W && contents.len > 0)
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_TAKE, W, user)
|
||||
user.put_in_hands(W)
|
||||
contents -= W
|
||||
to_chat(user, "<span class='notice'>You take \a [W] out of the pack.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There are no items left in the pack.</span>")
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/derringer/PopulateContents()
|
||||
new spawn_type(src)
|
||||
new /obj/item/ammo_casing/a357(src)
|
||||
new /obj/item/ammo_casing/a357(src)
|
||||
new /obj/item/ammo_casing/a357(src)
|
||||
new /obj/item/ammo_casing/a357(src)
|
||||
new /obj/item/clothing/mask/cigarette/syndicate(src)
|
||||
|
||||
//For traitors with luck/class
|
||||
/obj/item/storage/fancy/cigarettes/derringer/gold
|
||||
name = "\improper Robust Gold packet"
|
||||
desc = "Smoked by the truly robust."
|
||||
icon_state = "robustg"
|
||||
spawn_type = /obj/item/gun/ballistic/derringer/gold
|
||||
|
||||
//For operatives, bound in a ka-tet.
|
||||
/obj/item/storage/fancy/cigarettes/derringer/midworld
|
||||
name = "\improper Midworld's Lime Bend"
|
||||
desc = "The wheel of Ka turns, Gunslinger."
|
||||
icon_state = "slime"
|
||||
spawn_type = /obj/item/gun/ballistic/derringer/nukeop
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/derringer/midworld/PopulateContents()
|
||||
new spawn_type(src)
|
||||
new /obj/item/ammo_casing/g4570(src)
|
||||
new /obj/item/ammo_casing/g4570(src)
|
||||
new /obj/item/ammo_casing/g4570(src)
|
||||
new /obj/item/ammo_casing/g4570(src)
|
||||
new /obj/item/clothing/mask/cigarette/xeno(src)
|
||||
|
||||
//For Cargomen, looking for a good deal on arms, with no quarrels as to where they're from.
|
||||
/obj/item/storage/fancy/cigarettes/derringer/smuggled
|
||||
name = "\improper Shady Jim's Super Slims packet"
|
||||
desc = "If you get caught with this, we don't know you, capiche?"
|
||||
icon_state = "shadyjim"
|
||||
spawn_type = /obj/item/gun/ballistic/derringer
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/derringer/smuggled/PopulateContents()
|
||||
new spawn_type(src)
|
||||
new /obj/item/ammo_casing/c38/lethal(src)
|
||||
new /obj/item/ammo_casing/c38/lethal(src)
|
||||
new /obj/item/ammo_casing/c38/lethal(src)
|
||||
new /obj/item/ammo_casing/c38/lethal(src)
|
||||
new /obj/item/clothing/mask/cigarette/shadyjims (src)
|
||||
/////////////
|
||||
//CIGAR BOX//
|
||||
/////////////
|
||||
|
||||
@@ -394,15 +394,15 @@
|
||||
desc = "You want penis enlargement pills?"
|
||||
|
||||
/obj/item/storage/pill_bottle/penis_enlargement/PopulateContents()
|
||||
for(var/i in 1 to 7)
|
||||
for(var/i in 1 to 10)
|
||||
new /obj/item/reagent_containers/pill/penis_enlargement(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/breast_enlargement
|
||||
name = "breast enlargement pills"
|
||||
desc = "Made by Fermichem - They have a woman with breasts larger than she is on them. The warming states not to take more than 10u at a time."
|
||||
desc = "Made by Fermichem - The bottle shows a woman with breasts larger than she is on them. The warning states to not take more than 10 units at a time."
|
||||
|
||||
/obj/item/storage/pill_bottle/breast_enlargement/PopulateContents()
|
||||
for(var/i in 1 to 7)
|
||||
for(var/i in 1 to 10)
|
||||
new /obj/item/reagent_containers/pill/breast_enlargement(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/neurine
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/item/storage/box/syndicate
|
||||
|
||||
/obj/item/storage/box/syndicate/PopulateContents()
|
||||
switch (pickweight(list("bloodyspai" = 3, "stealth" = 2, "bond" = 2, "screwed" = 2, "sabotage" = 3, "guns" = 2, "murder" = 2, "baseball" = 1, "implant" = 1, "hacker" = 3, "darklord" = 1, "sniper" = 1, "metaops" = 1, "ninja" = 1)))
|
||||
switch (pickweight(list("bloodyspai" = 3, "stealth" = 2, "bond" = 2, "screwed" = 2, "sabotage" = 3, "guns" = 2, "murder" = 2, "baseball" = 1, "implant" = 1, "hacker" = 3, "darklord" = 1, "sniper" = 1, "metaops" = 1, "ninja" = 1, "ancient" = 1)))
|
||||
if("bloodyspai") // 30 tc now this is more right
|
||||
new /obj/item/clothing/under/chameleon(src) // 2 tc since it's not the full set
|
||||
new /obj/item/clothing/mask/chameleon(src) // Goes with above
|
||||
@@ -62,7 +62,7 @@
|
||||
new /obj/item/clothing/glasses/phantomthief/syndicate(src)
|
||||
new /obj/item/reagent_containers/syringe/stimulants(src)
|
||||
|
||||
if("baseball") // 42~ tc
|
||||
if("baseball") // 44~ tc
|
||||
new /obj/item/melee/baseball_bat/ablative/syndi(src) //Lets say 12 tc, lesser sleeping carp
|
||||
new /obj/item/clothing/glasses/sunglasses/garb(src) //Lets say 2 tc
|
||||
new /obj/item/card/emag(src) //6 tc
|
||||
@@ -72,6 +72,7 @@
|
||||
new /obj/item/clothing/under/syndicate/baseball(src) //3tc
|
||||
new /obj/item/clothing/head/soft/baseball(src) //Lets say 4 tc
|
||||
new /obj/item/reagent_containers/hypospray/medipen/stimulants/baseball(src) //lets say 5tc
|
||||
new /obj/item/melee/baseball_bat/telescopic(src) // 2 tc
|
||||
|
||||
if("implant") // 67+ tc holy shit what the fuck this is a lottery disguised as fun boxes isn't it?
|
||||
new /obj/item/implanter/freedom(src)
|
||||
@@ -155,6 +156,20 @@
|
||||
new /obj/item/card/id/syndicate(src) // 2 tc
|
||||
new /obj/item/chameleon(src) // 7 tc
|
||||
|
||||
if("ancient") //A kit so old, it's probably older than you. //This bundle is filled with the entire unlink contents traitors had access to in 2006, from OpenSS13. Notably the esword was not a choice but existed in code.
|
||||
new /obj/item/storage/toolbox/emergency/old/ancientbundle(src) //Items fit neatly into a classic toolbox just to remind you what the theme is.
|
||||
|
||||
/obj/item/storage/toolbox/emergency/old/ancientbundle //So the subtype works
|
||||
|
||||
/obj/item/storage/toolbox/emergency/old/ancientbundle/PopulateContents()
|
||||
new /obj/item/card/emag(src)
|
||||
new /obj/item/pen/sleepy(src)
|
||||
new /obj/item/reagent_containers/pill/cyanide(src)
|
||||
new /obj/item/chameleon(src) //its not the original cloaking device, but it will do.
|
||||
new /obj/item/gun/ballistic/revolver(src)
|
||||
new /obj/item/implanter/freedom(src)
|
||||
new /obj/item/stack/telecrystal(src) //The failsafe/self destruct isn't an item we can physically include in the kit, but 1 TC is technically enough to buy the equivalent.
|
||||
|
||||
/obj/item/storage/box/syndie_kit
|
||||
name = "box"
|
||||
desc = "A sleek, sturdy box."
|
||||
@@ -531,3 +546,21 @@
|
||||
. = ..()
|
||||
new /obj/item/cardpack/syndicate(src)
|
||||
new /obj/item/cardpack/syndicate(src)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/imp_deathrattle
|
||||
name = "deathrattle implant box"
|
||||
desc = "Contains eight linked deathrattle implants."
|
||||
|
||||
/obj/item/storage/box/syndie_kit/imp_deathrattle/PopulateContents()
|
||||
new /obj/item/implanter(src)
|
||||
|
||||
var/datum/deathrattle_group/group = new
|
||||
|
||||
var/implants = list()
|
||||
for(var/j in 1 to 8)
|
||||
var/obj/item/implantcase/deathrattle/case = new (src)
|
||||
implants += case.imp
|
||||
|
||||
for(var/i in implants)
|
||||
group.register(i)
|
||||
desc += " The implants are registered to the \"[group.name]\" group."
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
/obj/item/instrument/harmonica,
|
||||
/obj/item/mining_voucher,
|
||||
/obj/item/suit_voucher,
|
||||
/obj/item/reagent_containers/pill))
|
||||
/obj/item/reagent_containers/pill,
|
||||
/obj/item/gun/ballistic/derringer))
|
||||
|
||||
/obj/item/storage/wallet/Exited(atom/movable/AM)
|
||||
. = ..()
|
||||
|
||||
@@ -16,17 +16,21 @@
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
|
||||
attack_speed = CLICK_CD_MELEE
|
||||
|
||||
var/stamforce = 35
|
||||
var/stamina_loss_amount = 35
|
||||
var/turned_on = FALSE
|
||||
var/knockdown = TRUE
|
||||
var/obj/item/stock_parts/cell/cell
|
||||
var/hitcost = 750
|
||||
var/throw_hit_chance = 35
|
||||
var/preload_cell_type //if not empty the baton starts with this type of cell
|
||||
var/cooldown_duration = 5 SECONDS //How long our baton rightclick goes on cooldown for after applying a knockdown
|
||||
var/status_duration = 5 SECONDS //how long our status effects last for otherwise
|
||||
COOLDOWN_DECLARE(shove_cooldown)
|
||||
|
||||
/obj/item/melee/baton/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Right click attack while in combat mode to disarm instead of stun.</span>"
|
||||
. += "<span class='notice'>Right click attack while in combat mode to knockdown, but only once per [cooldown_duration / 10] seconds.</span>"
|
||||
. += "<span class='notice'>This knockdown will also put them off balance for [status_duration / 20] seconds, allowing you to shove a weapon out of their hand with a right click in Disarm intent.</span>"
|
||||
|
||||
/obj/item/melee/baton/get_cell()
|
||||
. = cell
|
||||
@@ -53,8 +57,8 @@
|
||||
/obj/item/melee/baton/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
..()
|
||||
//Only mob/living types have stun handling
|
||||
if(turned_on && prob(throw_hit_chance) && iscarbon(hit_atom))
|
||||
baton_stun(hit_atom)
|
||||
if(turned_on && prob(throw_hit_chance) && iscarbon(hit_atom) && thrownby)
|
||||
baton_stun(hit_atom, thrownby, shoving = TRUE)
|
||||
|
||||
/obj/item/melee/baton/loaded //this one starts with a cell pre-installed.
|
||||
preload_cell_type = /obj/item/stock_parts/cell/high/plus
|
||||
@@ -74,6 +78,16 @@
|
||||
//we're below minimum, turn off
|
||||
switch_status(FALSE)
|
||||
|
||||
///Check for our cell to determine how much penetration our weapon does.
|
||||
/obj/item/melee/baton/proc/get_cell_zap_pen()
|
||||
var/obj/item/stock_parts/cell/copper_top = get_cell()
|
||||
if(copper_top)
|
||||
var/chargepower = copper_top.maxcharge
|
||||
var/zap_penetration = (chargepower/1000) //This is our effective penetration. Every 1000 max charge, we get 1 pen power. A high capacity cell is equal to 10 armor pen, as an example.
|
||||
return zap_penetration
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/item/melee/baton/proc/switch_status(new_status = FALSE, silent = FALSE)
|
||||
if(turned_on != new_status)
|
||||
turned_on = new_status
|
||||
@@ -101,6 +115,7 @@
|
||||
var/obj/item/stock_parts/cell/copper_top = get_cell()
|
||||
if(copper_top)
|
||||
. += "<span class='notice'>\The [src] is [round(copper_top.percent())]% charged.</span>"
|
||||
. += "<span class='notice'>\The [src] currently can penetrate [round(copper_top.maxcharge/1000)]% of enemy armor thanks to it's loaded cell.</span>"
|
||||
else
|
||||
. += "<span class='warning'>\The [src] does not have a power source installed.</span>"
|
||||
|
||||
@@ -150,10 +165,10 @@
|
||||
/obj/item/melee/baton/alt_pre_attack(atom/A, mob/living/user, params)
|
||||
if(!user.CheckActionCooldown(CLICK_CD_MELEE))
|
||||
return
|
||||
. = common_baton_melee(A, user, TRUE) //return true (attackchain interrupt) if this also returns true. no harm-disarming.
|
||||
. = common_baton_melee(A, user, TRUE) //return true (attackchain interrupt) if this also returns true. no harm-shoving.
|
||||
|
||||
//return TRUE to interrupt attack chain.
|
||||
/obj/item/melee/baton/proc/common_baton_melee(mob/M, mob/living/user, disarming = FALSE)
|
||||
/obj/item/melee/baton/proc/common_baton_melee(mob/M, mob/living/user, shoving = FALSE)
|
||||
if(iscyborg(M) || !isliving(M)) //can't baton cyborgs
|
||||
return FALSE
|
||||
if(turned_on && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
|
||||
@@ -167,21 +182,26 @@
|
||||
if(check_martial_counter(L, user))
|
||||
return TRUE
|
||||
if(turned_on)
|
||||
if(baton_stun(M, user, disarming))
|
||||
if(baton_stun(M, user, shoving))
|
||||
user.do_attack_animation(M)
|
||||
else if(user.a_intent != INTENT_HARM) //they'll try to bash in the last proc.
|
||||
M.visible_message("<span class='warning'>[user] has prodded [M] with [src]. Luckily it was off.</span>", \
|
||||
"<span class='warning'>[user] has prodded you with [src]. Luckily it was off</span>")
|
||||
return disarming || (user.a_intent != INTENT_HARM)
|
||||
return shoving || (user.a_intent != INTENT_HARM)
|
||||
|
||||
/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/living/user, disarming = FALSE)
|
||||
/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/living/user, shoving = FALSE)
|
||||
var/list/return_list = list()
|
||||
if(L.mob_run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user, null, return_list) & BLOCK_SUCCESS) //No message; check_shields() handles that
|
||||
playsound(L, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
return FALSE
|
||||
var/stunpwr = stamforce
|
||||
stunpwr = block_calculate_resultant_damage(stunpwr, return_list)
|
||||
var/final_stamina_loss_amount = stamina_loss_amount //Our stunning power for the baton
|
||||
var/shoved = FALSE //Did we succeed on knocking our target over?
|
||||
var/zap_penetration = get_cell_zap_pen() //Find out what kind of cell we have, and calculating the resultant armor pen we get from it
|
||||
var/zap_block = L.run_armor_check(BODY_ZONE_CHEST, "melee", null, null, zap_penetration) //armor check, including calculation for armor penetration, for our attack
|
||||
final_stamina_loss_amount = block_calculate_resultant_damage(final_stamina_loss_amount, return_list)
|
||||
|
||||
var/obj/item/stock_parts/cell/our_cell = get_cell()
|
||||
|
||||
if(!our_cell)
|
||||
switch_status(FALSE)
|
||||
return FALSE
|
||||
@@ -194,26 +214,31 @@
|
||||
L.visible_message("<span class='warning'>[user] has prodded [L] with [src]. Luckily it was out of charge.</span>", \
|
||||
"<span class='warning'>[user] has prodded you with [src]. Luckily it was out of charge.</span>")
|
||||
return FALSE
|
||||
stunpwr *= round(stuncharge/hitcost, 0.1)
|
||||
final_stamina_loss_amount *= round(stuncharge/hitcost, 0.1)
|
||||
|
||||
if(user && !user.UseStaminaBuffer(getweight(user, STAM_COST_BATON_MOB_MULT), warn = TRUE))
|
||||
return FALSE
|
||||
|
||||
if(!disarming)
|
||||
if(knockdown)
|
||||
L.DefaultCombatKnockdown(50, override_stamdmg = 0) //knockdown
|
||||
L.adjustStaminaLoss(stunpwr)
|
||||
else
|
||||
L.drop_all_held_items() //no knockdown/stamina damage, instead disarm.
|
||||
if(shoving && COOLDOWN_FINISHED(src, shove_cooldown) && !HAS_TRAIT(L, TRAIT_IWASBATONED)) //Rightclicking applies a knockdown, but only once every couple of seconds, based on the cooldown_duration var. If they were recently knocked down, they can't be knocked down again by a baton.
|
||||
L.DefaultCombatKnockdown(50, override_stamdmg = 0)
|
||||
L.apply_status_effect(STATUS_EFFECT_TASED_WEAK, status_duration) //Even if they shove themselves up, they're still slowed.
|
||||
L.apply_status_effect(STATUS_EFFECT_OFF_BALANCE, status_duration) //They're very likely to drop items if shoved briefly after a knockdown.
|
||||
shoved = TRUE
|
||||
COOLDOWN_START(src, shove_cooldown, cooldown_duration)
|
||||
ADD_TRAIT(L, TRAIT_IWASBATONED, STATUS_EFFECT_TRAIT) //Prevents swapping to a new baton to avoid the cooldown by just acquiring more batons
|
||||
addtimer(TRAIT_CALLBACK_REMOVE(L, TRAIT_IWASBATONED, STATUS_EFFECT_TRAIT), cooldown_duration)
|
||||
playsound(loc, 'sound/weapons/zapbang.ogg', 50, 1, -1)
|
||||
else //If we cannot/don't knock down the target, we apply a stagger, which keeps them from just running off
|
||||
L.apply_status_effect(STATUS_EFFECT_STAGGERED, status_duration)
|
||||
|
||||
L.apply_effect(EFFECT_STUTTER, stamforce)
|
||||
L.apply_damage (final_stamina_loss_amount, STAMINA, BODY_ZONE_CHEST, zap_block)
|
||||
L.apply_effect(EFFECT_STUTTER, stamina_loss_amount)
|
||||
SEND_SIGNAL(L, COMSIG_LIVING_MINOR_SHOCK)
|
||||
if(user)
|
||||
L.lastattacker = user.real_name
|
||||
L.lastattackerckey = user.ckey
|
||||
L.visible_message("<span class='danger'>[user] has [disarming? "disarmed" : "stunned"] [L] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has [disarming? "disarmed" : "stunned"] you with [src]!</span>")
|
||||
log_combat(user, L, disarming? "disarmed" : "stunned")
|
||||
L.set_last_attacker(user)
|
||||
L.visible_message("<span class='danger'>[user] has [shoved ? "brutally stunned" : "stunned"] [L] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has [shoved ? "brutally stunnned" : "stunned"] you with [src]!</span>")
|
||||
log_combat(user, L, shoved ? "stunned and attempted knockdown" : "stunned")
|
||||
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
|
||||
@@ -228,7 +253,7 @@
|
||||
user.visible_message("<span class='danger'>[user] accidentally hits [user.p_them()]self with [src]!</span>", \
|
||||
"<span class='userdanger'>You accidentally hit yourself with [src]!</span>")
|
||||
SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
|
||||
user.DefaultCombatKnockdown(stamforce*6)
|
||||
user.DefaultCombatKnockdown(stamina_loss_amount*6)
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
deductcharge(hitcost)
|
||||
|
||||
@@ -306,18 +331,20 @@
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 3
|
||||
throwforce = 5
|
||||
stamforce = 25
|
||||
stamina_loss_amount = 25
|
||||
hitcost = 1000
|
||||
throw_hit_chance = 10
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
cooldown_duration = 7 SECONDS //It's a little on the weak side
|
||||
status_duration = 3 //Slows someone for a tiny bit
|
||||
var/obj/item/assembly/igniter/sparkler
|
||||
|
||||
/obj/item/melee/baton/cattleprod/Initialize()
|
||||
. = ..()
|
||||
sparkler = new (src)
|
||||
sparkler.activate_cooldown = 5
|
||||
sparkler.activate_cooldown = 7 //Helps visualize the knockdown
|
||||
|
||||
/obj/item/melee/baton/cattleprod/baton_stun()
|
||||
/obj/item/melee/baton/cattleprod/baton_stun(mob/living/L, mob/living/carbon/user, shoving = FALSE)
|
||||
sparkler?.activate()
|
||||
. = ..()
|
||||
|
||||
@@ -344,8 +371,8 @@
|
||||
/obj/item/melee/baton/boomerang/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
if(turned_on)
|
||||
var/caught = hit_atom.hitby(src, FALSE, FALSE, throwingdatum=throwingdatum)
|
||||
if(ishuman(hit_atom) && !caught && prob(throw_hit_chance))//if they are a carbon and they didn't catch it
|
||||
baton_stun(hit_atom)
|
||||
if(ishuman(hit_atom) && !caught && prob(throw_hit_chance) && thrownby)//if they are a carbon and they didn't catch it
|
||||
baton_stun(hit_atom, thrownby, shoving = TRUE)
|
||||
if(thrownby && !caught)
|
||||
sleep(1)
|
||||
if(!QDELETED(src))
|
||||
|
||||
@@ -139,14 +139,14 @@
|
||||
/obj/item/hand_tele/attack_self(mob/user)
|
||||
var/turf/current_location = get_turf(user)//What turf is the user on?
|
||||
var/area/current_area = current_location.loc
|
||||
if(!current_location || current_area.noteleport || is_away_level(current_location.z) || !isturf(user.loc))//If turf was not found or they're on z level 2 or >7 which does not currently exist. or if user is not located on a turf
|
||||
if(!current_location || (current_area.area_flags & NOTELEPORT) || is_away_level(current_location.z) || !isturf(user.loc))//If turf was not found or they're on z level 2 or >7 which does not currently exist. or if user is not located on a turf
|
||||
to_chat(user, "<span class='notice'>\The [src] is malfunctioning.</span>")
|
||||
return
|
||||
var/list/L = list( )
|
||||
for(var/obj/machinery/computer/teleporter/com in GLOB.machines)
|
||||
if(com.target)
|
||||
var/area/A = get_area(com.target)
|
||||
if(!A || A.noteleport)
|
||||
if(!A || (A.area_flags & NOTELEPORT))
|
||||
continue
|
||||
if(com.power_station && com.power_station.teleporter_hub && com.power_station.engaged)
|
||||
L["[get_area(com.target)] (Active)"] = com.target
|
||||
@@ -159,7 +159,7 @@
|
||||
if(T.y>world.maxy-8 || T.y<8)
|
||||
continue
|
||||
var/area/A = T.loc
|
||||
if(A.noteleport)
|
||||
if(A.area_flags & NOTELEPORT)
|
||||
continue
|
||||
turfs += T
|
||||
if(turfs.len)
|
||||
@@ -172,12 +172,12 @@
|
||||
return
|
||||
var/atom/T = L[t1]
|
||||
var/area/A = get_area(T)
|
||||
if(A.noteleport)
|
||||
to_chat(user, "<span class='notice'>\The [src] is malfunctioning.</span>")
|
||||
if (A.area_flags & NOTELEPORT)
|
||||
to_chat(user, "<span class='notice'>[src] is malfunctioning.</span>")
|
||||
return
|
||||
current_location = get_turf(user) //Recheck.
|
||||
current_area = current_location.loc
|
||||
if(!current_location || current_area.noteleport || is_away_level(current_location.z) || !isturf(user.loc))//If turf was not found or they're on z level 2 or >7 which does not currently exist. or if user is not located on a turf
|
||||
if (!current_location || (current_area.area_flags & NOTELEPORT) || is_away_level(current_location.z) || !isturf(user.loc))
|
||||
to_chat(user, "<span class='notice'>\The [src] is malfunctioning.</span>")
|
||||
return
|
||||
user.show_message("<span class='notice'>Locked In.</span>", MSG_AUDIBLE)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
item_state = "teleprod"
|
||||
slot_flags = null
|
||||
|
||||
/obj/item/melee/baton/cattleprod/teleprod/baton_stun(mob/living/L, mob/living/carbon/user)//handles making things teleport when hit
|
||||
/obj/item/melee/baton/cattleprod/teleprod/baton_stun(mob/living/L, mob/living/carbon/user, shoving = FALSE)//handles making things teleport when hit
|
||||
. = ..()
|
||||
if(!. || L.anchored)
|
||||
return
|
||||
@@ -16,7 +16,7 @@
|
||||
user.visible_message("<span class='danger'>[user] accidentally hits [user.p_them()]self with [src]!</span>", \
|
||||
"<span class='userdanger'>You accidentally hit yourself with [src]!</span>")
|
||||
SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
|
||||
user.DefaultCombatKnockdown(stamforce * 6)
|
||||
user.DefaultCombatKnockdown(stamina_loss_amount * 6)
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
if(do_teleport(user, get_turf(user), 50, channel = TELEPORT_CHANNEL_BLUESPACE))
|
||||
deductcharge(hitcost)
|
||||
|
||||
@@ -911,6 +911,16 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
var/homerun_ready = 0
|
||||
var/homerun_able = 0
|
||||
total_mass = 2.7 //a regular wooden major league baseball bat weighs somewhere between 2 to 3.4 pounds, according to google
|
||||
var/on_sound
|
||||
var/on = TRUE // Are we on or off
|
||||
var/on_icon_state // What is our sprite when turned on
|
||||
var/off_icon_state // What is our sprite when turned off
|
||||
var/on_item_state // What is our in-hand sprite when turned on
|
||||
var/force_on // Damage when on
|
||||
var/force_off // Damage when off
|
||||
var/throwforce_on // Damage when on
|
||||
var/throwforce_off // Damage when off
|
||||
var/weight_class_on // What is the new size class when turned on
|
||||
|
||||
/obj/item/melee/baseball_bat/Initialize()
|
||||
. = ..()
|
||||
@@ -992,6 +1002,58 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
force = 18 //Spear damage...
|
||||
throwforce = 30
|
||||
|
||||
/obj/item/melee/baseball_bat/proc/get_on_description()
|
||||
. = list()
|
||||
.["local_on"] = "<span class ='warning'>You extend the bat.</span>"
|
||||
.["local_off"] = "<span class ='notice'>You collapse the bat.</span>"
|
||||
return .
|
||||
|
||||
/obj/item/melee/baseball_bat/telescopic
|
||||
name = "telescopic baseball bat"
|
||||
desc = "A stealthy telescopic bat that can fit in a pocket when collapsed."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "baseball_bat_telescopic_0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
|
||||
item_state = null
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
item_flags = NONE
|
||||
force = 5
|
||||
throwforce = 10
|
||||
on = FALSE
|
||||
on_sound = 'sound/weapons/batonextend.ogg'
|
||||
on_icon_state = "baseball_bat_telescopic_1"
|
||||
off_icon_state = "baseball_bat_telescopic_0"
|
||||
on_item_state = "baseball_bat_telescopic"
|
||||
force_on = 15
|
||||
force_off = 5
|
||||
throwforce_on = 20
|
||||
throwforce_off = 10
|
||||
weight_class_on = WEIGHT_CLASS_HUGE
|
||||
total_mass = TOTAL_MASS_NORMAL_ITEM
|
||||
|
||||
/obj/item/melee/baseball_bat/telescopic/attack_self(mob/user)
|
||||
on = !on
|
||||
var/list/desc = get_on_description()
|
||||
if(on)
|
||||
to_chat(user, desc["local_on"])
|
||||
icon_state = on_icon_state
|
||||
item_state = on_item_state
|
||||
w_class = weight_class_on
|
||||
force = force_on
|
||||
throwforce = throwforce_on
|
||||
attack_verb = list("beat", "smacked")
|
||||
else
|
||||
to_chat(user, desc["local_off"])
|
||||
icon_state = off_icon_state
|
||||
item_state = null //no sprite for concealment even when in hand
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
force = force_off
|
||||
throwforce = throwforce_off
|
||||
attack_verb = list("drubbed", "beaned")
|
||||
playsound(src.loc, on_sound, 50, 1)
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/item/melee/flyswatter
|
||||
name = "flyswatter"
|
||||
desc = "Useful for killing pests of all sizes."
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
return FALSE
|
||||
var/turf/T = get_turf(src)
|
||||
var/area/A = get_area(src)
|
||||
if(!A.blob_allowed)
|
||||
if(!(A.area_flags & BLOBS_ALLOWED))
|
||||
return FALSE
|
||||
if(!A.powered(EQUIP))
|
||||
return FALSE
|
||||
|
||||
@@ -275,16 +275,15 @@
|
||||
/obj/structure/closet/proc/tool_interact(obj/item/W, mob/living/user)//returns TRUE if attackBy call shouldn't be continued (because tool was used/closet was of wrong type), FALSE if otherwise
|
||||
. = TRUE
|
||||
if(opened)
|
||||
if(istype(W, /obj/item/weldingtool))
|
||||
if(W.tool_behaviour == TOOL_WELDER)
|
||||
// eigen check
|
||||
if(eigen_teleport)
|
||||
to_chat(user, "<span class='notice'>The unstable nature of \the [src] makes it impossible to deconstruct!</span>")
|
||||
return
|
||||
if(W.tool_behaviour == cutting_tool)
|
||||
// eigen check
|
||||
if(eigen_teleport)
|
||||
to_chat(user, "<span class='notice'>The unstable nature of \the [src] makes it impossible to deconstruct!</span>")
|
||||
return
|
||||
|
||||
if(W.tool_behaviour == TOOL_WELDER)
|
||||
if(!W.tool_start_check(user, amount=0))
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You begin cutting \the [src] apart...</span>")
|
||||
if(W.use_tool(src, user, 40, volume=50))
|
||||
if(!opened)
|
||||
@@ -294,13 +293,29 @@
|
||||
"<span class='hear'>You hear welding.</span>")
|
||||
deconstruct(TRUE)
|
||||
return
|
||||
else // for example cardboard box is cut with wirecutters
|
||||
else if(W.tool_behaviour == TOOL_WIRECUTTER)
|
||||
W.use_tool(src, user, 40, volume=50)
|
||||
user.visible_message("<span class='notice'>[user] cut apart \the [src].</span>", \
|
||||
"<span class='notice'>You cut \the [src] apart with \the [W].</span>")
|
||||
deconstruct(TRUE)
|
||||
return
|
||||
W.use_tool(src, user, 40, volume=50)
|
||||
user.visible_message("<span class='notice'>[user] deconstructed \the [src].</span>", \
|
||||
"<span class='notice'>You deconstructed \the [src] with \the [W].</span>")
|
||||
deconstruct(TRUE) //Honestly by this point, if all checks were right and this is the cutting tool, just cut it
|
||||
return
|
||||
if(user.transferItemToLoc(W, drop_location())) // so we put in unlit welder too
|
||||
return
|
||||
else if(!opened && user.a_intent == INTENT_HELP)
|
||||
var/item_is_id = W.GetID()
|
||||
if(!item_is_id)
|
||||
if(!open(user))
|
||||
togglelock(user)
|
||||
return
|
||||
return
|
||||
if(item_is_id || !toggle(user))
|
||||
togglelock(user)
|
||||
return
|
||||
else if(W.tool_behaviour == TOOL_WELDER && can_weld_shut)
|
||||
// eigen check
|
||||
if(eigen_teleport)
|
||||
@@ -328,12 +343,6 @@
|
||||
user.visible_message("<span class='notice'>[user] [anchored ? "anchored" : "unanchored"] \the [src] [anchored ? "to" : "from"] the ground.</span>", \
|
||||
"<span class='notice'>You [anchored ? "anchored" : "unanchored"] \the [src] [anchored ? "to" : "from"] the ground.</span>", \
|
||||
"<span class='hear'>You hear a ratchet.</span>")
|
||||
else if(user.a_intent != INTENT_HARM && !(W.item_flags & NOBLUDGEON))
|
||||
var/item_is_id = W.GetID()
|
||||
if(!item_is_id)
|
||||
return FALSE
|
||||
if(item_is_id || !toggle(user))
|
||||
togglelock(user)
|
||||
// cit addons
|
||||
else if(istype(W, /obj/item/electronics/airlock))
|
||||
handle_lock_addition(user, W)
|
||||
|
||||
@@ -19,3 +19,50 @@
|
||||
desc = "A sturdier card-locked storage unit used for bulky shipments."
|
||||
max_integrity = 500 // Same as crates.
|
||||
melee_min_damage = 25 // Idem.
|
||||
|
||||
/obj/structure/closet/secure_closet/goodies/owned
|
||||
name = "private locker"
|
||||
desc = "A locker designed to only open for who purchased its contents."
|
||||
///Account of the person buying the crate if private purchasing.
|
||||
var/datum/bank_account/buyer_account
|
||||
///Department of the person buying the crate if buying via the NIRN app.
|
||||
var/datum/bank_account/department/department_account
|
||||
///Is the secure crate opened or closed?
|
||||
var/privacy_lock = TRUE
|
||||
///Is the crate being bought by a person, or a budget card?
|
||||
var/department_purchase = FALSE
|
||||
|
||||
/obj/structure/closet/secure_closet/goodies/owned/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>It's locked with a privacy lock, and can only be unlocked by the buyer's ID.</span>"
|
||||
|
||||
/obj/structure/closet/secure_closet/goodies/owned/Initialize(mapload, datum/bank_account/_buyer_account)
|
||||
. = ..()
|
||||
buyer_account = _buyer_account
|
||||
if(istype(buyer_account, /datum/bank_account/department))
|
||||
department_purchase = TRUE
|
||||
department_account = buyer_account
|
||||
|
||||
/obj/structure/closet/secure_closet/goodies/owned/togglelock(mob/living/user, silent)
|
||||
if(privacy_lock)
|
||||
if(!broken)
|
||||
var/obj/item/card/id/id_card = user.get_idcard(TRUE)
|
||||
if(id_card)
|
||||
if(id_card.registered_account)
|
||||
if(id_card.registered_account == buyer_account || (department_purchase && (id_card.registered_account?.account_job?.paycheck_department) == (department_account.department_id)))
|
||||
if(iscarbon(user))
|
||||
add_fingerprint(user)
|
||||
locked = !locked
|
||||
user.visible_message("<span class='notice'>[user] unlocks [src]'s privacy lock.</span>",
|
||||
"<span class='notice'>You unlock [src]'s privacy lock.</span>")
|
||||
privacy_lock = FALSE
|
||||
update_icon()
|
||||
else if(!silent)
|
||||
to_chat(user, "<span class='notice'>Bank account does not match with buyer!</span>")
|
||||
else if(!silent)
|
||||
to_chat(user, "<span class='notice'>No linked bank account detected!</span>")
|
||||
else if(!silent)
|
||||
to_chat(user, "<span class='notice'>No ID detected!</span>")
|
||||
else if(!silent)
|
||||
to_chat(user, "<span class='warning'>[src] is broken!</span>")
|
||||
else ..()
|
||||
|
||||
@@ -590,7 +590,7 @@
|
||||
|
||||
/obj/effect/mob_spawn/human/pirate
|
||||
name = "space pirate sleeper"
|
||||
desc = "A cryo sleeper smelling faintly of rum."
|
||||
desc = "A cryo sleeper smelling faintly of rum. The sleeper looks unstable. <i>Perhaps the pirate within can be killed with the right tools...</i>"
|
||||
job_description = "Space Pirate"
|
||||
random = TRUE
|
||||
icon = 'icons/obj/machines/sleeper.dmi'
|
||||
@@ -608,6 +608,54 @@
|
||||
assignedrole = "Space Pirate"
|
||||
var/rank = "Mate"
|
||||
|
||||
/obj/effect/mob_spawn/human/pirate/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(user.mind.has_antag_datum(/datum/antagonist/pirate))
|
||||
to_chat(user, "<span class='notice'>Your shipmate sails within their dreams for now. Perhaps they may wake up eventually.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>If you want to kill the pirate off, something to pry open the sleeper might be the best way to do it.</span>")
|
||||
|
||||
|
||||
/obj/effect/mob_spawn/human/pirate/attackby(obj/item/W, mob/user, params)
|
||||
if(W.tool_behaviour == TOOL_CROWBAR && user.a_intent != INTENT_HARM)
|
||||
if(user.mind.has_antag_datum(/datum/antagonist/pirate))
|
||||
to_chat(user,"<span class='warning'>Why would you want to do that to your shipmate? That'd kill them.</span>")
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] start to pry open [src]...</span>",
|
||||
"<span class='notice'>You start to pry open [src]...</span>",
|
||||
"<span class='italics'>You hear prying...</span>")
|
||||
W.play_tool_sound(src)
|
||||
if(do_after(user, 100*W.toolspeed, target = src))
|
||||
user.visible_message("<span class='warning'>[user] pries open [src], disrupting the sleep of the pirate within and killing them.</span>",
|
||||
"<span class='notice'>You pry open [src], disrupting the sleep of the pirate within and killing them.</span>",
|
||||
"<span class='italics'>You hear prying, followed by the death rattling of bones.</span>")
|
||||
log_game("[key_name(user)] has successfully pried open [src] and disabled a space pirate spawner.")
|
||||
W.play_tool_sound(src)
|
||||
playsound(src.loc, 'modular_citadel/sound/voice/scream_skeleton.ogg', 50, 1, 4, 1.2)
|
||||
if(rank == "Captain")
|
||||
new /obj/effect/mob_spawn/human/pirate/corpse/captain(get_turf(src))
|
||||
else
|
||||
new /obj/effect/mob_spawn/human/pirate/corpse(get_turf(src))
|
||||
qdel(src)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/effect/mob_spawn/human/pirate/corpse //occurs when someone pries a pirate out of their sleeper.
|
||||
mob_name = "Dead Space Pirate"
|
||||
death = TRUE
|
||||
instant = TRUE
|
||||
random = FALSE
|
||||
|
||||
/obj/effect/mob_spawn/human/pirate/corpse/Destroy()
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/human/pirate/corpse/captain
|
||||
rank = "Captain"
|
||||
mob_name = "Dead Space Pirate Captain"
|
||||
outfit = /datum/outfit/pirate/space/captain
|
||||
|
||||
/obj/effect/mob_spawn/human/pirate/special(mob/living/new_spawn)
|
||||
new_spawn.fully_replace_character_name(new_spawn.real_name,generate_pirate_name())
|
||||
new_spawn.mind.add_antag_datum(/datum/antagonist/pirate)
|
||||
@@ -662,6 +710,72 @@
|
||||
to_chat(M,"<span class='notice'>You're once again longer hearing deadchat.</span>")
|
||||
|
||||
|
||||
/datum/action/disguise
|
||||
name = "Disguise"
|
||||
button_icon_state = "ling_transform"
|
||||
icon_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
background_icon_state = "bg_mime"
|
||||
var/currently_disguised = FALSE
|
||||
var/static/list/mob_blacklist = typecacheof(list(
|
||||
/mob/living/simple_animal/pet,
|
||||
/mob/living/simple_animal/hostile/retaliate/goose,
|
||||
/mob/living/simple_animal/hostile/poison,
|
||||
/mob/living/simple_animal/hostile/retaliate/goat,
|
||||
/mob/living/simple_animal/cow,
|
||||
/mob/living/simple_animal/chick,
|
||||
/mob/living/simple_animal/chicken,
|
||||
/mob/living/simple_animal/kiwi,
|
||||
/mob/living/simple_animal/babyKiwi,
|
||||
/mob/living/simple_animal/deer,
|
||||
/mob/living/simple_animal/parrot,
|
||||
/mob/living/simple_animal/hostile/lizard,
|
||||
/mob/living/simple_animal/crab,
|
||||
/mob/living/simple_animal/cockroach,
|
||||
/mob/living/simple_animal/butterfly,
|
||||
/mob/living/simple_animal/mouse,
|
||||
/mob/living/simple_animal/sloth,
|
||||
/mob/living/simple_animal/opossum,
|
||||
/mob/living/simple_animal/hostile/bear,
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear,
|
||||
/mob/living/simple_animal/hostile/asteroid/wolf,
|
||||
/mob/living/carbon/monkey,
|
||||
/mob/living/simple_animal/hostile/gorilla,
|
||||
/mob/living/carbon/alien/larva,
|
||||
/mob/living/simple_animal/hostile/retaliate/frog
|
||||
))
|
||||
|
||||
|
||||
/datum/action/disguise/Trigger()
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(!currently_disguised)
|
||||
var/user_object_type = input(H, "Disguising as OBJECT or MOB?") as null|anything in list("OBJECT", "MOB")
|
||||
if(user_object_type)
|
||||
var/search_term = stripped_input(H, "Enter the search term")
|
||||
if(search_term)
|
||||
var/list_to_search
|
||||
if(user_object_type == "MOB")
|
||||
list_to_search = subtypesof(/mob) - mob_blacklist
|
||||
else
|
||||
list_to_search = subtypesof(/obj)
|
||||
var/list/filtered_results = list()
|
||||
for(var/some_search_item in list_to_search)
|
||||
if(findtext("[some_search_item]", search_term))
|
||||
filtered_results += some_search_item
|
||||
if(!length(filtered_results))
|
||||
to_chat(H, "Nothing matched your search query!")
|
||||
else
|
||||
var/disguise_selection = input("Select item to disguise as") as null|anything in filtered_results
|
||||
if(disguise_selection)
|
||||
var/atom/disguise_item = disguise_selection
|
||||
var/image/I = image(icon = initial(disguise_item.icon), icon_state = initial(disguise_item.icon_state), loc = H)
|
||||
I.override = TRUE
|
||||
I.layer = ABOVE_MOB_LAYER
|
||||
H.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/everyone, "ghost_cafe_disguise", I)
|
||||
currently_disguised = TRUE
|
||||
else
|
||||
H.remove_alt_appearance("ghost_cafe_disguise")
|
||||
currently_disguised = FALSE
|
||||
|
||||
/obj/effect/mob_spawn/human/ghostcafe/special(mob/living/carbon/human/new_spawn)
|
||||
if(new_spawn.client)
|
||||
new_spawn.client.prefs.copy_to(new_spawn)
|
||||
@@ -679,6 +793,8 @@
|
||||
to_chat(new_spawn,"<span class='boldwarning'>Ghosting is free!</span>")
|
||||
var/datum/action/toggle_dead_chat_mob/D = new(new_spawn)
|
||||
D.Grant(new_spawn)
|
||||
var/datum/action/disguise/disguise_action = new(new_spawn)
|
||||
disguise_action.Grant(new_spawn)
|
||||
|
||||
/datum/outfit/ghostcafe
|
||||
name = "ID, jumpsuit and shoes"
|
||||
|
||||
@@ -199,8 +199,7 @@
|
||||
return TRUE
|
||||
|
||||
/obj/item/gun_control/attack(mob/living/M, mob/living/user)
|
||||
M.lastattacker = user.real_name
|
||||
M.lastattackerckey = user.ckey
|
||||
M.set_last_attacker(user)
|
||||
M.attacked_by(src, user)
|
||||
add_fingerprint(user)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#define STAIR_TERMINATOR_YES 2
|
||||
|
||||
// dir determines the direction of travel to go upwards (due to lack of sprites, currently only 1 and 2 make sense)
|
||||
// stairs require /turf/open/transparent/openspace as the tile above them to work
|
||||
// stairs require /turf/open/openspace as the tile above them to work
|
||||
// multiple stair objects can be chained together; the Z level transition will happen on the final stair object in the chain
|
||||
|
||||
/obj/structure/stairs
|
||||
@@ -12,7 +12,7 @@
|
||||
icon_state = "stairs"
|
||||
anchored = TRUE
|
||||
|
||||
var/force_open_above = FALSE // replaces the turf above this stair obj with /turf/open/transparent/openspace
|
||||
var/force_open_above = FALSE // replaces the turf above this stair obj with /turf/open/openspace
|
||||
var/terminator_mode = STAIR_TERMINATOR_AUTOMATIC
|
||||
var/turf/listeningTo
|
||||
|
||||
@@ -107,23 +107,23 @@
|
||||
/obj/structure/stairs/proc/build_signal_listener()
|
||||
if(listeningTo)
|
||||
UnregisterSignal(listeningTo, COMSIG_TURF_MULTIZ_NEW)
|
||||
var/turf/open/transparent/openspace/T = get_step_multiz(get_turf(src), UP)
|
||||
var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP)
|
||||
RegisterSignal(T, COMSIG_TURF_MULTIZ_NEW, .proc/on_multiz_new)
|
||||
listeningTo = T
|
||||
|
||||
/obj/structure/stairs/proc/force_open_above()
|
||||
var/turf/open/transparent/openspace/T = get_step_multiz(get_turf(src), UP)
|
||||
var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP)
|
||||
if(T && !istype(T))
|
||||
T.ChangeTurf(/turf/open/transparent/openspace, flags = CHANGETURF_INHERIT_AIR)
|
||||
T.ChangeTurf(/turf/open/openspace, flags = CHANGETURF_INHERIT_AIR)
|
||||
|
||||
/obj/structure/stairs/proc/on_multiz_new(turf/source, dir)
|
||||
//SIGNAL_HANDLER
|
||||
SHOULD_NOT_SLEEP(TRUE) //the same thing.
|
||||
|
||||
if(dir == UP)
|
||||
var/turf/open/transparent/openspace/T = get_step_multiz(get_turf(src), UP)
|
||||
var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP)
|
||||
if(T && !istype(T))
|
||||
T.ChangeTurf(/turf/open/transparent/openspace, flags = CHANGETURF_INHERIT_AIR)
|
||||
T.ChangeTurf(/turf/open/openspace, flags = CHANGETURF_INHERIT_AIR)
|
||||
|
||||
/obj/structure/stairs/intercept_zImpact(atom/movable/AM, levels = 1)
|
||||
. = ..()
|
||||
|
||||
@@ -93,6 +93,9 @@
|
||||
user.stop_pulling()
|
||||
return ..()
|
||||
|
||||
/obj/structure/table/attack_robot(mob/user)
|
||||
on_attack_hand(user)
|
||||
|
||||
/obj/structure/table/attack_tk()
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -67,6 +67,9 @@
|
||||
to_chat(user, "<span class='notice'>You put [I] in [src].</span>")
|
||||
update_icon()
|
||||
|
||||
/obj/structure/tank_dispenser/attack_robot(mob/user)
|
||||
return _try_interact(user)
|
||||
|
||||
/obj/structure/tank_dispenser/ui_state(mob/user)
|
||||
return GLOB.physical_state
|
||||
|
||||
|
||||
@@ -554,7 +554,7 @@
|
||||
if(B.cell)
|
||||
if(B.cell.charge > 0 && B.turned_on)
|
||||
flick("baton_active", src)
|
||||
var/stunforce = B.stamforce
|
||||
var/stunforce = B.stamina_loss_amount
|
||||
user.DefaultCombatKnockdown(stunforce * 2)
|
||||
user.stuttering = stunforce/20
|
||||
B.deductcharge(B.hitcost)
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/turf/open/transparent
|
||||
baseturfs = /turf/open/transparent/openspace
|
||||
intact = FALSE //this means wires go on top
|
||||
|
||||
/turf/open/transparent/Initialize() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker
|
||||
. = ..()
|
||||
plane = OPENSPACE_PLANE
|
||||
layer = OPENSPACE_LAYER
|
||||
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/turf/open/transparent/LateInitialize()
|
||||
update_multiz(TRUE, TRUE)
|
||||
|
||||
/turf/open/transparent/Destroy()
|
||||
vis_contents.len = 0
|
||||
return ..()
|
||||
|
||||
/turf/open/transparent/update_multiz(prune_on_fail = FALSE, init = FALSE)
|
||||
. = ..()
|
||||
var/turf/T = below()
|
||||
if(!T)
|
||||
vis_contents.len = 0
|
||||
if(!show_bottom_level() && prune_on_fail) //If we cant show whats below, and we prune on fail, change the turf to plating as a fallback
|
||||
ChangeTurf(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
|
||||
return FALSE
|
||||
if(init)
|
||||
vis_contents += T
|
||||
return TRUE
|
||||
|
||||
/turf/open/transparent/multiz_turf_del(turf/T, dir)
|
||||
if(dir != DOWN)
|
||||
return
|
||||
update_multiz()
|
||||
|
||||
/turf/open/transparent/multiz_turf_new(turf/T, dir)
|
||||
if(dir != DOWN)
|
||||
return
|
||||
update_multiz()
|
||||
|
||||
///Called when there is no real turf below this turf
|
||||
/turf/open/transparent/proc/show_bottom_level()
|
||||
var/turf/path = SSmapping.level_trait(z, ZTRAIT_BASETURF) || /turf/open/space
|
||||
if(!ispath(path))
|
||||
path = text2path(path)
|
||||
if(!ispath(path))
|
||||
warning("Z-level [z] has invalid baseturf '[SSmapping.level_trait(z, ZTRAIT_BASETURF)]'")
|
||||
path = /turf/open/space
|
||||
var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), initial(path.icon_state), layer = TURF_LAYER, plane = PLANE_SPACE)
|
||||
underlays += underlay_appearance
|
||||
return TRUE
|
||||
|
||||
|
||||
/turf/open/transparent/glass
|
||||
name = "Glass floor"
|
||||
desc = "Dont jump on it, or do, I'm not your mom."
|
||||
icon = 'icons/turf/floors/glass.dmi'
|
||||
icon_state = "floor_glass"
|
||||
smooth = SMOOTH_MORE
|
||||
var/floor_tile = /obj/item/stack/sheet/glass
|
||||
canSmoothWith = list(/turf/open/transparent/glass, /turf/open/transparent/glass/reinforced)
|
||||
footstep = FOOTSTEP_PLATING
|
||||
barefootstep = FOOTSTEP_HARD_BAREFOOT
|
||||
clawfootstep = FOOTSTEP_HARD_CLAW
|
||||
heavyfootstep = FOOTSTEP_GENERIC_HEAVY
|
||||
|
||||
/turf/open/transparent/glass/Initialize()
|
||||
icon_state = "" //Prevent the normal icon from appearing behind the smooth overlays
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/turf/open/floor/glass/LateInitialize()
|
||||
. = ..()
|
||||
// AddElement(/datum/element/turf_z_transparency, TRUE)
|
||||
|
||||
/turf/open/transparent/glass/wrench_act(mob/living/user, obj/item/I)
|
||||
to_chat(user, "<span class='notice'>You begin removing glass...</span>")
|
||||
if(I.use_tool(src, user, 30, volume=80))
|
||||
if(!istype(src, /turf/open/transparent/glass))
|
||||
return TRUE
|
||||
if(floor_tile)
|
||||
new floor_tile(src, 2)
|
||||
ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
|
||||
return TRUE
|
||||
|
||||
/turf/open/transparent/glass/reinforced
|
||||
name = "Reinforced glass floor"
|
||||
desc = "Do jump on it, it can take it."
|
||||
icon = 'icons/turf/floors/reinf_glass.dmi'
|
||||
floor_tile = /obj/item/stack/sheet/rglass
|
||||
|
||||
/turf/open/transparent/glass/reinforced/wrench_act(mob/living/user, obj/item/I)
|
||||
to_chat(user, "<span class='notice'>You begin removing reinforced glass...</span>")
|
||||
if(I.use_tool(src, user, 30, volume=80))
|
||||
if(!istype(src, /turf/open/transparent/glass/reinforced))
|
||||
return TRUE
|
||||
if(floor_tile)
|
||||
new floor_tile(src, 2)
|
||||
ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
|
||||
return TRUE
|
||||
@@ -8,12 +8,10 @@
|
||||
//Making the station dirty, one tile at a time. Called by master controller's setup_objects
|
||||
|
||||
/turf/open/floor/proc/MakeDirty()
|
||||
// We start with a 1/3 chance of having this proc called by Initialize()
|
||||
if(CONFIG_GET(flag/persistent_debris_only))
|
||||
return
|
||||
|
||||
if(prob(66)) //fastest possible exit 2/3 of the time
|
||||
return
|
||||
|
||||
if(!(flags_1 & CAN_BE_DIRTY_1))
|
||||
return
|
||||
|
||||
@@ -31,22 +29,23 @@
|
||||
var/static/list/high_dirt_areas = typecacheof(list(/area/science/test_area,
|
||||
/area/mine/production,
|
||||
/area/mine/living_quarters,
|
||||
/area/commons/vacant_room/office,
|
||||
/area/ruin/space))
|
||||
if(is_type_in_typecache(A, high_dirt_areas))
|
||||
new /obj/effect/decal/cleanable/dirt(src) //vanilla, but it works
|
||||
new /obj/effect/decal/cleanable/dirt(src) //vanilla, but it works
|
||||
return
|
||||
|
||||
|
||||
if(prob(80)) //mid dirt - 1/15
|
||||
if(prob(80)) //mid dirt - 1/15
|
||||
return
|
||||
|
||||
//Construction zones. Blood, sweat, and oil. Oh, and dirt.
|
||||
var/static/list/engine_dirt_areas = typecacheof(list(/area/engine,
|
||||
/area/crew_quarters/heads/chief,
|
||||
/area/ruin/space/derelict/assembly_line,
|
||||
var/static/list/engine_dirt_areas = typecacheof(list(/area/engineering,
|
||||
/area/command/heads_quarters/ce,
|
||||
/area/science/robotics,
|
||||
/area/maintenance,
|
||||
/area/construction,
|
||||
/area/commons/vacant_room/commissary,
|
||||
/area/survivalpod))
|
||||
if(is_type_in_typecache(A, engine_dirt_areas))
|
||||
if(prob(3))
|
||||
@@ -62,7 +61,7 @@
|
||||
return
|
||||
|
||||
//Bathrooms. Blood, vomit, and shavings in the sinks.
|
||||
var/static/list/bathroom_dirt_areas = typecacheof(list( /area/crew_quarters/toilet,
|
||||
var/static/list/bathroom_dirt_areas = typecacheof(list( /area/commons/toilet,
|
||||
/area/awaymission/research/interior/bathroom))
|
||||
if(is_type_in_typecache(A, bathroom_dirt_areas))
|
||||
if(prob(40))
|
||||
@@ -72,21 +71,24 @@
|
||||
new /obj/effect/decal/cleanable/blood/old(src)
|
||||
return
|
||||
|
||||
//Hangars and pods covered in oil.
|
||||
var/static/list/oily_areas = typecacheof(/area/quartermaster)
|
||||
// Cargo bays covered in oil.
|
||||
var/static/list/oily_areas = typecacheof(/area/cargo)
|
||||
if(is_type_in_typecache(A, oily_areas))
|
||||
if(prob(25))
|
||||
new /obj/effect/decal/cleanable/oil(src)
|
||||
// else if(prob(20))
|
||||
// // or occasionally the signs of opened packages
|
||||
// new /obj/effect/decal/cleanable/wrapping(src)
|
||||
return
|
||||
|
||||
|
||||
if(prob(75)) //low dirt - 1/60
|
||||
if(prob(75)) //low dirt - 1/60
|
||||
return
|
||||
|
||||
//Areas where gibs will be present. Robusting probably happened some time ago.
|
||||
var/static/list/gib_covered_areas = typecacheof(list(/area/ai_monitored/turret_protected,
|
||||
/area/security,
|
||||
/area/crew_quarters/heads/hos))
|
||||
/area/command/heads_quarters/hos))
|
||||
if(is_type_in_typecache(A, gib_covered_areas))
|
||||
if(prob(20))
|
||||
if(prob(5))
|
||||
@@ -96,8 +98,8 @@
|
||||
return
|
||||
|
||||
//Kitchen areas. Broken eggs, flour, spilled milk (no crying allowed.)
|
||||
var/static/list/kitchen_dirt_areas = typecacheof(list(/area/crew_quarters/kitchen,
|
||||
/area/crew_quarters/cafeteria))
|
||||
var/static/list/kitchen_dirt_areas = typecacheof(list(/area/service/kitchen,
|
||||
/area/service/cafeteria))
|
||||
if(is_type_in_typecache(A, kitchen_dirt_areas))
|
||||
if(prob(60))
|
||||
if(prob(50))
|
||||
@@ -108,7 +110,7 @@
|
||||
|
||||
//Medical areas. Mostly clean by space-OSHA standards, but has some blood and oil spread about.
|
||||
var/static/list/medical_dirt_areas = typecacheof(list(/area/medical,
|
||||
/area/crew_quarters/heads/cmo))
|
||||
/area/command/heads_quarters/cmo))
|
||||
if(is_type_in_typecache(A, medical_dirt_areas))
|
||||
if(prob(66))
|
||||
if(prob(5))
|
||||
@@ -124,10 +126,10 @@
|
||||
|
||||
//Science messes. Mostly green glowy stuff -WHICH YOU SHOULD NOT INJEST-.
|
||||
var/static/list/science_dirt_areas = typecacheof(list(/area/science,
|
||||
/area/crew_quarters/heads/hor))
|
||||
if(is_type_in_typecache(A, medical_dirt_areas))
|
||||
/area/command/heads_quarters/rd))
|
||||
if(is_type_in_typecache(A, science_dirt_areas))
|
||||
if(prob(20))
|
||||
new /obj/effect/decal/cleanable/greenglow(src) //this cleans itself up but it might startle you when you see it.
|
||||
new /obj/effect/decal/cleanable/greenglow(src) //this cleans itself up but it might startle you when you see it.
|
||||
return
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
icon_regular_floor = "floor"
|
||||
else
|
||||
icon_regular_floor = icon_state
|
||||
if(mapload)
|
||||
if(mapload && prob(66)) // 2/3 instead of 1/3 (default)
|
||||
MakeDirty()
|
||||
|
||||
/turf/open/floor/ex_act(severity, target)
|
||||
|
||||
@@ -80,11 +80,11 @@
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You begin adding glass to the floor...</span>")
|
||||
if(do_after(user, 5, target = src))
|
||||
if (G.get_amount() >= 2 && !istype(src, /turf/open/transparent/glass))
|
||||
if (G.get_amount() >= 2 && !istype(src, /turf/open/floor/glass))
|
||||
for(var/obj/effect/decal/cleanable/decal in src)
|
||||
if(decal.wiped_by_floor_change)
|
||||
qdel(decal)
|
||||
PlaceOnTop(/turf/open/transparent/glass, flags = CHANGETURF_INHERIT_AIR)
|
||||
PlaceOnTop(/turf/open/floor/glass, flags = CHANGETURF_INHERIT_AIR)
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 80, 1)
|
||||
G.use(2)
|
||||
to_chat(user, "<span class='notice'>You add glass to the floor.</span>")
|
||||
@@ -100,11 +100,11 @@
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You begin adding reinforced glass to the floor...</span>")
|
||||
if(do_after(user, 10, target = src))
|
||||
if (RG.get_amount() >= 2 && !istype(src, /turf/open/transparent/glass/reinforced))
|
||||
if (RG.get_amount() >= 2 && !istype(src, /turf/open/floor/glass/reinforced))
|
||||
for(var/obj/effect/decal/cleanable/decal in src)
|
||||
if(decal.wiped_by_floor_change)
|
||||
qdel(decal)
|
||||
PlaceOnTop(/turf/open/transparent/glass/reinforced, flags = CHANGETURF_INHERIT_AIR)
|
||||
PlaceOnTop(/turf/open/floor/glass/reinforced, flags = CHANGETURF_INHERIT_AIR)
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 80, 1)
|
||||
RG.use(2)
|
||||
to_chat(user, "<span class='notice'>You add reinforced glass to the floor.</span>")
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "asteroid"
|
||||
icon_plating = "asteroid"
|
||||
postdig_icon_change = TRUE
|
||||
footstep = FOOTSTEP_SAND
|
||||
barefootstep = FOOTSTEP_SAND
|
||||
clawfootstep = FOOTSTEP_SAND
|
||||
@@ -16,13 +15,19 @@
|
||||
/// Environment type for the turf
|
||||
var/environment_type = "asteroid"
|
||||
/// Base turf type to be created by the tunnel
|
||||
var/turf_type = /turf/open/floor/plating/asteroid //Because caves do whacky shit to revert to normal
|
||||
/// Probability the floor has a different icon state
|
||||
var/turf_type = /turf/open/floor/plating/asteroid
|
||||
/// Probability floor has a different icon state
|
||||
var/floor_variance = 20
|
||||
attachment_holes = FALSE
|
||||
/// Itemstack to drop when dug by a shovel
|
||||
var/obj/item/stack/digResult = /obj/item/stack/ore/glass/basalt
|
||||
/// Whether the turf has been dug or not
|
||||
var/dug
|
||||
/// Whether to change the turf's icon_state to "[base_icon_state]_dug" when its dugged up
|
||||
postdig_icon_change = TRUE
|
||||
|
||||
// /turf/open/floor/plating/asteroid/setup_broken_states()
|
||||
// return list("asteroid_dug")
|
||||
|
||||
/turf/open/floor/plating/asteroid/Initialize()
|
||||
var/proper_name = name
|
||||
@@ -33,19 +38,18 @@
|
||||
|
||||
/// Drops itemstack when dug and changes icon
|
||||
/turf/open/floor/plating/asteroid/proc/getDug()
|
||||
dug = TRUE
|
||||
new digResult(src, 5)
|
||||
if(postdig_icon_change)
|
||||
if(!postdig_icon)
|
||||
icon_plating = "[environment_type]_dug"
|
||||
icon_state = "[environment_type]_dug"
|
||||
dug = TRUE
|
||||
icon_plating = "[environment_type]_dug"
|
||||
icon_state = "[environment_type]_dug"
|
||||
|
||||
/// If the user can dig the turf
|
||||
/turf/open/floor/plating/asteroid/proc/can_dig(mob/user)
|
||||
if(!dug)
|
||||
return TRUE
|
||||
if(user)
|
||||
to_chat(user, "<span class='notice'>Looks like someone has dug here already.</span>")
|
||||
to_chat(user, "<span class='warning'>Looks like someone has dug here already!</span>")
|
||||
|
||||
/turf/open/floor/plating/asteroid/try_replace_tile(obj/item/stack/tile/T, mob/user, params)
|
||||
return
|
||||
@@ -59,6 +63,9 @@
|
||||
/turf/open/floor/plating/asteroid/MakeDry()
|
||||
return
|
||||
|
||||
// /turf/open/floor/plating/asteroid/crush()
|
||||
// return
|
||||
|
||||
/turf/open/floor/plating/asteroid/attackby(obj/item/W, mob/user, params)
|
||||
. = ..()
|
||||
if(!.)
|
||||
@@ -99,6 +106,9 @@
|
||||
floor_variance = 15
|
||||
digResult = /obj/item/stack/ore/glass/basalt
|
||||
|
||||
// /turf/open/floor/plating/asteroid/basalt/setup_broken_states()
|
||||
// return list("basalt_dug")
|
||||
|
||||
/turf/open/floor/plating/asteroid/basalt/lava //lava underneath
|
||||
baseturfs = /turf/open/lava/smooth
|
||||
|
||||
@@ -128,280 +138,16 @@
|
||||
planetary_atmos = TRUE
|
||||
baseturfs = /turf/open/lava/smooth/lava_land_surface
|
||||
|
||||
|
||||
|
||||
// /turf/open/floor/plating/asteroid/lowpressure
|
||||
// initial_gas_mix = OPENTURF_LOW_PRESSURE
|
||||
// baseturfs = /turf/open/floor/plating/asteroid/lowpressure
|
||||
// turf_type = /turf/open/floor/plating/asteroid/lowpressure
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless
|
||||
initial_gas_mix = AIRLESS_ATMOS
|
||||
baseturfs = /turf/open/floor/plating/asteroid/airless
|
||||
turf_type = /turf/open/floor/plating/asteroid/airless
|
||||
|
||||
|
||||
#define SPAWN_MEGAFAUNA "bluh bluh huge boss"
|
||||
#define SPAWN_BUBBLEGUM 6
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave
|
||||
/// Length of the tunnel
|
||||
var/length = 100
|
||||
/// Mobs that can spawn in the tunnel, weighted list
|
||||
var/list/mob_spawn_list
|
||||
/// Megafauna that can spawn in the tunnel, weighted list
|
||||
var/list/megafauna_spawn_list
|
||||
/// Flora that can spawn in the tunnel, weighted list
|
||||
var/list/flora_spawn_list
|
||||
//terrain to spawn weighted list
|
||||
var/list/terrain_spawn_list
|
||||
/// Turf type to choose when spawning in tunnel at 1% chance, weighted list
|
||||
var/list/choose_turf_type
|
||||
/// if the tunnel should keep being created
|
||||
var/sanity = 1
|
||||
/// Cave direction to move
|
||||
var/forward_cave_dir = 1
|
||||
/// Backwards cave direction for tracking
|
||||
var/backward_cave_dir = 2
|
||||
/// If the tunnel is moving backwards
|
||||
var/going_backwards = TRUE
|
||||
/// If this is a cave creating type
|
||||
var/has_data = FALSE
|
||||
/// The non-cave creating type
|
||||
var/data_having_type = /turf/open/floor/plating/asteroid/airless/cave/has_data
|
||||
/// Option tunnel width, wegihted list
|
||||
var/list/pick_tunnel_width
|
||||
turf_type = /turf/open/floor/plating/asteroid/airless
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/has_data //subtype for producing a tunnel with given data
|
||||
has_data = TRUE
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/volcanic
|
||||
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/random = 50, /obj/structure/spawner/lavaland/goliath = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random = 40, /obj/structure/spawner/lavaland = 2, \
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/random = 30, /obj/structure/spawner/lavaland/legion = 3, \
|
||||
SPAWN_MEGAFAUNA = 6, /mob/living/simple_animal/hostile/asteroid/goldgrub = 10)
|
||||
|
||||
data_having_type = /turf/open/floor/plating/asteroid/airless/cave/volcanic/has_data
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/volcanic/has_data //subtype for producing a tunnel with given data
|
||||
has_data = TRUE
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/snow
|
||||
gender = PLURAL
|
||||
name = "snow"
|
||||
desc = "Looks cold."
|
||||
icon = 'icons/turf/snow.dmi'
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
icon_state = "snow"
|
||||
icon_plating = "snow"
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
slowdown = 2
|
||||
environment_type = "snow"
|
||||
flags_1 = NONE
|
||||
planetary_atmos = TRUE
|
||||
burnt_states = list("snow_dug")
|
||||
bullet_sizzle = TRUE
|
||||
bullet_bounce_sound = null
|
||||
digResult = /obj/item/stack/sheet/mineral/snow
|
||||
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/wolf = 50, /obj/structure/spawner/ice_moon = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear = 30, /obj/structure/spawner/ice_moon/polarbear = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50, /mob/living/simple_animal/hostile/asteroid/goldgrub = 10, \
|
||||
/mob/living/simple_animal/hostile/asteroid/lobstrosity = 15)
|
||||
flora_spawn_list = list(/obj/structure/flora/tree/pine = 2, /obj/structure/flora/grass/both = 12, /obj/structure/flora/rock/icy = 6, /obj/structure/flora/rock/pile/icy = 6)
|
||||
data_having_type = /turf/open/floor/plating/asteroid/airless/cave/snow/has_data
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
choose_turf_type = list(/turf/open/floor/plating/asteroid/snow/icemoon = 19, /turf/open/floor/plating/ice/icemoon = 1)
|
||||
pick_tunnel_width = list("1" = 6, "2" = 1)
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/snow/underground
|
||||
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/ice_demon = 50, /obj/structure/spawner/ice_moon/demonic_portal = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_whelp = 30, /obj/structure/spawner/ice_moon/demonic_portal/ice_whelp = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50, /obj/structure/spawner/ice_moon/demonic_portal/snowlegion = 3)
|
||||
flora_spawn_list = list(/obj/structure/flora/rock/icy = 6, /obj/structure/flora/rock/pile/icy = 6)
|
||||
data_having_type = /turf/open/floor/plating/asteroid/airless/cave/snow/underground/has_data
|
||||
choose_turf_type = null
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/snow/has_data //subtype for producing a tunnel with given data
|
||||
has_data = TRUE
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/snow/underground/has_data //subtype for producing a tunnel with given data
|
||||
has_data = TRUE
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/Initialize()
|
||||
if (!mob_spawn_list)
|
||||
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goldgrub = 1, /mob/living/simple_animal/hostile/asteroid/goliath = 5, /mob/living/simple_animal/hostile/asteroid/basilisk = 4, /mob/living/simple_animal/hostile/asteroid/hivelord = 3)
|
||||
if (!megafauna_spawn_list)
|
||||
megafauna_spawn_list = list(/mob/living/simple_animal/hostile/megafauna/dragon = 4, /mob/living/simple_animal/hostile/megafauna/colossus = 2, /mob/living/simple_animal/hostile/megafauna/bubblegum = SPAWN_BUBBLEGUM)
|
||||
if (!flora_spawn_list)
|
||||
flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2 , /obj/structure/flora/ash/cap_shroom = 2 , /obj/structure/flora/ash/stem_shroom = 2 , /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2)
|
||||
if(!terrain_spawn_list)
|
||||
terrain_spawn_list = list(/obj/structure/geyser/random = 1)
|
||||
. = ..()
|
||||
if(!has_data)
|
||||
produce_tunnel_from_data()
|
||||
|
||||
/// Sets the tunnel length and direction
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/get_cave_data(set_length, exclude_dir = -1)
|
||||
// If set_length (arg1) isn't defined, get a random length; otherwise assign our length to the length arg.
|
||||
if(!set_length)
|
||||
length = rand(25, 50)
|
||||
else
|
||||
length = set_length
|
||||
|
||||
// Get our directiosn
|
||||
forward_cave_dir = pick(GLOB.alldirs - exclude_dir)
|
||||
// Get the opposite direction of our facing direction
|
||||
backward_cave_dir = angle2dir(dir2angle(forward_cave_dir) + 180)
|
||||
|
||||
/// Gets the tunnel length and direction then makes the tunnel
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/produce_tunnel_from_data(tunnel_length, excluded_dir = -1)
|
||||
get_cave_data(tunnel_length, excluded_dir)
|
||||
// Make our tunnels
|
||||
make_tunnel(forward_cave_dir)
|
||||
if(going_backwards)
|
||||
make_tunnel(backward_cave_dir)
|
||||
// Kill ourselves by replacing ourselves with a normal floor.
|
||||
SpawnFloor(src)
|
||||
|
||||
/**
|
||||
* Makes the tunnel and spawns things inside of it
|
||||
*
|
||||
* Picks a tunnel width for the tunnel and then starts spawning turfs in the direction it moves in
|
||||
* Can randomly change directions of the tunnel, stops if it hits the edge of the map, or a no tunnel area
|
||||
* Can randomly make new tunnels out of itself
|
||||
*
|
||||
*/
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/make_tunnel(dir)
|
||||
var/turf/closed/mineral/tunnel = src
|
||||
var/next_angle = pick(45, -45)
|
||||
|
||||
var/tunnel_width = 1
|
||||
if(pick_tunnel_width)
|
||||
tunnel_width = text2num(pickweight(pick_tunnel_width))
|
||||
|
||||
for(var/i = 0; i < length; i++)
|
||||
if(!sanity)
|
||||
break
|
||||
|
||||
var/list/L = list(45)
|
||||
if(ISODD(dir2angle(dir))) // We're going at an angle and we want thick angled tunnels.
|
||||
L += -45
|
||||
|
||||
// Expand the edges of our tunnel
|
||||
for(var/edge_angle in L)
|
||||
var/turf/closed/mineral/edge = tunnel
|
||||
for(var/current_tunnel_width = 1 to tunnel_width)
|
||||
edge = get_step(edge, angle2dir(dir2angle(dir) + edge_angle))
|
||||
if(istype(edge))
|
||||
SpawnFloor(edge)
|
||||
|
||||
if(!sanity)
|
||||
break
|
||||
|
||||
// Move our tunnel forward
|
||||
tunnel = get_step(tunnel, dir)
|
||||
|
||||
if(istype(tunnel))
|
||||
// Small chance to have forks in our tunnel; otherwise dig our tunnel.
|
||||
if(i > 3 && prob(20))
|
||||
if(isarea(tunnel.loc))
|
||||
|
||||
var/area/A = tunnel.loc
|
||||
if(!A.tunnel_allowed)
|
||||
sanity = 0
|
||||
break
|
||||
var/turf/open/floor/plating/asteroid/airless/cave/C = tunnel.ChangeTurf(data_having_type, null, CHANGETURF_IGNORE_AIR)
|
||||
C.going_backwards = FALSE
|
||||
C.produce_tunnel_from_data(rand(10, 15), dir)
|
||||
else
|
||||
SpawnFloor(tunnel)
|
||||
else //if(!istype(tunnel, parent)) // We hit space/normal/wall, stop our tunnel.
|
||||
break
|
||||
|
||||
// Chance to change our direction left or right.
|
||||
if(i > 2 && prob(33))
|
||||
// We can't go a full loop though
|
||||
next_angle = -next_angle
|
||||
setDir(angle2dir(dir2angle(dir) )+ next_angle)
|
||||
|
||||
|
||||
/// Spawns the floor of the tunnel and any type of structure or mob it can have
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/SpawnFloor(turf/T)
|
||||
var/area/A = T.loc
|
||||
if(!A.tunnel_allowed)
|
||||
sanity = 0
|
||||
return
|
||||
if(choose_turf_type)
|
||||
turf_type = pickweight(choose_turf_type)
|
||||
if(turf_type == initial(turf_type)) // Don't spawn different turf types under flora or terrain
|
||||
var/spawned_flora = FALSE
|
||||
if(is_mining_level(z))
|
||||
spawned_flora = SpawnFlora(T)
|
||||
if(!spawned_flora) // no rocks beneath mob spawners / mobs.
|
||||
SpawnMonster(T)
|
||||
SpawnTerrain(T)
|
||||
T.ChangeTurf(turf_type, null, CHANGETURF_IGNORE_AIR)
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/SpawnTerrain(turf/T)
|
||||
if(prob(1))
|
||||
if(istype(loc, /area/mine/explored) || istype(loc, /area/lavaland/surface/outdoors/explored))
|
||||
return
|
||||
var/randumb = pickweight(terrain_spawn_list)
|
||||
for(var/obj/structure/geyser/F in range(7, T))
|
||||
if(istype(F, randumb))
|
||||
return
|
||||
new randumb(T)
|
||||
|
||||
/// Spawns a random mob or megafauna in the tunnel
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/SpawnMonster(turf/T)
|
||||
if(!isarea(loc))
|
||||
return
|
||||
var/area/A = loc
|
||||
if(prob(30))
|
||||
if(!A.mob_spawn_allowed)
|
||||
return
|
||||
var/randumb = pickweight(mob_spawn_list)
|
||||
if(!randumb)
|
||||
return
|
||||
while(randumb == SPAWN_MEGAFAUNA)
|
||||
if(A.megafauna_spawn_allowed && megafauna_spawn_list && megafauna_spawn_list.len) //this is danger. it's boss time.
|
||||
var/maybe_boss = pickweight(megafauna_spawn_list)
|
||||
if(megafauna_spawn_list[maybe_boss])
|
||||
randumb = maybe_boss
|
||||
if(ispath(maybe_boss, /mob/living/simple_animal/hostile/megafauna/bubblegum)) //there can be only one bubblegum, so don't waste spawns on it
|
||||
megafauna_spawn_list[maybe_boss] = 0
|
||||
else //this is not danger, don't spawn a boss, spawn something else
|
||||
randumb = pickweight(mob_spawn_list)
|
||||
|
||||
for(var/mob/living/simple_animal/hostile/H in urange(12,T)) //prevents mob clumps
|
||||
if((ispath(randumb, /mob/living/simple_animal/hostile/megafauna) || ismegafauna(H)) && get_dist(src, H) <= 7)
|
||||
return //if there's a megafauna within standard view don't spawn anything at all
|
||||
if(ispath(randumb, /mob/living/simple_animal/hostile/asteroid) || istype(H, /mob/living/simple_animal/hostile/asteroid))
|
||||
return //if the random is a standard mob, avoid spawning if there's another one within 12 tiles
|
||||
if((ispath(randumb, /obj/structure/spawner/lavaland) || istype(H, /obj/structure/spawner/lavaland)) && get_dist(src, H) <= 2)
|
||||
return //prevents tendrils spawning in each other's collapse range
|
||||
|
||||
new randumb(T)
|
||||
return TRUE
|
||||
|
||||
#undef SPAWN_MEGAFAUNA
|
||||
#undef SPAWN_BUBBLEGUM
|
||||
|
||||
/// Spawns a random flora in the tunnel, can spawn clumps of them.
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/SpawnFlora(turf/T)
|
||||
if(prob(12))
|
||||
if(isarea(loc))
|
||||
var/area/A = loc
|
||||
if(!A.flora_allowed)
|
||||
return
|
||||
var/randumb = pickweight(flora_spawn_list)
|
||||
if(!randumb)
|
||||
return
|
||||
for(var/obj/structure/flora/F in range(4, T)) // Allows for growing patches, but not ridiculous stacks of flora
|
||||
if(!istype(F, randumb))
|
||||
return
|
||||
new randumb(T)
|
||||
return TRUE
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow
|
||||
gender = PLURAL
|
||||
name = "snow"
|
||||
@@ -420,6 +166,9 @@
|
||||
bullet_bounce_sound = null
|
||||
digResult = /obj/item/stack/sheet/mineral/snow
|
||||
|
||||
// /turf/open/floor/plating/asteroid/snow/setup_broken_states()
|
||||
// return list("snow_dug")
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/burn_tile()
|
||||
if(!burnt)
|
||||
visible_message("<span class='danger'>[src] melts away!.</span>")
|
||||
@@ -430,8 +179,9 @@
|
||||
return FALSE
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
baseturfs = /turf/open/openspace/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
slowdown = 0
|
||||
|
||||
/turf/open/lava/plasma/ice_moon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
@@ -442,24 +192,22 @@
|
||||
name = "icy snow"
|
||||
desc = "Looks colder."
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120"
|
||||
initial_gas_mix = "n2=82;plasma=24;TEMP=120"
|
||||
floor_variance = 0
|
||||
icon_state = "snow-ice"
|
||||
icon_plating = "snow-ice"
|
||||
environment_type = "snow_cavern"
|
||||
environment_type = "snow-ice"
|
||||
footstep = FOOTSTEP_FLOOR
|
||||
barefootstep = FOOTSTEP_HARD_BAREFOOT
|
||||
clawfootstep = FOOTSTEP_HARD_CLAW
|
||||
heavyfootstep = FOOTSTEP_GENERIC_HEAVY
|
||||
|
||||
// /turf/open/floor/plating/asteroid/snow/ice/setup_broken_states()
|
||||
// return list("snow-ice")
|
||||
/turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
planetary_atmos = TRUE
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/ice/icemoon/solarpanel
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "solarpanel"
|
||||
slowdown = 0
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/ice/burn_tile()
|
||||
return FALSE
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/turf/open/floor/glass
|
||||
name = "Glass floor"
|
||||
desc = "Dont jump on it, or do, I'm not your mom."
|
||||
icon = 'icons/turf/floors/glass.dmi'
|
||||
icon_state = "floor_glass"
|
||||
baseturfs = /turf/open/openspace
|
||||
intact = FALSE //this means wires go on top
|
||||
smooth = SMOOTH_MORE
|
||||
canSmoothWith = list(/turf/open/floor/glass, /turf/open/floor/glass/reinforced)
|
||||
footstep = FOOTSTEP_PLATING
|
||||
barefootstep = FOOTSTEP_HARD_BAREFOOT
|
||||
clawfootstep = FOOTSTEP_HARD_CLAW
|
||||
heavyfootstep = FOOTSTEP_GENERIC_HEAVY
|
||||
floor_tile = /obj/item/stack/sheet/glass
|
||||
|
||||
// /turf/open/floor/glass/setup_broken_states()
|
||||
// return list("glass-damaged1", "glass-damaged2", "glass-damaged3")
|
||||
|
||||
|
||||
/turf/open/floor/glass/Initialize()
|
||||
icon_state = "" //Prevent the normal icon from appearing behind the smooth overlays
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/turf/open/floor/glass/LateInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/turf_z_transparency, TRUE)
|
||||
|
||||
/// n(omegalul)
|
||||
/turf/open/floor/glass/crowbar_act(mob/living/user, obj/item/I)
|
||||
return TRUE
|
||||
|
||||
/turf/open/floor/glass/wrench_act(mob/living/user, obj/item/I)
|
||||
to_chat(user, "<span class='notice'>You begin removing glass...</span>")
|
||||
if(I.use_tool(src, user, 30, volume=80))
|
||||
if(!istype(src, /turf/open/floor/glass))
|
||||
return TRUE
|
||||
if(floor_tile)
|
||||
new floor_tile(src, 2)
|
||||
ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
|
||||
return TRUE
|
||||
|
||||
/turf/open/floor/glass/reinforced
|
||||
name = "Reinforced glass floor"
|
||||
desc = "Do jump on it, it can take it."
|
||||
icon = 'icons/turf/floors/reinf_glass.dmi'
|
||||
icon_state = "floor_glass"
|
||||
// base_icon_state = "reinf_glass"
|
||||
|
||||
// /turf/open/floor/glass/reinforced/setup_broken_states()
|
||||
// return list("reinf_glass-damaged1", "reinf_glass-damaged2", "reinf_glass-damaged3")
|
||||
|
||||
/turf/open/floor/glass/reinforced/wrench_act(mob/living/user, obj/item/I)
|
||||
to_chat(user, "<span class='notice'>You begin removing reinforced glass...</span>")
|
||||
if(I.use_tool(src, user, 30, volume=80))
|
||||
if(!istype(src, /turf/open/floor/glass/reinforced))
|
||||
return TRUE
|
||||
if(floor_tile)
|
||||
new floor_tile(src, 2)
|
||||
ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
|
||||
return TRUE
|
||||
@@ -1,43 +1,59 @@
|
||||
#define MINING_MESSAGE_COOLDOWN 20
|
||||
|
||||
/**********************Mineral deposits**************************/
|
||||
|
||||
/turf/closed/mineral //wall piece
|
||||
name = "rock"
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
icon_state = "rock"
|
||||
var/smooth_icon = 'icons/turf/smoothrocks.dmi'
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
canSmoothWith = null
|
||||
baseturfs = /turf/open/floor/plating/asteroid/airless
|
||||
initial_gas_mix = AIRLESS_ATMOS
|
||||
opacity = 1
|
||||
opacity = TRUE
|
||||
density = TRUE
|
||||
blocks_air = 1
|
||||
blocks_air = TRUE
|
||||
layer = EDGED_TURF_LAYER
|
||||
// base_icon_state = "smoothrocks"
|
||||
temperature = TCMB
|
||||
var/smooth_icon = 'icons/turf/smoothrocks.dmi'
|
||||
var/environment_type = "asteroid"
|
||||
var/turf/open/floor/plating/turf_type = /turf/open/floor/plating/asteroid/airless
|
||||
var/mineralType = null
|
||||
var/obj/item/stack/ore/mineralType = null
|
||||
var/mineralAmt = 3
|
||||
var/spread = 0 //will the seam spread?
|
||||
var/spreadChance = 0 //the percentual chance of an ore spreading to the neighbouring tiles
|
||||
var/last_act = 0
|
||||
var/scan_state = "" //Holder for the image we display when we're pinged by a mining scanner
|
||||
var/defer_change = 0
|
||||
// If true you can mine the mineral turf with your hands
|
||||
var/weak_turf = FALSE
|
||||
|
||||
/turf/closed/mineral/Initialize()
|
||||
if (!canSmoothWith)
|
||||
canSmoothWith = list(/turf/closed/mineral, /turf/closed/indestructible)
|
||||
. = ..()
|
||||
var/matrix/M = new
|
||||
M.Translate(-4, -4)
|
||||
transform = M
|
||||
icon = smooth_icon
|
||||
. = ..()
|
||||
if (mineralType && mineralAmt && spread && spreadChance)
|
||||
|
||||
|
||||
/turf/closed/mineral/proc/Spread_Vein()
|
||||
var/spreadChance = initial(mineralType.spreadChance)
|
||||
if(spreadChance)
|
||||
for(var/dir in GLOB.cardinals)
|
||||
if(prob(spreadChance))
|
||||
var/turf/T = get_step(src, dir)
|
||||
if(istype(T, /turf/closed/mineral/random))
|
||||
Spread(T)
|
||||
var/turf/closed/mineral/random/M = T
|
||||
if(istype(M) && !M.mineralType)
|
||||
M.Change_Ore(mineralType)
|
||||
|
||||
/turf/closed/mineral/proc/Change_Ore(ore_type, random = 0)
|
||||
if(random)
|
||||
mineralAmt = rand(1, 5)
|
||||
if(ispath(ore_type, /obj/item/stack/ore)) //If it has a scan_state, switch to it
|
||||
var/obj/item/stack/ore/the_ore = ore_type
|
||||
scan_state = initial(the_ore.scan_state) // I SAID. SWITCH. TO. IT.
|
||||
mineralType = ore_type // Everything else assumes that this is typed correctly so don't set it to non-ores thanks.
|
||||
|
||||
/turf/closed/mineral/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
if(turf_type)
|
||||
@@ -48,7 +64,6 @@
|
||||
|
||||
|
||||
/turf/closed/mineral/attackby(obj/item/pickaxe/I, mob/user, params)
|
||||
var/stored_dir = user.dir
|
||||
if (!user.IsAdvancedToolUser())
|
||||
to_chat(usr, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
return
|
||||
@@ -69,7 +84,7 @@
|
||||
if(ismineralturf(src))
|
||||
if(I.digrange > 0)
|
||||
for(var/turf/closed/mineral/M in range(user,range))
|
||||
if(get_dir(user,M)&stored_dir)
|
||||
if(get_dir(user,M) & user.dir)
|
||||
M.gets_drilled(user)
|
||||
dug_tiles += M
|
||||
to_chat(user, "<span class='notice'>You finish cutting into the rock.</span>")
|
||||
@@ -79,30 +94,63 @@
|
||||
else
|
||||
return attack_hand(user)
|
||||
|
||||
/turf/closed/mineral/proc/gets_drilled()
|
||||
/turf/closed/mineral/attack_hand(mob/user)
|
||||
if(!weak_turf)
|
||||
return ..()
|
||||
var/turf/user_turf = user.loc
|
||||
if (!isturf(user_turf))
|
||||
return
|
||||
if(last_act + MINING_MESSAGE_COOLDOWN > world.time)//prevents message spam
|
||||
return
|
||||
last_act = world.time
|
||||
to_chat(user, "<span class='notice'>You start pulling out pieces of [src] with your hands...</span>")
|
||||
if(!do_after(user, 15 SECONDS, target = src))
|
||||
return
|
||||
if(ismineralturf(src))
|
||||
to_chat(user, "<span class='notice'>You finish pulling apart [src].</span>")
|
||||
gets_drilled(user)
|
||||
|
||||
/turf/closed/mineral/proc/gets_drilled(user, give_exp = FALSE)
|
||||
if (mineralType && (mineralAmt > 0))
|
||||
new mineralType(src, mineralAmt)
|
||||
SSblackbox.record_feedback("tally", "ore_mined", mineralAmt, mineralType)
|
||||
// if(ishuman(user))
|
||||
// var/mob/living/carbon/human/H = user
|
||||
// if(give_exp)
|
||||
// if (mineralType && (mineralAmt > 0))
|
||||
// H.mind.adjust_experience(/datum/skill/mining, initial(mineralType.mine_experience) * mineralAmt)
|
||||
// else
|
||||
// H.mind.adjust_experience(/datum/skill/mining, 4)
|
||||
|
||||
for(var/obj/effect/temp_visual/mining_overlay/M in src)
|
||||
qdel(M)
|
||||
var/flags = NONE
|
||||
if(defer_change) // TODO: make the defer change var a var for any changeturf flag
|
||||
flags = CHANGETURF_DEFER_CHANGE
|
||||
ScrapeAway(null, flags)
|
||||
var/turf/open/mined = ScrapeAway(null, flags)
|
||||
addtimer(CALLBACK(src, .proc/AfterChange), 1, TIMER_UNIQUE)
|
||||
playsound(src, 'sound/effects/break_stone.ogg', 50, 1) //beautiful destruction
|
||||
playsound(src, 'sound/effects/break_stone.ogg', 50, TRUE) //beautiful destruction
|
||||
mined.update_visuals()
|
||||
|
||||
/turf/closed/mineral/attack_animal(mob/living/simple_animal/user)
|
||||
/turf/closed/mineral/attack_animal(mob/living/simple_animal/user, list/modifiers)
|
||||
if((user.environment_smash & ENVIRONMENT_SMASH_WALLS) || (user.environment_smash & ENVIRONMENT_SMASH_RWALLS))
|
||||
gets_drilled()
|
||||
gets_drilled(user)
|
||||
..()
|
||||
|
||||
/turf/closed/mineral/attack_alien(mob/living/carbon/alien/M)
|
||||
to_chat(M, "<span class='notice'>You start digging into the rock...</span>")
|
||||
playsound(src, 'sound/effects/break_stone.ogg', 50, 1)
|
||||
if(do_after(M, 40, target = src))
|
||||
to_chat(M, "<span class='notice'>You tunnel into the rock.</span>")
|
||||
gets_drilled(M)
|
||||
/turf/closed/mineral/attack_alien(mob/living/carbon/alien/user, list/modifiers)
|
||||
to_chat(user, "<span class='notice'>You start digging into the rock...</span>")
|
||||
playsound(src, 'sound/effects/break_stone.ogg', 50, TRUE)
|
||||
if(do_after(user, 4 SECONDS, target = src))
|
||||
to_chat(user, "<span class='notice'>You tunnel into the rock.</span>")
|
||||
gets_drilled(user)
|
||||
|
||||
/turf/closed/mineral/attack_hulk(mob/living/carbon/human/H)
|
||||
..()
|
||||
if(do_after(H, 50, target = src))
|
||||
playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE)
|
||||
H.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
|
||||
gets_drilled(H)
|
||||
return TRUE
|
||||
|
||||
/turf/closed/mineral/Bumped(atom/movable/AM)
|
||||
..()
|
||||
@@ -128,72 +176,57 @@
|
||||
switch(severity)
|
||||
if(3)
|
||||
if (prob(75))
|
||||
gets_drilled(null, 1)
|
||||
gets_drilled(null, FALSE)
|
||||
if(2)
|
||||
if (prob(90))
|
||||
gets_drilled(null, 1)
|
||||
gets_drilled(null, FALSE)
|
||||
if(1)
|
||||
gets_drilled(null, 1)
|
||||
gets_drilled(null, FALSE)
|
||||
return
|
||||
|
||||
/turf/closed/mineral/Spread(turf/T)
|
||||
T.ChangeTurf(type)
|
||||
|
||||
/turf/closed/mineral/random
|
||||
var/list/mineralSpawnChanceList = list(/turf/closed/mineral/uranium = 5, /turf/closed/mineral/diamond = 1, /turf/closed/mineral/gold = 10,
|
||||
/turf/closed/mineral/silver = 12, /turf/closed/mineral/plasma = 20, /turf/closed/mineral/iron = 40, /turf/closed/mineral/titanium = 11,
|
||||
/turf/closed/mineral/gibtonite = 4, /turf/open/floor/plating/asteroid/airless/cave = 2, /turf/closed/mineral/bscrystal = 1)
|
||||
var/list/mineralSpawnChanceList = list(/obj/item/stack/ore/uranium = 5, /obj/item/stack/ore/diamond = 1, /obj/item/stack/ore/gold = 10,
|
||||
/obj/item/stack/ore/silver = 12, /obj/item/stack/ore/plasma = 20, /obj/item/stack/ore/iron = 40, /obj/item/stack/ore/titanium = 11,
|
||||
/turf/closed/mineral/gibtonite = 4, /obj/item/stack/ore/bluespace_crystal = 1)
|
||||
//Currently, Adamantine won't spawn as it has no uses. -Durandan
|
||||
var/mineralChance = 13
|
||||
var/display_icon_state = "rock"
|
||||
|
||||
/turf/closed/mineral/random/more_caves
|
||||
mineralSpawnChanceList = list(/turf/closed/mineral/uranium = 5, /turf/closed/mineral/diamond = 1, /turf/closed/mineral/gold = 10,
|
||||
/turf/closed/mineral/silver = 12, /turf/closed/mineral/plasma = 20, /turf/closed/mineral/iron = 40, /turf/closed/mineral/titanium = 11,
|
||||
/turf/closed/mineral/gibtonite = 4, /turf/open/floor/plating/asteroid/airless/cave = 15, /turf/closed/mineral/bscrystal = 1)
|
||||
|
||||
/turf/closed/mineral/random/Initialize()
|
||||
|
||||
mineralSpawnChanceList = typelist("mineralSpawnChanceList", mineralSpawnChanceList)
|
||||
|
||||
if (display_icon_state)
|
||||
icon_state = display_icon_state
|
||||
. = ..()
|
||||
if (prob(mineralChance))
|
||||
var/path = pickweight(mineralSpawnChanceList)
|
||||
var/turf/T = ChangeTurf(path,null,CHANGETURF_IGNORE_AIR)
|
||||
if(ispath(path, /turf))
|
||||
var/stored_flags = 0
|
||||
if(flags_1 & NO_RUINS_1)
|
||||
stored_flags |= NO_RUINS_1
|
||||
var/turf/T = ChangeTurf(path,null,CHANGETURF_IGNORE_AIR)
|
||||
T.flags_1 |= stored_flags
|
||||
|
||||
if(T && ismineralturf(T))
|
||||
var/turf/closed/mineral/M = T
|
||||
M.mineralAmt = rand(1, 5)
|
||||
M.environment_type = src.environment_type
|
||||
M.turf_type = src.turf_type
|
||||
M.baseturfs = src.baseturfs
|
||||
src = M
|
||||
M.levelupdate()
|
||||
T.baseturfs = src.baseturfs
|
||||
if(ismineralturf(T))
|
||||
var/turf/closed/mineral/M = T
|
||||
M.turf_type = src.turf_type
|
||||
M.mineralAmt = rand(1, 5)
|
||||
M.environment_type = src.environment_type
|
||||
src = M
|
||||
M.levelupdate()
|
||||
else
|
||||
src = T
|
||||
T.levelupdate()
|
||||
|
||||
|
||||
/turf/closed/mineral/random/no_caves
|
||||
mineralSpawnChanceList = list(/turf/closed/mineral/uranium = 5, /turf/closed/mineral/diamond = 1, /turf/closed/mineral/gold = 10,
|
||||
/turf/closed/mineral/silver = 12, /turf/closed/mineral/plasma = 20, /turf/closed/mineral/iron = 40, /turf/closed/mineral/titanium = 11,
|
||||
/turf/closed/mineral/gibtonite = 4, /turf/closed/mineral/bscrystal = 1)
|
||||
|
||||
/turf/closed/mineral/random/no_caves/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
turf_type = /turf/open/floor/plating/asteroid
|
||||
baseturfs = /turf/open/floor/plating/asteroid
|
||||
mineralSpawnChanceList = list(/turf/closed/mineral/uranium/earth_like = 5, /turf/closed/mineral/diamond/earth_like = 1, /turf/closed/mineral/gold/earth_like = 10,
|
||||
/turf/closed/mineral/silver/earth_like = 12, /turf/closed/mineral/plasma/earth_like = 20, /turf/closed/mineral/iron/earth_like = 40,
|
||||
/turf/closed/mineral/titanium/earth_like = 11, /turf/closed/mineral/gibtonite/earth_like = 4, /turf/closed/mineral/bscrystal/earth_like = 1)
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
else
|
||||
Change_Ore(path, 1)
|
||||
Spread_Vein(path)
|
||||
|
||||
/turf/closed/mineral/random/high_chance
|
||||
icon_state = "rock_highchance"
|
||||
mineralChance = 25
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium = 35, /turf/closed/mineral/diamond = 30, /turf/closed/mineral/gold = 45, /turf/closed/mineral/titanium = 45,
|
||||
/turf/closed/mineral/silver = 50, /turf/closed/mineral/plasma = 50, /turf/closed/mineral/bscrystal = 20)
|
||||
/obj/item/stack/ore/uranium = 35, /obj/item/stack/ore/diamond = 30, /obj/item/stack/ore/gold = 45, /obj/item/stack/ore/titanium = 45,
|
||||
/obj/item/stack/ore/silver = 50, /obj/item/stack/ore/plasma = 50, /obj/item/stack/ore/bluespace_crystal = 20)
|
||||
|
||||
/turf/closed/mineral/random/high_chance/volcanic
|
||||
environment_type = "basalt"
|
||||
@@ -202,55 +235,16 @@
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/volcanic = 35, /turf/closed/mineral/diamond/volcanic = 30, /turf/closed/mineral/gold/volcanic = 45, /turf/closed/mineral/titanium/volcanic = 45,
|
||||
/turf/closed/mineral/silver/volcanic = 50, /turf/closed/mineral/plasma/volcanic = 50, /turf/closed/mineral/bscrystal/volcanic = 20)
|
||||
|
||||
/turf/closed/mineral/random/high_chance/snow
|
||||
name = "snowy mountainside"
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
smooth_icon = 'icons/turf/walls/mountain_wall.dmi'
|
||||
icon_state = "mountainrock"
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
canSmoothWith = list (/turf/closed)
|
||||
defer_change = TRUE
|
||||
environment_type = "snow"
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/ice/icemoon = 35, /turf/closed/mineral/diamond/ice/icemoon = 30, /turf/closed/mineral/gold/ice/icemoon = 45, /turf/closed/mineral/titanium/ice/icemoon = 45,
|
||||
/turf/closed/mineral/silver/ice/icemoon = 50, /turf/closed/mineral/plasma/ice/icemoon = 50, /turf/closed/mineral/bscrystal/ice/icemoon = 20)
|
||||
|
||||
/turf/closed/mineral/random/high_chance/earth_like
|
||||
icon_state = "rock_highchance_oxy"
|
||||
turf_type = /turf/open/floor/plating/asteroid
|
||||
baseturfs = /turf/open/floor/plating/asteroid
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/earth_like = 35, /turf/closed/mineral/diamond/earth_like = 30, /turf/closed/mineral/gold/earth_like = 45,
|
||||
/turf/closed/mineral/titanium/earth_like = 45, /turf/closed/mineral/silver/earth_like = 50, /turf/closed/mineral/plasma/earth_like = 50,
|
||||
/turf/closed/mineral/bscrystal/earth_like = 20)
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/obj/item/stack/ore/uranium = 35, /obj/item/stack/ore/diamond = 30, /obj/item/stack/ore/gold = 45, /obj/item/stack/ore/titanium = 45,
|
||||
/obj/item/stack/ore/silver = 50, /obj/item/stack/ore/plasma = 50, /obj/item/stack/ore/bluespace_crystal)
|
||||
|
||||
/turf/closed/mineral/random/low_chance
|
||||
icon_state = "rock_lowchance"
|
||||
mineralChance = 6
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium = 2, /turf/closed/mineral/diamond = 1, /turf/closed/mineral/gold = 4, /turf/closed/mineral/titanium = 4,
|
||||
/turf/closed/mineral/silver = 6, /turf/closed/mineral/plasma = 15, /turf/closed/mineral/iron = 40,
|
||||
/turf/closed/mineral/gibtonite = 2, /turf/closed/mineral/bscrystal = 1)
|
||||
|
||||
/turf/closed/mineral/random/low_chance/earth_like
|
||||
icon_state = "rock_lowchance_oxy"
|
||||
turf_type = /turf/open/floor/plating/asteroid
|
||||
baseturfs = /turf/open/floor/plating/asteroid
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/earth_like = 2, /turf/closed/mineral/diamond/earth_like = 1, /turf/closed/mineral/gold/earth_like = 4,
|
||||
/turf/closed/mineral/titanium/earth_like = 4, /turf/closed/mineral/silver/earth_like = 6, /turf/closed/mineral/plasma/earth_like = 15,
|
||||
/turf/closed/mineral/iron/earth_like = 40, /turf/closed/mineral/gibtonite/earth_like = 2, /turf/closed/mineral/bscrystal/earth_like = 1)
|
||||
defer_change = TRUE
|
||||
/obj/item/stack/ore/uranium = 2, /obj/item/stack/ore/diamond = 1, /obj/item/stack/ore/gold = 4, /obj/item/stack/ore/titanium = 4,
|
||||
/obj/item/stack/ore/silver = 6, /obj/item/stack/ore/plasma = 15, /obj/item/stack/ore/iron = 40,
|
||||
/turf/closed/mineral/gibtonite = 2, /obj/item/stack/ore/bluespace_crystal = 1)
|
||||
|
||||
/turf/closed/mineral/random/volcanic
|
||||
environment_type = "basalt"
|
||||
@@ -261,15 +255,9 @@
|
||||
|
||||
mineralChance = 10
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/volcanic = 5, /turf/closed/mineral/diamond/volcanic = 1, /turf/closed/mineral/gold/volcanic = 10, /turf/closed/mineral/titanium/volcanic = 11,
|
||||
/turf/closed/mineral/silver/volcanic = 12, /turf/closed/mineral/plasma/volcanic = 20, /turf/closed/mineral/iron/volcanic = 40,
|
||||
/turf/closed/mineral/gibtonite/volcanic = 4, /turf/open/floor/plating/asteroid/airless/cave/volcanic = 1, /turf/closed/mineral/bscrystal/volcanic = 1)
|
||||
|
||||
/turf/closed/mineral/random/volcanic/more_caves
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/volcanic = 5, /turf/closed/mineral/diamond/volcanic = 1, /turf/closed/mineral/gold/volcanic = 10, /turf/closed/mineral/titanium/volcanic = 11,
|
||||
/turf/closed/mineral/silver/volcanic = 12, /turf/closed/mineral/plasma/volcanic = 20, /turf/closed/mineral/iron/volcanic = 40,
|
||||
/turf/closed/mineral/gibtonite/volcanic = 4, /turf/open/floor/plating/asteroid/airless/cave/volcanic = 15, /turf/closed/mineral/bscrystal/volcanic = 1)
|
||||
/obj/item/stack/ore/uranium = 5, /obj/item/stack/ore/diamond = 1, /obj/item/stack/ore/gold = 10, /obj/item/stack/ore/titanium = 11,
|
||||
/obj/item/stack/ore/silver = 12, /obj/item/stack/ore/plasma = 20, /obj/item/stack/ore/iron = 40,
|
||||
/turf/closed/mineral/gibtonite/volcanic = 4, /obj/item/stack/ore/bluespace_crystal = 1)
|
||||
|
||||
/turf/closed/mineral/random/snow
|
||||
name = "snowy mountainside"
|
||||
@@ -283,38 +271,43 @@
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
weak_turf = TRUE
|
||||
|
||||
mineralChance = 10
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/ice/icemoon = 5, /turf/closed/mineral/diamond/ice/icemoon = 1, /turf/closed/mineral/gold/ice/icemoon = 10, /turf/closed/mineral/titanium/ice/icemoon = 11,
|
||||
/turf/closed/mineral/silver/ice/icemoon = 12, /turf/closed/mineral/plasma/ice/icemoon = 20, /turf/closed/mineral/iron/ice/icemoon = 40,
|
||||
/turf/closed/mineral/gibtonite/ice/icemoon = 4, /turf/open/floor/plating/asteroid/airless/cave/snow = 1, /turf/closed/mineral/bscrystal/ice/icemoon = 1)
|
||||
/turf/closed/mineral/random/snow/Change_Ore(ore_type, random = 0)
|
||||
. = ..()
|
||||
if(mineralType)
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
icon_state = "icerock_wall-0"
|
||||
// base_icon_state = "icerock_wall"
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
|
||||
/turf/closed/mineral/random/snow/no_caves
|
||||
/turf/closed/mineral/random/snow
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/ice/icemoon = 5, /turf/closed/mineral/diamond/ice/icemoon = 1, /turf/closed/mineral/gold/ice/icemoon = 10, /turf/closed/mineral/titanium/ice/icemoon = 11,
|
||||
/turf/closed/mineral/silver/ice/icemoon = 12, /turf/closed/mineral/plasma/ice/icemoon = 20, /turf/closed/mineral/iron/ice/icemoon = 40,
|
||||
/turf/closed/mineral/gibtonite/ice/icemoon = 4, /turf/closed/mineral/bscrystal/ice/icemoon = 1)
|
||||
|
||||
/turf/closed/mineral/random/labormineral
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium = 3, /turf/closed/mineral/diamond = 1, /turf/closed/mineral/gold = 8, /turf/closed/mineral/titanium = 8,
|
||||
/turf/closed/mineral/silver = 20, /turf/closed/mineral/plasma = 30, /turf/closed/mineral/iron = 95,
|
||||
/turf/closed/mineral/gibtonite = 2)
|
||||
icon_state = "rock_labor"
|
||||
/obj/item/stack/ore/uranium = 5, /obj/item/stack/ore/diamond = 1, /obj/item/stack/ore/gold = 10, /obj/item/stack/ore/titanium = 11,
|
||||
/obj/item/stack/ore/silver = 12, /obj/item/stack/ore/plasma = 20, /obj/item/stack/ore/iron = 40,
|
||||
/turf/closed/mineral/gibtonite/ice/icemoon = 4, /obj/item/stack/ore/bluespace_crystal = 1)
|
||||
|
||||
/turf/closed/mineral/random/snow/underground
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
// abundant ore
|
||||
mineralChance = 20
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/ice/icemoon = 5, /turf/closed/mineral/diamond/ice/icemoon = 1, /turf/closed/mineral/gold/ice/icemoon = 10, /turf/closed/mineral/titanium/ice/icemoon = 11,
|
||||
/turf/closed/mineral/silver/ice/icemoon = 12, /turf/closed/mineral/plasma/ice/icemoon = 20, /turf/closed/mineral/iron/ice/icemoon = 40,
|
||||
/turf/closed/mineral/gibtonite/ice/icemoon = 4, /turf/open/floor/plating/asteroid/airless/cave/snow/underground = 1, /turf/closed/mineral/bscrystal/ice/icemoon = 1)
|
||||
/obj/item/stack/ore/uranium = 10, /obj/item/stack/ore/diamond = 4, /obj/item/stack/ore/gold = 20, /obj/item/stack/ore/titanium = 22,
|
||||
/obj/item/stack/ore/silver = 24, /obj/item/stack/ore/plasma = 20, /obj/item/stack/ore/iron = 20, /obj/item/stack/ore/bananium = 1,
|
||||
/turf/closed/mineral/gibtonite/ice/icemoon = 8, /obj/item/stack/ore/bluespace_crystal = 2)
|
||||
|
||||
/turf/closed/mineral/random/snow/more_caves
|
||||
/turf/closed/mineral/random/snow/high_chance
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/ice/icemoon = 5, /turf/closed/mineral/diamond/ice/icemoon = 1, /turf/closed/mineral/gold/ice/icemoon = 10, /turf/closed/mineral/titanium/ice/icemoon = 11,
|
||||
/turf/closed/mineral/silver/ice/icemoon = 12, /turf/closed/mineral/plasma/ice/icemoon = 20, /turf/closed/mineral/iron/ice/icemoon = 40,
|
||||
/turf/closed/mineral/gibtonite/ice/icemoon = 4, /turf/open/floor/plating/asteroid/airless/cave/snow = 15, /turf/closed/mineral/bscrystal/ice/icemoon = 1)
|
||||
/obj/item/stack/ore/uranium = 35, /obj/item/stack/ore/diamond = 30, /obj/item/stack/ore/gold = 45, /obj/item/stack/ore/titanium = 45,
|
||||
/obj/item/stack/ore/silver = 50, /obj/item/stack/ore/plasma = 50, /obj/item/stack/ore/bluespace_crystal = 20)
|
||||
|
||||
/turf/closed/mineral/random/labormineral
|
||||
icon_state = "rock_labor"
|
||||
mineralSpawnChanceList = list(
|
||||
/obj/item/stack/ore/uranium = 3, /obj/item/stack/ore/diamond = 1, /obj/item/stack/ore/gold = 8, /obj/item/stack/ore/titanium = 8,
|
||||
/obj/item/stack/ore/silver = 20, /obj/item/stack/ore/plasma = 30, /obj/item/stack/ore/iron = 95,
|
||||
/turf/closed/mineral/gibtonite = 2)
|
||||
|
||||
/turf/closed/mineral/random/labormineral/volcanic
|
||||
environment_type = "basalt"
|
||||
@@ -323,16 +316,17 @@
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/volcanic = 3, /turf/closed/mineral/diamond/volcanic = 1, /turf/closed/mineral/gold/volcanic = 8, /turf/closed/mineral/titanium/volcanic = 8,
|
||||
/turf/closed/mineral/silver/volcanic = 20, /turf/closed/mineral/plasma/volcanic = 30, /turf/closed/mineral/bscrystal/volcanic = 1, /turf/closed/mineral/gibtonite/volcanic = 2,
|
||||
/turf/closed/mineral/iron/volcanic = 95)
|
||||
/obj/item/stack/ore/uranium = 3, /obj/item/stack/ore/diamond = 1, /obj/item/stack/ore/gold = 8, /obj/item/stack/ore/titanium = 8,
|
||||
/obj/item/stack/ore/silver = 20, /obj/item/stack/ore/plasma = 30, /obj/item/stack/ore/bluespace_crystal = 1, /turf/closed/mineral/gibtonite/volcanic = 2,
|
||||
/obj/item/stack/ore/iron = 95)
|
||||
|
||||
//Subtypes for placing ores manually.
|
||||
// Subtypes for mappers placing ores manually.
|
||||
/turf/closed/mineral/random/labormineral/ice
|
||||
name = "snowy mountainside"
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
smooth_icon = 'icons/turf/walls/mountain_wall.dmi'
|
||||
icon_state = "mountainrock"
|
||||
// base_icon_state = "mountain_wall"
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
canSmoothWith = list (/turf/closed)
|
||||
defer_change = TRUE
|
||||
@@ -340,124 +334,57 @@
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
defer_change = TRUE
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/ice/icemoon = 3, /turf/closed/mineral/diamond/ice/icemoon = 1, /turf/closed/mineral/gold/ice/icemoon = 8, /turf/closed/mineral/titanium/ice/icemoon = 8,
|
||||
/turf/closed/mineral/silver/ice/icemoon = 20, /turf/closed/mineral/plasma/ice/icemoon = 30, /turf/closed/mineral/bscrystal/ice/icemoon = 1, /turf/closed/mineral/gibtonite/ice/icemoon = 2,
|
||||
/turf/closed/mineral/iron/ice/icemoon = 95)
|
||||
|
||||
/obj/item/stack/ore/uranium = 3, /obj/item/stack/ore/diamond = 1, /obj/item/stack/ore/gold = 8, /obj/item/stack/ore/titanium = 8,
|
||||
/obj/item/stack/ore/silver = 20, /obj/item/stack/ore/plasma = 30, /obj/item/stack/ore/bluespace_crystal = 1, /turf/closed/mineral/gibtonite/volcanic = 2,
|
||||
/obj/item/stack/ore/iron = 95)
|
||||
|
||||
/turf/closed/mineral/random/labormineral/ice/Change_Ore(ore_type, random = 0)
|
||||
. = ..()
|
||||
if(mineralType)
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
icon_state = "icerock_wall-0"
|
||||
// base_icon_state = "icerock_wall"
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
|
||||
/turf/closed/mineral/iron
|
||||
mineralType = /obj/item/stack/ore/iron
|
||||
spreadChance = 20
|
||||
spread = 1
|
||||
scan_state = "rock_Iron"
|
||||
|
||||
/turf/closed/mineral/iron/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = 1
|
||||
|
||||
/turf/closed/mineral/iron/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
turf_type = /turf/open/floor/plating/asteroid
|
||||
baseturfs = /turf/open/floor/plating/asteroid
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/iron/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_iron"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
// base_icon_state = "icerock_wall"
|
||||
// smoothing_flags = SMOOTH_BITMASK | SMOOTH_BORDER
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/iron/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
|
||||
/turf/closed/mineral/uranium
|
||||
mineralType = /obj/item/stack/ore/uranium
|
||||
spreadChance = 5
|
||||
spread = 1
|
||||
scan_state = "rock_Uranium"
|
||||
|
||||
/turf/closed/mineral/uranium/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/uranium/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_Uranium"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/uranium/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/closed/mineral/uranium/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
turf_type = /turf/open/floor/plating/asteroid
|
||||
baseturfs = /turf/open/floor/plating/asteroid
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
|
||||
/turf/closed/mineral/diamond
|
||||
mineralType = /obj/item/stack/ore/diamond
|
||||
spreadChance = 0
|
||||
spread = 1
|
||||
scan_state = "rock_Diamond"
|
||||
|
||||
/turf/closed/mineral/diamond/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/diamond/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
turf_type = /turf/open/floor/plating/asteroid
|
||||
baseturfs = /turf/open/floor/plating/asteroid
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/diamond/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_diamond"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
// base_icon_state = "icerock_wall"
|
||||
// smoothing_flags = SMOOTH_BITMASK | SMOOTH_BORDER
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/diamond/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
|
||||
/turf/closed/mineral/gold
|
||||
mineralType = /obj/item/stack/ore/gold
|
||||
spreadChance = 5
|
||||
spread = 1
|
||||
scan_state = "rock_Gold"
|
||||
|
||||
/turf/closed/mineral/gold/volcanic
|
||||
@@ -467,56 +394,10 @@
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/gold/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
turf_type = /turf/open/floor/plating/asteroid
|
||||
baseturfs = /turf/open/floor/plating/asteroid
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/gold/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_gold"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/gold/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/closed/mineral/silver
|
||||
mineralType = /obj/item/stack/ore/silver
|
||||
spreadChance = 5
|
||||
spread = 1
|
||||
scan_state = "rock_Silver"
|
||||
|
||||
/turf/closed/mineral/silver/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/silver/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
turf_type = /turf/open/floor/plating/asteroid
|
||||
baseturfs = /turf/open/floor/plating/asteroid
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/silver/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_silver"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/silver/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
@@ -524,107 +405,31 @@
|
||||
|
||||
/turf/closed/mineral/titanium
|
||||
mineralType = /obj/item/stack/ore/titanium
|
||||
spreadChance = 5
|
||||
spread = 1
|
||||
scan_state = "rock_Titanium"
|
||||
|
||||
/turf/closed/mineral/titanium/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/titanium/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
turf_type = /turf/open/floor/plating/asteroid
|
||||
baseturfs = /turf/open/floor/plating/asteroid
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/titanium/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_titanium"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/titanium/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/closed/mineral/plasma
|
||||
mineralType = /obj/item/stack/ore/plasma
|
||||
spreadChance = 8
|
||||
spread = 1
|
||||
scan_state = "rock_Plasma"
|
||||
|
||||
/turf/closed/mineral/plasma/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/plasma/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
turf_type = /turf/open/floor/plating/asteroid
|
||||
baseturfs = /turf/open/floor/plating/asteroid
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/plasma/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_plasma"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
// base_icon_state = "icerock_wall"
|
||||
// smoothing_flags = SMOOTH_BITMASK | SMOOTH_BORDER
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/plasma/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
|
||||
/turf/closed/mineral/bananium
|
||||
mineralType = /obj/item/stack/ore/bananium
|
||||
mineralAmt = 3
|
||||
spreadChance = 0
|
||||
spread = 0
|
||||
scan_state = "rock_Bananium"
|
||||
|
||||
/turf/closed/mineral/bananium/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
turf_type = /turf/open/floor/plating/asteroid
|
||||
baseturfs = /turf/open/floor/plating/asteroid
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/bananium/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_Bananium"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/bananium/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
|
||||
/turf/closed/mineral/bscrystal
|
||||
mineralType = /obj/item/stack/ore/bluespace_crystal
|
||||
mineralAmt = 1
|
||||
spreadChance = 0
|
||||
spread = 0
|
||||
scan_state = "rock_BScrystal"
|
||||
|
||||
/turf/closed/mineral/bscrystal/volcanic
|
||||
@@ -634,27 +439,6 @@
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/bscrystal/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
turf_type = /turf/open/floor/plating/asteroid
|
||||
baseturfs = /turf/open/floor/plating/asteroid
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/bscrystal/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_BScrystal"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/bscrystal/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/closed/mineral/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt
|
||||
@@ -667,18 +451,12 @@
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
turf_type = /turf/open/floor/plating/asteroid
|
||||
baseturfs = /turf/open/floor/plating/asteroid
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/ash_rock //wall piece
|
||||
name = "rock"
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
smooth_icon = 'icons/turf/walls/rock_wall.dmi'
|
||||
icon_state = "rock2"
|
||||
// base_icon_state = "rock_wall"
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
canSmoothWith = list (/turf/closed)
|
||||
baseturfs = /turf/open/floor/plating/ashplanet/wateryrock
|
||||
@@ -692,6 +470,7 @@
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
smooth_icon = 'icons/turf/walls/mountain_wall.dmi'
|
||||
icon_state = "mountainrock"
|
||||
// base_icon_state = "mountain_wall"
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
canSmoothWith = list (/turf/closed)
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow
|
||||
@@ -710,6 +489,7 @@
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
icon_state = "icerock"
|
||||
// base_icon_state = "icerock_wall"
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
canSmoothWith = list (/turf/closed)
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
@@ -725,8 +505,6 @@
|
||||
|
||||
/turf/closed/mineral/gibtonite
|
||||
mineralAmt = 1
|
||||
spreadChance = 0
|
||||
spread = 0
|
||||
scan_state = "rock_Gibtonite"
|
||||
var/det_time = 8 //Countdown till explosion, but also rewards the player for how close you were to detonation when you defuse it
|
||||
var/stage = GIBTONITE_UNSTRUCK //How far into the lifecycle of gibtonite we are
|
||||
@@ -746,21 +524,15 @@
|
||||
|
||||
/turf/closed/mineral/gibtonite/proc/explosive_reaction(mob/user = null, triggered_by_explosion = 0)
|
||||
if(stage == GIBTONITE_UNSTRUCK)
|
||||
activated_overlay = mutable_appearance('icons/turf/smoothrocks.dmi', "rock_Gibtonite_active", ON_EDGED_TURF_LAYER)
|
||||
activated_overlay = mutable_appearance('icons/turf/smoothrocks.dmi', "rock_Gibtonite_inactive", ON_EDGED_TURF_LAYER) //shows in gaps between pulses if there are any
|
||||
add_overlay(activated_overlay)
|
||||
name = "gibtonite deposit"
|
||||
desc = "An active gibtonite reserve. Run!"
|
||||
stage = GIBTONITE_ACTIVE
|
||||
visible_message("<span class='danger'>There was gibtonite inside! It's going to explode!</span>")
|
||||
var/turf/bombturf = get_turf(src)
|
||||
visible_message("<span class='danger'>There's gibtonite inside! It's going to explode!</span>")
|
||||
|
||||
var/notify_admins = 0
|
||||
if(z != 5)
|
||||
notify_admins = 1
|
||||
if(!triggered_by_explosion)
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] has triggered a gibtonite deposit reaction at [ADMIN_VERBOSEJMP(bombturf)].")
|
||||
else
|
||||
message_admins("An explosion has triggered a gibtonite deposit reaction at [ADMIN_VERBOSEJMP(bombturf)].")
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/notify_admins = !is_mining_level(z)
|
||||
|
||||
if(!triggered_by_explosion)
|
||||
log_game("[key_name(user)] has triggered a gibtonite deposit reaction at [AREACOORD(bombturf)].")
|
||||
@@ -769,9 +541,10 @@
|
||||
|
||||
countdown(notify_admins)
|
||||
|
||||
/turf/closed/mineral/gibtonite/proc/countdown(notify_admins = 0)
|
||||
set waitfor = 0
|
||||
/turf/closed/mineral/gibtonite/proc/countdown(notify_admins = FALSE)
|
||||
set waitfor = FALSE
|
||||
while(istype(src, /turf/closed/mineral/gibtonite) && stage == GIBTONITE_ACTIVE && det_time > 0 && mineralAmt >= 1)
|
||||
flick_overlay_view(image('icons/turf/smoothrocks.dmi', src, "rock_Gibtonite_active"), src, 5) //makes the animation pulse one time per tick
|
||||
det_time--
|
||||
sleep(5)
|
||||
if(istype(src, /turf/closed/mineral/gibtonite))
|
||||
@@ -790,18 +563,18 @@
|
||||
stage = GIBTONITE_STABLE
|
||||
if(det_time < 0)
|
||||
det_time = 0
|
||||
visible_message("<span class='notice'>The chain reaction was stopped! The gibtonite had [det_time] reactions left till the explosion!</span>")
|
||||
visible_message("<span class='notice'>The chain reaction stopped! The gibtonite had [det_time] reactions left till the explosion!</span>")
|
||||
|
||||
/turf/closed/mineral/gibtonite/gets_drilled(mob/user, triggered_by_explosion = 0)
|
||||
/turf/closed/mineral/gibtonite/gets_drilled(mob/user, triggered_by_explosion = FALSE)
|
||||
if(stage == GIBTONITE_UNSTRUCK && mineralAmt >= 1) //Gibtonite deposit is activated
|
||||
playsound(src,'sound/effects/hit_on_shattered_glass.ogg',50,1)
|
||||
playsound(src,'sound/effects/hit_on_shattered_glass.ogg',50,TRUE)
|
||||
explosive_reaction(user, triggered_by_explosion)
|
||||
return
|
||||
if(stage == GIBTONITE_ACTIVE && mineralAmt >= 1) //Gibtonite deposit goes kaboom
|
||||
var/turf/bombturf = get_turf(src)
|
||||
mineralAmt = 0
|
||||
stage = GIBTONITE_DETONATE
|
||||
explosion(bombturf,1,2,5, adminlog = 0)
|
||||
explosion(bombturf,1,2,5, adminlog = FALSE)
|
||||
if(stage == GIBTONITE_STABLE) //Gibtonite deposit is now benign and extractable. Depending on how close you were to it blowing up before defusing, you get better quality ore.
|
||||
var/obj/item/gibtonite/G = new (src)
|
||||
if(det_time <= 0)
|
||||
@@ -825,18 +598,12 @@
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/gibtonite/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
turf_type = /turf/open/floor/plating/asteroid
|
||||
baseturfs = /turf/open/floor/plating/asteroid
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
|
||||
/turf/closed/mineral/gibtonite/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_Gibtonite"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
// base_icon_state = "icerock_wall"
|
||||
// smoothing_flags = SMOOTH_BITMASK | SMOOTH_BORDER
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
@@ -856,18 +623,18 @@
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = 1
|
||||
smooth_icon = 'icons/turf/walls/rock_wall.dmi'
|
||||
// base_icon_state = "rock_wall"
|
||||
// smoothing_flags = SMOOTH_BITMASK | SMOOTH_BORDER
|
||||
|
||||
// /turf/closed/mineral/strong/attackby(obj/item/I, mob/user, params)
|
||||
// if(!ishuman(user))
|
||||
// to_chat(usr, "<span class='warning'>Only a more advanced species could break a rock such as this one!</span>")
|
||||
// return FALSE
|
||||
// if(user.mind?.get_skill_level(/datum/skill/mining) >= SKILL_LEVEL_MASTER)
|
||||
// . = ..()
|
||||
// else
|
||||
// to_chat(usr, "<span class='warning'>The rock seems to be too strong to destroy. Maybe I can break it once I become a master miner.</span>")
|
||||
|
||||
/*
|
||||
/turf/closed/mineral/strong/attackby(obj/item/I, mob/user, params)
|
||||
if(!ishuman(user))
|
||||
to_chat(usr, "<span class='warning'>Only a more advanced species could break a rock such as this one!</span>")
|
||||
return FALSE
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.mind.get_skill_level(/datum/skill/mining) >= SKILL_LEVEL_MASTER)
|
||||
. = ..()
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>The rock seems to be too strong to destroy. Maybe I can break it once I become a master miner.</span>")
|
||||
*/
|
||||
|
||||
/turf/closed/mineral/strong/gets_drilled(mob/user)
|
||||
if(!ishuman(user))
|
||||
@@ -896,3 +663,5 @@
|
||||
|
||||
/turf/closed/mineral/strong/ex_act(severity, target)
|
||||
return
|
||||
|
||||
#undef MINING_MESSAGE_COOLDOWN
|
||||
|
||||
@@ -1,39 +1,40 @@
|
||||
GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdrop, new)
|
||||
|
||||
/atom/movable/openspace_backdrop
|
||||
name = "openspace_backdrop"
|
||||
name = "openspace_backdrop"
|
||||
|
||||
anchored = TRUE
|
||||
anchored = TRUE
|
||||
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "grey"
|
||||
plane = OPENSPACE_BACKDROP_PLANE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
layer = SPLASHSCREEN_LAYER
|
||||
//I don't know why the others are aligned but I shall do the same.
|
||||
vis_flags = VIS_INHERIT_ID
|
||||
vis_flags = VIS_INHERIT_ID
|
||||
|
||||
/turf/open/transparent/openspace
|
||||
/turf/open/openspace
|
||||
name = "open space"
|
||||
desc = "Watch your step!"
|
||||
icon_state = "transparent"
|
||||
baseturfs = /turf/open/transparent/openspace
|
||||
baseturfs = /turf/open/openspace
|
||||
CanAtmosPassVertical = ATMOS_PASS_YES
|
||||
baseturfs = /turf/open/openspace
|
||||
intact = FALSE //this means wires go on top
|
||||
//mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
var/can_cover_up = TRUE
|
||||
var/can_build_on = TRUE
|
||||
|
||||
/turf/open/transparent/openspace/airless
|
||||
/turf/open/openspace/airless
|
||||
initial_gas_mix = AIRLESS_ATMOS
|
||||
|
||||
/turf/open/transparent/openspace/debug/update_multiz()
|
||||
..()
|
||||
return TRUE
|
||||
// /turf/open/transparent/openspace/debug/update_multiz()
|
||||
// ..()
|
||||
// return TRUE
|
||||
|
||||
///No bottom level for openspace.
|
||||
/turf/open/transparent/openspace/show_bottom_level()
|
||||
return FALSE
|
||||
// ///No bottom level for openspace.
|
||||
// /turf/open/transparent/openspace/show_bottom_level()
|
||||
// return FALSE
|
||||
|
||||
/turf/open/openspace/Initialize() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker
|
||||
. = ..()
|
||||
@@ -42,20 +43,20 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
|
||||
/turf/open/openspace/LateInitialize()
|
||||
. = ..()
|
||||
// AddElement(/datum/element/turf_z_transparency, FALSE)
|
||||
AddElement(/datum/element/turf_z_transparency, FALSE)
|
||||
|
||||
/turf/open/transparent/openspace/can_have_cabling()
|
||||
/turf/open/openspace/can_have_cabling()
|
||||
if(locate(/obj/structure/lattice/catwalk, src))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/turf/open/transparent/openspace/zAirIn()
|
||||
/turf/open/openspace/zAirIn()
|
||||
return TRUE
|
||||
|
||||
/turf/open/transparent/openspace/zAirOut()
|
||||
/turf/open/openspace/zAirOut()
|
||||
return TRUE
|
||||
|
||||
/turf/open/transparent/openspace/zPassIn(atom/movable/A, direction, turf/source)
|
||||
/turf/open/openspace/zPassIn(atom/movable/A, direction, turf/source)
|
||||
if(direction == DOWN)
|
||||
for(var/obj/O in contents)
|
||||
if(O.obj_flags & BLOCK_Z_IN_DOWN)
|
||||
@@ -68,7 +69,7 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/turf/open/transparent/openspace/zPassOut(atom/movable/A, direction, turf/destination)
|
||||
/turf/open/openspace/zPassOut(atom/movable/A, direction, turf/destination)
|
||||
if(A.anchored)
|
||||
return FALSE
|
||||
if(direction == DOWN)
|
||||
@@ -83,13 +84,13 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/turf/open/transparent/openspace/proc/CanCoverUp()
|
||||
/turf/open/openspace/proc/CanCoverUp()
|
||||
return can_cover_up
|
||||
|
||||
/turf/open/transparent/openspace/proc/CanBuildHere()
|
||||
/turf/open/openspace/proc/CanBuildHere()
|
||||
return can_build_on
|
||||
|
||||
/turf/open/transparent/openspace/attackby(obj/item/C, mob/user, params)
|
||||
/turf/open/openspace/attackby(obj/item/C, mob/user, params)
|
||||
..()
|
||||
if(!CanBuildHere())
|
||||
return
|
||||
@@ -130,9 +131,9 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need one floor tile to build a floor!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The plating is going to need some support! Place metal rods first.</span>")
|
||||
to_chat(user, "<span class='warning'>The plating is going to need some support! Place iron rods first.</span>")
|
||||
|
||||
/turf/open/transparent/openspace/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
|
||||
/turf/open/openspace/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
|
||||
if(!CanBuildHere())
|
||||
return FALSE
|
||||
|
||||
@@ -145,7 +146,7 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 3)
|
||||
return FALSE
|
||||
|
||||
/turf/open/transparent/openspace/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode)
|
||||
/turf/open/openspace/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode)
|
||||
switch(passed_mode)
|
||||
if(RCD_FLOORWALL)
|
||||
to_chat(user, "<span class='notice'>You build a floor.</span>")
|
||||
@@ -153,25 +154,33 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/turf/open/transparent/openspace/icemoon
|
||||
/turf/open/openspace/icemoon
|
||||
name = "ice chasm"
|
||||
baseturfs = /turf/open/transparent/openspace/icemoon
|
||||
baseturfs = /turf/open/openspace/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
planetary_atmos = TRUE
|
||||
var/replacement_turf = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
/// Replaces itself with replacement_turf if the turf below this one is in a no ruins allowed area (usually ruins themselves)
|
||||
var/protect_ruin = TRUE
|
||||
/// If true mineral turfs below this openspace turf will be mined automatically
|
||||
var/drill_below = TRUE
|
||||
|
||||
/turf/open/transparent/openspace/icemoon/Initialize()
|
||||
/turf/open/openspace/icemoon/Initialize()
|
||||
. = ..()
|
||||
var/turf/T = below()
|
||||
// if(T.flags_1 & NO_RUINS_1)
|
||||
// ChangeTurf(replacement_turf, null, CHANGETURF_IGNORE_AIR)
|
||||
// return
|
||||
// if(!ismineralturf(T))
|
||||
// return
|
||||
if(T.flags_1 & NO_RUINS_1 && protect_ruin)
|
||||
ChangeTurf(replacement_turf, null, CHANGETURF_IGNORE_AIR)
|
||||
return
|
||||
if(!ismineralturf(T) || !drill_below)
|
||||
return
|
||||
var/turf/closed/mineral/M = T
|
||||
M.mineralAmt = 0
|
||||
M.gets_drilled()
|
||||
baseturfs = /turf/open/transparent/openspace/icemoon //This is to ensure that IF random turf generation produces a openturf, there won't be other turfs assigned other than openspace.
|
||||
baseturfs = /turf/open/openspace/icemoon //This is to ensure that IF random turf generation produces a openturf, there won't be other turfs assigned other than openspace.
|
||||
|
||||
/turf/open/transparent/openspace/icemoon/can_zFall(atom/movable/A, levels = 1, turf/target)
|
||||
return TRUE
|
||||
/turf/open/openspace/icemoon/keep_below
|
||||
drill_below = FALSE
|
||||
|
||||
/turf/open/openspace/icemoon/ruins
|
||||
protect_ruin = FALSE
|
||||
drill_below = FALSE
|
||||
@@ -58,8 +58,8 @@
|
||||
set waitfor = FALSE
|
||||
if(!AM || istype(AM, /obj/docking_port))
|
||||
return
|
||||
if(AM.loc != src) // Multi-tile objects are "in" multiple locs but its loc is it's true placement.
|
||||
return // Don't move multi tile objects if their origin isnt in transit
|
||||
if(AM.loc != src) // Multi-tile objects are "in" multiple locs but its loc is it's true placement.
|
||||
return // Don't move multi tile objects if their origin isn't in transit
|
||||
var/max = world.maxx-TRANSITIONEDGE
|
||||
var/min = 1+TRANSITIONEDGE
|
||||
|
||||
@@ -68,6 +68,10 @@
|
||||
var/datum/space_level/D = A
|
||||
if (D.linkage == CROSSLINKED)
|
||||
possible_transtitons += D.z_value
|
||||
if(!length(possible_transtitons)) //No space to throw them to - try throwing them onto mining
|
||||
possible_transtitons = SSmapping.levels_by_trait(ZTRAIT_MINING)
|
||||
if(!length(possible_transtitons)) //Just throw them back on station, if not just runtime.
|
||||
possible_transtitons = SSmapping.levels_by_trait(ZTRAIT_STATION)
|
||||
var/_z = pick(possible_transtitons)
|
||||
|
||||
//now select coordinates for a border turf
|
||||
|
||||
@@ -131,7 +131,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
|
||||
user.Move_Pulled(src)
|
||||
|
||||
/turf/proc/multiz_turf_del(turf/T, dir)
|
||||
// SEND_SIGNAL(src, COMSIG_TURF_MULTIZ_DEL, T, dir)
|
||||
SEND_SIGNAL(src, COMSIG_TURF_MULTIZ_DEL, T, dir)
|
||||
|
||||
/turf/proc/multiz_turf_new(turf/T, dir)
|
||||
SEND_SIGNAL(src, COMSIG_TURF_MULTIZ_NEW, T, dir)
|
||||
|
||||
Reference in New Issue
Block a user