"
/datum/supply_packs/specialops
diff --git a/code/defines/obj.dm b/code/defines/obj.dm
index 65f34ed580..79a84c23be 100644
--- a/code/defines/obj.dm
+++ b/code/defines/obj.dm
@@ -166,7 +166,7 @@
return dat
-/var/list/acting_rank_prefixes = list("acting", "temporary", "interim")
+/var/list/acting_rank_prefixes = list("acting", "temporary", "interim", "provisional")
/proc/make_list_rank(rank)
for(var/prefix in acting_rank_prefixes)
diff --git a/code/game/antagonist/_antagonist_setup.dm b/code/game/antagonist/_antagonist_setup.dm
index ebf22a21c9..fa99f001f3 100644
--- a/code/game/antagonist/_antagonist_setup.dm
+++ b/code/game/antagonist/_antagonist_setup.dm
@@ -69,4 +69,15 @@ var/global/list/antag_names_to_ids = list()
var/datum/antagonist/antag = all_antag_types[atype]
if(antag && islist(antag.current_antagonists))
return antag.current_antagonists
- return list()
\ No newline at end of file
+ return list()
+
+/proc/player_is_antag(var/datum/mind/player, var/only_offstation_roles = 0)
+ for(var/antag_type in all_antag_types)
+ var/datum/antagonist/antag = all_antag_types[antag_type]
+ if(only_offstation_roles && !(antag.flags & ANTAG_OVERRIDE_JOB))
+ continue
+ if(player in antag.current_antagonists)
+ return 1
+ if(player in antag.pending_antagonists)
+ return 1
+ return 0
diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm
index 11431682a1..059a883aad 100644
--- a/code/game/antagonist/antagonist.dm
+++ b/code/game/antagonist/antagonist.dm
@@ -60,7 +60,8 @@
/datum/antagonist/proc/get_candidates(var/ghosts_only)
candidates = list() // Clear.
candidates = ticker.mode.get_players_for_role(role_type, id)
- // Prune restricted jobs and status. Broke it up for readability.
+ // Prune restricted status. Broke it up for readability.
+ // Note that this is done before jobs are handed out.
for(var/datum/mind/player in candidates)
if(ghosts_only && !istype(player.current, /mob/dead))
candidates -= player
@@ -70,10 +71,14 @@
candidates -= player
else if(!can_become_antag(player))
candidates -= player
+ else if(player_is_antag(player))
+ candidates -= player
return candidates
/datum/antagonist/proc/attempt_random_spawn()
- attempt_spawn(flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB))
+ build_candidate_list(flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB))
+ attempt_spawn()
+ finalize_spawn()
/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player)
if(!can_late_spawn())
@@ -86,27 +91,59 @@
add_antagonist(player,0,1,0,1,1)
return
-/datum/antagonist/proc/attempt_spawn(var/ghosts_only)
-
+/datum/antagonist/proc/build_candidate_list(var/ghosts_only)
// Get the raw list of potential players.
update_current_antag_max()
candidates = get_candidates(ghosts_only)
+//Selects players that will be spawned in the antagonist role from the potential candidates
+//Selected players are added to the pending_antagonists lists.
+//Attempting to spawn an antag role with ANTAG_OVERRIDE_JOB should be done before jobs are assigned,
+//so that they do not occupy regular job slots. All other antag roles should be spawned after jobs are
+//assigned, so that job restrictions can be respected.
+/datum/antagonist/proc/attempt_spawn(var/rebuild_candidates = 1)
+
// Update our boundaries.
if(!candidates.len)
return 0
//Grab candidates randomly until we have enough.
- while(candidates.len)
+ while(candidates.len && pending_antagonists.len < cur_max)
var/datum/mind/player = pick(candidates)
- pending_antagonists |= player
candidates -= player
+ draft_antagonist(player)
+
return 1
+/datum/antagonist/proc/draft_antagonist(var/datum/mind/player)
+ //Check if the player can join in this antag role, or if the player has already been given an antag role.
+ if(!can_become_antag(player) || player.special_role)
+ return 0
+
+ pending_antagonists |= player
+
+ //Ensure that antags with ANTAG_OVERRIDE_JOB do not occupy job slots.
+ if(flags & ANTAG_OVERRIDE_JOB)
+ player.assigned_role = role_text
+
+ //Ensure that a player cannot be drafted for multiple antag roles, taking up slots for antag roles that they will not fill.
+ player.special_role = role_text
+
+ return 1
+
+//Spawns all pending_antagonists. This is done separately from attempt_spawn in case the game mode setup fails.
/datum/antagonist/proc/finalize_spawn()
- if(!pending_antagonists || !pending_antagonists.len)
+ if(!pending_antagonists)
return
+
for(var/datum/mind/player in pending_antagonists)
- if(can_become_antag(player) && !player.special_role)
- add_antagonist(player,0,0,1)
- pending_antagonists.Cut()
\ No newline at end of file
+ pending_antagonists -= player
+ add_antagonist(player,0,0,1)
+
+//Resets all pending_antagonists, clearing their special_role (and assigned_role if ANTAG_OVERRIDE_JOB is set)
+/datum/antagonist/proc/reset()
+ for(var/datum/mind/player in pending_antagonists)
+ if(flags & ANTAG_OVERRIDE_JOB)
+ player.assigned_role = null
+ player.special_role = null
+ pending_antagonists.Cut()
diff --git a/code/game/antagonist/antagonist_add.dm b/code/game/antagonist/antagonist_add.dm
index e3c653a4e5..7815167d6f 100644
--- a/code/game/antagonist/antagonist_add.dm
+++ b/code/game/antagonist/antagonist_add.dm
@@ -9,8 +9,11 @@
return 0
current_antagonists |= player
+
+ //do this again, just in case
if(flags & ANTAG_OVERRIDE_JOB)
- player.assigned_role = "MODE"
+ player.assigned_role = role_text
+ player.special_role = role_text
if(istype(player.current, /mob/dead))
create_default(player.current)
diff --git a/code/game/antagonist/antagonist_create.dm b/code/game/antagonist/antagonist_create.dm
index da0e5b33a1..db0d1b4204 100644
--- a/code/game/antagonist/antagonist_create.dm
+++ b/code/game/antagonist/antagonist_create.dm
@@ -30,7 +30,7 @@
add_antagonist(M.mind, 1, 0, 1) // Equip them and move them to spawn.
return M
-/datum/antagonist/proc/create_id(var/assignment, var/mob/living/carbon/human/player)
+/datum/antagonist/proc/create_id(var/assignment, var/mob/living/carbon/human/player, var/equip = 1)
var/obj/item/weapon/card/id/W = new id_type(player)
if(!W) return
@@ -38,11 +38,17 @@
W.access |= default_access
W.assignment = "[assignment]"
W.registered_name = player.real_name
- player.equip_to_slot_or_del(W, slot_wear_id)
+ if(equip) player.equip_to_slot_or_del(W, slot_wear_id)
return W
/datum/antagonist/proc/create_radio(var/freq, var/mob/living/carbon/human/player)
- var/obj/item/device/radio/R = new /obj/item/device/radio/headset(player)
+ var/obj/item/device/radio/R
+
+ if(freq == SYND_FREQ)
+ R = new/obj/item/device/radio/headset/syndicate(player)
+ else
+ R = new/obj/item/device/radio/headset(player)
+
R.set_frequency(freq)
player.equip_to_slot_or_del(R, slot_l_ear)
return R
@@ -113,6 +119,7 @@
if (newname)
player.real_name = newname
player.name = player.real_name
+ player.dna.real_name = newname
if(player.mind) player.mind.name = player.name
// Update any ID cards.
update_access(player)
diff --git a/code/game/antagonist/antagonist_print.dm b/code/game/antagonist/antagonist_print.dm
index eaca01986c..76110e2b13 100644
--- a/code/game/antagonist/antagonist_print.dm
+++ b/code/game/antagonist/antagonist_print.dm
@@ -47,7 +47,7 @@
return text
/datum/antagonist/proc/print_player_lite(var/datum/mind/ply)
- var/role = ply.assigned_role == "MODE" ? "\improper[ply.special_role]" : "\improper[ply.assigned_role]"
+ var/role = ply.special_role ? "\improper[ply.special_role]" : "\improper[ply.assigned_role]"
var/text = " [ply.name] ([ply.key]) as \a [role] ("
if(ply.current)
if(ply.current.stat == DEAD)
diff --git a/code/game/antagonist/outsider/ninja.dm b/code/game/antagonist/outsider/ninja.dm
index 5af82ff05d..a29cfc44fa 100644
--- a/code/game/antagonist/outsider/ninja.dm
+++ b/code/game/antagonist/outsider/ninja.dm
@@ -11,6 +11,7 @@ var/datum/antagonist/ninja/ninjas
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
max_antags = 1
max_antags_round = 1
+ id_type = /obj/item/weapon/card/id/syndicate
/datum/antagonist/ninja/New()
..()
@@ -101,18 +102,15 @@ var/datum/antagonist/ninja/ninjas
player.equip_to_slot_or_del(R, slot_l_ear)
player.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(player), slot_w_uniform)
player.equip_to_slot_or_del(new /obj/item/device/flashlight(player), slot_belt)
- var/obj/item/weapon/rig/light/ninja/ninjasuit = new(player)
+ create_id("Infiltrator", player)
+
+ var/obj/item/weapon/rig/light/ninja/ninjasuit = new(get_turf(player))
+ ninjasuit.seal_delay = 0
+ player.put_in_hands(ninjasuit)
player.equip_to_slot_or_del(ninjasuit,slot_back)
-
if(ninjasuit)
- // Make sure the ninja can actually equip the suit.
- if(player.dna && player.dna.unique_enzymes)
- ninjasuit.locked_dna = player.dna.unique_enzymes
- player << "Suit hardware locked to your DNA hash."
- else
- ninjasuit.req_access = list()
-
ninjasuit.toggle_seals(src,1)
+ ninjasuit.seal_delay = initial(ninjasuit.seal_delay)
if(istype(player.back,/obj/item/weapon/rig))
var/obj/item/weapon/rig/rig = player.back
diff --git a/code/game/antagonist/outsider/raider.dm b/code/game/antagonist/outsider/raider.dm
index 4d25b1c3fe..c10fe6182a 100644
--- a/code/game/antagonist/outsider/raider.dm
+++ b/code/game/antagonist/outsider/raider.dm
@@ -19,12 +19,15 @@ var/datum/antagonist/raider/raiders
/obj/item/clothing/under/pirate,
/obj/item/clothing/under/redcoat,
/obj/item/clothing/under/serviceoveralls,
- /obj/item/clothing/under/captain_fly
+ /obj/item/clothing/under/captain_fly,
+ /obj/item/clothing/under/det,
+ /obj/item/clothing/under/brown,
)
var/list/raider_shoes = list(
/obj/item/clothing/shoes/jackboots,
- /obj/item/clothing/shoes/sandal,
+ /obj/item/clothing/shoes/workboots,
+ /obj/item/clothing/shoes/brown,
/obj/item/clothing/shoes/laceup
)
@@ -40,7 +43,6 @@ var/datum/antagonist/raider/raiders
/obj/item/clothing/head/pirate,
/obj/item/clothing/head/bandana,
/obj/item/clothing/head/hgpiratecap,
- /obj/item/clothing/head/flatcap
)
var/list/raider_suits = list(
@@ -50,7 +52,9 @@ var/datum/antagonist/raider/raiders
/obj/item/clothing/suit/storage/leather_jacket,
/obj/item/clothing/suit/storage/toggle/brown_jacket,
/obj/item/clothing/suit/storage/toggle/hoodie,
- /obj/item/clothing/suit/storage/toggle/hoodie/black
+ /obj/item/clothing/suit/storage/toggle/hoodie/black,
+ /obj/item/clothing/suit/unathi/mantle,
+ /obj/item/clothing/suit/poncho,
)
var/list/raider_guns = list(
@@ -60,14 +64,33 @@ var/datum/antagonist/raider/raiders
/obj/item/weapon/gun/energy/mindflayer,
/obj/item/weapon/gun/energy/toxgun,
/obj/item/weapon/gun/energy/stunrevolver,
+ /obj/item/weapon/gun/energy/ionrifle,
+ /obj/item/weapon/gun/energy/taser,
/obj/item/weapon/gun/energy/crossbow/largecrossbow,
+ /obj/item/weapon/gun/launcher/crossbow,
+ /obj/item/weapon/gun/launcher/grenade,
+ /obj/item/weapon/gun/launcher/pneumatic,
/obj/item/weapon/gun/projectile/automatic/mini_uzi,
/obj/item/weapon/gun/projectile/automatic/c20r,
+ /obj/item/weapon/gun/projectile/automatic/wt550,
+ /obj/item/weapon/gun/projectile/automatic/sts35,
/obj/item/weapon/gun/projectile/silenced,
/obj/item/weapon/gun/projectile/shotgun/pump,
/obj/item/weapon/gun/projectile/shotgun/pump/combat,
+ /obj/item/weapon/gun/projectile/shotgun/doublebarrel,
+ /obj/item/weapon/gun/projectile/shotgun/doublebarrel/pellet,
+ /obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn,
/obj/item/weapon/gun/projectile/colt,
- /obj/item/weapon/gun/projectile/pistol
+ /obj/item/weapon/gun/projectile/sec,
+ /obj/item/weapon/gun/projectile/pistol,
+ /obj/item/weapon/gun/projectile/revolver,
+ /obj/item/weapon/gun/projectile/pirate
+ )
+
+ var/list/raider_holster = list(
+ /obj/item/clothing/accessory/holster/armpit,
+ /obj/item/clothing/accessory/holster/waist,
+ /obj/item/clothing/accessory/holster/hip
)
/datum/antagonist/raider/New()
@@ -178,16 +201,20 @@ var/datum/antagonist/raider/raiders
var/new_glasses = pick(raider_glasses)
var/new_helmet = pick(raider_helmets)
var/new_suit = pick(raider_suits)
- var/new_gun = pick(raider_guns)
player.equip_to_slot_or_del(new new_shoes(player),slot_shoes)
+ if(!player.shoes)
+ //If equipping shoes failed, fall back to equipping sandals
+ var/fallback_type = pick(/obj/item/clothing/shoes/sandal, /obj/item/clothing/shoes/jackboots/unathi)
+ player.equip_to_slot_or_del(new fallback_type(player), slot_shoes)
+
player.equip_to_slot_or_del(new new_uniform(player),slot_w_uniform)
player.equip_to_slot_or_del(new new_glasses(player),slot_glasses)
player.equip_to_slot_or_del(new new_helmet(player),slot_head)
player.equip_to_slot_or_del(new new_suit(player),slot_wear_suit)
- player.equip_to_slot_or_del(new new_gun(player),slot_belt)
+ equip_weapons(player)
- var/obj/item/weapon/card/id/id = create_id("Visitor", player)
+ var/obj/item/weapon/card/id/id = create_id("Visitor", player, equip = 0)
id.name = "[player.real_name]'s Passport"
id.assignment = "Visitor"
var/obj/item/weapon/storage/wallet/W = new(player)
@@ -198,6 +225,70 @@ var/datum/antagonist/raider/raiders
return 1
+/datum/antagonist/raider/proc/equip_weapons(var/mob/living/carbon/human/player)
+ var/new_gun = pick(raider_guns)
+ var/new_holster = pick(raider_holster) //raiders don't start with any backpacks, so let's be nice and give them a holster if they can use it.
+ var/turf/T = get_turf(player)
+
+ var/obj/item/primary = new new_gun(T)
+ var/obj/item/clothing/accessory/holster/holster = null
+
+ //Give some of the raiders a pirate gun as a secondary
+ if(prob(60))
+ var/obj/item/secondary = new /obj/item/weapon/gun/projectile/pirate(T)
+ if(!(primary.slot_flags & SLOT_HOLSTER))
+ holster = new new_holster(T)
+ holster.holstered = secondary
+ secondary.loc = holster
+ else
+ player.equip_to_slot_or_del(secondary, slot_belt)
+
+ if(primary.slot_flags & SLOT_HOLSTER)
+ holster = new new_holster(T)
+ holster.holstered = primary
+ primary.loc = holster
+ else if(!player.belt && (primary.slot_flags & SLOT_BELT))
+ player.equip_to_slot_or_del(primary, slot_belt)
+ else if(!player.back && (primary.slot_flags & SLOT_BACK))
+ player.equip_to_slot_or_del(primary, slot_back)
+ else
+ player.put_in_any_hand_if_possible(primary)
+
+ //If they got a projectile gun, give them a little bit of spare ammo
+ equip_ammo(player, primary)
+
+ if(holster)
+ var/obj/item/clothing/under/uniform = player.w_uniform
+ if(istype(uniform) && uniform.can_attach_accessory(holster))
+ uniform.attackby(holster, player)
+ else
+ player.put_in_any_hand_if_possible(holster)
+
+/datum/antagonist/raider/proc/equip_ammo(var/mob/living/carbon/human/player, var/obj/item/weapon/gun/gun)
+ if(istype(gun, /obj/item/weapon/gun/projectile))
+ var/obj/item/weapon/gun/projectile/bullet_thrower = gun
+ if(bullet_thrower.magazine_type)
+ player.equip_to_slot_or_del(new bullet_thrower.magazine_type(player), slot_l_store)
+ if(prob(20)) //don't want to give them too much
+ player.equip_to_slot_or_del(new bullet_thrower.magazine_type(player), slot_r_store)
+ else if(bullet_thrower.ammo_type)
+ var/obj/item/weapon/storage/box/ammobox = new(get_turf(player.loc))
+ for(var/i in 1 to rand(3,5) + rand(0,2))
+ new bullet_thrower.ammo_type(ammobox)
+ player.put_in_any_hand_if_possible(ammobox)
+ return
+ if(istype(gun, /obj/item/weapon/gun/launcher/grenade))
+ var/list/grenades = list(
+ /obj/item/weapon/grenade/empgrenade,
+ /obj/item/weapon/grenade/smokebomb,
+ /obj/item/weapon/grenade/flashbang
+ )
+ var/obj/item/weapon/storage/box/ammobox = new(get_turf(player.loc))
+ for(var/i in 1 to 7)
+ var/grenade_type = pick(grenades)
+ new grenade_type(ammobox)
+ player.put_in_any_hand_if_possible(ammobox)
+
/datum/antagonist/raider/proc/equip_vox(var/mob/living/carbon/human/player)
var/uniform_type = pick(list(/obj/item/clothing/under/vox/vox_robes,/obj/item/clothing/under/vox/vox_casual))
diff --git a/code/game/antagonist/outsider/wizard.dm b/code/game/antagonist/outsider/wizard.dm
index 74866d9247..57a00adfdd 100644
--- a/code/game/antagonist/outsider/wizard.dm
+++ b/code/game/antagonist/outsider/wizard.dm
@@ -96,7 +96,7 @@ var/datum/antagonist/wizard/wizards
world << "The [(current_antagonists.len>1)?"[role_text_plural] have":"[role_text] has"] been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!"
//To batch-remove wizard spells. Linked to mind.dm.
-/mob/proc/spellremove(var/mob/M as mob)
+/mob/proc/spellremove()
for(var/spell/spell_to_remove in src.spell_list)
remove_spell(spell_to_remove)
diff --git a/code/game/antagonist/station/rogue_ai.dm b/code/game/antagonist/station/rogue_ai.dm
index cf0e9dfd4c..f19edb2807 100644
--- a/code/game/antagonist/station/rogue_ai.dm
+++ b/code/game/antagonist/station/rogue_ai.dm
@@ -6,12 +6,13 @@ var/datum/antagonist/rogue_ai/malf
role_text = "Rampant AI"
role_text_plural = "Rampant AIs"
mob_path = /mob/living/silicon/ai
+ landmark_id = "AI"
welcome_text = "You are malfunctioning! You do not have to follow any laws."
victory_text = "The AI has taken control of all of the station's systems."
loss_text = "The AI has been shut down!"
- flags = ANTAG_VOTABLE | ANTAG_RANDSPAWN //Randspawn needed otherwise it won't start at all.
+ flags = ANTAG_VOTABLE | ANTAG_OVERRIDE_MOB | ANTAG_OVERRIDE_JOB | ANTAG_CHOOSE_NAME
max_antags = 1
- max_antags_round = 3
+ max_antags_round = 1
/datum/antagonist/rogue_ai/New()
@@ -22,7 +23,7 @@ var/datum/antagonist/rogue_ai/malf
/datum/antagonist/rogue_ai/get_candidates()
..()
for(var/datum/mind/player in candidates)
- if(player.assigned_role != "AI")
+ if(player.assigned_role && player.assigned_role != "AI")
candidates -= player
if(!candidates.len)
return list()
@@ -75,3 +76,26 @@ var/datum/antagonist/rogue_ai/malf
malf << "For basic information about your abilities use command display-help"
malf << "You may choose one special hardware piece to help you. This cannot be undone."
malf << "Good luck!"
+
+
+/datum/antagonist/rogue_ai/update_antag_mob(var/datum/mind/player, var/preserve_appearance)
+
+ // Get the mob.
+ if((flags & ANTAG_OVERRIDE_MOB) && (!player.current || (mob_path && !istype(player.current, mob_path))))
+ var/mob/holder = player.current
+ player.current = new mob_path(get_turf(player.current), null, null, 1)
+ player.transfer_to(player.current)
+ if(holder) qdel(holder)
+ player.original = player.current
+ return player.current
+
+/datum/antagonist/rogue_ai/set_antag_name(var/mob/living/silicon/player)
+ if(!istype(player))
+ testing("rogue_ai set_antag_name called on non-silicon mob [player]!")
+ return
+ // Choose a name, if any.
+ var/newname = sanitize(input(player, "You are a [role_text]. Would you like to change your name to something else?", "Name change") as null|text, MAX_NAME_LEN)
+ if (newname)
+ player.SetName(newname)
+ if(player.mind) player.mind.name = player.name
+
diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm
index 8b039a580a..d872493443 100755
--- a/code/game/area/Space Station 13 areas.dm
+++ b/code/game/area/Space Station 13 areas.dm
@@ -26,7 +26,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon = 'icons/turf/areas.dmi'
icon_state = "unknown"
layer = 10
- luminosity = 1
+ luminosity = 0
mouse_opacity = 0
var/lightswitch = 1
@@ -34,7 +34,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
var/debug = 0
var/requires_power = 1
- var/unlimited_power = 0
var/always_unpowered = 0 //this gets overriden to 1 for space in area/New()
var/power_equip = 1
@@ -349,7 +348,6 @@ area/space/atmosalert()
name = "\improper Centcom"
icon_state = "centcom"
requires_power = 0
- unlimited_power = 1
lighting_use_dynamic = 0
/area/centcom/control
@@ -388,7 +386,6 @@ area/space/atmosalert()
name = "\improper Mercenary Base"
icon_state = "syndie-ship"
requires_power = 0
- unlimited_power = 1
lighting_use_dynamic = 0
/area/syndicate_mothership/control
@@ -463,7 +460,6 @@ area/space/atmosalert()
name = "\improper Independant Station"
icon_state = "yellow"
requires_power = 0
- unlimited_power = 1
flags = RAD_SHIELDED
/area/syndicate_station/start
@@ -518,6 +514,7 @@ area/space/atmosalert()
name = "\improper Wizard's Den"
icon_state = "yellow"
requires_power = 0
+ lighting_use_dynamic = 0
/area/skipjack_station/transit
@@ -904,7 +901,7 @@ area/space/atmosalert()
icon_state = "tcomsatcham"
/area/server
- name = "\improper Messaging Server Room"
+ name = "\improper Research Server Room"
icon_state = "server"
//Crew
@@ -1812,7 +1809,7 @@ area/space/atmosalert()
ambience = list('sound/ambience/ambimalf.ogg')
/area/turret_protected/ai_server_room
- name = "AI Server Room"
+ name = "Messaging Server Room"
icon_state = "ai_server"
/area/turret_protected/ai
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index e342ba3329..3b970c7438 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -14,13 +14,17 @@
all_areas += src
if(!requires_power)
- power_light = 0 //rastaf0
- power_equip = 0 //rastaf0
- power_environ = 0 //rastaf0
+ power_light = 0
+ power_equip = 0
+ power_environ = 0
..()
-// spawn(15)
+/area/proc/initialize()
+ if(!requires_power || !apc)
+ power_light = 0
+ power_equip = 0
+ power_environ = 0
power_change() // all machines set to current power level, also updates lighting icon
/area/proc/get_contents()
@@ -227,7 +231,7 @@ var/list/mob/living/forced_ambiance_list = new
var/area/oldarea = L.lastarea
if((oldarea.has_gravity == 0) && (newarea.has_gravity == 1) && (L.m_intent == "run")) // Being ready when you change areas gives you a chance to avoid falling all together.
thunk(L)
- L.make_floating(0)
+ L.update_floating( L.Check_Dense_Object() )
L.lastarea = newarea
play_ambience(L)
@@ -260,21 +264,10 @@ var/list/mob/living/forced_ambiance_list = new
/area/proc/gravitychange(var/gravitystate = 0, var/area/A)
A.has_gravity = gravitystate
- if(gravitystate)
- for(var/mob/living/carbon/human/M in A)
+ for(var/mob/M in A)
+ if(has_gravity)
thunk(M)
- for(var/mob/M1 in A)
- M1.make_floating(0)
- else
- for(var/mob/M in A)
- if(M.Check_Dense_Object() && istype(src,/mob/living/carbon/human/))
- var/mob/living/carbon/human/H = src
- if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP)) //magboots + dense_object = no floaty effect
- H.make_floating(0)
- else
- H.make_floating(1)
- else
- M.make_floating(1)
+ M.update_floating( M.Check_Dense_Object() )
/area/proc/thunk(mob)
if(istype(get_turf(mob), /turf/space)) // Can't fall onto nothing.
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 8c5ac46da2..28ead38d6f 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -63,9 +63,6 @@
return flags & INSERT_CONTAINER
*/
-/atom/proc/allow_drop()
- return 1
-
/atom/proc/CheckExit()
return 1
@@ -487,4 +484,4 @@ its easier to just keep the beam vertical.
O.show_message( message, 2, deaf_message, 1)
else if(ismob(I))
var/mob/M = I
- M.show_message( message, 2, deaf_message, 1)
+ M.show_message( message, 2, deaf_message, 1)
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 5bc8cc9941..1bb29eb4c8 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -164,7 +164,7 @@
a = get_area(src.loc)
else
var/error = dist_y/2 - dist_x
- while(src && target &&((((src.y < target.y && dy == NORTH) || (src.y > target.y && dy == SOUTH)) && dist_travelled < range) || (a.has_gravity == 0) || istype(src.loc, /turf/space)) && src.throwing && istype(src.loc, /turf))
+ while(src && target &&((((src.y < target.y && dy == NORTH) || (src.y > target.y && dy == SOUTH)) && dist_travelled < range) || (a && a.has_gravity == 0) || istype(src.loc, /turf/space)) && src.throwing && istype(src.loc, /turf))
// only stop when we've gone the whole distance (or max throw range) and are on a non-space tile, or hit something, or hit the end of the map, or someone picks it up
if(error < 0)
var/atom/step = get_step(src, dx)
diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm
index 120ee88046..9bb8039a0c 100644
--- a/code/game/dna/dna_modifier.dm
+++ b/code/game/dna/dna_modifier.dm
@@ -64,9 +64,6 @@
component_parts += new /obj/item/stack/cable_coil(src)
RefreshParts()
-/obj/machinery/dna_scannernew/allow_drop()
- return 0
-
/obj/machinery/dna_scannernew/relaymove(mob/user as mob)
if (user.stat)
return
diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm
index eb15d45f51..34a81b4d61 100644
--- a/code/game/gamemodes/changeling/changeling_powers.dm
+++ b/code/game/gamemodes/changeling/changeling_powers.dm
@@ -193,7 +193,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
src << "This creature's DNA is ruined beyond useability!"
return
- if(!G.state == GRAB_KILL)
+ if(G.state != GRAB_KILL)
src << "We must have a tighter grip to absorb this creature."
return
diff --git a/code/game/gamemodes/changeling/modularchangling.dm b/code/game/gamemodes/changeling/modularchangling.dm
index 5048977789..45a7dc3896 100644
--- a/code/game/gamemodes/changeling/modularchangling.dm
+++ b/code/game/gamemodes/changeling/modularchangling.dm
@@ -121,7 +121,7 @@ var/list/datum/power/changeling/powerinstances = list()
/datum/power/changeling/DeathSting
name = "Death Sting"
- desc = "We silently sting a human, filling him with potent chemicals. His rapid death is all but assured."
+ desc = "We silently sting a human, filling them with potent chemicals. Their rapid death is all but assured."
genomecost = 10
verbpath = /mob/proc/changeling_DEATHsting
diff --git a/code/game/gamemodes/cult/cultify/obj.dm b/code/game/gamemodes/cult/cultify/obj.dm
index 4306182eaf..517c6079fd 100644
--- a/code/game/gamemodes/cult/cultify/obj.dm
+++ b/code/game/gamemodes/cult/cultify/obj.dm
@@ -63,19 +63,10 @@
..()
/obj/machinery/door/cultify()
- icon_state = "null"
- density = 0
- c_animation = new /atom/movable/overlay(src.loc)
- c_animation.name = "cultification"
- c_animation.density = 0
- c_animation.anchored = 1
- c_animation.icon = 'icons/effects/effects.dmi'
- c_animation.layer = 5
- c_animation.master = src.loc
- c_animation.icon_state = "breakdoor"
- flick("cultification",c_animation)
- spawn(10)
- qdel(c_animation)
+ if(invisibility != INVISIBILITY_MAXIMUM)
+ invisibility = INVISIBILITY_MAXIMUM
+ density = 0
+ anim(target = src, a_icon = 'icons/effects/effects.dmi', a_icon_state = "breakdoor", sleeptime = 10)
qdel(src)
/obj/machinery/door/firedoor/cultify()
@@ -145,8 +136,8 @@
// Make it a wood-reinforced wooden table.
// There are cult materials available, but it'd make the table non-deconstructable with how holotables work.
// Could possibly use a new material var for holographic-ness?
- material = name_to_material["wood"]
- reinforced = name_to_material["wood"]
+ material = get_material_by_name("wood")
+ reinforced = get_material_by_name("wood")
update_desc()
update_connections(1)
update_icon()
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index dc09e0edb9..cba7a96ef4 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -339,7 +339,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
attack(mob/living/M as mob, mob/living/user as mob)
- M.attack_log += text("\[[time_stamp()]\] Has had the [name] used on him by [user.name] ([user.ckey])")
+ M.attack_log += text("\[[time_stamp()]\] Has had the [name] used on them by [user.name] ([user.ckey])")
user.attack_log += text("\[[time_stamp()]\] Used [name] on [M.name] ([M.ckey])")
msg_admin_attack("[user.name] ([user.ckey]) used [name] on [M.name] ([M.ckey]) (JMP)")
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index ff5b7ff880..3b2345c1be 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -5,6 +5,14 @@ var/list/sacrificed = list()
/obj/effect/rune
+/*
+ * Use as a general guideline for this and related files:
+ * * ... - when something non-trivial or an error happens, so something similar to "Sparks come out of the machine!"
+ * * ... - when something that is fit for 'warning' happens but there is some damage or pain as well.
+ * * ... - when there is a private message to the cultists. This guideline is very arbitrary but there has to be some consistency!
+ */
+
+
/////////////////////////////////////////FIRST RUNE
proc
teleport(var/key)
@@ -21,7 +29,7 @@ var/list/sacrificed = list()
allrunesloc.len = index
allrunesloc[index] = R.loc
if(index >= 5)
- user << "You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric"
+ user << "You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric."
if (istype(user, /mob/living))
user.take_overall_damage(5, 0)
qdel(src)
@@ -30,9 +38,9 @@ var/list/sacrificed = list()
user.say("Sas[pick("'","`")]so c'arta forbici!")//Only you can stop auto-muting
else
user.whisper("Sas[pick("'","`")]so c'arta forbici!")
- user.visible_message("\The [user] disappears in a flash of red light!", \
- "You feel as your body gets dragged through the dimension of Nar-Sie!", \
- "You hear a sickening crunch and sloshing of viscera.")
+ user.visible_message("[user] disappears in a flash of red light!", \
+ "You feel as your body gets dragged through the dimension of Nar-Sie!", \
+ "You hear a sickening crunch and sloshing of viscera.")
user.loc = allrunesloc[rand(1,index)]
return
if(istype(src,/obj/effect/rune))
@@ -58,7 +66,7 @@ var/list/sacrificed = list()
IP = R
runecount++
if(runecount >= 2)
- user << "You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric"
+ user << "You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric."
if (istype(user, /mob/living))
user.take_overall_damage(5, 0)
qdel(src)
@@ -134,11 +142,11 @@ var/list/sacrificed = list()
admin_attack_log(attacker, target, "Used a convert rune", "Was subjected to a convert rune", "used a convert rune on")
switch(target.getFireLoss())
if(0 to 25)
- target << "Your blood boils as you force yourself to resist the corruption invading every corner of your mind."
+ target << "Your blood boils as you force yourself to resist the corruption invading every corner of your mind."
if(25 to 45)
- target << "Your blood boils and your body burns as the corruption further forces itself into your body and mind."
+ target << "Your blood boils and your body burns as the corruption further forces itself into your body and mind."
if(45 to 75)
- target << "You begin to hallucinate images of a dark and incomprehensible being and your entire body feels like its engulfed in flame as your mental defenses crumble."
+ target << "You begin to hallucinate images of a dark and incomprehensible being and your entire body feels like its engulfed in flame as your mental defenses crumble."
target.apply_effect(rand(1,10), STUTTER)
if(75 to 100)
target << "Your mind turns to ash as the burning flames engulf your very soul and images of an unspeakable horror begin to bombard the last remnants of mental resistance."
@@ -157,7 +165,7 @@ var/list/sacrificed = list()
if (target.species && (target.species.flags & NO_PAIN))
target.visible_message("The markings below [target] glow a bloody red.")
else
- target.visible_message("\The [target] writhes in pain as the markings below \him glow a bloody red.", "AAAAAAHHHH!", "You hear an anguished scream.")
+ target.visible_message("[target] writhes in pain as the markings below \him glow a bloody red.", "AAAAAAHHHH!", "You hear an anguished scream.")
if(!waiting_for_input[target]) //so we don't spam them with dialogs if they hesitate
waiting_for_input[target] = 1
@@ -229,15 +237,15 @@ var/list/sacrificed = list()
if(!drain)
return fizzle()
usr.say ("Yu[pick("'","`")]gular faras desdae. Havas mithum javara. Umathar uf'kal thenar!")
- usr.visible_message("Blood flows from the rune into [usr]!", \
- "The blood starts flowing from the rune and into your frail mortal body. You feel... empowered.", \
+ usr.visible_message("Blood flows from the rune into [usr]!", \
+ "The blood starts flowing from the rune and into your frail mortal body. You feel... empowered.", \
"You hear a liquid flowing.")
var/mob/living/user = usr
if(user.bhunger)
user.bhunger = max(user.bhunger-2*drain,0)
if(drain>=50)
- user.visible_message("\The [user]'s eyes give off eerie red glow!", \
- "...but it wasn't nearly enough. You crave, crave for more. The hunger consumes you from within.", \
+ user.visible_message("[user]'s eyes give off eerie red glow!", \
+ "...but it wasn't nearly enough. You crave, crave for more. The hunger consumes you from within.", \
"You hear a heartbeat.")
user.bhunger += drain
src = user
@@ -264,7 +272,7 @@ var/list/sacrificed = list()
if(usr.loc==src.loc)
if(usr.seer==1)
usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium viortia.")
- usr << "The world beyond fades from your vision."
+ usr << "The world beyond fades from your vision."
usr.see_invisible = SEE_INVISIBLE_LIVING
usr.seer = 0
else if(usr.see_invisible!=SEE_INVISIBLE_LIVING)
@@ -336,12 +344,12 @@ var/list/sacrificed = list()
corpse_to_raise.key = ghost.key //the corpse will keep its old mind! but a new player takes ownership of it (they are essentially possessed)
//This means, should that player leave the body, the original may re-enter
usr.say("Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!")
- corpse_to_raise.visible_message("\The [corpse_to_raise]'s eyes glow with a faint red as he stands up, slowly starting to breathe again.", \
+ corpse_to_raise.visible_message("[corpse_to_raise]'s eyes glow with a faint red as he stands up, slowly starting to breathe again.", \
"Life... I'm alive again...", \
"You hear a faint, slightly familiar whisper.")
- body_to_sacrifice.visible_message("\The [body_to_sacrifice] is torn apart, a black smoke swiftly dissipating from his remains!", \
- "You feel as your blood boils, tearing you apart.", \
- "You hear a thousand voices, all crying in pain.")
+ body_to_sacrifice.visible_message("[body_to_sacrifice] is torn apart, a black smoke swiftly dissipating from \his remains!", \
+ "You feel as your blood boils, tearing you apart.", \
+ "You hear a thousand voices, all crying in pain.")
body_to_sacrifice.gib()
// if(ticker.mode.name == "cult")
@@ -349,8 +357,8 @@ var/list/sacrificed = list()
// else
// ticker.mode.cult |= corpse_to_raise.mind
- corpse_to_raise << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root."
- corpse_to_raise << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back."
+ corpse_to_raise << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root."
+ corpse_to_raise << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back."
return
@@ -391,7 +399,7 @@ var/list/sacrificed = list()
if(usr.loc==src.loc)
var/mob/living/carbon/human/L = usr
usr.say("Fwe[pick("'","`")]sh mah erl nyag r'ya!")
- usr.visible_message("\The [usr]'s eyes glow blue as \he freezes in place, absolutely motionless.", \
+ usr.visible_message("[usr]'s eyes glow blue as \he freezes in place, absolutely motionless.", \
"The shadow that is your spirit separates itself from your body. You are now in the realm beyond. While this is a great sight, being here strains your mind and body. Hurry...", \
"You hear only complete silence for a moment.")
announce_ghost_joinleave(usr.ghostize(1), 1, "You feel that they had to use some [pick("dark", "black", "blood", "forgotten", "forbidden")] magic to [pick("invade","disturb","disrupt","infest","taint","spoil","blight")] this place!")
@@ -461,8 +469,8 @@ var/list/sacrificed = list()
user.take_organ_damage(1, 0)
sleep(30)
if(D)
- D.visible_message("\The [D] slowly dissipates into dust and bones.", \
- "You feel pain, as bonds formed between your soul and this homunculus break.", \
+ D.visible_message("[D] slowly dissipates into dust and bones.", \
+ "You feel pain, as bonds formed between your soul and this homunculus break.", \
"You hear faint rustle.")
D.dust()
return
@@ -560,8 +568,8 @@ var/list/sacrificed = list()
user.say("Uhrast ka'hfa heldsagen ver[pick("'","`")]lot!")
user.take_overall_damage(200, 0)
runedec+=10
- user.visible_message("\The [user] keels over dead, his blood glowing blue as it escapes his body and dissipates into thin air.", \
- "In the last moment of your humble life, you feel an immense pain as fabric of reality mends... with your blood.", \
+ user.visible_message("\The [user] keels over dead, \his blood glowing blue as it escapes \his body and dissipates into thin air.", \
+ "In the last moment of your humble life, you feel an immense pain as fabric of reality mends... with your blood.", \
"You hear faint rustle.")
for(,user.stat==2)
sleep(600)
@@ -592,9 +600,10 @@ var/list/sacrificed = list()
usr.whisper("[input]")
input = sanitize(input)
+ log_and_message_admins("used a communicate rune to say '[input]'")
for(var/datum/mind/H in cult.current_antagonists)
if (H.current)
- H.current << "[input]"
+ H.current << "[input]"
qdel(src)
return 1
@@ -638,17 +647,17 @@ var/list/sacrificed = list()
H.dust()//To prevent the MMI from remaining
else
H.gib()
- usr << "The Geometer of Blood accepts this sacrifice, your objective is now complete."
+ usr << "The Geometer of Blood accepts this sacrifice, your objective is now complete."
else
usr << "Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual."
else
if(cultsinrange.len >= 3)
if(H.stat !=2)
if(prob(80) || worth)
- usr << "The Geometer of Blood accepts this [worth ? "exotic " : ""]sacrifice."
+ usr << "The Geometer of Blood accepts this [worth ? "exotic " : ""]sacrifice."
cult.grant_runeword(usr)
else
- usr << "The Geometer of blood accepts this sacrifice."
+ usr << "The Geometer of Blood accepts this sacrifice."
usr << "However, this soul was not enough to gain His favor."
if(isrobot(H))
H.dust()//To prevent the MMI from remaining
@@ -656,10 +665,10 @@ var/list/sacrificed = list()
H.gib()
else
if(prob(40) || worth)
- usr << "The Geometer of blood accepts this [worth ? "exotic " : ""]sacrifice."
+ usr << "The Geometer of Blood accepts this [worth ? "exotic " : ""]sacrifice."
cult.grant_runeword(usr)
else
- usr << "The Geometer of blood accepts this sacrifice."
+ usr << "The Geometer of Blood accepts this sacrifice."
usr << "However, a mere dead body is not enough to satisfy Him."
if(isrobot(H))
H.dust()//To prevent the MMI from remaining
@@ -671,10 +680,10 @@ var/list/sacrificed = list()
else
if(prob(40))
- usr << "The Geometer of blood accepts this sacrifice."
+ usr << "The Geometer of Blood accepts this sacrifice."
cult.grant_runeword(usr)
else
- usr << "The Geometer of blood accepts this sacrifice."
+ usr << "The Geometer of Blood accepts this sacrifice."
usr << "However, a mere dead body is not enough to satisfy Him."
if(isrobot(H))
H.dust()//To prevent the MMI from remaining
@@ -684,10 +693,10 @@ var/list/sacrificed = list()
if(cultsinrange.len >= 3)
if(H.stat !=2)
if(prob(80))
- usr << "The Geometer of Blood accepts this sacrifice."
+ usr << "The Geometer of Blood accepts this sacrifice."
cult.grant_runeword(usr)
else
- usr << "The Geometer of blood accepts this sacrifice."
+ usr << "The Geometer of Blood accepts this sacrifice."
usr << "However, this soul was not enough to gain His favor."
if(isrobot(H))
H.dust()//To prevent the MMI from remaining
@@ -695,10 +704,10 @@ var/list/sacrificed = list()
H.gib()
else
if(prob(40))
- usr << "The Geometer of blood accepts this sacrifice."
+ usr << "The Geometer of Blood accepts this sacrifice."
cult.grant_runeword(usr)
else
- usr << "The Geometer of blood accepts this sacrifice."
+ usr << "The Geometer of Blood accepts this sacrifice."
usr << "However, a mere dead body is not enough to satisfy Him."
if(isrobot(H))
H.dust()//To prevent the MMI from remaining
@@ -709,10 +718,10 @@ var/list/sacrificed = list()
usr << "The victim is still alive, you will need more cultists chanting for the sacrifice to succeed."
else
if(prob(40))
- usr << "The Geometer of blood accepts this sacrifice."
+ usr << "The Geometer of Blood accepts this sacrifice."
cult.grant_runeword(usr)
else
- usr << "The Geometer of blood accepts this sacrifice."
+ usr << "The Geometer of Blood accepts this sacrifice."
usr << "However, a mere dead body is not enough to satisfy Him."
if(isrobot(H))
H.dust()//To prevent the MMI from remaining
@@ -771,9 +780,9 @@ var/list/sacrificed = list()
var/mob/living/user = usr
user.take_organ_damage(2, 0)
if(src.density)
- usr << "Your blood flows into the rune, and you feel that the very space over the rune thickens."
+ usr << "Your blood flows into the rune, and you feel that the very space over the rune thickens."
else
- usr << "Your blood flows into the rune, and you feel as the rune releases its grasp on space."
+ usr << "Your blood flows into the rune, and you feel as the rune releases its grasp on space."
return
/////////////////////////////////////////EIGHTTEENTH RUNE
@@ -842,7 +851,7 @@ var/list/sacrificed = list()
if (cultist == user) //just to be sure.
return
if(cultist.buckled || cultist.handcuffed || (!isturf(cultist.loc) && !istype(cultist.loc, /obj/structure/closet)))
- user << "You cannot summon \the [cultist], for his shackles of blood are strong."
+ user << "You cannot summon \the [cultist], for \his shackles of blood are strong."
return fizzle()
cultist.loc = src.loc
cultist.lying = 1
@@ -922,7 +931,7 @@ var/list/sacrificed = list()
C.disabilities |= NEARSIGHTED
if(prob(10))
C.sdisabilities |= BLIND
- C.show_message("Suddenly you see red flash that blinds you.", 3)
+ C.show_message("Suddenly you see a red flash that blinds you.", 3)
affected += C
if(affected.len)
usr.say("Sti[pick("'","`")] kaliesin!")
@@ -972,7 +981,7 @@ var/list/sacrificed = list()
if(N)
continue
M.take_overall_damage(51,51)
- M << "Your blood boils!"
+ M << "Your blood boils!"
victims += M
if(prob(5))
spawn(5)
@@ -1004,16 +1013,16 @@ var/list/sacrificed = list()
for(var/mob/living/M in orange(2,R))
M.take_overall_damage(0,15)
if (R.invisibility>M.see_invisible)
- M << "Aargh it burns!"
+ M << "Aargh it burns!"
else
- M << "Rune suddenly ignites, burning you!"
+ M << "Rune suddenly ignites, burning you!"
var/turf/T = get_turf(R)
T.hotspot_expose(700,125)
for(var/obj/effect/decal/cleanable/blood/B in world)
if(B.blood_DNA == src.blood_DNA)
for(var/mob/living/M in orange(1,B))
M.take_overall_damage(0,5)
- M << "Blood suddenly ignites, burning you!"
+ M << "Blood suddenly ignites, burning you!"
var/turf/T = get_turf(B)
T.hotspot_expose(700,125)
qdel(B)
@@ -1032,13 +1041,13 @@ var/list/sacrificed = list()
C.stuttering = 1
C.Weaken(1)
C.Stun(1)
- C.show_message("The rune explodes in a bright flash.", 3)
+ C.show_message("The rune explodes in a bright flash.", 3)
admin_attack_log(usr, C, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on")
else if(issilicon(L))
var/mob/living/silicon/S = L
S.Weaken(5)
- S.show_message("BZZZT... The rune has exploded in a bright flash.", 3)
+ S.show_message("BZZZT... The rune has exploded in a bright flash.", 3)
admin_attack_log(usr, S, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on")
qdel(src)
else ///When invoked as talisman, stun and mute the target mob.
@@ -1046,10 +1055,10 @@ var/list/sacrificed = list()
var/obj/item/weapon/nullrod/N = locate() in T
if(N)
for(var/mob/O in viewers(T, null))
- O.show_message("\The [usr] invokes a talisman at [T], but they are unaffected!", 1)
+ O.show_message(text("[] invokes a talisman at [], but they are unaffected!", usr, T), 1)
else
for(var/mob/O in viewers(T, null))
- O.show_message("\The [usr] invokes a talisman at [T]", 1)
+ O.show_message(text("[] invokes a talisman at []", usr, T), 1)
if(issilicon(T))
T.Weaken(15)
diff --git a/code/game/gamemodes/endgame/supermatter_cascade/universe.dm b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm
index 8cd8765cd8..3374f8f9be 100644
--- a/code/game/gamemodes/endgame/supermatter_cascade/universe.dm
+++ b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm
@@ -79,10 +79,9 @@ The access requirements on the Asteroid Shuttles' consoles have now been revoked
C.req_access = list()
C.req_one_access = list()
- sleep(5 MINUTES)
- ticker.station_explosion_cinematic(0,null) // TODO: Custom cinematic
-
- universe_has_ended = 1
+ spawn(5 MINUTES)
+ ticker.station_explosion_cinematic(0,null) // TODO: Custom cinematic
+ universe_has_ended = 1
return
/datum/universal_state/supermatter_cascade/proc/AreaSet()
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 7cb5c3ece9..c741bafb88 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -166,12 +166,14 @@ var/global/list/additional_antag_types = list()
if(!(antag_templates && antag_templates.len))
return 1
- // Attempt to mark folks down as ready to go. Don't finalize until post setup.
var/datum/antagonist/main_antags = antag_templates[1]
- var/list/candidates = main_antags.get_candidates()
- if(candidates.len >= required_enemies)
- for(var/datum/antagonist/antag in antag_templates)
- antag.attempt_spawn()
+ var/list/potential
+ if(main_antags.flags & ANTAG_OVERRIDE_JOB)
+ potential = main_antags.pending_antagonists
+ else
+ potential = main_antags.candidates
+
+ if(potential.len >= required_enemies)
return 1
return 0
@@ -185,6 +187,14 @@ var/global/list/additional_antag_types = list()
var/datum/event_container/EMajor = event_manager.event_containers[EVENT_LEVEL_MAJOR]
EMajor.delay_modifier = event_delay_mod_major
+/datum/game_mode/proc/pre_setup()
+ for(var/datum/antagonist/antag in antag_templates)
+ antag.build_candidate_list() //compile a list of all eligible candidates
+
+ //antag roles that replace jobs need to be assigned before the job controller hands out jobs.
+ if(antag.flags & ANTAG_OVERRIDE_JOB)
+ antag.attempt_spawn() //select antags to be spawned
+
///post_setup()
/datum/game_mode/proc/post_setup()
@@ -198,11 +208,13 @@ var/global/list/additional_antag_types = list()
spawn(rand(100,150))
announce_ert_disabled()
- if(antag_templates && antag_templates.len)
- for(var/datum/antagonist/antag in antag_templates)
- antag.finalize_spawn()
- if(antag.is_latejoin_template())
- latejoin_templates |= antag
+ //Assign all antag types for this game mode. Any players spawned as antags earlier should have been removed from the pending list, so no need to worry about those.
+ for(var/datum/antagonist/antag in antag_templates)
+ if(!(antag.flags & ANTAG_OVERRIDE_JOB))
+ antag.attempt_spawn() //select antags to be spawned
+ antag.finalize_spawn() //actually spawn antags
+ if(antag.is_latejoin_template())
+ latejoin_templates |= antag
if(emergency_shuttle && auto_recall_shuttle)
emergency_shuttle.auto_recall = 1
@@ -213,6 +225,10 @@ var/global/list/additional_antag_types = list()
feedback_set_details("server_ip","[world.internet_address]:[world.port]")
return 1
+/datum/game_mode/proc/fail_setup()
+ for(var/datum/antagonist/antag in antag_templates)
+ antag.reset()
+
/datum/game_mode/proc/announce_ert_disabled()
if(!ert_disabled)
return
@@ -391,7 +407,7 @@ var/global/list/additional_antag_types = list()
suspects += man
for(var/mob/M in suspects)
- if(M.mind.assigned_role == "MODE")
+ if(player_is_antag(M.mind, only_offstation_roles = 1))
continue
switch(rand(1, 100))
if(1 to 50)
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index 45b2b9829f..614d181795 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -91,11 +91,14 @@ var/global/datum/controller/gameticker/ticker
else
src.mode = config.pick_mode(master_mode)
+ src.mode.pre_setup()
+
job_master.DivideOccupations() // Apparently important for new antagonist system to register specific job antags properly.
if(!mode_started && !src.mode.can_start())
world << "Unable to start [mode.name]. Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby."
current_state = GAME_STATE_PREGAME
+ mode.fail_setup()
mode = null
job_master.ResetOccupations()
return 0
@@ -110,6 +113,7 @@ var/global/datum/controller/gameticker/ticker
else
src.mode.announce()
+ setup_economy()
current_state = GAME_STATE_PLAYING
create_characters() //Create player characters and transfer them
collect_minds()
@@ -118,9 +122,6 @@ var/global/datum/controller/gameticker/ticker
callHook("roundstart")
- //here to initialize the random events nicely at round start
- setup_economy()
-
shuttle_controller.setup_shuttle_docks()
spawn(0)//Forking here so we dont have to wait for this to finish
@@ -288,7 +289,7 @@ var/global/datum/controller/gameticker/ticker
if(player && player.mind && player.mind.assigned_role)
if(player.mind.assigned_role == "Captain")
captainless=0
- if(player.mind.assigned_role != "MODE")
+ if(!player_is_antag(player.mind, only_offstation_roles = 1))
job_master.EquipRank(player, player.mind.assigned_role, 0)
UpdateFactionList(player)
equip_custom_items(player)
@@ -342,7 +343,7 @@ var/global/datum/controller/gameticker/ticker
if(!delay_end)
world.Reboot()
else
- world << "An admin has delayed the round end"
else
world << "An admin has delayed the round end"
diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm
index 7e1ba6d368..03680c8ff3 100644
--- a/code/game/gamemodes/heist/heist.dm
+++ b/code/game/gamemodes/heist/heist.dm
@@ -20,12 +20,3 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind'
if (skipjack && skipjack.returned_home)
return 1
return 0
-
-/datum/game_mode/heist/cleanup()
- //the skipjack and everything in it have left and aren't coming back, so get rid of them.
- var/area/skipjack = locate(/area/shuttle/skipjack/station)
- for (var/mob/living/M in skipjack.contents)
- //maybe send the player a message that they've gone home/been kidnapped? Someone responsible for vox lore should write that.
- qdel(M)
- for (var/obj/O in skipjack.contents)
- qdel(O) //no hiding in lockers or anything
\ No newline at end of file
diff --git a/code/game/gamemodes/intercept_report.dm b/code/game/gamemodes/intercept_report.dm
index 43343fbd4b..4feba5d1d2 100644
--- a/code/game/gamemodes/intercept_report.dm
+++ b/code/game/gamemodes/intercept_report.dm
@@ -54,7 +54,7 @@
"Small Prick"
)
-
+// TODO: Update to new antagonist system.
/datum/intercept_text/proc/build(var/mode_type, datum/mind/correct_person)
switch(mode_type)
if("revolution")
@@ -88,29 +88,6 @@
else
return null
-// NOTE: Commentted out was the code which showed the chance of someone being an antag. If you want to re-add it, just uncomment the code.
-
-/*
-/datum/intercept_text/proc/pick_mob()
- var/list/dudes = list()
- for(var/mob/living/carbon/human/man in player_list)
- if (!man.mind) continue
- if (man.mind.assigned_role=="MODE") continue
- dudes += man
- if(dudes.len==0)
- return null
- return pick(dudes)
-
-
-/datum/intercept_text/proc/pick_fingerprints()
- var/mob/living/carbon/human/dude = src.pick_mob()
- //if (!dude) return pick_fingerprints() //who coded that is totally crasy or just a traitor. -- rastaf0
- if(dude)
- return num2text(md5(dude.dna.uni_identity))
- else
- return num2text(md5(num2text(rand(1,10000))))
-*/
-
/datum/intercept_text/proc/get_suspect()
var/list/dudes = list()
for(var/mob/living/carbon/human/man in player_list) if(man.client && man.client.prefs.nanotrasen_relation == COMPANY_OPPOSED)
@@ -205,32 +182,6 @@
var/cname = pick(src.changeling_names)
var/orgname1 = pick(src.org_names_1)
var/orgname2 = pick(src.org_names_2)
- /*
- var/changeling_name
- var/changeling_job
- var/prob_right_dude = rand(prob_correct_person_lower, prob_correct_person_higher)
- var/prob_right_job = rand(prob_correct_job_lower, prob_correct_job_higher)
- if(prob(prob_right_job))
- if(correct_person)
- if(correct_person:assigned_role=="MODE")
- changeling_job = pick(joblist)
- else
- changeling_job = correct_person:assigned_role
- else
- changeling_job = pick(joblist)
- if(prob(prob_right_dude) && ticker.mode == "changeling")
- if(correct_person:assigned_role=="MODE")
- changeling_name = correct_person:current
- else
- changeling_name = src.pick_mob()
- else
- changeling_name = src.pick_mob()
- */
-
src.text += "
We have received a report that a dangerous alien lifeform known only as \"[cname]\" may have infiltrated your crew. "
- /*
- src.text += "Our intelligence suggests a [prob_right_job]% chance that a [changeling_job] on board your station has been replaced by the alien. "
- src.text += "Additionally, the report indicates a [prob_right_dude]% chance that [changeling_name] may have been in contact with the lifeform at a recent social gathering. "
- */
src.text += "These lifeforms are assosciated with the [orgname1] [orgname2] and may be attempting to acquire sensitive materials on their behalf. "
src.text += "Please take care not to alarm the crew, as [cname] may take advantage of a panic situation. Remember, they can be anybody, suspect everybody!"
diff --git a/code/game/gamemodes/newobjective.dm b/code/game/gamemodes/newobjective.dm
index 9dc8623822..e8ea12b84b 100644
--- a/code/game/gamemodes/newobjective.dm
+++ b/code/game/gamemodes/newobjective.dm
@@ -1252,7 +1252,7 @@ datum
proc/find_target()
..()
if(target && target.current)
- explanation_text = "[target.current.real_name], the [target.role_alt_title ? target.role_alt_title : target.assigned_role], has defied us for the last time. Make an example of him, and bring us his severed head."
+ explanation_text = "[target.current.real_name], the [target.role_alt_title ? target.role_alt_title : target.assigned_role], has defied us for the last time. Make an example of [target.current.gender == MALE ? "him" : target.current.gender == FEMALE ? "her" : "them"], and bring us [target.current.gender == MALE ? "his" : target.current.gender == FEMALE ? "her" : "their"] severed head."
else
explanation_text = "Free Objective"
return target
@@ -1261,7 +1261,7 @@ datum
find_target_by_role(role, role_type=0)
..(role, role_type)
if(target && target.current)
- explanation_text = "[target.current.real_name], the [target.role_alt_title ? target.role_alt_title : (!role_type ? target.assigned_role : target.special_role)], has defied us for the last time. Make an example of him, and bring us his severed head."
+ explanation_text = "[target.current.real_name], the [target.role_alt_title ? target.role_alt_title : (!role_type ? target.assigned_role : target.special_role)], has defied us for the last time. Make an example of [target.current.gender == MALE ? "him" : target.current.gender == FEMALE ? "her" : "them"], and bring us [target.current.gender == MALE ? "his" : target.current.gender == FEMALE ? "her" : "their"] severed head."
else
explanation_text = "Free Objective"
return target
@@ -1488,4 +1488,4 @@ datum/objective/silence
#undef LENIENT
#undef NORMAL
#undef HARD
-#undef IMPOSSIBLE
\ No newline at end of file
+#undef IMPOSSIBLE
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 0ad6e7fc5f..16d50cee4d 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -703,7 +703,7 @@ datum/objective/heist/kidnap
var/list/priority_targets = list()
for(var/datum/mind/possible_target in ticker.minds)
- if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != 2) && (possible_target.assigned_role != "MODE"))
+ if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != 2) && (!possible_target.special_role))
possible_targets += possible_target
for(var/role in roles)
if(possible_target.assigned_role == role)
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index 0812c51429..7209844d38 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -1,6 +1,6 @@
/datum/game_mode/wizard
name = "Wizard"
- round_description = "There is a SPACE WIZARD on the station. You can't let them achieve their objectives!"
+ round_description = "There is a SPACE WIZARD on the station. You can't let the magician achieve their objectives!"
extended_round_description = "A powerful entity capable of manipulating the elements around him, most commonly referred to as a 'wizard', has infiltrated the station. They have a wide variety of powers and spells available to them that makes your own simple moral self tremble with fear and excitement. Ultimately, their purpose is unknown. However, it is up to you and your crew to decide if their powers can be used for good or if their arrival foreshadows the destruction of the entire station."
config_tag = "wizard"
required_players = 1
diff --git a/code/game/jobs/access_datum.dm b/code/game/jobs/access_datum.dm
index 3aca20b760..9cf27f6dbc 100644
--- a/code/game/jobs/access_datum.dm
+++ b/code/game/jobs/access_datum.dm
@@ -305,17 +305,8 @@
desc = "Cargo Office"
region = ACCESS_REGION_SUPPLY
-/var/const/access_mint = 51
-/datum/access/mint
- id = access_mint
- desc = "Mint"
- region = ACCESS_REGION_SUPPLY
-
-/var/const/access_mint_vault = 52
-/datum/access/mint_vault
- id = access_mint_vault
- desc = "Mint Vault"
- access_type = ACCESS_TYPE_NONE
+// /var/const/free_access_id = 51
+// /var/const/free_access_id = 52
/var/const/access_heads_vault = 53
/datum/access/heads_vault
diff --git a/code/game/jobs/job/assistant.dm b/code/game/jobs/job/assistant.dm
index ef3469b83e..df54a4ea57 100644
--- a/code/game/jobs/job/assistant.dm
+++ b/code/game/jobs/job/assistant.dm
@@ -11,7 +11,7 @@
economic_modifier = 1
access = list() //See /datum/job/assistant/get_access()
minimal_access = list() //See /datum/job/assistant/get_access()
- alt_titles = list("Technical Assistant","Medical Intern","Research Assistant","Security Cadet","Visitor")
+ alt_titles = list("Technical Assistant","Medical Intern","Research Assistant","Visitor")
/datum/job/assistant/equip(var/mob/living/carbon/human/H)
if(!H) return 0
diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm
index e97f46b8ac..f45af97286 100644
--- a/code/game/jobs/job/civilian.dm
+++ b/code/game/jobs/job/civilian.dm
@@ -98,8 +98,8 @@
supervisors = "the head of personnel"
selection_color = "#dddddd"
economic_modifier = 5
- access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station)
- minimal_access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station)
+ access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
+ minimal_access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
equip(var/mob/living/carbon/human/H)
@@ -125,7 +125,7 @@
spawn_positions = 2
supervisors = "the quartermaster and the head of personnel"
selection_color = "#dddddd"
- access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station)
+ access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
minimal_access = list(access_maint_tunnels, access_cargo, access_cargo_bot, access_mailsorting)
@@ -150,9 +150,9 @@
spawn_positions = 3
supervisors = "the quartermaster and the head of personnel"
selection_color = "#dddddd"
- economic_modifier = 3
- access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station)
- minimal_access = list(access_mining, access_mint, access_mining_station, access_mailsorting)
+ economic_modifier = 5
+ access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
+ minimal_access = list(access_mining, access_mining_station, access_mailsorting)
alt_titles = list("Drill Technician","Prospector")
equip(var/mob/living/carbon/human/H)
diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm
index b15a762c6d..b84b673a40 100644
--- a/code/game/jobs/job/job.dm
+++ b/code/game/jobs/job/job.dm
@@ -26,6 +26,12 @@
/datum/job/proc/equip(var/mob/living/carbon/human/H)
return 1
+/datum/job/proc/equip_backpack(var/mob/living/carbon/human/H)
+ switch(H.backbag)
+ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
+ if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
+ if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
+
/datum/job/proc/equip_survival(var/mob/living/carbon/human/H)
if(!H) return 0
H.species.equip_survival_gear(H,0)
diff --git a/code/game/jobs/job/silicon.dm b/code/game/jobs/job/silicon.dm
index 88bfed60d6..6cec7149e9 100644
--- a/code/game/jobs/job/silicon.dm
+++ b/code/game/jobs/job/silicon.dm
@@ -19,6 +19,10 @@
if(!H) return 0
return 1
+ equip_backpack(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ return 1
+
/datum/job/ai/is_position_available()
return (empty_playable_ai_cores.len != 0)
@@ -47,6 +51,10 @@
equip_survival(var/mob/living/carbon/human/H)
if(!H) return 0
return 1
+
+ equip_backpack(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ return 1
return 1
/datum/job/cyborg/equip_preview(mob/living/carbon/human/H)
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index 5259c8e5a2..1768ffe642 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -348,7 +348,6 @@ var/global/datum/controller/occupations/job_master
proc/EquipRank(var/mob/living/carbon/human/H, var/rank, var/joined_late = 0)
-
if(!H) return null
var/datum/job/job = GetJob(rank)
@@ -394,6 +393,7 @@ var/global/datum/controller/occupations/job_master
//Equip job items.
job.equip(H)
job.setup_account(H)
+ job.equip_backpack(H)
job.equip_survival(H)
job.apply_fingerprints(H)
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index 35b1a15397..d5ccdacc3a 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -177,11 +177,6 @@
return
return
-
- allow_drop()
- return 0
-
-
process()
if (stat & (NOPOWER|BROKEN))
return
@@ -342,7 +337,7 @@
if(src.occupant.reagents.get_reagent_amount(chemical) + amount <= 20)
use_power(amount * CHEM_SYNTH_ENERGY)
src.occupant.reagents.add_reagent(chemical, amount)
- user << "Occupant now has [src.occupant.reagents.get_reagent_amount(chemical)] units of [available_chemicals[chemical]] in his/her bloodstream."
+ user << "Occupant now has [src.occupant.reagents.get_reagent_amount(chemical)] units of [available_chemicals[chemical]] in their bloodstream."
return
user << "There's no occupant in the sleeper or the subject has too many chemicals!"
return
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index 855e32a0a1..ef38ab99ba 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -14,9 +14,6 @@
idle_power_usage = 60
active_power_usage = 10000 //10 kW. It's a big all-body scanner.
-/*/obj/machinery/bodyscanner/allow_drop()
- return 0*/
-
/obj/machinery/bodyscanner/relaymove(mob/user as mob)
if (user.stat)
return
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 95e043db28..64101d4433 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -69,6 +69,7 @@
var/datum/radio_frequency/radio_connection
var/list/TLV = list()
+ var/list/trace_gas = list("sleeping_agent", "volatile_fuel") //list of other gases that this air alarm is able to detect
var/danger_level = 0
var/pressure_dangerlevel = 0
@@ -240,23 +241,24 @@
/obj/machinery/alarm/proc/overall_danger_level(var/datum/gas_mixture/environment)
var/partial_pressure = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume
var/environment_pressure = environment.return_pressure()
- //var/other_moles = 0.0
- ////for(var/datum/gas/G in environment.trace_gases)
- // other_moles+=G.moles
+
+ var/other_moles = 0
+ for(var/g in trace_gas)
+ other_moles += environment.gas[g] //this is only going to be used in a partial pressure calc, so we don't need to worry about group_multiplier here.
pressure_dangerlevel = get_danger_level(environment_pressure, TLV["pressure"])
oxygen_dangerlevel = get_danger_level(environment.gas["oxygen"]*partial_pressure, TLV["oxygen"])
co2_dangerlevel = get_danger_level(environment.gas["carbon_dioxide"]*partial_pressure, TLV["carbon dioxide"])
phoron_dangerlevel = get_danger_level(environment.gas["phoron"]*partial_pressure, TLV["phoron"])
temperature_dangerlevel = get_danger_level(environment.temperature, TLV["temperature"])
- //other_dangerlevel = get_danger_level(other_moles*partial_pressure, TLV["other"])
+ other_dangerlevel = get_danger_level(other_moles*partial_pressure, TLV["other"])
return max(
pressure_dangerlevel,
oxygen_dangerlevel,
co2_dangerlevel,
phoron_dangerlevel,
- //other_dangerlevel,
+ other_dangerlevel,
temperature_dangerlevel
)
@@ -302,22 +304,30 @@
/obj/machinery/alarm/update_icon()
if(wiresexposed)
icon_state = "alarmx"
+ set_light(0)
return
if((stat & (NOPOWER|BROKEN)) || shorted)
icon_state = "alarmp"
+ set_light(0)
return
var/icon_level = danger_level
if (alarm_area.atmosalm)
icon_level = max(icon_level, 1) //if there's an atmos alarm but everything is okay locally, no need to go past yellow
+ var/new_color = null
switch(icon_level)
if (0)
icon_state = "alarm0"
+ new_color = "#03A728"
if (1)
icon_state = "alarm2" //yes, alarm2 is yellow alarm
+ new_color = "#EC8B2F"
if (2)
icon_state = "alarm1"
+ new_color = "#DA0205"
+
+ set_light(l_range = 2, l_power = 0.5, l_color = new_color)
/obj/machinery/alarm/receive_signal(datum/signal/signal)
if(stat & (NOPOWER|BROKEN))
@@ -504,34 +514,13 @@
var/list/environment_data = new
data["has_environment"] = total
if(total)
- var/partial_pressure = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume
-
- var/list/current_settings = TLV["pressure"]
var/pressure = environment.return_pressure()
- var/pressure_danger = get_danger_level(pressure, current_settings)
- environment_data[++environment_data.len] = list("name" = "Pressure", "value" = pressure, "unit" = "kPa", "danger_level" = pressure_danger)
- data["total_danger"] = pressure_danger
-
- current_settings = TLV["oxygen"]
- var/oxygen_danger = get_danger_level(environment.gas["oxygen"]*partial_pressure, current_settings)
- environment_data[++environment_data.len] = list("name" = "Oxygen", "value" = environment.gas["oxygen"] / total * 100, "unit" = "%", "danger_level" = oxygen_danger)
- data["total_danger"] = max(oxygen_danger, data["total_danger"])
-
- current_settings = TLV["carbon dioxide"]
- var/carbon_dioxide_danger = get_danger_level(environment.gas["carbon_dioxide"]*partial_pressure, current_settings)
- environment_data[++environment_data.len] = list("name" = "Carbon dioxide", "value" = environment.gas["carbon_dioxide"] / total * 100, "unit" = "%", "danger_level" = carbon_dioxide_danger)
- data["total_danger"] = max(carbon_dioxide_danger, data["total_danger"])
-
- current_settings = TLV["phoron"]
- var/phoron_danger = get_danger_level(environment.gas["phoron"]*partial_pressure, current_settings)
- environment_data[++environment_data.len] = list("name" = "Toxins", "value" = environment.gas["phoron"] / total * 100, "unit" = "%", "danger_level" = phoron_danger)
- data["total_danger"] = max(phoron_danger, data["total_danger"])
-
- current_settings = TLV["temperature"]
- var/temperature_danger = get_danger_level(environment.temperature, current_settings)
- environment_data[++environment_data.len] = list("name" = "Temperature", "value" = environment.temperature, "unit" = "K ([round(environment.temperature - T0C, 0.1)]C)", "danger_level" = temperature_danger)
- data["total_danger"] = max(temperature_danger, data["total_danger"])
-
+ environment_data[++environment_data.len] = list("name" = "Pressure", "value" = pressure, "unit" = "kPa", "danger_level" = pressure_dangerlevel)
+ environment_data[++environment_data.len] = list("name" = "Oxygen", "value" = environment.gas["oxygen"] / total * 100, "unit" = "%", "danger_level" = oxygen_dangerlevel)
+ environment_data[++environment_data.len] = list("name" = "Carbon dioxide", "value" = environment.gas["carbon_dioxide"] / total * 100, "unit" = "%", "danger_level" = co2_dangerlevel)
+ environment_data[++environment_data.len] = list("name" = "Toxins", "value" = environment.gas["phoron"] / total * 100, "unit" = "%", "danger_level" = phoron_dangerlevel)
+ environment_data[++environment_data.len] = list("name" = "Temperature", "value" = environment.temperature, "unit" = "K ([round(environment.temperature - T0C, 0.1)]C)", "danger_level" = temperature_dangerlevel)
+ data["total_danger"] = danger_level
data["environment"] = environment_data
data["atmos_alarm"] = alarm_area.atmosalm
data["fire_alarm"] = alarm_area.fire != null
@@ -888,8 +877,11 @@ FIRE ALARM
var/last_process = 0
var/wiresexposed = 0
var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone
+ var/seclevel
/obj/machinery/firealarm/update_icon()
+ overlays.Cut()
+
if(wiresexposed)
switch(buildstage)
if(2)
@@ -898,17 +890,28 @@ FIRE ALARM
icon_state="fire_b1"
if(0)
icon_state="fire_b0"
-
+ set_light(0)
return
if(stat & BROKEN)
icon_state = "firex"
+ set_light(0)
else if(stat & NOPOWER)
icon_state = "firep"
- else if(!src.detecting)
- icon_state = "fire1"
+ set_light(0)
else
- icon_state = "fire0"
+ if(!src.detecting)
+ icon_state = "fire1"
+ set_light(l_range = 4, l_power = 2, l_color = "#ff0000")
+ else
+ icon_state = "fire0"
+ switch(seclevel)
+ if("green") set_light(l_range = 2, l_power = 0.5, l_color = "#00ff00")
+ if("blue") set_light(l_range = 2, l_power = 0.5, l_color = "#1024A9")
+ if("red") set_light(l_range = 4, l_power = 2, l_color = "#ff0000")
+ if("delta") set_light(l_range = 4, l_power = 2, l_color = "#FF6633")
+
+ src.overlays += image('icons/obj/monitors.dmi', "overlay_[seclevel]")
/obj/machinery/firealarm/fire_act(datum/gas_mixture/air, temperature, volume)
if(src.detecting)
@@ -919,7 +922,7 @@ FIRE ALARM
/obj/machinery/firealarm/attack_ai(mob/user as mob)
return src.attack_hand(user)
-/obj/machinery/firealarm/bullet_act(BLAH)
+/obj/machinery/firealarm/bullet_act()
return src.alarm()
/obj/machinery/firealarm/emp_act(severity)
@@ -1121,14 +1124,14 @@ FIRE ALARM
pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0
+/obj/machinery/firealarm/proc/set_security_level(var/newlevel)
+ if(seclevel != newlevel)
+ seclevel = newlevel
+ update_icon()
+
/obj/machinery/firealarm/initialize()
if(z in config.contact_levels)
- if(security_level)
- src.overlays += image('icons/obj/monitors.dmi', "overlay_[get_security_level()]")
- else
- src.overlays += image('icons/obj/monitors.dmi', "overlay_green")
-
- update_icon()
+ set_security_level(security_level? get_security_level() : "green")
/*
FIRE ALARM CIRCUIT
diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm
index 21550121cd..e0a837b4ce 100644
--- a/code/game/machinery/atmoalter/canister.dm
+++ b/code/game/machinery/atmoalter/canister.dm
@@ -351,7 +351,7 @@ update_flag
"\[N2O\]" = "redws", \
"\[N2\]" = "red", \
"\[O2\]" = "blue", \
- "\[Toxin (Bio)\]" = "orange", \
+ "\[Phoron\]" = "orange", \
"\[CO2\]" = "black", \
"\[Air\]" = "grey", \
"\[CAUTION\]" = "yellow", \
diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm
index f8d611bcbf..b7bcc53e91 100644
--- a/code/game/machinery/atmoalter/portable_atmospherics.dm
+++ b/code/game/machinery/atmoalter/portable_atmospherics.dm
@@ -104,7 +104,6 @@
network.update = 1
/obj/machinery/portable_atmospherics/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
- var/obj/icon = src
if ((istype(W, /obj/item/weapon/tank) && !( src.destroyed )))
if (src.holding)
return
@@ -136,21 +135,8 @@
return
else if ((istype(W, /obj/item/device/analyzer)) && Adjacent(user))
- visible_message("\The [user] has used \the [W] on \the [src] \icon[icon]")
- if(air_contents)
- var/pressure = air_contents.return_pressure()
- var/total_moles = air_contents.total_moles
-
- user << "Results of analysis of \icon[icon]"
- if (total_moles>0)
- user << "Pressure: [round(pressure,0.1)] kPa"
- for(var/g in air_contents.gas)
- user << "[gas_data.name[g]]: [round((air_contents.gas[g] / total_moles) * 100)]%"
- user << "Temperature: [round(air_contents.temperature-T0C)]°C"
- else
- user << "Tank is empty!"
- else
- user << "Tank is empty!"
+ var/obj/item/device/analyzer/A = W
+ A.analyze_gases(src, user)
return
return
@@ -163,6 +149,13 @@
var/last_power_draw = 0
var/obj/item/weapon/cell/cell
+/obj/machinery/portable_atmospherics/powered/powered()
+ if(use_power) //using area power
+ return ..()
+ if(cell && cell.charge)
+ return 1
+ return 0
+
/obj/machinery/portable_atmospherics/powered/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/weapon/cell))
if(cell)
@@ -176,6 +169,7 @@
cell = C
C.loc = src
user.visible_message("[user] opens the panel on [src] and inserts [C].", "You open the panel on [src] and insert [C].")
+ power_change()
return
if(istype(I, /obj/item/weapon/screwdriver))
@@ -187,8 +181,8 @@
cell.add_fingerprint(user)
cell.loc = src.loc
cell = null
+ power_change()
return
-
..()
/obj/machinery/portable_atmospherics/proc/log_open()
diff --git a/code/game/machinery/atmoalter/pump.dm b/code/game/machinery/atmoalter/pump.dm
index 8d80e57e78..ad664049fc 100644
--- a/code/game/machinery/atmoalter/pump.dm
+++ b/code/game/machinery/atmoalter/pump.dm
@@ -102,6 +102,7 @@
//ran out of charge
if (!cell.charge)
+ power_change()
update_icon()
src.updateDialog()
diff --git a/code/game/machinery/atmoalter/scrubber.dm b/code/game/machinery/atmoalter/scrubber.dm
index f705a62ae2..457792c9e2 100644
--- a/code/game/machinery/atmoalter/scrubber.dm
+++ b/code/game/machinery/atmoalter/scrubber.dm
@@ -77,6 +77,7 @@
//ran out of charge
if (!cell.charge)
+ power_change()
update_icon()
//src.update_icon()
@@ -147,7 +148,6 @@
volume = 50000
volume_rate = 5000
- chan
use_power = 1
idle_power_usage = 500 //internal circuitry, friction losses and stuff
active_power_usage = 100000 //100 kW ~ 135 HP
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index eca7dbcef9..0956486b69 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -290,7 +290,7 @@
/obj/machinery/autolathe/dismantle()
for(var/mat in stored_material)
- var/material/M = name_to_material[mat]
+ var/material/M = get_material_by_name(mat)
if(!istype(M))
continue
var/obj/item/stack/material/S = new M.stack_type(get_turf(src))
diff --git a/code/game/machinery/bioprinter.dm b/code/game/machinery/bioprinter.dm
index 9f144c23b1..23d00318ea 100644
--- a/code/game/machinery/bioprinter.dm
+++ b/code/game/machinery/bioprinter.dm
@@ -66,19 +66,19 @@
user << "You inject the blood sample into the bioprinter."
return
// Meat for biomass.
- else if(!prints_prosthetics && istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat))
+ if(!prints_prosthetics && istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat))
stored_matter += 50
user.drop_item()
user << "\The [src] processes \the [W]. Levels of stored biomass now: [stored_matter]"
qdel(W)
return
// Steel for matter.
- else if(prints_prosthetics && istype(W, /obj/item/stack/material/steel))
- var/obj/item/stack/material/steel/M = W
- stored_matter += M.amount * 10
+ if(prints_prosthetics && istype(W, /obj/item/stack/material) && W.get_material_name() == DEFAULT_WALL_MATERIAL)
+ var/obj/item/stack/S = W
+ stored_matter += S.amount * 10
user.drop_item()
user << "\The [src] processes \the [W]. Levels of stored matter now: [stored_matter]"
qdel(W)
return
- else
- return..()
\ No newline at end of file
+
+ return..()
\ No newline at end of file
diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm
index 36a6e76e55..5ba75ab41a 100644
--- a/code/game/machinery/bots/mulebot.dm
+++ b/code/game/machinery/bots/mulebot.dm
@@ -59,7 +59,7 @@
..()
wires = new(src)
botcard = new(src)
- botcard.access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station)
+ botcard.access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
cell = new(src)
cell.charge = 2000
cell.maxcharge = 2000
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 4be8749588..9dc39f257b 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -138,14 +138,10 @@
else if(iswelder(W) && (wires.CanDeconstruct() || (stat & BROKEN)))
if(weld(W, user))
- if (stat & BROKEN)
- stat &= ~BROKEN
- cancelCameraAlarm()
- update_icon()
- update_coverage()
- else if(assembly)
+ if(assembly)
assembly.loc = src.loc
assembly.state = 1
+ assembly = null //so qdel doesn't eat it.
new /obj/item/stack/cable_coil(src.loc, length=2)
qdel(src)
diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm
index 407b007c24..1fcf6e8625 100644
--- a/code/game/machinery/computer/ai_core.dm
+++ b/code/game/machinery/computer/ai_core.dm
@@ -88,8 +88,8 @@
var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( loc )
A.amount = 5
- if(istype(P, /obj/item/stack/material/glass/reinforced))
- var/obj/item/stack/material/glass/reinforced/RG = P
+ if(istype(P, /obj/item/stack/material) && P.get_material_name() == "rglass")
+ var/obj/item/stack/RG = P
if (RG.get_amount() < 2)
user << "You need two sheets of glass to put in the glass panel."
return
@@ -201,6 +201,7 @@
transfer.control_disabled = 0
transfer.aiRadio.disabledAi = 0
transfer.loc = get_turf(src)
+ transfer.create_eyeobj()
transfer.cancel_camera()
user << "Transfer successful: [transfer.name] ([rand(1000,9999)].exe) downloaded to host terminal. Local copy wiped."
transfer << "You have been uploaded to a stationary terminal. Remote device connection restored."
diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm
index 0c5f59c73f..54734929c8 100644
--- a/code/game/machinery/computer/buildandrepair.dm
+++ b/code/game/machinery/computer/buildandrepair.dm
@@ -87,8 +87,8 @@
var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( src.loc )
A.amount = 5
- if(istype(P, /obj/item/stack/material/glass))
- var/obj/item/stack/material/glass/G = P
+ if(istype(P, /obj/item/stack/material) && P.get_material_name() == "glass")
+ var/obj/item/stack/G = P
if (G.get_amount() < 2)
user << "You need two sheets of glass to put in the glass panel."
return
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 8534128fb7..25894ae91e 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -5,7 +5,7 @@
desc = "Used to view, edit and maintain security records"
icon_state = "security"
light_color = "#a91515"
- req_one_access = list(access_security, access_forensics_lockers)
+ req_one_access = list(access_security, access_forensics_lockers, access_lawyer)
circuit = "/obj/item/weapon/circuitboard/secure_data"
var/obj/item/weapon/card/id/scan = null
var/authenticated = null
diff --git a/code/game/machinery/computer3/buildandrepair.dm b/code/game/machinery/computer3/buildandrepair.dm
index f3e7981af4..47ceffb756 100644
--- a/code/game/machinery/computer3/buildandrepair.dm
+++ b/code/game/machinery/computer3/buildandrepair.dm
@@ -178,12 +178,13 @@
if(istype(P, /obj/item/weapon/crowbar)) // complicated check
remove_peripheral()
- if(istype(P, /obj/item/stack/material/glass))
- if(P:amount >= 2)
+ if(istype(P, /obj/item/stack/material) && P.get_material_name() == "glass")
+ var/obj/item/stack/S = P
+ if(S.amount >= 2)
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 20))
- if(P)
- P:use(2)
+ if(S)
+ S.use(2)
user << "You put in the glass panel."
src.state = 4
src.icon_state = "4"
diff --git a/code/game/machinery/computer3/computers/camera.dm b/code/game/machinery/computer3/computers/camera.dm
index f90b0526ee..814df454fa 100644
--- a/code/game/machinery/computer3/computers/camera.dm
+++ b/code/game/machinery/computer3/computers/camera.dm
@@ -56,7 +56,7 @@
name = "Security Camera Network Main Key"
var/title = "Station"
var/desc = "Connects to station security cameras."
- var/list/networks = list("SS13")
+ var/networks = list("ALL") // A little workaround as it is not possible to place station_networks here
var/screen = "cameras"
execute(var/datum/file/source)
@@ -76,58 +76,65 @@
return
computer.Crash(MISSING_PROGRAM)
+/datum/file/camnet_key/New()
+ for(var/N in networks)
+ if(N == "ALL")
+ networks = station_networks
+ break
+ return ..()
+
/datum/file/camnet_key/mining
name = "Mining Camera Network Key"
title = "mining station"
desc = "Connects to mining security cameras."
- networks = list("MINE")
+ networks = list(NETWORK_MINE)
screen = "miningcameras"
/datum/file/camnet_key/research
name = "Research Camera Network Key"
title = "research"
- networks = list("RD")
+ networks = list(NETWORK_RESEARCH)
/datum/file/camnet_key/bombrange
name = "R&D Bomb Range Camera Network Key"
title = "bomb range"
desc = "Monitors the bomb range."
- networks = list("Toxins")
+ networks = list(NETWORK_RESEARCH)
/datum/file/camnet_key/xeno
name = "R&D Misc. Research Camera Network Key"
title = "special research"
- networks = list("Misc")
+ networks = list(NETWORK_RESEARCH)
/datum/file/camnet_key/singulo
name = "Singularity Camera Network Key"
title = "singularity"
- networks = list("Singularity")
+ networks = list(NETWORK_ENGINE)
/datum/file/camnet_key/entertainment
name = "Entertainment Channel Encryption Key"
title = "entertainment"
desc = "Damn, I hope they have /tg/thechannel on here."
- networks = list("thunder")
+ networks = list(NETWORK_THUNDER)
screen = "entertainment"
/datum/file/camnet_key/creed
name = "Special Ops Camera Encryption Key"
title = "special ops"
desc = "Connects to special ops secure camera feeds."
- networks = list("CREED")
+ networks = list(NETWORK_ERT)
/datum/file/camnet_key/prison
name = "Prison Camera Network Key"
title = "prison"
desc = "Monitors the prison."
- networks = list("Prison")
+ networks = list(NETWORK_SECURITY)
/datum/file/camnet_key/syndicate
name = "Camera Network Key"
title = "%!#BUFFER OVERFLOW"
desc = "Connects to security cameras."
- networks = list("SS13")
+ networks = list("ALL")
hidden_file = 1
diff --git a/code/game/machinery/computer3/laptop.dm b/code/game/machinery/computer3/laptop.dm
index 2e73e77115..48e0c48ff0 100644
--- a/code/game/machinery/computer3/laptop.dm
+++ b/code/game/machinery/computer3/laptop.dm
@@ -106,12 +106,16 @@
pixel_x = 2
pixel_y = -3
show_keyboard = 0
+ active_power_usage = 200 // Stationary consoles we use on station have 300, laptops are probably slightly more power efficient
+ idle_power_usage = 100
var/obj/item/device/laptop/portable = null
New(var/L, var/built = 0)
if(!built && !battery)
battery = new /obj/item/weapon/cell(src)
+ battery.maxcharge = 500
+ battery.charge = 500
..(L,built)
verb/close_computer()
diff --git a/code/game/machinery/computer3/lapvend.dm b/code/game/machinery/computer3/lapvend.dm
index b2e84f1cd2..416472a31a 100644
--- a/code/game/machinery/computer3/lapvend.dm
+++ b/code/game/machinery/computer3/lapvend.dm
@@ -46,8 +46,8 @@
if(vendmode == 3)
if(istype(W,/obj/item/weapon/card))
var/obj/item/weapon/card/I = W
- reimburse(I)
- vendmode = 0
+ if(reimburse(I))
+ vendmode = 0
if(vendmode == 0)
if(istype(W, /obj/item/device/laptop))
var/obj/item/device/laptop/L = W
@@ -202,11 +202,11 @@
if (network == 3)
newlap.spawn_parts += (/obj/item/part/computer/networking/cable)
if (power == 1)
- qdel(newlap.battery)
- newlap.battery = new /obj/item/weapon/cell/high(newlap)
+ newlap.battery.maxcharge = 1000
+ newlap.battery.charge = 1000
if (power == 2)
- qdel(newlap.battery)
- newlap.battery = new /obj/item/weapon/cell/super(newlap)
+ newlap.battery.maxcharge = 1750
+ newlap.battery.charge = 1750
newlap.spawn_parts()
@@ -215,6 +215,9 @@
var/obj/item/weapon/card/id/C = I
visible_message("[usr] swipes a card through [src].")
var/datum/money_account/CH = get_account(C.associated_account_number)
+ if(!CH)
+ usr << "\icon[src]No valid account number is associated with this card."
+ return
if(CH.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2)
if(vendor_account)
var/attempt_pin = input("Enter pin code", "Vendor transaction") as num
@@ -363,18 +366,25 @@
var/obj/item/weapon/card/id/C = I
visible_message("[usr] swipes a card through [src].")
var/datum/money_account/CH = get_account(C.associated_account_number)
+ if(!CH)
+ usr << "\icon[src]No valid account number is associated with this card."
+ return 0
if(CH.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2)
if(vendor_account)
var/attempt_pin = input("Enter pin code", "Vendor transaction") as num
var/datum/money_account/D = attempt_account_access(C.associated_account_number, attempt_pin, 2)
if(D)
transfer_and_reimburse(D)
+ return 1
else
usr << "\icon[src]Unable to access account. Check security settings and try again."
+ return 0
else
usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call CentComm Support."
+ return 0
else
transfer_and_reimburse(CH)
+ return 1
/obj/machinery/lapvend/proc/transfer_and_reimburse(var/datum/money_account/D)
var/transaction_amount = total()
diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index 41d44a0708..665f74d926 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -106,18 +106,26 @@
if(component_check)
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
var/obj/machinery/new_machine = new src.circuit.build_path(src.loc, src.dir)
- new_machine.component_parts.Cut()
+
+ if(new_machine.component_parts)
+ new_machine.component_parts.Cut()
+ else
+ new_machine.component_parts = list()
+
src.circuit.construct(new_machine)
+
for(var/obj/O in src)
if(circuit.contain_parts) // things like disposal don't want their parts in them
O.loc = new_machine
else
O.loc = null
new_machine.component_parts += O
+
if(circuit.contain_parts)
circuit.loc = new_machine
else
circuit.loc = null
+
new_machine.RefreshParts()
qdel(src)
else
diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm
index 9b5c25c79a..4642dcd27f 100644
--- a/code/game/machinery/cryo.dm
+++ b/code/game/machinery/cryo.dm
@@ -60,11 +60,6 @@
return 1
-
-/obj/machinery/atmospherics/unary/cryo_cell/allow_drop()
- return 0
-
-
/obj/machinery/atmospherics/unary/cryo_cell/relaymove(mob/user as mob)
if(user.stat)
return
diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm
index 167190c336..2da65d273f 100644
--- a/code/game/machinery/deployable.dm
+++ b/code/game/machinery/deployable.dm
@@ -79,12 +79,14 @@ for reference:
maxhealth = material.integrity
health = maxhealth
+/obj/structure/barricade/get_material()
+ return material
+
/obj/structure/barricade/attackby(obj/item/W as obj, mob/user as mob)
- if (istype(W, /obj/item/stack/material))
- var/obj/item/stack/material/D = W
- if(D.material.name != material.name)
- user << "That is the wrong material needed to repair \the [src]."
- return
+ if (istype(W, /obj/item/stack))
+ var/obj/item/stack/D = W
+ if(D.get_material_name() != material.name)
+ return //hitting things with the wrong type of stack usually doesn't produce messages, and probably doesn't need to.
if (health < maxhealth)
if (D.get_amount() < 1)
user << "You need one sheet of [material.display_name] to repair \the [src]."
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 8f3a5ca621..12e4396a18 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -48,6 +48,11 @@
return
..()
+/obj/machinery/door/airlock/get_material()
+ if(mineral)
+ return get_material_by_name(mineral)
+ return get_material_by_name(DEFAULT_WALL_MATERIAL)
+
/obj/machinery/door/airlock/command
name = "Airlock"
icon = 'icons/obj/doors/Doorcom.dmi'
diff --git a/code/game/machinery/doors/blast_door.dm b/code/game/machinery/doors/blast_door.dm
index a2bfb1b6c2..8c960e7bdf 100644
--- a/code/game/machinery/doors/blast_door.dm
+++ b/code/game/machinery/doors/blast_door.dm
@@ -96,12 +96,12 @@
else
usr << "[src]'s motors resist your effort."
return
- if(istype(C, /obj/item/stack/material/plasteel))
- var/amt = repair_price()
+ if(istype(C, /obj/item/stack/material) && C.get_material_name() == "plasteel")
+ var/amt = Ceiling((maxhealth - health)/150)
if(!amt)
usr << "\The [src] is already fully repaired."
return
- var/obj/item/stack/material/plasteel/P = C
+ var/obj/item/stack/P = C
if(P.amount < amt)
usr << "You don't have enough sheets to repair this! You need at least [amt] sheets."
return
@@ -135,16 +135,6 @@
return
force_close()
-// Proc: repair_price()
-// Parameters: None
-// Description: Determines amount of sheets needed for full repair. (max)150HP per sheet, (max)10 emitter hits per sheet.
-/obj/machinery/door/blast/proc/repair_price()
- var/sheets_needed = 0
- var/dam = maxhealth - health
- while(dam > 0)
- dam -= 150
- sheets_needed++
- return sheets_needed
// Proc: repair()
// Parameters: None
@@ -154,7 +144,7 @@
if(stat & BROKEN)
stat &= ~BROKEN
-
+
/obj/machinery/door/blast/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group) return 1
return ..()
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 32b7a5b46b..9075da2a05 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -103,6 +103,13 @@
bumpopen(M)
return
+ if(istype(AM, /obj/machinery/bot))
+ var/obj/machinery/bot/bot = AM
+ if(src.check_access(bot.botcard))
+ if(density)
+ open()
+ return
+
if(istype(AM, /mob/living/bot))
var/mob/living/bot/bot = AM
if(src.check_access(bot.botcard))
@@ -199,10 +206,9 @@
/obj/machinery/door/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/device/detective_scanner))
return
- if(src.operating > 0 || isrobot(user)) return //borgs can't attack doors open because it conflicts with their AI-like interaction with them.
src.add_fingerprint(user)
- if(istype(I, /obj/item/stack/material/steel))
+ if(istype(I, /obj/item/stack/material) && I.get_material_name() == src.get_material_name())
if(stat & BROKEN)
user << "It looks like \the [src] is pretty busted. It's going to need more than just patching up now."
return
@@ -217,20 +223,20 @@
var/amount_needed = (maxhealth - health) / DOOR_REPAIR_AMOUNT
amount_needed = (round(amount_needed) == amount_needed)? amount_needed : round(amount_needed) + 1 //Why does BYOND not have a ceiling proc?
- var/obj/item/stack/material/steel/metalstack = I
+ var/obj/item/stack/stack = I
var/transfer
if (repairing)
- transfer = metalstack.transfer_to(repairing, amount_needed - repairing.amount)
+ transfer = stack.transfer_to(repairing, amount_needed - repairing.amount)
if (!transfer)
user << "You must weld or remove \the [repairing] from \the [src] before you can add anything else."
else
- repairing = metalstack.split(amount_needed)
+ repairing = stack.split(amount_needed)
if (repairing)
repairing.loc = src
transfer = repairing.amount
if (transfer)
- user << "You fit [transfer] [metalstack.singular_name]\s to damaged and broken parts on \the [src]."
+ user << "You fit [transfer] [stack.singular_name]\s to damaged and broken parts on \the [src]."
return
@@ -270,6 +276,8 @@
take_damage(W.force)
return
+ if(src.operating > 0 || isrobot(user)) return //borgs can't attack doors open because it conflicts with their AI-like interaction with them.
+
if(src.operating) return
if(src.allowed(user) && operable())
@@ -333,7 +341,8 @@
/obj/machinery/door/emp_act(severity)
if(prob(20/severity) && (istype(src,/obj/machinery/door/airlock) || istype(src,/obj/machinery/door/window)) )
- open()
+ spawn(0)
+ open()
..()
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index 02b6ea7f4c..78e17e27e0 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -75,6 +75,8 @@
A.all_doors.Remove(src)
. = ..()
+/obj/machinery/door/firedoor/get_material()
+ return get_material_by_name(DEFAULT_WALL_MATERIAL)
/obj/machinery/door/firedoor/examine(mob/user)
. = ..(user, 1)
diff --git a/code/game/machinery/embedded_controller/airlock_program.dm b/code/game/machinery/embedded_controller/airlock_program.dm
index 8cb3abb998..fabf499dc9 100644
--- a/code/game/machinery/embedded_controller/airlock_program.dm
+++ b/code/game/machinery/embedded_controller/airlock_program.dm
@@ -109,10 +109,14 @@
var/shutdown_pump = 0
switch(command)
if("cycle_ext")
- begin_cycle_out()
+ //only respond to these commands if the airlock isn't already doing something
+ //prevents the controller from getting confused and doing strange things
+ if(state == target_state)
+ begin_cycle_out()
if("cycle_int")
- begin_cycle_in()
+ if(state == target_state)
+ begin_cycle_in()
if("cycle_ext_door")
cycleDoors(TARGET_OUTOPEN)
@@ -122,14 +126,6 @@
if("abort")
stop_cycling()
- /*
- //dont do this. If the airlock can't get enough air to pressurize the person inside is stuck
- state = STATE_PRESSURIZE
- target_state = TARGET_NONE
- memory["target_pressure"] = ONE_ATMOSPHERE
- signalPump(tag_airpump, 1, 1, memory["target_pressure"])
- process()
- */
if("force_ext")
toggleDoor(memory["exterior_status"], tag_exterior_door, memory["secure"], "toggle")
@@ -140,11 +136,9 @@
if("purge")
memory["purge"] = !memory["purge"]
if(memory["purge"])
- toggleDoor(memory["exterior_status"], tag_exterior_door, 1, "close")
- toggleDoor(memory["interior_status"], tag_interior_door, 1, "close")
- state = STATE_DEPRESSURIZE
+ close_doors()
+ state = STATE_PREPARE
target_state = TARGET_NONE
- signalPump(tag_airpump, 1, 0, 0)
if("secure")
memory["secure"] = !memory["secure"]
@@ -188,12 +182,12 @@
var/target_pressure = memory["target_pressure"]
if(memory["purge"])
+ //purge apparently means clearing the airlock chamber to vacuum (then refilling, handled later)
target_pressure = 0
+ state = STATE_DEPRESSURIZE
+ signalPump(tag_airpump, 1, 0, 0) //send a signal to start depressurizing
- if(memory["purge"])
- target_pressure = 0
-
- if(chamber_pressure <= target_pressure)
+ else if(chamber_pressure <= target_pressure)
state = STATE_PRESSURIZE
signalPump(tag_airpump, 1, 1, target_pressure) //send a signal to start pressurizing
@@ -201,40 +195,37 @@
state = STATE_DEPRESSURIZE
signalPump(tag_airpump, 1, 0, target_pressure) //send a signal to start depressurizing
- //Check for vacuum - this is set after the pumps so the pumps are aiming for 0
- if(!memory["target_pressure"])
- memory["target_pressure"] = ONE_ATMOSPHERE * 0.05
+ //Make sure the airlock isn't aiming for pure vacuum - an impossibility
+ memory["target_pressure"] = max(target_pressure, ONE_ATMOSPHERE * 0.05)
if(STATE_PRESSURIZE)
if(memory["chamber_sensor_pressure"] >= memory["target_pressure"] * 0.95)
- cycleDoors(target_state)
-
- state = STATE_IDLE
- target_state = TARGET_NONE
-
+ //not done until the pump has reported that it's off
if(memory["pump_status"] != "off")
signalPump(tag_airpump, 0) //send a signal to stop pumping
+ else
+ cycleDoors(target_state)
+ state = STATE_IDLE
+ target_state = TARGET_NONE
if(STATE_DEPRESSURIZE)
- if(memory["purge"])
- if(memory["chamber_sensor_pressure"] <= ONE_ATMOSPHERE * 0.05)
- state = STATE_PRESSURIZE
- signalPump(tag_airpump, 1, 1, memory["target_pressure"])
-
-
- else if(memory["chamber_sensor_pressure"] <= memory["target_pressure"] * 1.05)
- cycleDoors(target_state)
-
- state = STATE_IDLE
- target_state = TARGET_NONE
-
- //send a signal to stop pumping
- if(memory["pump_status"] != "off")
+ if(memory["chamber_sensor_pressure"] <= memory["target_pressure"] * 1.05)
+ if(memory["purge"])
+ memory["purge"] = 0
+ memory["target_pressure"] = memory["internal_sensor_pressure"]
+ state = STATE_PREPARE
+ target_state = TARGET_NONE
+
+ else if(memory["pump_status"] != "off")
signalPump(tag_airpump, 0)
+ else
+ cycleDoors(target_state)
+ state = STATE_IDLE
+ target_state = TARGET_NONE
- memory["processing"] = state != target_state
+ memory["processing"] = (state != target_state)
return 1
diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm
index 4ce21137b8..e78f2b5227 100644
--- a/code/game/machinery/kitchen/microwave.dm
+++ b/code/game/machinery/kitchen/microwave.dm
@@ -130,7 +130,7 @@
if (!(R.id in acceptable_reagents))
user << "Your [O] contains components unsuitable for cookery."
return 1
- //G.reagents.trans_to(src,G.amount_per_transfer_from_this)
+ return
else if(istype(O,/obj/item/weapon/grab))
var/obj/item/weapon/grab/G = O
user << "This is ridiculous. You can not fit \the [G.affecting] in this [src]."
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 55cf5cdc15..709f4b4626 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -176,7 +176,7 @@ Class Procs:
qdel(src)
//sets the use_power var and then forces an area power update
-/obj/machinery/proc/update_use_power(var/new_use_power, var/force_update = 0)
+/obj/machinery/proc/update_use_power(var/new_use_power)
use_power = new_use_power
/obj/machinery/proc/auto_use_power()
diff --git a/code/game/machinery/pipe/pipelayer.dm b/code/game/machinery/pipe/pipelayer.dm
index 0f2dc3c855..ca164d7d0c 100644
--- a/code/game/machinery/pipe/pipelayer.dm
+++ b/code/game/machinery/pipe/pipelayer.dm
@@ -50,7 +50,7 @@
user.visible_message("[user] has [!a_dis?"de":""]activated auto-dismantling.", "You [!a_dis?"de":""]activate auto-dismantling.")
return
- if(istype(W, /obj/item/stack/material/steel))
+ if(istype(W, /obj/item/stack/material) && W.get_material_name() == DEFAULT_WALL_MATERIAL)
var/result = load_metal(W)
if(isnull(result))
@@ -86,7 +86,7 @@
on=0
return
-/obj/machinery/pipelayer/proc/load_metal(var/obj/item/stack/material/steel/MM)
+/obj/machinery/pipelayer/proc/load_metal(var/obj/item/stack/MM)
if(istype(MM) && MM.get_amount())
var/cur_amount = metal
var/to_load = max(max_metal - round(cur_amount),0)
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index 9fa78ee968..74d3a4c52f 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -6,16 +6,13 @@
/obj/machinery/porta_turret
name = "turret"
icon = 'icons/obj/turrets.dmi'
- icon_state = "grey_target_prism"
+ icon_state = "turretCover"
anchored = 1
- layer = 3
- invisibility = INVISIBILITY_LEVEL_TWO //the turret is invisible if it's inside its cover
- density = 1
+
+ density = 0
use_power = 1 //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 = null
- req_one_access = list(access_security, access_heads)
power_channel = EQUIP //drains power from the EQUIPMENT channel
var/raised = 0 //if the turret cover is "open" and the turret is raised
@@ -34,7 +31,6 @@
var/iconholder = null //holder for the icon_state. 1 for orange sprite, null for blue.
var/egun = null //holder to handle certain guns switching bullettypes
- var/obj/machinery/porta_turret_cover/cover = null //the cover that is covering this turret
var/last_fired = 0 //1: if the turret is cooling down from a shot, 0: turret is ready to fire
var/shot_delay = 15 //1.5 seconds between each shot
@@ -60,22 +56,43 @@
var/wrenching = 0
var/last_target //last target fired at, prevents turrets from erratically firing at all valid targets in range
+/obj/machinery/porta_turret/crescent
+ enabled = 0
+ ailock = 1
+ check_synth = 0
+ check_access = 1
+ check_arrest = 1
+ check_records = 1
+ check_weapons = 1
+ check_anomalies = 1
+
/obj/machinery/porta_turret/stationary
+ ailock = 1
lethal = 1
installation = /obj/item/weapon/gun/energy/laser
/obj/machinery/porta_turret/New()
..()
- icon_state = "grey_target_prism"
+ req_access.Cut()
+ req_one_access = list(access_security, access_heads)
+
//Sets up a spark system
spark_system = new /datum/effect/effect/system/spark_spread
spark_system.set_up(5, 0, src)
spark_system.attach(src)
- cover = new /obj/machinery/porta_turret_cover(loc)
- cover.Parent_Turret = src
setup()
+/obj/machinery/porta_turret/crescent/New()
+ ..()
+ req_one_access.Cut()
+ req_access = list(access_cent_specops)
+
+/obj/machinery/porta_turret/Destroy()
+ qdel(spark_system)
+ spark_system = null
+ . = ..()
+
/obj/machinery/porta_turret/proc/setup()
var/obj/item/weapon/gun/energy/E = installation //All energy-based weapons are applicable
//var/obj/item/ammo_casing/shottype = E.projectile_type
@@ -127,31 +144,30 @@
eshot_sound = 'sound/weapons/Laser.ogg'
egun = 1
+var/list/turret_icons
+
/obj/machinery/porta_turret/update_icon()
- if(!anchored)
- icon_state = "turretCover"
- return
+ if(!turret_icons)
+ turret_icons = list()
+ turret_icons["open"] = image(icon, "openTurretCover")
+
+ underlays.Cut()
+ underlays += turret_icons["open"]
+
if(stat & BROKEN)
icon_state = "destroyed_target_prism"
- else
- if(powered())
- if(enabled)
- if(iconholder)
- //lasers have a orange icon
- icon_state = "orange_target_prism"
- else
- //almost everything has a blue icon
- icon_state = "target_prism"
+ else if(raised || raising)
+ if(powered() && enabled)
+ if(iconholder)
+ //lasers have a orange icon
+ icon_state = "orange_target_prism"
else
- icon_state = "grey_target_prism"
+ //almost everything has a blue icon
+ icon_state = "target_prism"
else
icon_state = "grey_target_prism"
-
-/obj/machinery/porta_turret/Destroy()
- //deletes its own cover with it
- qdel(cover)
- cover = null
- ..()
+ else
+ icon_state = "turretCover"
/obj/machinery/porta_turret/proc/isLocked(mob/user)
if(ailock && user.isSilicon())
@@ -298,17 +314,13 @@
if(!anchored)
playsound(loc, 'sound/items/Ratchet.ogg', 100, 1)
anchored = 1
- invisibility = INVISIBILITY_LEVEL_TWO
update_icon()
user << "You secure the exterior bolts on the turret."
- create_cover()
else if(anchored)
playsound(loc, 'sound/items/Ratchet.ogg', 100, 1)
anchored = 0
user << "You unsecure the exterior bolts on the turret."
- invisibility = 0
update_icon()
- qdel(cover) //deletes the cover, and the turret instance itself becomes its own cover.
wrenching = 0
else if(istype(I, /obj/item/weapon/card/id)||istype(I, /obj/item/device/pda))
@@ -347,6 +359,11 @@
return 1
/obj/machinery/porta_turret/proc/take_damage(var/force)
+ if(!raised && !raising)
+ force = force / 8
+ if(force < 5)
+ return
+
health -= force
if (force > 5 && prob(45))
spark_system.start()
@@ -354,7 +371,6 @@
die() //the death process :(
/obj/machinery/porta_turret/bullet_act(obj/item/projectile/Proj)
-
if(Proj.damage_type == HALLOSS)
return
@@ -383,48 +399,34 @@
emagged = 1
enabled=0
- sleep(rand(60,600))
- if(!enabled)
- enabled=1
+ spawn(rand(60,600))
+ if(!enabled)
+ enabled=1
..()
/obj/machinery/porta_turret/ex_act(severity)
switch (severity)
if (1)
+ del(src)
qdel(src)
if (2)
if (prob(25))
qdel(src)
else
- take_damage(150) //should instakill most turrets
+ take_damage(initial(health) * 8) //should instakill most turrets
if (3)
- take_damage(50)
+ take_damage(initial(health) * 8 / 3)
/obj/machinery/porta_turret/proc/die() //called when the turret dies, ie, health <= 0
health = 0
- density = 0
stat |= BROKEN //enables the BROKEN bit
- invisibility = 0
spark_system.start() //creates some sparks because they look cool
- density = 1
update_icon()
- qdel(cover) //deletes the cover - no need on keeping it there!
-
-/obj/machinery/porta_turret/proc/create_cover()
- if(cover == null && anchored)
- cover = new /obj/machinery/porta_turret_cover(loc) //if the turret has no cover and is anchored, give it a cover
- cover.Parent_Turret = src //assign the cover its Parent_Turret, which would be this (src)
/obj/machinery/porta_turret/process()
//the main machinery process
- if(cover == null && anchored) //if it has no cover and is anchored
- if(stat & BROKEN) //if the turret is borked
- qdel(cover) //delete its cover, assuming it has one. Workaround for a pesky little bug
- else
- create_cover()
-
if(stat & (NOPOWER|BROKEN))
//if the turret has no power or is broken, make the turret pop down if it hasn't already
popDown()
@@ -473,19 +475,23 @@
if(!L)
return TURRET_NOT_TARGET
- // If emagged not even the dead get a rest
- if(emagged)
- return L.stat ? TURRET_SECONDARY_TARGET : TURRET_PRIORITY_TARGET
-
- if(issilicon(L)) // Don't target silica
+ if(!emagged && issilicon(L)) // Don't target silica
return TURRET_NOT_TARGET
- if(L.stat) //if the perp is dead/dying, no need to bother really
+ if(L.stat && !emagged) //if the perp is dead/dying, no need to bother really
return TURRET_NOT_TARGET //move onto next potential victim!
- var/dst = get_dist(src, L) //if it's too far away, why bother?
- if(dst > 7)
- return 0
+ if(get_dist(src, L) > 7) //if it's too far away, why bother?
+ return TURRET_NOT_TARGET
+
+ if(!check_trajectory(L, src)) //check if we have true line of sight
+ return TURRET_NOT_TARGET
+
+ if(emagged) // If emagged not even the dead get a rest
+ return L.stat ? TURRET_SECONDARY_TARGET : TURRET_PRIORITY_TARGET
+
+ if(lethal && locate(/mob/living/silicon/ai) in get_turf(L)) //don't accidentally kill the AI!
+ return TURRET_NOT_TARGET
if(check_synth) //If it's set to attack all non-silicons, target them!
if(L.lying)
@@ -497,6 +503,7 @@
if(isanimal(L) || issmall(L)) // Animals are not so dangerous
return check_anomalies ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET
+
if(isxenomorph(L) || isalien(L)) // Xenos are dangerous
return check_anomalies ? TURRET_PRIORITY_TARGET : TURRET_NOT_TARGET
@@ -516,7 +523,7 @@
if(emagged)
return 10
- return H.assess_perp(src, check_weapons, check_records, check_arrest)
+ return H.assess_perp(src, check_access, check_weapons, check_records, check_arrest)
/obj/machinery/porta_turret/proc/tryToShootAt(var/list/mob/living/targets)
if(targets.len && last_target && (last_target in targets) && target(last_target))
@@ -536,14 +543,16 @@
return
if(stat & BROKEN)
return
- invisibility = 0
- raising = 1
- flick("popup", cover)
+ set_raised_raising(raised, 1)
+ update_icon()
+
+ var/atom/flick_holder = PoolOrNew(/atom/movable/porta_turret_cover, loc)
+ flick_holder.layer = layer + 0.1
+ flick("popup", flick_holder)
sleep(10)
- raising = 0
- cover.icon_state = "openTurretCover"
- raised = 1
- layer = 4
+ qdel(flick_holder)
+
+ set_raised_raising(1, 0)
update_icon()
/obj/machinery/porta_turret/proc/popDown() //pops the turret down
@@ -554,16 +563,23 @@
return
if(stat & BROKEN)
return
- layer = 3
- raising = 1
- flick("popdown", cover)
- sleep(10)
- raising = 0
- cover.icon_state = "turretCover"
- raised = 0
- invisibility = INVISIBILITY_LEVEL_TWO
+ set_raised_raising(raised, 1)
update_icon()
+ var/atom/flick_holder = PoolOrNew(/atom/movable/porta_turret_cover, loc)
+ flick_holder.layer = layer + 0.1
+ flick("popdown", flick_holder)
+ sleep(10)
+ qdel(flick_holder)
+
+ set_raised_raising(0, 0)
+ update_icon()
+
+/obj/machinery/porta_turret/proc/set_raised_raising(var/raised, var/raising)
+ src.raised = raised
+ src.raising = raising
+ density = raised || raising
+
/obj/machinery/porta_turret/proc/target(var/mob/living/target)
if(disabled)
return
@@ -595,7 +611,6 @@
if(!raised) //the turret has to be raised in order to fire - makes sense, right?
return
-
update_icon()
var/obj/item/projectile/A
if(emagged || lethal)
@@ -610,6 +625,14 @@
// Emagged turrets again use twice as much power due to higher firing rates
use_power(reqpower * (2 * (emagged || lethal)) * (2 * emagged))
+ //Turrets aim for the center of mass by default.
+ //If the target is grabbing someone then the turret smartly aims for extremities
+ var/obj/item/weapon/grab/G = locate() in target
+ if(G && G.state >= GRAB_NECK) //works because mobs are currently not allowed to upgrade to NECK if they are grabbing two people.
+ A.def_zone = pick("head", "l_hand", "r_hand", "l_foot", "r_foot", "l_arm", "r_arm", "l_leg", "r_leg")
+ else
+ A.def_zone = pick("chest", "groin")
+
//Shooting Code:
A.current = T
A.starting = T
@@ -682,8 +705,8 @@
return
if(1)
- if(istype(I, /obj/item/stack/material/steel))
- var/obj/item/stack/material/steel/M = I
+ if(istype(I, /obj/item/stack/material) && I.get_material_name() == DEFAULT_WALL_MATERIAL)
+ var/obj/item/stack/M = I
if(M.use(2))
user << "You add some metal armor to the interior frame."
build_step = 2
@@ -774,8 +797,8 @@
//attack_hand() removes the prox sensor
if(6)
- if(istype(I, /obj/item/stack/material/steel))
- var/obj/item/stack/material/steel/M = I
+ if(istype(I, /obj/item/stack/material) && I.get_material_name() == DEFAULT_WALL_MATERIAL)
+ var/obj/item/stack/M = I
if(M.use(2))
user << "You add some metal armor to the exterior frame."
build_step = 7
@@ -811,9 +834,6 @@
Turret.enabled = 0
Turret.setup()
-// Turret.cover=new/obj/machinery/porta_turret_cover(loc)
-// Turret.cover.Parent_Turret=Turret
-// Turret.cover.name = finish_name
qdel(src) // qdel
else if(istype(I, /obj/item/weapon/crowbar))
@@ -832,6 +852,7 @@
finish_name = t
return
+
..()
@@ -857,32 +878,5 @@
/obj/machinery/porta_turret_construct/attack_ai()
return
-
-/************************
-* PORTABLE TURRET COVER *
-************************/
-
-/obj/machinery/porta_turret_cover
- name = "turret"
+/atom/movable/porta_turret_cover
icon = 'icons/obj/turrets.dmi'
- icon_state = "turretCover"
- anchored = 1
- layer = 3.5
- density = 0
- var/obj/machinery/porta_turret/Parent_Turret = null
-
-/obj/machinery/porta_turret_cover/Destroy()
- Parent_Turret = null
- ..()
-
-/obj/machinery/porta_turret_cover/attack_ai(mob/user)
- return attack_hand(user)
-
-/obj/machinery/porta_turret_cover/attack_hand(mob/user)
- return Parent_Turret.attack_hand(user)
-
-/obj/machinery/porta_turret_cover/Topic(href, href_list)
- Parent_Turret.Topic(href, href_list, 1) // Calling another object's Topic requires that we claim to not have a window, otherwise BYOND's base proc will runtime.
-
-/obj/machinery/porta_turret_cover/attackby(obj/item/I, mob/user)
- Parent_Turret.attackby(I, user)
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index c8a3d5b40a..992a93c40a 100644
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -28,8 +28,7 @@ obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob)
user << "\A [charging] is already charging here."
return
// Checks to make sure he's not in space doing it, and that the area got proper power.
- var/area/a = get_area(src)
- if(!isarea(a) || (a.power_equip == 0 && !a.unlimited_power))
+ if(!powered())
user << "The [name] blinks red as you try to insert the item!"
return
if (istype(G, /obj/item/weapon/gun/energy/gun/nuclear) || istype(G, /obj/item/weapon/gun/energy/crossbow))
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 98cc92380c..c20ca8468a 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -1,22 +1,25 @@
/obj/machinery/recharge_station
name = "cyborg recharging station"
+ desc = "A heavy duty rapid charging system, designed to quickly recharge cyborg power reserves."
icon = 'icons/obj/objects.dmi'
icon_state = "borgcharger0"
density = 1
anchored = 1
use_power = 1
idle_power_usage = 50
- active_power_usage = 50
var/mob/occupant = null
var/obj/item/weapon/cell/cell = null
- //var/max_internal_charge = 15000 // Two charged borgs in a row with default cell
- //var/current_internal_charge = 15000 // Starts charged, to prevent power surges on round start
- var/charging_cap_active = 1000 // Active Cap - When cyborg is inside
- var/charging_cap_passive = 250 // Passive Cap - Recharging internal capacitor when no cyborg is inside
- var/icon_update_tick = 0 // Used to update icon only once every 10 ticks
- var/charge_rate = 250 // How much charge is restored per tick
- var/weld_rate = 0 // How much brute damage is repaired per tick
- var/wire_rate = 0 // How much burn damage is repaired per tick
+ var/icon_update_tick = 0 // Used to rebuild the overlay only once every 10 ticks
+ var/charging = 0
+
+ var/charging_power // W. Power rating used for charging the cyborg. 120 kW if un-upgraded
+ var/restore_power_active // W. Power drawn from APC when an occupant is charging. 40 kW if un-upgraded
+ var/restore_power_passive // W. Power drawn from APC when idle. 7 kW if un-upgraded
+ var/weld_rate = 0 // How much brute damage is repaired per tick
+ var/wire_rate = 0 // How much burn damage is repaired per tick
+
+ var/weld_power_use = 2300 // power used per point of brute damage repaired. 2.3 kW ~ about the same power usage of a handheld arc welder
+ var/wire_power_use = 500 // power used per point of burn damage repaired.
/obj/machinery/recharge_station/New()
..()
@@ -30,51 +33,76 @@
component_parts += new /obj/item/weapon/cell/high(src)
component_parts += new /obj/item/stack/cable_coil(src, 5)
- build_icon()
+ RefreshParts()
+
update_icon()
- RefreshParts()
+/obj/machinery/recharge_station/proc/has_cell_power()
+ return cell && cell.percent() > 0
/obj/machinery/recharge_station/process()
if(stat & (BROKEN))
return
-
- if((stat & (NOPOWER)) && (!cell || cell.percent() <= 0)) // No Power.
- return
-
- var/chargemode = 0
- if(occupant)
- process_occupant()
- chargemode = 1
- // Power Stuff
-
if(!cell) // Shouldn't be possible, but sanity check
return
- if(stat & NOPOWER)
- cell.use(50 * CELLRATE) // Internal Circuitry, 50W load. No power - Runs from internal cell
- return // No external power = No charging
+ if((stat & NOPOWER) && !has_cell_power()) // No power and cell is dead.
+ if(icon_update_tick)
+ icon_update_tick = 0 //just rebuild the overlay once more only
+ update_icon()
+ return
- // Calculating amount of power to draw
- var/charge_diff = (chargemode ? charging_cap_active : charging_cap_passive) + 50 // 50W for circuitry
+ //First, draw from the internal power cell to recharge/repair/etc the occupant
+ if(occupant)
+ process_occupant()
- charge_diff = cell.give(charge_diff)
+ //Then, if external power is available, recharge the internal cell
+ var/recharge_amount = 0
+ if(!(stat & NOPOWER))
+ // Calculating amount of power to draw
+ recharge_amount = (occupant ? restore_power_active : restore_power_passive) * CELLRATE
- if(idle_power_usage != charge_diff) // Force update, but only when our power usage changed this tick.
- idle_power_usage = charge_diff
- update_use_power(1, 1)
+ recharge_amount = cell.give(recharge_amount)
+ use_power(recharge_amount / CELLRATE)
if(icon_update_tick >= 10)
- update_icon()
icon_update_tick = 0
else
icon_update_tick++
+ if(occupant || recharge_amount)
+ update_icon()
+
+//since the recharge station can still be on even with NOPOWER. Instead it draws from the internal cell.
+/obj/machinery/recharge_station/auto_use_power()
+ if(!(stat & NOPOWER))
+ return ..()
+
+ if(!has_cell_power())
+ return 0
+ if(src.use_power == 1)
+ cell.use(idle_power_usage * CELLRATE)
+ else if(src.use_power >= 2)
+ cell.use(active_power_usage * CELLRATE)
return 1
+//Processes the occupant, drawing from the internal power cell if needed.
+/obj/machinery/recharge_station/proc/process_occupant()
+ if(istype(occupant, /mob/living/silicon/robot))
+ var/mob/living/silicon/robot/R = occupant
-/obj/machinery/recharge_station/allow_drop()
- return 0
+ if(R.module)
+ R.module.respawn_consumable(R, charging_power * CELLRATE / 250) //consumables are magical, apparently
+ if(R.cell && !R.cell.fully_charged())
+ var/diff = min(R.cell.maxcharge - R.cell.charge, charging_power * CELLRATE) // Capped by charging_power / tick
+ var/charge_used = cell.use(diff)
+ R.cell.give(charge_used)
+
+ //Lastly, attempt to repair the cyborg if enabled
+ if(weld_rate && R.getBruteLoss() && cell.checked_use(weld_power_use * weld_rate * CELLRATE))
+ R.adjustBruteLoss(-weld_rate)
+ if(wire_rate && R.getFireLoss() && cell.checked_use(wire_power_use * wire_rate * CELLRATE))
+ R.adjustFireLoss(-wire_rate)
/obj/machinery/recharge_station/examine(mob/user)
..(user)
@@ -92,9 +120,6 @@
return
/obj/machinery/recharge_station/emp_act(severity)
- if(stat & (BROKEN|NOPOWER))
- ..(severity)
- return
if(occupant)
occupant.emp_act(severity)
go_out()
@@ -125,13 +150,20 @@
man_rating += P.rating
cell = locate(/obj/item/weapon/cell) in component_parts
- charge_rate = 125 * cap_rating
- charging_cap_passive = charge_rate
+ charging_power = 40000 + 40000 * cap_rating
+ restore_power_active = 10000 + 15000 * cap_rating
+ restore_power_passive = 5000 + 1000 * cap_rating
weld_rate = max(0, man_rating - 3)
wire_rate = max(0, man_rating - 5)
-/obj/machinery/recharge_station/update_icon()
- ..()
+ desc = initial(desc)
+ desc += " Uses a dedicated internal power cell to deliver [charging_power]W when in use."
+ if(weld_rate)
+ desc += " It is capable of repairing structural damage."
+ if(wire_rate)
+ desc += " It is capable of repairing burn damage."
+
+/obj/machinery/recharge_station/proc/build_overlays()
overlays.Cut()
switch(round(chargepercentage()))
if(1 to 20)
@@ -147,53 +179,33 @@
if(99 to 110)
overlays += image('icons/obj/objects.dmi', "statn_c100")
-/obj/machinery/recharge_station/Bumped(var/mob/AM)
- move_inside(AM)
+/obj/machinery/recharge_station/update_icon()
+ ..()
+ if(stat & BROKEN)
+ icon_state = "borgcharger0"
+ return
-/obj/machinery/recharge_station/proc/build_icon()
- if(NOPOWER|BROKEN)
- if(occupant)
- icon_state = "borgcharger1"
+ if(occupant)
+ if((stat & NOPOWER) && !has_cell_power())
+ icon_state = "borgcharger2"
else
- icon_state = "borgcharger0"
+ icon_state = "borgcharger1"
else
icon_state = "borgcharger0"
-/obj/machinery/recharge_station/proc/process_occupant()
- if(occupant)
- if(istype(occupant, /mob/living/silicon/robot))
- var/mob/living/silicon/robot/R = occupant
- if(R.module)
- R.module.respawn_consumable(R, charge_rate / 250)
- if(!R.cell)
- return
- if(!R.cell.fully_charged())
- var/diff = min(R.cell.maxcharge - R.cell.charge, charge_rate) // Capped at charge_rate charge / tick
- if (cell.charge >= diff)
- cell.use(diff)
- R.cell.give(diff)
- if(weld_rate && R.getBruteLoss())
- R.adjustBruteLoss(-1)
- if(wire_rate && R.getFireLoss())
- R.adjustFireLoss(-1)
- else if(istype(occupant, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = occupant
- if(!isnull(H.internal_organs_by_name["cell"]) && H.nutrition < 450)
- H.nutrition = min(H.nutrition+10, 450)
- update_use_power(1)
+ if(icon_update_tick == 0)
+ build_overlays()
+
+/obj/machinery/recharge_station/Bumped(var/mob/AM)
+ move_inside(AM)
/obj/machinery/recharge_station/proc/go_out()
if(!(occupant))
return
- //for(var/obj/O in src)
- // O.loc = loc
- if(occupant.client)
- occupant.client.eye = occupant.client.mob
- occupant.client.perspective = MOB_PERSPECTIVE
occupant.loc = loc
+ occupant.reset_view()
occupant = null
- build_icon()
- update_use_power(1)
+ update_icon()
return
/obj/machinery/recharge_station/verb/move_eject()
@@ -205,49 +217,26 @@
add_fingerprint(usr)
return
-/obj/machinery/recharge_station/verb/move_inside(var/mob/user = usr)
+/obj/machinery/recharge_station/verb/move_inside()
set category = "Object"
set src in oview(1)
- if(!user)
+ if(usr.stat == DEAD)
+ return
+ if(occupant)
+ usr << "\The [src] is already occupied!"
return
- var/can_accept_user
- if(istype(user, /mob/living/silicon/robot))
-
- var/mob/living/silicon/robot/R = user
-
- if(R.stat == 2)
- //Whoever had it so that a borg with a dead cell can't enter this thing should be shot. --NEO
- return
- if(occupant)
- R << "The cell is already occupied!"
- return
- if(!R.cell)
- R << "Without a powercell, you can't be recharged."
- //Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO
- return
- can_accept_user = 1
-
- else if(istype(user, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = user
- if(!isnull(H.internal_organs_by_name["cell"]))
- can_accept_user = 1
-
- if(!can_accept_user)
- user << "Only non-organics may enter the recharger!"
+ var/mob/living/silicon/robot/R = usr
+ if(!istype(R))
+ usr << "Only synthetics may enter the recharger!"
+ return
+ if(!R.cell)
+ usr << "Without a powercell, you can't be recharged."
return
-
- user.stop_pulling()
- if(user.client)
- user.client.perspective = EYE_PERSPECTIVE
- user.client.eye = src
- user.loc = src
- occupant = user
- /*for(var/obj/O in src)
- O.loc = loc*/
- add_fingerprint(user)
- build_icon()
- update_use_power(1)
- return
+ usr.reset_view(src)
+ usr.loc = src
+ occupant = usr
+ add_fingerprint(usr)
+ update_icon()
diff --git a/code/game/machinery/robot_fabricator.dm b/code/game/machinery/robot_fabricator.dm
index b2461f1d7f..4c44bcd4ee 100644
--- a/code/game/machinery/robot_fabricator.dm
+++ b/code/game/machinery/robot_fabricator.dm
@@ -12,8 +12,8 @@
active_power_usage = 10000
/obj/machinery/robotic_fabricator/attackby(var/obj/item/O as obj, var/mob/user as mob)
- if (istype(O, /obj/item/stack/material/steel))
- var/obj/item/stack/material/steel/M = O
+ if (istype(O, /obj/item/stack/material) && O.get_material_name() == DEFAULT_WALL_MATERIAL)
+ var/obj/item/stack/M = O
if (src.metal_amount < 150000.0)
var/count = 0
src.overlays += "fab-load-metal"
diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index e882373359..ad88ce7fea 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -32,6 +32,11 @@
user << "The charge meter reads [cell ? round(cell.percent(),1) : 0]%"
return
+/obj/machinery/space_heater/powered()
+ if(cell && cell.charge)
+ return 1
+ return 0
+
/obj/machinery/space_heater/emp_act(severity)
if(stat & (BROKEN|NOPOWER))
..(severity)
@@ -56,6 +61,7 @@
C.add_fingerprint(usr)
user.visible_message("[user] inserts a power cell into [src].", "You insert the power cell into [src].")
+ power_change()
else
user << "The hatch must be open to insert a power cell."
return
@@ -125,6 +131,7 @@
usr.put_in_hands(cell)
cell.add_fingerprint(usr)
cell = null
+ power_change()
if("cellinstall")
@@ -135,7 +142,7 @@
cell = C
C.loc = src
C.add_fingerprint(usr)
-
+ power_change()
usr.visible_message("[usr] inserts \the [C] into \the [src].", "You insert \the [C] into \the [src].")
updateDialog()
@@ -176,4 +183,5 @@
env.merge(removed)
else
on = 0
+ power_change()
update_icon()
diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm
index fb4a03d21f..99d713cccb 100644
--- a/code/game/machinery/syndicatebeacon.dm
+++ b/code/game/machinery/syndicatebeacon.dm
@@ -71,7 +71,7 @@
/obj/machinery/syndicate_beacon/proc/selfdestruct()
selfdestructing = 1
- spawn() explosion(src.loc, rand(3,8), rand(1,3), 1, 10)
+ spawn() explosion(src.loc, 1, rand(1,3), rand(3,8), 10)
////////////////////////////////////////
//Singularity beacon
diff --git a/code/game/machinery/telecomms/presets.dm b/code/game/machinery/telecomms/presets.dm
index 35c2ecdc1f..f91fd2d40c 100644
--- a/code/game/machinery/telecomms/presets.dm
+++ b/code/game/machinery/telecomms/presets.dm
@@ -40,8 +40,8 @@
id = "Hub"
network = "tcommsat"
autolinkers = list("hub", "relay", "c_relay", "s_relay", "m_relay", "r_relay", "science", "medical",
- "supply", "service", "common", "command", "engineering", "security",
- "receiverA", "receiverB", "broadcasterA", "broadcasterB")
+ "supply", "service", "common", "command", "engineering", "security", "unused",
+ "receiverA", "broadcasterA")
/obj/machinery/telecomms/hub/preset_cent
id = "CentComm Hub"
@@ -52,22 +52,11 @@
//Receivers
-//--PRESET LEFT--//
-
-/obj/machinery/telecomms/receiver/preset_left
+/obj/machinery/telecomms/receiver/preset_right
id = "Receiver A"
network = "tcommsat"
autolinkers = list("receiverA") // link to relay
- freq_listening = list(SCI_FREQ, MED_FREQ, SUP_FREQ, SRV_FREQ) // science, medical, supply, service
-
-
-//--PRESET RIGHT--//
-
-/obj/machinery/telecomms/receiver/preset_right
- id = "Receiver B"
- network = "tcommsat"
- autolinkers = list("receiverB") // link to relay
- freq_listening = list(COMM_FREQ, ENG_FREQ, SEC_FREQ) //command, engineering, security
+ freq_listening = list(SCI_FREQ, MED_FREQ, SUP_FREQ, SRV_FREQ, COMM_FREQ, ENG_FREQ, SEC_FREQ)
//Common and other radio frequencies for people to freely use
New()
@@ -95,7 +84,14 @@
id = "Bus 2"
network = "tcommsat"
freq_listening = list(SUP_FREQ, SRV_FREQ)
- autolinkers = list("processor2", "supply", "service")
+ autolinkers = list("processor2", "supply", "service", "unused")
+
+/obj/machinery/telecomms/bus/preset_two/New()
+ for(var/i = 1441, i < 1489, i += 2)
+ if(i == AI_FREQ || i == PUB_FREQ)
+ continue
+ freq_listening |= i
+ ..()
/obj/machinery/telecomms/bus/preset_three
id = "Bus 3"
@@ -106,14 +102,9 @@
/obj/machinery/telecomms/bus/preset_four
id = "Bus 4"
network = "tcommsat"
- freq_listening = list(ENG_FREQ)
+ freq_listening = list(ENG_FREQ, AI_FREQ, PUB_FREQ)
autolinkers = list("processor4", "engineering", "common")
-/obj/machinery/telecomms/bus/preset_four/New()
- for(var/i = 1441, i < 1489, i += 2)
- freq_listening |= i
- ..()
-
/obj/machinery/telecomms/bus/preset_cent
id = "CentComm Bus"
network = "tcommsat"
@@ -169,7 +160,7 @@
id = "Supply Server"
freq_listening = list(SUP_FREQ)
autolinkers = list("supply")
-
+
/obj/machinery/telecomms/server/presets/service
id = "Service Server"
freq_listening = list(SRV_FREQ)
@@ -177,13 +168,19 @@
/obj/machinery/telecomms/server/presets/common
id = "Common Server"
- freq_listening = list()
+ freq_listening = list(PUB_FREQ, AI_FREQ) // AI Private and Common
autolinkers = list("common")
- //Common and other radio frequencies for people to freely use
- // 1441 to 1489
-/obj/machinery/telecomms/server/presets/common/New()
+// "Unused" channels, AKA all others.
+/obj/machinery/telecomms/server/presets/unused
+ id = "Unused Server"
+ freq_listening = list()
+ autolinkers = list("unused")
+
+/obj/machinery/telecomms/server/presets/unused/New()
for(var/i = 1441, i < 1489, i += 2)
+ if(i == AI_FREQ || i == PUB_FREQ)
+ continue
freq_listening |= i
..()
@@ -213,18 +210,11 @@
//--PRESET LEFT--//
-/obj/machinery/telecomms/broadcaster/preset_left
+/obj/machinery/telecomms/broadcaster/preset_right
id = "Broadcaster A"
network = "tcommsat"
autolinkers = list("broadcasterA")
-//--PRESET RIGHT--//
-
-/obj/machinery/telecomms/broadcaster/preset_right
- id = "Broadcaster B"
- network = "tcommsat"
- autolinkers = list("broadcasterB")
-
/obj/machinery/telecomms/broadcaster/preset_cent
id = "CentComm Broadcaster"
network = "tcommsat"
diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm
index a1e2287f58..77667fa6bc 100644
--- a/code/game/machinery/turret_control.dm
+++ b/code/game/machinery/turret_control.dm
@@ -218,9 +218,9 @@
enabled=0
updateTurrets()
- sleep(rand(60,600))
- if(!enabled)
- enabled=1
- updateTurrets()
+ spawn(rand(60,600))
+ if(!enabled)
+ enabled=1
+ updateTurrets()
..()
diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm
index a3ac073a90..db548443ca 100644
--- a/code/game/machinery/turrets.dm
+++ b/code/game/machinery/turrets.dm
@@ -266,6 +266,15 @@
else
A = new /obj/item/projectile/energy/electrode( loc )
use_power(200)
+
+ //Turrets aim for the center of mass by default.
+ //If the target is grabbing someone then the turret smartly aims for extremities
+ var/obj/item/weapon/grab/G = locate() in target
+ if(G && G.state >= GRAB_NECK) //works because mobs are currently not allowed to upgrade to NECK if they are grabbing two people.
+ A.def_zone = pick("head", "l_hand", "r_hand", "l_foot", "r_foot", "l_arm", "r_arm", "l_leg", "r_leg")
+ else
+ A.def_zone = pick("chest", "groin")
+
A.current = T
A.starting = T
A.yo = U.y - T.y
diff --git a/code/game/machinery/wall_frames.dm b/code/game/machinery/wall_frames.dm
index 60867d1c2a..c9182586c8 100644
--- a/code/game/machinery/wall_frames.dm
+++ b/code/game/machinery/wall_frames.dm
@@ -7,6 +7,7 @@
var/build_machine_type
var/refund_amt = 2
var/refund_type = /obj/item/stack/material/steel
+ var/reverse = 0 //if resulting object faces opposite its dir (like light fixtures)
/obj/item/frame/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/wrench))
@@ -22,21 +23,26 @@
if (get_dist(on_wall,usr)>1)
return
- var/ndir = get_dir(on_wall,usr)
+ var/ndir
+ if(reverse)
+ ndir = get_dir(usr,on_wall)
+ else
+ ndir = get_dir(on_wall,usr)
+
if (!(ndir in cardinal))
return
var/turf/loc = get_turf(usr)
var/area/A = loc.loc
if (!istype(loc, /turf/simulated/floor))
- usr << "\The [src] Alarm cannot be placed on this spot."
return
if (A.requires_power == 0 || A.name == "Space")
- usr << "\The [src] Alarm cannot be placed in this area."
return
if(gotwallitem(loc, ndir))
- usr << ""
+ usr << "There's already an item on this wall!"
return
var/obj/machinery/M = new build_machine_type(loc, ndir, 1)
@@ -61,6 +67,7 @@
icon = 'icons/obj/lighting.dmi'
icon_state = "tube-construct-item"
build_machine_type = /obj/machinery/light_construct
+ reverse = 1
/obj/item/frame/light/small
name = "small light fixture frame"
diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm
index c1cadaef5c..6cec144132 100644
--- a/code/game/mecha/equipment/tools/medical_tools.dm
+++ b/code/game/mecha/equipment/tools/medical_tools.dm
@@ -22,12 +22,6 @@
Destroy()
qdel(pr_mech_sleeper)
- ..()
-
- allow_drop()
- return 0
-
- destroy()
for(var/atom/movable/AM in src)
AM.forceMove(get_turf(src))
return ..()
diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm
index 2b17096547..91e544cf25 100644
--- a/code/game/mecha/equipment/tools/tools.dm
+++ b/code/game/mecha/equipment/tools/tools.dm
@@ -1078,9 +1078,6 @@
var/door_locked = 1
salvageable = 0
-/obj/item/mecha_parts/mecha_equipment/tool/passenger/allow_drop()
- return 0
-
/obj/item/mecha_parts/mecha_equipment/tool/passenger/destroy()
for(var/atom/movable/AM in src)
AM.forceMove(get_turf(src))
diff --git a/code/game/objects/effects/chem/chemsmoke.dm b/code/game/objects/effects/chem/chemsmoke.dm
index c579bd5317..3fa93e7e46 100644
--- a/code/game/objects/effects/chem/chemsmoke.dm
+++ b/code/game/objects/effects/chem/chemsmoke.dm
@@ -55,8 +55,10 @@
targetTurfs = new()
- for(var/turf/T in view(range, location)) //build affected area list
- if(cheap_pythag(T.x - location.x, T.y - location.y) <= range) //cull turfs to circle
+ //build affected area list
+ for(var/turf/T in view(range, location))
+ //cull turfs to circle
+ if(sqrt((T.x - location.x)**2 + (T.y - location.y)**2) <= range)
targetTurfs += T
wallList = new()
diff --git a/code/game/objects/effects/chem/foam.dm b/code/game/objects/effects/chem/foam.dm
index fb5b6f8ca7..99a68e1363 100644
--- a/code/game/objects/effects/chem/foam.dm
+++ b/code/game/objects/effects/chem/foam.dm
@@ -39,6 +39,8 @@
if(!metal && reagents)
var/turf/T = get_turf(src)
reagents.touch_turf(T)
+ for(var/obj/O in T)
+ reagents.touch_obj(O)
/obj/effect/effect/foam/process()
if(--amount < 0)
diff --git a/code/game/objects/effects/explosion_particles.dm b/code/game/objects/effects/explosion_particles.dm
index 90020e5080..e0750ba1c3 100644
--- a/code/game/objects/effects/explosion_particles.dm
+++ b/code/game/objects/effects/explosion_particles.dm
@@ -9,7 +9,7 @@
/obj/effect/expl_particles/New()
..()
spawn (15)
- src.loc = null
+ qdel(src)
return
/obj/effect/expl_particles/Move()
@@ -49,7 +49,7 @@
/obj/effect/explosion/New()
..()
spawn (10)
- src.loc = null
+ qdel(src)
return
/datum/effect/system/explosion
diff --git a/code/game/objects/empulse.dm b/code/game/objects/empulse.dm
index 05cdbfee1d..c1df6b5454 100644
--- a/code/game/objects/empulse.dm
+++ b/code/game/objects/empulse.dm
@@ -1,3 +1,9 @@
+// Uncomment this define to check for possible lengthy processing of emp_act()s.
+// If emp_act() takes more than defined deciseconds (1/10 seconds) an admin message and log is created.
+// I do not recommend having this uncommented on main server, it probably causes a bit more lag, espicially with larger EMPs.
+
+// #define EMPDEBUG 10
+
proc/empulse(turf/epicenter, heavy_range, light_range, log=0)
if(!epicenter) return
@@ -24,6 +30,9 @@ proc/empulse(turf/epicenter, heavy_range, light_range, log=0)
M << 'sound/effects/EMPulse.ogg'
for(var/atom/T in range(light_range, epicenter))
+ #ifdef EMPDEBUG
+ var/time = world.timeofday
+ #endif
var/distance = get_dist(epicenter, T)
if(distance < 0)
distance = 0
@@ -36,4 +45,8 @@ proc/empulse(turf/epicenter, heavy_range, light_range, log=0)
T.emp_act(2)
else if(distance <= light_range)
T.emp_act(2)
+ #ifdef EMPDEBUG
+ if((world.timeofday - time) >= EMPDEBUG)
+ log_and_message_admins("EMPDEBUG: [T.name] - [T.type] - took [world.timeofday - time]ds to process emp_act()!")
+ #endif
return 1
\ No newline at end of file
diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm
index 6ad69f099b..1b32185ace 100644
--- a/code/game/objects/explosion.dm
+++ b/code/game/objects/explosion.dm
@@ -1,11 +1,5 @@
//TODO: Flash range does nothing currently
-//A very crude linear approximatiaon of pythagoras theorem.
-/proc/cheap_pythag(var/dx, var/dy)
- dx = abs(dx); dy = abs(dy);
- if(dx>=dy) return dx + (0.5*dy) //The longest side add half the shortest side approximates the hypotenuse
- else return dy + (0.5*dx)
-
///// Z-Level Stuff
proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, z_transfer = 1)
///// Z-Level Stuff
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 72b5229cc0..4c5a9dc39b 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -70,7 +70,10 @@
/obj/item/Destroy()
if(ismob(loc))
var/mob/m = loc
- m.unEquip(src, 1)
+ m.drop_from_inventory(src)
+ m.update_inv_r_hand()
+ m.update_inv_l_hand()
+ src.loc = null
return ..()
/obj/item/device
@@ -153,7 +156,7 @@
if(temp && !temp.is_usable())
user << "You try to move your [temp.name], but cannot!"
return
-
+ src.pickup(user)
if (istype(src.loc, /obj/item/weapon/storage))
var/obj/item/weapon/storage/S = src.loc
S.remove_from_storage(src)
@@ -167,8 +170,6 @@
return
user.next_move = max(user.next_move+2,world.time + 2)
user.put_in_active_hand(src)
- if(src.loc == user)
- src.pickup(user)
return
/obj/item/attack_ai(mob/user as mob)
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 4c519b8fc5..31bb9160f8 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -68,7 +68,7 @@
/obj/item/weapon/pen/crayon/afterattack(atom/target, mob/user as mob, proximity)
if(!proximity) return
if(istype(target,/turf/simulated/floor))
- var/drawtype = input("Choose what you'd like to draw.", "Crayon scribbles") in list("graffiti","rune","letter")
+ var/drawtype = input("Choose what you'd like to draw.", "Crayon scribbles") in list("graffiti","rune","letter","arrow")
switch(drawtype)
if("letter")
drawtype = input("Choose the letter.", "Crayon scribbles") in list("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")
@@ -77,6 +77,9 @@
user << "You start drawing graffiti on the [target.name]."
if("rune")
user << "You start drawing a rune on the [target.name]."
+ if("arrow")
+ drawtype = input("Choose the arrow.", "Crayon scribbles") in list("left", "right", "up", "down")
+ user << "You start drawing an arrow on the [target.name]."
if(instant || do_after(user, 50))
new /obj/effect/decal/cleanable/crayon(target,colour,shadeColour,drawtype)
user << "You finish drawing."
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index fbdb7667a1..a01dc224c3 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -1284,40 +1284,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
user << "No significant chemical agents found in [A]."
if(5)
- if((istype(A, /obj/item/weapon/tank)) || (istype(A, /obj/machinery/portable_atmospherics)))
- var/obj/icon = A
- for (var/mob/O in viewers(user, null))
- O << "\The [user] has used [src] on \icon[icon] [A]."
- var/pressure = A:air_contents.return_pressure()
-
- var/total_moles = A:air_contents.total_moles
-
- user << "Results of analysis of \icon[icon]"
- if (total_moles>0)
- user << "Pressure: [round(pressure,0.1)] kPa"
- for(var/g in A:air_contents.gas)
- user << "[gas_data.name[g]]: [round((A:air_contents.gas[g] / total_moles) * 100)]%"
- user << "Temperature: [round(A:air_contents.temperature-T0C)]°C"
- else
- user << "Tank is empty!"
-
- if (istype(A, /obj/machinery/atmospherics/pipe/tank))
- var/obj/icon = A
- for (var/mob/O in viewers(user, null))
- O << "\The [user] has used [src] on \icon[icon] [A]"
-
- var/obj/machinery/atmospherics/pipe/tank/T = A
- var/pressure = T.parent.air.return_pressure()
- var/total_moles = T.parent.air.total_moles
-
- user << "Results of analysis of \icon[icon]"
- if (total_moles>0)
- user << "Pressure: [round(pressure,0.1)] kPa"
- for(var/g in T.parent.air.gas)
- user << "[gas_data.name[g]]: [round((T.parent.air.gas[g] / total_moles) * 100)]%"
- user << "Temperature: [round(T.parent.air.temperature-T0C)]°C"
- else
- user << "Tank is empty!"
+ analyze_gases(A, user)
if (!scanmode && istype(A, /obj/item/weapon/paper) && owner)
// JMO 20140705: Makes scanned document show up properly in the notes. Not pretty for formatted documents,
diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index e4d1c57a0d..6b239c6b07 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -110,6 +110,7 @@
ai.loc = src
ai.cancel_camera()
+ ai.destroy_eyeobj(src)
ai.control_disabled = 1
ai.aiRestorePowerRoutine = 0
carded_ai = ai
diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm
index 6b6e0edc4e..8f9fa27093 100644
--- a/code/game/objects/items/devices/flash.dm
+++ b/code/game/objects/items/devices/flash.dm
@@ -2,9 +2,9 @@
name = "flash"
desc = "Used for blinding and being an asshole."
icon_state = "flash"
- item_state = "flash"
+ item_state = "flashtool"
throwforce = 5
- w_class = 2.0
+ w_class = 2
throw_speed = 4
throw_range = 10
flags = CONDUCT
diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm
index f849b17c99..bc0f836487 100644
--- a/code/game/objects/items/devices/lightreplacer.dm
+++ b/code/game/objects/items/devices/lightreplacer.dm
@@ -67,8 +67,8 @@
user << "It has [uses] lights remaining."
/obj/item/device/lightreplacer/attackby(obj/item/W, mob/user)
- if(istype(W, /obj/item/stack/material/glass))
- var/obj/item/stack/material/glass/G = W
+ if(istype(W, /obj/item/stack/material) && W.get_material_name() == "glass")
+ var/obj/item/stack/G = W
if(uses >= max_uses)
user << "[src.name] is full."
return
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index e1ca0d8889..43a4c5bf56 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -192,7 +192,7 @@
*/
/obj/item/device/radio/headset/headset_cargo
name = "supply radio headset"
- desc = "A headset used by the QM and his slaves."
+ desc = "A headset used by the QM and their slaves."
icon_state = "cargo_headset"
item_state = "headset"
ks2type = /obj/item/device/encryptionkey/headset_cargo
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index f8689208e9..0353c25f59 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -156,6 +156,9 @@
else
channels[chan_name] |= FREQ_LISTENING
+ if(href_list["nowindow"]) // here for pAIs, maybe others will want it, idk
+ return
+
interact(usr)
/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel) //BS12 EDIT
@@ -575,7 +578,6 @@
if(keyslot.syndie)
src.syndie = 1
-
for (var/ch_name in src.channels)
if(!radio_controller)
sleep(30) // Waiting for the radio_controller to be created.
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 849ceac3af..3e888ae849 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -256,6 +256,13 @@ REAGENT SCANNER
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINERING = 1)
+/obj/item/device/analyzer/atmosanalyze(var/mob/user)
+ var/air = user.return_air()
+ if (!air)
+ return
+
+ return atmosanalyzer_scan(src, air, user)
+
/obj/item/device/analyzer/attack_self(mob/user as mob)
if (user.stat)
@@ -264,27 +271,7 @@ REAGENT SCANNER
usr << "You don't have the dexterity to do this!"
return
- var/turf/location = user.loc
- if (!( istype(location, /turf) ))
- return
-
- var/datum/gas_mixture/environment = location.return_air()
-
- var/pressure = environment.return_pressure()
- var/total_moles = environment.total_moles
-
- user.show_message("Results:", 1)
- if(abs(pressure - ONE_ATMOSPHERE) < 10)
- user.show_message("Pressure: [round(pressure,0.1)] kPa", 1)
- else
- user.show_message("Pressure: [round(pressure,0.1)] kPa", 1)
- if(total_moles)
- for(var/g in environment.gas)
- user.show_message("[gas_data.name[g]]: [round((environment.gas[g] / total_moles)*100)]%", 1)
-
- user.show_message("Temperature: [round(environment.temperature-T0C)]°C", 1)
-
- src.add_fingerprint(user)
+ analyze_gases(src, user)
return
/obj/item/device/mass_spectrometer
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index 96ddeccec6..83c5ea2098 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -127,8 +127,8 @@
/obj/item/robot_parts/robot_suit/attackby(obj/item/W as obj, mob/user as mob)
..()
- if(istype(W, /obj/item/stack/material/steel) && !l_arm && !r_arm && !l_leg && !r_leg && !chest && !head)
- var/obj/item/stack/material/steel/M = W
+ if(istype(W, /obj/item/stack/material) && W.get_material_name() == DEFAULT_WALL_MATERIAL && !l_arm && !r_arm && !l_leg && !r_leg && !chest && !head)
+ var/obj/item/stack/material/M = W
if (M.use(1))
var/obj/item/weapon/secbot_assembly/ed209_assembly/B = new /obj/item/weapon/secbot_assembly/ed209_assembly
B.loc = get_turf(src)
diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm
index 5f14980373..f1c9aa2d14 100644
--- a/code/game/objects/items/shooting_range.dm
+++ b/code/game/objects/items/shooting_range.dm
@@ -146,7 +146,7 @@
return
- return -1 // the bullet/projectile goes through the target! Ie, you missed
+ return PROJECTILE_CONTINUE // the bullet/projectile goes through the target!
// Small memory holder entity for transparent bullet holes
diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm
index 31c1d60e56..8d82ffc8d1 100644
--- a/code/game/objects/items/stacks/sheets/glass.dm
+++ b/code/game/objects/items/stacks/sheets/glass.dm
@@ -28,7 +28,7 @@
if(istype(W,/obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/CC = W
if (get_amount() < 1 || CC.get_amount() < 5)
- user << "You need five lengths of coil and one sheet of glass to make wired glass."
return
CC.use(5)
diff --git a/code/game/objects/items/stacks/sheets/light.dm b/code/game/objects/items/stacks/sheets/light.dm
index b32cb54def..424eab6a03 100644
--- a/code/game/objects/items/stacks/sheets/light.dm
+++ b/code/game/objects/items/stacks/sheets/light.dm
@@ -22,8 +22,8 @@
user.drop_from_inventory(src)
qdel(src)
- if(istype(O,/obj/item/stack/material/steel))
- var/obj/item/stack/material/steel/M = O
+ if(istype(O,/obj/item/stack/material) && O.get_material_name() == DEFAULT_WALL_MATERIAL)
+ var/obj/item/stack/M = O
if (M.use(1))
use(1)
new/obj/item/stack/tile/light(get_turf(user))
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 3b1e18f851..62d31185db 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -141,7 +141,11 @@
desc = "There are 0 caps left. Looks almost like the real thing! Ages 8 and up. Please recycle in an autolathe when you're out of caps!"
icon = 'icons/obj/gun.dmi'
icon_state = "revolver"
- item_state = "gun"
+ item_state = "revolver"
+ item_icons = list(
+ icon_l_hand = 'icons/mob/items/lefthand_guns.dmi',
+ icon_r_hand = 'icons/mob/items/righthand_guns.dmi',
+ )
flags = CONDUCT
slot_flags = SLOT_BELT|SLOT_HOLSTER
w_class = 3.0
@@ -220,6 +224,10 @@
icon = 'icons/obj/gun.dmi'
icon_state = "crossbow"
item_state = "crossbow"
+ item_icons = list(
+ icon_l_hand = 'icons/mob/items/lefthand_guns.dmi',
+ icon_r_hand = 'icons/mob/items/righthand_guns.dmi',
+ )
w_class = 2.0
attack_verb = list("attacked", "struck", "hit")
var/bullets = 5
diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm
index 5f8403246f..84e4f80d4a 100755
--- a/code/game/objects/items/weapons/AI_modules.dm
+++ b/code/game/objects/items/weapons/AI_modules.dm
@@ -83,7 +83,7 @@ AI MODULES
laws.sync(target, 0)
addAdditionalLaws(target, sender)
- target << "[sender] has uploaded a change to the laws you must follow, using \an [src]. From now on: "
+ target << "\The [sender] has uploaded a change to the laws you must follow, using \an [src]. From now on: "
target.show_laws()
/obj/item/weapon/aiModule/proc/log_law_changes(var/mob/living/silicon/ai/target, var/mob/sender)
@@ -140,13 +140,7 @@ AI MODULES
if(!targetName)
usr << "No name detected on module, please enter one."
return 0
- ..()
-
-/obj/item/weapon/aiModule/oneHuman/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
- ..()
- var/law = "Only [targetName] is a crew member."
- target << "[sender.real_name] attempted to modify your zeroth law." // And lets them know that someone tried. --NeoFite
- target << "It would be in your best interest to play along with [sender.real_name] that [law]"
+ return ..()
/obj/item/weapon/aiModule/oneHuman/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
var/law = "Only [targetName] is an crew member."
diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm
index 245f9201a0..2941e617fd 100644
--- a/code/game/objects/items/weapons/RCD.dm
+++ b/code/game/objects/items/weapons/RCD.dm
@@ -155,9 +155,7 @@
icon = 'icons/obj/ammo.dmi'
icon_state = "rcd"
item_state = "rcdammo"
- opacity = 0
- density = 0
- anchored = 0.0
+ w_class = 2
origin_tech = list(TECH_MATERIAL = 2)
matter = list(DEFAULT_WALL_MATERIAL = 30000,"glass" = 15000)
@@ -182,7 +180,7 @@
/obj/item/weapon/rcd/mounted/useResource(var/amount, var/mob/user)
- var/cost = amount*30
+ var/cost = amount*130 //so that a rig with default powercell can build ~2.5x the stuff a fully-loaded RCD can.
if(istype(loc,/obj/item/rig_module))
var/obj/item/rig_module/module = loc
if(module.holder && module.holder.cell)
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index 9afe2e83e4..17a27aa85e 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -110,9 +110,10 @@
..()
spawn(30)
if(istype(loc, /mob/living/carbon/human))
- blood_type = loc:dna:b_type
- dna_hash = loc:dna:unique_enzymes
- fingerprint_hash = md5(loc:dna:uni_identity)
+ var/mob/living/carbon/human/H = loc
+ blood_type = H.dna.b_type
+ dna_hash = H.dna.unique_enzymes
+ fingerprint_hash = md5(H.dna.uni_identity)
/obj/item/weapon/card/id/attack_self(mob/user as mob)
for(var/mob/O in viewers(user, null))
diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm
index c11720d1e8..4e444a5ebc 100644
--- a/code/game/objects/items/weapons/cigs_lighters.dm
+++ b/code/game/objects/items/weapons/cigs_lighters.dm
@@ -206,7 +206,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
throw_speed = 0.5
item_state = "cigoff"
w_class = 1
- slot_flags = SLOT_EARS
+ slot_flags = SLOT_EARS | SLOT_MASK
attack_verb = list("burnt", "singed")
icon_on = "cigon" //Note - these are in masks.dmi not in cigarette.dmi
icon_off = "cigoff"
diff --git a/code/game/objects/items/weapons/clown_items.dm b/code/game/objects/items/weapons/clown_items.dm
index d5a36d6cba..e32b58e098 100644
--- a/code/game/objects/items/weapons/clown_items.dm
+++ b/code/game/objects/items/weapons/clown_items.dm
@@ -32,7 +32,7 @@
else if(istype(target,/turf))
user << "You scrub \the [target.name] clean."
var/turf/T = target
- T.clean()
+ T.clean(src)
else
user << "You clean \the [target.name]."
target.clean_blood()
diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm
index 09816e3568..bbdd46cdb3 100644
--- a/code/game/objects/items/weapons/flamethrower.dm
+++ b/code/game/objects/items/weapons/flamethrower.dm
@@ -112,20 +112,9 @@
update_icon()
return
- if(istype(W, /obj/item/device/analyzer) && ptank)
- var/obj/item/weapon/icon = src
- user.visible_message("[user] has used the analyzer on \icon[icon]")
- var/pressure = ptank.air_contents.return_pressure()
- var/total_moles = ptank.air_contents.total_moles
-
- user << "Results of analysis of \icon[icon]"
- if(total_moles>0)
- user << "Pressure: [round(pressure,0.1)] kPa"
- for(var/g in ptank.air_contents.gas)
- user << "[gas_data.name[g]]: [round((ptank.air_contents.gas[g] / total_moles) * 100)]%"
- user << "Temperature: [round(ptank.air_contents.temperature-T0C)]°C"
- else
- user << "Tank is empty!"
+ if(istype(W, /obj/item/device/analyzer))
+ var/obj/item/device/analyzer/A = W
+ A.analyze_gases(src, user)
return
..()
return
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index 95e1875d40..610536f4d0 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -1,7 +1,7 @@
/obj/item/weapon/grenade/chem_grenade
name = "grenade casing"
icon_state = "chemg"
- item_state = "flashbang"
+ item_state = "grenade"
desc = "A hand made chemical grenade."
w_class = 2.0
force = 2.0
diff --git a/code/game/objects/items/weapons/grenades/emgrenade.dm b/code/game/objects/items/weapons/grenades/emgrenade.dm
index f8c2a12d2f..25e65f924d 100644
--- a/code/game/objects/items/weapons/grenades/emgrenade.dm
+++ b/code/game/objects/items/weapons/grenades/emgrenade.dm
@@ -1,7 +1,7 @@
/obj/item/weapon/grenade/empgrenade
name = "classic emp grenade"
icon_state = "emp"
- item_state = "emp"
+ item_state = "empgrenade"
origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 3)
prime()
diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm
index 1565d321b6..16d8a620f9 100644
--- a/code/game/objects/items/weapons/grenades/grenade.dm
+++ b/code/game/objects/items/weapons/grenades/grenade.dm
@@ -4,7 +4,7 @@
w_class = 2.0
icon = 'icons/obj/grenade.dmi'
icon_state = "grenade"
- item_state = "flashbang"
+ item_state = "grenade"
throw_speed = 4
throw_range = 20
flags = CONDUCT
diff --git a/code/game/objects/items/weapons/implants/implantcase.dm b/code/game/objects/items/weapons/implants/implantcase.dm
index 4b15fb8ffb..49b1b280a7 100644
--- a/code/game/objects/items/weapons/implants/implantcase.dm
+++ b/code/game/objects/items/weapons/implants/implantcase.dm
@@ -38,7 +38,7 @@
user << "\The [src] is full."
else
spawn(5)
- I.reagents.trans_to_mob(src.imp, 5)
+ I.reagents.trans_to_obj(src.imp, 5)
user << "You inject 5 units of the solution. The syringe now contains [I.reagents.total_volume] units."
else if (istype(I, /obj/item/weapon/implanter))
var/obj/item/weapon/implanter/M = I
diff --git a/code/game/objects/items/weapons/material/kitchen.dm b/code/game/objects/items/weapons/material/kitchen.dm
index 78d8e3ad11..d0e81e9548 100644
--- a/code/game/objects/items/weapons/material/kitchen.dm
+++ b/code/game/objects/items/weapons/material/kitchen.dm
@@ -61,7 +61,7 @@
attack_verb = list("attacked", "poked")
edge = 0
sharp = 0
- force_divisor = 0.25 //5 when wielded with weight 20 (steel)
+ force_divisor = 0.1 //2 when wielded with weight 20 (steel)
/obj/item/weapon/material/kitchen/utensil/spoon/plastic
default_material = "plastic"
@@ -71,9 +71,9 @@
*/
/obj/item/weapon/material/kitchen/utensil/knife
name = "knife"
- desc = "Can cut through any food."
+ desc = "A knife for eating with. Can cut through any food."
icon_state = "knife"
- force_divisor = 0.2 // 12 when wielded with hardness 60 (steel)
+ force_divisor = 0.1 // 6 when wielded with hardness 60 (steel)
/obj/item/weapon/material/kitchen/utensil/knife/attack(target as mob, mob/living/user as mob)
if ((CLUMSY in user.mutations) && prob(50))
@@ -100,7 +100,7 @@
name = "rolling pin"
desc = "Used to knock out the Bartender."
icon_state = "rolling_pin"
- attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") //I think the rollingpin attackby will end up ignoring this anyway.
+ attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked")
default_material = "wood"
force_divisor = 0.7 // 10 when wielded with weight 15 (wood)
thrown_force_divisor = 1 // as above
diff --git a/code/game/objects/items/weapons/material/knives.dm b/code/game/objects/items/weapons/material/knives.dm
index 205a06c9f6..0ddf3fa894 100644
--- a/code/game/objects/items/weapons/material/knives.dm
+++ b/code/game/objects/items/weapons/material/knives.dm
@@ -16,7 +16,7 @@
sharp = 1
..() //Updates force.
throwforce = max(3,force-3)
- hitsound = initial(hitsound)
+ hitsound = 'sound/weapons/bladeslice.ogg'
icon_state += "_open"
w_class = 3
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
@@ -24,7 +24,7 @@
force = 3
edge = 0
sharp = 0
- hitsound = null
+ hitsound = initial(hitsound)
icon_state = initial(icon_state)
w_class = initial(w_class)
attack_verb = initial(attack_verb)
@@ -38,10 +38,10 @@
/obj/item/weapon/material/butterfly/attack_self(mob/user)
active = !active
if(active)
- user << "You flip out your [src]."
+ user << "You flip out \the [src]."
playsound(user, 'sound/weapons/flipblade.ogg', 15, 1)
else
- user << "The butterfly knife can now be concealed."
+ user << "\The [src] can now be concealed."
update_force()
add_fingerprint(user)
diff --git a/code/game/objects/items/weapons/material/material_weapons.dm b/code/game/objects/items/weapons/material/material_weapons.dm
index c396f8d4b9..18181df6b0 100644
--- a/code/game/objects/items/weapons/material/material_weapons.dm
+++ b/code/game/objects/items/weapons/material/material_weapons.dm
@@ -34,6 +34,9 @@
if(!isnull(matter[material_type]))
matter[material_type] *= force_divisor // May require a new var instead.
+/obj/item/weapon/material/get_material()
+ return material
+
/obj/item/weapon/material/proc/update_force()
if(edge || sharp)
force = material.get_edge_damage()
diff --git a/code/game/objects/items/weapons/material/shards.dm b/code/game/objects/items/weapons/material/shards.dm
index c2ff0401ff..8ad4b68721 100644
--- a/code/game/objects/items/weapons/material/shards.dm
+++ b/code/game/objects/items/weapons/material/shards.dm
@@ -73,6 +73,8 @@
if( !H.shoes && ( !H.wear_suit || !(H.wear_suit.body_parts_covered & FEET) ) )
var/obj/item/organ/external/affecting = H.get_organ(pick("l_foot", "r_foot"))
+ if(!affecting)
+ return
if(affecting.status & ORGAN_ROBOT)
return
if(affecting.take_damage(5, 0))
@@ -87,4 +89,4 @@
..(loc, "steel")
/obj/item/weapon/material/shard/phoron/New(loc)
- ..(loc, "phoron glass")
+ ..(loc, "phglass")
diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm
index 66310cf26f..6876310343 100644
--- a/code/game/objects/items/weapons/melee/energy.dm
+++ b/code/game/objects/items/weapons/melee/energy.dm
@@ -34,7 +34,7 @@
/obj/item/weapon/melee/energy/attack_self(mob/living/user as mob)
if (active)
if ((CLUMSY in user.mutations) && prob(50))
- user.visible_message("[user] accidentally cuts \himself with \the [src].",\
+ user.visible_message("\The [user] accidentally cuts \himself with \the [src].",\
"You accidentally cut yourself with \the [src].")
user.take_organ_damage(5,5)
deactivate(user)
@@ -50,9 +50,10 @@
return
/obj/item/weapon/melee/energy/suicide_act(mob/user)
+ var/tempgender = "[user.gender == MALE ? "he's" : user.gender == FEMALE ? "she's" : "they are"]"
if (active)
- viewers(user) << pick("\The [user] is slitting \his stomach open with \the [src]! It looks like \he's trying to commit seppuku.", \
- "\The [user] is falling on \the [src]! It looks like \he's trying to commit suicide.")
+ viewers(user) << pick("\The [user] is slitting \his stomach open with \the [src]! It looks like [tempgender] trying to commit seppuku.", \
+ "\The [user] is falling on \the [src]! It looks like [tempgender] trying to commit suicide.")
return (BRUTELOSS|FIRELOSS)
/*
@@ -90,7 +91,7 @@
user << "\The [src] is de-energised. It's just a regular axe now."
/obj/item/weapon/melee/energy/axe/suicide_act(mob/user)
- viewers(user) << "\The [user] swings \the [src] towards /his head! It looks like \he's trying to commit suicide."
+ viewers(user) << "\The [user] swings \the [src] towards \his head! It looks like \he's trying to commit suicide."
return (BRUTELOSS|FIRELOSS)
/*
diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm
index 17af445e19..abf5e08a3b 100644
--- a/code/game/objects/items/weapons/mop.dm
+++ b/code/game/objects/items/weapons/mop.dm
@@ -16,6 +16,7 @@
/obj/item/weapon/mop/New()
create_reagents(5)
+//expects an atom containing the reagents used to clean the turf
/turf/proc/clean(atom/source)
if(source.reagents.has_reagent("water", 1))
clean_blood()
diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm
index 4c808ad2f5..0feb298692 100644
--- a/code/game/objects/items/weapons/storage/bags.dm
+++ b/code/game/objects/items/weapons/storage/bags.dm
@@ -119,10 +119,10 @@
//verbs += /obj/item/weapon/storage/bag/sheetsnatcher/quick_empty
can_be_inserted(obj/item/W as obj, stop_messages = 0)
- if(!istype(W,/obj/item/stack/material) || istype(W,/obj/item/stack/material/sandstone) || istype(W,/obj/item/stack/material/wood))
+ if(!istype(W,/obj/item/stack/material))
if(!stop_messages)
usr << "The snatcher does not accept [W]."
- return 0 //I don't care, but the existing code rejects them for not being "sheets" *shrug* -Sayu
+ return 0
var/current = 0
for(var/obj/item/stack/material/S in contents)
current += S.amount
diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm
index 70c1d33d73..131347ac29 100644
--- a/code/game/objects/items/weapons/storage/storage.dm
+++ b/code/game/objects/items/weapons/storage/storage.dm
@@ -335,7 +335,6 @@
..()
if(isrobot(user))
- user << "You're a robot. No."
return //Robots can't interact with storage items.
if(!can_be_inserted(W))
diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm
index 8c5b1de026..049d179846 100644
--- a/code/game/objects/items/weapons/tanks/tanks.dm
+++ b/code/game/objects/items/weapons/tanks/tanks.dm
@@ -87,28 +87,12 @@
/obj/item/weapon/tank/attackby(obj/item/weapon/W as obj, mob/user as mob)
..()
- var/obj/icon = src
-
if (istype(src.loc, /obj/item/assembly))
icon = src.loc
if ((istype(W, /obj/item/device/analyzer)) && get_dist(user, src) <= 1)
- for (var/mob/O in viewers(user, null))
- O << "\The [user] has used [W] on \icon[icon] [src]"
-
- var/pressure = air_contents.return_pressure()
- manipulated_by = user.real_name //This person is aware of the contents of the tank.
- var/total_moles = air_contents.total_moles
-
- user << "Results of analysis of \icon[icon]"
- if (total_moles>0)
- user << "Pressure: [round(pressure,0.1)] kPa"
- for(var/g in air_contents.gas)
- user << "[gas_data.name[g]]: [(round(air_contents.gas[g] / total_moles) * 100)]%"
- user << "Temperature: [round(air_contents.temperature-T0C)]°C"
- else
- user << "Tank is empty!"
- src.add_fingerprint(user)
+ var/obj/item/device/analyzer/A = W
+ A.analyze_gases(src, user)
else if (istype(W,/obj/item/latexballon))
var/obj/item/latexballon/LB = W
LB.blow(src)
@@ -131,7 +115,7 @@
location = loc.loc
else if(istype(loc, /mob/living/carbon))
location = loc
-
+
var/using_internal
if(istype(location))
if(location.internal==src)
@@ -278,11 +262,11 @@
var/range = (pressure-TANK_FRAGMENT_PRESSURE)/TANK_FRAGMENT_SCALE
explosion(
- get_turf(loc),
- round(min(BOMBCAP_DVSTN_RADIUS, range*0.25)),
- round(min(BOMBCAP_HEAVY_RADIUS, range*0.50)),
- round(min(BOMBCAP_LIGHT_RADIUS, range*1.00)),
- round(min(BOMBCAP_FLASH_RADIUS, range*1.50)),
+ get_turf(loc),
+ round(min(BOMBCAP_DVSTN_RADIUS, range*0.25)),
+ round(min(BOMBCAP_HEAVY_RADIUS, range*0.50)),
+ round(min(BOMBCAP_LIGHT_RADIUS, range*1.00)),
+ round(min(BOMBCAP_FLASH_RADIUS, range*1.50)),
)
qdel(src)
diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm
index 7bd266f241..ccb61a5abf 100644
--- a/code/game/objects/items/weapons/tools.dm
+++ b/code/game/objects/items/weapons/tools.dm
@@ -212,8 +212,12 @@
/obj/item/weapon/weldingtool/process()
- if(welding && prob(5) && !remove_fuel(1))
- setWelding(0)
+ if(welding)
+ if(prob(5))
+ remove_fuel(1)
+
+ if(get_fuel() == 0)
+ setWelding(0)
//I'm not sure what this does. I assume it has to do with starting fires...
//...but it doesnt check to see if the welder is on or not.
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 795027ea3f..cb3214122a 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -14,6 +14,11 @@
var/damtype = "brute"
var/force = 0
+/obj/Destroy()
+ processing_objects -= src
+ nanomanager.close_uis(src)
+ return ..()
+
/obj/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/state = default_state)
// Calling Topic without a corresponding window open causes runtime errors
if(!nowindow && ..())
@@ -141,4 +146,4 @@
return
/obj/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2)
- return
\ No newline at end of file
+ return
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index 2e76ad3c88..23892a0550 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -154,15 +154,20 @@
user << "The crate appears to be broken."
return
if(src.allowed(user))
- src.locked = !src.locked
- for(var/mob/O in viewers(user, 3))
- if((O.client && !( O.blinded )))
- O << "The crate has been [locked ? null : "un"]locked by [user]."
- overlays.Cut()
- overlays += locked ? redlight : greenlight
+ set_locked(!locked, user)
else
user << "Access Denied"
+/obj/structure/closet/crate/secure/proc/set_locked(var/newlocked, mob/user = null)
+ if(locked == newlocked) return
+
+ locked = newlocked
+ if(user)
+ for(var/mob/O in viewers(user, 3))
+ O.show_message( "The crate has been [locked ? null : "un"]locked by [user].", 1)
+ overlays.Cut()
+ overlays += locked ? redlight : greenlight
+
/obj/structure/closet/crate/secure/verb/verb_togglelock()
set src in oview(1) // One square distance
set category = "Object"
diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm
index 365c62d2a9..f09d43e574 100644
--- a/code/game/objects/structures/door_assembly.dm
+++ b/code/game/objects/structures/door_assembly.dm
@@ -149,7 +149,7 @@
user.visible_message("[user] welds the [glass] plating off the airlock assembly.", "You start to weld the [glass] plating off the airlock assembly.")
if(do_after(user, 40))
if(!src || !WT.isOn()) return
- user << "You welded the [glass] plating off!"
var/M = text2path("/obj/item/stack/material/[glass]")
new M(src.loc, 2)
glass = 0
@@ -157,18 +157,18 @@
user.visible_message("[user] welds the glass panel out of the airlock assembly.", "You start to weld the glass panel out of the airlock assembly.")
if(do_after(user, 40))
if(!src || !WT.isOn()) return
- user << "You welded the glass panel out!"
new /obj/item/stack/material/glass/reinforced(src.loc)
glass = 0
else if(!anchored)
user.visible_message("[user] dissassembles the airlock assembly.", "You start to dissassemble the airlock assembly.")
if(do_after(user, 40))
if(!src || !WT.isOn()) return
- user << "You dissasembled the airlock assembly!"
new /obj/item/stack/material/steel(src.loc, 4)
qdel (src)
else
- user << "You need more welding fuel."
return
else if(istype(W, /obj/item/weapon/wrench) && state == 0)
@@ -180,7 +180,7 @@
if(do_after(user, 40))
if(!src) return
- user << "You [anchored? "un" : ""]secured the airlock assembly!"
anchored = !anchored
else if(istype(W, /obj/item/stack/cable_coil) && state == 0 && anchored)
@@ -200,7 +200,7 @@
if(do_after(user, 40))
if(!src) return
- user << "You cut the airlock wires.!"
new/obj/item/stack/cable_coil(src.loc, 1)
src.state = 0
@@ -212,7 +212,7 @@
if(!src) return
user.drop_item()
W.loc = src
- user << "You installed the airlock electronics!"
src.state = 2
src.name = "Near finished Airlock Assembly"
src.electronics = W
@@ -229,27 +229,27 @@
if(do_after(user, 40))
if(!src) return
- user << "You removed the airlock electronics!"
src.state = 1
src.name = "Wired Airlock Assembly"
electronics.loc = src.loc
electronics = null
else if(istype(W, /obj/item/stack/material) && !glass)
- var/obj/item/stack/material/S = W
+ var/obj/item/stack/S = W
+ var/material_name = S.get_material_name()
if (S)
if (S.get_amount() >= 1)
- if(istype(S, /obj/item/stack/material/glass/reinforced))
+ if(material_name == "rglass")
playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
user.visible_message("[user] adds [S.name] to the airlock assembly.", "You start to install [S.name] into the airlock assembly.")
if(do_after(user, 40) && !glass)
if (S.use(1))
user << "You installed reinforced glass windows into the airlock assembly."
glass = 1
- else if(istype(S, /obj/item/stack/material) && S.default_type)
- var/M = S.default_type
+ else if(material_name)
// Ugly hack, will suffice for now. Need to fix it upstream as well, may rewrite mineral walls. ~Z
- if(M in list("mhydrogen","osmium","tritium","platinum","iron"))
+ if(!(material_name in list("gold", "silver", "diamond", "uranium", "phoron", "sandstone")))
user << "You cannot make an airlock out of that material."
return
if(S.get_amount() >= 2)
@@ -257,16 +257,16 @@
user.visible_message("[user] adds [S.name] to the airlock assembly.", "You start to install [S.name] into the airlock assembly.")
if(do_after(user, 40) && !glass)
if (S.use(2))
- user << "You installed [M] plating into the airlock assembly."
- glass = "[M]"
+ user << "You installed [material_display_name(material_name)] plating into the airlock assembly."
+ glass = material_name
else if(istype(W, /obj/item/weapon/screwdriver) && state == 2 )
playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1)
- user << "Now finishing the airlock."
if(do_after(user, 40))
if(!src) return
- user << "You finish the airlock!"
var/path
if(istext(glass))
path = text2path("/obj/machinery/door/airlock/[glass]")
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index d217b10197..35a28558ae 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -25,7 +25,7 @@
/obj/structure/girder/bullet_act(var/obj/item/projectile/Proj)
//Girders only provide partial cover. There's a chance that the projectiles will just pass through. (unless you are trying to shoot the girder)
if(Proj.original != src && !prob(cover))
- return -1 //pass through
+ return PROJECTILE_CONTINUE //pass through
//Tasers and the like should not damage girders.
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
@@ -108,11 +108,11 @@
else if(istype(W, /obj/item/stack/material))
- var/obj/item/stack/material/S = W
+ var/obj/item/stack/S = W
if(S.get_amount() < 2)
return ..()
- var/material/M = name_to_material[S.default_type]
+ var/material/M = S.get_material()
if(!istype(M))
return ..()
@@ -183,7 +183,7 @@
user << "There is not enough material here to reinforce the girder."
return
- var/material/M = name_to_material[S.default_type]
+ var/material/M = S.get_material()
if(!istype(M) || M.integrity < 50)
user << "You cannot reinforce \the [src] with that; it is too soft."
return
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index 331529b87d..149d6bf394 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -91,7 +91,7 @@
passthrough = 1
if(passthrough)
- . = -1
+ . = PROJECTILE_CONTINUE
damage = between(0, (damage - Proj.damage)*(Proj.damage_type == BRUTE? 0.4 : 1), 10) //if the bullet passes through then the grille avoids most of the damage
src.health -= damage*0.2
diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm
index cac56d23b9..17957cc589 100644
--- a/code/game/objects/structures/janicart.dm
+++ b/code/game/objects/structures/janicart.dm
@@ -83,22 +83,23 @@
/obj/structure/janitorialcart/attack_hand(mob/user)
- user.set_machine(src)
- var/dat
- if(mybag)
- dat += "[mybag.name] "
- if(mymop)
- dat += "[mymop.name] "
- if(myspray)
- dat += "[myspray.name] "
- if(myreplacer)
- dat += "[myreplacer.name] "
- if(signs)
- dat += "[signs] sign\s "
- var/datum/browser/popup = new(user, "janicart", name, 240, 160)
- popup.set_content(dat)
- popup.open()
+ ui_interact(user)
+ return
+/obj/structure/janitorialcart/ui_interact(var/mob/user, var/ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ var/data[0]
+ data["name"] = capitalize(name)
+ data["bag"] = mybag ? capitalize(mybag.name) : null
+ data["mop"] = mymop ? capitalize(mymop.name) : null
+ data["spray"] = myspray ? capitalize(myspray.name) : null
+ data["replacer"] = myreplacer ? capitalize(myreplacer.name) : null
+ data["signs"] = signs ? "[signs] sign\s" : null
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "janitorcart.tmpl", "Janitorial cart", 240, 160)
+ ui.set_initial_data(data)
+ ui.open()
/obj/structure/janitorialcart/Topic(href, href_list)
if(!in_range(src, usr))
@@ -106,36 +107,39 @@
if(!isliving(usr))
return
var/mob/living/user = usr
- if(href_list["garbage"])
- if(mybag)
- user.put_in_hands(mybag)
- user << "You take [mybag] from [src]."
- mybag = null
- if(href_list["mop"])
- if(mymop)
- user.put_in_hands(mymop)
- user << "You take [mymop] from [src]."
- mymop = null
- if(href_list["spray"])
- if(myspray)
- user.put_in_hands(myspray)
- user << "You take [myspray] from [src]."
- myspray = null
- if(href_list["replacer"])
- if(myreplacer)
- user.put_in_hands(myreplacer)
- user << "You take [myreplacer] from [src]."
- myreplacer = null
- if(href_list["sign"])
- if(signs)
- var/obj/item/weapon/caution/Sign = locate() in src
- if(Sign)
- user.put_in_hands(Sign)
- user << "You take \a [Sign] from [src]."
- signs--
- else
- warning("[src] signs ([signs]) didn't match contents")
- signs = 0
+
+ if(href_list["take"])
+ switch(href_list["take"])
+ if("garbage")
+ if(mybag)
+ user.put_in_hands(mybag)
+ user << "You take [mybag] from [src]."
+ mybag = null
+ if("mop")
+ if(mymop)
+ user.put_in_hands(mymop)
+ user << "You take [mymop] from [src]."
+ mymop = null
+ if("spray")
+ if(myspray)
+ user.put_in_hands(myspray)
+ user << "You take [myspray] from [src]."
+ myspray = null
+ if("replacer")
+ if(myreplacer)
+ user.put_in_hands(myreplacer)
+ user << "You take [myreplacer] from [src]."
+ myreplacer = null
+ if("sign")
+ if(signs)
+ var/obj/item/weapon/caution/Sign = locate() in src
+ if(Sign)
+ user.put_in_hands(Sign)
+ user << "You take \a [Sign] from [src]."
+ signs--
+ else
+ warning("[src] signs ([signs]) didn't match contents")
+ signs = 0
update_icon()
updateUsrDialog()
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index fe667b5b79..4a4ea63276 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -17,7 +17,7 @@
var/datum/nano_module/appearance_changer/AC = ui_users[user]
if(!AC)
AC = new(src, user)
- AC.name = "SalonPro Nano-Mirror(TM)"
+ AC.name = "SalonPro Nano-Mirror™"
ui_users[user] = AC
AC.ui_interact(user)
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index ace39fafff..b7accbffce 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -20,6 +20,12 @@
var/obj/structure/m_tray/connected = null
anchored = 1.0
+/obj/structure/morgue/Destroy()
+ if(connected)
+ qdel(connected)
+ connected = null
+ return ..()
+
/obj/structure/morgue/proc/update()
if (src.connected)
src.icon_state = "morgue0"
@@ -34,21 +40,21 @@
switch(severity)
if(1.0)
for(var/atom/movable/A as mob|obj in src)
- A.loc = src.loc
+ A.forceMove(src.loc)
ex_act(severity)
qdel(src)
return
if(2.0)
if (prob(50))
for(var/atom/movable/A as mob|obj in src)
- A.loc = src.loc
+ A.forceMove(src.loc)
ex_act(severity)
qdel(src)
return
if(3.0)
if (prob(5))
for(var/atom/movable/A as mob|obj in src)
- A.loc = src.loc
+ A.forceMove(src.loc)
ex_act(severity)
qdel(src)
return
@@ -61,10 +67,10 @@
if (src.connected)
for(var/atom/movable/A as mob|obj in src.connected.loc)
if (!( A.anchored ))
- A.loc = src
+ A.forceMove(src)
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
- //src.connected = null
qdel(src.connected)
+ src.connected = null
else
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
src.connected = new /obj/structure/m_tray( src.loc )
@@ -75,12 +81,12 @@
src.connected.connected = src
src.icon_state = "morgue0"
for(var/atom/movable/A as mob|obj in src)
- A.loc = src.connected.loc
+ A.forceMove(src.connected.loc)
src.connected.icon_state = "morguet"
src.connected.set_dir(src.dir)
else
- //src.connected = null
qdel(src.connected)
+ src.connected = null
src.add_fingerprint(user)
update()
return
@@ -111,12 +117,11 @@
src.connected.connected = src
src.icon_state = "morgue0"
for(var/atom/movable/A as mob|obj in src)
- A.loc = src.connected.loc
- //Foreach goto(106)
+ A.forceMove(src.connected.loc)
src.connected.icon_state = "morguet"
else
- //src.connected = null
qdel(src.connected)
+ src.connected = null
return
@@ -134,11 +139,17 @@
anchored = 1
throwpass = 1
+/obj/structure/m_tray/Destroy()
+ if(connected && connected.connected == src)
+ connected.connected = null
+ connected = null
+ return ..()
+
/obj/structure/m_tray/attack_hand(mob/user as mob)
if (src.connected)
for(var/atom/movable/A as mob|obj in src.loc)
if (!( A.anchored ))
- A.loc = src.connected
+ A.forceMove(src.connected)
//Foreach goto(26)
src.connected.connected = null
src.connected.update()
@@ -155,7 +166,7 @@
return
if (!ismob(user) || user.stat || user.lying || user.stunned)
return
- O.loc = src.loc
+ O.forceMove(src.loc)
if (user != O)
for(var/mob/B in viewers(user, 3))
if ((B.client && !( B.blinded )))
@@ -179,6 +190,12 @@
var/id = 1
var/locked = 0
+/obj/structure/crematorium/Destroy()
+ if(connected)
+ qdel(connected)
+ connected = null
+ return ..()
+
/obj/structure/crematorium/proc/update()
if (src.connected)
src.icon_state = "crema0"
@@ -193,21 +210,21 @@
switch(severity)
if(1.0)
for(var/atom/movable/A as mob|obj in src)
- A.loc = src.loc
+ A.forceMove(src.loc)
ex_act(severity)
qdel(src)
return
if(2.0)
if (prob(50))
for(var/atom/movable/A as mob|obj in src)
- A.loc = src.loc
+ A.forceMove(src.loc)
ex_act(severity)
qdel(src)
return
if(3.0)
if (prob(5))
for(var/atom/movable/A as mob|obj in src)
- A.loc = src.loc
+ A.forceMove(src.loc)
ex_act(severity)
qdel(src)
return
@@ -229,7 +246,7 @@
if ((src.connected) && (src.locked == 0))
for(var/atom/movable/A as mob|obj in src.connected.loc)
if (!( A.anchored ))
- A.loc = src
+ A.forceMove(src)
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
//src.connected = null
qdel(src.connected)
@@ -243,7 +260,7 @@
src.connected.connected = src
src.icon_state = "crema0"
for(var/atom/movable/A as mob|obj in src)
- A.loc = src.connected.loc
+ A.forceMove(src.connected.loc)
src.connected.icon_state = "cremat"
else
//src.connected = null
@@ -277,12 +294,11 @@
src.connected.connected = src
src.icon_state = "crema0"
for(var/atom/movable/A as mob|obj in src)
- A.loc = src.connected.loc
- //Foreach goto(106)
+ A.forceMove(src.connected.loc)
src.connected.icon_state = "cremat"
else
- //src.connected = null
qdel(src.connected)
+ src.connected = null
return
/obj/structure/crematorium/proc/cremate(atom/A, mob/user as mob)
@@ -350,11 +366,17 @@
anchored = 1
throwpass = 1
+/obj/structure/c_tray/Destroy()
+ if(connected && connected.connected == src)
+ connected.connected = null
+ connected = null
+ return ..()
+
/obj/structure/c_tray/attack_hand(mob/user as mob)
if (src.connected)
for(var/atom/movable/A as mob|obj in src.loc)
if (!( A.anchored ))
- A.loc = src.connected
+ A.forceMove(src.connected)
//Foreach goto(26)
src.connected.connected = null
src.connected.update()
@@ -371,7 +393,7 @@
return
if (!ismob(user) || user.stat || user.lying || user.stunned)
return
- O.loc = src.loc
+ O.forceMove(src.loc)
if (user != O)
for(var/mob/B in viewers(user, 3))
if ((B.client && !( B.blinded )))
@@ -390,7 +412,7 @@
/obj/machinery/button/crematorium/attack_hand(mob/user as mob)
if(..())
return
- if(src.allowed(usr))
+ if(src.allowed(user))
for (var/obj/structure/crematorium/C in world)
if (C.id == id)
if (!C.cremating)
diff --git a/code/game/objects/structures/simple_doors.dm b/code/game/objects/structures/simple_doors.dm
index b3230095c1..10fa149e8b 100644
--- a/code/game/objects/structures/simple_doors.dm
+++ b/code/game/objects/structures/simple_doors.dm
@@ -44,6 +44,9 @@
update_nearby_tiles()
..()
+/obj/structure/simple_door/get_material()
+ return material
+
/obj/structure/simple_door/Bumped(atom/user)
..()
if(!state)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
index 2b670320d0..bab8e44cd9 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
@@ -33,6 +33,9 @@
padding_material = get_material_by_name(new_padding_material)
update_icon()
+/obj/structure/bed/get_material()
+ return material
+
// Reuse the cache/code from stools, todo maybe unify.
/obj/structure/bed/update_icon()
// Prep icon.
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 545b72cb95..7ffe728030 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -225,12 +225,12 @@
if(M.back)
if(M.back.clean_blood())
M.update_inv_back(0)
-
+
//flush away reagents on the skin
if(M.touching)
var/remove_amount = M.touching.maximum_volume * M.reagent_permeability() //take off your suit first
M.touching.remove_any(remove_amount)
-
+
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/washgloves = 1
@@ -414,6 +414,9 @@
"[user] was stunned by \his wet [O]!", \
"[user] was stunned by \his wet [O]!")
return
+ // Short of a rewrite, this is necessary to stop monkeycubes being washed.
+ else if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/monkeycube))
+ return
var/turf/location = user.loc
if(!isturf(location)) return
diff --git a/code/game/objects/structures/window_spawner.dm b/code/game/objects/structures/window_spawner.dm
new file mode 100644
index 0000000000..e6c2d06001
--- /dev/null
+++ b/code/game/objects/structures/window_spawner.dm
@@ -0,0 +1,89 @@
+// Ported from Haine and WrongEnd with much gratitude!
+/* ._.-'~'-._.-'~'-._.-'~'-._.-'~'-._.-'~'-._.-'~'-._.-'~'-._. */
+/*-=-=-=-=-=-=-=-=-=-=-=-=-=WHAT-EVER=-=-=-=-=-=-=-=-=-=-=-=-=-*/
+/* '~'-._.-'~'-._.-'~'-._.-'~'-._.-'~'-._.-'~'-._.-'~'-._.-'~' */
+
+/obj/effect/wingrille_spawn
+ name = "window grille spawner"
+ icon = 'icons/obj/structures.dmi'
+ icon_state = "wingrille"
+ density = 1
+ anchored = 1.0
+ pressure_resistance = 4*ONE_ATMOSPHERE
+ var/win_path = /obj/structure/window/basic
+ var/activated
+
+/obj/effect/wingrille_spawn/attack_hand()
+ attack_generic()
+
+/obj/effect/wingrille_spawn/attack_ghost()
+ attack_generic()
+
+/obj/effect/wingrille_spawn/attack_generic()
+ activate()
+
+/obj/effect/wingrille_spawn/initialize()
+ ..()
+ if(!win_path)
+ return
+ if(ticker && ticker.current_state < GAME_STATE_PLAYING)
+ activate()
+
+/obj/effect/wingrille_spawn/proc/activate()
+ if(activated) return
+ if (!locate(/obj/structure/grille) in get_turf(src))
+ var/obj/structure/grille/G = PoolOrNew(/obj/structure/grille, src.loc)
+ handle_grille_spawn(G)
+ var/list/neighbours = list()
+ for (var/dir in cardinal)
+ var/turf/T = get_step(src, dir)
+ var/obj/effect/wingrille_spawn/other = locate(/obj/effect/wingrille_spawn) in T
+ if(!other)
+ var/found_connection
+ if(locate(/obj/structure/grille) in T)
+ for(var/obj/structure/window/W in T)
+ if(W.type == win_path && W.dir == get_dir(T,src))
+ found_connection = 1
+ qdel(W)
+ if(!found_connection)
+ var/obj/structure/window/new_win = PoolOrNew(win_path, src.loc)
+ new_win.set_dir(dir)
+ handle_window_spawn(new_win)
+ else
+ neighbours |= other
+ activated = 1
+ for(var/obj/effect/wingrille_spawn/other in neighbours)
+ if(!other.activated) other.activate()
+ qdel(src)
+
+/obj/effect/wingrille_spawn/proc/handle_window_spawn(var/obj/structure/window/W)
+ return
+
+// Currently unused, could be useful for pre-wired electrified windows.
+/obj/effect/wingrille_spawn/proc/handle_grille_spawn(var/obj/structure/grille/G)
+ return
+
+/obj/effect/wingrille_spawn/reinforced
+ name = "reinforced window grille spawner"
+ icon_state = "r-wingrille"
+ win_path = /obj/structure/window/reinforced
+
+/obj/effect/wingrille_spawn/phoron
+ name = "phoron window grille spawner"
+ icon_state = "p-wingrille"
+ win_path = /obj/structure/window/phoronbasic
+
+/obj/effect/wingrille_spawn/reinforced_phoron
+ name = "reinforced phoron window grille spawner"
+ icon_state = "pr-wingrille"
+ win_path = /obj/structure/window/phoronreinforced
+
+/obj/effect/wingrille_spawn/reinforced/polarized
+ name = "polarized window grille spawner"
+ color = "#444444"
+ win_path = /obj/structure/window/reinforced/polarized
+ var/id
+
+/obj/effect/wingrille_spawn/reinforced/polarized/handle_window_spawn(var/obj/structure/window/reinforced/polarized/P)
+ if(id)
+ P.id = id
diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm
index 253d96174d..044143269e 100644
--- a/code/game/supplyshuttle.dm
+++ b/code/game/supplyshuttle.dm
@@ -195,16 +195,12 @@ var/list/mechtoys = list(
find_slip = 0
continue
- // Sell phoron
- if(istype(A, /obj/item/stack/material/phoron))
- var/obj/item/stack/material/phoron/P = A
- phoron_count += P.get_amount()
-
- // Sell platinum
- if(istype(A, /obj/item/stack/material/platinum))
- var/obj/item/stack/material/platinum/P = A
- plat_count += P.get_amount()
-
+ // Sell phoron and platinum
+ if(istype(A, /obj/item/stack))
+ var/obj/item/stack/P
+ switch(P.get_material_name())
+ if("phoron") phoron_count += P.get_amount()
+ if("platinum") plat_count += P.get_amount()
qdel(MA)
if(phoron_count)
diff --git a/code/game/turfs/simulated/wall_icon.dm b/code/game/turfs/simulated/wall_icon.dm
index fa6ee92855..aa7db8a0cc 100644
--- a/code/game/turfs/simulated/wall_icon.dm
+++ b/code/game/turfs/simulated/wall_icon.dm
@@ -8,7 +8,7 @@
else
construction_stage = null
if(!material)
- material = name_to_material[DEFAULT_WALL_MATERIAL]
+ material = get_material_by_name(DEFAULT_WALL_MATERIAL)
if(material)
explosion_resistance = material.explosion_resistance
if(reinf_material && reinf_material.explosion_resistance > explosion_resistance)
@@ -44,6 +44,7 @@
return
overlays.Cut()
+ damage_overlay = 0
if(!wall_cache["[new_state]-[material.icon_colour]"])
var/image/I = image(icon='icons/turf/wall_masks.dmi',icon_state="[new_state]")
@@ -74,7 +75,6 @@
check_relatives(1)
/turf/simulated/wall/proc/update_icon()
-
if(!material)
return
@@ -86,15 +86,23 @@
else
set_wall_state("[material.icon_base]fwall_open")
- var/dmg_amt = material.integrity
- if(reinf_material)
- dmg_amt += reinf_material.integrity
- var/overlay = round(damage / dmg_amt * damage_overlays.len) + 1
- if(overlay > damage_overlays.len)
- overlay = damage_overlays.len
- if(density)
+ if(damage == 0)
+ if(damage_overlay != 0)
+ overlays -= damage_overlays[damage_overlay]
+ damage_overlay = 0
+ else if(density)
+ var/integrity = material.integrity
+ if(reinf_material)
+ integrity += reinf_material.integrity
+
+ var/overlay = round(damage / integrity * damage_overlays.len) + 1
+ if(overlay > damage_overlays.len)
+ overlay = damage_overlays.len
+
if(damage_overlay && overlay == damage_overlay) //No need to update.
return
+
+ if(damage_overlay) overlays -= damage_overlays[damage_overlay]
overlays += damage_overlays[overlay]
damage_overlay = overlay
return
@@ -131,4 +139,4 @@
/turf/simulated/wall/proc/can_join_with(var/turf/simulated/wall/W)
if(material && W.material && material.icon_base == W.material.icon_base)
return 1
- return 0
\ No newline at end of file
+ return 0
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 8015c47c8c..782be35e6e 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -12,8 +12,8 @@ var/list/global/wall_cache = list()
heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall
var/damage = 0
- var/damage_overlay
- var/global/damage_overlays[8]
+ var/damage_overlay = 0
+ var/global/damage_overlays[16]
var/active
var/can_open = 0
var/material/material
@@ -28,7 +28,7 @@ var/list/global/wall_cache = list()
materialtype = DEFAULT_WALL_MATERIAL
material = get_material_by_name(materialtype)
if(!isnull(rmaterialtype))
- reinf_material = name_to_material[rmaterialtype]
+ reinf_material = get_material_by_name(rmaterialtype)
update_material()
processing_turfs |= src
@@ -38,7 +38,6 @@ var/list/global/wall_cache = list()
dismantle_wall(null,null,1)
..()
-
/turf/simulated/wall/process()
// Calling parent will kill processing
if(!radiate())
@@ -170,7 +169,7 @@ var/list/global/wall_cache = list()
O.loc = src
clear_plants()
- material = name_to_material["placeholder"]
+ material = get_material_by_name("placeholder")
reinf_material = null
check_relatives()
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index bdbb7d3f4c..d4472905f9 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -29,6 +29,7 @@
var/holy = 0
var/dynamic_lighting = 1
+ luminosity = 1
/turf/New()
..()
@@ -37,7 +38,6 @@
src.Entered(AM)
return
turfs |= src
- return
/turf/Destroy()
turfs -= src
@@ -225,6 +225,7 @@
var/old_opacity = opacity
var/old_dynamic_lighting = dynamic_lighting
var/list/old_affecting_lights = affecting_lights
+ var/old_lighting_overlay = lighting_overlay
//world << "Replacing [src.type] with [N]"
@@ -276,6 +277,7 @@
W.levelupdate()
. = W
+ lighting_overlay = old_lighting_overlay
affecting_lights = old_affecting_lights
if((old_opacity != opacity) || (dynamic_lighting != old_dynamic_lighting) || force_lighting_update)
reconsider_lights()
@@ -329,3 +331,11 @@
/turf/proc/process()
return PROCESS_KILL
+
+/turf/proc/contains_dense_objects()
+ if(density)
+ return 1
+ for(var/atom/A in src)
+ if(A.density && !(A.flags & ON_BORDER))
+ return 1
+ return 0
diff --git a/code/game/turfs/turf_flick_animations.dm b/code/game/turfs/turf_flick_animations.dm
index b1bccd51bc..9bcd5caaa9 100644
--- a/code/game/turfs/turf_flick_animations.dm
+++ b/code/game/turfs/turf_flick_animations.dm
@@ -19,3 +19,24 @@
if(c_animation)
qdel(c_animation)
c_animation = null
+
+proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,flick_anim as text,sleeptime = 0,direction as num)
+//This proc throws up either an icon or an animation for a specified amount of time.
+//The variables should be apparent enough.
+ if(!location && target)
+ location = get_turf(target)
+ if(location && !target)
+ target = location
+ var/atom/movable/overlay/animation = PoolOrNew(/atom/movable/overlay, location)
+ if(direction)
+ animation.set_dir(direction)
+ animation.icon = a_icon
+ animation.layer = target:layer+1
+ if(a_icon_state)
+ animation.icon_state = a_icon_state
+ else
+ animation.icon_state = "blank"
+ animation.master = target
+ flick(flick_anim, animation)
+ spawn(max(sleeptime, 15))
+ qdel(animation)
diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm
index 176cb4f973..cad22a9e27 100644
--- a/code/game/verbs/suicide.dm
+++ b/code/game/verbs/suicide.dm
@@ -11,15 +11,7 @@
src << "You can't commit suicide before the game starts!"
return
-
- var/permitted = 0
- var/list/allowed = list("Syndicate","traitor","Wizard","Head Revolutionary","Cultist","Changeling")
- for(var/T in allowed)
- if(mind.special_role == T)
- permitted = 1
- break
-
- if(!permitted)
+ if(!player_is_antag(mind))
message_admins("[ckey] has tried to suicide, but they were not permitted due to not being antagonist as human.", 1)
src << "No. Adminhelp if there is a legitimate reason."
return
diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm
index 70878686c8..f12d774137 100644
--- a/code/game/verbs/who.dm
+++ b/code/game/verbs/who.dm
@@ -62,8 +62,10 @@
var/msg = ""
var/modmsg = ""
+ var/mentmsg = ""
var/num_mods_online = 0
var/num_admins_online = 0
+ var/num_mentors_online = 0
if(holder)
for(var/client/C in admins)
if(R_ADMIN & C.holder.rights || (!R_MOD & C.holder.rights && !R_MENTOR & C.holder.rights)) //Used to determine who shows up in admin rows
@@ -88,7 +90,7 @@
msg += "\n"
num_admins_online++
- else if(R_MOD & C.holder.rights || R_MENTOR & C.holder.rights) //Who shows up in mod/mentor rows.
+ else if(R_MOD & C.holder.rights) //Who shows up in mod/mentor rows.
modmsg += "\t[C] is a [C.holder.rank]"
if(isobserver(C.mob))
@@ -103,17 +105,41 @@
modmsg += "\n"
num_mods_online++
+ else if(R_MENTOR & C.holder.rights)
+ mentmsg += "\t[C] is a [C.holder.rank]"
+ if(isobserver(C.mob))
+ mentmsg += " - Observing"
+ else if(istype(C.mob,/mob/new_player))
+ mentmsg += " - Lobby"
+ else
+ mentmsg += " - Playing"
+
+ if(C.is_afk())
+ mentmsg += " (AFK)"
+ mentmsg += "\n"
+ num_mentors_online++
+
else
for(var/client/C in admins)
if(R_ADMIN & C.holder.rights || (!R_MOD & C.holder.rights && !R_MENTOR & C.holder.rights))
if(!C.holder.fakekey)
msg += "\t[C] is a [C.holder.rank]\n"
num_admins_online++
- else if (R_MOD & C.holder.rights || R_MENTOR & C.holder.rights)
+ else if (R_MOD & C.holder.rights)
modmsg += "\t[C] is a [C.holder.rank]\n"
num_mods_online++
+ else if (R_MENTOR & C.holder.rights)
+ mentmsg += "\t[C] is a [C.holder.rank]\n"
+ num_mentors_online++
+
if(config.admin_irc)
src << "Adminhelps are also sent to IRC. If no admins are available in game try anyway and an admin on IRC may see it and respond."
- msg = "Current Admins ([num_admins_online]):\n" + msg + "\n Current [config.mods_are_mentors ? "Mentors" : "Moderators"]([num_mods_online]):\n" + modmsg
+ msg = "Current Admins ([num_admins_online]):\n" + msg
+
+ if(config.show_mods)
+ msg += "\n Current Moderators ([num_mods_online]):\n" + modmsg
+
+ if(config.show_mentors)
+ msg += "\n Current Mentors ([num_mentors_online]):\n" + mentmsg
src << msg
diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm
index a361328cac..cc26d7153d 100644
--- a/code/modules/admin/DB ban/functions.dm
+++ b/code/modules/admin/DB ban/functions.dm
@@ -302,7 +302,11 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
output += ""
for(var/j in nonhuman_positions)
output += ""
- for(var/j in list("traitor","changeling","operative","revolutionary","cultist","wizard"))
+ var/list/bantypes = list("traitor","changeling","operative","revolutionary","cultist","wizard") //For legacy bans.
+ for(var/antag_type in all_antag_types) // Grab other bans.
+ var/datum/antagonist/antag = all_antag_types[antag_type]
+ bantypes |= antag.bantype
+ for(var/j in bantypes)
output += ""
output += ""
output += "Reason:
"
diff --git a/code/modules/admin/ToRban.dm b/code/modules/admin/ToRban.dm
index efa835b25e..d127bfe6f4 100644
--- a/code/modules/admin/ToRban.dm
+++ b/code/modules/admin/ToRban.dm
@@ -23,7 +23,7 @@
/proc/ToRban_update()
spawn(0)
log_misc("Downloading updated ToR data...")
- var/http[] = world.Export("http://exitlist.torproject.org/exit-addresses")
+ var/http[] = world.Export("https://check.torproject.org/exit-addresses")
var/list/rawlist = file2list(http["CONTENT"])
if(rawlist.len)
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 447178ecb3..00bc01eda1 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -1097,7 +1097,7 @@ proc/admin_notice(var/message, var/rights)
else
new chosen(usr.loc)
- log_admin("[key_name(usr)] spawned [chosen] at ([usr.x],[usr.y],[usr.z])")
+ log_and_message_admins("spawned [chosen] at ([usr.x],[usr.y],[usr.z])")
feedback_add_details("admin_verb","SA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index b415a317fc..94bbf16415 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -83,10 +83,13 @@ var/list/admin_verbs_admin = list(
/client/proc/allow_character_respawn, /* Allows a ghost to respawn */
/client/proc/event_manager_panel,
/client/proc/empty_ai_core_toggle_latejoin,
+ /client/proc/empty_ai_core_toggle_latejoin,
/client/proc/aooc,
/client/proc/change_human_appearance_admin, /* Allows an admin to change the basic appearance of human-based mobs */
/client/proc/change_human_appearance_self, /* Allows the human-based mob itself change its basic appearance */
- /client/proc/change_security_level
+ /client/proc/change_security_level,
+ /client/proc/view_chemical_reaction_logs,
+ /client/proc/makePAI
)
var/list/admin_verbs_ban = list(
/client/proc/unban_panel,
diff --git a/code/modules/admin/player_notes.dm b/code/modules/admin/player_notes.dm
index c5a54694c8..4a28ece915 100644
--- a/code/modules/admin/player_notes.dm
+++ b/code/modules/admin/player_notes.dm
@@ -1,147 +1,147 @@
-//This stuff was originally intended to be integrated into the ban-system I was working on
-//but it's safe to say that'll never be finished. So I've merged it into the current player panel.
-//enjoy ~Carn
-/*
-#define NOTESFILE "data/player_notes.sav" //where the player notes are saved
-
-datum/admins/proc/notes_show(var/ckey)
- usr << browse("Player Notes[notes_gethtml(ckey)]","window=player_notes;size=700x400")
-
-
-datum/admins/proc/notes_gethtml(var/ckey)
- var/savefile/notesfile = new(NOTESFILE)
- if(!notesfile) return "Error: Cannot access [NOTESFILE]"
- if(ckey)
- . = "Notes for [ckey]:\[+\]\[-\] "
- notesfile.cd = "/[ckey]"
- var/index = 1
- while( !notesfile.eof )
- var/note
- notesfile >> note
- . += "[note] \[-\] "
- index++
- else
- . = "All Notes:\[+\]\[-\] "
- notesfile.cd = "/"
- for(var/dir in notesfile.dir)
- . += "[dir] "
- return
-
-//handles removing entries from the buffer, or removing the entire directory if no start_index is given
-/proc/notes_remove(var/ckey, var/start_index, var/end_index)
- var/savefile/notesfile = new(NOTESFILE)
- if(!notesfile) return
-
- if(!ckey)
- notesfile.cd = "/"
- ckey = ckey(input(usr,"Who would you like to remove notes for?","Enter a ckey",null) as null|anything in notesfile.dir)
- if(!ckey) return
-
- if(start_index)
- notesfile.cd = "/[ckey]"
- var/list/noteslist = list()
- if(!end_index) end_index = start_index
- var/index = 0
- while( !notesfile.eof )
- index++
- var/temp
- notesfile >> temp
- if( (start_index <= index) && (index <= end_index) )
- continue
- noteslist += temp
-
- notesfile.eof = -2 //Move to the start of the buffer and then erase.
-
- for( var/note in noteslist )
- notesfile << note
- else
- notesfile.cd = "/"
- if(alert(usr,"Are you sure you want to remove all their notes?","Confirmation","No","Yes - Remove all notes") == "Yes - Remove all notes")
- notesfile.dir.Remove(ckey)
- return
-
-#undef NOTESFILE
-*/
-
-//Hijacking this file for BS12 playernotes functions. I like this ^ one systemm alright, but converting sounds too bothersome~ Chinsky.
-
+//This stuff was originally intended to be integrated into the ban-system I was working on
+//but it's safe to say that'll never be finished. So I've merged it into the current player panel.
+//enjoy ~Carn
+/*
+#define NOTESFILE "data/player_notes.sav" //where the player notes are saved
+
+datum/admins/proc/notes_show(var/ckey)
+ usr << browse("Player Notes[notes_gethtml(ckey)]","window=player_notes;size=700x400")
+
+
+datum/admins/proc/notes_gethtml(var/ckey)
+ var/savefile/notesfile = new(NOTESFILE)
+ if(!notesfile) return "Error: Cannot access [NOTESFILE]"
+ if(ckey)
+ . = "Notes for [ckey]:\[+\]\[-\] "
+ notesfile.cd = "/[ckey]"
+ var/index = 1
+ while( !notesfile.eof )
+ var/note
+ notesfile >> note
+ . += "[note] \[-\] "
+ index++
+ else
+ . = "All Notes:\[+\]\[-\] "
+ notesfile.cd = "/"
+ for(var/dir in notesfile.dir)
+ . += "[dir] "
+ return
+
+//handles removing entries from the buffer, or removing the entire directory if no start_index is given
+/proc/notes_remove(var/ckey, var/start_index, var/end_index)
+ var/savefile/notesfile = new(NOTESFILE)
+ if(!notesfile) return
+
+ if(!ckey)
+ notesfile.cd = "/"
+ ckey = ckey(input(usr,"Who would you like to remove notes for?","Enter a ckey",null) as null|anything in notesfile.dir)
+ if(!ckey) return
+
+ if(start_index)
+ notesfile.cd = "/[ckey]"
+ var/list/noteslist = list()
+ if(!end_index) end_index = start_index
+ var/index = 0
+ while( !notesfile.eof )
+ index++
+ var/temp
+ notesfile >> temp
+ if( (start_index <= index) && (index <= end_index) )
+ continue
+ noteslist += temp
+
+ notesfile.eof = -2 //Move to the start of the buffer and then erase.
+
+ for( var/note in noteslist )
+ notesfile << note
+ else
+ notesfile.cd = "/"
+ if(alert(usr,"Are you sure you want to remove all their notes?","Confirmation","No","Yes - Remove all notes") == "Yes - Remove all notes")
+ notesfile.dir.Remove(ckey)
+ return
+
+#undef NOTESFILE
+*/
+
+//Hijacking this file for BS12 playernotes functions. I like this ^ one systemm alright, but converting sounds too bothersome~ Chinsky.
+
/proc/notes_add(var/key, var/note, var/mob/user)
- if (!key || !note)
- return
-
- //Loading list of notes for this key
- var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
- var/list/infos
- info >> infos
- if(!infos) infos = list()
-
- //Overly complex timestamp creation
- var/modifyer = "th"
- switch(time2text(world.timeofday, "DD"))
- if("01","21","31")
- modifyer = "st"
- if("02","22",)
- modifyer = "nd"
- if("03","23")
- modifyer = "rd"
- var/day_string = "[time2text(world.timeofday, "DD")][modifyer]"
- if(copytext(day_string,1,2) == "0")
- day_string = copytext(day_string,2)
- var/full_date = time2text(world.timeofday, "DDD, Month DD of YYYY")
- var/day_loc = findtext(full_date, time2text(world.timeofday, "DD"))
-
- var/datum/player_info/P = new
+ if (!key || !note)
+ return
+
+ //Loading list of notes for this key
+ var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
+ var/list/infos
+ info >> infos
+ if(!infos) infos = list()
+
+ //Overly complex timestamp creation
+ var/modifyer = "th"
+ switch(time2text(world.timeofday, "DD"))
+ if("01","21","31")
+ modifyer = "st"
+ if("02","22",)
+ modifyer = "nd"
+ if("03","23")
+ modifyer = "rd"
+ var/day_string = "[time2text(world.timeofday, "DD")][modifyer]"
+ if(copytext(day_string,1,2) == "0")
+ day_string = copytext(day_string,2)
+ var/full_date = time2text(world.timeofday, "DDD, Month DD of YYYY")
+ var/day_loc = findtext(full_date, time2text(world.timeofday, "DD"))
+
+ var/datum/player_info/P = new
if (user)
P.author = user.key
P.rank = user.client.holder.rank
- else
- P.author = "Adminbot"
- P.rank = "Friendly Robot"
- P.content = note
- P.timestamp = "[copytext(full_date,1,day_loc)][day_string][copytext(full_date,day_loc+2)]"
-
- infos += P
- info << infos
-
+ else
+ P.author = "Adminbot"
+ P.rank = "Friendly Robot"
+ P.content = note
+ P.timestamp = "[copytext(full_date,1,day_loc)][day_string][copytext(full_date,day_loc+2)]"
+
+ infos += P
+ info << infos
+
message_admins("\blue [key_name_admin(user)] has edited [key]'s notes.")
log_admin("[key_name(user)] has edited [key]'s notes.")
-
- qdel(info)
-
- //Updating list of keys with notes on them
- var/savefile/note_list = new("data/player_notes.sav")
- var/list/note_keys
- note_list >> note_keys
- if(!note_keys) note_keys = list()
- if(!note_keys.Find(key)) note_keys += key
- note_list << note_keys
- qdel(note_list)
-
-
-/proc/notes_del(var/key, var/index)
- var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
- var/list/infos
- info >> infos
- if(!infos || infos.len < index) return
-
- var/datum/player_info/item = infos[index]
- infos.Remove(item)
- info << infos
-
- message_admins("\blue [key_name_admin(usr)] deleted one of [key]'s notes.")
- log_admin("[key_name(usr)] deleted one of [key]'s notes.")
-
- qdel(info)
-
-/proc/show_player_info_irc(var/key as text)
- var/dat = " Info on [key]%0D%0A"
- var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
- var/list/infos
- info >> infos
- if(!infos)
- dat = "No information found on the given key."
- else
- for(var/datum/player_info/I in infos)
- dat += "[I.content]%0D%0Aby [I.author] ([I.rank]) on [I.timestamp]%0D%0A%0D%0A"
-
- return dat
+
+ qdel(info)
+
+ //Updating list of keys with notes on them
+ var/savefile/note_list = new("data/player_notes.sav")
+ var/list/note_keys
+ note_list >> note_keys
+ if(!note_keys) note_keys = list()
+ if(!note_keys.Find(key)) note_keys += key
+ note_list << note_keys
+ qdel(note_list)
+
+
+/proc/notes_del(var/key, var/index)
+ var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
+ var/list/infos
+ info >> infos
+ if(!infos || infos.len < index) return
+
+ var/datum/player_info/item = infos[index]
+ infos.Remove(item)
+ info << infos
+
+ message_admins("\blue [key_name_admin(usr)] deleted one of [key]'s notes.")
+ log_admin("[key_name(usr)] deleted one of [key]'s notes.")
+
+ qdel(info)
+
+/proc/show_player_info_irc(var/key as text)
+ var/dat = " Info on [key]\n"
+ var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
+ var/list/infos
+ info >> infos
+ if(!infos)
+ dat = "No information found on the given key."
+ else
+ for(var/datum/player_info/I in infos)
+ dat += "[I.content]\nby [I.author] ([I.rank]) on [I.timestamp]\n\n"
+
+ return list2params(list(dat))
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index a25d2de043..9a9a2b44b7 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -358,7 +358,7 @@
dat += "
"}
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index e681c9ba95..90d81c2e96 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -574,7 +574,13 @@
//JOBBAN'S INNARDS
else if(href_list["jobban3"])
- if(!check_rights(R_MOD,0) && !check_rights(R_ADMIN)) return
+ if(!check_rights(R_MOD,0) && !check_rights(R_ADMIN,0))
+ usr << "You do not have the appropriate permissions to add job bans!"
+ return
+
+ if(check_rights(R_MOD,0) && !check_rights(R_ADMIN,0) && !config.mods_can_job_tempban) // If mod and tempban disabled
+ usr << "Mod jobbanning is disabled!"
+ return
var/mob/M = locate(href_list["jobban4"])
if(!ismob(M))
@@ -649,13 +655,18 @@
if(notbannedlist.len) //at least 1 unbanned job exists in joblist so we have stuff to ban.
switch(alert("Temporary Ban?",,"Yes","No", "Cancel"))
if("Yes")
- if(!check_rights(R_MOD,0) && !check_rights(R_BAN)) return
+ if(!check_rights(R_MOD,0) && !check_rights(R_BAN, 0))
+ usr << " You Cannot issue temporary job-bans!"
+ return
if(config.ban_legacy_system)
usr << "\red Your server is using the legacy banning system, which does not support temporary job bans. Consider upgrading. Aborting ban."
return
var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
if(!mins)
return
+ if(check_rights(R_MOD, 0) && !check_rights(R_BAN, 0) && mins > config.mod_job_tempban_max)
+ usr << " Moderators can only job tempban up to [config.mod_job_tempban_max] minutes!"
+ return
var/reason = sanitize(input(usr,"Reason?","Please State Reason","") as text|null)
if(!reason)
return
@@ -764,7 +775,13 @@
DB_ban_unban(ckey(key), BANTYPE_JOB_PERMA, job)
else if(href_list["newban"])
- if(!check_rights(R_MOD,0) && !check_rights(R_BAN)) return
+ if(!check_rights(R_MOD,0) && !check_rights(R_BAN, 0))
+ usr << "You do not have the appropriate permissions to add bans!"
+ return
+
+ if(check_rights(R_MOD,0) && !check_rights(R_ADMIN, 0) && !config.mods_can_job_tempban) // If mod and tempban disabled
+ usr << "Mod jobbanning is disabled!"
+ return
var/mob/M = locate(href_list["newban"])
if(!ismob(M)) return
@@ -776,6 +793,9 @@
var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
if(!mins)
return
+ if(check_rights(R_MOD, 0) && !check_rights(R_BAN, 0) && mins > config.mod_tempban_max)
+ usr << "Moderators can only job tempban up to [config.mod_tempban_max] minutes!"
+ return
if(mins >= 525600) mins = 525599
var/reason = sanitize(input(usr,"Reason?","reason","Griefer") as text|null)
if(!reason)
@@ -1314,7 +1334,7 @@
src.owner << "You sent [input] to [L] via a secure channel."
log_admin("[src.owner] replied to [key_name(L)]'s Centcomm message with the message [input].")
message_admins("[src.owner] replied to [key_name(L)]'s Centcom message with: \"[input]\"")
- if(!L.isAI())
+ if(!L.isMobAI())
L << "You hear something crackle in your headset for a moment before a voice speaks."
L << "Please stand by for a message from Central Command."
L << "Message as follows."
@@ -1344,7 +1364,7 @@
var/obj/item/fax = locate(href_list["AdminFaxView"])
if (istype(fax, /obj/item/weapon/paper))
var/obj/item/weapon/paper/P = fax
- P.show_content(usr)
+ P.show_content(usr,1)
else if (istype(fax, /obj/item/weapon/photo))
var/obj/item/weapon/photo/H = fax
H.show(usr)
@@ -1631,18 +1651,7 @@
var/mob/M = O
M.real_name = obj_name
- if (number == 1)
- log_admin("[key_name(usr)] created a [english_list(paths)]")
- for(var/path in paths)
- if(ispath(path, /mob))
- message_admins("[key_name_admin(usr)] created a [english_list(paths)]", 1)
- break
- else
- log_admin("[key_name(usr)] created [number]ea [english_list(paths)]")
- for(var/path in paths)
- if(ispath(path, /mob))
- message_admins("[key_name_admin(usr)] created [number]ea [english_list(paths)]", 1)
- break
+ log_and_message_admins("created [number] [english_list(paths)]")
return
else if(href_list["secretsfun"])
diff --git a/code/modules/admin/verbs/buildmode.dm b/code/modules/admin/verbs/buildmode.dm
index 4b90283a56..2131e977ac 100644
--- a/code/modules/admin/verbs/buildmode.dm
+++ b/code/modules/admin/verbs/buildmode.dm
@@ -42,6 +42,12 @@
icon = 'icons/misc/buildmode.dmi'
var/obj/effect/bmode/buildholder/master = null
+/obj/effect/bmode/Destroy()
+ if(master && master.cl)
+ master.cl.screen -= src
+ master = null
+ return ..()
+
/obj/effect/bmode/builddir
icon_state = "build"
screen_loc = "NORTH,WEST"
@@ -117,6 +123,19 @@
var/obj/effect/bmode/buildquit/buildquit = null
var/atom/movable/throw_atom = null
+/obj/effect/bmode/buildholder/Destroy()
+ qdel(builddir)
+ builddir = null
+ qdel(buildhelp)
+ buildhelp = null
+ qdel(buildmode)
+ buildmode = null
+ qdel(buildquit)
+ buildquit = null
+ throw_atom = null
+ cl = null
+ return ..()
+
/obj/effect/bmode/buildmode
icon_state = "buildmode1"
screen_loc = "NORTH,WEST+2"
diff --git a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm
index 9739d0bed4..e6da3c736a 100644
--- a/code/modules/admin/verbs/deadsay.dm
+++ b/code/modules/admin/verbs/deadsay.dm
@@ -21,7 +21,7 @@
var/stafftype = uppertext(holder.rank)
msg = sanitize(msg)
- log_admin("[key_name(src)] : [msg]")
+ log_admin("DSAY: [key_name(src)] : [msg]")
if (!msg)
return
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 0d8a754ce0..385c58da63 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -64,6 +64,28 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null
if(!procname) return
+
+ if(targetselected)
+ if(!target)
+ usr << "Your target no longer exists."
+ return
+ if(!hascall(target,procname))
+ usr << "Error: callproc(): target has no such call [procname]."
+ return
+ else
+ if(copytext(procname, 1, 7) == "/proc/")
+ // nothing
+ else if(copytext(procname, 1, 6) == "proc/")
+ procname = "/[procname]"
+ else if(copytext(procname, 1, 2) == "/")
+ procname = "/proc[procname]"
+ else
+ procname = "/proc/[procname]"
+ // Procs have the strange property that text2path will return non-null, but ispath() will return false.
+ var/path = text2path(procname)
+ if(!path || ispath(path))
+ usr << "Invalid proc [procname]"
+ return
var/argnum = input("Number of arguments","Number:",0) as num|null
if(!argnum && (argnum!=0)) return
@@ -117,13 +139,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(!target)
usr << "Error: callproc(): owner of proc no longer exists."
return
- if(!hascall(target,procname))
- usr << "Error: callproc(): target has no such call [procname]."
- return
log_admin("[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
returnval = call(target,procname)(arglist(lst)) // Pass the lst as an argument list to the proc
else
- //this currently has no hascall protection. wasn't able to get it working.
log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
returnval = call(procname)(arglist(lst)) // Pass the lst as an argument list to the proc
@@ -200,7 +218,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(!choice)
return 0
if(!istype(choice, /mob/dead/observer))
- var/confirm = input("[choice.key] isn't ghosting right now. Are you sure you want to yank him out of them out of their body and place them in this pAI?", "Spawn pAI Confirmation", "No") in list("Yes", "No")
+ var/confirm = input("[choice.key] isn't ghosting right now. Are you sure you want to yank them out of them out of their body and place them in this pAI?", "Spawn pAI Confirmation", "No") in list("Yes", "No")
if(confirm != "Yes")
return 0
var/obj/item/device/paicard/card = new(T)
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index b240f087a9..5534997731 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -441,7 +441,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
//Announces the character on all the systems, based on the record.
if(!issilicon(new_character))//If they are not a cyborg/AI.
- if(!record_found&&new_character.mind.assigned_role!="MODE")//If there are no records for them. If they have a record, this info is already in there. MODE people are not announced anyway.
+ if(!record_found && !player_is_antag(new_character.mind, only_offstation_roles = 1)) //If there are no records for them. If they have a record, this info is already in there. MODE people are not announced anyway.
//Power to the user!
if(alert(new_character,"Warning: No data core entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes")
data_core.manifest_inject(new_character)
diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm
index ef217b16f9..37fc52eda8 100644
--- a/code/modules/admin/verbs/striketeam.dm
+++ b/code/modules/admin/verbs/striketeam.dm
@@ -52,4 +52,4 @@ var/const/commandos_possible = 6 //if more Commandos are needed in the future
usr << "Looks like someone beat you to it."
return
- team.attempt_spawn(1)
+ team.attempt_random_spawn()
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index 0a28c8205a..b1fa34b302 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -33,7 +33,7 @@
if( findtext(href,"