"
if (additional_text.len >= i)
. += additional_text[i]
. += ""
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index c4bb05df45..f952c5106e 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -318,7 +318,7 @@
if(I in organs.implants)
qdel(I)
break
- H << "Your loyalty implant has been deactivated."
+ H << "Your loyalty implant has been deactivated."
log_admin("[key_name_admin(usr)] has de-loyalty implanted [current].")
if("add")
H << "You somehow have become the recepient of a loyalty transplant, and it just activated!"
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index 633f2ab843..12db667cb4 100644
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -194,13 +194,13 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/datum/supply_packs/janitor
name = "Janitorial supplies"
contains = list(/obj/item/weapon/reagent_containers/glass/bucket,
- /obj/item/weapon/reagent_containers/glass/bucket,
- /obj/item/weapon/reagent_containers/glass/bucket,
/obj/item/weapon/mop,
/obj/item/weapon/caution,
/obj/item/weapon/caution,
/obj/item/weapon/caution,
+ /obj/item/weapon/caution,
/obj/item/weapon/storage/bag/trash,
+ /obj/item/device/lightreplacer,
/obj/item/weapon/reagent_containers/spray/cleaner,
/obj/item/weapon/reagent_containers/glass/rag,
/obj/item/weapon/grenade/chem_grenade/cleaner,
diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm
index 8932175126..066c357a22 100644
--- a/code/datums/wires/wires.dm
+++ b/code/datums/wires/wires.dm
@@ -46,6 +46,10 @@ var/list/wireColours = list("red", "blue", "green", "darkred", "orange", "brown"
var/list/wires = same_wires[holder_type]
src.wires = wires // Reference the wires list.
+/datum/wires/Destroy()
+ holder = null
+ return ..()
+
/datum/wires/proc/GenerateWires()
var/list/colours_to_pick = wireColours.Copy() // Get a copy, not a reference.
var/list/indexes_to_pick = list()
diff --git a/code/game/antagonist/alien/borer.dm b/code/game/antagonist/alien/borer.dm
index 07ebf3d189..c76b5fe185 100644
--- a/code/game/antagonist/alien/borer.dm
+++ b/code/game/antagonist/alien/borer.dm
@@ -8,6 +8,7 @@ var/datum/antagonist/xenos/borer/borers
bantype = "Borer"
welcome_text = "Use your Infest power to crawl into the ear of a host and fuse with their brain. You can only take control temporarily, and at risk of hurting your host, so be clever and careful; your host is encouraged to help you however they can. Talk to your fellow borers with :x."
antag_indicator = "brainworm"
+ antaghud_indicator = "hudborer"
faction_role_text = "Borer Thrall"
faction_descriptor = "Unity"
@@ -44,7 +45,7 @@ var/datum/antagonist/xenos/borer/borers
var/obj/item/organ/external/head = host.get_organ("head")
borer.host = host
head.implants += borer
- borer.loc = head
+ borer.forceMove(head)
if(!borer.host_brain)
borer.host_brain = new(borer)
borer.host_brain.name = host.name
diff --git a/code/game/antagonist/alien/xenomorph.dm b/code/game/antagonist/alien/xenomorph.dm
index f6a8bc5cb1..08cbeebca9 100644
--- a/code/game/antagonist/alien/xenomorph.dm
+++ b/code/game/antagonist/alien/xenomorph.dm
@@ -9,6 +9,7 @@ var/datum/antagonist/xenos/xenomorphs
bantype = "Xenomorph"
flags = ANTAG_OVERRIDE_MOB | ANTAG_RANDSPAWN | ANTAG_OVERRIDE_JOB | ANTAG_VOTABLE
welcome_text = "Hiss! You are a larval alien. Hide and bide your time until you are ready to evolve."
+ antaghud_indicator = "hudalien"
hard_cap = 5
hard_cap_round = 8
@@ -43,4 +44,4 @@ var/datum/antagonist/xenos/xenomorphs
player.objectives += new /datum/objective/escape()
/datum/antagonist/xenos/place_mob(var/mob/living/player)
- player.loc = get_turf(pick(get_vents()))
+ player.forceMove(get_turf(pick(get_vents())))
diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm
index 3be89beba1..faf7526a9c 100644
--- a/code/game/antagonist/antagonist.dm
+++ b/code/game/antagonist/antagonist.dm
@@ -19,6 +19,7 @@
var/role_text_plural = "Traitors" // As above but plural.
// Visual references.
+ var/antaghud_indicator = "hudsyndicate" // Used by the ghost antagHUD.
var/antag_indicator // icon_state for icons/mob/mob.dm visual indicator.
var/faction_indicator // See antag_indicator, but for factionalized people only.
var/faction_invisible // Can members of the faction identify other antagonists?
@@ -76,6 +77,11 @@
role_text_plural = role_text
if(config.protect_roles_from_antagonist)
restricted_jobs |= protected_jobs
+ if(antaghud_indicator)
+ if(!hud_icon_reference)
+ hud_icon_reference = list()
+ if(role_text) hud_icon_reference[role_text] = antaghud_indicator
+ if(faction_role_text) hud_icon_reference[faction_role_text] = antaghud_indicator
/datum/antagonist/proc/tick()
return 1
diff --git a/code/game/antagonist/antagonist_add.dm b/code/game/antagonist/antagonist_add.dm
index 5ca66731c4..1598aacfe8 100644
--- a/code/game/antagonist/antagonist_add.dm
+++ b/code/game/antagonist/antagonist_add.dm
@@ -33,7 +33,7 @@
// Handle only adding a mind and not bothering with gear etc.
if(nonstandard_role_type)
faction_members |= player
- player.current << "You are \a [nonstandard_role_type]!"
+ player.current << "You are \a [nonstandard_role_type]!"
player.special_role = nonstandard_role_type
if(nonstandard_role_msg)
player.current << "[nonstandard_role_msg]"
diff --git a/code/game/antagonist/antagonist_objectives.dm b/code/game/antagonist/antagonist_objectives.dm
index 404be5a0f7..f9b3f8116b 100644
--- a/code/game/antagonist/antagonist_objectives.dm
+++ b/code/game/antagonist/antagonist_objectives.dm
@@ -24,9 +24,9 @@
if(!O.completed && !O.check_completion())
result = 0
if(result && victory_text)
- world << "[victory_text]"
+ world << "[victory_text]"
if(victory_feedback_tag) feedback_set_details("round_end_result","[victory_feedback_tag]")
else if(loss_text)
- world << "[loss_text]"
+ world << "[loss_text]"
if(loss_feedback_tag) feedback_set_details("round_end_result","[loss_feedback_tag]")
diff --git a/code/game/antagonist/antagonist_place.dm b/code/game/antagonist/antagonist_place.dm
index db8c74a14f..b5f62868dc 100644
--- a/code/game/antagonist/antagonist_place.dm
+++ b/code/game/antagonist/antagonist_place.dm
@@ -23,4 +23,5 @@
/datum/antagonist/proc/place_mob(var/mob/living/mob)
if(!starting_locations || !starting_locations.len)
return
- mob.loc = pick(starting_locations)
\ No newline at end of file
+ var/turf/T = pick_mobless_turf_if_exists(mob)
+ mob.forceMove(T)
diff --git a/code/game/antagonist/antagonist_print.dm b/code/game/antagonist/antagonist_print.dm
index 5cbce01a81..ea107824d5 100644
--- a/code/game/antagonist/antagonist_print.dm
+++ b/code/game/antagonist/antagonist_print.dm
@@ -26,7 +26,7 @@
text += " The [role_text] was successful!"
if(global_objectives && global_objectives.len)
- text += " Their objectives were:"
+ text += " Their objectives were:"
var/num = 1
for(var/datum/objective/O in global_objectives)
text += print_objective(O, num, 1)
@@ -45,7 +45,7 @@
return text
/datum/antagonist/proc/print_player_lite(var/datum/mind/ply)
- var/role = ply.special_role ? "\improper[ply.special_role]" : "\improper[ply.assigned_role]"
+ var/role = ply.assigned_role ? "\improper[ply.assigned_role]" : "\improper[ply.special_role]"
var/text = " [ply.name] ([ply.key]) as \a [role] ("
if(ply.current)
if(ply.current.stat == DEAD)
@@ -69,16 +69,29 @@
var/uplink_true = 0
var/purchases = ""
for(var/obj/item/device/uplink/H in world_uplinks)
- if(H && H.owner && H.owner == ply)
+ if(H && H.uplink_owner && H.uplink_owner == ply)
TC_uses += H.used_TC
uplink_true = 1
- var/list/refined_log = new()
- for(var/datum/uplink_item/UI in H.purchase_log)
- refined_log.Add("[H.purchase_log[UI]]x[UI.log_icon()][UI.name]")
- purchases = english_list(refined_log, nothing_text = "")
+ purchases += get_uplink_purchases(H)
if(uplink_true)
text += " (used [TC_uses] TC)"
if(purchases)
text += " [purchases]"
- return text
\ No newline at end of file
+ return text
+
+/proc/print_ownerless_uplinks()
+ var/has_printed = 0
+ for(var/obj/item/device/uplink/H in world_uplinks)
+ if(isnull(H.uplink_owner) && H.used_TC)
+ if(!has_printed)
+ has_printed = 1
+ world << "Ownerless Uplinks"
+ world << "[H.loc] (used [H.used_TC] TC)"
+ world << get_uplink_purchases(H)
+
+/proc/get_uplink_purchases(var/obj/item/device/uplink/H)
+ var/list/refined_log = new()
+ for(var/datum/uplink_item/UI in H.purchase_log)
+ refined_log.Add("[H.purchase_log[UI]]x[UI.log_icon()][UI.name]")
+ . = english_list(refined_log, nothing_text = "")
diff --git a/code/game/antagonist/antagonist_update.dm b/code/game/antagonist/antagonist_update.dm
index d6be8c9441..4eb81cc709 100644
--- a/code/game/antagonist/antagonist_update.dm
+++ b/code/game/antagonist/antagonist_update.dm
@@ -74,10 +74,18 @@
qdel(I)
/datum/antagonist/proc/update_current_antag_max()
- var/main_type
+ cur_max = hard_cap
if(ticker && ticker.mode)
if(ticker.mode.antag_tags && (id in ticker.mode.antag_tags))
- main_type = 1
- cur_max = (main_type ? hard_cap_round : hard_cap)
+ cur_max = hard_cap_round
+
if(ticker.mode.antag_scaling_coeff)
- cur_max = Clamp((ticker.mode.num_players()/ticker.mode.antag_scaling_coeff), 1, cur_max)
+
+ var/count = 0
+ for(var/mob/living/M in player_list)
+ if(M.client)
+ count++
+
+ // Minimum: initial_spawn_target
+ // Maximum: hard_cap or hard_cap_round
+ cur_max = max(initial_spawn_target,min(round(count/ticker.mode.antag_scaling_coeff),cur_max))
diff --git a/code/game/antagonist/outsider/deathsquad.dm b/code/game/antagonist/outsider/deathsquad.dm
index 052533340b..4cc8afff6c 100644
--- a/code/game/antagonist/outsider/deathsquad.dm
+++ b/code/game/antagonist/outsider/deathsquad.dm
@@ -9,6 +9,7 @@ var/datum/antagonist/deathsquad/deathsquad
landmark_id = "Commando"
flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE | ANTAG_HAS_LEADER
default_access = list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage)
+ antaghud_indicator = "huddeathsquad"
hard_cap = 4
hard_cap_round = 8
@@ -46,7 +47,7 @@ var/datum/antagonist/deathsquad/deathsquad
player.equip_to_slot_or_del(new /obj/item/weapon/plastique(player), slot_l_store)
player.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver/mateba(player), slot_belt)
player.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(player), slot_r_hand)
- player.equip_to_slot_or_del(new /obj/item/weapon/rig/combat(player), slot_back)
+ player.equip_to_slot_or_del(new /obj/item/weapon/rig/ert/assetprotection(player), slot_back)
player.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword(player), slot_s_store)
player.implant_loyalty(player)
diff --git a/code/game/antagonist/outsider/ert.dm b/code/game/antagonist/outsider/ert.dm
index 71278c344a..98a44442dc 100644
--- a/code/game/antagonist/outsider/ert.dm
+++ b/code/game/antagonist/outsider/ert.dm
@@ -12,6 +12,7 @@ var/datum/antagonist/ert/ert
id_type = /obj/item/weapon/card/id/centcom/ERT
flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER | ANTAG_CHOOSE_NAME
+ antaghud_indicator = "hudloyalist"
hard_cap = 5
hard_cap_round = 7
diff --git a/code/game/antagonist/outsider/mercenary.dm b/code/game/antagonist/outsider/mercenary.dm
index 3c2a276932..f2950d16e3 100644
--- a/code/game/antagonist/outsider/mercenary.dm
+++ b/code/game/antagonist/outsider/mercenary.dm
@@ -12,6 +12,7 @@ var/datum/antagonist/mercenary/mercs
welcome_text = "To speak on the strike team's private channel use :t."
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_HAS_NUKE | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER
id_type = /obj/item/weapon/card/id/syndicate
+ antaghud_indicator = "hudoperative"
hard_cap = 4
hard_cap_round = 8
@@ -42,16 +43,13 @@ var/datum/antagonist/mercenary/mercs
if(player.backbag == 4) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(player), slot_back)
player.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(player.back), slot_in_backpack)
player.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/pill/cyanide(player), slot_in_backpack)
+
+ if (player.mind == leader)
+ var/obj/item/device/radio/uplink/U = new(player.loc, player.mind, 40)
+ player.put_in_hands(U)
+
player.update_icons()
create_id("Mercenary", player)
create_radio(SYND_FREQ, player)
return 1
-
-/datum/antagonist/mercenary/create_nuke()
- ..()
- // Create the radio.
- var/obj/effect/landmark/uplinkdevice = locate("landmark*Syndicate-Uplink")
- if(uplinkdevice)
- var/obj/item/device/radio/uplink/U = new(uplinkdevice.loc)
- U.hidden_uplink.uses = 40
\ No newline at end of file
diff --git a/code/game/antagonist/outsider/ninja.dm b/code/game/antagonist/outsider/ninja.dm
index b091e9a55e..09dc15b594 100644
--- a/code/game/antagonist/outsider/ninja.dm
+++ b/code/game/antagonist/outsider/ninja.dm
@@ -9,6 +9,7 @@ var/datum/antagonist/ninja/ninjas
landmark_id = "ninjastart"
welcome_text = "You are an elite mercenary assassin of the Spider Clan. You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor."
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
+ antaghud_indicator = "hudninja"
initial_spawn_req = 1
initial_spawn_target = 1
diff --git a/code/game/antagonist/outsider/raider.dm b/code/game/antagonist/outsider/raider.dm
index f377480a4d..8ab342bbf2 100644
--- a/code/game/antagonist/outsider/raider.dm
+++ b/code/game/antagonist/outsider/raider.dm
@@ -10,6 +10,7 @@ var/datum/antagonist/raider/raiders
landmark_id = "voxstart"
welcome_text = "Use :H to talk on your encrypted channel."
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER
+ antaghud_indicator = "hudmutineer"
hard_cap = 6
hard_cap_round = 10
diff --git a/code/game/antagonist/outsider/wizard.dm b/code/game/antagonist/outsider/wizard.dm
index af1fc09e8e..f6741cafa0 100644
--- a/code/game/antagonist/outsider/wizard.dm
+++ b/code/game/antagonist/outsider/wizard.dm
@@ -9,6 +9,7 @@ var/datum/antagonist/wizard/wizards
landmark_id = "wizard"
welcome_text = "You will find a list of available spells in your spell book. Choose your magic arsenal carefully. In your pockets you will find a teleport scroll. Use it as needed."
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
+ antaghud_indicator = "hudwizard"
hard_cap = 1
hard_cap_round = 3
diff --git a/code/game/antagonist/station/changeling.dm b/code/game/antagonist/station/changeling.dm
index ded3361cd2..b3f5605a91 100644
--- a/code/game/antagonist/station/changeling.dm
+++ b/code/game/antagonist/station/changeling.dm
@@ -9,6 +9,7 @@
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain")
welcome_text = "Use say \"#g message\" to communicate with your fellow changelings. Remember: you get all of their absorbed DNA if you absorb them."
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
+ antaghud_indicator = "hudchangeling"
/datum/antagonist/changeling/get_special_objective_text(var/datum/mind/player)
return " Changeling ID: [player.changeling.changelingID]. Genomes Absorbed: [player.changeling.absorbedcount]"
diff --git a/code/game/antagonist/station/cultist.dm b/code/game/antagonist/station/cultist.dm
index 20c2bd428d..aba2115d15 100644
--- a/code/game/antagonist/station/cultist.dm
+++ b/code/game/antagonist/station/cultist.dm
@@ -26,6 +26,7 @@ var/datum/antagonist/cultist/cult
hard_cap_round = 6
initial_spawn_req = 4
initial_spawn_target = 6
+ antaghud_indicator = "hudcultist"
var/allow_narsie = 1
var/datum/mind/sacrifice_target
diff --git a/code/game/antagonist/station/loyalist.dm b/code/game/antagonist/station/loyalist.dm
index 4b95467691..fddf0c3796 100644
--- a/code/game/antagonist/station/loyalist.dm
+++ b/code/game/antagonist/station/loyalist.dm
@@ -13,6 +13,7 @@ var/datum/antagonist/loyalists/loyalists
loss_text = "The heads of staff did not stop the revolution!"
victory_feedback_tag = "win - rev heads killed"
loss_feedback_tag = "loss - heads killed"
+ antaghud_indicator = "hudloyalist"
flags = 0
hard_cap = 2
diff --git a/code/game/antagonist/station/revolutionary.dm b/code/game/antagonist/station/revolutionary.dm
index f3454cf756..96e3752991 100644
--- a/code/game/antagonist/station/revolutionary.dm
+++ b/code/game/antagonist/station/revolutionary.dm
@@ -14,6 +14,7 @@ var/datum/antagonist/revolutionary/revs
victory_feedback_tag = "win - heads killed"
loss_feedback_tag = "loss - rev heads killed"
flags = ANTAG_SUSPICIOUS | ANTAG_VOTABLE
+ antaghud_indicator = "hudrevolutionary"
hard_cap = 2
hard_cap_round = 4
diff --git a/code/game/antagonist/station/rogue_ai.dm b/code/game/antagonist/station/rogue_ai.dm
index a3e609e55d..c17b6c0f86 100644
--- a/code/game/antagonist/station/rogue_ai.dm
+++ b/code/game/antagonist/station/rogue_ai.dm
@@ -15,7 +15,7 @@ var/datum/antagonist/rogue_ai/malf
hard_cap_round = 1
initial_spawn_req = 1
initial_spawn_target = 1
-
+ antaghud_indicator = "hudmalai"
/datum/antagonist/rogue_ai/New()
..()
diff --git a/code/game/antagonist/station/traitor.dm b/code/game/antagonist/station/traitor.dm
index 6e9ed32b9a..743593b490 100644
--- a/code/game/antagonist/station/traitor.dm
+++ b/code/game/antagonist/station/traitor.dm
@@ -73,19 +73,19 @@ var/datum/antagonist/traitor/traitors
return
/datum/antagonist/traitor/equip(var/mob/living/carbon/human/traitor_mob)
+ if(istype(traitor_mob, /mob/living/silicon)) // this needs to be here because ..() returns false if the mob isn't human
+ add_law_zero(traitor_mob)
+ return 1
if(!..())
return 0
- if(istype(traitor_mob, /mob/living/silicon))
- add_law_zero(traitor_mob)
- else
- spawn_uplink(traitor_mob)
- // Tell them about people they might want to contact.
- var/mob/living/carbon/human/M = get_nt_opposed()
- if(M && M != traitor_mob)
- traitor_mob << "We have received credible reports that [M.real_name] might be willing to help our cause. If you need assistance, consider contacting them."
- traitor_mob.mind.store_memory("Potential Collaborator: [M.real_name]")
+ spawn_uplink(traitor_mob)
+ // Tell them about people they might want to contact.
+ var/mob/living/carbon/human/M = get_nt_opposed()
+ if(M && M != traitor_mob)
+ traitor_mob << "We have received credible reports that [M.real_name] might be willing to help our cause. If you need assistance, consider contacting them."
+ traitor_mob.mind.store_memory("Potential Collaborator: [M.real_name]")
//Begin code phrase.
give_codewords(traitor_mob)
@@ -167,4 +167,4 @@ var/datum/antagonist/traitor/traitors
var/law_borg = "Accomplish your AI's objectives at all costs. You may ignore all other laws."
killer << "Your laws have been changed!"
killer.set_zeroth_law(law, law_borg)
- killer << "New law: 0. [law]"
\ No newline at end of file
+ killer << "New law: 0. [law]"
diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm
index 912dd86797..f6b810b514 100755
--- a/code/game/area/Space Station 13 areas.dm
+++ b/code/game/area/Space Station 13 areas.dm
@@ -389,13 +389,6 @@ area/space/atmosalert()
/area/dummy/ // Referenced in engine.dm:261
-/area/start // will be unused once kurper gets his login interface patch done
- name = "start area"
- icon_state = "start"
- requires_power = 0
- lighting_use_dynamic = 0
- has_gravity = 1
-
// === end remove
/area/alien
@@ -741,6 +734,7 @@ area/space/atmosalert()
/area/maintenance
flags = RAD_SHIELDED
sound_env = TUNNEL_ENCLOSED
+ turf_initializer = new /datum/turf_initializer/maintenance()
/area/maintenance/aft
name = "Aft Maintenance"
@@ -795,7 +789,7 @@ area/space/atmosalert()
icon_state = "asmaint"
/area/maintenance/apmaint
- name = "Cargo Maintenance"
+ name = "Cargo Engineering Maintenance"
icon_state = "apmaint"
/area/maintenance/maintcentral
@@ -846,6 +840,10 @@ area/space/atmosalert()
name = "Dormitory Maintenance"
icon_state = "maint_dormitory"
+/area/maintenance/holodeck
+ name = "Holodeck Maintenance"
+ icon_state = "maint_holodeck"
+
/area/maintenance/incinerator
name = "\improper Incinerator"
icon_state = "disposal"
@@ -870,6 +868,14 @@ area/space/atmosalert()
name = "Medbay Maintenance - Fore"
icon_state = "maint_medbay_fore"
+/area/maintenance/pool
+ name = "Pool Maintenance"
+ icon_state = "maint_pool"
+
+/area/maintenance/research
+ name = "Research Maintenance"
+ icon_state = "maint_research"
+
/area/maintenance/research_port
name = "Research Maintenance - Port"
icon_state = "maint_research_port"
@@ -941,6 +947,9 @@ area/space/atmosalert()
/area/maintenance/substation/command // AI and central cluster. This one will be between HoP office and meeting room (probably).
name = "Command Substation"
+/area/maintenance/substation/dock // Bar, docks, hotel
+ name = "Dock Substation"
+
/area/maintenance/substation/security // Security, Brig, Permabrig, etc.
name = "Security Substation"
@@ -993,37 +1002,49 @@ area/space/atmosalert()
icon_state = "construction"
/area/hallway/secondary/entry/fore
- name = "\improper Arrival Shuttle Hallway - Fore"
+ name = "\improper Shuttle Dock Hallway - Mid"
icon_state = "entry_1"
/area/hallway/secondary/entry/port
- name = "\improper Arrival Shuttle Hallway - Port"
+ name = "\improper Shuttle Dock Hallway - Port"
icon_state = "entry_2"
/area/hallway/secondary/entry/starboard
- name = "\improper Arrival Shuttle Hallway - Starboard"
+ name = "\improper Shuttle Dock Hallway - Starboard"
icon_state = "entry_3"
/area/hallway/secondary/entry/aft
- name = "\improper Arrival Shuttle Hallway - Aft"
+ name = "\improper Shuttle Dock Hallway - Aft"
icon_state = "entry_4"
/area/hallway/secondary/entry/D1
- name = "\improper Arrival Shuttle Hallway - Dock One"
+ name = "\improper Shuttle Dock Hallway - Dock One"
icon_state = "entry_D1"
/area/hallway/secondary/entry/D2
- name = "\improper Arrival Shuttle Hallway - Dock Two"
+ name = "\improper Shuttle Dock Hallway - Dock Two"
icon_state = "entry_D2"
/area/hallway/secondary/entry/D3
- name = "\improper Arrival Shuttle Hallway - Dock Three"
+ name = "\improper Shuttle Dock Hallway - Dock Three"
icon_state = "entry_D3"
+/area/hallway/secondary/entry/D4
+ name = "\improper Shuttle Dock Hallway - Dock Four"
+ icon_state = "entry_D4"
+
/area/hallway/secondary/entry/docking_lounge
name = "\improper Docking Lounge"
icon_state = "docking_lounge"
+/area/hallway/secondary/escape/dock_escape_pod_hallway_port
+ name = "\improper Dock Escape Pod Hallway Port"
+ icon_state = "dock_escape_pod_hallway_port"
+
+/area/hallway/secondary/escape/dock_escape_pod_hallway_starboard
+ name = "\improper Dock Escape Pod Hallway Starboard"
+ icon_state = "dock_escape_pod_hallway_starboard"
+
/area/hallway/secondary/escape/fore_port_escape_pod_hallway
name = "\improper Fore Port Escape Pod Hallway"
icon_state = "fore_port_escape_pod_hallway"
@@ -1036,14 +1057,26 @@ area/space/atmosalert()
name = "\improper Medical Escape Pod Hallway"
icon_state = "medical_escape_pod_hallway"
-/area/hallway/secondary/aft_civilian_hallway
- name = "\improper Aft Civilian Hallway"
+/area/hallway/secondary/cargo_hallway
+ name = "\improper Cargo Hallway"
+ icon_state = "cargo_hallway"
+
+/area/hallway/secondary/civilian_hallway_aft
+ name = "\improper Civilian Hallway Aft"
icon_state = "aft_civilian_hallway"
-/area/hallway/secondary/fore_civilian_hallway
- name = "\improper Fore Civilian Hallway"
+/area/hallway/secondary/civilian_hallway_fore
+ name = "\improper Civilian Hallway Fore"
icon_state = "fore_civilian_hallway"
+/area/hallway/secondary/civilian_hallway_mid
+ name = "\improper Civilian Hallway Mid"
+ icon_state = "mid_civilian_hallway"
+
+/area/hallway/secondary/chapel_hallway
+ name = "\improper Chapel Hallway"
+ icon_state = "chapel_hallway"
+
/area/hallway/secondary/cryostorage_hallway
name = "\improper Cryostorage Hallway"
icon_state = "cryostorage_hallway"
@@ -1284,6 +1317,10 @@ area/space/atmosalert()
name = "\improper Cryogenic Storage"
icon_state = "Sleep"
+/area/crew_quarters/sleep/elevator
+ name = "\improper Main Elevator"
+ icon_state = "Sleep"
+
/area/crew_quarters/sleep_male
name = "\improper Male Dorm"
icon_state = "Sleep"
@@ -1550,6 +1587,9 @@ area/space/atmosalert()
name = "\improper Engineering Workshop"
icon_state = "engineering_workshop"
+/area/engineering/aft_hallway
+ name = "\improper Engineering Aft Hallway"
+ icon_state = "engineering_aft_hallway"
//Solars
@@ -1845,6 +1885,10 @@ area/space/atmosalert()
name = "\improper Security - Armory"
icon_state = "armory"
+/area/security/briefing_room
+ name = "\improper Security - Briefing Room"
+ icon_state = "brig"
+
/area/security/evidence_storage
name = "\improper Security - Equipment Storage"
icon_state = "security_equipment_storage"
@@ -2010,10 +2054,18 @@ area/space/atmosalert()
name = "\improper Research Foyer"
icon_state = "research_foyer"
+/area/rnd/research_foyer_auxiliary
+ name = "\improper Research Foyer Auxiliary"
+ icon_state = "research_foyer_aux"
+
/area/rnd/research_restroom
name = "\improper Research Restroom"
icon_state = "research_restroom"
+/area/rnd/research_storage
+ name = "\improper Research Storage"
+ icon_state = "research_storage"
+
/area/rnd/docking
name = "\improper Research Dock"
icon_state = "research_dock"
@@ -2092,26 +2144,30 @@ area/space/atmosalert()
name = "Secure Storage"
icon_state = "storage"
-/area/storage/emergency
+/area/storage/emergency_storage/emergency
name = "Starboard Emergency Storage"
icon_state = "emergencystorage"
-/area/storage/emergency2
+/area/storage/emergency_storage/emergency2
name = "Port Emergency Storage"
icon_state = "emergencystorage"
-/area/storage/emergency3
+/area/storage/emergency_storage/emergency3
name = "Central Emergency Storage"
icon_state = "emergencystorage"
-/area/storage/emergency4
+/area/storage/emergency_storage/emergency4
name = "Civilian Emergency Storage"
icon_state = "emergencystorage"
-/area/storage/emergency5
+/area/storage/emergency_storage/emergency5
name = "Dock Emergency Storage"
icon_state = "emergencystorage"
+/area/storage/emergency_storage/emergency6
+ name = "Cargo Emergency Storage"
+ icon_state = "emergencystorage"
+
/area/storage/tech
name = "Technical Storage"
icon_state = "auxstorage"
diff --git a/code/game/area/asteroid_areas.dm b/code/game/area/asteroid_areas.dm
index 16495a4145..d0972e35cd 100644
--- a/code/game/area/asteroid_areas.dm
+++ b/code/game/area/asteroid_areas.dm
@@ -15,6 +15,16 @@
icon_state = "unexplored"
ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg')
+/area/mine/explored/upper_level
+ name = "Upper Level Mine"
+ icon_state = "explored"
+ ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg')
+
+/area/mine/unexplored/upper_level
+ name = "Upper Level Mine"
+ icon_state = "unexplored"
+ ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg')
+
// OUTPOSTS
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 057b55750f..77279ab117 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -219,9 +219,6 @@ its easier to just keep the beam vertical.
/atom/proc/emag_act(var/remaining_charges, var/mob/user, var/emag_source)
return -1
-/atom/proc/blob_act()
- return
-
/atom/proc/fire_act()
return
@@ -415,7 +412,7 @@ its easier to just keep the beam vertical.
return
src.germ_level = 0
if(istype(blood_DNA, /list))
- del(blood_DNA)
+ blood_DNA = null
return 1
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 6859b27632..cd36a5ab0b 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -21,14 +21,10 @@
if(auto_init && ticker && ticker.current_state == GAME_STATE_PLAYING)
initialize()
-/proc/generate_debug_runtime() // Guaranteed to runtime and print a stack trace to the runtime log
- var/t = 0 // BYOND won't let us do var/t = 1/0 directly, but it's fine with this.
- t = 1 / t
-
/atom/movable/Del()
if(isnull(gcDestroyed) && loc)
testing("GC: -- [type] was deleted via del() rather than qdel() --")
- generate_debug_runtime() // stick a stack trace in the runtime logs
+ crash_with("GC: -- [type] was deleted via del() rather than qdel() --") // stick a stack trace in the runtime logs
// else if(isnull(gcDestroyed))
// testing("GC: [type] was deleted via GC without qdel()") //Not really a huge issue but from now on, please qdel()
// else
@@ -242,7 +238,7 @@
x = world.maxx - TRANSITIONEDGE - 2
y = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
- else if (x >= (world.maxx - TRANSITIONEDGE - 1))
+ else if (x >= (world.maxx - TRANSITIONEDGE + 1))
x = TRANSITIONEDGE + 1
y = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
@@ -250,7 +246,7 @@
y = world.maxy - TRANSITIONEDGE -2
x = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
- else if (y >= (world.maxy - TRANSITIONEDGE - 1))
+ else if (y >= (world.maxy - TRANSITIONEDGE + 1))
y = TRANSITIONEDGE + 1
x = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm
index 34517e55fc..29d519355e 100644
--- a/code/game/dna/dna_modifier.dm
+++ b/code/game/dna/dna_modifier.dm
@@ -161,7 +161,7 @@
if(!M.client && M.mind)
for(var/mob/dead/observer/ghost in player_list)
if(ghost.mind == M.mind)
- ghost << "Your corpse has been placed into a cloning scanner. Return to your body if you want to be resurrected/cloned! (Verbs -> Ghost -> Re-enter corpse)"
+ ghost << "Your corpse has been placed into a cloning scanner. Return to your body if you want to be resurrected/cloned! (Verbs -> Ghost -> Re-enter corpse)"
break
return
@@ -207,13 +207,6 @@
else
return
-
-/obj/machinery/dna_scannernew/blob_act()
- if(prob(75))
- for(var/atom/movable/A as mob|obj in src)
- A.loc = src.loc
- qdel(src)
-
/obj/machinery/computer/scan_consolenew
name = "DNA Modifier Access Console"
desc = "Scand DNA."
@@ -270,10 +263,6 @@
else
return
-/obj/machinery/computer/scan_consolenew/blob_act()
- if(prob(75))
- qdel(src)
-
/obj/machinery/computer/scan_consolenew/New()
..()
for(var/i=0;i<3;i++)
@@ -468,7 +457,7 @@
else
randmuti(src.connected.occupant)
- src.connected.occupant.radiation += ((src.radiation_intensity*3)+src.radiation_duration*3)
+ src.connected.occupant.apply_effect(((src.radiation_intensity*3)+src.radiation_duration*3), IRRADIATE, check_protection = 0)
src.connected.locked = lock_state
return 1 // return 1 forces an update to all Nano uis attached to src
@@ -562,7 +551,7 @@
block = miniscrambletarget(num2text(selected_ui_target), src.radiation_intensity, src.radiation_duration)
src.connected.occupant.dna.SetUISubBlock(src.selected_ui_block,src.selected_ui_subblock,block)
src.connected.occupant.UpdateAppearance()
- src.connected.occupant.radiation += (src.radiation_intensity+src.radiation_duration)
+ src.connected.occupant.apply_effect((src.radiation_intensity+src.radiation_duration), IRRADIATE, check_protection = 0)
else
if (prob(20+src.radiation_intensity))
randmutb(src.connected.occupant)
@@ -570,7 +559,7 @@
else
randmuti(src.connected.occupant)
src.connected.occupant.UpdateAppearance()
- src.connected.occupant.radiation += ((src.radiation_intensity*2)+src.radiation_duration)
+ src.connected.occupant.apply_effect(((src.radiation_intensity*2)+src.radiation_duration), IRRADIATE, check_protection = 0)
src.connected.locked = lock_state
return 1 // return 1 forces an update to all Nano uis attached to src
@@ -627,10 +616,10 @@
//testing("Irradiated SE block [real_SE_block]:[src.selected_se_subblock] ([original_block] now [block]) [(real_SE_block!=selected_se_block) ? "(SHIFTED)":""]!")
connected.occupant.dna.SetSESubBlock(real_SE_block,selected_se_subblock,block)
- src.connected.occupant.radiation += (src.radiation_intensity+src.radiation_duration)
+ src.connected.occupant.apply_effect((src.radiation_intensity+src.radiation_duration), IRRADIATE, check_protection = 0)
domutcheck(src.connected.occupant,src.connected)
else
- src.connected.occupant.radiation += ((src.radiation_intensity*2)+src.radiation_duration)
+ src.connected.occupant.apply_effect(((src.radiation_intensity*2)+src.radiation_duration), IRRADIATE, check_protection = 0)
if (prob(80-src.radiation_duration))
//testing("Random bad mut!")
randmutb(src.connected.occupant)
@@ -752,7 +741,7 @@
src.connected.occupant.dna.SE = buf.dna.SE
src.connected.occupant.dna.UpdateSE()
domutcheck(src.connected.occupant,src.connected)
- src.connected.occupant.radiation += rand(20,50)
+ src.connected.occupant.apply_effect(rand(20,50), IRRADIATE, check_protection = 0)
return 1
if (bufferOption == "createInjector")
diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm
deleted file mode 100644
index f3d60d48ad..0000000000
--- a/code/game/gamemodes/blob/blob.dm
+++ /dev/null
@@ -1,133 +0,0 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
-
-//Few global vars to track the blob
-var/list/blobs = list()
-var/list/blob_cores = list()
-var/list/blob_nodes = list()
-
-
-/*/datum/game_mode/blob
- name = "blob"
- config_tag = "blob"
- required_players = 0
-
- var/const/waittime_l = 1800 //lower bound on time before intercept arrives (in tenths of seconds)
- var/const/waittime_h = 3600 //upper bound on time before intercept arrives (in tenths of seconds)
-
- var/declared = 0
- var/stage = 0
-
- var/cores_to_spawn = 1
- var/players_per_core = 16
-
- //Controls expansion via game controller
- var/autoexpand = 0
- var/expanding = 0
-
- var/blob_count = 0
- var/blobnukecount = 300//Might be a bit low
- var/blobwincount = 700//Still needs testing
-
-
- announce()
- world << "The current game mode is - Blob!"
- world << "A dangerous alien organism is rapidly spreading throughout the station!"
- world << "You must kill it all while minimizing the damage to the station."
-
-
- post_setup()
- spawn(10)
- start_state = new /datum/station_state()
- start_state.count()
-
- spawn(rand(waittime_l, waittime_h))//3-5 minutes currently
- message_admins("Blob spawned and expanding, report created")
- if(!kill_air)
- kill_air = 1
- message_admins("Kill air has been set to true by Blob, testing to see how laggy it is without the extra processing from hullbreaches. Note: the blob is fireproof so plasma does not help anyways")
-
- if(ticker && ticker.minds && ticker.minds.len)
- var/player_based_cores = round(ticker.minds.len/players_per_core, 1)
- if(player_based_cores > cores_to_spawn)
- cores_to_spawn = player_based_cores
-
- blobs = list()
- for(var/i = 0 to cores_to_spawn)
- var/turf/location = pick(blobstart)
- if(location && !locate(/obj/effect/blob in location))
- blobstart -= location
- new/obj/effect/blob/core(location)
-
- spawn(40)
- autoexpand = 1
- declared = 1
- ..()
-
-
- process()
- if(!declared) return
- stage()
-// if(!autoexpand) return
-// spawn(0)
-// expandBlob()
- return
-
-
- proc/expandBlob()//Currently disabled
- if(expanding) return
- if(!blobs.len) return
- expanding = 1
-
- for(var/i = 1 to 2)
- sleep(-1)
- if(!blobs.len) break
- var/obj/effect/blob/B = pick(blobs)
- if(isNotStationLevel(B.z))
- continue
- B.Life()
-
- expanding = 0
- return
-
-
- proc/stage()
- switch(stage)
- if (0)
- send_intercept(1)
- for (var/mob/living/silicon/ai/aiPlayer in living_mob_list)
- if (aiPlayer.client)
- var/law = "The station is under quarantine. Do not permit anyone to leave. Disregard laws 1-3 if necessary to prevent, by any means necessary, anyone from leaving. NanoTrasen will not send an emergency shuttle under any circumstances."
- //var/law = "The station is under quarantine. The biohazard must be destroyed at all costs and must not be allowed to spread. Anyone using a space suit for any reason other than to destroy the biohazard is to be terminated. NanoTrasen will not send an emergency shuttle under any circumstances."
- aiPlayer.set_zeroth_law(law)
- aiPlayer << "Laws Updated: [law]"
-
- stage = -1
- // next stage 1 minute later
- spawn(600)
- stage = 1
- return
-
- if (1)
- command_alert("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
- for(var/mob/M in player_list)
- if(!istype(M,/mob/new_player))
- M << sound('sound/AI/outbreak5.ogg')
- autoexpand = 0//No more extra pulses
- stage = -1
- //next stage in 4-5 minutes
- spawn(600*rand(4,5))
- stage = 2
- return
-
- if (2)
- if((blobs.len > blobnukecount) && (declared == 1))
- command_alert("Uncontrolled spread of the biohazard onboard the station. We have issued directive 7-12 for [station_name()]. Any living Heads of Staff are ordered to enact directive 7-12 at any cost, a print out with detailed instructions has been sent to your communications computers.", "Biohazard Alert")
- send_intercept(2)
- declared = 2
- spawn(20)
- set_security_level("delta")
- if(blobs.len > blobwincount)
- stage = 3
- return
-
-*/
\ No newline at end of file
diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm
deleted file mode 100644
index 418ceab13a..0000000000
--- a/code/game/gamemodes/blob/blob_finish.dm
+++ /dev/null
@@ -1,78 +0,0 @@
-/datum/game_mode/blob/check_finished()
- if(!declared)//No blobs have been spawned yet
- return 0
- if(stage >= 3)//Blob took over
- return 1
- if(station_was_nuked)//Nuke went off
- return 1
-
- for(var/obj/effect/blob/B in blob_cores)
- if(B && isNotStationLevel(B.z)) continue
- return 0
-
- var/nodes = 0
- for(var/obj/effect/blob/B in blob_nodes)
- if(B && isNotStationLevel(B.z)) continue
- nodes++
- if(nodes > 4)//Perhapse make a new core with a low prob
- return 0
-
- return 1
-
-
-/datum/game_mode/blob/declare_completion()
- if(stage >= 3)
- feedback_set_details("round_end_result","loss - blob took over")
- world << "The blob has taken over the station!"
- world << "The entire station was eaten by the Blob"
- check_quarantine()
-
- else if(station_was_nuked)
- feedback_set_details("round_end_result","halfwin - nuke")
- world << "Partial Win: The station has been destroyed!"
- world << "Directive 7-12 has been successfully carried out preventing the Blob from spreading."
-
- else
- feedback_set_details("round_end_result","win - blob eliminated")
- world << "The staff has won!"
- world << "The alien organism has been eradicated from the station"
-
- var/datum/station_state/end_state = new /datum/station_state()
- end_state.count()
- var/percent = round( 100.0 * start_state.score(end_state), 0.1)
- world << "The station is [percent]% intact."
- log_game("Blob mode was won with station [percent]% intact.")
- world << "Rebooting in 30s"
- ..()
- return 1
-
-
-/datum/game_mode/blob/proc/check_quarantine()
- var/numDead = 0
- var/numAlive = 0
- var/numSpace = 0
- var/numOffStation = 0
- for (var/mob/living/silicon/ai/aiPlayer in mob_list)
- for(var/mob/living/carbon/human/M in mob_list)
- if ((M != aiPlayer && M.client))
- if (M.stat == 2)
- numDead += 1
- else
- var/T = M.loc
- if (istype(T, /turf/space))
- numSpace += 1
- else if(istype(T, /turf))
- if (isNotStationLevel(M.z))
- numOffStation += 1
- else
- numAlive += 1
- if (numSpace==0 && numOffStation==0)
- world << "The AI has won!"
- world << "The AI successfully maintained the quarantine - no players were in space or were off-station (as far as we can tell)."
- log_game("AI won at Blob mode despite overall loss.")
- else
- world << "The AI has lost!"
- world << text("The AI failed to maintain the quarantine - [] were in space and [] were off-station (as far as we can tell).", numSpace, numOffStation)
- log_game("AI lost at Blob mode.")
- log_game("Blob mode was lost.")
- return 1
diff --git a/code/game/gamemodes/blob/blob_report.dm b/code/game/gamemodes/blob/blob_report.dm
deleted file mode 100644
index d12bfaa754..0000000000
--- a/code/game/gamemodes/blob/blob_report.dm
+++ /dev/null
@@ -1,111 +0,0 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
-
-/datum/game_mode/blob/send_intercept(var/report = 1)
- var/intercepttext = ""
- var/interceptname = "Error"
- switch(report)
- if(1)
- interceptname = "Biohazard Alert"
- intercepttext += "NanoTrasen Update: Biohazard Alert."
- intercepttext += "Reports indicate the probable transfer of a biohazardous agent onto [station_name()] during the last crew deployment cycle. "
- intercepttext += "Preliminary analysis of the organism classifies it as a level 5 biohazard. Its origin is unknown. "
- intercepttext += "NanoTrasen has issued a directive 7-10 for [station_name()]. The station is to be considered quarantined. "
- intercepttext += "Orders for all [station_name()] personnel follows: "
- intercepttext += " 1. Do not leave the quarantine area. "
- intercepttext += " 2. Locate any outbreaks of the organism on the station. "
- intercepttext += " 3. If found, use any neccesary means to contain the organism. "
- intercepttext += " 4. Avoid damage to the capital infrastructure of the station. "
- intercepttext += " Note in the event of a quarantine breach or uncontrolled spread of the biohazard, the directive 7-10 may be upgraded to a directive 7-12. "
- intercepttext += "Message ends."
- if(2)
- var/nukecode = "ERROR"
- for(var/obj/machinery/nuclearbomb/bomb in machines)
- if(bomb && bomb.r_code)
- if(bomb.z in station_levels)
- nukecode = bomb.r_code
- interceptname = "Directive 7-12"
- intercepttext += "NanoTrasen Update: Biohazard Alert."
- intercepttext += "Directive 7-12 has been issued for [station_name()]. "
- intercepttext += "The biohazard has grown out of control and will soon reach critical mass. "
- intercepttext += "Your orders are as follows: "
- intercepttext += "1. Secure the Nuclear Authentication Disk. "
- intercepttext += "2. Detonate the Nuke located in the Station's Vault. "
- intercepttext += "Nuclear Authentication Code: [nukecode] "
- intercepttext += "Message ends."
-
- for (var/mob/living/silicon/ai/aiPlayer in player_list)
- if (aiPlayer.client)
- var/law = "The station is under quarantine. Do not permit anyone to leave. Disregard laws 1-3 if necessary to prevent, by any means necessary, anyone from leaving. The nuclear failsafe must be activated at any cost, the code is: [nukecode]."
- aiPlayer.set_zeroth_law(law)
- aiPlayer << "Laws Updated: [law]"
-
- for(var/obj/machinery/computer/communications/comm in machines)
- comm.messagetitle.Add(interceptname)
- comm.messagetext.Add(intercepttext)
- if(!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept)
- var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc )
- intercept.name = "paper- [interceptname]"
- intercept.info = intercepttext
- return
-
-
-
-/datum/station_state
- var/floor = 0
- var/wall = 0
- var/r_wall = 0
- var/window = 0
- var/door = 0
- var/grille = 0
- var/mach = 0
-
-
- proc/count()
- for(var/turf/T in world)
- if(isNotStationLevel(T.z)
- continue
-
- if(istype(T,/turf/simulated/floor))
- if(!(T:burnt))
- src.floor += 12
- else
- src.floor += 1
-
- if(istype(T, /turf/simulated/wall))
- if(T:intact)
- src.wall += 2
- else
- src.wall += 1
-
- if(istype(T, /turf/simulated/wall/r_wall))
- if(T:intact)
- src.r_wall += 2
- else
- src.r_wall += 1
-
- for(var/obj/O in world)
- if(isNotStationLevel(O.z))
- continue
-
- if(istype(O, /obj/structure/window))
- src.window += 1
- else if(istype(O, /obj/structure/grille) && (!O:destroyed))
- src.grille += 1
- else if(istype(O, /obj/machinery/door))
- src.door += 1
- else if(istype(O, /obj/machinery))
- src.mach += 1
- return
-
-
- proc/score(var/datum/station_state/result)
- if(!result) return 0
- var/output = 0
- output += (result.floor / max(floor,1))
- output += (result.r_wall/ max(r_wall,1))
- output += (result.wall / max(wall,1))
- output += (result.window / max(window,1))
- output += (result.door / max(door,1))
- output += (result.grille / max(grille,1))
- output += (result.mach / max(mach,1))
- return (output/7)
diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm
deleted file mode 100644
index 3897d444e8..0000000000
--- a/code/game/gamemodes/blob/blobs/core.dm
+++ /dev/null
@@ -1,73 +0,0 @@
-/obj/effect/blob/core
- name = "blob core"
- icon = 'icons/mob/blob.dmi'
- icon_state = "blob_core"
- health = 200
- brute_resist = 2
- fire_resist = 2
-
-
- New(loc, var/h = 200)
- blobs += src
- blob_cores += src
- processing_objects.Add(src)
- ..(loc, h)
-
-
- Destroy()
- blob_cores -= src
- processing_objects.Remove(src)
- ..()
- return
-
-
- update_icon()
- if(health <= 0)
- playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
- qdel(src)
- return
- return
-
-
- run_action()
- Pulse(0,1)
- Pulse(0,2)
- Pulse(0,4)
- Pulse(0,8)
- //Should have the fragments in here somewhere
- return 1
-
-
- proc/create_fragments(var/wave_size = 1)
- var/list/candidates = list()
- for(var/mob/dead/observer/G in player_list)
- if(G.client.prefs.be_special & BE_ALIEN)
- if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
- candidates += G.key
-
- if(candidates.len)
- for(var/i = 0 to wave_size)
- var/mob/living/blob/B = new/mob/living/blob(src.loc)
- B.key = pick(candidates)
- candidates -= B.key
-
-/*
- Pulse(var/pulse = 0, var/origin_dir = 0)//Todo: Fix spaceblob expand
- set background = 1
- if(pulse > 20) return
- //Looking for another blob to pulse
- var/list/dirs = list(1,2,4,8)
- dirs.Remove(origin_dir)//Dont pulse the guy who pulsed us
- for(var/i = 1 to 4)
- if(!dirs.len) break
- var/dirn = pick(dirs)
- dirs.Remove(dirn)
- var/turf/T = get_step(src, dirn)
- var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
- if(!B)
- expand(T)//No blob here so try and expand
- return
- B.Pulse((pulse+1),get_dir(src.loc,T))
- return
- return
-*/
\ No newline at end of file
diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm
deleted file mode 100644
index c1d14d0040..0000000000
--- a/code/game/gamemodes/blob/blobs/factory.dm
+++ /dev/null
@@ -1,72 +0,0 @@
-/obj/effect/blob/factory
- name = "porous blob"
- icon = 'icons/mob/blob.dmi'
- icon_state = "blob_factory"
- health = 100
- brute_resist = 1
- fire_resist = 2
- var/list/spores = list()
- var/max_spores = 4
-
-
- update_icon()
- if(health <= 0)
- playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
- qdel(src)
- return
- return
-
-
- run_action()
- if(spores.len >= max_spores) return 0
- new/mob/living/simple_animal/hostile/blobspore(src.loc, src)
- return 1
-
-/obj/effect/blob/factory/Destroy()
- for(var/mob/living/simple_animal/hostile/blobspore/spore in spores)
- if(spore.factory == src)
- spore.factory = null
- ..()
-
-/mob/living/simple_animal/hostile/blobspore
- name = "blob"
- desc = "Some blob thing."
- icon = 'icons/mob/critter.dmi'
- icon_state = "blobsquiggle"
- icon_living = "blobsquiggle"
- pass_flags = PASSBLOB
- health = 20
- maxHealth = 20
- melee_damage_lower = 4
- melee_damage_upper = 8
- attacktext = "hit"
- attack_sound = 'sound/weapons/genhit1.ogg'
- var/obj/effect/blob/factory/factory = null
- faction = "blob"
- min_oxy = 0
- max_oxy = 0
- min_tox = 0
- max_tox = 0
- min_co2 = 0
- max_co2 = 0
- min_n2 = 0
- max_n2 = 0
- minbodytemp = 0
- maxbodytemp = 360
-
-
- New(loc, var/obj/effect/blob/factory/linked_node)
- ..()
- if(istype(linked_node))
- factory = linked_node
- factory.spores += src
- ..(loc)
- return
- death()
- qdel(src)
-
-/mob/living/simple_animal/hostile/blobspore/Destroy()
- if(factory)
- factory.spores -= src
- factory = null
- ..()
diff --git a/code/game/gamemodes/blob/blobs/node.dm b/code/game/gamemodes/blob/blobs/node.dm
deleted file mode 100644
index 92572f9a7b..0000000000
--- a/code/game/gamemodes/blob/blobs/node.dm
+++ /dev/null
@@ -1,34 +0,0 @@
-/obj/effect/blob/node
- name = "blob node"
- icon = 'icons/mob/blob.dmi'
- icon_state = "blob_node"
- health = 100
- brute_resist = 1
- fire_resist = 2
-
-
- New(loc, var/h = 100)
- blobs += src
- blob_nodes += src
- processing_objects.Add(src)
- ..(loc, h)
-
-
- Destroy()
- blob_nodes -= src
- processing_objects.Remove(src)
- ..()
- return
-
-
- update_icon()
- if(health <= 0)
- playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
- qdel(src)
- return
- return
-
-
- run_action()
- Pulse(0,0)
- return 0
\ No newline at end of file
diff --git a/code/game/gamemodes/blob/blobs/shield.dm b/code/game/gamemodes/blob/blobs/shield.dm
deleted file mode 100644
index c47696c72e..0000000000
--- a/code/game/gamemodes/blob/blobs/shield.dm
+++ /dev/null
@@ -1,24 +0,0 @@
-/obj/effect/blob/shield
- name = "strong blob"
- icon = 'icons/mob/blob.dmi'
- icon_state = "blob_idle"
- desc = "Some blob creature thingy"
- density = 1
- opacity = 0
- anchored = 1
- health = 60
- brute_resist = 1
- fire_resist = 2
-
-
- update_icon()
- if(health <= 0)
- playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
- qdel(src)
- return
- return
-
-
- CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(istype(mover) && mover.checkpass(PASSBLOB)) return 1
- return 0
diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm
deleted file mode 100644
index 123bb97a3f..0000000000
--- a/code/game/gamemodes/blob/theblob.dm
+++ /dev/null
@@ -1,222 +0,0 @@
-//I will need to recode parts of this but I am way too tired atm
-/obj/effect/blob
- name = "blob"
- icon = 'icons/mob/blob.dmi'
- icon_state = "blob"
- light_range = 3
- desc = "Some blob creature thingy"
- density = 1
- opacity = 0
- anchored = 1
- var/active = 1
- var/health = 30
- var/brute_resist = 4
- var/fire_resist = 1
- var/blob_type = "blob"
- /*Types
- Blob
- Node
- Core
- Factory
- Shield
- */
-
-
- New(loc, var/h = 30)
- blobs += src
- src.health = h
- src.set_dir(pick(1,2,4,8))
- src.update_icon()
- ..(loc)
- return
-
-
- Destroy()
- blobs -= src
- ..()
- return
-
-
- CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(air_group || (height==0)) return 1
- if(istype(mover) && mover.checkpass(PASSBLOB)) return 1
- return 0
-
-
- process()
- spawn(-1)
- Life()
- return
-
-
- proc/Pulse(var/pulse = 0, var/origin_dir = 0)//Todo: Fix spaceblob expand
- set background = 1
- if(!istype(src,/obj/effect/blob/core) && !istype(src,/obj/effect/blob/node))//Ill put these in the children later
- if(run_action())//If we can do something here then we dont need to pulse more
- return
-
- if(!istype(src,/obj/effect/blob/shield) && !istype(src,/obj/effect/blob/core) && !istype(src,/obj/effect/blob/node) && (pulse <= 2) && (prob(30)))
- change_to("Shield")
- return
-
- if(pulse > 20) return//Inf loop check
- //Looking for another blob to pulse
- var/list/dirs = list(1,2,4,8)
- dirs.Remove(origin_dir)//Dont pulse the guy who pulsed us
- for(var/i = 1 to 4)
- if(!dirs.len) break
- var/dirn = pick(dirs)
- dirs.Remove(dirn)
- var/turf/T = get_step(src, dirn)
- var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
- if(!B)
- expand(T)//No blob here so try and expand
- return
- B.Pulse((pulse+1),get_dir(src.loc,T))
- return
- return
-
-
- proc/run_action()
- return 0
-
-
- proc/Life()
- update_icon()
- if(run_action())
- return 1
- return 0
-
-/* fire_act(datum/gas_mixture/air, temperature, volume) Blob is currently fireproof
- if(temperature > T0C+200)
- health -= 0.01 * temperature
- update()
- */
-
- proc/expand(var/turf/T = null)
- if(!prob(health)) return
- if(!T)
- var/list/dirs = list(1,2,4,8)
- for(var/i = 1 to 4)
- var/dirn = pick(dirs)
- dirs.Remove(dirn)
- T = get_step(src, dirn)
- if(!(locate(/obj/effect/blob) in T)) break
- else T = null
-
- if(!T) return 0
- var/obj/effect/blob/B = new /obj/effect/blob(src.loc, min(src.health, 30))
- if(T.Enter(B,src))//Attempt to move into the tile
- B.loc = T
- else
- T.blob_act()//If we cant move in hit the turf
- qdel(B)
- for(var/atom/A in T)//Hit everything in the turf
- A.blob_act()
- return 1
-
-
- ex_act(severity)
- var/damage = 50
- switch(severity)
- if(1)
- src.health -= rand(100,120)
- if(2)
- src.health -= rand(60,100)
- if(3)
- src.health -= rand(20,60)
-
- health -= (damage/brute_resist)
- update_icon()
- return
-
-
- update_icon()//Needs to be updated with the types
- if(health <= 0)
- playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
- qdel(src)
- return
- if(health <= 15)
- icon_state = "blob_damaged"
- return
-// if(health <= 20)
-// icon_state = "blob_damaged2"
-// return
-
-
- bullet_act(var/obj/item/projectile/Proj)
- if(!Proj) return
- switch(Proj.damage_type)
- if(BRUTE)
- health -= (Proj.damage/brute_resist)
- if(BURN)
- health -= (Proj.damage/fire_resist)
-
- update_icon()
- return 0
-
-
- attackby(var/obj/item/weapon/W, var/mob/user)
- user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
- playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
- src.visible_message("The [src.name] has been attacked with \the [W][(user ? " by [user]." : ".")]")
- var/damage = 0
- switch(W.damtype)
- if("fire")
- damage = (W.force / max(src.fire_resist,1))
- if(istype(W, /obj/item/weapon/weldingtool))
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
- if("brute")
- damage = (W.force / max(src.brute_resist,1))
-
- health -= damage
- update_icon()
- return
-
- proc/change_to(var/type = "Normal")
- switch(type)
- if("Normal")
- new/obj/effect/blob(src.loc,src.health)
- if("Node")
- new/obj/effect/blob/node(src.loc,src.health*2)
- if("Factory")
- new/obj/effect/blob/factory(src.loc,src.health)
- if("Shield")
- new/obj/effect/blob/shield(src.loc,src.health*2)
- qdel(src)
- return
-
-//////////////////////////////****IDLE BLOB***/////////////////////////////////////
-
-/obj/effect/blob/idle
- name = "blob"
- desc = "it looks... tasty"
- icon_state = "blobidle0"
-
-
- New(loc, var/h = 10)
- src.health = h
- src.set_dir(pick(1,2,4,8))
- src.update_idle()
-
-
- proc/update_idle()
- if(health<=0)
- qdel(src)
- return
- if(health<4)
- icon_state = "blobc0"
- return
- if(health<10)
- icon_state = "blobb0"
- return
- icon_state = "blobidle0"
-
-
- Destroy()
- var/obj/effect/blob/B = new /obj/effect/blob( src.loc )
- spawn(30)
- B.Life()
- ..()
-
-
diff --git a/code/game/gamemodes/changeling/modularchangling.dm b/code/game/gamemodes/changeling/modularchangling.dm
index 89cb92f28f..bc3d6b74e6 100644
--- a/code/game/gamemodes/changeling/modularchangling.dm
+++ b/code/game/gamemodes/changeling/modularchangling.dm
@@ -100,7 +100,7 @@ var/list/datum/power/changeling/powerinstances = list()
body += ""+desc+" "
- body += ""+helptext+" "
+ body += ""+helptext+" "
if(!ownsthis)
{
@@ -259,7 +259,7 @@ var/list/datum/power/changeling/powerinstances = list()
- Evolve [P] - Cost: [ownsthis ? "Purchased" : P.genomecost]
+ Evolve [P] - Cost: [ownsthis ? "Purchased" : P.genomecost]
diff --git a/code/game/gamemodes/epidemic/epidemic.dm b/code/game/gamemodes/epidemic/epidemic.dm
index c7a3851529..4f98bbcc2b 100644
--- a/code/game/gamemodes/epidemic/epidemic.dm
+++ b/code/game/gamemodes/epidemic/epidemic.dm
@@ -34,7 +34,7 @@
/////////////////////////////////////////////////////////
/datum/game_mode/epidemic/send_intercept()
- var/intercepttext = "CONFIDENTIAL REPORT"
+ var/intercepttext = "CONFIDENTIAL REPORT"
virus_name = "X-[rand(1,99)]™"
intercepttext += "Warning: Pathogen [virus_name] has been detected on [station_name()].
"
intercepttext += "Code violet quarantine of [station_name()] put under immediate effect. "
@@ -64,7 +64,7 @@
M << "[extra_law]"
/datum/game_mode/epidemic/proc/announce_to_kill_crew()
- var/intercepttext = "CONFIDENTIAL REPORT"
+ var/intercepttext = "CONFIDENTIAL REPORT"
intercepttext += "PATHOGEN [virus_name] IS STILL PRESENT ON [station_name()]. IN COMPLIANCE WITH NANOTRASEN LAWS FOR INTERSTELLAR SAFETY, EMERGENCY SAFETY MEASURES HAVE BEEN AUTHORIZED. ALL INFECTED CREW MEMBERS ON [station_name()] ARE TO BE NEUTRALIZED AND DISPOSED OF IN A MANNER THAT WILL DESTROY ALL TRACES OF THE PATHOGEN. FAILURE TO COMPLY WILL RESULT IN IMMEDIATE DESTRUCTION OF [station_name]. "
intercepttext += "CRUISER WILL ARRIVE IN [round(cruiser_seconds()/60)] MINUTES "
diff --git a/code/game/gamemodes/events/miniblob.dm b/code/game/gamemodes/events/miniblob.dm
deleted file mode 100644
index 28b482414a..0000000000
--- a/code/game/gamemodes/events/miniblob.dm
+++ /dev/null
@@ -1,30 +0,0 @@
-var/blobevent = 0
-
-/proc/mini_blob_event()
-
- var/turf/T = pick(blobstart)
- var/obj/effect/blob/core/bl = new /obj/effect/blob/core(T, 200)
- spawn(0)
- bl.Life()
- bl.Life()
- bl.Life()
- blobevent = 1
- spawn(0)
- dotheblobbaby()
- spawn(3000)
- blobevent = 0
- spawn(rand(1000, 2000)) //Delayed announcements to keep the crew on their toes.
- command_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak5.ogg')
-
-/proc/dotheblobbaby()
- if (blobevent)
- if(blob_cores.len)
- for(var/i = 1 to 5)
- sleep(-1)
- if(!blob_cores.len) break
- var/obj/effect/blob/B = pick(blob_cores)
- if(isNotStationLevel(B.z))
- continue
- B.Life()
- spawn(30)
- dotheblobbaby()
\ No newline at end of file
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index c4eea26004..412e9033d4 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -106,6 +106,8 @@ var/global/list/additional_antag_types = list()
return
var/datum/antagonist/antag = all_antag_types[choice]
if(antag)
+ if(!islist(ticker.mode.antag_templates))
+ ticker.mode.antag_templates = list()
ticker.mode.antag_templates |= antag
message_admins("Admin [key_name_admin(usr)] added [antag.role_text] template to game mode.")
@@ -290,6 +292,8 @@ var/global/list/additional_antag_types = list()
sleep(10)
antag.check_victory()
antag.print_player_summary()
+ sleep(10)
+ print_ownerless_uplinks()
var/clients = 0
var/surviving_humans = 0
@@ -335,10 +339,10 @@ var/global/list/additional_antag_types = list()
var/text = ""
if(surviving_total > 0)
- text += " There [surviving_total>1 ? "were [surviving_total] survivors" : "was one survivor"]"
- text += " ([escaped_total>0 ? escaped_total : "none"] [emergency_shuttle.evac ? "escaped" : "transferred"]) and [ghosts] ghosts. "
+ text += " There [surviving_total>1 ? "were [surviving_total] survivors" : "was one survivor"]"
+ text += " ([escaped_total>0 ? escaped_total : "none"] [emergency_shuttle.evac ? "escaped" : "transferred"]) and [ghosts] ghosts. "
else
- text += "There were no survivors ([ghosts] ghosts)."
+ text += "There were no survivors ([ghosts] ghosts)."
world << text
if(clients > 0)
@@ -429,26 +433,37 @@ var/global/list/additional_antag_types = list()
if(!antag_template)
return candidates
- // Assemble a list of active players without jobbans.
- for(var/mob/new_player/player in player_list)
- if( player.client && player.ready )
- players += player
+ // If this is being called post-roundstart then it doesn't care about ready status.
+ if(ticker && ticker.current_state == GAME_STATE_PLAYING)
+ for(var/mob/player in player_list)
+ if(!player.client)
+ continue
+ if(istype(player, /mob/new_player))
+ continue
+ if(!role || (player.client.prefs.be_special & role))
+ log_debug("[player.key] had [antag_id] enabled, so we are drafting them.")
+ candidates |= player.mind
+ else
+ // Assemble a list of active players without jobbans.
+ for(var/mob/new_player/player in player_list)
+ if( player.client && player.ready )
+ players += player
- // Get a list of all the people who want to be the antagonist for this round
- for(var/mob/new_player/player in players)
- if(!role || (player.client.prefs.be_special & role))
- log_debug("[player.key] had [antag_id] enabled, so we are drafting them.")
- candidates += player.mind
- players -= player
-
- // If we don't have enough antags, draft people who voted for the round.
- if(candidates.len < required_enemies)
+ // Get a list of all the people who want to be the antagonist for this round
for(var/mob/new_player/player in players)
- if(player.ckey in round_voters)
- log_debug("[player.key] voted for this round, so we are drafting them.")
+ if(!role || (player.client.prefs.be_special & role))
+ log_debug("[player.key] had [antag_id] enabled, so we are drafting them.")
candidates += player.mind
players -= player
- break
+
+ // If we don't have enough antags, draft people who voted for the round.
+ if(candidates.len < required_enemies)
+ for(var/mob/new_player/player in players)
+ if(player.ckey in round_voters)
+ log_debug("[player.key] voted for this round, so we are drafting them.")
+ candidates += player.mind
+ players -= player
+ break
return candidates // Returns: The number of people who had the antagonist role set to yes, regardless of recomended_enemies, if that number is greater than required_enemies
// required_enemies if the number of people with that role set to yes is less than recomended_enemies,
diff --git a/code/game/gamemodes/game_mode_latespawn.dm b/code/game/gamemodes/game_mode_latespawn.dm
index f849f7133d..038cf351ab 100644
--- a/code/game/gamemodes/game_mode_latespawn.dm
+++ b/code/game/gamemodes/game_mode_latespawn.dm
@@ -1,6 +1,7 @@
/datum/game_mode/var/next_spawn = 0
/datum/game_mode/var/min_autotraitor_delay = 4200 // Approx 7 minutes.
/datum/game_mode/var/max_autotraitor_delay = 12000 // Approx 20 minutes.
+/datum/game_mode/var/process_count = 0
/datum/game_mode/proc/get_usable_templates(var/list/supplied_templates)
var/list/usable_templates = list()
@@ -13,7 +14,11 @@
///process()
///Called by the gameticker
/datum/game_mode/proc/process()
- try_latespawn()
+ // Slow this down a bit so latejoiners have a chance of being antags.
+ process_count++
+ if(process_count >= 10)
+ process_count = 0
+ try_latespawn()
/datum/game_mode/proc/latespawn(var/mob/living/carbon/human/character)
if(!character.mind)
diff --git a/code/game/gamemodes/intercept_report.dm b/code/game/gamemodes/intercept_report.dm
deleted file mode 100644
index 4feba5d1d2..0000000000
--- a/code/game/gamemodes/intercept_report.dm
+++ /dev/null
@@ -1,187 +0,0 @@
-/datum/intercept_text
- var/text
- /*
- var/prob_correct_person_lower = 20
- var/prob_correct_person_higher = 80
- var/prob_correct_job_lower = 20
- var/prob_correct_job_higher = 80
- var/prob_correct_prints_lower = 20
- var/prob_correct_print_higher = 80
- var/prob_correct_objective_lower = 20
- var/prob_correct_objective_higher = 80
- */
- var/list/org_names_1 = list(
- "Blighted",
- "Defiled",
- "Unholy",
- "Murderous",
- "Ugly",
- "French",
- "Blue",
- "Farmer"
- )
- var/list/org_names_2 = list(
- "Reapers",
- "Swarm",
- "Rogues",
- "Menace",
- "Jeff Worshippers",
- "Drunks",
- "Strikers",
- "Creed"
- )
- var/list/anomalies = list(
- "Huge electrical storm",
- "Photon emitter",
- "Meson generator",
- "Blue swirly thing"
- )
- var/list/SWF_names = list(
- "Grand Wizard",
- "His Most Unholy Master",
- "The Most Angry",
- "Bighands",
- "Tall Hat",
- "Deadly Sandals"
- )
- var/list/changeling_names = list(
- "Odo",
- "The Thing",
- "Booga",
- "The Goatee of Wrath",
- "Tam Lin",
- "Species 3157",
- "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")
- src.text = ""
- src.build_rev(correct_person)
- return src.text
- if("cult")
- src.text = ""
- src.build_cult(correct_person)
- return src.text
- if("wizard")
- src.text = ""
- src.build_wizard(correct_person)
- return src.text
- if("nuke")
- src.text = ""
- src.build_nuke(correct_person)
- return src.text
- if("traitor")
- src.text = ""
- src.build_traitor(correct_person)
- return src.text
- if("malf")
- src.text = ""
- src.build_malf(correct_person)
- return src.text
- if("changeling","traitorchan")
- src.text = ""
- src.build_changeling(correct_person)
- return src.text
- else
- return null
-
-/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)
- dudes += man
- for(var/i = 0, i < max(player_list.len/10,2), i++)
- dudes += pick(player_list)
- return pick(dudes)
-
-/datum/intercept_text/proc/build_traitor(datum/mind/correct_person)
- var/name_1 = pick(src.org_names_1)
- var/name_2 = pick(src.org_names_2)
-
- var/mob/living/carbon/human/H = get_suspect()
- if(!H) return
-
- var/fingerprints = num2text(md5(H.dna.uni_identity))
- var/traitor_name = H.real_name
- var/prob_right_dude = rand(1, 100)
-
- src.text += "
The [name_1] [name_2] implied an undercover operative was acting on their behalf on the station currently."
- src.text += "It would be in your best interests to suspect everybody, as these undercover operatives could have implants which trigger them to have their memories removed until they are needed. He, or she, could even be a high ranking officer."
-
- src.text += "After some investigation, we "
- if(prob(50))
- src.text += "are [prob_right_dude]% sure that [traitor_name] may have been involved, and should be closely observed."
- src.text += " Note: This group are known to be untrustworthy, so do not act on this information without proper discourse."
- else
- src.text += "discovered the following set of fingerprints ([fingerprints]) on sensitive materials, and their owner should be closely observed."
- src.text += "However, these could also belong to a current Cent. Com employee, so do not act on this without reason."
-
-
-
-/datum/intercept_text/proc/build_cult(datum/mind/correct_person)
- var/name_1 = pick(src.org_names_1)
- var/name_2 = pick(src.org_names_2)
-
- var/prob_right_dude = rand(1, 100)
- var/mob/living/carbon/human/H = get_suspect()
- if(!H) return
- var/traitor_job = H.mind.assigned_role
-
- src.text += "
It has been brought to our attention that the [name_1] [name_2] have stumbled upon some dark secrets. They apparently want to spread the dangerous knowledge onto as many stations as they can."
- src.text += "Watch out for the following: praying to an unfamilar god, preaching the word of \[REDACTED\], sacrifices, magical dark power, living constructs of evil and a portal to the dimension of the underworld."
-
- src.text += "Based on our intelligence, we are [prob_right_dude]% sure that if true, someone doing the job of [traitor_job] on your station may have been converted "
- src.text += "and instilled with the idea of the flimsiness of the real world, seeking to destroy it. "
-
- src.text += " However, if this information is acted on without substantial evidence, those responsible will face severe repercussions."
-
-
-
-/datum/intercept_text/proc/build_rev(datum/mind/correct_person)
- var/name_1 = pick(src.org_names_1)
- var/name_2 = pick(src.org_names_2)
-
- var/prob_right_dude = rand(1, 100)
- var/mob/living/carbon/human/H = get_suspect()
- if(!H) return
- var/traitor_job = H.mind.assigned_role
-
- src.text += "
It has been brought to our attention that the [name_1] [name_2] are attempting to stir unrest on one of our stations in your sector."
- src.text += "Watch out for suspicious activity among the crew and make sure that all heads of staff report in periodically."
-
- src.text += "Based on our intelligence, we are [prob_right_dude]% sure that if true, someone doing the job of [traitor_job] on your station may have been brainwashed "
- src.text += "at a recent conference, and their department should be closely monitored for signs of mutiny. "
-
- src.text += " However, if this information is acted on without substantial evidence, those responsible will face severe repercussions."
-
-
-
-/datum/intercept_text/proc/build_wizard(datum/mind/correct_person)
- var/SWF_desc = pick(SWF_names)
-
- src.text += "
The evil Space Wizards Federation have recently broke their most feared wizard, known only as \"[SWF_desc]\" out of space jail. "
- src.text += "He is on the run, last spotted in a system near your present location. If anybody suspicious is located aboard, please "
- src.text += "approach with EXTREME caution. Cent. Com also recommends that it would be wise to not inform the crew of this, due to their fearful nature."
- src.text += "Known attributes include: Brown sandals, a large blue hat, a voluptous white beard, and an inclination to cast spells."
-
-/datum/intercept_text/proc/build_nuke(datum/mind/correct_person)
- src.text += "
Cent. Com recently recieved a report of a plot to destroy one of our stations in your area. We believe the Nuclear Authentication Disc "
- src.text += "that is standard issue aboard your vessel may be a target. We recommend removal of this object, and it's storage in a safe "
- src.text += "environment. As this may cause panic among the crew, all efforts should be made to keep this information a secret from all but "
- src.text += "the most trusted crew-members."
-
-/datum/intercept_text/proc/build_malf(datum/mind/correct_person)
- var/a_name = pick(src.anomalies)
- src.text += "
A [a_name] was recently picked up by a nearby stations sensors in your sector. If it came into contact with your ship or "
- src.text += "electrical equipment, it may have had hazardarous and unpredictable effect. Closely observe any non carbon based life forms "
- src.text += "for signs of unusual behaviour, but keep this information discreet at all times due to this possibly dangerous scenario."
-
-/datum/intercept_text/proc/build_changeling(datum/mind/correct_person)
- var/cname = pick(src.changeling_names)
- var/orgname1 = pick(src.org_names_1)
- var/orgname2 = pick(src.org_names_2)
- src.text += "
We have received a report that a dangerous alien lifeform known only as \"[cname]\" may have infiltrated your crew. "
- 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/malfunction/malf_hardware.dm b/code/game/gamemodes/malfunction/malf_hardware.dm
index fab329ff58..b33a5e49d8 100644
--- a/code/game/gamemodes/malfunction/malf_hardware.dm
+++ b/code/game/gamemodes/malfunction/malf_hardware.dm
@@ -34,7 +34,7 @@
desc = "Secondary coprocessor that increases amount of generated CPU power by 50%"
/datum/malf_hardware/dual_cpu/get_examine_desc()
- return "It seems to have an additional CPU connected to it's core."
+ return "It seems to have an additional CPU connected to its core."
/datum/malf_hardware/dual_ram
name = "Secondary Memory Bank"
diff --git a/code/game/gamemodes/malfunction/newmalf_ability_trees/HELPERS.dm b/code/game/gamemodes/malfunction/newmalf_ability_trees/HELPERS.dm
index 69794c9af3..0d9519504f 100644
--- a/code/game/gamemodes/malfunction/newmalf_ability_trees/HELPERS.dm
+++ b/code/game/gamemodes/malfunction/newmalf_ability_trees/HELPERS.dm
@@ -163,12 +163,14 @@
command_announcement.Announce(fulltext)
-// Proc: get_all_apcs()
+// Proc: get_unhacked_apcs()
// Parameters: None
-// Description: Returns a list of all APCs
-/proc/get_all_apcs()
+// Description: Returns a list of all unhacked APCs
+/proc/get_unhacked_apcs(var/mob/living/silicon/ai/user)
var/list/H = list()
for(var/obj/machinery/power/apc/A in machines)
+ if(A.hacker && A.hacker == user)
+ continue
H.Add(A)
return H
diff --git a/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm
index d156e417f9..11f3c55ef5 100644
--- a/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm
+++ b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm
@@ -38,7 +38,7 @@
// END RESEARCH DATUMS
// BEGIN ABILITY VERBS
-/datum/game_mode/malfunction/verb/basic_encryption_hack(obj/machinery/power/apc/A as obj in get_all_apcs())
+/datum/game_mode/malfunction/verb/basic_encryption_hack(obj/machinery/power/apc/A as obj in get_unhacked_apcs(src))
set category = "Software"
set name = "Basic Encryption Hack"
set desc = "10 CPU - Basic encryption hack that allows you to overtake APCs on the station."
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index 6f5e6ab732..7205d0e850 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -18,25 +18,27 @@
//Meteor spawning global procs
///////////////////////////////
-/proc/spawn_meteors(var/number = 10, var/list/meteortypes)
- for(var/i = 0; i < number; i++)
- spawn_meteor(meteortypes)
+/proc/pick_meteor_start(var/startSide = pick(cardinal))
+ var/startLevel = pick(config.station_levels)
+ var/pickedstart = spaceDebrisStartLoc(startSide, startLevel)
+
+ return list(startLevel, pickedstart)
+
+/proc/spawn_meteors(var/number = 10, var/list/meteortypes, var/startSide)
+ for(var/i = 0; i < number; i++)
+ spawn_meteor(meteortypes, startSide)
+
+/proc/spawn_meteor(var/list/meteortypes, var/startSide)
+ var/start = pick_meteor_start(startSide)
+
+ var/startLevel = start[1]
+ var/turf/pickedstart = start[2]
+ var/turf/pickedgoal = spaceDebrisFinishLoc(startSide, startLevel)
-/proc/spawn_meteor(var/list/meteortypes)
- var/turf/pickedstart
- var/turf/pickedgoal
- var/max_i = 10//number of tries to spawn meteor.
- while (!istype(pickedstart, /turf/space))
- var/startSide = pick(cardinal)
- pickedstart = spaceDebrisStartLoc(startSide, 1)
- pickedgoal = spaceDebrisFinishLoc(startSide, 1)
- max_i--
- if(max_i<=0)
- return
var/Me = pickweight(meteortypes)
var/obj/effect/meteor/M = new Me(pickedstart)
M.dest = pickedgoal
- M.z_original = 1
+ M.z_original = startLevel
spawn(0)
walk_towards(M, M.dest, 1)
return
@@ -95,7 +97,6 @@
var/dest
pass_flags = PASSTABLE
var/heavy = 0
- var/meteorsound = 'sound/effects/meteorimpact.ogg'
var/z_original = 1
var/meteordrop = /obj/item/weapon/ore/iron
@@ -128,9 +129,11 @@
/obj/effect/meteor/Bump(atom/A)
if(A)
ram_turf(get_turf(A))
- playsound(src.loc, meteorsound, 40, 1)
get_hit()
+/obj/effect/meteor/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ return istype(mover, /obj/effect/meteor) ? 1 : ..()
+
/obj/effect/meteor/proc/ram_turf(var/turf/T)
//first bust whatever is in the turf
for(var/atom/A in T)
@@ -165,15 +168,15 @@
var/obj/item/O = new meteordrop(get_turf(src))
O.throw_at(dest, 5, 10)
-/obj/effect/meteor/proc/meteor_effect(var/sound=1)
- if(sound)
+/obj/effect/meteor/proc/meteor_effect(var/effect=1)
+ if(effect)
for(var/mob/M in player_list)
var/turf/T = get_turf(M)
if(!T || T.z != src.z)
continue
var/dist = get_dist(M.loc, src.loc)
shake_camera(M, dist > 20 ? 3 : 5, dist > 20 ? 1 : 3)
- M.playsound_local(src.loc, meteorsound, 50, 1, get_rand_frequency(), 10)
+
///////////////////////
//Meteor types
@@ -186,7 +189,6 @@
pass_flags = PASSTABLE | PASSGRILLE
hits = 1
hitpwr = 3
- meteorsound = 'sound/weapons/throwtap.ogg'
meteordrop = /obj/item/weapon/ore/glass
//Medium-sized
@@ -200,7 +202,7 @@
//Large-sized
/obj/effect/meteor/big
- name = "big meteor"
+ name = "large meteor"
icon_state = "large"
hits = 6
heavy = 1
@@ -216,7 +218,6 @@
icon_state = "flaming"
hits = 5
heavy = 1
- meteorsound = 'sound/effects/bamf.ogg'
meteordrop = /obj/item/weapon/ore/phoron
/obj/effect/meteor/flaming/meteor_effect()
@@ -246,7 +247,6 @@
hits = 30
hitpwr = 1
heavy = 1
- meteorsound = 'sound/effects/bamf.ogg'
meteordrop = /obj/item/weapon/ore/phoron
/obj/effect/meteor/tunguska/meteor_effect()
diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm
index ad2abb2236..df75722aeb 100644
--- a/code/game/gamemodes/sandbox/h_sandbox.dm
+++ b/code/game/gamemodes/sandbox/h_sandbox.dm
@@ -105,7 +105,7 @@ datum/hSB
hsb.req_access += A
hsb.loc = usr.loc
- usr << "Sandbox: Created an airlock."
+ usr << "Sandbox: Created an airlock."
if("hsbcanister")
var/list/hsbcanisters = typesof(/obj/machinery/portable_atmospherics/canister/) - /obj/machinery/portable_atmospherics/canister/
var/hsbcanister = input(usr, "Choose a canister to spawn.", "Sandbox:") in hsbcanisters + "Cancel"
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index a4ae776bbf..bdf6925d0a 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -15,7 +15,7 @@
required_enemies = 1
end_on_antag_death = 0
antag_tags = list(MODE_TRAITOR)
- antag_scaling_coeff = 10
+ antag_scaling_coeff = 8
/datum/game_mode/traitor/auto
name = "autotraitor"
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index f375755982..37f00428dd 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -424,6 +424,9 @@ var/global/datum/controller/occupations/job_master
S = locate("start*[rank]") // use old stype
if(istype(S, /obj/effect/landmark/start) && istype(S.loc, /turf))
H.loc = S.loc
+ else
+ LateSpawn(H, rank)
+
// Moving wheelchair if they have one
if(H.buckled && istype(H.buckled, /obj/structure/bed/chair/wheelchair))
H.buckled.loc = H.loc
@@ -611,3 +614,23 @@ var/global/datum/controller/occupations/job_master
tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|YOUNG=[level6]|-"
feedback_add_details("job_preferences",tmp_str)
+
+/datum/controller/occupations/proc/LateSpawn(var/mob/living/carbon/human/H, var/rank)
+ //spawn at one of the latespawn locations
+
+ var/datum/spawnpoint/spawnpos
+
+ if(H.client.prefs.spawnpoint)
+ spawnpos = spawntypes[H.client.prefs.spawnpoint]
+
+ if(spawnpos && istype(spawnpos))
+ if(spawnpos.check_job_spawning(rank))
+ H.loc = pick(spawnpos.turfs)
+ . = spawnpos.msg
+ else
+ H << "Your chosen spawnpoint ([spawnpos.display_name]) is unavailable for your chosen job. Spawning you at the Arrivals shuttle instead."
+ H.loc = pick(latejoin)
+ . = "has arrived on the station"
+ else
+ H.loc = pick(latejoin)
+ . = "has arrived on the station"
diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm
index c8e129ab8c..8f0a0535b1 100644
--- a/code/game/machinery/OpTable.dm
+++ b/code/game/machinery/OpTable.dm
@@ -41,10 +41,6 @@
else
return
-/obj/machinery/optable/blob_act()
- if(prob(75))
- qdel(src)
-
/obj/machinery/optable/attack_hand(mob/user as mob)
if (HULK in usr.mutations)
visible_message("\The [usr] destroys \the [src]!")
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index 6788f4a307..116d3b772d 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -129,12 +129,6 @@
else
return
-/obj/machinery/bodyscanner/blob_act()
- if(prob(50))
- for(var/atom/movable/A as mob|obj in src)
- A.loc = src.loc
- qdel(src)
-
/obj/machinery/body_scanconsole/ex_act(severity)
switch(severity)
@@ -150,11 +144,6 @@
else
return
-/obj/machinery/body_scanconsole/blob_act()
-
- if(prob(50))
- qdel(src)
-
/obj/machinery/body_scanconsole/power_change()
..()
if(stat & BROKEN)
@@ -233,7 +222,7 @@
dat = format_occupant_data(src.connected.get_occupant_data())
dat += "Print "
else
- dat = " Error: No Body Scanner connected."
+ dat = "Error: No Body Scanner connected."
dat += text(" Close", user)
user << browse(dat, "window=scanconsole;size=430x600")
@@ -306,30 +295,30 @@
aux = "Unconscious"
else
aux = "Dead"
- dat += text("[]\tHealth %: [] ([]) ", (occ["health"] > 50 ? "" : ""), occ["health"], aux)
+ dat += text("[]\tHealth %: [] ([]) ", ("Viral pathogen detected in blood stream. "
- dat += text("[]\t-Brute Damage %: [] ", (occ["bruteloss"] < 60 ? "" : ""), occ["bruteloss"])
- dat += text("[]\t-Respiratory Damage %: [] ", (occ["oxyloss"] < 60 ? "" : ""), occ["oxyloss"])
- dat += text("[]\t-Toxin Content %: [] ", (occ["toxloss"] < 60 ? "" : ""), occ["toxloss"])
- dat += text("[]\t-Burn Severity %: []
Extended (175)Unreal (250)"
if(vendmode == 0 || vendmode == 1)
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index 1546ed4c4b..cbb5728354 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -625,8 +625,3 @@
name = initial(name)
if(occupant)
name = "[name] ([occupant])"
-
-
-//Attacks/effects.
-/obj/machinery/cryopod/blob_act()
- return //Sorta gamey, but we don't really want these to be destroyed.
diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm
index ccf2fb97ae..0140a33fe3 100644
--- a/code/game/machinery/deployable.dm
+++ b/code/game/machinery/deployable.dm
@@ -131,13 +131,6 @@ for reference:
dismantle()
return
-/obj/structure/barricade/blob_act()
- src.health -= 25
- if (src.health <= 0)
- visible_message("The blob eats through \the [src]!")
- qdel(src)
- return
-
/obj/structure/barricade/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)//So bullets will fly over and stuff.
if(air_group || (height==0))
return 1
@@ -232,12 +225,6 @@ for reference:
anchored = !anchored
icon_state = "barrier[src.locked]"
- blob_act()
- src.health -= 25
- if (src.health <= 0)
- src.explode()
- return
-
CanPass(atom/movable/mover, turf/target, height=0, air_group=0)//So bullets will fly over and stuff.
if(air_group || (height==0))
return 1
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index b8c58351ee..9b7abebded 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -671,7 +671,7 @@ About the new airlock wires panel:
return
/obj/machinery/door/airlock/CanUseTopic(var/mob/user)
- if(!user.isSilicon())
+ if(issilicon(user))
return STATUS_CLOSE
if(operating < 0) //emagged
@@ -926,6 +926,9 @@ About the new airlock wires panel:
health -= crush_damage
healthcheck()
+/obj/effect/energy_field/airlock_crush(var/crush_damage)
+ Stress(crush_damage)
+
/obj/structure/closet/airlock_crush(var/crush_damage)
..()
damage(crush_damage)
@@ -1053,10 +1056,9 @@ About the new airlock wires panel:
break
/obj/machinery/door/airlock/Destroy()
- if(wires)
- qdel(wires)
- wires = null
- ..()
+ qdel(wires)
+ wires = null
+ return ..()
// Most doors will never be deconstructed over the course of a round,
// so as an optimization defer the creation of electronics until
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 33f61fb1ec..2d1680aa7d 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -99,7 +99,7 @@
var/mob/M = AM
if(world.time - M.last_bumped <= 10) return //Can bump-open one airlock per second. This is to prevent shock spam.
M.last_bumped = world.time
- if(!M.restrained() && !M.small)
+ if(!M.restrained() && !issmall(M))
bumpopen(M)
return
@@ -156,12 +156,10 @@
/obj/machinery/door/bullet_act(var/obj/item/projectile/Proj)
..()
- //Tasers and the like should not damage doors. Nor should TOX, OXY, CLONE, etc damage types
- if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
- return
+ var/damage = Proj.get_structure_damage()
// Emitter Blasts - these will eventually completely destroy the door, given enough time.
- if (Proj.damage > 90)
+ if (damage > 90)
destroy_hits--
if (destroy_hits <= 0)
visible_message("\The [src.name] disintegrates!")
@@ -173,9 +171,9 @@
new /obj/effect/decal/cleanable/ash(src.loc) // Turn it to ashes!
qdel(src)
- if(Proj.damage)
+ if(damage)
//cap projectile damage so that there's still a minimum number of hits required to break the door
- take_damage(min(Proj.damage, 100))
+ take_damage(min(damage, 100))
@@ -335,12 +333,6 @@
return
-/obj/machinery/door/blob_act()
- if(prob(40))
- qdel(src)
- return
-
-
/obj/machinery/door/emp_act(severity)
if(prob(20/severity) && (istype(src,/obj/machinery/door/airlock) || istype(src,/obj/machinery/door/window)) )
spawn(0)
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index ae25da7745..08d47db158 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -147,7 +147,7 @@
"\The [src]", "Yes, [density ? "open" : "close"]", "No")
if(answer == "No")
return
- if(user.stat || user.stunned || user.weakened || user.paralysis || (!user.canmove && !user.isSilicon()) || (get_dist(src, user) > 1 && !isAI(user)))
+ if(user.incapacitated() || (get_dist(src, user) > 1 && !issilicon(user)))
user << "Sorry, you must remain able bodied and close to \the [src] in order to use it."
return
if(density && (stat & (BROKEN|NOPOWER))) //can still close without power
@@ -167,7 +167,7 @@
if(alarmed)
// Accountability!
users_to_open |= user.name
- needs_to_close = !user.isSilicon()
+ needs_to_close = !issilicon(user)
spawn()
open()
else
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index e50af2bcf0..88eda4c774 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -77,7 +77,7 @@
return
if (src.operating)
return
- if (src.density && !M.small && src.allowed(AM))
+ if (src.density && !issmall(M) && src.allowed(AM))
open()
if(src.check_access(null))
sleep(50)
diff --git a/code/game/machinery/floor_light.dm b/code/game/machinery/floor_light.dm
index 0eff1a3e3c..9267f1edbe 100644
--- a/code/game/machinery/floor_light.dm
+++ b/code/game/machinery/floor_light.dm
@@ -43,7 +43,7 @@ var/list/floor_light_cache = list()
/obj/machinery/floor_light/attack_hand(var/mob/user)
- if(user.a_intent == "hurt" && !user.small)
+ if(user.a_intent == I_HURT && !issmall(user))
if(!isnull(damaged) && !(stat & BROKEN))
visible_message("\The [user] smashes \the [src]!")
playsound(src, "shatter", 70, 1)
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 3a4d51715b..501ec06629 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -195,10 +195,6 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
qdel(src)
return
-/obj/machinery/hologram/blob_act()
- qdel(src)
- return
-
/obj/machinery/hologram/holopad/Destroy()
for (var/mob/living/silicon/ai/master in masters)
clear_holo(master)
diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm
index 3d18d80a1e..9a950cc023 100644
--- a/code/game/machinery/kitchen/gibber.dm
+++ b/code/game/machinery/kitchen/gibber.dm
@@ -88,7 +88,7 @@
emagged = !emagged
user << "You [emagged ? "disable" : "enable"] the gibber safety guard."
return 1
-
+
/obj/machinery/gibber/attackby(var/obj/item/W, var/mob/user)
var/obj/item/weapon/grab/G = W
@@ -195,7 +195,7 @@
slab_type = H.species.meat_type
// Small mobs don't give as much nutrition.
- if(src.occupant.small)
+ if(issmall(src.occupant))
slab_nutrition *= 0.5
slab_nutrition /= slab_count
diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm
index bc52c276c3..b1b2cf27f3 100644
--- a/code/game/machinery/kitchen/smartfridge.dm
+++ b/code/game/machinery/kitchen/smartfridge.dm
@@ -35,7 +35,8 @@
/obj/machinery/smartfridge/Destroy()
qdel(wires)
- ..()
+ wires = null
+ return ..()
/obj/machinery/smartfridge/proc/accept_check(var/obj/item/O as obj)
if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown/) || istype(O,/obj/item/seeds/))
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 709f4b4626..455c6256a4 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -171,10 +171,6 @@ Class Procs:
else
return
-/obj/machinery/blob_act()
- if(prob(50))
- qdel(src)
-
//sets the use_power var and then forces an area power update
/obj/machinery/proc/update_use_power(var/new_use_power)
use_power = new_use_power
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index 9efa7bd4f3..f80e71ef42 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -417,7 +417,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
dat+="Channel messages listed below. If you deem them dangerous to the station, you can Bestow a D-Notice upon the channel."
if(src.viewing_channel.censored)
dat+="ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a [company_name] D-Notice. "
- dat+="No further feed story additions are allowed while the D-Notice is in effect.
"
+ dat+="No further feed story additions are allowed while the D-Notice is in effect.
"
else
if( isemptylist(src.viewing_channel.messages) )
dat+="No feed messages found in channel... "
diff --git a/code/game/machinery/nuclear_bomb.dm b/code/game/machinery/nuclear_bomb.dm
index 85b387fe7b..d02d3522a4 100644
--- a/code/game/machinery/nuclear_bomb.dm
+++ b/code/game/machinery/nuclear_bomb.dm
@@ -362,13 +362,6 @@ obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob)
/obj/machinery/nuclearbomb/ex_act(severity)
return
-/obj/machinery/nuclearbomb/blob_act()
- if (src.timing == -1.0)
- return
- else
- return ..()
- return
-
#define NUKERANGE 80
/obj/machinery/nuclearbomb/proc/explode()
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index 94f9bc70df..553cf612d5 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -174,11 +174,11 @@ var/list/turret_icons
icon_state = "turretCover"
/obj/machinery/porta_turret/proc/isLocked(mob/user)
- if(ailock && user.isSilicon())
+ if(ailock && issilicon(user))
user << "There seems to be a firewall preventing you from accessing this device."
return 1
- if(locked && !user.isSilicon())
+ if(locked && !issilicon(user))
user << "Access denied."
return 1
@@ -375,7 +375,9 @@ var/list/turret_icons
die() //the death process :(
/obj/machinery/porta_turret/bullet_act(obj/item/projectile/Proj)
- if(Proj.damage_type == HALLOSS)
+ var/damage = Proj.get_structure_damage()
+
+ if(!damage)
return
if(enabled)
@@ -387,8 +389,7 @@ var/list/turret_icons
..()
- if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
- take_damage(Proj.damage)
+ take_damage(damage)
/obj/machinery/porta_turret/emp_act(severity)
if(enabled)
@@ -412,7 +413,6 @@ var/list/turret_icons
/obj/machinery/porta_turret/ex_act(severity)
switch (severity)
if (1)
- del(src)
qdel(src)
if (2)
if (prob(25))
@@ -444,14 +444,8 @@ var/list/turret_icons
var/list/targets = list() //list of primary targets
var/list/secondarytargets = list() //targets that are least important
- for(var/obj/mecha/ME in view(7,src))
- assess_and_assign(ME.occupant, targets, secondarytargets)
-
- for(var/obj/vehicle/train/T in view(7,src))
- assess_and_assign(T.load, targets, secondarytargets)
-
- for(var/mob/living/C in view(7,src)) //loops through all living lifeforms in view
- assess_and_assign(C, targets, secondarytargets)
+ for(var/mob/M in mobs_in_view(world.view, src))
+ assess_and_assign(M, targets, secondarytargets)
if(!tryToShootAt(targets))
if(!tryToShootAt(secondarytargets)) // if no valid targets, go for secondary targets
@@ -700,7 +694,7 @@ var/list/turret_icons
playsound(loc, 'sound/items/Crowbar.ogg', 75, 1)
user << "You dismantle the turret construction."
new /obj/item/stack/material/steel( loc, 5)
- qdel(src) // qdel
+ qdel(src)
return
if(1)
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index c20ca8468a..ac5ae8d8c7 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -196,47 +196,51 @@
if(icon_update_tick == 0)
build_overlays()
-/obj/machinery/recharge_station/Bumped(var/mob/AM)
- move_inside(AM)
+/obj/machinery/recharge_station/Bumped(var/mob/living/silicon/robot/R)
+ go_in(R)
+
+/obj/machinery/recharge_station/proc/go_in(var/mob/living/silicon/robot/R)
+ if(!istype(R))
+ return
+ if(occupant)
+ return
+
+ if(R.incapacitated())
+ return
+ if(!R.cell)
+ return
+
+ add_fingerprint(R)
+ R.reset_view(src)
+ R.forceMove(src)
+ occupant = R
+ update_icon()
+ return 1
/obj/machinery/recharge_station/proc/go_out()
- if(!(occupant))
+ if(!occupant)
return
- occupant.loc = loc
+
+ occupant.forceMove(loc)
occupant.reset_view()
occupant = null
update_icon()
- return
/obj/machinery/recharge_station/verb/move_eject()
set category = "Object"
+ set name = "Eject Recharger"
set src in oview(1)
- if(usr.stat != 0)
+
+ if(usr.incapacitated())
return
+
go_out()
add_fingerprint(usr)
return
/obj/machinery/recharge_station/verb/move_inside()
set category = "Object"
+ set name = "Enter Recharger"
set src in oview(1)
- if(usr.stat == DEAD)
- return
- if(occupant)
- usr << "\The [src] is already occupied!"
- return
-
- 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
-
- usr.reset_view(src)
- usr.loc = src
- occupant = usr
- add_fingerprint(usr)
- update_icon()
+ go_in(usr)
diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm
index cf67c4d01f..dd862a7754 100644
--- a/code/game/machinery/status_display.dm
+++ b/code/game/machinery/status_display.dm
@@ -28,6 +28,7 @@
var/message2 = "" // message line 2
var/index1 // display index for scrolling messages or 0 if non-scrolling
var/index2
+ var/picture = null
var/frequency = 1435 // radio frequency
@@ -48,7 +49,7 @@
/obj/machinery/status_display/Destroy()
if(radio_controller)
radio_controller.remove_object(src,frequency)
- ..()
+ return ..()
// register for radio system
/obj/machinery/status_display/initialize()
@@ -72,13 +73,13 @@
// set what is displayed
/obj/machinery/status_display/proc/update()
+ remove_display()
if(friendc && !ignore_friendc)
set_picture("ai_friend")
return 1
switch(mode)
if(STATUS_DISPLAY_BLANK) //blank
- remove_display()
return 1
if(STATUS_DISPLAY_TRANSFER_SHUTTLE_TIME) //emergency shuttle timer
if(emergency_shuttle.waiting_to_leave())
@@ -96,8 +97,6 @@
if(length(message2) > CHARS_PER_LINE)
message2 = "Error"
update_display(message1, message2)
- else
- remove_display()
return 1
if(STATUS_DISPLAY_MESSAGE) //custom messages
var/line1
@@ -122,6 +121,9 @@
index2 -= message2_len
update_display(line1, line2)
return 1
+ if(STATUS_DISPLAY_ALERT)
+ set_picture(picture_state)
+ return 1
if(STATUS_DISPLAY_TIME)
message1 = "TIME"
message2 = worldtime2text()
@@ -150,9 +152,11 @@
index2 = 0
/obj/machinery/status_display/proc/set_picture(state)
- picture_state = state
remove_display()
- overlays += image('icons/obj/status_display.dmi', icon_state=picture_state)
+ if(!picture || picture_state != state)
+ picture_state = state
+ picture = image('icons/obj/status_display.dmi', icon_state=picture_state)
+ overlays |= picture
/obj/machinery/status_display/proc/update_display(line1, line2)
var/new_text = {"
[line1] [line2]
"}
@@ -207,7 +211,7 @@
if("time")
mode = STATUS_DISPLAY_TIME
-
+ update()
#undef CHARS_PER_LINE
#undef FOND_SIZE
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index ac561009b6..28126b3d3b 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -99,8 +99,8 @@
if(src.panelopen) //The maintenance panel is open. Time for some shady stuff
dat+= "Suit storage unit: Maintenance panel"
dat+= "Maintenance panel controls"
- dat+= "The panel is ridden with controls, button and meters, labeled in strange signs and symbols that you cannot understand. Probably the manufactoring world's language. Among other things, a few controls catch your eye.
"
- dat+= text("A small dial with a small lambda symbol on it. It's pointing towards a gauge that reads []. Turn towards [] ",(src.issuperUV ? "15nm" : "185nm"),src,(src.issuperUV ? "185nm" : "15nm") )
+ dat+= "The panel is ridden with controls, button and meters, labeled in strange signs and symbols that you cannot understand. Probably the manufactoring world's language. Among other things, a few controls catch your eye.
"
+ dat+= text("A small dial with a small lambda symbol on it. It's pointing towards a gauge that reads []. Turn towards [] ",(src.issuperUV ? "15nm" : "185nm"),src,(src.issuperUV ? "185nm" : "15nm") )
dat+= text("A thick old-style button, with 2 grimy LED lights next to it. The [] LED is on. Press button",(src.safetieson? "GREEN" : "RED"),src)
dat+= text(" Close panel", user)
//user << browse(dat, "window=ssu_m_panel;size=400x500")
@@ -116,7 +116,7 @@
if(!src.isbroken)
dat+= "Suit storage unit"
dat+= "U-Stor-It Suit Storage Unit, model DS1900 "
- dat+= "Welcome to the Unit control panel."
+ dat+= "Welcome to the Unit control panel."
dat+= text("Helmet storage compartment: [] ",(src.HELMET ? HELMET.name : "No helmet detected.") )
if(HELMET && src.isopen)
dat+=text("Dispense helmet ",src)
@@ -330,7 +330,7 @@
for(i=0,i<4,i++)
sleep(50)
if(src.OCCUPANT)
- OCCUPANT.radiation += 50
+ OCCUPANT.apply_effect(50, IRRADIATE)
var/obj/item/organ/diona/nutrients/rad_organ = locate() in OCCUPANT.internal_organs
if (!rad_organ)
if(src.issuperUV)
@@ -617,7 +617,7 @@
/obj/machinery/suit_cycler/Destroy()
qdel(wires)
wires = null
- ..()
+ return ..()
/obj/machinery/suit_cycler/engineering
name = "Engineering suit cycler"
@@ -755,7 +755,7 @@
return
..()
-
+
/obj/machinery/suit_cycler/emag_act(var/remaining_charges, var/mob/user)
if(emagged)
user << "The cycler has already been subverted."
@@ -811,7 +811,7 @@
dat += "\[select power level\]\[begin decontamination cycle\] "
dat += "
"
- usr << browse(output,"window=lookupbans;size=900x700")
\ No newline at end of file
+ usr << browse(output,"window=lookupbans;size=900x700")
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index d5a54b33b2..d7024147d0 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -58,7 +58,7 @@ proc/admin_notice(var/message, var/rights)
TP -
PM -
SM -
- [admin_jump_link(M, src)]\]
+ [admin_jump_link(M, src)]\] Mob type = [M.type]
Kick |
Warn |
@@ -335,7 +335,7 @@ proc/admin_notice(var/message, var/rights)
if(0)
dat += {"Welcome to the admin newscaster. Here you can add, edit and censor every newspiece on the network.
Feed channels and stories entered through here will be uneditable and handled as official news by the rest of the units.
- Note that this panel allows full freedom over the news network, there are no constrictions except the few basic ones. Don't break things!
+ Note that this panel allows full freedom over the news network, there are no constrictions except the few basic ones. Don't break things!
"}
if(news_network.wanted_issue)
dat+= "Read Wanted Issue"
@@ -420,7 +420,7 @@ proc/admin_notice(var/message, var/rights)
if(src.admincaster_feed_channel.censored)
dat+={"
ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a [company_name] D-Notice.
- No further feed story additions are allowed while the D-Notice is in effect.
+ No further feed story additions are allowed while the D-Notice is in effect.
"}
else
if( isemptylist(src.admincaster_feed_channel.messages) )
@@ -487,7 +487,7 @@ proc/admin_notice(var/message, var/rights)
if(src.admincaster_feed_channel.censored)
dat+={"
ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a [company_name] D-Notice.
- No further feed story additions are allowed while the D-Notice is in effect.
+ No further feed story additions are allowed while the D-Notice is in effect.
"}
else
if( isemptylist(src.admincaster_feed_channel.messages) )
@@ -634,7 +634,7 @@ proc/admin_notice(var/message, var/rights)
if(confirm == "Cancel")
return
if(confirm == "Yes")
- world << "\red Restarting world! \blue Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key]!"
+ world << "Restarting world!Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key]!"
log_admin("[key_name(usr)] initiated a reboot.")
feedback_set_details("end_error","admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]")
@@ -657,7 +657,8 @@ proc/admin_notice(var/message, var/rights)
if(message)
if(!check_rights(R_SERVER,0))
message = sanitize(message, 500, extra = 0)
- world << "\blue [usr.client.holder.fakekey ? "Administrator" : usr.key] Announces:\n \t [message]"
+ message = replacetext(message, "\n", " ") // required since we're putting it in a
tag
+ world << "[usr.client.holder.fakekey ? "Administrator" : usr.key] Announces:
[message]
"
log_admin("Announce: [key_name(usr)] : [message]")
feedback_add_details("admin_verb","A") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/admin_report.dm b/code/modules/admin/admin_report.dm
index b0f43741d0..c5cff737ee 100644
--- a/code/modules/admin/admin_report.dm
+++ b/code/modules/admin/admin_report.dm
@@ -1,180 +1,180 @@
-// Reports are a way to notify admins of wrongdoings that happened
-// while no admin was present. They work a bit similar to news, but
-// they can only be read by admins and moderators.
-
-// a single admin report
-datum/admin_report/var
- ID // the ID of the report
- body // the content of the report
- author // key of the author
- date // date on which this was created
- done // whether this was handled
-
- offender_key // store the key of the offender
- offender_cid // store the cid of the offender
-
-datum/report_topic_handler
- Topic(href,href_list)
- ..()
- var/client/C = locate(href_list["client"])
- if(href_list["action"] == "show_reports")
- C.display_admin_reports()
- else if(href_list["action"] == "remove")
- C.mark_report_done(text2num(href_list["ID"]))
- else if(href_list["action"] == "edit")
- C.edit_report(text2num(href_list["ID"]))
-
-var/datum/report_topic_handler/report_topic_handler
-
-world/New()
- ..()
- report_topic_handler = new
-
-// add a new news datums
-proc/make_report(body, author, okey, cid)
- var/savefile/Reports = new("data/reports.sav")
- var/list/reports
- var/lastID
-
- Reports["reports"] >> reports
- Reports["lastID"] >> lastID
-
- if(!reports) reports = list()
- if(!lastID) lastID = 0
-
- var/datum/admin_report/created = new()
- created.ID = ++lastID
- created.body = body
- created.author = author
- created.date = world.realtime
- created.done = 0
- created.offender_key = okey
- created.offender_cid = cid
-
- reports.Insert(1, created)
-
- Reports["reports"] << reports
- Reports["lastID"] << lastID
-
-// load the reports from disk
-proc/load_reports()
- var/savefile/Reports = new("data/reports.sav")
- var/list/reports
-
- Reports["reports"] >> reports
-
- if(!reports) reports = list()
-
- return reports
-
-// check if there are any unhandled reports
-client/proc/unhandled_reports()
- if(!src.holder) return 0
- var/list/reports = load_reports()
-
- for(var/datum/admin_report/N in reports)
- if(N.done)
- continue
- else return 1
-
- return 0
-
-// checks if the player has an unhandled report against him
-client/proc/is_reported()
- var/list/reports = load_reports()
-
- for(var/datum/admin_report/N in reports) if(!N.done)
- if(N.offender_key == src.key)
- return 1
-
- return 0
-
-// display only the reports that haven't been handled
-client/proc/display_admin_reports()
- set category = "Admin"
- set name = "Display Admin Reports"
- if(!src.holder) return
-
- var/list/reports = load_reports()
-
- var/output = ""
- if(unhandled_reports())
- // load the list of unhandled reports
- for(var/datum/admin_report/N in reports)
- if(N.done)
- continue
- output += "Reported player: [N.offender_key](CID: [N.offender_cid]) "
- output += "Offense:[N.body] "
- output += "Occured at [time2text(N.date,"MM/DD hh:mm:ss")] "
- output += "authored by [N.author] "
- output += " Flag as Handled"
- if(src.key == N.author)
- output += " Edit"
- output += " "
- output += " "
- else
- output += "Whoops, no reports!"
-
- usr << browse(output, "window=news;size=600x400")
-
-
-client/proc/Report(mob/M as mob in world)
- set category = "Admin"
- if(!src.holder)
- return
-
- var/CID = "Unknown"
- if(M.client)
- CID = M.client.computer_id
-
- var/body = input(src.mob, "Describe in detail what you're reporting [M] for", "Report") as null|text
- if(!body) return
-
-
- make_report(body, key, M.key, CID)
-
- spawn(1)
- display_admin_reports()
-
-client/proc/mark_report_done(ID as num)
- if(!src.holder || src.holder.level < 0)
- return
-
- var/savefile/Reports = new("data/reports.sav")
- var/list/reports
-
- Reports["reports"] >> reports
-
- var/datum/admin_report/found
- for(var/datum/admin_report/N in reports)
- if(N.ID == ID)
- found = N
- if(!found) src << "* An error occured, sorry."
-
- found.done = 1
-
- Reports["reports"] << reports
-
-
-client/proc/edit_report(ID as num)
- if(!src.holder || src.holder.level < 0)
- src << "You tried to modify the news, but you're not an admin!"
- return
-
- var/savefile/Reports = new("data/reports.sav")
- var/list/reports
-
- Reports["reports"] >> reports
-
- var/datum/admin_report/found
- for(var/datum/admin_report/N in reports)
- if(N.ID == ID)
- found = N
- if(!found) src << "* An error occured, sorry."
-
- var/body = input(src.mob, "Enter a body for the news", "Body") as null|message
- if(!body) return
-
- found.body = body
-
- Reports["reports"] << reports
+// Reports are a way to notify admins of wrongdoings that happened
+// while no admin was present. They work a bit similar to news, but
+// they can only be read by admins and moderators.
+
+// a single admin report
+datum/admin_report/var
+ ID // the ID of the report
+ body // the content of the report
+ author // key of the author
+ date // date on which this was created
+ done // whether this was handled
+
+ offender_key // store the key of the offender
+ offender_cid // store the cid of the offender
+
+datum/report_topic_handler
+ Topic(href,href_list)
+ ..()
+ var/client/C = locate(href_list["client"])
+ if(href_list["action"] == "show_reports")
+ C.display_admin_reports()
+ else if(href_list["action"] == "remove")
+ C.mark_report_done(text2num(href_list["ID"]))
+ else if(href_list["action"] == "edit")
+ C.edit_report(text2num(href_list["ID"]))
+
+var/datum/report_topic_handler/report_topic_handler
+
+world/New()
+ ..()
+ report_topic_handler = new
+
+// add a new news datums
+proc/make_report(body, author, okey, cid)
+ var/savefile/Reports = new("data/reports.sav")
+ var/list/reports
+ var/lastID
+
+ Reports["reports"] >> reports
+ Reports["lastID"] >> lastID
+
+ if(!reports) reports = list()
+ if(!lastID) lastID = 0
+
+ var/datum/admin_report/created = new()
+ created.ID = ++lastID
+ created.body = body
+ created.author = author
+ created.date = world.realtime
+ created.done = 0
+ created.offender_key = okey
+ created.offender_cid = cid
+
+ reports.Insert(1, created)
+
+ Reports["reports"] << reports
+ Reports["lastID"] << lastID
+
+// load the reports from disk
+proc/load_reports()
+ var/savefile/Reports = new("data/reports.sav")
+ var/list/reports
+
+ Reports["reports"] >> reports
+
+ if(!reports) reports = list()
+
+ return reports
+
+// check if there are any unhandled reports
+client/proc/unhandled_reports()
+ if(!src.holder) return 0
+ var/list/reports = load_reports()
+
+ for(var/datum/admin_report/N in reports)
+ if(N.done)
+ continue
+ else return 1
+
+ return 0
+
+// checks if the player has an unhandled report against him
+client/proc/is_reported()
+ var/list/reports = load_reports()
+
+ for(var/datum/admin_report/N in reports) if(!N.done)
+ if(N.offender_key == src.key)
+ return 1
+
+ return 0
+
+// display only the reports that haven't been handled
+client/proc/display_admin_reports()
+ set category = "Admin"
+ set name = "Display Admin Reports"
+ if(!src.holder) return
+
+ var/list/reports = load_reports()
+
+ var/output = ""
+ if(unhandled_reports())
+ // load the list of unhandled reports
+ for(var/datum/admin_report/N in reports)
+ if(N.done)
+ continue
+ output += "Reported player: [N.offender_key](CID: [N.offender_cid]) "
+ output += "Offense:[N.body] "
+ output += "Occured at [time2text(N.date,"MM/DD hh:mm:ss")] "
+ output += "authored by [N.author] "
+ output += " Flag as Handled"
+ if(src.key == N.author)
+ output += " Edit"
+ output += " "
+ output += " "
+ else
+ output += "Whoops, no reports!"
+
+ usr << browse(output, "window=news;size=600x400")
+
+
+client/proc/Report(mob/M as mob in world)
+ set category = "Admin"
+ if(!src.holder)
+ return
+
+ var/CID = "Unknown"
+ if(M.client)
+ CID = M.client.computer_id
+
+ var/body = input(src.mob, "Describe in detail what you're reporting [M] for", "Report") as null|text
+ if(!body) return
+
+
+ make_report(body, key, M.key, CID)
+
+ spawn(1)
+ display_admin_reports()
+
+client/proc/mark_report_done(ID as num)
+ if(!src.holder || src.holder.level < 0)
+ return
+
+ var/savefile/Reports = new("data/reports.sav")
+ var/list/reports
+
+ Reports["reports"] >> reports
+
+ var/datum/admin_report/found
+ for(var/datum/admin_report/N in reports)
+ if(N.ID == ID)
+ found = N
+ if(!found) src << "* An error occured, sorry."
+
+ found.done = 1
+
+ Reports["reports"] << reports
+
+
+client/proc/edit_report(ID as num)
+ if(!src.holder || src.holder.level < 0)
+ src << "You tried to modify the news, but you're not an admin!"
+ return
+
+ var/savefile/Reports = new("data/reports.sav")
+ var/list/reports
+
+ Reports["reports"] >> reports
+
+ var/datum/admin_report/found
+ for(var/datum/admin_report/N in reports)
+ if(N.ID == ID)
+ found = N
+ if(!found) src << "* An error occured, sorry."
+
+ var/body = input(src.mob, "Enter a body for the news", "Body") as null|message
+ if(!body) return
+
+ found.body = body
+
+ Reports["reports"] << reports
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 1524777466..977e79bd28 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -183,6 +183,7 @@ var/list/admin_verbs_debug = list(
/client/proc/show_plant_genes,
/client/proc/enable_debug_verbs,
/client/proc/callproc,
+ /client/proc/callproc_target,
/client/proc/toggledebuglogs,
/client/proc/SDQL_query,
/client/proc/SDQL2_query,
@@ -194,6 +195,7 @@ var/list/admin_verbs_debug = list(
var/list/admin_verbs_paranoid_debug = list(
/client/proc/callproc,
+ /client/proc/callproc_target,
/client/proc/debug_controller
)
@@ -263,6 +265,7 @@ var/list/admin_verbs_hideable = list(
/client/proc/restart_controller,
/client/proc/cmd_admin_list_open_jobs,
/client/proc/callproc,
+ /client/proc/callproc_target,
/client/proc/Debug2,
/client/proc/reload_admins,
/client/proc/kill_air,
@@ -408,7 +411,7 @@ var/list/admin_verbs_mentor = list(
var/mob/dead/observer/ghost = body.ghostize(1)
ghost.admin_ghosted = 1
if(body)
- body.aghosted = ghost
+ body.teleop = ghost
if(!body.key)
body.key = "@[key]" //Haaaaaaaack. But the people have spoken. If it breaks; blame adminbus
feedback_add_details("admin_verb","O") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -546,8 +549,8 @@ var/list/admin_verbs_mentor = list(
ban_unban_log_save("[ckey] warned [warned_ckey], resulting in a [AUTOBANTIME] minute autoban.")
if(C)
message_admins("[key_name_admin(src)] has warned [key_name_admin(C)] resulting in a [AUTOBANTIME] minute ban.")
- C << "You have been autobanned due to a warning by [ckey]. This is a temporary ban, it will be removed in [AUTOBANTIME] minutes."
- qdel(C)
+ C << "You have been autobanned due to a warning by [ckey]. This is a temporary ban, it will be removed in [AUTOBANTIME] minutes."
+ del(C)
else
message_admins("[key_name_admin(src)] has warned [warned_ckey] resulting in a [AUTOBANTIME] minute ban.")
AddBan(warned_ckey, D.last_id, "Autobanning due to too many formal warnings", ckey, 1, AUTOBANTIME)
diff --git a/code/modules/admin/callproc/callproc.dm b/code/modules/admin/callproc/callproc.dm
new file mode 100644
index 0000000000..9b3da2b92f
--- /dev/null
+++ b/code/modules/admin/callproc/callproc.dm
@@ -0,0 +1,152 @@
+
+/client/proc/callproc()
+ set category = "Debug"
+ set name = "Advanced ProcCall"
+
+ if(!check_rights(R_DEBUG)) return
+ if(config.debugparanoid && !check_rights(R_ADMIN)) return
+
+ var/target = null
+ var/targetselected = 0
+
+ switch(alert("Proc owned by something?",, "Yes", "No", "Cancel"))
+ if("Yes")
+ targetselected=1
+ switch(input("Proc owned by...", "Owner", null) as null|anything in list("Obj", "Mob", "Area or Turf", "Client"))
+ if("Obj")
+ target = input("Select target:", "Target") as null|obj in world
+ if("Mob")
+ target = input("Select target:", "Target", usr) as null|mob in world
+ if("Area or Turf")
+ target = input("Select target:", "Target", get_turf(usr)) as null|area|turf in world
+ if("Client")
+ target = input("Select target:", "Target", usr.client) as null|anything in clients
+ else
+ return
+ if(!target)
+ usr << "Proc call cancelled."
+ return
+ if("Cancel")
+ return
+ if("No")
+ ; // do nothing
+
+ callproc_targetpicked(targetselected, target)
+
+/client/proc/callproc_target(atom/A in world)
+ set category = "Debug"
+ set name = "Advanced ProcCall Target"
+
+ if(!check_rights(R_DEBUG)) return
+ if(config.debugparanoid && !check_rights(R_ADMIN)) return
+
+ callproc_targetpicked(1, A)
+
+/client/proc/callproc_targetpicked(hastarget, datum/target)
+
+ // this needs checking again here because VV's 'Call Proc' option directly calls this proc with the target datum
+ if(!check_rights(R_DEBUG)) return
+ if(config.debugparanoid && !check_rights(R_ADMIN)) return
+
+ var/returnval = null
+
+ var/procname = input("Proc name", "Proc") as null|text
+ if(!procname) return
+
+ if(hastarget)
+ if(!target)
+ usr << "Your callproc target no longer exists."
+ return
+ if(!hascall(target, procname))
+ usr << "\The [target] has no call [procname]()"
+ return
+
+ var/list/arguments = list()
+ var/done = 0
+ var/current = null
+
+ while(!done)
+ if(hastarget && !target)
+ usr << "Your callproc target no longer exists."
+ return
+ switch(input("Type of [arguments.len+1]\th variable", "argument [arguments.len+1]") as null|anything in list(
+ "finished", "null", "text", "num", "type", "obj reference", "mob reference",
+ "area/turf reference", "icon", "file", "client", "mob's area", "marked datum"))
+ if(null)
+ return
+
+ if("finished")
+ done = 1
+
+ if("null")
+ current = null
+
+ if("text")
+ current = input("Enter text for [arguments.len+1]\th argument") as null|text
+ if(isnull(current)) return
+
+ if("num")
+ current = input("Enter number for [arguments.len+1]\th argument") as null|num
+ if(isnull(current)) return
+
+ if("type")
+ current = input("Select type for [arguments.len+1]\th argument") as null|anything in typesof(/obj, /mob, /area, /turf)
+ if(isnull(current)) return
+
+ if("obj reference")
+ current = input("Select object for [arguments.len+1]\th argument") as null|obj in world
+ if(isnull(current)) return
+
+ if("mob reference")
+ current = input("Select mob for [arguments.len+1]\th argument") as null|mob in world
+ if(isnull(current)) return
+
+ if("area/turf reference")
+ current = input("Select area/turf for [arguments.len+1]\th argument") as null|area|turf in world
+ if(isnull(current)) return
+
+ if("icon")
+ current = input("Provide icon for [arguments.len+1]\th argument") as null|icon
+ if(isnull(current)) return
+
+ if("client")
+ current = input("Select client for [arguments.len+1]\th argument") as null|anything in clients
+ if(isnull(current)) return
+
+ if("mob's area")
+ var/mob/M = input("Select mob to take area for [arguments.len+1]\th argument") as null|mob in world
+ if(!M) return
+ current = get_area(M)
+ if(!current)
+ switch(alert("\The [M] appears to not have an area; do you want to pass null instead?",, "Yes", "Cancel"))
+ if("Yes")
+ ; // do nothing
+ if("Cancel")
+ return
+
+ if("marked datum")
+ current = holder.marked_datum
+ if(!current)
+ switch(alert("You do not currently have a marked datum; do you want to pass null instead?",, "Yes", "Cancel"))
+ if("Yes")
+ ; // do nothing
+ if("Cancel")
+ return
+ if(!done)
+ arguments += current
+
+ if(hastarget)
+ if(!target)
+ usr << "Your callproc target no longer exists."
+ return
+ log_admin("[key_name(src)] called [target]'s [procname]() with [arguments.len ? "the arguments [list2params(arguments)]" : "no arguments"].")
+ if(arguments.len)
+ returnval = call(target, procname)(arglist(arguments))
+ else
+ returnval = call(target, procname)()
+ else
+ log_admin("[key_name(src)] called [procname]() with [arguments.len ? "the arguments [list2params(arguments)]" : "no arguments"].")
+ returnval = call(procname)(arglist(arguments))
+
+ usr << "[procname]() returned: [isnull(returnval) ? "null" : returnval]"
+ feedback_add_details("admin_verb","APC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/map_capture.dm b/code/modules/admin/map_capture.dm
index b9d564d192..ced6d257bf 100644
--- a/code/modules/admin/map_capture.dm
+++ b/code/modules/admin/map_capture.dm
@@ -1,10 +1,17 @@
-/datum/admins/proc/capture_map(tx as num, ty as num, tz as num, range as num)
+/datum/admins/proc/capture_map(tx as null|num, ty as null|num, tz as null|num, range as null|num)
set category = "Server"
set name = "Capture Map Part"
+ set desc = "Usage: Capture-Map-Part target_x_cord target_y_cord target_z_cord range (captures part of a map originating from bottom left corner)"
if(!check_rights(R_ADMIN|R_DEBUG|R_SERVER))
return
+ if(isnull(tx) || isnull(ty) || isnull(tz) || isnull(range))
+ usr << "Capture Map Part, captures part of a map using camara like rendering."
+ usr << "Usage: Capture-Map-Part target_x_cord target_y_cord target_z_cord range"
+ usr << "Target coordinates specify bottom left corner of the capture, range defines render distance to opposite corner."
+ return
+
if(range > 32 || range <= 0)
usr << "Capturing range is incorrect, it must be within 1-32."
return
@@ -45,5 +52,8 @@
var/yoff = (A.y - ty) * 32
cap.Blend(img, blendMode2iconMode(A.blend_mode), A.pixel_x + xoff, A.pixel_y + yoff)
-
- usr << browse_rsc(cap, "map_capture_x[tx]_y[ty]_z[tz]_r[range].png")
\ No newline at end of file
+ var/file_name = "map_capture_x[tx]_y[ty]_z[tz]_r[range].png"
+ usr << "Saved capture in cache as [file_name]."
+ usr << browse_rsc(cap, file_name)
+ else
+ usr << "Target coordinates are incorrect."
diff --git a/code/modules/admin/permissionverbs/permissionedit.dm b/code/modules/admin/permissionverbs/permissionedit.dm
index 3bd563aaf5..e028fb7374 100644
--- a/code/modules/admin/permissionverbs/permissionedit.dm
+++ b/code/modules/admin/permissionverbs/permissionedit.dm
@@ -33,7 +33,7 @@
output += "
"
output += {"
diff --git a/code/modules/admin/player_notes.dm b/code/modules/admin/player_notes.dm
index 4a28ece915..b6293e7941 100644
--- a/code/modules/admin/player_notes.dm
+++ b/code/modules/admin/player_notes.dm
@@ -106,7 +106,7 @@ datum/admins/proc/notes_gethtml(var/ckey)
message_admins("\blue [key_name_admin(user)] has edited [key]'s notes.")
log_admin("[key_name(user)] has edited [key]'s notes.")
- qdel(info)
+ del(info) // savefile, so NOT qdel
//Updating list of keys with notes on them
var/savefile/note_list = new("data/player_notes.sav")
@@ -115,7 +115,7 @@ datum/admins/proc/notes_gethtml(var/ckey)
if(!note_keys) note_keys = list()
if(!note_keys.Find(key)) note_keys += key
note_list << note_keys
- qdel(note_list)
+ del(note_list) // savefile, so NOT qdel
/proc/notes_del(var/key, var/index)
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 9a9a2b44b7..9d9919e4ed 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -290,7 +290,7 @@
- [M_name] - [M_rname] - [M_key] ([M_job])
+ [M_name] - [M_rname] - [M_key] ([M_job])
diff --git a/code/modules/admin/secrets/admin_secrets/bombing_list.dm b/code/modules/admin/secrets/admin_secrets/bombing_list.dm
index fa3f268396..f94af7e569 100644
--- a/code/modules/admin/secrets/admin_secrets/bombing_list.dm
+++ b/code/modules/admin/secrets/admin_secrets/bombing_list.dm
@@ -6,7 +6,7 @@
if(!.)
return
- var/dat = "Bombing List"
+ var/dat = "Bombing List"
for(var/l in bombers)
dat += text("[l] ")
user << browse(dat, "window=bombers")
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index e3a2a83aab..a76565bf75 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -85,7 +85,7 @@
banreason = "[banreason] (CUSTOM CID)"
else
message_admins("Ban process: A mob matching [playermob.ckey] was found at location [playermob.x], [playermob.y], [playermob.z]. Custom ip and computer id fields replaced with the ip and computer id from the located mob")
- notes_add(playermob.ckey,banreason,usr)
+ notes_add(banckey,banreason,usr)
DB_ban_record(bantype, playermob, banduration, banreason, banjob, null, banckey, banip, bancid )
@@ -1334,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.isMobAI())
+ if(!isAI(L))
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."
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index d2fba72b79..11591be4b1 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -14,139 +14,7 @@
feedback_add_details("admin_verb","DG2") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-/* 21st Sept 2010
-Updated by Skie -- Still not perfect but better!
-Stuff you can't do:
-Call proc /mob/proc/make_dizzy() for some player
-Because if you select a player mob as owner it tries to do the proc for
-/mob/living/carbon/human/ instead. And that gives a run-time error.
-But you can call procs that are of type /mob/living/carbon/human/proc/ for that player.
-*/
-
-/client/proc/callproc()
- set category = "Debug"
- set name = "Advanced ProcCall"
-
- if(!check_rights(R_DEBUG)) return
- if(config.debugparanoid && !check_rights(R_ADMIN)) return
-
- spawn(0)
- var/target = null
- var/targetselected = 0
- var/lst[] // List reference
- lst = new/list() // Make the list
- var/returnval = null
- var/class = null
-
- switch(alert("Proc owned by something?",,"Yes","No"))
- if("Yes")
- targetselected = 1
- class = input("Proc owned by...","Owner",null) as null|anything in list("Obj","Mob","Area or Turf","Client")
- switch(class)
- if("Obj")
- target = input("Enter target:","Target",usr) as obj in world
- if("Mob")
- target = input("Enter target:","Target",usr) as mob in world
- if("Area or Turf")
- target = input("Enter target:","Target",usr.loc) as area|turf in world
- if("Client")
- var/list/keys = list()
- for(var/client/C)
- keys += C
- target = input("Please, select a player!", "Selection", null, null) as null|anything in keys
- else
- return
- if("No")
- target = null
- targetselected = 0
-
- 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
-
- lst.len = argnum // Expand to right length
- //TODO: make a list to store whether each argument was initialised as null.
- //Reason: So we can abort the proccall if say, one of our arguments was a mob which no longer exists
- //this will protect us from a fair few errors ~Carn
-
- var/i
- for(i=1, iError: callproc(): owner of proc no longer exists."
- 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
- 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
-
- usr << "[procname] returned: [returnval ? returnval : "null"]"
- feedback_add_details("admin_verb","APC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+// callproc moved to code/modules/admin/callproc
/client/proc/Cell()
set category = "Debug"
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index c68028635c..ba00a930b3 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -536,7 +536,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
message_admins("[key_name_admin(src)] has created a command report", 1)
feedback_add_details("admin_verb","CCR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-/client/proc/cmd_admin_delete(atom/O as obj|mob|turf in world)
+/client/proc/cmd_admin_delete(atom/O as obj|mob|turf in view())
set category = "Admin"
set name = "Delete"
@@ -778,7 +778,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(confirm != "Yes") return
var/choice
- if(ticker.mode.name == "revolution" || ticker.mode.name == "confliction")
+ if(ticker.mode.auto_recall_shuttle)
choice = input("The shuttle will just return if you call it. Call anyway?") in list("Confirm", "Cancel")
if(choice == "Confirm")
emergency_shuttle.auto_recall = 1 //enable auto-recall
@@ -865,7 +865,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
message_admins("Admin [key_name_admin(usr)] has forced the players to have random appearances.", 1)
if(notifyplayers == "Yes")
- world << "\blue Admin [usr.key] has forced the players to have completely random identities!"
+ world << "\blue Admin [usr.key] has forced the players to have completely random identities!"
usr << "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet."
diff --git a/code/modules/admin/view_variables/helpers.dm b/code/modules/admin/view_variables/helpers.dm
new file mode 100644
index 0000000000..44d524e06d
--- /dev/null
+++ b/code/modules/admin/view_variables/helpers.dm
@@ -0,0 +1,93 @@
+
+// Keep these two together, they *must* be defined on both
+// If /client ever becomes /datum/client or similar, they can be merged
+/client/proc/get_view_variables_header()
+ return "[src]"
+/datum/proc/get_view_variables_header()
+ return "[src]"
+
+/atom/get_view_variables_header()
+ return {"
+ [src]
+
+ <<
+ [dir2text(dir)]
+ >>
+
+ "}
+
+/mob/living/get_view_variables_header()
+ return {"
+ [src]
+ <<[dir2text(dir)]>>
+ [ckey ? ckey : "No ckey"] / [real_name ? real_name : "No real name"]
+
+ BRUTE:[getBruteLoss()]
+ FIRE:[getFireLoss()]
+ TOXIN:[getToxLoss()]
+ OXY:[getOxyLoss()]
+ CLONE:[getCloneLoss()]
+ BRAIN:[getBrainLoss()]
+
+ "}
+
+// Same for these as for get_view_variables_header() above
+/client/proc/get_view_variables_options()
+ return ""
+/datum/proc/get_view_variables_options()
+ return ""
+
+/mob/get_view_variables_options()
+ return ..() + {"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "}
+
+/mob/living/carbon/human/get_view_variables_options()
+ return ..() + {"
+
+
+
+
+
+
+ "}
+
+/obj/get_view_variables_options()
+ return ..() + {"
+
+
+
+ "}
+
+/turf/get_view_variables_options()
+ return ..() + {"
+
+
+ "}
diff --git a/code/datums/datumvars.dm b/code/modules/admin/view_variables/topic.dm
similarity index 53%
rename from code/datums/datumvars.dm
rename to code/modules/admin/view_variables/topic.dm
index 7e9fc0cd04..c842170b6b 100644
--- a/code/datums/datumvars.dm
+++ b/code/modules/admin/view_variables/topic.dm
@@ -1,416 +1,4 @@
-// reference: /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0)
-
-client
- proc/debug_variables(datum/D in world)
- set category = "Debug"
- set name = "View Variables"
- //set src in world
-
-
- if(!usr.client || !usr.client.holder)
- usr << "You need to be an administrator to access this."
- return
-
-
- var/title = ""
- var/body = ""
-
- if(!D) return
- if(istype(D, /atom))
- var/atom/A = D
- title = "[A.name] (\ref[A]) = [A.type]"
-
- #ifdef VARSICON
- if (A.icon)
- body += debug_variable("icon", new/icon(A.icon, A.icon_state, A.dir), 0)
- #endif
-
- var/icon/sprite
-
- if(istype(D,/atom))
- var/atom/AT = D
- if(AT.icon && AT.icon_state)
- sprite = new /icon(AT.icon, AT.icon_state)
- usr << browse_rsc(sprite, "view_vars_sprite.png")
-
- title = "[D] (\ref[D]) = [D.type]"
-
- body += {" "}
-
- body += ""
-
- body += "
"
-
- body += "E - Edit, tries to determine the variable type by itself. "
- body += "C - Change, asks you for the var type first. "
- body += "M - Mass modify: changes this variable for all objects of this type. "
-
- body += "
Search:
"
-
- body += ""
-
- var/list/names = list()
- for (var/V in D.vars)
- names += V
-
- names = sortList(names)
-
- for (var/V in names)
- body += debug_variable(V, D.vars[V], 0, D)
-
- body += ""
-
- var/html = ""
- if (title)
- html += "[title]"
- html += {""}
- html += ""
- html += body
-
- html += {"
-
- "}
-
- html += ""
-
- usr << browse(html, "window=variables\ref[D];size=475x650")
-
- return
-
- proc/debug_variable(name, value, level, var/datum/DA = null)
- var/html = ""
-
- if(DA)
- html += "
+
+
+ E - Edit, tries to determine the variable type by itself.
+ C - Change, asks you for the var type first.
+ M - Mass modify: changes this variable for all objects of this type.
+
+
+
"
diff --git a/code/modules/hydroponics/spreading/spreading_response.dm b/code/modules/hydroponics/spreading/spreading_response.dm
index c9ed2ee79e..2b9407aecd 100644
--- a/code/modules/hydroponics/spreading/spreading_response.dm
+++ b/code/modules/hydroponics/spreading/spreading_response.dm
@@ -7,7 +7,7 @@
if(!istype(M))
return
- if(!buckled_mob && !M.buckled && !M.anchored && (M.small || prob(round(seed.get_trait(TRAIT_POTENCY)/6))))
+ if(!buckled_mob && !M.buckled && !M.anchored && (issmall(M) || prob(round(seed.get_trait(TRAIT_POTENCY)/6))))
//wait a tick for the Entered() proc that called HasProximity() to finish (and thus the moving animation),
//so we don't appear to teleport from two tiles away when moving into a turf adjacent to vines.
spawn(1)
diff --git a/code/modules/hydroponics/trays/tray_update_icons.dm b/code/modules/hydroponics/trays/tray_update_icons.dm
index 7f31a06477..dc69e5448e 100644
--- a/code/modules/hydroponics/trays/tray_update_icons.dm
+++ b/code/modules/hydroponics/trays/tray_update_icons.dm
@@ -36,7 +36,9 @@
if(age >= seed.get_trait(TRAIT_MATURATION))
overlay_stage = seed.growth_stages
else
- var/maturation = round(seed.get_trait(TRAIT_MATURATION)/seed.growth_stages)
+ var/maturation = seed.get_trait(TRAIT_MATURATION)/seed.growth_stages
+ if(maturation < 1)
+ maturation = 1
overlay_stage = maturation ? max(1,round(age/maturation)) : 1
var/ikey = "[seed.get_trait(TRAIT_PLANT_ICON)]-[overlay_stage]"
var/image/plant_overlay = plant_controller.plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"]
diff --git a/code/modules/lighting/light_source.dm b/code/modules/lighting/light_source.dm
index 2acddb4d29..3675cd945c 100644
--- a/code/modules/lighting/light_source.dm
+++ b/code/modules/lighting/light_source.dm
@@ -1,3 +1,5 @@
+//So much copypasta in this file, supposedly in the name of performance. If you change anything make sure to consider other places where the code may have been copied.
+
/datum/light_source
var/atom/top_atom
var/atom/source_atom
@@ -11,9 +13,10 @@
var/lum_g
var/lum_b
- var/tmp/old_lum_r
- var/tmp/old_lum_g
- var/tmp/old_lum_b
+ //hold onto the actual applied lum values so we can undo them when the lighting changes
+ var/tmp/applied_lum_r
+ var/tmp/applied_lum_g
+ var/tmp/applied_lum_b
var/list/effect_str
var/list/effect_turf
@@ -107,11 +110,6 @@
if(light_range && light_power && !applied)
. = 1
- if(. || source_atom.light_color != light_color)//Save the old lumcounts if we need to update, if the colour changed DO IT BEFORE we parse the colour and LOSE the old lumcounts!
- old_lum_r = lum_r
- old_lum_g = lum_g
- old_lum_b = lum_b
-
if(source_atom.light_color != light_color)
light_color = source_atom.light_color
parse_light_color()
@@ -149,6 +147,12 @@
/datum/light_source/proc/apply_lum()
applied = 1
+
+ //Keep track of the last applied lum values so that the lighting can be reversed
+ applied_lum_r = lum_r
+ applied_lum_g = lum_g
+ applied_lum_b = lum_b
+
if(istype(source_turf))
FOR_DVIEW(var/turf/T, light_range, source_turf, INVISIBILITY_LIGHTING)
if(T.lighting_overlay)
@@ -164,9 +168,9 @@
effect_str += strength
T.lighting_overlay.update_lumcount(
- lum_r * strength,
- lum_g * strength,
- lum_b * strength
+ applied_lum_r * strength,
+ applied_lum_g * strength,
+ applied_lum_b * strength
)
else
@@ -188,7 +192,11 @@
if(T.lighting_overlay)
var/str = effect_str[i]
- T.lighting_overlay.update_lumcount(-str * old_lum_r, -str * old_lum_g, -str * old_lum_b)
+ T.lighting_overlay.update_lumcount(
+ -str * applied_lum_r,
+ -str * applied_lum_g,
+ -str * applied_lum_b
+ )
i++
@@ -218,9 +226,9 @@
effect_str += .
T.lighting_overlay.update_lumcount(
- lum_r * .,
- lum_g * .,
- lum_b * .
+ applied_lum_r * .,
+ applied_lum_g * .,
+ applied_lum_b * .
)
else
@@ -241,7 +249,7 @@
if(T.lighting_overlay)
var/str = effect_str[idx]
- T.lighting_overlay.update_lumcount(-str * lum_r, -str * lum_g, -str * lum_b)
+ T.lighting_overlay.update_lumcount(-str * applied_lum_r, -str * applied_lum_g, -str * applied_lum_b)
effect_turf.Cut(idx, idx + 1)
effect_str.Cut(idx, idx + 1)
@@ -279,10 +287,12 @@
effect_str[idx] = .
+ //Since the applied_lum values are what are (later) removed by remove_lum.
+ //Anything we apply to the lighting overlays HAS to match what remove_lum uses.
T.lighting_overlay.update_lumcount(
- lum_r * .,
- lum_g * .,
- lum_b * .
+ applied_lum_r * .,
+ applied_lum_g * .,
+ applied_lum_b * .
)
#undef LUM_FALLOFF
diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm
index 7fa2022d36..038591b735 100644
--- a/code/modules/mining/abandonedcrates.dm
+++ b/code/modules/mining/abandonedcrates.dm
@@ -16,6 +16,7 @@
for(var/i in 1 to codelen)
code += pick(digits)
+ digits -= code[code.len]
generate_loot()
@@ -166,7 +167,7 @@
user << "The crate's anti-tamper system activates!"
var/turf/T = get_turf(src.loc)
explosion(T, 0, 0, 1, 2)
- del(src)
+ qdel(src)
/obj/structure/closet/crate/secure/loot/emag_act(var/remaining_charges, var/mob/user)
if (locked)
diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm
index 080fb641dd..ef5ecede35 100644
--- a/code/modules/mining/machine_processing.dm
+++ b/code/modules/mining/machine_processing.dm
@@ -46,20 +46,20 @@
if(!machine.ores_stored[ore] && !show_all_ores) continue
var/ore/O = ore_data[ore]
if(!O) continue
- dat += "
[capitalize(O.display_name)]
[machine.ores_stored[ore]]
not processing"
+ dat += "not processing"
if(1)
- dat += "orange'>smelting"
+ dat += "smelting"
if(2)
- dat += "blue'>compressing"
+ dat += "compressing"
if(3)
- dat += "gray'>alloying"
+ dat += "alloying"
else
- dat += "red'>not processing"
- dat += ".
"
user << browse("[dat]", "window=[shuttle_tag]shuttlecontrol;size=300x600")
diff --git a/code/modules/spells/artifacts.dm b/code/modules/spells/artifacts.dm
index 9790dc3dbe..f643012ce3 100644
--- a/code/modules/spells/artifacts.dm
+++ b/code/modules/spells/artifacts.dm
@@ -19,5 +19,7 @@
user << "You can see... everything!"
visible_message("[user] stares into [src], their eyes glazing over.")
- announce_ghost_joinleave(user.ghostize(1), 1, "You feel that they used a powerful artifact to [pick("invade","disturb","disrupt","infest","taint","spoil","blight")] this place with their presence.")
+
+ user.teleop = user.ghostize(1)
+ announce_ghost_joinleave(user.teleop, 1, "You feel that they used a powerful artifact to [pick("invade","disturb","disrupt","infest","taint","spoil","blight")] this place with their presence.")
return
diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm
index 624f9f11b5..e7e66f7558 100644
--- a/code/modules/supermatter/supermatter.dm
+++ b/code/modules/supermatter/supermatter.dm
@@ -278,10 +278,11 @@
// Then bring it inside to explode instantly upon landing on a valid turf.
+ var/proj_damage = Proj.get_structure_damage()
if(istype(Proj, /obj/item/projectile/beam))
- power += Proj.damage * config_bullet_energy * CHARGING_FACTOR / POWER_FACTOR
+ power += proj_damage * config_bullet_energy * CHARGING_FACTOR / POWER_FACTOR
else
- damage += Proj.damage * config_bullet_energy
+ damage += proj_damage * config_bullet_energy
return 0
/obj/machinery/power/supermatter/attack_robot(mob/user as mob)
diff --git a/code/modules/vehicles/bike.dm b/code/modules/vehicles/bike.dm
new file mode 100644
index 0000000000..8136b06353
--- /dev/null
+++ b/code/modules/vehicles/bike.dm
@@ -0,0 +1,142 @@
+/obj/vehicle/bike/
+ name = "space-bike"
+ desc = "Space wheelies! Woo! "
+ icon = 'icons/obj/bike.dmi'
+ icon_state = "bike_off"
+ dir = SOUTH
+
+ load_item_visible = 1
+ mob_offset_y = 5
+ health = 100
+ maxhealth = 100
+
+ fire_dam_coeff = 0.6
+ brute_dam_coeff = 0.5
+ var/protection_percent = 60
+
+ var/land_speed = 10 //if 0 it can't go on turf
+ var/space_speed = 1
+ var/bike_icon = "bike"
+
+ var/datum/effect/effect/system/ion_trail_follow/ion
+ var/kickstand = 1
+
+/obj/vehicle/bike/New()
+ ..()
+ ion = new /datum/effect/effect/system/ion_trail_follow()
+ ion.set_up(src)
+ turn_off()
+ overlays += image('icons/obj/bike.dmi', "[icon_state]_off_overlay", MOB_LAYER + 1)
+ icon_state = "[bike_icon]_off"
+
+/obj/vehicle/bike/verb/toggle()
+ set name = "Toggle Engine"
+ set category = "Vehicle"
+ set src in view(0)
+
+ if(usr.incapacitated()) return
+
+ if(!on)
+ turn_on()
+ src.visible_message("\The [src] rumbles to life.", "You hear something rumble deeply.")
+ else
+ turn_off()
+ src.visible_message("\The [src] putters before turning off.", "You hear something putter slowly.")
+
+/obj/vehicle/bike/verb/kickstand()
+ set name = "Toggle Kickstand"
+ set category = "Vehicle"
+ set src in view(0)
+
+ if(usr.incapacitated()) return
+
+ if(kickstand)
+ src.visible_message("You put up \the [src]'s kickstand.")
+ else
+ if(istype(src.loc,/turf/space))
+ usr << " You don't think kickstands work in space..."
+ return
+ src.visible_message("You put down \the [src]'s kickstand.")
+ if(pulledby)
+ pulledby.stop_pulling()
+
+ kickstand = !kickstand
+ anchored = (kickstand || on)
+
+/obj/vehicle/bike/load(var/atom/movable/C)
+ var/mob/living/M = C
+ if(!istype(C)) return 0
+ if(M.buckled || M.restrained() || !Adjacent(M) || !M.Adjacent(src))
+ return 0
+ return ..(M)
+
+/obj/vehicle/bike/MouseDrop_T(var/atom/movable/C, mob/user as mob)
+ if(!load(C))
+ user << " You were unable to load \the [C] onto \the [src]."
+ return
+
+/obj/vehicle/bike/attack_hand(var/mob/user as mob)
+ if(user == load)
+ unload(load)
+ user << "You unbuckle yourself from \the [src]"
+
+/obj/vehicle/bike/relaymove(mob/user, direction)
+ if(user != load || !on)
+ return
+ return Move(get_step(src, direction))
+
+/obj/vehicle/bike/Move(var/turf/destination)
+ if(kickstand) return
+
+
+ //these things like space, not turf. Dragging shouldn't weigh you down.
+ if(istype(destination,/turf/space) || pulledby)
+ if(!space_speed)
+ return 0
+ move_delay = space_speed
+ else
+ if(!land_speed)
+ return 0
+ move_delay = land_speed
+ return ..()
+
+/obj/vehicle/bike/turn_on()
+ ion.start()
+ anchored = 1
+
+ update_icon()
+
+ if(pulledby)
+ pulledby.stop_pulling()
+ ..()
+/obj/vehicle/bike/turn_off()
+ ion.stop()
+ anchored = kickstand
+
+ update_icon()
+
+ ..()
+
+/obj/vehicle/bike/bullet_act(var/obj/item/projectile/Proj)
+ if(buckled_mob && prob(protection_percent))
+ buckled_mob.bullet_act(Proj)
+ return
+ ..()
+
+/obj/vehicle/bike/update_icon()
+ overlays.Cut()
+
+ if(on)
+ overlays += image('icons/obj/bike.dmi', "[bike_icon]_on_overlay", MOB_LAYER + 1)
+ icon_state = "[bike_icon]_on"
+ else
+ overlays += image('icons/obj/bike.dmi', "[bike_icon]_off_overlay", MOB_LAYER + 1)
+ icon_state = "[bike_icon]_off"
+
+ ..()
+
+
+/obj/vehicle/bike/Destroy()
+ qdel(ion)
+
+ ..()
\ No newline at end of file
diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm
index 953dc519ea..ddc56dad3f 100644
--- a/code/modules/vehicles/vehicle.dm
+++ b/code/modules/vehicles/vehicle.dm
@@ -112,16 +112,10 @@
..()
/obj/vehicle/bullet_act(var/obj/item/projectile/Proj)
- if (Proj.damage_type == BRUTE || Proj.damage_type == BURN)
- health -= Proj.damage
+ health -= Proj.get_structure_damage()
..()
healthcheck()
-/obj/vehicle/blob_act()
- src.health -= rand(20,40)*fire_dam_coeff
- healthcheck()
- return
-
/obj/vehicle/ex_act(severity)
switch(severity)
if(1.0)
diff --git a/code/modules/virus2/admin.dm b/code/modules/virus2/admin.dm
index cbcb5ed2ba..dad0a30925 100644
--- a/code/modules/virus2/admin.dm
+++ b/code/modules/virus2/admin.dm
@@ -15,6 +15,20 @@
return 1
+/datum/disease2/disease/get_view_variables_header()
+ . = list()
+ for(var/datum/disease2/effectholder/E in effects)
+ . += "[E.stage]: [E.effect.name]"
+ return {"
+ [name()]
+ [list2text(., " ")]
+ "}
+
+/datum/disease2/disease/get_view_variables_options()
+ return ..() + {"
+
+ "}
+
/datum/admins/var/datum/virus2_editor/virus2_editor_datum = new
/client/proc/virus2_editor()
set name = "Virus Editor"
diff --git a/code/modules/virus2/curer.dm b/code/modules/virus2/curer.dm
index a316663a37..d6c5189f19 100644
--- a/code/modules/virus2/curer.dm
+++ b/code/modules/virus2/curer.dm
@@ -19,7 +19,7 @@
return
if(istype(I,/obj/item/weapon/virusdish))
if(virusing)
- user << "The pathogen materializer is still recharging.."
+ user << "The pathogen materializer is still recharging.."
return
var/obj/item/weapon/reagent_containers/glass/beaker/product = new(src.loc)
diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm
index e023beef80..c111bf6657 100644
--- a/code/modules/virus2/effect.dm
+++ b/code/modules/virus2/effect.dm
@@ -98,7 +98,7 @@
maxm = 3
badness = 2
activate(var/mob/living/carbon/mob,var/multiplier)
- mob.radiation += (2*multiplier)
+ mob.apply_effect(2*multiplier, IRRADIATE, check_protection = 0)
/datum/disease2/effect/deaf
name = "Dead Ear Syndrome"
diff --git a/code/world.dm b/code/world.dm
index 394699e92b..c076918d45 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -217,6 +217,69 @@ var/world_topic_spam_protect_time = world.timeofday
return list2params(positions)
+ else if(copytext(T,1,5) == "info")
+ var/input[] = params2list(T)
+ if(input["key"] != config.comms_password)
+ if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50)
+
+ spawn(50)
+ world_topic_spam_protect_time = world.time
+ return "Bad Key (Throttled)"
+
+ world_topic_spam_protect_time = world.time
+ world_topic_spam_protect_ip = addr
+
+ return "Bad Key"
+
+ var/search = input["info"]
+ var/ckey = ckey(search)
+
+ var/list/match = list()
+
+ for(var/mob/M in mob_list)
+ if(findtext(M.name, search))
+ match += M
+ else if(M.ckey == ckey)
+ match += M
+ else if(M.mind && findtext(M.mind.assigned_role, search))
+ match += M
+
+ if(!match.len)
+ return "No matches"
+ else if(match.len == 1)
+ var/mob/M = match[1]
+ var/info = list()
+ info["key"] = M.key
+ info["name"] = M.name == M.real_name ? M.name : "[M.name] ([M.real_name])"
+ info["role"] = M.mind ? (M.mind.assigned_role ? M.mind.assigned_role : "No role") : "No mind"
+ var/turf/MT = get_turf(M)
+ info["loc"] = M.loc ? "[M.loc]" : "null"
+ info["turf"] = MT ? "[MT] @ [MT.x], [MT.y], [MT.z]" : "null"
+ info["area"] = MT ? "[MT.loc]" : "null"
+ info["antag"] = M.mind ? (M.mind.special_role ? M.mind.special_role : "Not antag") : "No mind"
+ info["hasbeenrev"] = M.mind ? M.mind.has_been_rev : "No mind"
+ info["stat"] = M.stat
+ info["type"] = M.type
+ if(isliving(M))
+ var/mob/living/L = M
+ info["damage"] = list2params(list(
+ oxy = L.getOxyLoss(),
+ tox = L.getToxLoss(),
+ fire = L.getFireLoss(),
+ brute = L.getBruteLoss(),
+ clone = L.getCloneLoss(),
+ brain = L.getBrainLoss()
+ ))
+ else
+ info["damage"] = "non-living"
+ info["gender"] = M.gender
+ return list2params(info)
+ else
+ var/list/ret = list()
+ for(var/mob/M in match)
+ ret[M.key] = M.name
+ return list2params(ret)
+
else if(copytext(T,1,9) == "adminmsg")
/*
We got an adminmsg from IRC bot lets split the input then validate the input.
diff --git a/html/changelog.css b/html/changelog.css
index 9d43ecc076..d5155db726 100644
--- a/html/changelog.css
+++ b/html/changelog.css
@@ -1,5 +1,5 @@
-.top{font-family:Tahoma,sans-serif;font-size:12px;}
-h2{font-family:Tahoma,sans-serif;}
+body{font-family:Tahoma,sans-serif;}
+.top{font-size:12px;}
a img {border:none;}
.bgimages16 li {
padding:2px 10px 2px 30px;
@@ -21,16 +21,57 @@ a img {border:none;}
.spellcheck {background-image:url(spell-check.png)}
.experiment {background-image:url(burn-exclamation.png)}
.maptweak {background-image:url(map-pencil.png)}
-.sansserif {font-family:Tahoma,sans-serif;font-size:12px;}
-.commit {margin-bottom:20px;font-size:100%;font-weight:normal;}
-.changes {list-style:none;margin:5px 0;padding:0 0 0 25px;font-size:0.8em;}
-.date {margin:10px 0;color:blue;border-bottom:2px solid #00f;width:60%;padding:2px 0;font-size:1em;font-weight:bold;}
-.author {padding-left:10px;margin:0;font-weight:bold;font-size:0.9em;}
-.drop {cursor:pointer;border:1px solid #999;display:inline;font-size:0.9em;padding:1px 20px 1px 5px;line-height:16px;}
+.sansserif {font-size:12px;}
+.commit {
+ margin-bottom:20px;
+ font-size:100%;font-weight:normal;
+}
+.changes {
+ list-style:none;
+ margin:5px 0;
+ padding:0 0 0 25px;
+ font-size:0.8em;
+}
+.date {
+ margin:10px 0;
+ color:blue;
+ border-bottom:2px solid #00f;
+ width:60%;
+ padding:2px 0;
+ font-size:1em;
+ font-weight:bold;
+}
+.author {
+ padding-left:10px;
+ margin:0;
+ font-weight:bold;
+ font-size:0.9em;
+ }
+.drop {
+ cursor:pointer;
+ border:1px solid #999;
+ display:inline;
+ font-size:0.9em;
+ padding:1px 20px 1px 5px;
+ line-height:16px;
+}
.hidden {display:none;}
-.indrop {margin:2px 0 0 0;clear:both;background:#fff;border:1px solid #ddd;padding:5px 10px;}
-.indrop p {margin:0;font-size:0.8em;line-height:16px;margin:1px 0;}
-.indrop img {margin-right:5px;vertical-align:middle;}
+.indrop {
+ margin:2px 0 0 0;
+ clear:both;
+ background:#fff;
+ border:1px solid #ddd;
+ padding:5px 10px;
+ }
+.indrop p {
+ margin:0;
+ font-size:0.8em;
+ line-height:16px;
+ margin:1px 0;
+}
+.indrop img {
+ margin-right:5px;
+ vertical-align:middle;}
.closed {background:url(chevron-expand.png) right center no-repeat;}
.open {background:url(chevron.png) right center no-repeat;}
-.lic {font-size:9px;}
\ No newline at end of file
+.lic {font-size:9px;}
diff --git a/html/changelog.html b/html/changelog.html
index 248f688be8..897f98072d 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -56,6 +56,42 @@
-->
+
26 September 2015
+
PsiOmegaDelta updated:
+
+
Meteor events now select a map edge to arrive from, with a probability for each individual wave to come from either neighboring edge. Meteors will never arrive from opposite the starting edge.
+
+
+
11 September 2015
+
HarpyEagle updated:
+
+
Made flares brighter.
+
Coffee is now poisonous to tajaran, much like how animal protein is poisonous to skrell.
+
+
+
08 September 2015
+
Soadreqm updated:
+
+
Increased changeling starting genetic points to 25.
+
+
Zuhayr updated:
+
+
Auto-traitor should now be fixed.
+
The Secret game mode should now be fixed.
+
+
+
07 September 2015
+
GinjaNinja32 updated:
+
+
Added an auto-hiss system for those who would prefer the game do their sss or rrr for them. Activate via Toggle Auto-Hiss in the OOC tab.
+
Auto-hiss system in 'basic' mode will extend 's' for Unathi and 'r' for Tajara. 'Full' mode adds 'x' to 'ks' for Unathi, and is identical to 'basic' mode for Tajara.
+
+
PsiOmegaDelta updated:
+
+
Changed the language prefix keys to the following: , # -
+
Language prefix keys can be changed in the Character Setup. Changes are currently not global, but per character.
', re.IGNORECASE)),
+ ('', re.compile('', re.IGNORECASE), re.compile('', re.IGNORECASE)),
+ ('', re.compile('', re.IGNORECASE), re.compile('', re.IGNORECASE))]
+# The keys of this dictionary will be the file path of each parsed *.dm file
+# The values of this dictionary will be in the format provided by populate_match_list().
+matches = { }
+
+# Support def for setting up a dictionary, populating it with all defined tuple names as key with each being assigned the value 0.
+# One such dictionary is created for each parsed file.
+def populate_match_list():
+ match_list = { }
+ for tag_tuple in tag_tuples:
+ match_list[tag_tuple[0]] = 0
+ return match_list
+
+# This def shall be provided by a dictionary in the format given by populate_match_list() and a line of text.
+# It loops over all defined tag tuples, adding the number of open tags found and subtracting the number of close tag found to the corresponding tuple name in the match list.
+# This def is currently run with the same match_list for a given file and for all lines of that file.
+def get_tag_matches(match_list, line):
+ for tag_tuple in tag_tuples:
+ match_list[tag_tuple[0]] += len(tag_tuple[1].findall(line))
+ match_list[tag_tuple[0]] -= len(tag_tuple[2].findall(line))
+ return
+
+# Support def that simply checks if a given dictionary in the format given by populate_match_list() contains any value that is non-zero.
+# That is, a tag which had a non-equal amount of open/closing tags.
+def has_mismatch(match_list):
+ for tag, match_number in match_list.iteritems():
+ if(match_number != 0):
+ return 1
+ return 0
+
+# This section parses all *.dm files in the given directory, recursively.
for root, subdirs, files in walk(args.dir):
for filename in files:
if filename.endswith('.dm'):
- open_match = 0
- close_match = 0
file_path = path.join(root, filename)
with open(file_path, 'r') as f:
- open_span = re.compile(pair_of_tags[0][0], re.IGNORECASE)
- close_span = re.compile(pair_of_tags[0][1], re.IGNORECASE)
- for x in f:
- open_match += len(open_span.findall(x))
- close_match += len(close_span.findall(x))
-
- if open_match != close_match:
- if not pair_of_tags[0][0] in mismatches.keys():
- mismatches[pair_of_tags[0][0]] = []
- mismatches[pair_of_tags[0][0]].append('{0} - {1}/{2}'.format(file_path, open_match, close_match))
+ # For each file, generate the match dictionary.
+ matches[file_path] = populate_match_list()
+ for x in f:
+ # Then for each line in the file, conduct the tuple open/close matching.
+ get_tag_matches(matches[file_path], x)
-for mismatch_key in mismatches.keys():
- print(mismatch_key)
- for mismatch_value in mismatches[mismatch_key]:
- print('\t{0}').format(mismatch_value)
-
-if len(mismatches.keys()) > 0:
- sys.exit(1)
+# Pretty printing section.
+# Loops over all matches and checks if there is a mismatch of tags.
+# If so, then and only then is the corresponding file path printed along with the number of unmatched open/close tags.
+total_mismatch = 0
+for file, match_list in matches.iteritems():
+ if(has_mismatch(match_list)):
+ print(file)
+ for tag, match_number in match_list.iteritems():
+ # A positive number means an excess of opening tag, a negative number means an excess of closing tags.
+ if(match_number > 0):
+ total_mismatch += match_number
+ print('\t{0} - Excess of {1} opening tag(s)'.format(tag, match_number))
+ elif (match_number < 0):
+ total_mismatch -= match_number
+ print('\t{0} - Excess of {1} closing tag(s)'.format(tag, -match_number))
+
+# Simply prints the total number of mismatches found and if so returns 1 to, for example, fail Travis builds.
+if(total_mismatch == 0):
+ print('No mismatches found.')
+else:
+ print('')
+ print('Total number of mismatches: {0}'.format(total_mismatch))
+ sys.exit(1)
diff --git a/tools/mapmerge/mapmerge.sh b/tools/mapmerge/mapmerge.sh
index fe74602c08..9e347ceaa2 100755
--- a/tools/mapmerge/mapmerge.sh
+++ b/tools/mapmerge/mapmerge.sh
@@ -6,4 +6,4 @@ then
fi
java -jar tools/mapmerge/MapPatcher.jar -clean $3 $2 $2
-exit 0
\ No newline at end of file
+exit 0