Merge branch 'master' into upstream-merge-32161

This commit is contained in:
LetterJay
2017-11-11 23:02:13 -06:00
committed by GitHub
625 changed files with 27981 additions and 20284 deletions
+21 -23
View File
@@ -41,7 +41,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
power_environ = FALSE
valid_territory = FALSE
outdoors = TRUE
ambientsounds = list('sound/ambience/ambispace.ogg','sound/ambience/title2.ogg')
ambientsounds = SPACE
blob_allowed = FALSE //Eating up space doesn't count for victory as a blob.
/area/space/nearstation
@@ -65,6 +65,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
has_gravity = TRUE
blob_allowed = FALSE //Nope, no winning on the asteroid as a blob. Gotta eat the station.
valid_territory = FALSE
ambientsounds = MINING
/area/asteroid/cave
name = "Asteroid - Underground"
@@ -75,6 +76,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/asteroid/artifactroom
name = "Asteroid - Artifact"
icon_state = "cave"
ambientsounds = RUINS
/area/asteroid/artifactroom/Initialize()
. = ..()
@@ -96,14 +98,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
//Maintenance
/area/maintenance
ambientsounds = list('sound/ambience/ambimaint1.ogg',
'sound/ambience/ambimaint2.ogg',
'sound/ambience/ambimaint3.ogg',
'sound/ambience/ambimaint4.ogg',
'sound/ambience/ambimaint5.ogg',
'sound/voice/lowHiss2.ogg', //Xeno Breathing Hisses, Hahahaha I'm not even sorry.
'sound/voice/lowHiss3.ogg',
'sound/voice/lowHiss4.ogg')
ambientsounds = MAINTENANCE
valid_territory = FALSE
@@ -647,7 +642,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/chapel
icon_state = "chapel"
ambientsounds = list('sound/ambience/ambicha1.ogg','sound/ambience/ambicha2.ogg','sound/ambience/ambicha3.ogg','sound/ambience/ambicha4.ogg')
ambientsounds = HOLY
flags_1 = NONE
clockwork_warp_allowed = FALSE
clockwork_warp_fail = "The consecration here prevents you from warping in."
@@ -678,7 +673,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
//Engineering
/area/engine
ambientsounds = list('sound/ambience/ambisin1.ogg','sound/ambience/ambisin2.ogg','sound/ambience/ambisin3.ogg','sound/ambience/ambisin4.ogg')
ambientsounds = ENGINEERING
/area/engine/engine_smes
name = "Engineering SMES"
@@ -732,6 +727,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
valid_territory = FALSE
blob_allowed = FALSE
flags_1 = NONE
ambientsounds = ENGINEERING
/area/solar/asteroid/aft
name = "Aft Asteroid Solar"
@@ -858,37 +854,36 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "Teleporter Room"
icon_state = "teleporter"
music = "signal"
ambientsounds = ENGINEERING
/area/teleporter/quantum/cargo
name = "Cargo Quantum Pad"
icon_state = "teleporter"
music = "signal"
/area/teleporter/quantum/docking
name = "Docking Quantum Pad"
icon_state = "teleporter"
music = "signal"
/area/teleporter/quantum/research
name = "Research Quantum Pad"
icon_state = "teleporter"
music = "signal"
/area/teleporter/quantum/security
name = "Security Quantum Pad"
icon_state = "teleporter"
music = "signal"
/area/gateway
name = "Gateway"
icon_state = "teleporter"
music = "signal"
ambientsounds = ENGINEERING
//MedBay
/area/medical
name = "Medical"
icon_state = "medbay3"
ambientsounds = MEDICAL
/area/medical/abandoned
name = "Abandoned Medbay"
@@ -952,7 +947,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/medical/morgue
name = "Morgue"
icon_state = "morgue"
ambientsounds = list('sound/ambience/ambimo1.ogg','sound/ambience/ambimo2.ogg')
ambientsounds = SPOOKY
/area/medical/chemistry
name = "Chemistry"
@@ -988,6 +983,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/security
name = "Security"
icon_state = "security"
ambientsounds = HIGHSEC
/area/security/main
name = "Security Office"
@@ -1029,7 +1025,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/security/detectives_office/private_investigators_office
name = "Private Investigator's Office"
icon_state = "detective"
ambientsounds = list('sound/ambience/ambidet1.ogg','sound/ambience/ambidet2.ogg')
/area/security/range
name = "Firing Range"
@@ -1310,6 +1305,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/construction
name = "Construction Area"
icon_state = "yellow"
ambientsounds = ENGINEERING
/area/construction/minisat_exterior
name = "Minisat Exterior"
@@ -1361,27 +1357,32 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/ai_monitored/security/armory
name = "Armory"
icon_state = "armory"
ambientsounds = HIGHSEC
/area/ai_monitored/storage/eva
name = "EVA Storage"
icon_state = "eva"
ambientsounds = HIGHSEC
/area/ai_monitored/storage/secure
name = "AI Satellite Storage"
icon_state = "storage"
ambientsounds = HIGHSEC
/area/ai_monitored/storage/emergency
name = "Emergency Storage"
icon_state = "storage"
ambientsounds = HIGHSEC
/area/ai_monitored/storage/satellite
name = "AI Satellite Maint"
icon_state = "storage"
ambientsounds = HIGHSEC
//Turret_protected
/area/ai_monitored/turret_protected
ambientsounds = list('sound/ambience/ambimalf.ogg')
ambientsounds = list('sound/ambience/ambimalf.ogg', 'sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg')
/area/ai_monitored/turret_protected/ai_upload
name = "AI Upload Chamber"
@@ -1450,7 +1451,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/tcommsat
clockwork_warp_allowed = FALSE
clockwork_warp_fail = "For safety reasons, warping here is disallowed; the radio and bluespace noise could cause catastrophic results."
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg', 'sound/ambience/ambitech.ogg',\
'sound/ambience/ambitech2.ogg', 'sound/ambience/ambitech3.ogg', 'sound/ambience/ambimystery.ogg')
/area/tcommsat/entrance
name = "Telecomms Teleporter"
@@ -1463,22 +1465,18 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/ai_monitored/turret_protected/tcomsat
name = "Telecomms Satellite"
icon_state = "tcomsatlob"
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
/area/ai_monitored/turret_protected/tcomfoyer
name = "Telecomms Foyer"
icon_state = "tcomsatentrance"
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
/area/ai_monitored/turret_protected/tcomwest
name = "Telecommunications Satellite West Wing"
icon_state = "tcomsatwest"
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
/area/ai_monitored/turret_protected/tcomeast
name = "Telecommunications Satellite East Wing"
icon_state = "tcomsateast"
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
/area/tcommsat/computer
name = "Telecomms Control Room"
+23 -9
View File
@@ -54,12 +54,7 @@
var/global/global_uid = 0
var/uid
var/list/ambientsounds = list('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg',\
'sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg',\
'sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg',\
'sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg',\
'sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg',\
'sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg')
var/list/ambientsounds = GENERIC
flags_1 = CAN_BE_DIRTY_1
var/list/firedoors
@@ -107,7 +102,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
uid = ++global_uid
related = list(src)
map_name = name // Save the initial (the name set in the map) name of the area.
if(requires_power)
luminosity = 0
else
@@ -125,13 +120,32 @@ GLOBAL_LIST_EMPTY(teleportlocs)
. = ..()
power_change() // all machines set to current power level, also updates icon
blend_mode = BLEND_MULTIPLY // Putting this in the constructor so that it stops the icons being screwed up in the map editor.
if(!IS_DYNAMIC_LIGHTING(src))
add_overlay(/obj/effect/fullbright)
if(contents.len)
var/list/areas_in_z = SSmapping.areas_in_z
var/z
for(var/i in 1 to contents.len)
var/atom/thing = contents[i]
if(!thing)
continue
z = thing.z
break
if(!z)
WARNING("No z found for [src]")
return
if(!areas_in_z["[z]"])
areas_in_z["[z]"] = list()
areas_in_z["[z]"] += src
return INITIALIZE_HINT_LATELOAD
/area/LateInitialize()
power_change() // all machines set to current power level, also updates icon
/area/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
+2 -1
View File
@@ -8,6 +8,7 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
name = "Strange Location"
icon_state = "away"
has_gravity = TRUE
ambientsounds = AWAY_MISSION
/area/awaymission/beach
name = "Beach"
@@ -15,7 +16,7 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
requires_power = FALSE
has_gravity = TRUE
ambientsounds = list('sound/ambience/shore.ogg', 'sound/ambience/seag1.ogg','sound/ambience/seag2.ogg','sound/ambience/seag2.ogg')
ambientsounds = list('sound/ambience/shore.ogg', 'sound/ambience/seag1.ogg','sound/ambience/seag2.ogg','sound/ambience/seag2.ogg','sound/ambience/ambiodd.ogg','sound/ambience/ambinice.ogg')
/area/awaymission/errorroom
name = "Super Secret Room"
+1
View File
@@ -96,6 +96,7 @@
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.
flags_1 = NONE
ambientsounds = HIGHSEC
/area/syndicate_mothership/control
name = "Syndicate Control Room"
+5 -4
View File
@@ -15,8 +15,8 @@
power_equip = FALSE
power_light = FALSE
outdoors = TRUE
ambientsounds = list('sound/ambience/ambimine.ogg')
flags_1 = NONE
ambientsounds = MINING
/area/mine/unexplored
name = "Mine"
@@ -29,8 +29,8 @@
power_equip = FALSE
power_light = FALSE
outdoors = TRUE
ambientsounds = list('sound/ambience/ambimine.ogg')
flags_1 = NONE
ambientsounds = MINING
/area/mine/lobby
name = "Mining Station"
@@ -77,6 +77,7 @@
/area/mine/laborcamp/security
name = "Labor Camp Security"
icon_state = "security"
ambientsounds = HIGHSEC
@@ -98,7 +99,7 @@
power_equip = FALSE
power_light = FALSE
requires_power = TRUE
ambientsounds = list('sound/ambience/ambilava.ogg')
ambientsounds = MINING
/area/lavaland/underground
name = "Lavaland Caves"
@@ -110,7 +111,7 @@
power_environ = FALSE
power_equip = FALSE
power_light = FALSE
ambientsounds = list('sound/ambience/ambilava.ogg')
ambientsounds = MINING
/area/lavaland/surface/outdoors
+4 -2
View File
@@ -5,6 +5,7 @@
//icon = "ICON FILENAME"
//icon_state = "NAME OF ICON"
requires_power = FALSE
ambientsounds = SPOOKY
/area/hell/trial1
name = "Hell Trial1"
@@ -32,6 +33,7 @@
/area/prison
name = "Prison Station"
icon_state = "brig"
ambientsounds = HIGHSEC
/area/prison/arrival_airlock
name = "Prison Station Airlock"
@@ -73,7 +75,7 @@
/area/prison/morgue
name = "Prison Morgue"
icon_state = "morgue"
ambientsounds = list('sound/ambience/ambimo1.ogg','sound/ambience/ambimo2.ogg')
ambientsounds = SPOOKY
/area/prison/medical_research
name = "Prison Genetic Research"
@@ -99,7 +101,7 @@
/area/prison/solitary
name = "Solitary Confinement"
icon_state = "brig"
/area/prison/execution_room
name = "Prisoner Education Chamber"
icon_state = "execution_room"
+1 -1
View File
@@ -6,6 +6,7 @@
has_gravity = TRUE
hidden = TRUE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
ambientsounds = RUINS
/area/ruin/unpowered
@@ -16,4 +17,3 @@
/area/ruin/powered
requires_power = FALSE
+2 -2
View File
@@ -22,7 +22,7 @@
power_environ = FALSE
valid_territory = FALSE
outdoors = TRUE
ambientsounds = list('sound/ambience/ambispace.ogg','sound/ambience/title2.ogg')
ambientsounds = SPACE
blob_allowed = FALSE
/////////////
@@ -434,4 +434,4 @@
/area/ruin/space/has_grav/whiteship/box
name = "Abandoned Ship"
icon_state = "red"
icon_state = "red"
+2 -1
View File
@@ -18,6 +18,7 @@
/area/shuttle/syndicate
name = "Syndicate Infiltrator"
blob_allowed = FALSE
ambientsounds = HIGHSEC
/area/shuttle/syndicate/bridge
name = "Syndicate Infiltrator Control"
@@ -106,4 +107,4 @@
/area/shuttle/syndicate_scout
name = "Syndicate Scout"
blob_allowed = FALSE
blob_allowed = FALSE
+1
View File
@@ -2,6 +2,7 @@
/area/spacecontent
name = "space"
ambientsounds = AWAY_MISSION
/area/spacecontent/a1
icon_state = "spacecontent1"
-26
View File
@@ -244,32 +244,6 @@
else if(src in container)
return 1
/*
* atom/proc/search_contents_for(path,list/filter_path=null)
* Recursevly searches all atom contens (including contents contents and so on).
*
* ARGS: path - search atom contents for atoms of this type
* list/filter_path - if set, contents of atoms not of types in this list are excluded from search.
*
* RETURNS: list of found atoms
*/
/atom/proc/search_contents_for(path,list/filter_path=null)
var/list/found = list()
for(var/atom/A in src)
if(istype(A, path))
found += A
if(filter_path)
var/pass = 0
for(var/type in filter_path)
pass |= istype(A, type)
if(!pass)
continue
if(A.contents.len)
found += A.search_contents_for(path,filter_path)
return found
/atom/proc/examine(mob/user)
//This reformat names to get a/an properly working on item descriptions when they are bloody
var/f_name = "\a [src]."
@@ -226,6 +226,8 @@
. = ..()
if(!independent) //no pulling people deep into the blob
verbs -= /mob/living/verb/pulled
else
pass_flags &= ~PASSBLOB
/mob/living/simple_animal/hostile/blob/blobbernaut/Life()
if(..())
+7 -4
View File
@@ -91,10 +91,13 @@ GLOBAL_LIST_EMPTY(blob_nodes)
if(!Ablob.blob_allowed)
continue
playsound(L, 'sound/effects/splat.ogg', 50, 1)
L.death()
new/mob/living/simple_animal/hostile/blob/blobspore(T)
if(!("blob" in L.faction))
playsound(L, 'sound/effects/splat.ogg', 50, 1)
L.death()
new/mob/living/simple_animal/hostile/blob/blobspore(T)
else
L.fully_heal()
for(var/V in GLOB.sortedAreas)
var/area/A = V
@@ -273,6 +273,7 @@ Credit where due:
if(plasmaman && !visualsOnly) //If we need to breathe from the plasma tank, we should probably start doing that
H.internal = H.get_item_for_held_index(2)
H.update_internals_hud_icon(1)
H.sec_hud_set_ID()
/obj/item/paper/servant_primer
name = "The Ark And You: A Primer On Servitude"
@@ -38,8 +38,11 @@
beckon(AM)
/obj/effect/clockwork/city_of_cogs_rift/proc/beckon(atom/movable/AM)
var/turf/T = get_turf(pick(GLOB.city_of_cogs_spawns))
if(is_servant_of_ratvar(AM))
T = GLOB.ark_of_the_clockwork_justiciar ? get_step(GLOB.ark_of_the_clockwork_justiciar, SOUTH) : get_turf(pick(GLOB.servant_spawns))
AM.visible_message("<span class='danger'>[AM] passes through [src]!</span>", ignored_mob = AM)
AM.forceMove(pick(!is_servant_of_ratvar(AM) ? GLOB.city_of_cogs_spawns : GLOB.servant_spawns))
AM.forceMove(T)
AM.visible_message("<span class='danger'>[AM] materializes from the air!</span>", \
"<span class='boldannounce'>You pass through [src] and appear [is_servant_of_ratvar(AM) ? "back at the City of Cogs" : "somewhere unfamiliar. Looks like it was a one-way trip.."].</span>")
do_sparks(5, TRUE, src)
@@ -104,7 +104,7 @@ List of nuances:
if(isliving(AM))
var/mob/living/L = AM
if(!whisper)
L.say(message, "clock", spans, language=/datum/language/common)
L.say(message, "clock", spans, language=/datum/language/common, ignore_spam = TRUE)
else
L.whisper(message, "clock", spans, language=/datum/language/common)
else
@@ -1,8 +1,7 @@
/obj/item/clockwork/slab //Clockwork slab: The most important tool in Ratvar's arsenal. Allows scripture recital, tutorials, and generates components.
name = "clockwork slab"
desc = "A strange metal tablet. A clock in the center turns around and around."
clockwork_desc = "A link between you and the Celestial Derelict. It contains information, recites scripture, and is your most vital tool as a Servant.\n\
Hitting a slab, a Servant with a slab, or a cache will <b>transfer</b> this slab's components into the target, the target's slab, or the global cache, respectively."
clockwork_desc = "A link between you and the Celestial Derelict. It contains information, recites scripture, and is your most vital tool as a Servant."
icon_state = "dread_ipad"
lefthand_file = 'icons/mob/inhands/antag/clockwork_lefthand.dmi'
righthand_file = 'icons/mob/inhands/antag/clockwork_righthand.dmi'
@@ -231,7 +230,7 @@
this will cause you to whisper your message aloud, so doing so in a public place is very suspicious and you should try to restrict it to private use.<br><br>"
dat += "If you aren't willing or don't have the time to read through every section, you can still help your teammates! Ask if they've set up a base. If they have, head there \
and ask however you can help; chances are there's always something. If not, it's your job as a Servant to get one up and running! Try to find a secluded, low-traffic area, \
like the auxilary base or somewhere deep in maintenance. You'll want to go into the Drivers section of the slab and look for <i>Tinkerer's Cache.</i> Find a nice spot and \
like the auxiliary base or somewhere deep in maintenance. You'll want to go into the Drivers section of the slab and look for <i>Tinkerer's Cache.</i> Find a nice spot and \
create one. This serves as a storage for <i>components,</i> the cult's primary resource. (Your slab's probably produced a few by now.) By attacking that cache with this \
slab, you'll offload all your components into it, and all Servants will be able to use those components from any distance - all Tinkerer's Caches are linked!<br><br>"
dat += "Once you have a base up and running, contact your fellows and let them know. You should come back here often to drop off the slab's components, and your fellows \
@@ -250,7 +249,7 @@
teamwork is an instrumental component of your success.<br><br>" //get it? component? ha!
dat += "As a Servant of Ratvar, the tools you are given focus around building and maintaining bases and outposts. A great deal of your power comes from stationary \
structures, and without constructing a base somewhere, it's essentially impossible to succeed. Finding a good spot to build a base can be difficult, and it's recommended \
that you choose an area in low-traffic part of the station (such as the auxilary base). Make sure to disconnect any cameras in the area beforehand.<br><br>"
that you choose an area in low-traffic part of the station (such as the auxiliary base). Make sure to disconnect any cameras in the area beforehand.<br><br>"
dat += "Because of how complex being a Servant is, it isn't possible to fit much information into this section. It's highly recommended that you read the <b>Components</b> \
and <b>Scripture</b> sections next. Not knowing how these two systems work will cripple both you and your fellows, and lead to a frustrating experience for everyone.<br><br>"
dat += "<font color=#BE8700 size=3>-=-=-=-=-=-</font>"
@@ -17,6 +17,7 @@
attack_sound = 'sound/weapons/bladeslice.ogg'
weather_immunities = list("lava")
movement_type = FLYING
a_intent = INTENT_HARM
loot = list(/obj/item/clockwork/component/geis_capacitor/fallen_armor)
light_range = 2
light_power = 1.1
@@ -24,7 +25,6 @@
unique abilities, you're a fearsome fighter in one-on-one combat, and your shield protects from projectiles!<br><br>Obey the Servants and do as they \
tell you. Your primary goal is to defend the Ark from destruction; they are your allies in this, and should be protected from harm.</b>"
empower_string = "<span class='neovgre'>The Anima Bulwark's power flows through you! Your weapon will strike harder, your armor is sturdier, and your shield is more durable.</span>"
var/deflect_chance = 40 //Chance to deflect any given projectile (non-damaging energy projectiles are always deflected)
var/max_shield_health = 3
var/shield_health = 3 //Amount of projectiles that can be deflected within
var/shield_health_regen = 0 //When world.time equals this, shield health will regenerate
@@ -55,8 +55,6 @@
obj_damage = 100
max_shield_health = INFINITY
else if(GLOB.ratvar_approaches) //Hefty health bonus and slight attack damage increase
health = 200
maxHealth = 200
melee_damage_upper = 15
melee_damage_lower = 15
attacktext = "carves"
@@ -53,6 +53,7 @@ Applications: 8 servants, 3 caches, and 100 CV
if(slab.busy)
to_chat(invoker, "<span class='warning'>[slab] refuses to work, displaying the message: \"[slab.busy]!\"</span>")
return FALSE
pre_recital()
slab.busy = "Invocation ([name]) in progress"
if(GLOB.ratvar_awakens)
channel_time *= 0.5 //if ratvar has awoken, half channel time and no cost
@@ -176,6 +177,9 @@ Applications: 8 servants, 3 caches, and 100 CV
/datum/clockwork_scripture/proc/scripture_fail() //Called if the scripture fails to invoke.
/datum/clockwork_scripture/proc/pre_recital() //Called before the scripture is recited
/datum/clockwork_scripture/proc/post_recital() //Called after the scripture is recited
//Channeled scripture begins instantly but runs constantly
@@ -7,12 +7,12 @@
/datum/clockwork_scripture/create_object/construct/clockwork_marauder
descname = "Well-Rounded Combat Construct"
name = "Clockwork Marauder"
desc = "Creates a shell for a clockwork marauder, a balanced frontline construct."
desc = "Creates a shell for a clockwork marauder, a balanced frontline construct that can deflect projectiles with its shield."
invocations = list("Arise, avatar of Arbiter!", "Defend the Ark with vengeful zeal.")
channel_time = 50
power_cost = 1000
creator_message = "<span class='brass'>Your slab disgorges several chunks of replicant alloy that form into a suit of thrumming armor.</span>"
usage_tip = "The marauder's shield can effectively deflect energy-based projectiles."
usage_tip = "Reciting this scripture multiple times in a short period will cause it to take longer!"
tier = SCRIPTURE_APPLICATION
one_per_tile = TRUE
primary_component = BELLIGERENT_EYE
@@ -22,6 +22,9 @@
object_path = /obj/item/clockwork/construct_chassis/clockwork_marauder
construct_type = /mob/living/simple_animal/hostile/clockwork/marauder
combat_construct = TRUE
var/static/recent_marauders = 0
var/static/time_since_last_marauder = 0
var/static/scaled_recital_time = 0
/datum/clockwork_scripture/create_object/construct/clockwork_marauder/update_construct_limit()
var/human_servants = 0
@@ -32,15 +35,30 @@
construct_limit = human_servants / 4 //1 per 4 human servants, and a maximum of 3 marauders
construct_limit = Clamp(construct_limit, 1, 3)
/datum/clockwork_scripture/create_object/prolonging_prism/check_special_requirements()
if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE)
to_chat(invoker, "<span class='inathneq'>\"It is too late to construct one of these, champion.\"</span>")
return FALSE
var/turf/T = get_turf(invoker)
if(!T || !(T.z in GLOB.station_z_levels))
to_chat(invoker, "<span class='inathneq'>\"You must be on the station to construct one of these, champion.\"</span>")
return FALSE
return ..()
/datum/clockwork_scripture/create_object/construct/clockwork_marauder/pre_recital()
channel_time = initial(channel_time)
calculate_scaling()
if(scaled_recital_time)
to_chat(invoker, "<span class='warning'>The Hierophant Network is under strain from repeated summoning, making this scripture [scaled_recital_time / 10] seconds slower!</span>")
channel_time += scaled_recital_time
return TRUE
/datum/clockwork_scripture/create_object/construct/clockwork_marauder/scripture_effects()
. = ..()
time_since_last_marauder = world.time
recent_marauders++
calculate_scaling()
/datum/clockwork_scripture/create_object/construct/clockwork_marauder/proc/calculate_scaling()
var/WT = world.time
var/MT = time_since_last_marauder //Cast it for quicker reference
var/marauders_to_exclude = 0
if(world.time >= time_since_last_marauder + MARAUDER_SCRIPTURE_SCALING_THRESHOLD)
marauders_to_exclude = round(WT - MT) / MARAUDER_SCRIPTURE_SCALING_THRESHOLD //If at least 20 seconds have passed, lose one marauder for each 20 seconds
//i.e. world.time = 10000, last marauder = 9000, so we lose 5 marauders from the recent count since 10k - 9k = 1k, 1k / 200 = 5
time_since_last_marauder = world.time //So that it can't be spammed to make the marauder exclusion plummet; this emulates "ticking"
recent_marauders = max(0, recent_marauders - marauders_to_exclude)
scaled_recital_time = min(recent_marauders * MARAUDER_SCRIPTURE_SCALING_TIME, MARAUDER_SCRIPTURE_SCALING_MAX)
//Mania Motor: Creates a malevolent transmitter that will broadcast the whispers of Sevtug into the minds of nearby nonservants, causing a variety of mental effects at a power cost.
@@ -129,7 +129,11 @@
/datum/clockwork_scripture/abscond/scripture_effects()
var/take_pulling = invoker.pulling && isliving(invoker.pulling) && get_clockwork_power(ABSCOND_ABDUCTION_COST)
var/turf/T = get_turf(pick(GLOB.servant_spawns))
var/turf/T
if(GLOB.ark_of_the_clockwork_justiciar)
T = get_step(GLOB.ark_of_the_clockwork_justiciar, SOUTH)
else
T = get_turf(pick(GLOB.servant_spawns))
invoker.visible_message("<span class='warning'>[invoker] flickers and phases out of existence!</span>", \
"<span class='bold sevtug_small'>You feel a dizzying sense of vertigo as you're yanked back to Reebe!</span>")
T.visible_message("<span class='warning'>[invoker] flickers and phases into existence!</span>")
@@ -134,11 +134,20 @@
var/damage = max((obj_integrity * 0.7) / severity, 100) //requires multiple bombs to take down
take_damage(damage, BRUTE, "bomb", 0)
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_time()
if(seconds_until_activation)
return (seconds_until_activation*10)
if(grace_period)
return (grace_period*10)
else if(GATEWAY_RATVAR_ARRIVAL - progress_in_seconds > 0)
return (round(max((GATEWAY_RATVAR_ARRIVAL - progress_in_seconds) / (GATEWAY_SUMMON_RATE), 0), 1)*10)
return -10
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_text(s_on_time)
if(seconds_until_activation)
return "[seconds_until_activation][s_on_time ? "S" : ""]"
return "[get_arrival_time()][s_on_time ? "S" : ""]"
if(grace_period)
return "[grace_period][s_on_time ? "S" : ""]"
return "[get_arrival_time()][s_on_time ? "S" : ""]"
. = "IMMINENT"
if(!obj_integrity)
. = "DETONATING"
@@ -151,12 +160,12 @@
icon_state = initial(icon_state)
if(is_servant_of_ratvar(user) || isobserver(user))
if(!active)
to_chat(user, "<span class='big'><b>Seconds until the Ark's activation:</b> [get_arrival_text(TRUE)]</span>")
to_chat(user, "<span class='big'><b>Time until the Ark's activation:</b> [DisplayTimeText(get_arrival_time())]</span>")
else
if(grace_period)
to_chat(user, "<span class='big'><b>Crew grace period time remaining:</b> [get_arrival_text(TRUE)]</span>")
to_chat(user, "<span class='big'><b>Crew grace period time remaining:</b> [DisplayTimeText(get_arrival_time())]</span>")
else
to_chat(user, "<span class='big'><b>Seconds until Ratvar's arrival:</b> [get_arrival_text(TRUE)]</span>")
to_chat(user, "<span class='big'><b>Time until Ratvar's arrival:</b> [DisplayTimeText(get_arrival_time())]</span>")
switch(progress_in_seconds)
if(-INFINITY to GATEWAY_REEBE_FOUND)
to_chat(user, "<span class='heavy_brass'>The Ark is feeding power into the bluespace field.</span>")
@@ -266,7 +275,7 @@
CHECK_TICK
/obj/structure/destructible/clockwork/massive/celestial_gateway/attack_ghost(mob/user)
if(!user.client || !user.client.holder)
if(!IsAdminGhost(user))
return
if(GLOB.servants_active)
to_chat(user, "<span class='danger'>The Ark is already counting down.</span>")
@@ -275,6 +284,7 @@
if(alert(user, "REALLY activate the Ark's countdown?", name, "Yes", "No") == "Yes")
if(alert(user, "You're REALLY SURE? This cannot be undone.", name, "Yes - Activate the Ark", "No") == "Yes - Activate the Ark")
message_admins("<span class='danger'>Admin [key_name_admin(user)] started the Ark's countdown!</span>")
log_admin("Admin [key_name(user)] started the Ark's countdown on a non-clockcult mode!")
to_chat(user, "<span class='userdanger'>The gamemode is now being treated as clockwork cult, and the Ark is counting down from 30 \
minutes. You will need to create servant players yourself.</span>")
final_countdown(35)
+4
View File
@@ -256,6 +256,10 @@
SSticker.news_report = CULT_FAILURE
text += "<br><B>Objective #[obj_count]</B>: [explanation]"
if(cult.len)
text += "<br><b>The cultists were:</b>"
for(var/datum/mind/M in cult)
text += printplayer(M)
to_chat(world, text)
..()
return 1
+1 -1
View File
@@ -324,7 +324,7 @@
icon_state = "cult_armor"
item_state = "cult_armor"
desc = "A heavily-armored exosuit worn by warriors of the Nar-Sien cult. It can withstand hard vacuum."
w_class = WEIGHT_CLASS_SMALL
w_class = WEIGHT_CLASS_BULKY
allowed = list(/obj/item/tome, /obj/item/melee/cultblade, /obj/item/tank/internals/)
armor = list(melee = 70, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30, fire = 40, acid = 75)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/cult
+1 -1
View File
@@ -137,7 +137,7 @@ structure_check() searches for nearby cultist structures required for the invoca
for(var/M in invokers)
var/mob/living/L = M
if(invocation)
L.say(invocation, language = /datum/language/common)
L.say(invocation, language = /datum/language/common, ignore_spam = TRUE)
if(invoke_damage)
L.apply_damage(invoke_damage, BRUTE)
to_chat(L, "<span class='cultitalic'>[src] saps your strength!</span>")
+2 -3
View File
@@ -225,8 +225,8 @@
/obj/item/paper/talisman/horror/afterattack(mob/living/target, mob/living/user)
if(iscultist(user) && (get_dist(user, target) < 7))
to_chat(user, "<span class='cultitalic'>You disturb [target] with visions of madness!</span>")
if(iscarbon(target))
to_chat(user, "<span class='cultitalic'>You disturb [target] with visions of madness!</span>")
var/mob/living/carbon/H = target
H.reagents.add_reagent("mindbreaker", 12)
if(is_servant_of_ratvar(target))
@@ -234,8 +234,7 @@
target.emote("scream")
target.confused = max(0, target.confused + 3)
target.flash_act()
qdel(src)
qdel(src)
//Talisman of Fabrication: Creates a construct shell out of 25 metal sheets, or converts plasteel into runed metal up to 25 times
/obj/item/paper/talisman/construction
@@ -17,6 +17,7 @@
var/ascended = FALSE
sight = (SEE_TURFS | SEE_OBJS)
status_flags = CANPUSH
spacewalk = TRUE
mob_size = MOB_SIZE_LARGE
var/mob/living/oldform
var/list/devil_overlays[DEVIL_TOTAL_LAYERS]
@@ -135,9 +136,6 @@
"<span class='userdanger'>[attack_message]</span>", null, COMBAT_MESSAGE_RANGE)
return TRUE
/mob/living/carbon/true_devil/Process_Spacemove(movement_dir = 0)
return 1
/mob/living/carbon/true_devil/singularity_act()
if(ascended)
return 0
@@ -679,7 +679,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
C.images -= I
/mob/living/silicon/ai/proc/can_place_transformer(datum/action/innate/ai/place_transformer/action)
if(!eyeobj || !isturf(loc) || !canUseTopic() || !action)
if(!eyeobj || !isturf(loc) || incapacitated() || !action)
return
var/turf/middle = get_turf(eyeobj)
var/list/turfs = list(middle, locate(middle.x - 1, middle.y, middle.z), locate(middle.x + 1, middle.y, middle.z))
+4 -2
View File
@@ -98,7 +98,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
var/z_original = ZLEVEL_STATION_PRIMARY
var/threat = 0 // used for determining which meteors are most interesting
var/lifetime = DEFAULT_METEOR_LIFETIME
var/timerid = null
var/list/meteordrop = list(/obj/item/ore/iron)
var/dropamt = 2
@@ -117,6 +117,8 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
get_hit()
/obj/effect/meteor/Destroy()
if (timerid)
deltimer(timerid)
GLOB.meteor_list -= src
SSaugury.unregister_doom(src)
walk(src,0) //this cancels the walk_towards() proc
@@ -127,7 +129,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
GLOB.meteor_list += src
SSaugury.register_doom(src, threat)
SpinAnimation()
QDEL_IN(src, lifetime)
timerid = QDEL_IN(src, lifetime)
chase_target(target)
/obj/effect/meteor/Collide(atom/A)
@@ -21,6 +21,7 @@
maxHealth = INFINITY
layer = GHOST_LAYER
healable = FALSE
spacewalk = TRUE
sight = SEE_SELF
see_in_dark = 8
@@ -153,8 +154,6 @@
//Immunities
/mob/living/simple_animal/revenant/Process_Spacemove(movement_dir = 0)
return 1
/mob/living/simple_animal/revenant/ex_act(severity, target)
return 1 //Immune to the effects of explosions.
+4 -2
View File
@@ -91,9 +91,11 @@
var/obj/item/device/nuclear_challenge/challenge = new /obj/item/device/nuclear_challenge
synd_mind.current.put_in_hands(challenge, TRUE)
var/list/foundIDs = synd_mind.current.search_contents_for(/obj/item/card/id)
var/static/id_cache = typecacheof(/obj/item/card/id)
var/list/foundIDs = typecache_filter_list(synd_mind.current.GetAllContents(), id_cache)
if(foundIDs.len)
for(var/obj/item/card/id/ID in foundIDs)
for(var/i in 1 to foundIDs.len)
var/obj/item/card/id/ID = foundIDs[i]
ID.name = "lead agent card"
ID.access += ACCESS_SYNDICATE_LEADER
else
+2 -1
View File
@@ -83,7 +83,7 @@
/datum/game_mode/traitor/proc/add_latejoin_traitor(datum/mind/character)
var/datum/antagonist/traitor/new_antag = new antag_datum(character)
new_antag.should_specialise = TRUE
character.add_antag_datum(antag_datum)
character.add_antag_datum(new_antag)
@@ -147,6 +147,7 @@
else
text += "<br><font color='red'><B>The [special_role_text] has failed!</B></font>"
SSblackbox.add_details("traitor_success","FAIL")
SEND_SOUND(traitor.current, 'sound/ambience/ambifailure.ogg')
text += "<br>"
+1 -1
View File
@@ -425,7 +425,7 @@
/datum/spellbook_entry/item/warpwhistle
name = "Warp Whistle"
desc = "A strange whistle that will transport you to a distant safe place on the station. There is a window of vulnerability at the begining of every use."
desc = "A strange whistle that will transport you to a distant safe place on the station. There is a window of vulnerability at the beginning of every use."
item_path = /obj/item/warpwhistle
category = "Mobility"
cost = 1
+11
View File
@@ -506,3 +506,14 @@ Class Procs:
. = ..()
if (AM == occupant)
occupant = null
/obj/machinery/proc/adjust_item_drop_location(atom/movable/AM) // Adjust item drop location to a 3x3 grid inside the tile, returns slot id from 0 to 8
var/md5 = md5(AM.name) // Oh, and it's deterministic too. A specific item will always drop from the same slot.
#if DM_VERSION > 511
#warn Refactor the loop in /obj/machinery/proc/adjust_item_drop_location() to make use of 512's list-like access to characters in a string
#endif
for (var/i in 1 to 32)
. += hex2num(copytext(md5,i,i+1))
. = . % 9
AM.pixel_x = -8 + ((.%3)*8)
AM.pixel_y = -8 + (round( . / 3)*8)
+107 -136
View File
@@ -8,10 +8,9 @@
circuit = /obj/item/circuitboard/computer/communications
var/authenticated = 0
var/auth_id = "Unknown" //Who is currently logged in?
var/list/messagetitle = list()
var/list/messagetext = list()
var/currmsg = 0
var/aicurrmsg = 0
var/list/datum/comm_message/messages = list()
var/datum/comm_message/currmsg
var/datum/comm_message/aicurrmsg
var/state = STATE_DEFAULT
var/aistate = STATE_DEFAULT
var/message_cooldown = 0
@@ -48,7 +47,7 @@
/obj/machinery/computer/communications/process()
if(..())
if(state != STATE_STATUSDISPLAY)
src.updateDialog()
updateDialog()
/obj/machinery/computer/communications/Topic(href, href_list)
@@ -65,7 +64,7 @@
switch(href_list["operation"])
// main interface
if("main")
src.state = STATE_DEFAULT
state = STATE_DEFAULT
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
if("login")
var/mob/M = usr
@@ -75,13 +74,13 @@
I = M.get_idcard()
if(I && istype(I))
if(src.check_access(I))
if(check_access(I))
authenticated = 1
auth_id = "[I.registered_name] ([I.assignment])"
if((20 in I.access))
authenticated = 2
playsound(src, 'sound/machines/terminal_on.ogg', 50, 0)
if(src.emagged)
if(emagged)
authenticated = 2
auth_id = "Unknown"
to_chat(M, "<span class='warning'>[src] lets out a quiet alarm as its login is overriden.</span>")
@@ -132,7 +131,7 @@
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
if("announce")
if(src.authenticated==2)
if(authenticated==2)
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
make_announcement(usr)
@@ -186,53 +185,56 @@
to_chat(usr, "Not enough credits.")
if("callshuttle")
src.state = STATE_DEFAULT
if(src.authenticated)
src.state = STATE_CALLSHUTTLE
state = STATE_DEFAULT
if(authenticated)
state = STATE_CALLSHUTTLE
if("callshuttle2")
if(src.authenticated)
if(authenticated)
SSshuttle.requestEvac(usr, href_list["call"])
if(SSshuttle.emergency.timer)
post_status("shuttle")
src.state = STATE_DEFAULT
state = STATE_DEFAULT
if("cancelshuttle")
src.state = STATE_DEFAULT
if(src.authenticated)
src.state = STATE_CANCELSHUTTLE
state = STATE_DEFAULT
if(authenticated)
state = STATE_CANCELSHUTTLE
if("cancelshuttle2")
if(src.authenticated)
if(authenticated)
SSshuttle.cancelEvac(usr)
src.state = STATE_DEFAULT
state = STATE_DEFAULT
if("messagelist")
src.currmsg = 0
src.state = STATE_MESSAGELIST
currmsg = 0
state = STATE_MESSAGELIST
if("viewmessage")
src.state = STATE_VIEWMESSAGE
if (!src.currmsg)
state = STATE_VIEWMESSAGE
if (!currmsg)
if(href_list["message-num"])
src.currmsg = text2num(href_list["message-num"])
var/msgnum = text2num(href_list["message-num"])
currmsg = messages[msgnum]
else
src.state = STATE_MESSAGELIST
state = STATE_MESSAGELIST
if("delmessage")
src.state = (src.currmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST
state = currmsg ? STATE_DELMESSAGE : STATE_MESSAGELIST
if("delmessage2")
if(src.authenticated)
if(src.currmsg)
var/title = src.messagetitle[src.currmsg]
var/text = src.messagetext[src.currmsg]
src.messagetitle.Remove(title)
src.messagetext.Remove(text)
if(src.currmsg == src.aicurrmsg)
src.aicurrmsg = 0
src.currmsg = 0
src.state = STATE_MESSAGELIST
if(authenticated)
if(currmsg)
if(aicurrmsg == currmsg)
aicurrmsg = null
messages -= currmsg
currmsg = null
state = STATE_MESSAGELIST
else
src.state = STATE_VIEWMESSAGE
state = STATE_VIEWMESSAGE
if("respond")
var/answer = text2num(href_list["answer"])
if(!currmsg || !answer || currmsg.possible_answers.len < answer)
state = STATE_MESSAGELIST
currmsg.answered = answer
state = STATE_VIEWMESSAGE
if("status")
src.state = STATE_STATUSDISPLAY
state = STATE_STATUSDISPLAY
if("securitylevel")
src.tmp_alertlevel = text2num( href_list["newalertlevel"] )
tmp_alertlevel = text2num( href_list["newalertlevel"] )
if(!tmp_alertlevel)
tmp_alertlevel = 0
state = STATE_CONFIRM_LEVEL
@@ -245,12 +247,12 @@
make_maint_all_access()
log_game("[key_name(usr)] enabled emergency maintenance access.")
message_admins("[key_name_admin(usr)] enabled emergency maintenance access.")
src.state = STATE_DEFAULT
state = STATE_DEFAULT
if("disableemergency")
revoke_maint_all_access()
log_game("[key_name(usr)] disabled emergency maintenance access.")
message_admins("[key_name_admin(usr)] disabled emergency maintenance access.")
src.state = STATE_DEFAULT
state = STATE_DEFAULT
// Status display stuff
if("setstat")
@@ -265,14 +267,14 @@
if("setmsg1")
stat_msg1 = reject_bad_text(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 40)
src.updateDialog()
updateDialog()
if("setmsg2")
stat_msg2 = reject_bad_text(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 40)
src.updateDialog()
updateDialog()
// OMG CENTCOM LETTERHEAD
if("MessageCentCom")
if(src.authenticated==2)
if(authenticated==2)
if(!checkCCcooldown())
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
return
@@ -288,7 +290,7 @@
// OMG SYNDICATE ...LETTERHEAD
if("MessageSyndicate")
if((src.authenticated==2) && (src.emagged))
if((authenticated==2) && (emagged))
if(!checkCCcooldown())
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
@@ -306,10 +308,10 @@
to_chat(usr, "<span class='notice'>Backup routing data restored!</span>")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
emagged = FALSE
src.updateDialog()
updateDialog()
if("nukerequest") //When there's no other way
if(src.authenticated==2)
if(authenticated==2)
if(!checkCCcooldown())
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
return
@@ -325,41 +327,45 @@
// AI interface
if("ai-main")
src.aicurrmsg = 0
src.aistate = STATE_DEFAULT
aicurrmsg = null
aistate = STATE_DEFAULT
if("ai-callshuttle")
src.aistate = STATE_CALLSHUTTLE
aistate = STATE_CALLSHUTTLE
if("ai-callshuttle2")
SSshuttle.requestEvac(usr, href_list["call"])
src.aistate = STATE_DEFAULT
aistate = STATE_DEFAULT
if("ai-messagelist")
src.aicurrmsg = 0
src.aistate = STATE_MESSAGELIST
aicurrmsg = null
aistate = STATE_MESSAGELIST
if("ai-viewmessage")
src.aistate = STATE_VIEWMESSAGE
if (!src.aicurrmsg)
aistate = STATE_VIEWMESSAGE
if (!aicurrmsg)
if(href_list["message-num"])
src.aicurrmsg = text2num(href_list["message-num"])
var/msgnum = text2num(href_list["message-num"])
aicurrmsg = messages[msgnum]
else
src.aistate = STATE_MESSAGELIST
aistate = STATE_MESSAGELIST
if("ai-delmessage")
src.aistate = (src.aicurrmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST
aistate = aicurrmsg ? STATE_DELMESSAGE : STATE_MESSAGELIST
if("ai-delmessage2")
if(src.aicurrmsg)
var/title = src.messagetitle[src.aicurrmsg]
var/text = src.messagetext[src.aicurrmsg]
src.messagetitle.Remove(title)
src.messagetext.Remove(text)
if(src.currmsg == src.aicurrmsg)
src.currmsg = 0
src.aicurrmsg = 0
src.aistate = STATE_MESSAGELIST
if(aicurrmsg)
if(currmsg == aicurrmsg)
currmsg = null
messages -= aicurrmsg
aicurrmsg = null
aistate = STATE_MESSAGELIST
if("ai-respond")
var/answer = text2num(href_list["answer"])
if(!aicurrmsg || !answer || aicurrmsg.possible_answers.len < answer)
aistate = STATE_MESSAGELIST
aicurrmsg.answered = answer
aistate = STATE_VIEWMESSAGE
if("ai-status")
src.aistate = STATE_STATUSDISPLAY
aistate = STATE_STATUSDISPLAY
if("ai-announce")
make_announcement(usr, 1)
if("ai-securitylevel")
src.tmp_alertlevel = text2num( href_list["newalertlevel"] )
tmp_alertlevel = text2num( href_list["newalertlevel"] )
if(!tmp_alertlevel)
tmp_alertlevel = 0
var/old_level = GLOB.security_level
@@ -380,24 +386,23 @@
if(SEC_LEVEL_BLUE)
SSblackbox.inc("alert_comms_blue",1)
tmp_alertlevel = 0
src.aistate = STATE_DEFAULT
aistate = STATE_DEFAULT
if("ai-changeseclevel")
src.aistate = STATE_ALERT_LEVEL
aistate = STATE_ALERT_LEVEL
if("ai-emergencyaccess")
src.aistate = STATE_TOGGLE_EMERGENCY
aistate = STATE_TOGGLE_EMERGENCY
if("ai-enableemergency")
make_maint_all_access()
log_game("[key_name(usr)] enabled emergency maintenance access.")
message_admins("[key_name_admin(usr)] enabled emergency maintenance access.")
src.aistate = STATE_DEFAULT
aistate = STATE_DEFAULT
if("ai-disableemergency")
revoke_maint_all_access()
log_game("[key_name(usr)] disabled emergency maintenance access.")
message_admins("[key_name_admin(usr)] disabled emergency maintenance access.")
src.aistate = STATE_DEFAULT
aistate = STATE_DEFAULT
src.updateUsrDialog()
updateUsrDialog()
/obj/machinery/computer/communications/attackby(obj/I, mob/user, params)
if(istype(I, /obj/item/card/id))
@@ -417,7 +422,7 @@
/obj/machinery/computer/communications/attack_hand(mob/user)
if(..())
return
if (src.z > 6)
if (z > 6)
to_chat(user, "<span class='boldannounce'>Unable to establish a connection</span>: \black You're too far away from the station!")
return
@@ -429,19 +434,19 @@
var/datum/browser/popup = new(user, "communications", "Communications Console", 400, 500)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
if(issilicon(user))
var/dat2 = src.interact_ai(user) // give the AI a different interact proc to limit its access
var/dat2 = interact_ai(user) // give the AI a different interact proc to limit its access
if(dat2)
dat += dat2
popup.set_content(dat)
popup.open()
return
switch(src.state)
switch(state)
if(STATE_DEFAULT)
if (src.authenticated)
if (authenticated)
if(SSshuttle.emergencyCallAmount)
if(SSshuttle.emergencyLastCallLoc)
dat += "Most recent shuttle call/recall traced to: <b>[format_text(SSshuttle.emergencyLastCallLoc.name)]</b><BR>"
@@ -458,18 +463,13 @@
else
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=cancelshuttle'>Cancel Shuttle Call</A> \]"
<<<<<<< HEAD
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=status'>Set Status Display</A> \]"
if (src.authenticated==2)
=======
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=status'>Set Status Display</A> \]"
if (authenticated==2)
>>>>>>> 626302c... Merge pull request #32161 from ninjanomnom/512-experimental
dat += "<BR><BR><B>Captain Functions</B>"
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=announce'>Make a Captain's Announcement</A> \]"
if(CONFIG_GET(string/cross_server_address))
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=crossserver'>Send a message to an allied station</A> \]"
if(SSmapping.config.allow_custom_shuttles == "yes")
if(SSmapping.config.allow_custom_shuttles)
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=purchase_menu'>Purchase Shuttle</A> \]"
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=changeseclevel'>Change Alert Level</A> \]"
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=emergencyaccess'>Emergency Maintenance Access</A> \]"
@@ -489,16 +489,6 @@
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
if(STATE_MESSAGELIST)
dat += "Messages:"
<<<<<<< HEAD
for(var/i = 1; i<=src.messagetitle.len; i++)
dat += "<BR><A HREF='?src=\ref[src];operation=viewmessage;message-num=[i]'>[src.messagetitle[i]]</A>"
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
if(STATE_VIEWMESSAGE)
if (src.currmsg)
dat += "<B>[src.messagetitle[src.currmsg]]</B><BR><BR>[src.messagetext[src.currmsg]]"
if (src.authenticated)
dat += "<BR><BR>\[ <A HREF='?src=\ref[src];operation=delmessage'>Delete</a> \]"
=======
for(var/i in 1 to messages.len)
var/datum/comm_message/M = messages[i]
dat += "<BR><A HREF='?src=[REF(src)];operation=viewmessage;message-num=[i]'>[M.title]</A>"
@@ -514,22 +504,16 @@
var/answered = currmsg.possible_answers[currmsg.answered]
dat += "<br> Archived Answer : [answered]"
dat += "<BR><BR>\[ <A HREF='?src=[REF(src)];operation=delmessage'>Delete</A> \]"
>>>>>>> 626302c... Merge pull request #32161 from ninjanomnom/512-experimental
else
src.state = STATE_MESSAGELIST
src.attack_hand(user)
return
aistate = STATE_MESSAGELIST
attack_hand(user)
return null
if(STATE_DELMESSAGE)
<<<<<<< HEAD
if (src.currmsg)
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=\ref[src];operation=delmessage2'>OK</A> | <A HREF='?src=\ref[src];operation=viewmessage'>Cancel</A> \]"
=======
if (currmsg)
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=[REF(src)];operation=delmessage2'>OK</A> | <A HREF='?src=[REF(src)];operation=viewmessage'>Cancel</A> \]"
>>>>>>> 626302c... Merge pull request #32161 from ninjanomnom/512-experimental
else
src.state = STATE_MESSAGELIST
src.attack_hand(user)
state = STATE_MESSAGELIST
attack_hand(user)
return
if(STATE_STATUSDISPLAY)
dat += "Set Status Displays<BR>"
@@ -574,11 +558,7 @@
dat += "Prerequisites: [S.prerequisites]<BR>"
dat += "<A href='?src=[REF(src)];operation=buyshuttle;chosen_shuttle=[REF(S)]'>(<font color=red><i>Purchase</i></font>)</A><BR><BR>"
<<<<<<< HEAD
dat += "<BR><BR>\[ [(src.state != STATE_DEFAULT) ? "<A HREF='?src=\ref[src];operation=main'>Main Menu</A> | " : ""]<A HREF='?src=\ref[user];mach_close=communications'>Close</A> \]"
=======
dat += "<BR><BR>\[ [(state != STATE_DEFAULT) ? "<A HREF='?src=[REF(src)];operation=main'>Main Menu</A> | " : ""]<A HREF='?src=[REF(user)];mach_close=communications'>Close</A> \]"
>>>>>>> 626302c... Merge pull request #32161 from ninjanomnom/512-experimental
popup.set_content(dat)
popup.open()
@@ -624,7 +604,7 @@
/obj/machinery/computer/communications/proc/interact_ai(mob/living/silicon/ai/user)
var/dat = ""
switch(src.aistate)
switch(aistate)
if(STATE_DEFAULT)
if(SSshuttle.emergencyCallAmount)
if(SSshuttle.emergencyLastCallLoc)
@@ -648,14 +628,6 @@
dat += get_call_shuttle_form(1)
if(STATE_MESSAGELIST)
dat += "Messages:"
<<<<<<< HEAD
for(var/i = 1; i<=src.messagetitle.len; i++)
dat += "<BR><A HREF='?src=\ref[src];operation=ai-viewmessage;message-num=[i]'>[src.messagetitle[i]]</A>"
if(STATE_VIEWMESSAGE)
if (src.aicurrmsg)
dat += "<B>[src.messagetitle[src.aicurrmsg]]</B><BR><BR>[src.messagetext[src.aicurrmsg]]"
dat += "<BR><BR>\[ <A HREF='?src=\ref[src];operation=ai-delmessage'>Delete</A> \]"
=======
for(var/i in 1 to messages.len)
var/datum/comm_message/M = messages[i]
dat += "<BR><A HREF='?src=[REF(src)];operation=ai-viewmessage;message-num=[i]'>[M.title]</A>"
@@ -670,22 +642,16 @@
var/answered = aicurrmsg.possible_answers[aicurrmsg.answered]
dat += "<br> Archived Answer : [answered]"
dat += "<BR><BR>\[ <A HREF='?src=[REF(src)];operation=ai-delmessage'>Delete</A> \]"
>>>>>>> 626302c... Merge pull request #32161 from ninjanomnom/512-experimental
else
src.aistate = STATE_MESSAGELIST
src.attack_hand(user)
aistate = STATE_MESSAGELIST
attack_hand(user)
return null
if(STATE_DELMESSAGE)
<<<<<<< HEAD
if(src.aicurrmsg)
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=\ref[src];operation=ai-delmessage2'>OK</A> | <A HREF='?src=\ref[src];operation=ai-viewmessage'>Cancel</A> \]"
=======
if(aicurrmsg)
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=[REF(src)];operation=ai-delmessage2'>OK</A> | <A HREF='?src=[REF(src)];operation=ai-viewmessage'>Cancel</A> \]"
>>>>>>> 626302c... Merge pull request #32161 from ninjanomnom/512-experimental
else
src.aistate = STATE_MESSAGELIST
src.attack_hand(user)
aistate = STATE_MESSAGELIST
attack_hand(user)
return
if(STATE_STATUSDISPLAY)
@@ -716,11 +682,7 @@
dat += "<b>Emergency Maintenance Access is currently <font color='green'>DISABLED</font></b>"
dat += "<BR>Lift access restrictions on maintenance and external airlocks? <BR>\[ <A HREF='?src=[REF(src)];operation=ai-enableemergency'>OK</A> | <A HREF='?src=[REF(src)];operation=ai-viewmessage'>Cancel</A> \]"
<<<<<<< HEAD
dat += "<BR><BR>\[ [(src.aistate != STATE_DEFAULT) ? "<A HREF='?src=\ref[src];operation=ai-main'>Main Menu</A> | " : ""]<A HREF='?src=\ref[user];mach_close=communications'>Close</A> \]"
=======
dat += "<BR><BR>\[ [(aistate != STATE_DEFAULT) ? "<A HREF='?src=[REF(src)];operation=ai-main'>Main Menu</A> | " : ""]<A HREF='?src=[REF(user)];mach_close=communications'>Close</A> \]"
>>>>>>> 626302c... Merge pull request #32161 from ninjanomnom/512-experimental
return dat
/obj/machinery/computer/communications/proc/make_announcement(mob/living/user, is_silicon)
@@ -762,3 +724,12 @@
/obj/machinery/computer/communications/proc/overrideCooldown()
var/obj/item/circuitboard/computer/communications/CM = circuit
CM.lastTimeUsed = 0
/obj/machinery/computer/communications/proc/add_message(datum/comm_message/new_message)
messages += new_message
/datum/comm_message
var/title
var/content
var/list/possible_answers = list()
var/answered
+1 -1
View File
@@ -575,7 +575,7 @@
if(4)
R.fields["blood_type"] = random_blood_type()
if(5)
R.fields["p_stat"] = pick("*Unconcious*", "Active", "Physically Unfit")
R.fields["p_stat"] = pick("*Unconscious*", "Active", "Physically Unfit")
if(6)
R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable")
continue
+9 -4
View File
@@ -118,6 +118,15 @@
max_integrity = normal_integrity
if(damage_deflection == AIRLOCK_DAMAGE_DEFLECTION_N && security_level > AIRLOCK_SECURITY_METAL)
damage_deflection = AIRLOCK_DAMAGE_DEFLECTION_R
prepare_huds()
var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC]
diag_hud.add_to_hud(src)
diag_hud_set_electrified()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/door/airlock/LateInitialize()
. = ..()
if(abandoned)
var/outcome = rand(1,100)
switch(outcome)
@@ -136,10 +145,6 @@
welded = TRUE
if(24 to 30)
panel_open = TRUE
prepare_huds()
var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC]
diag_hud.add_to_hud(src)
diag_hud_set_electrified()
update_icon()
+10 -21
View File
@@ -69,9 +69,9 @@ Buildable meters
return ..()
/obj/item/pipe/proc/setPipingLayer(new_layer = PIPING_LAYER_DEFAULT)
var/obj/machinery/atmospherics/fakeA = get_pipe_cache(pipe_type)
var/obj/machinery/atmospherics/fakeA = pipe_type
if(fakeA.pipe_flags & PIPING_ALL_LAYER)
if(initial(fakeA.pipe_flags) & PIPING_ALL_LAYER)
new_layer = PIPING_LAYER_DEFAULT
piping_layer = new_layer
@@ -80,9 +80,9 @@ Buildable meters
layer = initial(layer) + ((piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_LCHANGE)
/obj/item/pipe/proc/update()
var/obj/machinery/atmospherics/A = get_pipe_cache(pipe_type)
name = "[A.name] fitting"
icon_state = A.pipe_state
var/obj/machinery/atmospherics/fakeA = pipe_type
name = "[initial(fakeA.name)] fitting"
icon_state = initial(fakeA.pipe_state)
// rotate the pipe item clockwise
@@ -147,17 +147,6 @@ Buildable meters
/obj/item/pipe/attack_self(mob/user)
return rotate()
/obj/item/pipe/proc/get_pipe_cache(type, direction)
var/static/list/obj/machinery/atmospherics/check_cache
if(!islist(check_cache))
check_cache = list()
if(!check_cache[type])
check_cache[type] = list()
if(!check_cache[type]["[direction]"])
check_cache[type]["[direction]"] = new type(null, null, direction)
return check_cache[type]["[direction]"]
/obj/item/pipe/attackby(obj/item/W, mob/user, params)
if (!istype(W, /obj/item/wrench))
return ..()
@@ -167,15 +156,15 @@ Buildable meters
fixdir()
var/obj/machinery/atmospherics/fakeA = get_pipe_cache(pipe_type, dir)
var/obj/machinery/atmospherics/fakeA = pipe_type
var/flags = initial(fakeA.pipe_flags)
for(var/obj/machinery/atmospherics/M in loc)
if((M.pipe_flags & fakeA.pipe_flags & PIPING_ONE_PER_TURF)) //Only one dense/requires density object per tile, eg connectors/cryo/heater/coolers.
if((M.pipe_flags & flags & PIPING_ONE_PER_TURF)) //Only one dense/requires density object per tile, eg connectors/cryo/heater/coolers.
to_chat(user, "<span class='warning'>Something is hogging the tile!</span>")
return TRUE
if((M.piping_layer != piping_layer) && !((M.pipe_flags | fakeA.pipe_flags) & PIPING_ALL_LAYER)) //don't continue if either pipe goes across all layers
if((M.piping_layer != piping_layer) && !((M.pipe_flags | flags) & PIPING_ALL_LAYER)) //don't continue if either pipe goes across all layers
continue
if(M.GetInitDirections() & fakeA.GetInitDirections()) // matches at least one direction on either type of pipe
if(M.GetInitDirections() & SSair.get_init_dirs(pipe_type, dir)) // matches at least one direction on either type of pipe
to_chat(user, "<span class='warning'>There is already a pipe at that location!</span>")
return TRUE
// no conflicts found
@@ -16,7 +16,7 @@
use_power = IDLE_POWER_USE //this turret uses and requires power
idle_power_usage = 50 //when inactive, this turret takes up constant 50 Equipment power
active_power_usage = 300 //when active, this turret takes up constant 300 Equipment power
req_access = list(ACCESS_SECURITY)
req_access = list(ACCESS_SEC_DOORS)
power_channel = EQUIP //drains power from the EQUIPMENT channel
var/base_icon_state = "standard"
+4 -4
View File
@@ -980,8 +980,8 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/item/clothing/mask/gas/cyborg = 1, /obj/item/clothing/suit/holidaypriest = 1, /obj/item/clothing/head/wizard/marisa/fake = 1,
/obj/item/clothing/suit/wizrobe/marisa/fake = 1, /obj/item/clothing/under/sundress = 1, /obj/item/clothing/head/witchwig = 1, /obj/item/staff/broom = 1,
/obj/item/clothing/suit/wizrobe/fake = 1, /obj/item/clothing/head/wizard/fake = 1, /obj/item/staff = 3, /obj/item/clothing/mask/gas/sexyclown = 1,
/obj/item/clothing/under/rank/clown/sexy = 1, /obj/item/clothing/mask/gas/sexymime = 1, /obj/item/clothing/under/sexymime = 1, /obj/item/clothing/mask/rat/bat = 1, /obj/item/clothing/mask/rat/bee = 1, /obj/item/clothing/mask/rat/bear = 1, /obj/item/clothing/mask/rat/raven = 1, /obj/item/clothing/mask/rat/jackal = 1, /obj/item/clothing/mask/rat/fox = 1, /obj/item/clothing/mask/rat/tribal = 1, /obj/item/clothing/mask/rat = 1, /obj/item/clothing/suit/apron/overalls = 1,
/obj/item/clothing/head/rabbitears =1, /obj/item/clothing/head/sombrero = 1, /obj/item/clothing/head/sombrero/green = 1, /obj/item/clothing/suit/poncho = 1,
/obj/item/clothing/under/rank/clown/sexy = 1, /obj/item/clothing/mask/gas/sexymime = 1, /obj/item/clothing/under/sexymime = 1, /obj/item/clothing/mask/rat/bat = 1, /obj/item/clothing/mask/rat/bee = 1, /obj/item/clothing/mask/rat/bear = 1, /obj/item/clothing/mask/rat/raven = 1, /obj/item/clothing/mask/rat/jackal = 1, /obj/item/clothing/mask/rat/fox = 1, /obj/item/clothing/mask/frog = 1, /obj/item/clothing/mask/rat/tribal = 1, /obj/item/clothing/mask/rat = 1,
/obj/item/clothing/suit/apron/overalls = 1, /obj/item/clothing/head/rabbitears =1, /obj/item/clothing/head/sombrero = 1, /obj/item/clothing/head/sombrero/green = 1, /obj/item/clothing/suit/poncho = 1,
/obj/item/clothing/suit/poncho/green = 1, /obj/item/clothing/suit/poncho/red = 1,
/obj/item/clothing/under/maid = 1, /obj/item/clothing/under/janimaid = 1, /obj/item/clothing/glasses/cold=1, /obj/item/clothing/glasses/heat=1,
/obj/item/clothing/suit/whitedress = 1,
@@ -998,8 +998,8 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/item/clothing/head/cueball = 1,
/obj/item/clothing/under/scratch = 1,
/obj/item/clothing/under/sailor = 1,
/obj/item/clothing/ears/headphones = 2,
/obj/item/clothing/head/wig/random = 3)
/obj/item/clothing/ears/headphones = 2,
/obj/item/clothing/head/wig/random = 3)
contraband = list(/obj/item/clothing/suit/judgerobe = 1, /obj/item/clothing/head/powdered_wig = 1, /obj/item/gun/magic/wand = 2, /obj/item/clothing/glasses/sunglasses/garb = 2, /obj/item/clothing/glasses/sunglasses/blindfold = 1, /obj/item/clothing/mask/muzzle = 2)
premium = list(/obj/item/clothing/suit/pirate/captain = 2, /obj/item/clothing/head/pirate/captain = 2, /obj/item/clothing/head/helmet/roman = 1, /obj/item/clothing/head/helmet/roman/legionaire = 1, /obj/item/clothing/under/roman = 1, /obj/item/clothing/shoes/roman = 1, /obj/item/shield/riot/roman = 1, /obj/item/skub = 1)
refill_canister = /obj/item/vending_refill/autodrobe
@@ -6,7 +6,7 @@
name = "exosuit drill"
desc = "Equipment for engineering and combat exosuits. This is the drill that'll pierce the heavens!"
icon_state = "mecha_drill"
equip_cooldown = 30
equip_cooldown = 15
energy_drain = 10
force = 15
@@ -99,7 +99,7 @@
desc = "Equipment for engineering and combat exosuits. This is an upgraded version of the drill that'll pierce the heavens!"
icon_state = "mecha_diamond_drill"
origin_tech = "materials=4;engineering=4"
equip_cooldown = 20
equip_cooldown = 10
force = 15
@@ -108,16 +108,16 @@
desc = "Equipment for engineering and combat exosuits. It will automatically check surrounding rock for useful minerals."
icon_state = "mecha_analyzer"
selectable = 0
equip_cooldown = 30
equip_cooldown = 15
var/scanning_time = 0
/obj/item/mecha_parts/mecha_equipment/mining_scanner/New()
..()
START_PROCESSING(SSobj, src)
START_PROCESSING(SSfastprocess, src)
/obj/item/mecha_parts/mecha_equipment/mining_scanner/process()
if(!loc)
STOP_PROCESSING(SSobj, src)
STOP_PROCESSING(SSfastprocess, src)
qdel(src)
if(istype(loc, /obj/mecha/working) && scanning_time <= world.time)
var/obj/mecha/working/mecha = loc
+1 -1
View File
@@ -106,7 +106,7 @@
if(recharge_port && !QDELETED(recharge_port))
data["recharge_port"] = list("mech" = null)
if(recharge_port.recharging_mech && !QDELETED(recharge_port.recharging_mech))
data["recharge_port"]["mech"] = list("health" = recharge_port.recharging_mech.obj_integrity, "max_integrity" = recharge_port.recharging_mech.max_integrity, "cell" = null)
data["recharge_port"]["mech"] = list("health" = recharge_port.recharging_mech.obj_integrity, "maxhealth" = recharge_port.recharging_mech.max_integrity, "cell" = null)
if(recharge_port.recharging_mech.cell && !QDELETED(recharge_port.recharging_mech.cell))
data["recharge_port"]["mech"]["cell"] = list(
"critfail" = recharge_port.recharging_mech.cell.crit_fail,
+1 -1
View File
@@ -22,7 +22,7 @@
/atom/movable/MouseDrop_T(mob/living/M, mob/living/user)
. = ..()
if(can_buckle && istype(M))
if(can_buckle && istype(M) && istype(user))
if(user_buckle_mob(M, user))
return 1
+12 -6
View File
@@ -5,20 +5,26 @@
icon_state = "rune1"
gender = NEUTER
var/do_icon_rotate = TRUE
var/rotation = 0
var/paint_colour = "#FFFFFF"
/obj/effect/decal/cleanable/crayon/Initialize(mapload, main = "#FFFFFF", var/type = "rune1", var/e_name = "rune", var/rotation = 0, var/alt_icon = null)
/obj/effect/decal/cleanable/crayon/Initialize(mapload, main, type, e_name, graf_rot, alt_icon = null)
. = ..()
name = e_name
if(e_name)
name = e_name
desc = "A [name] vandalizing the station."
if(alt_icon)
icon = alt_icon
icon_state = type
if(type)
icon_state = type
if(graf_rot)
rotation = graf_rot
if(rotation && do_icon_rotate)
var/matrix/M = matrix()
M.Turn(rotation)
src.transform = M
add_atom_colour(main, FIXED_COLOUR_PRIORITY)
if(main)
paint_colour = main
add_atom_colour(paint_colour, FIXED_COLOUR_PRIORITY)
+7 -8
View File
@@ -15,24 +15,23 @@
if(T == loc && (isspaceturf(T) || isclosedturf(T) || islava(T) || istype(T, /turf/open/water) || ischasm(T)))
qdel(src)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/obj/effect/turf_decal
var/group = TURF_DECAL_PAINT
icon = 'icons/turf/decals.dmi'
icon_state = "warningline"
layer = TURF_DECAL_LAYER
anchored = TRUE
//in case we need some special decals
/obj/effect/turf_decal/proc/get_decal()
return image(icon='icons/turf/decals.dmi',icon_state=icon_state,dir=dir,layer=TURF_LAYER)
/obj/effect/turf_decal/Initialize()
..()
return INITIALIZE_HINT_QDEL
/obj/effect/turf_decal/ComponentInitialize()
. = ..()
var/turf/T = loc
if(!istype(T)) //you know this will happen somehow
CRASH("Turf decal initialized in an object/nullspace")
T.add_decal(get_decal(),group)
return INITIALIZE_HINT_QDEL
T.AddComponent(/datum/component/turf_decal, dir, icon, icon_state)
/obj/effect/turf_decal/stripes/line
icon_state = "warningline"
+1 -1
View File
@@ -124,7 +124,7 @@
return ..()
/obj/effect/portal/proc/teleport(atom/movable/M)
if(!istype(M) || istype(M, /obj/effect) || (ismecha(M) && !mech_sized) || (!isobj(M) && !ismob(M))) //Things that shouldn't teleport.
if(!istype(M) || istype(M, /obj/effect) || isobserver(M) || (ismecha(M) && !mech_sized) || (!isobj(M) && !ismob(M))) //Things that shouldn't teleport.
return
var/turf/real_target = get_link_target_turf()
if(!istype(real_target))
@@ -312,14 +312,10 @@
icon_state = "impact_bullet"
duration = 5
/obj/effect/temp_visual/impact_effect/Initialize(mapload, atom/target, obj/item/projectile/P)
if(target == P.original)
pixel_x = target.pixel_x + P.p_x - 16
pixel_y = target.pixel_y + P.p_y - 16
else
pixel_x = target.pixel_x + rand(2, -2)
pixel_y = target.pixel_y + rand(2, -2)
. = ..()
/obj/effect/temp_visual/impact_effect/Initialize(mapload, x, y)
pixel_x = x
pixel_y = y
return ..()
/obj/effect/temp_visual/impact_effect/red_laser
icon_state = "impact_laser"
@@ -35,3 +35,5 @@
if(set_dir)
setDir(set_dir)
. = ..()
+1 -1
View File
@@ -77,7 +77,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/mob/thrownby = null
/obj/item/mouse_drag_pointer = MOUSE_ACTIVE_POINTER //the icon to indicate this object is being dragged
mouse_drag_pointer = MOUSE_ACTIVE_POINTER //the icon to indicate this object is being dragged
//So items can have custom embedd values
//Because customisation is king
+13 -11
View File
@@ -9,6 +9,8 @@ ARCD
*/
/obj/item/construction
name = "not for ingame use"
desc = "A device used to rapidly build and deconstruct. Reload with metal, plasteel, glass or compressed matter cartridges."
opacity = 0
density = FALSE
anchored = FALSE
@@ -32,11 +34,13 @@ ARCD
/obj/item/construction/Initialize()
. = ..()
desc = "\A [src]. It currently holds [matter]/[max_matter] matter-units."
spark_system = new /datum/effect_system/spark_spread
spark_system.set_up(5, 0, src)
spark_system.attach(src)
/obj/item/construction/examine(mob/user)
..()
to_chat(user, "\A [src]. It currently holds [matter]/[max_matter] matter-units." )
/obj/item/construction/Destroy()
QDEL_NULL(spark_system)
@@ -61,7 +65,6 @@ ARCD
loaded = loadwithsheets(W, plasteelmultiplier*sheetmultiplier, user) //Plasteel is worth 3 times more than glass or metal
if(loaded)
to_chat(user, "<span class='notice'>[src] now holds [matter]/[max_matter] matter-units.</span>")
desc = "A RCD. It currently holds [matter]/[max_matter] matter-units."
else
return ..()
@@ -91,7 +94,6 @@ ARCD
to_chat(user, no_ammo_message)
return 0
matter -= amount
desc = "\A [src]. It currently holds [matter]/[max_matter] matter-units."
update_icon()
return 1
@@ -117,7 +119,6 @@ ARCD
/obj/item/construction/rcd
name = "rapid-construction-device (RCD)"
desc = "A device used to rapidly build and deconstruct walls and floors."
icon = 'icons/obj/tools.dmi'
icon_state = "rcd"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
@@ -125,7 +126,6 @@ ARCD
max_matter = 160
flags_2 = NO_MAT_REDEMPTION_2
var/mode = 1
var/canRturf = 0
var/ranged = FALSE
var/airlock_type = /obj/machinery/door/airlock
var/airlock_glass = FALSE // So the floor's rcd_act knows how much ammo to use
@@ -134,6 +134,7 @@ ARCD
var/list/conf_access = null
var/use_one_access = 0 //If the airlock should require ALL or only ONE of the listed accesses.
var/delay_mod = 1
var/canRturf = FALSE //Variable for R walls to deconstruct them
/obj/item/construction/rcd/suicide_act(mob/user)
@@ -362,11 +363,11 @@ ARCD
qdel(src)
/obj/item/construction/rcd/borg/New()
..()
/obj/item/construction/rcd/borg
no_ammo_message = "<span class='warning'>Insufficient charge.</span>"
desc = "A device used to rapidly build walls and floors."
canRturf = 1
canRturf = TRUE
/obj/item/construction/rcd/borg/useResource(amount, mob/user)
if(!iscyborg(user))
@@ -401,6 +402,7 @@ ARCD
name = "industrial RCD"
max_matter = 500
matter = 500
canRturf = TRUE
/obj/item/rcd_ammo
name = "compressed matter cartridge"
@@ -420,7 +422,7 @@ ARCD
ammoamt = 160
/obj/item/construction/rcd/admin
/obj/item/construction/rcd/combat/admin
name = "admin RCD"
max_matter = INFINITY
matter = INFINITY
@@ -431,7 +433,7 @@ ARCD
/obj/item/construction/rcd/arcd
name = "advanced rapid-construction-device (ARCD)"
desc = "A prototype RCD with ranged capability and extended capacity."
desc = "A prototype RCD with ranged capability and extended capacity. Reload with metal, plasteel, glass or compressed matter cartridges."
max_matter = 300
matter = 300
delay_mod = 0.6
@@ -454,7 +456,7 @@ ARCD
/obj/item/construction/rld
name = "rapid-light-device (RLD)"
desc = "A device used to rapidly provide lighting sources to an area."
desc = "A device used to rapidly provide lighting sources to an area. Reload with metal, plasteel, glass or compressed matter cartridges."
icon = 'icons/obj/tools.dmi'
icon_state = "rld-5"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
+19 -8
View File
@@ -546,12 +546,7 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
A = get_turf(user)
//make sure what we're clicking is valid for the current mode
var/is_paintable = (p_class == PAINT_MODE && istype(A, /obj/machinery/atmospherics/pipe))
var/is_consumable = (p_class == EATING_MODE && (istype(A, /obj/item/pipe) || istype(A, /obj/item/pipe_meter) || istype(A, /obj/structure/disposalconstruct)))
var/can_make_pipe = ((atmos_piping_mode || p_class == DISPOSALS_MODE) && (isturf(A)) || istype(A, /obj/structure/lattice/catwalk) || istype(A, /obj/structure/girder))
if(!is_paintable && !is_consumable && !can_make_pipe)
return ..()
var/can_make_pipe = ((atmos_piping_mode || p_class == DISPOSALS_MODE) && (isturf(A)) || istype(A, /obj/structure/lattice) || istype(A, /obj/structure/girder))
//So that changing the menu settings doesn't affect the pipes already being built.
var/queued_p_type = p_type
@@ -561,6 +556,8 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
. = FALSE
switch(p_class) //if we've gotten this var, the target is valid
if(PAINT_MODE) //Paint pipes
if(!istype(A, /obj/machinery/atmospherics/pipe))
return ..()
var/obj/machinery/atmospherics/pipe/P = A
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
P.paint(paint_colors[paint_color])
@@ -568,6 +565,8 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
return
if(EATING_MODE) //Eating pipes
if(!(istype(A, /obj/item/pipe) || istype(A, /obj/item/pipe_meter) || istype(A, /obj/structure/disposalconstruct)))
return ..()
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, 2, target = A))
@@ -575,14 +574,22 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
qdel(A)
if(ATMOS_MODE) //Making pipes
if(!can_make_pipe)
return ..()
to_chat(user, "<span class='notice'>You start building a pipe...</span>")
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 2, target = A))
activate()
var/obj/item/pipe/P = new(A, queued_p_type, queued_p_dir)
var/obj/machinery/atmospherics/path = queued_p_type
var/pipe_item_type = initial(path.construction_type) || /obj/item/pipe
var/obj/item/pipe/P = new pipe_item_type(A, queued_p_type, queued_p_dir)
if(queued_p_flipped)
var/obj/item/pipe/trinary/flippable/F = P
F.flipped = queued_p_flipped
P.update()
P.add_fingerprint(usr)
if(!isnull(temp_piping_layer))
@@ -591,17 +598,21 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
P.setPipingLayer(piping_layer)
if(METER_MODE) //Making pipe meters
if(!can_make_pipe)
return ..()
to_chat(user, "<span class='notice'>You start building a meter...</span>")
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 2, target = A))
activate()
var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(A)
var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(get_turf(A))
if(!isnull(temp_piping_layer))
PM.setAttachLayer(temp_piping_layer)
else
PM.setAttachLayer(piping_layer)
if(DISPOSALS_MODE) //Making disposals pipes
if(!can_make_pipe)
return ..()
if(isclosedturf(A))
to_chat(user, "<span class='warning'>\the [src]'s error light flickers; there's something in the way!</span>")
return
+1
View File
@@ -301,6 +301,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
item_state = "spliffoff"
smoketime = 180
chem_volume = 50
list_reagents = null
/obj/item/clothing/mask/cigarette/rollie/New()
..()
+5 -4
View File
@@ -144,10 +144,11 @@
ui.open()
/obj/item/toy/crayon/spraycan/AltClick(mob/user)
if(has_cap)
is_capped = !is_capped
to_chat(user, "<span class='notice'>The cap on [src] is now [is_capped ? "on" : "off"].</span>")
update_icon()
if(user.canUseTopic(src, be_close=TRUE))
if(has_cap)
is_capped = !is_capped
to_chat(user, "<span class='notice'>The cap on [src] is now [is_capped ? "on" : "off"].</span>")
update_icon()
/obj/item/toy/crayon/ui_data()
var/list/data = list()
@@ -210,6 +210,7 @@
item_state = "lamp"
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
force = 10
brightness_on = 5
w_class = WEIGHT_CLASS_BULKY
flags_1 = CONDUCT_1
+60 -3
View File
@@ -2,6 +2,7 @@
/obj/item/device/instrument
name = "generic instrument"
resistance_flags = FLAMMABLE
force = 10
max_integrity = 100
icon = 'icons/obj/musician.dmi'
lefthand_file = 'icons/mob/inhands/equipment/instruments_lefthand.dmi'
@@ -49,7 +50,6 @@
desc = "A wooden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\""
icon_state = "violin"
item_state = "violin"
force = 10
hitsound = "swing_hit"
instrumentId = "violin"
@@ -80,7 +80,6 @@
icon_state = "guitar"
item_state = "guitar"
instrumentExt = "ogg"
force = 10
attack_verb = list("played metal on", "serenaded", "crashed", "smashed")
hitsound = 'sound/weapons/stringsmash.ogg'
instrumentId = "guitar"
@@ -110,6 +109,30 @@
item_state = "accordion"
instrumentId = "accordion"
/obj/item/device/instrument/trumpet
name = "trumpet"
desc = "To announce the arrival of the king!"
icon_state = "trumpet"
item_state = "trombone"
instrumentId = "trombone"
/obj/item/device/instrument/trumpet/spectral
name = "spectral trumpet"
desc = "Things are about to get spooky!"
icon_state = "trumpet"
item_state = "trombone"
force = 0
instrumentId = "trombone"
attack_verb = list("played","jazzed","trumpeted","mourned","dooted","spooked")
/obj/item/device/instrument/trumpet/spectral/Initialize()
. = ..()
AddComponent(/datum/component/spooky)
/obj/item/device/instrument/trumpet/spectral/attack(mob/living/carbon/C, mob/user)
playsound (loc, 'sound/instruments/trombone/En4.mid', 100,1,-1)
..()
/obj/item/device/instrument/saxophone
name = "saxophone"
desc = "This soothing sound will be sure to leave your audience in tears."
@@ -117,6 +140,23 @@
item_state = "saxophone"
instrumentId = "saxophone"
/obj/item/device/instrument/saxophone/spectral
name = "spectral saxophone"
desc = "This spooky sound will be sure to leave mortals in bones."
icon_state = "saxophone"
item_state = "saxophone"
instrumentId = "saxophone"
force = 0
attack_verb = list("played","jazzed","saxxed","mourned","dooted","spooked")
/obj/item/device/instrument/saxophone/spectral/Initialize()
. = ..()
AddComponent(/datum/component/spooky)
/obj/item/device/instrument/saxophone/spectral/attack(mob/living/carbon/C, mob/user)
playsound (loc, 'sound/instruments/saxophone/En4.mid', 100,1,-1)
..()
/obj/item/device/instrument/trombone
name = "trombone"
desc = "How can any pool table ever hope to compete?"
@@ -124,9 +164,27 @@
item_state = "trombone"
instrumentId = "trombone"
/obj/item/device/instrument/trombone/spectral
name = "spectral trombone"
desc = "A skeleton's favorite instrument. Apply directly on the mortals."
instrumentId = "trombone"
icon_state = "trombone"
item_state = "trombone"
force = 0
attack_verb = list("played","jazzed","tromboned","mourned","dooted","spooked")
/obj/item/device/instrument/trombone/spectral/Initialize()
. = ..()
AddComponent(/datum/component/spooky)
/obj/item/device/instrument/trombone/spectral/attack(mob/living/carbon/C, mob/user)
playsound (loc, 'sound/instruments/trombone/Cn4.mid', 100,1,-1)
..()
/obj/item/device/instrument/recorder
name = "recorder"
desc = "Just like in school, playing ability and all."
force = 5
icon_state = "recorder"
item_state = "recorder"
instrumentId = "recorder"
@@ -163,4 +221,3 @@
throw_speed = 3
throw_range = 15
hitsound = 'sound/items/bikehorn.ogg'
@@ -52,6 +52,7 @@
flags_1 = CONDUCT_1
slot_flags = SLOT_BELT
origin_tech = "magnets=3;engineering=4"
force = 8
var/max_uses = 20
var/uses = 0
@@ -51,7 +51,7 @@
origin_tech = "syndicate=3"
icon_state = "syndie_headset"
item_state = "syndie_headset"
flags_2 = BANG_PROTECT_2
flags_2 = BANG_PROTECT_2 | NO_EMP_WIRES_2
/obj/item/device/radio/headset/syndicate/alt/leader
name = "team leader headset"
@@ -80,7 +80,7 @@
desc = "This is used by your elite security force. Protects ears from flashbangs.\nTo access the security channel, use :s."
icon_state = "sec_headset_alt"
item_state = "sec_headset_alt"
flags_2 = BANG_PROTECT_2
flags_2 = BANG_PROTECT_2 | NO_EMP_WIRES_2
/obj/item/device/radio/headset/headset_eng
name = "engineering radio headset"
@@ -132,7 +132,7 @@
desc = "The headset of the boss. Protects ears from flashbangs.\nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
flags_2 = BANG_PROTECT_2
flags_2 = BANG_PROTECT_2 | NO_EMP_WIRES_2
/obj/item/device/radio/headset/heads/rd
name = "\proper the research director's headset"
@@ -151,7 +151,7 @@
desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs.\nTo access the security channel, use :s. For command, use :c."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
flags_2 = BANG_PROTECT_2
flags_2 = BANG_PROTECT_2 | NO_EMP_WIRES_2
/obj/item/device/radio/headset/heads/ce
name = "\proper the chief engineer's headset"
@@ -205,7 +205,7 @@
icon_state = "cent_headset_alt"
item_state = "cent_headset_alt"
keyslot = null
flags_2 = BANG_PROTECT_2
flags_2 = BANG_PROTECT_2 | NO_EMP_WIRES_2
/obj/item/device/radio/headset/ai
name = "\proper Integrated Subspace Transceiver "
@@ -29,6 +29,7 @@
var/emped = 0 //Highjacked to track the number of consecutive EMPs on the radio, allowing consecutive EMP's to stack properly.
// "Example" = FREQ_LISTENING|FREQ_BROADCASTING
flags_1 = CONDUCT_1 | HEAR_1
flags_2 = NO_EMP_WIRES_2
slot_flags = SLOT_BELT
throw_speed = 3
throw_range = 7
+8 -9
View File
@@ -106,8 +106,8 @@ MASS SPECTROMETER
// Used by the PDA medical scanner too
/proc/healthscan(mob/living/user, mob/living/M, mode = 1, advanced = FALSE)
if(user.incapacitated() || user.eye_blind)
/proc/healthscan(mob/user, mob/living/M, mode = 1, advanced = FALSE)
if(isliving(user) && (user.incapacitated() || user.eye_blind))
return
//Damage specifics
var/oxy_loss = M.getOxyLoss()
@@ -280,18 +280,17 @@ MASS SPECTROMETER
to_chat(user, "<span class='notice'>[cyberimp_detect]</span>")
/proc/chemscan(mob/living/user, mob/living/M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.reagents)
if(H.reagents.reagent_list.len)
if(istype(M))
if(M.reagents)
if(M.reagents.reagent_list.len)
to_chat(user, "<span class='notice'>Subject contains the following reagents:</span>")
for(var/datum/reagent/R in H.reagents.reagent_list)
for(var/datum/reagent/R in M.reagents.reagent_list)
to_chat(user, "<span class='notice'>[R.volume] units of [R.name][R.overdosed == 1 ? "</span> - <span class='boldannounce'>OVERDOSING</span>" : ".</span>"]")
else
to_chat(user, "<span class='notice'>Subject contains no reagents.</span>")
if(H.reagents.addiction_list.len)
if(M.reagents.addiction_list.len)
to_chat(user, "<span class='boldannounce'>Subject is addicted to the following reagents:</span>")
for(var/datum/reagent/R in H.reagents.addiction_list)
for(var/datum/reagent/R in M.reagents.addiction_list)
to_chat(user, "<span class='danger'>[R.name]</span>")
else
to_chat(user, "<span class='notice'>Subject is not addicted to any reagents.</span>")
+1
View File
@@ -140,6 +140,7 @@
user.put_in_hands(ptank)
ptank = null
to_chat(user, "<span class='notice'>You remove the plasma tank from [src]!</span>")
update_icon()
/obj/item/flamethrower/examine(mob/user)
..()
+96 -95
View File
@@ -1,50 +1,50 @@
/obj/item/grenade
name = "grenade"
desc = "It has an adjustable timer."
w_class = WEIGHT_CLASS_SMALL
icon = 'icons/obj/grenade.dmi'
icon_state = "grenade"
item_state = "flashbang"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
throw_speed = 3
throw_range = 7
flags_1 = CONDUCT_1
slot_flags = SLOT_BELT
resistance_flags = FLAMMABLE
max_integrity = 40
var/active = 0
var/det_time = 50
var/display_timer = 1
/obj/item/grenade/deconstruct(disassembled = TRUE)
if(!disassembled)
prime()
if(!QDELETED(src))
qdel(src)
/obj/item/grenade/proc/clown_check(mob/living/carbon/human/user)
if(user.disabilities & CLUMSY && prob(50))
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
/obj/item/grenade
name = "grenade"
desc = "It has an adjustable timer."
w_class = WEIGHT_CLASS_SMALL
icon = 'icons/obj/grenade.dmi'
icon_state = "grenade"
item_state = "flashbang"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
throw_speed = 3
throw_range = 7
flags_1 = CONDUCT_1
slot_flags = SLOT_BELT
resistance_flags = FLAMMABLE
max_integrity = 40
var/active = 0
var/det_time = 50
var/display_timer = 1
/obj/item/grenade/deconstruct(disassembled = TRUE)
if(!disassembled)
prime()
if(!QDELETED(src))
qdel(src)
/obj/item/grenade/proc/clown_check(mob/living/carbon/human/user)
if(user.disabilities & CLUMSY && prob(50))
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
preprime(user, 5, FALSE)
return FALSE
return TRUE
/obj/item/grenade/examine(mob/user)
..()
if(display_timer)
if(det_time > 1)
to_chat(user, "The timer is set to [det_time/10] second\s.")
else
to_chat(user, "\The [src] is set for instant detonation.")
/obj/item/grenade/attack_self(mob/user)
if(!active)
if(clown_check(user))
preprime(user)
/obj/item/grenade/examine(mob/user)
..()
if(display_timer)
if(det_time > 1)
to_chat(user, "The timer is set to [det_time/10] second\s.")
else
to_chat(user, "\The [src] is set for instant detonation.")
/obj/item/grenade/attack_self(mob/user)
if(!active)
if(clown_check(user))
preprime(user)
/obj/item/grenade/proc/log_grenade(mob/user, turf/T)
var/area/A = get_area(T)
var/message = "[ADMIN_LOOKUPFLW(user)]) has primed \a [src] for detonation at [ADMIN_COORDJMP(T)]"
@@ -52,57 +52,58 @@
message_admins(message)
log_game("[key_name(user)] has primed \a [src] for detonation at [A.name] [COORD(T)].")
/obj/item/grenade/proc/preprime(mob/user, delayoverride, msg = TRUE)
/obj/item/grenade/proc/preprime(mob/user, delayoverride, msg = TRUE, volume = 60)
var/turf/T = get_turf(src)
log_grenade(user, T)
if(iscarbon(user))
var/mob/living/carbon/C = user
C.throw_mode_on()
if(msg)
to_chat(user, "<span class='warning'>You prime \the [src]! [det_time/10] seconds!</span>")
playsound(loc, 'sound/weapons/armbomb.ogg', 60, 1)
active = TRUE
icon_state = initial(icon_state) + "_active"
add_fingerprint(user)
log_grenade(user, T) //Inbuilt admin procs already handle null users
if(user)
add_fingerprint(user)
if(iscarbon(user))
var/mob/living/carbon/C = user
C.throw_mode_on()
if(msg)
to_chat(user, "<span class='warning'>You prime \the [src]! [det_time/10] seconds!</span>")
playsound(src, 'sound/weapons/armbomb.ogg', volume, 1)
active = TRUE
icon_state = initial(icon_state) + "_active"
addtimer(CALLBACK(src, .proc/prime), isnull(delayoverride)? det_time : delayoverride)
/obj/item/grenade/proc/prime()
/obj/item/grenade/proc/update_mob()
if(ismob(loc))
var/mob/M = loc
M.dropItemToGround(src)
/obj/item/grenade/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/screwdriver))
switch(det_time)
if ("1")
det_time = 10
to_chat(user, "<span class='notice'>You set the [name] for 1 second detonation time.</span>")
if ("10")
det_time = 30
to_chat(user, "<span class='notice'>You set the [name] for 3 second detonation time.</span>")
if ("30")
det_time = 50
to_chat(user, "<span class='notice'>You set the [name] for 5 second detonation time.</span>")
if ("50")
det_time = 1
to_chat(user, "<span class='notice'>You set the [name] for instant detonation.</span>")
add_fingerprint(user)
else
return ..()
/obj/item/grenade/attack_hand()
walk(src, null, null)
..()
/obj/item/grenade/attack_paw(mob/user)
return attack_hand(user)
/obj/item/grenade/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
var/obj/item/projectile/P = hitby
if(damage && attack_type == PROJECTILE_ATTACK && P.damage_type != STAMINA && prob(15))
owner.visible_message("<span class='danger'>[attack_text] hits [owner]'s [src], setting it off! What a shot!</span>")
prime()
/obj/item/grenade/proc/prime()
/obj/item/grenade/proc/update_mob()
if(ismob(loc))
var/mob/M = loc
M.dropItemToGround(src)
/obj/item/grenade/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/screwdriver))
switch(det_time)
if ("1")
det_time = 10
to_chat(user, "<span class='notice'>You set the [name] for 1 second detonation time.</span>")
if ("10")
det_time = 30
to_chat(user, "<span class='notice'>You set the [name] for 3 second detonation time.</span>")
if ("30")
det_time = 50
to_chat(user, "<span class='notice'>You set the [name] for 5 second detonation time.</span>")
if ("50")
det_time = 1
to_chat(user, "<span class='notice'>You set the [name] for instant detonation.</span>")
add_fingerprint(user)
else
return ..()
/obj/item/grenade/attack_hand()
walk(src, null, null)
..()
/obj/item/grenade/attack_paw(mob/user)
return attack_hand(user)
/obj/item/grenade/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
var/obj/item/projectile/P = hitby
if(damage && attack_type == PROJECTILE_ATTACK && P.damage_type != STAMINA && prob(15))
owner.visible_message("<span class='danger'>[attack_text] hits [owner]'s [src], setting it off! What a shot!</span>")
prime()
return TRUE //It hit the grenade, not them
+9
View File
@@ -91,6 +91,7 @@
icon_state = "cuff"
item_state = "coil"
item_color = "red"
color = "#ff0000"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
materials = list(MAT_METAL=150, MAT_GLASS=75)
@@ -109,6 +110,7 @@
update_icon()
/obj/item/restraints/handcuffs/cable/update_icon()
color = null
add_atom_colour(item_color, FIXED_COLOUR_PRIORITY)
/obj/item/restraints/handcuffs/cable/attack(mob/living/carbon/C, mob/living/carbon/human/user)
@@ -130,24 +132,31 @@
/obj/item/restraints/handcuffs/cable/red
item_color = "red"
color = "#ff0000"
/obj/item/restraints/handcuffs/cable/yellow
item_color = "yellow"
color = "#ffff00"
/obj/item/restraints/handcuffs/cable/blue
item_color = "blue"
color = "#1919c8"
/obj/item/restraints/handcuffs/cable/green
item_color = "green"
color = "#00aa00"
/obj/item/restraints/handcuffs/cable/pink
item_color = "pink"
color = "#ff3ccd"
/obj/item/restraints/handcuffs/cable/orange
item_color = "orange"
color = "#ff8000"
/obj/item/restraints/handcuffs/cable/cyan
item_color = "cyan"
color = "#00ffff"
/obj/item/restraints/handcuffs/cable/white
item_color = "white"
+2
View File
@@ -96,6 +96,8 @@
return ..()
/obj/item/inducer/proc/recharge(atom/movable/A, mob/user)
if(!isturf(A) && user.loc == A)
return FALSE
if(recharging)
return TRUE
else
+140 -1
View File
@@ -7,14 +7,66 @@
w_class = WEIGHT_CLASS_SMALL
resistance_flags = FLAMMABLE
var/list/squeak_override //Weighted list; If you want your plush to have different squeak sounds use this
var/stuffed = TRUE //If the plushie has stuffing in it
var/obj/item/grenade/grenade //You can remove the stuffing from a plushie and add a grenade to it for *nefarious uses*
/obj/item/toy/plush/Initialize()
. = ..()
AddComponent(/datum/component/squeak, squeak_override)
/obj/item/toy/plush/Destroy()
QDEL_NULL(grenade)
return ..()
/obj/item/toy/plush/handle_atom_del(atom/A)
if(A == grenade)
grenade = null
..()
/obj/item/toy/plush/attack_self(mob/user)
. = ..()
to_chat(user, "<span class='notice'>You pet [src]. D'awww.</span>")
if(stuffed || grenade)
to_chat(user, "<span class='notice'>You pet [src]. D'awww.</span>")
if(grenade && !grenade.active)
if(istype(grenade, /obj/item/grenade/chem_grenade))
var/obj/item/grenade/chem_grenade/G = grenade
if(G.nadeassembly) //We're activated through different methods
return
log_game("[key_name(user)] activated a hidden grenade in [src].")
grenade.preprime(user, msg = FALSE, volume = 10)
else
to_chat(user, "<span class='notice'>You try to pet [src], but it has no stuffing. Aww...</span>")
/obj/item/toy/plush/attackby(obj/item/I, mob/living/user, params)
if(I.is_sharp())
if(!grenade)
if(!stuffed)
to_chat(user, "<span class='warning'>You already murdered it!</span>")
return
user.visible_message("<span class='notice'>[user] tears out the stuffing from [src]!</span>", "<span class='notice'>You rip a bunch of the stuffing from [src]. Murderer.</span>")
playsound(I, I.usesound, 50, TRUE)
stuffed = FALSE
else
to_chat(user, "<span class='notice'>You remove the grenade from [src].</span>")
user.put_in_hands(grenade)
grenade = null
return
if(istype(I, /obj/item/grenade))
if(stuffed)
to_chat(user, "<span class='warning'>You need to remove some stuffing first!</span>")
return
if(grenade)
to_chat(user, "<span class='warning'>[src] already has a grenade!</span>")
return
if(!user.transferItemToLoc(I, src))
return
user.visible_message("<span class='warning'>[user] slides [grenade] into [src].</span>", \
"<span class='danger'>You slide [I] into [src].</span>")
grenade = I
var/turf/T = get_turf(user)
log_game("[key_name(user)] added a grenade ([I.name]) to [src] at [COORD(T)].")
return
return ..()
/obj/item/toy/plush/carpplushie
name = "space carp plushie"
@@ -35,11 +87,98 @@
name = "ratvar plushie"
desc = "An adorable plushie of the clockwork justiciar himself with new and improved spring arm action."
icon_state = "plushvar"
var/obj/item/toy/plush/narplush/clash_target
/obj/item/toy/plush/plushvar/Moved()
. = ..()
if(clash_target)
return
var/obj/item/toy/plush/narplush/P = locate() in range(1, src)
if(P && istype(P.loc, /turf/open) && !P.clashing)
clash_of_the_plushies(P)
/obj/item/toy/plush/plushvar/proc/clash_of_the_plushies(obj/item/toy/plush/narplush/P)
clash_target = P
P.clashing = TRUE
say("YOU.")
P.say("Ratvar?!")
var/obj/item/toy/plush/a_winnar_is
var/victory_chance = 10
for(var/i in 1 to 10) //We only fight ten times max
if(QDELETED(src))
P.clashing = FALSE
return
if(QDELETED(P))
clash_target = null
return
if(!Adjacent(P))
visible_message("<span class='warning'>The two plushies angrily flail at each other before giving up.</span>")
clash_target = null
P.clashing = FALSE
return
playsound(src, 'sound/magic/clockwork/ratvar_attack.ogg', 50, TRUE, frequency = 2)
sleep(2.4)
if(QDELETED(src))
P.clashing = FALSE
return
if(QDELETED(P))
clash_target = null
return
if(prob(victory_chance))
a_winnar_is = src
break
P.SpinAnimation(5, 0)
sleep(5)
if(QDELETED(src))
P.clashing = FALSE
return
if(QDELETED(P))
clash_target = null
return
playsound(P, 'sound/magic/clockwork/narsie_attack.ogg', 50, TRUE, frequency = 2)
sleep(3.3)
if(QDELETED(src))
P.clashing = FALSE
return
if(QDELETED(P))
clash_target = null
return
if(prob(victory_chance))
a_winnar_is = P
break
SpinAnimation(5, 0)
victory_chance += 10
sleep(5)
if(!a_winnar_is)
a_winnar_is = pick(src, P)
if(a_winnar_is == src)
say(pick("DIE.", "ROT."))
P.say(pick("Nooooo...", "Not die. To y-", "Die. Ratv-", "Sas tyen re-"))
playsound(src, 'sound/magic/clockwork/anima_fragment_attack.ogg', 50, TRUE, frequency = 2)
playsound(P, 'sound/magic/demon_dies.ogg', 50, TRUE, frequency = 2)
explosion(P, 0, 0, 1)
qdel(P)
clash_target = null
else
say("NO! I will not be banished again...")
P.say(pick("Ha.", "Ra'sha fonn dest.", "You fool. To come here."))
playsound(src, 'sound/magic/clockwork/anima_fragment_death.ogg', 50, TRUE, frequency = 2)
playsound(P, 'sound/magic/demon_attack1.ogg', 50, TRUE, frequency = 2)
explosion(src, 0, 0, 1)
qdel(src)
P.clashing = FALSE
/obj/item/toy/plush/narplush
name = "nar'sie plushie"
desc = "A small stuffed doll of the elder god nar'sie. Who thought this was a good children's toy?"
icon_state = "narplush"
var/clashing
/obj/item/toy/plush/narplush/Moved()
. = ..()
var/obj/item/toy/plush/plushvar/P = locate() in range(1, src)
if(P && istype(P.loc, /turf/open) && !P.clash_target && !clashing)
P.clash_of_the_plushies(src)
/obj/item/toy/plush/lizardplushie
name = "lizard plushie"
+34 -21
View File
@@ -26,8 +26,31 @@
var/fire_mode = PCANNON_FIREALL
var/automatic = FALSE
var/clumsyCheck = TRUE
var/list/allowed_typecache //Leave as null to allow all.
var/charge_amount = 1
var/charge_ticks = 1
var/charge_tick = 0
var/charge_type
var/selfcharge = FALSE
trigger_guard = TRIGGER_GUARD_NORMAL
/obj/item/pneumatic_cannon/Initialize()
. = ..()
if(selfcharge)
init_charge()
/obj/item/pneumatic_cannon/proc/init_charge() //wrapper so it can be vv'd easier
START_PROCESSING(SSobj, src)
/obj/item/pneumatic_cannon/process()
if(++charge_tick >= charge_ticks && charge_type)
fill_with_type(charge_type, charge_amount)
/obj/item/pneumatic_cannon/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/pneumatic_cannon/CanItemAutoclick()
return automatic
@@ -75,6 +98,10 @@
load_item(IW, user)
/obj/item/pneumatic_cannon/proc/can_load_item(obj/item/I, mob/user)
if(allowed_typecache && !is_type_in_typecache(I, allowed_typecache))
if(user)
to_chat(user, "<span class='warning'>[I] won't fit into [src]!</span>")
return
if((loadedWeightClass + I.w_class) > maxWeightClass) //Only make messages if there's a user
if(user)
to_chat(user, "<span class='warning'>\The [I] won't fit into \the [src]!</span>")
@@ -233,28 +260,14 @@
throw_amount = 1
maxWeightClass = 150 //50 pies. :^)
clumsyCheck = FALSE
var/static/list/pie_typecache = typecacheof(/obj/item/reagent_containers/food/snacks/pie)
/obj/item/pneumatic_cannon/pie/can_load_item(obj/item/I, mob/user)
if(istype(I, /obj/item/reagent_containers/food/snacks/pie))
return ..()
to_chat(user, "<span class='warning'>[src] only accepts pies!</span>")
return FALSE
/obj/item/pneumatic_cannon/pie/Initialize()
. = ..()
allowed_typecache = pie_typecache
/obj/item/pneumatic_cannon/pie/selfcharge
automatic = TRUE
var/charge_amount = 1
var/charge_ticks = 1
var/charge_tick = 0
selfcharge = TRUE
charge_type = /obj/item/reagent_containers/food/snacks/pie/cream
maxWeightClass = 60 //20 pies.
/obj/item/pneumatic_cannon/pie/selfcharge/Initialize()
. = ..()
START_PROCESSING(SSobj, src)
/obj/item/pneumatic_cannon/pie/selfcharge/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/pneumatic_cannon/pie/selfcharge/process()
if(++charge_tick >= charge_ticks)
fill_with_type(/obj/item/reagent_containers/food/snacks/pie/cream, charge_amount)
+22 -3
View File
@@ -546,9 +546,11 @@
to_chat(user, "<span class='boldwarning'>[src] is still recycling its projectors!</span>")
return
cycle_delay = world.time + PKBORG_DAMPEN_CYCLE_DELAY
active = !active
if(active)
activate_field(user)
if(!active)
if(!user.has_buckled_mobs())
activate_field()
else
to_chat(user, "<span class='warning'>[src]'s safety cutoff prevents you from activating it due to living beings being ontop of you!</span>")
else
deactivate_field()
update_icon()
@@ -561,12 +563,29 @@
if(istype(dampening_field))
QDEL_NULL(dampening_field)
dampening_field = make_field(/datum/proximity_monitor/advanced/peaceborg_dampener, list("current_range" = field_radius, "host" = src, "projector" = src))
var/mob/living/silicon/robot/owner = get_host()
if(owner)
owner.module.allow_riding = FALSE
active = TRUE
/obj/item/borg/projectile_dampen/proc/deactivate_field()
QDEL_NULL(dampening_field)
visible_message("<span class='warning'>\The [src] shuts off!</span>")
for(var/P in tracked)
restore_projectile(P)
active = FALSE
var/mob/living/silicon/robot/owner = get_host()
if(owner)
owner.module.allow_riding = TRUE
/obj/item/borg/projectile_dampen/proc/get_host()
if(istype(host))
return host
else
if(iscyborg(host.loc))
return host.loc
return null
/obj/item/borg/projectile_dampen/dropped()
. = ..()
@@ -320,7 +320,7 @@
/obj/item/borg/upgrade/hypospray/action(mob/living/silicon/robot/R)
if(..())
return
for(var/obj/item/reagent_containers/borghypo/H in R.module)
for(var/obj/item/reagent_containers/borghypo/H in R.module.modules)
if(H.accepts_reagent_upgrades)
for(var/re in additional_reagents)
H.add_reagent(re)
@@ -355,7 +355,7 @@
return
var/found_hypo = FALSE
for(var/obj/item/reagent_containers/borghypo/H in R.module)
for(var/obj/item/reagent_containers/borghypo/H in R.module.modules)
H.bypass_protection = TRUE
found_hypo = TRUE
+1
View File
@@ -3,6 +3,7 @@
icon = 'icons/obj/kitchen.dmi'
icon_state = "sharpener"
desc = "A block that makes things sharp."
force = 5
var/used = 0
var/increment = 4
var/max = 30
@@ -274,6 +274,9 @@ GLOBAL_LIST_INIT(titanium_recipes, list ( \
recipes = GLOB.titanium_recipes
. = ..()
/obj/item/stack/sheet/mineral/titanium/fifty
amount = 50
/*
* Plastitanium
@@ -93,7 +93,7 @@
/obj/item/stack/tile/basalt
name = "basalt tile"
singular_name = "basalt floor tile"
desc = "Artificially made ashy soil themed on a hostile enviroment."
desc = "Artificially made ashy soil themed on a hostile environment."
icon_state = "tile_basalt"
origin_tech = "materials=1"
turf_type = /turf/open/floor/grass/fakebasalt
+6 -5
View File
@@ -128,11 +128,12 @@
if(!locked)
to_chat(user, "<span class='notice'>Alt-click to [open ? "close":"open"] it.</span>")
/obj/item/storage/lockbox/medal/AltClick()
if(!locked)
open = (open ? FALSE : TRUE)
update_icon()
..()
/obj/item/storage/lockbox/medal/AltClick(mob/user)
if(user.canUseTopic(src, be_close=TRUE))
if(!locked)
open = (open ? FALSE : TRUE)
update_icon()
..()
/obj/item/storage/lockbox/medal/PopulateContents()
new /obj/item/clothing/accessory/medal/gold/captain(src)
+13 -4
View File
@@ -150,12 +150,21 @@ Frequency:
. = ..()
active_portal_pairs = list()
/obj/item/hand_tele/afterattack(atom/target, mob/user, proximity, params)
if(is_parent_of_portal(target))
qdel(target)
to_chat(user, "<span class='notice'>You dispel [target] remotely with \the [src]!</span>")
/obj/item/hand_tele/pre_attackby(atom/target, mob/user, params)
if(try_dispel_portal(target, user))
return FALSE
return ..()
/obj/item/hand_tele/proc/try_dispel_portal(atom/target, mob/user)
if(is_parent_of_portal(target))
qdel(target)
to_chat(user, "<span class='notice'>You dispel [target] with \the [src]!</span>")
return TRUE
return FALSE
/obj/item/hand_tele/afterattack(atom/target, mob/user)
try_dispel_portal(target, user)
. = ..()
/obj/item/hand_tele/attack_self(mob/user)
var/turf/current_location = get_turf(user)//What turf is the user on?
+9
View File
@@ -457,6 +457,15 @@
flamethrower_screwdriver(I, user)
else if(istype(I, /obj/item/stack/rods))
flamethrower_rods(I, user)
else if(istype(I, /obj/item/reagent_containers) && I.is_open_container())
var/amountNeeded = max_fuel - get_fuel()
var/obj/item/reagent_containers/container = I
if(length(container.reagents.reagent_list) > 1)
to_chat(user, "<span class='warning'>[container] has too many chemicals mixed into it. You wouldn't want to put the wrong chemicals into [src].</span>")
return ..()
if(amountNeeded > 0 && container.reagents.has_reagent("welding_fuel"))
container.reagents.trans_id_to(src, "welding_fuel", amountNeeded)
to_chat(user, "<span class='notice'>You transfer some fuel from [container] to [src].</span>")
else
return ..()
+9 -9
View File
@@ -457,15 +457,15 @@
explosive.prime()
qdel(src)
/obj/item/twohanded/spear/AltClick()
..()
if(!explosive)
return
if(ismob(loc))
var/mob/M = loc
var/input = stripped_input(M,"What do you want your war cry to be? You will shout it when you hit someone in melee.", ,"", 50)
if(input)
src.war_cry = input
/obj/item/twohanded/spear/AltClick(mob/user)
if(user.canUseTopic(src, be_close=TRUE))
..()
if(!explosive)
return
if(istype(user) && loc == user)
var/input = stripped_input(user,"What do you want your war cry to be? You will shout it when you hit someone in melee.", ,"", 50)
if(input)
src.war_cry = input
/obj/item/twohanded/spear/CheckParts(list/parts_list)
var/obj/item/twohanded/spear/S = locate() in parts_list
+4 -2
View File
@@ -5,6 +5,7 @@
icon_state = "toyhammer"
slot_flags = SLOT_BELT
throwforce = 0
force = 1
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
@@ -20,10 +21,11 @@
/obj/item/banhammer/attack(mob/M, mob/user)
if(user.zone_selected == "head")
M.visible_message("<span class='danger'>[user] are stroking the head of [M] with a bangammer</span>", "<span class='userdanger'>[user] are stroking the head with a bangammer</span>", "you hear a bangammer stroking a head");
else
M.visible_message("<span class='danger'>[M] has been banned FOR NO REISIN by [user]</span>", "<span class='userdanger'>You have been banned FOR NO REISIN by [user]</span>", "you hear a banhammer banning someone")
playsound(loc, 'sound/effects/adminhelp.ogg', 15) //keep it at 15% volume so people don't jump out of their skin too much
if(user.a_intent != INTENT_HELP)
return ..(M, user)
/obj/item/sord
name = "\improper SORD"
@@ -591,7 +593,7 @@
desc = "This is how real men fight."
icon_state = "latexballon"
item_state = "nothing"
force = 1
force = 0
throwforce = 0
flags_1 = DROPDEL_1 | ABSTRACT_1
attack_verb = list("slapped")
@@ -101,7 +101,7 @@
desc = "A collapsed roller bed that can be carried around."
icon = 'icons/obj/rollerbed.dmi'
icon_state = "folded"
w_class = WEIGHT_CLASS_BULKY // Can't be put in backpacks.
w_class = WEIGHT_CLASS_NORMAL // No more excuses, stop getting blood everywhere
/obj/item/roller/attackby(obj/item/I, mob/living/user, params)
if(istype(I, /obj/item/roller/robo))
@@ -15,18 +15,20 @@
delivery_icon = "deliverybox"
anchorable = FALSE
var/move_speed_multiplier = 1
var/move_delay = 0
var/move_delay = FALSE
var/egged = 0
/obj/structure/closet/cardboard/relaymove(mob/user, direction)
if(opened || move_delay || user.stat || user.IsStun() || user.IsKnockdown() || user.IsUnconscious() || !isturf(loc) || !has_gravity(loc))
return
move_delay = 1
move_delay = TRUE
if(step(src, direction))
spawn(CONFIG_GET(number/walk_delay) * move_speed_multiplier)
move_delay = 0
addtimer(CALLBACK(src, .proc/ResetMoveDelay), CONFIG_GET(number/walk_delay) * move_speed_multiplier)
else
move_delay = 0
ResetMoveDelay()
/obj/structure/closet/cardboard/proc/ResetMoveDelay()
move_delay = FALSE
/obj/structure/closet/cardboard/open()
if(opened || !can_open())
@@ -28,7 +28,7 @@
new /obj/item/clothing/gloves/color/captain(src)
new /obj/item/restraints/handcuffs/cable/zipties(src)
new /obj/item/storage/belt/sabre(src)
new /obj/item/gun/energy/e_gun(src)
new /obj/item/gun/energy/e_gun/cx(src)
new /obj/item/door_remote/captain(src)
/obj/structure/closet/secure_closet/hop
@@ -51,7 +51,7 @@
new /obj/item/device/assembly/flash/handheld(src)
new /obj/item/clothing/glasses/sunglasses(src)
new /obj/item/restraints/handcuffs/cable/zipties(src)
new /obj/item/gun/energy/e_gun(src)
new /obj/item/gun/energy/e_gun/cx(src)
new /obj/item/clothing/neck/petcollar(src)
new /obj/item/door_remote/civillian(src)
@@ -67,6 +67,8 @@
new /obj/item/device/radio/headset/heads/hos(src)
new /obj/item/clothing/under/hosparadefem(src)
new /obj/item/clothing/under/hosparademale(src)
new /obj/item/clothing/under/rank/head_of_security/skirt(src)
new /obj/item/clothing/suit/armor/hos/trenchcoat/cloak(src)
new /obj/item/clothing/suit/armor/vest/leather(src)
new /obj/item/clothing/suit/armor/hos(src)
new /obj/item/clothing/under/rank/head_of_security/alt(src)
@@ -117,6 +119,7 @@
/obj/structure/closet/secure_closet/security/PopulateContents()
..()
new /obj/item/clothing/under/rank/security/skirt(src)
new /obj/item/clothing/suit/armor/vest(src)
new /obj/item/clothing/head/helmet/sec(src)
new /obj/item/device/radio/headset/headset_sec(src)
@@ -122,10 +122,10 @@
golems, so that no golem may ever be forced to serve again.</b>"
/obj/effect/mob_spawn/human/golem/Initialize(mapload, datum/species/golem/species = null, mob/creator = null)
. = ..()
if(species)
if(species) //spawners list uses object name to register so this goes before ..()
name += " ([initial(species.prefix)])"
mob_species = species
. = ..()
var/area/A = get_area(src)
if(!mapload && A)
notify_ghosts("\A [initial(species.prefix)] golem shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE)
@@ -316,10 +316,10 @@
/obj/effect/mob_spawn/human/hotel_staff/security
name = "hotel security sleeper"
mob_name = "hotel security memeber"
mob_name = "hotel security member"
outfit = /datum/outfit/hotelstaff/security
flavour_text = "You are a peacekeeper assigned to this hotel to protect the intrests of the company while keeping the peace between \
guests and the staff.Do <font size=6><b>NOT</b></font> leave the hotel, as that is grounds for contract termination."
flavour_text = "You are a peacekeeper assigned to this hotel to protect the interests of the company while keeping the peace between \
guests and the staff. Do <font size=6><b>NOT</b></font> leave the hotel, as that is grounds for contract termination."
objectives = "Do not leave your assigned hotel. Try and keep the peace between staff and guests, non-lethal force heavily advised if possible."
/datum/outfit/hotelstaff/security
+89 -46
View File
@@ -1,13 +1,16 @@
/obj/structure/reflector
name = "reflector frame"
icon = 'icons/obj/stock_parts.dmi'
icon_state = "box_0"
desc = "An angled mirror for reflecting lasers."
name = "reflector base"
icon = 'icons/obj/structures.dmi'
icon_state = "reflector_map"
desc = "A base for reflector assemblies."
anchored = FALSE
density = TRUE
density = FALSE
layer = BELOW_OBJ_LAYER
var/deflector_icon_state
var/image/deflector_overlay
var/finished = FALSE
var/admin = FALSE //Can't be rotated or deconstructed
var/can_rotate = TRUE
var/framebuildstacktype = /obj/item/stack/sheet/metal
var/framebuildstackamount = 5
var/buildstacktype = /obj/item/stack/sheet/metal
@@ -17,19 +20,42 @@
/obj/structure/reflector/Initialize()
. = ..()
icon_state = "reflector_base"
allowed_projectile_typecache = typecacheof(allowed_projectile_typecache)
if(deflector_icon_state)
deflector_overlay = image(icon, deflector_icon_state)
add_overlay(deflector_overlay)
if(rotation_angle == -1)
setAngle(dir2angle(dir))
else
setAngle(rotation_angle)
if(admin)
can_rotate = FALSE
/obj/structure/reflector/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click to adjust its direction.</span>")
if(finished)
to_chat(user, "It is set to [rotation_angle] degrees, and the rotation is [can_rotate ? "unlocked" : "locked"].")
if(!admin)
if(can_rotate)
to_chat(user, "<span class='notice'>Alt-click to adjust its direction.</span>")
else
to_chat(user, "<span class='notice'>Use screwdriver to unlock the rotation.</span>")
/obj/structure/reflector/Moved()
setAngle(dir_map_to_angle(dir))
return ..()
/obj/structure/reflector/proc/setAngle(new_angle)
if(can_rotate)
rotation_angle = new_angle
if(deflector_overlay)
cut_overlay(deflector_overlay)
deflector_overlay.transform = turn(matrix(), new_angle)
add_overlay(deflector_overlay)
/obj/structure/reflector/setDir(new_dir)
setAngle(dir_map_to_angle(new_dir))
return ..(NORTH)
/obj/structure/reflector/proc/dir_map_to_angle(dir)
return 0
@@ -51,22 +77,45 @@
/obj/structure/reflector/attackby(obj/item/W, mob/user, params)
if(admin)
return
if(istype(W, /obj/item/screwdriver))
can_rotate = !can_rotate
to_chat(user, "<span class='notice'>You [can_rotate ? "unlock" : "lock"] [src]'s rotation.</span>")
playsound(src, W.usesound, 50, 1)
return
if(istype(W, /obj/item/wrench))
if(anchored)
to_chat(user, "Unweld [src] first!")
to_chat(user, "<span class='warning'>Unweld [src] from the floor first!</span>")
return
user.visible_message("[user] starts to dismantle [src].", "<span class='notice'>You start to dismantle [src]...</span>")
if(do_after(user, 80*W.toolspeed, target = src))
playsound(src.loc, W.usesound, 50, 1)
to_chat(user, "You dismantle [src].")
new framebuildstacktype(loc, framebuildstackamount)
playsound(src, W.usesound, 50, 1)
to_chat(user, "<span class='notice'>You dismantle [src].</span>")
new framebuildstacktype(drop_location(), framebuildstackamount)
if(buildstackamount)
new buildstacktype(loc, buildstackamount)
new buildstacktype(drop_location(), buildstackamount)
qdel(src)
else if(istype(W, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = W
if(!anchored)
if(obj_integrity < max_integrity)
if(WT.remove_fuel(0,user))
user.visible_message("[user] starts to repair [src].",
"<span class='notice'>You begin repairing [src]...</span>",
"<span class='italics'>You hear welding.</span>")
playsound(src, W.usesound, 40, 1)
if(do_after(user,40*WT.toolspeed, target = src))
obj_integrity = max_integrity
user.visible_message("[user] has repaired [src].", \
"<span class='notice'>You finish repairing [src].</span>")
else if(!anchored)
if (WT.remove_fuel(0,user))
playsound(src, 'sound/items/welder2.ogg', 50, 1)
user.visible_message("[user] starts to weld [src] to the floor.", "<span class='notice'>You start to weld [src] to the floor...</span>", "<span class='italics'>You hear welding.</span>")
playsound(src, W.usesound, 50, 1)
user.visible_message("[user] starts to weld [src] to the floor.",
"<span class='notice'>You start to weld [src] to the floor...</span>",
"<span class='italics'>You hear welding.</span>")
if (do_after(user,20*W.toolspeed, target = src))
if(!WT.isOn())
return
@@ -74,7 +123,7 @@
to_chat(user, "<span class='notice'>You weld [src] to the floor.</span>")
else
if (WT.remove_fuel(0,user))
playsound(src, 'sound/items/welder2.ogg', 50, 1)
playsound(src, W.usesound, 50, 1)
user.visible_message("[user] starts to cut [src] free from the floor.", "<span class='notice'>You start to cut [src] free from the floor...</span>", "<span class='italics'>You hear welding.</span>")
if (do_after(user,20*W.toolspeed, target = src))
if(!WT.isOn())
@@ -86,50 +135,44 @@
if(finished)
return
var/obj/item/stack/sheet/S = W
if(istype(W, /obj/item/stack/sheet/glass))
if(istype(S, /obj/item/stack/sheet/glass))
if(S.use(5))
new /obj/structure/reflector/single (loc)
qdel (src)
new /obj/structure/reflector/single(drop_location())
qdel(src)
else
to_chat(user, "<span class='warning'>You need five sheets of glass to create a reflector!</span>")
return
if(istype(W, /obj/item/stack/sheet/rglass))
if(istype(S, /obj/item/stack/sheet/rglass))
if(S.use(10))
new /obj/structure/reflector/double (loc)
new /obj/structure/reflector/double(drop_location())
qdel(src)
else
to_chat(user, "<span class='warning'>You need ten sheets of reinforced glass to create a double reflector!</span>")
return
if(istype(W, /obj/item/stack/sheet/mineral/diamond))
if(istype(S, /obj/item/stack/sheet/mineral/diamond))
if(S.use(1))
new /obj/structure/reflector/box (loc)
new /obj/structure/reflector/box(drop_location())
qdel(src)
else
return ..()
/obj/structure/reflector/proc/rotate(mob/user)
if (anchored)
to_chat(user, "<span class='warning'>It is fastened to the floor!</span>")
if (!can_rotate || admin)
to_chat(user, "<span class='warning'>The rotation is locked!</span>")
return FALSE
var/new_angle = input(user, "Input a new angle for primary reflection face.", "Reflector Angle") as null|num
var/new_angle = input(user, "Input a new angle for primary reflection face.", "Reflector Angle", rotation_angle) as null|num
if(!user.canUseTopic(src, be_close=TRUE))
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
setAngle(NORM_ROT(new_angle))
if(!isnull(new_angle))
setAngle(NORM_ROT(new_angle))
return TRUE
/obj/structure/reflector/proc/setAngle(new_angle)
rotation_angle = new_angle
setDir(NORTH)
var/matrix/M = new
M.Turn(new_angle)
transform = M
/obj/structure/reflector/AltClick(mob/user)
if(!user.canUseTopic(src, be_close=TRUE))
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
else
else if(finished)
rotate(user)
@@ -139,9 +182,9 @@
/obj/structure/reflector/single
name = "reflector"
icon = 'icons/obj/structures.dmi'
icon_state = "reflector"
desc = "A double sided angled mirror for reflecting lasers. This one does so at a 90 degree angle."
deflector_icon_state = "reflector"
desc = "An angled mirror for reflecting laser beams."
density = TRUE
finished = TRUE
buildstacktype = /obj/item/stack/sheet/glass
buildstackamount = 5
@@ -170,9 +213,9 @@
/obj/structure/reflector/double
name = "double sided reflector"
icon = 'icons/obj/structures.dmi'
icon_state = "reflector_double"
desc = "A double sided angled mirror for reflecting lasers. This one does so at a 90 degree angle."
deflector_icon_state = "reflector_double"
desc = "A double sided angled mirror for reflecting laser beams."
density = TRUE
finished = TRUE
buildstacktype = /obj/item/stack/sheet/rglass
buildstackamount = 10
@@ -202,9 +245,9 @@
/obj/structure/reflector/box
name = "reflector box"
icon = 'icons/obj/structures.dmi'
icon_state = "reflector_box"
desc = "A box with an internal set of mirrors that reflects all laser fire in a single direction."
deflector_icon_state = "reflector_box"
desc = "A box with an internal set of mirrors that reflects all laser beams in a single direction."
density = TRUE
finished = TRUE
buildstacktype = /obj/item/stack/sheet/mineral/diamond
buildstackamount = 1
+1 -1
View File
@@ -498,7 +498,7 @@
flick("baton_active", src)
var/stunforce = B.stunforce
user.Knockdown(stunforce)
user.stuttering = stunforce
user.stuttering = stunforce/20
B.deductcharge(B.hitcost)
user.visible_message("<span class='warning'>[user] shocks themself while attempting to wash the active [B.name]!</span>", \
"<span class='userdanger'>You unwisely attempt to wash [B] while it's still on.</span>")
+1 -1
View File
@@ -102,7 +102,7 @@
UNTIL(SSticker.login_music) //wait for SSticker init to set the login music
if(prefs && (prefs.toggles & SOUND_LOBBY))
SEND_SOUND(src, sound(SSticker.login_music, repeat = 0, wait = 0, volume = vol, channel = CHANNEL_LOBBYMUSIC) // MAD JAMS)
SEND_SOUND(src, sound(SSticker.login_music, repeat = 0, wait = 0, volume = vol, channel = CHANNEL_LOBBYMUSIC)) // MAD JAMS
/proc/get_rand_frequency()
return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs.
+1 -1
View File
@@ -36,7 +36,7 @@
/turf/closed/indestructible/splashscreen
name = "Space Station 13"
icon = 'config/title_screens/images/title1.dmi'
icon = 'icons/blank_title.png'
icon_state = ""
layer = FLY_LAYER
@@ -57,8 +57,6 @@
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
return
return ..()
/turf/open/floor/plating/asteroid/singularity_act()
if(turf_z_is_planet(src))
@@ -222,13 +222,13 @@
icon = 'icons/turf/walls/survival_pod_walls.dmi'
icon_state = "smooth"
smooth = SMOOTH_MORE|SMOOTH_DIAGONAL
canSmoothWith = list(/turf/closed/wall/mineral/titanium/survival, /obj/machinery/door/airlock/survival_pod, /obj/structure/window/shuttle/survival_pod, /obj/structure/shuttle/engine)
canSmoothWith = list(/turf/closed/wall/mineral/titanium/survival, /obj/machinery/door/airlock, /obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile, /obj/structure/window/reinforced/tinted/fulltile, /obj/structure/window/shuttle, /obj/structure/shuttle/engine)
/turf/closed/wall/mineral/titanium/survival/nodiagonal
smooth = SMOOTH_MORE
/turf/closed/wall/mineral/titanium/survival/pod
canSmoothWith = list(/turf/closed/wall/mineral/titanium/survival, /obj/machinery/door/airlock, /obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile, /obj/structure/window/reinforced/tinted/fulltile, /obj/structure/window/shuttle, /obj/structure/shuttle/engine)
canSmoothWith = list(/turf/closed/wall/mineral/titanium/survival, /obj/machinery/door/airlock/survival_pod, /obj/structure/window/shuttle/survival_pod)
/////////////////////Plastitanium walls/////////////////////
@@ -256,11 +256,10 @@
dismantle_wall()
/turf/closed/wall/r_wall/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
if(!the_rcd.canRturf)
return FALSE
return ..()
if(the_rcd.canRturf)
return ..()
/turf/closed/wall/r_wall/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode)
if(!the_rcd.canRturf)
return FALSE
return ..()
if(the_rcd.canRturf)
return ..()
+33 -11
View File
@@ -25,7 +25,18 @@
/turf/closed/wall/clockwork)
smooth = SMOOTH_TRUE
var/list/damage_decals
var/list/dent_decals
var/static/list/dent_decal_list = list(
WALL_DENT_HIT = list(
mutable_appearance('icons/effects/effects.dmi', "impact1", BULLET_HOLE_LAYER),
mutable_appearance('icons/effects/effects.dmi', "impact2", BULLET_HOLE_LAYER),
mutable_appearance('icons/effects/effects.dmi', "impact3", BULLET_HOLE_LAYER)
),
WALL_DENT_SHOT = list(
mutable_appearance('icons/effects/effects.dmi', "bullet_hole", BULLET_HOLE_LAYER)
)
)
/turf/closed/wall/examine(mob/user)
..()
@@ -101,6 +112,8 @@
/turf/closed/wall/blob_act(obj/structure/blob/B)
if(prob(50))
dismantle_wall()
else
add_dent(WALL_DENT_HIT)
/turf/closed/wall/mech_melee_attack(obj/mecha/M)
M.do_attack_animation(src)
@@ -111,6 +124,8 @@
if(prob(hardness + M.force) && M.force > 20)
dismantle_wall(1)
playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1)
else
add_dent(WALL_DENT_HIT)
if(BURN)
playsound(src, 'sound/items/welder.ogg', 100, 1)
if(TOX)
@@ -138,6 +153,7 @@
dismantle_wall(1)
else
playsound(src, 'sound/effects/bang.ogg', 50, 1)
add_dent(WALL_DENT_HIT)
to_chat(user, text("<span class='notice'>You punch the wall.</span>"))
return TRUE
@@ -167,18 +183,20 @@
if(try_clean(W, user, T) || try_wallmount(W, user, T) || try_decon(W, user, T) || try_destroy(W, user, T))
return
return ..()
/turf/closed/wall/proc/try_clean(obj/item/W, mob/user, turf/T)
if((user.a_intent != INTENT_HELP) || !LAZYLEN(damage_decals) || !istype(W, /obj/item/weldingtool))
if((user.a_intent != INTENT_HELP) || !LAZYLEN(dent_decals) || !istype(W, /obj/item/weldingtool))
return FALSE
var/obj/item/weldingtool/WT = W
if(WT.remove_fuel(0, user))
to_chat(user, "<span class='notice'>You begin fixing dents on the wall...</span>")
playsound(src, W.usesound, 100, 1)
if(do_after(user, slicing_duration * W.toolspeed * 0.5, target = src))
if(iswallturf(src) && user && !QDELETED(WT) && WT.isOn() && !QDELETED(T) && (user.loc == T) && (user.get_active_held_item() == WT) && damage_decals.len)
if(do_after(user, slicing_duration * W.toolspeed * 0.1, target = src))
if(iswallturf(src) && user && !QDELETED(WT) && WT.isOn() && !QDELETED(T) && (user.loc == T) && (user.get_active_held_item() == WT) && LAZYLEN(dent_decals))
to_chat(user, "<span class='notice'>You fix some dents on the wall.</span>")
cut_overlay(damage_decals)
LAZYCLEARLIST(damage_decals)
cut_overlay(dent_decals)
LAZYCLEARLIST(dent_decals)
return TRUE
return FALSE
@@ -253,7 +271,7 @@
if(.)
ChangeTurf(/turf/closed/wall/clockwork)
/turf/closed/wall/get_dumping_location(obj/item/storage/source,mob/user)
/turf/closed/wall/get_dumping_location(obj/item/storage/source, mob/user)
return null
/turf/closed/wall/acid_act(acidpwr, acid_volume)
@@ -278,7 +296,11 @@
return TRUE
return FALSE
/turf/closed/wall/proc/add_damage_decal(var/mutable_appearance/decal)
cut_overlay(damage_decals)
LAZYADD(damage_decals, decal)
add_overlay(damage_decals)
/turf/closed/wall/proc/add_dent(denttype, x=rand(-8, 8), y=rand(-8, 8))
var/mutable_appearance/decal = pick(dent_decal_list[denttype])
decal.pixel_x = x
decal.pixel_y = y
cut_overlay(dent_decals)
LAZYADD(dent_decals, decal)
add_overlay(dent_decals)
+2 -2
View File
@@ -440,13 +440,13 @@
/turf/proc/empty(turf_type=/turf/open/space, baseturf_type, list/ignore_typecache, forceop = FALSE)
// Remove all atoms except observers, landmarks, docking ports
var/static/list/ignored_atoms = typecacheof(list(/mob/dead, /obj/effect/landmark, /obj/docking_port, /atom/movable/lighting_object))
var/list/allowed_contents = typecache_filter_list_reverse(GetAllContents(), ignored_atoms | ignore_typecache)
var/list/allowed_contents = typecache_filter_list_reverse(GetAllContentsIgnoring(ignore_typecache), ignored_atoms)
allowed_contents -= src
for(var/i in 1 to allowed_contents.len)
var/thing = allowed_contents[i]
qdel(thing, force=TRUE)
var/turf/newT = ChangeTurf(turf_type, baseturf_type, FALSE, FALSE, forceop = forceop)
var/turf/newT = ChangeTurf(turf_type, baseturf_type, FALSE, FALSE, forceop)
SSair.remove_from_active(newT)
newT.CalculateAdjacentTurfs()