+ "}
+ var/even = 0
+ // sort mobs
+ for(var/datum/data/record/t in data_core.general)
+ var/name = t.fields["name"]
+ var/rank = t.fields["rank"]
+ var/real_rank = t.fields["real_rank"]
+ if(OOC)
+ var/active = 0
+ for(var/mob/M in player_list)
+ if(M.real_name == name && M.client && M.client.inactivity <= 10 * 60 * 10)
+ active = 1
+ break
+ isactive[name] = active ? "Active" : "Inactive"
+ else
+ isactive[name] = t.fields["p_stat"]
//world << "[name]: [rank]"
-
//cael - to prevent multiple appearances of a player/job combination, add a continue after each line
- var/department = 0
- if(real_rank in command_positions)
- heads[name] = rank
- department = 1
- if(real_rank in security_positions)
- sec[name] = rank
- department = 1
- if(real_rank in engineering_positions)
- eng[name] = rank
- department = 1
- if(real_rank in medical_positions)
- med[name] = rank
- department = 1
- if(real_rank in science_positions)
- sci[name] = rank
- department = 1
- if(real_rank in civilian_positions)
- civ[name] = rank
- department = 1
- if(real_rank in nonhuman_positions)
- bot[name] = rank
- department = 1
+ var/department = 0
+ if(real_rank in command_positions)
+ heads[name] = rank
+ department = 1
+ if(real_rank in security_positions)
+ sec[name] = rank
+ department = 1
+ if(real_rank in engineering_positions)
+ eng[name] = rank
+ department = 1
+ if(real_rank in medical_positions)
+ med[name] = rank
+ department = 1
+ if(real_rank in science_positions)
+ sci[name] = rank
+ department = 1
+ if(real_rank in civilian_positions)
+ civ[name] = rank
+ department = 1
+ if(real_rank in nonhuman_positions)
+ bot[name] = rank
+ department = 1
+ if(!department && !(name in heads))
+ misc[name] = rank
+ if(heads.len > 0)
+ dat += "
Heads
"
+ for(name in heads)
+ dat += "
[name]
[heads[name]]
[isactive[name]]
"
+ even = !even
+ if(sec.len > 0)
+ dat += "
Security
"
+ for(name in sec)
+ dat += "
[name]
[sec[name]]
[isactive[name]]
"
+ even = !even
+ if(eng.len > 0)
+ dat += "
Engineering
"
+ for(name in eng)
+ dat += "
[name]
[eng[name]]
[isactive[name]]
"
+ even = !even
+ if(med.len > 0)
+ dat += "
Medical
"
+ for(name in med)
+ dat += "
[name]
[med[name]]
[isactive[name]]
"
+ even = !even
+ if(sci.len > 0)
+ dat += "
Science
"
+ for(name in sci)
+ dat += "
[name]
[sci[name]]
[isactive[name]]
"
+ even = !even
+ if(civ.len > 0)
+ dat += "
Civilian
"
+ for(name in civ)
+ dat += "
[name]
[civ[name]]
[isactive[name]]
"
+ even = !even
+ // in case somebody is insane and added them to the manifest, why not
+ if(bot.len > 0)
+ dat += "
Silicon
"
+ for(name in bot)
+ dat += "
[name]
[bot[name]]
[isactive[name]]
"
+ even = !even
+ // misc guys
+ if(misc.len > 0)
+ dat += "
Miscellaneous
"
+ for(name in misc)
+ dat += "
[name]
[misc[name]]
[isactive[name]]
"
+ even = !even
- if(!department && !(name in heads))
- misc[name] = rank
-
- if(heads.len > 0)
- dat += "
Heads
"
- for(name in heads)
- dat += "
[name]
[heads[name]]
[isactive[name]]
"
- even = !even
- if(sec.len > 0)
- dat += "
Security
"
- for(name in sec)
- dat += "
[name]
[sec[name]]
[isactive[name]]
"
- even = !even
- if(eng.len > 0)
- dat += "
Engineering
"
- for(name in eng)
- dat += "
[name]
[eng[name]]
[isactive[name]]
"
- even = !even
- if(med.len > 0)
- dat += "
Medical
"
- for(name in med)
- dat += "
[name]
[med[name]]
[isactive[name]]
"
- even = !even
- if(sci.len > 0)
- dat += "
Science
"
- for(name in sci)
- dat += "
[name]
[sci[name]]
[isactive[name]]
"
- even = !even
- if(civ.len > 0)
- dat += "
Civilian
"
- for(name in civ)
- dat += "
[name]
[civ[name]]
[isactive[name]]
"
- even = !even
- // in case somebody is insane and added them to the manifest, why not
- if(bot.len > 0)
- dat += "
Silicon
"
- for(name in bot)
- dat += "
[name]
[bot[name]]
[isactive[name]]
"
- even = !even
- // misc guys
- if(misc.len > 0)
- dat += "
Miscellaneous
"
- for(name in misc)
- dat += "
[name]
[misc[name]]
[isactive[name]]
"
- even = !even
+ dat += "
"
+ dat = replacetext(dat, "\n", "") // so it can be placed on paper correctly
+ dat = replacetext(dat, "\t", "")
+ return dat
+
+
+/*
+We can't just insert in HTML into the nanoUI so we need the raw data to play with.
+Instead of creating this list over and over when someone leaves their PDA open to the page
+we'll only update it when it changes. The PDA_Manifest global list is zeroed out upon any change
+using /obj/effect/datacore/proc/manifest_inject( ), or manifest_insert( )
+*/
+
+var/global/list/PDA_Manifest = list()
+
+/obj/effect/datacore/proc/get_manifest_json()
+ if(PDA_Manifest.len)
+ return PDA_Manifest
+ var/heads[0]
+ var/sec[0]
+ var/eng[0]
+ var/med[0]
+ var/sci[0]
+ var/civ[0]
+ var/bot[0]
+ var/misc[0]
+ for(var/datum/data/record/t in data_core.general)
+ var/name = sanitize(t.fields["name"])
+ var/rank = sanitize(t.fields["rank"])
+ var/real_rank = t.fields["real_rank"]
+ var/isactive = t.fields["p_stat"]
+ var/department = 0
+ var/depthead = 0 // Department Heads will be placed at the top of their lists.
+ if(real_rank in command_positions)
+ heads[++heads.len] = list("name" = name, "rank" = rank, "active" = isactive)
+ department = 1
+ depthead = 1
+ if(rank=="Captain" && heads.len != 1)
+ heads.Swap(1,heads.len)
+
+ if(real_rank in security_positions)
+ sec[++sec.len] = list("name" = name, "rank" = rank, "active" = isactive)
+ department = 1
+ if(depthead && sec.len != 1)
+ sec.Swap(1,sec.len)
+
+ if(real_rank in engineering_positions)
+ eng[++eng.len] = list("name" = name, "rank" = rank, "active" = isactive)
+ department = 1
+ if(depthead && eng.len != 1)
+ eng.Swap(1,eng.len)
+
+ if(real_rank in medical_positions)
+ med[++med.len] = list("name" = name, "rank" = rank, "active" = isactive)
+ department = 1
+ if(depthead && med.len != 1)
+ med.Swap(1,med.len)
+
+ if(real_rank in science_positions)
+ sci[++sci.len] = list("name" = name, "rank" = rank, "active" = isactive)
+ department = 1
+ if(depthead && sci.len != 1)
+ sci.Swap(1,sci.len)
+
+ if(real_rank in civilian_positions)
+ civ[++civ.len] = list("name" = name, "rank" = rank, "active" = isactive)
+ department = 1
+ if(depthead && civ.len != 1)
+ civ.Swap(1,civ.len)
+
+ if(real_rank in nonhuman_positions)
+ bot[++bot.len] = list("name" = name, "rank" = rank, "active" = isactive)
+ department = 1
+
+ if(!department && !(name in heads))
+ misc[++misc.len] = list("name" = name, "rank" = rank, "active" = isactive)
+
+
+ PDA_Manifest = list(\
+ "heads" = heads,\
+ "sec" = sec,\
+ "eng" = eng,\
+ "med" = med,\
+ "sci" = sci,\
+ "civ" = civ,\
+ "bot" = bot,\
+ "misc" = misc\
+ )
+ return PDA_Manifest
- dat += "
"
- dat = replacetext(dat, "\n", "") // so it can be placed on paper correctly
- dat = replacetext(dat, "\t", "")
- return dat
/obj/effect/laser
name = "laser"
@@ -185,49 +268,6 @@
var/list/container = list( )
-
-/obj/structure/cable
- level = 1
- anchored =1
- var/datum/powernet/powernet
- name = "power cable"
- desc = "A flexible superconducting cable for heavy-duty power transfer"
- icon = 'icons/obj/power_cond_red.dmi'
- icon_state = "0-1"
- var/d1 = 0
- var/d2 = 1
- layer = 2.44 //Just below unary stuff, which is at 2.45 and above pipes, which are at 2.4
- var/cable_color = "red"
- var/obj/structure/powerswitch/power_switch
-
-/obj/structure/cable/yellow
- cable_color = "yellow"
- icon = 'icons/obj/power_cond_yellow.dmi'
-
-/obj/structure/cable/green
- cable_color = "green"
- icon = 'icons/obj/power_cond_green.dmi'
-
-/obj/structure/cable/blue
- cable_color = "blue"
- icon = 'icons/obj/power_cond_blue.dmi'
-
-/obj/structure/cable/pink
- cable_color = "pink"
- icon = 'icons/obj/power_cond_pink.dmi'
-
-/obj/structure/cable/orange
- cable_color = "orange"
- icon = 'icons/obj/power_cond_orange.dmi'
-
-/obj/structure/cable/cyan
- cable_color = "cyan"
- icon = 'icons/obj/power_cond_cyan.dmi'
-
-/obj/structure/cable/white
- cable_color = "white"
- icon = 'icons/obj/power_cond_white.dmi'
-
/obj/effect/projection
name = "Projection"
desc = "This looks like a projection of something."
@@ -257,7 +297,7 @@
item_state = "beachball"
density = 0
anchored = 0
- w_class = 1.0
+ w_class = 2.0
force = 0.0
throwforce = 0.0
throw_speed = 1
diff --git a/code/defines/obj/hydro.dm b/code/defines/obj/hydro.dm
index 2b57dbeffa..443ba95b09 100644
--- a/code/defines/obj/hydro.dm
+++ b/code/defines/obj/hydro.dm
@@ -18,7 +18,7 @@
icon = 'icons/obj/seeds.dmi'
icon_state = "seed" // unknown plant seed - these shouldn't exist in-game
flags = FPRINT | TABLEPASS
- w_class = 1.0 // Makes them pocketable
+ w_class = 2.0 // Makes them pocketable
var/mypath = "/obj/item/seeds"
var/plantname = "Plants"
var/productname = ""
@@ -1167,7 +1167,7 @@
attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || (istype(W, /obj/item/weapon/twohanded/fireaxe) && W:wielded) || istype(W, /obj/item/weapon/melee/energy))
- user.show_message("You make planks out of the [src]!", 1)
+ user.show_message("You make planks out of \the [src]!", 1)
for(var/i=0,i<2,i++)
var/obj/item/stack/sheet/wood/NG = new (user.loc)
for (var/obj/item/stack/sheet/wood/G in user.loc)
@@ -1205,7 +1205,7 @@
force = 0
flags = TABLEPASS
throwforce = 1
- w_class = 1.0
+ w_class = 2.0
throw_speed = 1
throw_range = 3
plant_type = 1
@@ -1229,7 +1229,7 @@
force = 15
flags = TABLEPASS
throwforce = 1
- w_class = 1.0
+ w_class = 2.0
throw_speed = 1
throw_range = 3
plant_type = 1
@@ -1251,7 +1251,7 @@
force = 30
flags = TABLEPASS
throwforce = 1
- w_class = 1.0
+ w_class = 2.0
throw_speed = 1
throw_range = 3
plant_type = 1
@@ -1417,7 +1417,7 @@
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle16"
flags = FPRINT | TABLEPASS
- w_class = 1.0
+ w_class = 2.0
var/mutmod = 0
var/yieldmod = 0
New()
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index e798f26c60..f16d2810b0 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -31,7 +31,7 @@
icon = 'icons/obj/items.dmi'
icon_state = "banana_peel"
item_state = "banana_peel"
- w_class = 1.0
+ w_class = 2.0
throwforce = 0
throw_speed = 4
throw_range = 20
@@ -42,7 +42,7 @@
icon = 'icons/obj/harvest.dmi'
icon_state = "corncob"
item_state = "corncob"
- w_class = 1.0
+ w_class = 2.0
throwforce = 0
throw_speed = 4
throw_range = 20
@@ -53,13 +53,13 @@
gender = PLURAL
icon = 'icons/obj/items.dmi'
icon_state = "soap"
- w_class = 1.0
+ w_class = 2.0
throwforce = 0
throw_speed = 4
throw_range = 20
/obj/item/weapon/soap/nanotrasen
- desc = "A Nanotrasen brand bar of soap. Smells of plasma."
+ desc = "A Nanotrasen brand bar of soap. Smells of phoron."
icon_state = "soapnt"
/obj/item/weapon/soap/deluxe
@@ -90,7 +90,7 @@
icon = 'icons/obj/items.dmi'
icon_state = "c_tube"
throwforce = 1
- w_class = 1.0
+ w_class = 2.0
throw_speed = 4
throw_range = 5
@@ -117,7 +117,7 @@
desc = "Better keep this safe."
icon_state = "nucleardisk"
item_state = "card-id"
- w_class = 1.0
+ w_class = 2.0
/*
/obj/item/weapon/game_kit
@@ -229,7 +229,7 @@
icon_state = "large"
sharp = 1
desc = "Could probably be used as ... a throwing weapon?"
- w_class = 1.0
+ w_class = 2.0
force = 5.0
throwforce = 8.0
item_state = "shard-glass"
@@ -325,6 +325,13 @@
icon = 'icons/obj/wizard.dmi'
icon_state = "broom"
+/obj/item/weapon/staff/gentcane
+ name = "Gentlemans Cane"
+ desc = "An ebony can with an ivory tip."
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "cane"
+ item_state = "stick"
+
/obj/item/weapon/staff/stick
name = "stick"
desc = "A great tool to drag someone else's drinks across the bar."
@@ -394,6 +401,8 @@
name = "power control module"
icon_state = "power_mod"
desc = "Heavy-duty switching circuits for power control."
+ m_amt = 50
+ g_amt = 50
/obj/item/weapon/module/id_auth
name = "\improper ID authentication module"
@@ -452,7 +461,7 @@
icon = 'icons/obj/food.dmi'
icon_state = "meat"
flags = FPRINT | TABLEPASS | CONDUCT
- w_class = 1.0
+ w_class = 2.0
origin_tech = "biotech=2"
/obj/item/weapon/hatchet
diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm
index 9c04d5b672..02b806a50c 100755
--- a/code/game/area/Space Station 13 areas.dm
+++ b/code/game/area/Space Station 13 areas.dm
@@ -14,6 +14,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
*/
+
/area
var/fire = null
var/atmos = 1
@@ -31,6 +32,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
var/eject = null
+ var/debug = 0
+ var/powerupdate = 10 //We give everything 10 ticks to settle out it's power usage.
var/requires_power = 1
var/always_unpowered = 0 //this gets overriden to 1 for space in area/New()
@@ -43,7 +46,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
var/used_environ = 0
var/has_gravity = 1
-
+ var/list/apc = list()
var/no_air = null
var/area/master // master area used for power calcluations
// (original area before splitting due to sd_DAL)
@@ -664,6 +667,10 @@ var/list/ghostteleportlocs = list()
name = "Waste Disposal"
icon_state = "disposal"
+/area/maintenance/evahallway
+ name = "\improper EVA Hallway"
+ icon_state = "eva"
+
//Hallway
/area/hallway/primary/fore
@@ -788,6 +795,14 @@ var/list/ghostteleportlocs = list()
name = "\improper Security Dormitories"
icon_state = "Sleep"
+/area/crew_quarters/sleep/bedrooms
+ name = "\improper Dormitory Bedroom"
+ icon_state = "Sleep"
+
+/area/crew_quarters/sleep/cryo
+ name = "\improper Cryogenic Storage"
+ icon_state = "Sleep"
+
/area/crew_quarters/sleep_male
name = "\improper Male Dorm"
icon_state = "Sleep"
@@ -845,7 +860,7 @@ var/list/ghostteleportlocs = list()
icon_state = "chapeloffice"
/area/lawoffice
- name = "\improper Law Office"
+ name = "\improper Internal Affairs"
icon_state = "law"
@@ -921,23 +936,64 @@ var/list/ghostteleportlocs = list()
//Engineering
/area/engine
+
+ drone_fabrication
+ name = "\improper Drone Fabrication"
+ icon_state = "engine"
+
engine_smes
- name = "\improper Engineering SMES"
+ name = "Engineering SMES"
icon_state = "engine_smes"
- requires_power = 0//This area only covers the batteries and they deal with their own power
+// requires_power = 0//This area only covers the batteries and they deal with their own power
+
+ engine_room
+ name = "\improper Engine Room"
+ icon_state = "engine"
+
+ engine_airlock
+ name = "\improper Engine Room Airlock"
+ icon_state = "engine"
+
+ engine_monitoring
+ name = "\improper Engine Monitoring Room"
+ icon_state = "engine_monitoring"
+
+ engineering_monitoring
+ name = "\improper Engineering Monitoring Room"
+ icon_state = "engine_monitoring"
engineering
name = "Engineering"
icon_state = "engine_smes"
- break_room
+ engineering_foyer
name = "\improper Engineering Foyer"
icon_state = "engine"
+ break_room
+ name = "\improper Engineering Break Room"
+ icon_state = "engine"
+
chiefs_office
name = "\improper Chief Engineer's office"
icon_state = "engine_control"
+ hallway
+ name = "\improper Engineering Hallway"
+ icon_state = "engine_hallway"
+
+ engine_eva
+ name = "\improper Engine EVA"
+ icon_state = "engine_eva"
+
+ workshop
+ name = "\improper Engineering Workshop"
+ icon_state = "engine_storage"
+
+ locker_room
+ name = "\improper Engineering Locker Room"
+ icon_state = "engine_storage"
+
//Solars
@@ -1041,7 +1097,6 @@ var/list/ghostteleportlocs = list()
icon_state = "medbay3"
music = 'sound/ambience/signal.ogg'
-
/area/medical/biostorage
name = "\improper Secondary Storage"
icon_state = "medbay2"
@@ -1067,7 +1122,7 @@ var/list/ghostteleportlocs = list()
icon_state = "patients"
/area/medical/ward
- name = "\improper Medbay Patient Ward"
+ name = "\improper Recovery Ward"
icon_state = "patients"
/area/medical/patient_a
@@ -1082,8 +1137,8 @@ var/list/ghostteleportlocs = list()
name = "\improper Isolation C"
icon_state = "patients"
-/area/medical/iso_access
- name = "\improper Isolation Access"
+/area/medical/patient_wing
+ name = "\improper Patient Wing"
icon_state = "patients"
/area/medical/cmo
@@ -1106,6 +1161,10 @@ var/list/ghostteleportlocs = list()
name = "\improper Virology"
icon_state = "virology"
+/area/medical/virologyaccess
+ name = "\improper Virology Access"
+ icon_state = "virology"
+
/area/medical/morgue
name = "\improper Morgue"
icon_state = "morgue"
@@ -1115,11 +1174,19 @@ var/list/ghostteleportlocs = list()
icon_state = "chem"
/area/medical/surgery
- name = "\improper Surgery"
+ name = "\improper Operating Theatre 1"
+ icon_state = "surgery"
+
+/area/medical/surgery2
+ name = "\improper Operating Theatre 2"
icon_state = "surgery"
/area/medical/surgeryobs
- name = "\improper Surgery Observation"
+ name = "\improper Operation Observation Room"
+ icon_state = "surgery"
+
+/area/medical/surgeryprep
+ name = "\improper Pre-Op Prep Room"
icon_state = "surgery"
/area/medical/cryo
@@ -1139,7 +1206,7 @@ var/list/ghostteleportlocs = list()
icon_state = "cloning"
/area/medical/sleeper
- name = "\improper Medical Treatment Center"
+ name = "\improper Emergency Treatment Centre"
icon_state = "exam_room"
//Security
@@ -1180,6 +1247,11 @@ var/list/ghostteleportlocs = list()
name = "\improper Firing Range"
icon_state = "firingrange"
+/area/security/tactical
+ name = "\improper Tactical Equipment"
+ icon_state = "Tactical"
+
+
/*
New()
..()
@@ -1277,48 +1349,44 @@ var/list/ghostteleportlocs = list()
name = "Hydroponics"
icon_state = "hydro"
-//Toxins
+//rnd (Research and Development
-/area/toxins/lab
+/area/rnd/lab
name = "\improper Research and Development"
icon_state = "toxlab"
-/area/toxins/hallway
+/area/rnd/hallway
name = "\improper Research Lab"
icon_state = "toxlab"
-/area/toxins/rdoffice
+/area/rnd/rdoffice
name = "\improper Research Director's Office"
icon_state = "head_quarters"
-/area/toxins/supermatter
+/area/rnd/supermatter
name = "\improper Supermatter Lab"
icon_state = "toxlab"
-/area/toxins/xenobiology
+/area/rnd/xenobiology
name = "\improper Xenobiology Lab"
icon_state = "toxlab"
-/area/toxins/storage
+/area/rnd/storage
name = "\improper Toxins Storage"
icon_state = "toxstorage"
-/area/toxins/test_area
+/area/rnd/test_area
name = "\improper Toxins Test Area"
icon_state = "toxtest"
-/area/toxins/mixing
+/area/rnd/mixing
name = "\improper Toxins Mixing Room"
icon_state = "toxmix"
-/area/toxins/misc_lab
+/area/rnd/misc_lab
name = "\improper Miscellaneous Research"
icon_state = "toxmisc"
-/area/toxins/telesci
- name = "\improper Telescience Lab"
- icon_state = "toxmisc"
-
/area/toxins/server
name = "\improper Server Room"
icon_state = "server"
@@ -1361,6 +1429,10 @@ var/list/ghostteleportlocs = list()
name = "Port Emergency Storage"
icon_state = "emergencystorage"
+/area/storage/emergency3
+ name = "Central Emergency Storage"
+ icon_state = "emergencystorage"
+
/area/storage/tech
name = "Technical Storage"
icon_state = "auxstorage"
@@ -1827,7 +1899,7 @@ var/list/the_station_areas = list (
/area/quartermaster,
/area/janitor,
/area/hydroponics,
- /area/toxins,
+ /area/rnd,
/area/storage,
/area/construction,
/area/ai_monitored/storage/eva, //do not try to simplify to "/area/ai_monitored" --rastaf0
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 6695fe4402..21b86f5bcc 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -13,6 +13,8 @@
master = src //moved outside the spawn(1) to avoid runtimes in lighting.dm when it references loc.loc.master ~Carn
uid = ++global_uid
related = list(src)
+ active_areas += src
+ all_areas += src
if(type == /area) // override defaults for space. TODO: make space areas of type /area/space rather than /area
requires_power = 1
@@ -100,6 +102,7 @@
return
if( !fire )
fire = 1
+ master.fire = 1 //used for firedoor checks
updateicon()
mouse_opacity = 0
for(var/obj/machinery/door/firedoor/D in all_doors)
@@ -122,6 +125,7 @@
/area/proc/firereset()
if (fire)
fire = 0
+ master.fire = 0 //used for firedoor checks
mouse_opacity = 0
updateicon()
for(var/obj/machinery/door/firedoor/D in all_doors)
@@ -218,6 +222,7 @@
// called when power status changes
/area/proc/power_change()
+ master.powerupdate = 2
for(var/area/RA in related)
for(var/obj/machinery/M in RA) // for each machine in the area
M.power_change() // reverify power status (to update icons etc.)
@@ -239,7 +244,6 @@
return used
/area/proc/clear_usage()
-
master.used_equip = 0
master.used_light = 0
master.used_environ = 0
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index f5870a2499..351216b8bf 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -6,6 +6,7 @@
var/list/fingerprintshidden
var/fingerprintslast = null
var/list/blood_DNA
+ var/blood_color
var/last_bumped = 0
var/pass_flags = 0
var/throwpass = 0
@@ -43,7 +44,6 @@
/atom/proc/assume_air(datum/gas_mixture/giver)
- del(giver)
return null
/atom/proc/remove_air(amount)
@@ -100,8 +100,10 @@
/atom/proc/emp_act(var/severity)
return
-/atom/proc/bullet_act(var/obj/item/projectile/Proj)
- return 0
+
+/atom/proc/bullet_act(obj/item/projectile/P, def_zone)
+ P.on_hit(src, 0, def_zone)
+ . = 0
/atom/proc/in_contents_of(container)//can take class or object instance as argument
if(ispath(container))
@@ -317,7 +319,43 @@ its easier to just keep the beam vertical.
var/full_print = md5(H.dna.uni_identity)
// Add the fingerprints
- fingerprints[full_print] = full_print
+ //
+ if(fingerprints[full_print])
+ switch(stringpercent(fingerprints[full_print])) //tells us how many stars are in the current prints.
+
+ if(28 to 32)
+ if(prob(1))
+ fingerprints[full_print] = full_print // You rolled a one buddy.
+ else
+ fingerprints[full_print] = stars(full_print, rand(0,40)) // 24 to 32
+
+ if(24 to 27)
+ if(prob(3))
+ fingerprints[full_print] = full_print //Sucks to be you.
+ else
+ fingerprints[full_print] = stars(full_print, rand(15, 55)) // 20 to 29
+
+ if(20 to 23)
+ if(prob(5))
+ fingerprints[full_print] = full_print //Had a good run didn't ya.
+ else
+ fingerprints[full_print] = stars(full_print, rand(30, 70)) // 15 to 25
+
+ if(16 to 19)
+ if(prob(5))
+ fingerprints[full_print] = full_print //Welp.
+ else
+ fingerprints[full_print] = stars(full_print, rand(40, 100)) // 0 to 21
+
+ if(0 to 15)
+ if(prob(5))
+ fingerprints[full_print] = stars(full_print, rand(0,50)) // small chance you can smudge.
+ else
+ fingerprints[full_print] = full_print
+
+ else
+ fingerprints[full_print] = stars(full_print, rand(0, 20)) //Initial touch, not leaving much evidence the first time.
+
return 1
else
@@ -333,17 +371,22 @@ its easier to just keep the beam vertical.
/atom/proc/transfer_fingerprints_to(var/atom/A)
+
if(!istype(A.fingerprints,/list))
A.fingerprints = list()
+
if(!istype(A.fingerprintshidden,/list))
A.fingerprintshidden = list()
+ if(!istype(fingerprintshidden, /list))
+ fingerprintshidden = list()
+
//skytodo
//A.fingerprints |= fingerprints //detective
//A.fingerprintshidden |= fingerprintshidden //admin
- if(fingerprints)
+ if(A.fingerprints && fingerprints)
A.fingerprints |= fingerprints.Copy() //detective
- if(fingerprintshidden)
+ if(A.fingerprintshidden && fingerprintshidden)
A.fingerprintshidden |= fingerprintshidden.Copy() //admin A.fingerprintslast = fingerprintslast
@@ -361,16 +404,9 @@ its easier to just keep the beam vertical.
return 0
if(!blood_DNA || !istype(blood_DNA, /list)) //if our list of DNA doesn't exist yet (or isn't a list) initialise it.
blood_DNA = list()
-
- //adding blood to humans
- else if (istype(src, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = src
- //if this blood isn't already in the list, add it
- if(blood_DNA[H.dna.unique_enzymes])
- return 0 //already bloodied with this blood. Cannot add more.
- blood_DNA[H.dna.unique_enzymes] = H.dna.b_type
- H.update_inv_gloves() //handles bloody hands overlays and updating
- return 1 //we applied blood to the item
+ blood_color = "#A10808"
+ if (M.species)
+ blood_color = M.species.blood_color
return
/atom/proc/add_vomit_floor(mob/living/carbon/M as mob, var/toxvomit = 0)
diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm
index 9102ee8780..32c7ef1dd6 100644
--- a/code/game/dna/dna2.dm
+++ b/code/game/dna/dna2.dm
@@ -16,15 +16,6 @@
#define DNA_HARDER_BOUNDS list(1,3049,3050,4095)
#define DNA_HARD_BOUNDS list(1,3490,3500,4095)
-// Defines which values mean "on" or "off".
-// This is to make some of the more OP superpowers a larger PITA to activate,
-// and to tell our new DNA datum which values to set in order to turn something
-// on or off.
-var/global/list/dna_activity_bounds[STRUCDNASIZE]
-
-// Used to determine what each block means (admin hax and species stuff on /vg/, mostly)
-var/global/list/assigned_blocks[STRUCDNASIZE]
-
// UI Indices (can change to mutblock style, if desired)
#define DNA_UI_HAIR_R 1
#define DNA_UI_HAIR_G 2
@@ -33,29 +24,43 @@ var/global/list/assigned_blocks[STRUCDNASIZE]
#define DNA_UI_BEARD_G 5
#define DNA_UI_BEARD_B 6
#define DNA_UI_SKIN_TONE 7
-#define DNA_UI_EYES_R 8
-#define DNA_UI_EYES_G 9
-#define DNA_UI_EYES_B 10
-#define DNA_UI_GENDER 11
-#define DNA_UI_BEARD_STYLE 12
-#define DNA_UI_HAIR_STYLE 13
-#define DNA_UI_LENGTH 13 // Update this when you add something, or you WILL break shit.
+#define DNA_UI_SKIN_R 8
+#define DNA_UI_SKIN_G 9
+#define DNA_UI_SKIN_B 10
+#define DNA_UI_EYES_R 11
+#define DNA_UI_EYES_G 12
+#define DNA_UI_EYES_B 13
+#define DNA_UI_GENDER 14
+#define DNA_UI_BEARD_STYLE 15
+#define DNA_UI_HAIR_STYLE 16
+#define DNA_UI_LENGTH 16 // Update this when you add something, or you WILL break shit.
+
+#define DNA_SE_LENGTH 27
+// For later:
+//#define DNA_SE_LENGTH 50 // Was STRUCDNASIZE, size 27. 15 new blocks added = 42, plus room to grow.
-/* Note RE: unassigned blocks
+// Defines which values mean "on" or "off".
+// This is to make some of the more OP superpowers a larger PITA to activate,
+// and to tell our new DNA datum which values to set in order to turn something
+// on or off.
+var/global/list/dna_activity_bounds[DNA_SE_LENGTH]
- Many genes in baycode are currently sitting unused
- (compare setupgame.dm to the number of *BLOCK variables).
+// Used to determine what each block means (admin hax and species stuff on /vg/, mostly)
+var/global/list/assigned_blocks[DNA_SE_LENGTH]
- This datum will return 0 (or equivalent) if asked about
- a block 0 (which means the gene was unassigned). Setters
- will silently return without performing any action.
+var/global/list/datum/dna/gene/dna_genes[0]
- I have code to assign these genes in a streamlined manner,
- but in order to avoid breaking things, I've left the
- existing setupgame.dm intact. Please let me know if you
- need this behavior changed.
- */
+/////////////////
+// GENE DEFINES
+/////////////////
+// Skip checking if it's already active.
+// Used for genes that check for value rather than a binary on/off.
+#define GENE_ALWAYS_ACTIVATE 1
+
+// Skip checking if it's already active.
+// Used for genes that check for value rather than a binary on/off.
+#define GENE_ALWAYS_ACTIVATE 1
/datum/dna
// READ-ONLY, GETS OVERWRITTEN
@@ -70,13 +75,33 @@ var/global/list/assigned_blocks[STRUCDNASIZE]
// Okay to read, but you're an idiot if you do.
// BLOCK = VALUE
- var/list/SE[STRUCDNASIZE]
+ var/list/SE[DNA_SE_LENGTH]
var/list/UI[DNA_UI_LENGTH]
// From old dna.
var/b_type = "A+" // Should probably change to an integer => string map but I'm lazy.
var/mutantrace = null // The type of mutant race the player is, if applicable (i.e. potato-man)
var/real_name // Stores the real name of the person who originally got this dna datum. Used primarily for changelings,
+
+ // New stuff
+ var/species = "Human"
+
+// Make a copy of this strand.
+// USE THIS WHEN COPYING STUFF OR YOU'LL GET CORRUPTION!
+/datum/dna/proc/Clone()
+ var/datum/dna/new_dna = new()
+ new_dna.unique_enzymes=unique_enzymes
+ new_dna.b_type=b_type
+ new_dna.mutantrace=mutantrace
+ new_dna.real_name=real_name
+ new_dna.species=species
+ for(var/b=1;b<=DNA_SE_LENGTH;b++)
+ new_dna.SE[b]=SE[b]
+ if(b<=DNA_UI_LENGTH)
+ new_dna.UI[b]=UI[b]
+ new_dna.UpdateUI()
+ new_dna.UpdateSE()
+ return new_dna
///////////////////////////////////////
// UNIQUE IDENTITY
///////////////////////////////////////
@@ -84,7 +109,11 @@ var/global/list/assigned_blocks[STRUCDNASIZE]
// Create random UI.
/datum/dna/proc/ResetUI(var/defer=0)
for(var/i=1,i<=DNA_UI_LENGTH,i++)
- UI[i]=rand(0,4095)
+ switch(i)
+ if(DNA_UI_SKIN_TONE)
+ SetUIValueRange(DNA_UI_SKIN_TONE,rand(1,220),220,1) // Otherwise, it gets fucked
+ else
+ UI[i]=rand(0,4095)
if(!defer)
UpdateUI()
@@ -110,13 +139,17 @@ var/global/list/assigned_blocks[STRUCDNASIZE]
SetUIValueRange(DNA_UI_BEARD_G, character.g_facial, 255, 1)
SetUIValueRange(DNA_UI_BEARD_B, character.b_facial, 255, 1)
- SetUIValueRange(DNA_UI_BEARD_R, character.r_eyes, 255, 1)
- SetUIValueRange(DNA_UI_BEARD_G, character.g_eyes, 255, 1)
- SetUIValueRange(DNA_UI_BEARD_B, character.b_eyes, 255, 1)
+ SetUIValueRange(DNA_UI_EYES_R, character.r_eyes, 255, 1)
+ SetUIValueRange(DNA_UI_EYES_G, character.g_eyes, 255, 1)
+ SetUIValueRange(DNA_UI_EYES_B, character.b_eyes, 255, 1)
- SetUIValueRange(DNA_UI_SKIN_TONE, character.s_tone, 220, 1)
+ SetUIValueRange(DNA_UI_SKIN_R, character.r_skin, 255, 1)
+ SetUIValueRange(DNA_UI_SKIN_G, character.g_skin, 255, 1)
+ SetUIValueRange(DNA_UI_SKIN_B, character.b_skin, 255, 1)
- SetUIState(DNA_UI_GENDER, character.gender!=MALE, 1)
+ SetUIValueRange(DNA_UI_SKIN_TONE, 35-character.s_tone, 220, 1) // Value can be negative.
+
+ SetUIState(DNA_UI_GENDER, character.gender!=MALE, 1)
SetUIValueRange(DNA_UI_HAIR_STYLE, hair, hair_styles_list.len, 1)
SetUIValueRange(DNA_UI_BEARD_STYLE, beard, facial_hair_styles_list.len,1)
@@ -126,7 +159,7 @@ var/global/list/assigned_blocks[STRUCDNASIZE]
// Set a DNA UI block's raw value.
/datum/dna/proc/SetUIValue(var/block,var/value,var/defer=0)
if (block<=0) return
- ASSERT(value>=0)
+ ASSERT(value>0)
ASSERT(value<=4095)
UI[block]=value
dirtyUI=1
@@ -140,12 +173,13 @@ var/global/list/assigned_blocks[STRUCDNASIZE]
// Set a DNA UI block's value, given a value and a max possible value.
// Used in hair and facial styles (value being the index and maxvalue being the len of the hairstyle list)
-/datum/dna/proc/SetUIValueRange(var/block,var/value,var/maxvalue)
+/datum/dna/proc/SetUIValueRange(var/block,var/value,var/maxvalue,var/defer=0)
if (block<=0) return
+ if (value==0) value = 1 // FIXME: hair/beard/eye RGB values if they are 0 are not set, this is a work around we'll encode it in the DNA to be 1 instead.
ASSERT(maxvalue<=4095)
- var/range = round(4095 / maxvalue)
+ var/range = (4095 / maxvalue)
if(value)
- SetUIValue(block,value * range - rand(1,range-1))
+ SetUIValue(block,round(value * range),defer)
// Getter version of above.
/datum/dna/proc/GetUIValueRange(var/block,var/maxvalue)
@@ -205,13 +239,12 @@ var/global/list/assigned_blocks[STRUCDNASIZE]
// "Zeroes out" all of the blocks.
/datum/dna/proc/ResetSE()
- for(var/i = 1, i <= STRUCDNASIZE, i++)
+ for(var/i = 1, i <= DNA_SE_LENGTH, i++)
SetSEValue(i,rand(1,1024),1)
UpdateSE()
// Set a DNA SE block's raw value.
/datum/dna/proc/SetSEValue(var/block,var/value,var/defer=0)
- //testing("SetSEBlock([block],[value],[defer]): [value] -> [nval]")
if (block<=0) return
ASSERT(value>=0)
ASSERT(value<=4095)
@@ -234,6 +267,12 @@ var/global/list/assigned_blocks[STRUCDNASIZE]
if(value)
SetSEValue(block, value * range - rand(1,range-1))
+// Getter version of above.
+/datum/dna/proc/GetSEValueRange(var/block,var/maxvalue)
+ if (block<=0) return 0
+ var/value = GetSEValue(block)
+ return round(1 +(value / 4096)*maxvalue)
+
// Is the block "on" (1) or "off" (0)? (Un-assigned genes are always off.)
/datum/dna/proc/GetSEState(var/block)
if (block<=0) return 0
@@ -249,7 +288,7 @@ var/global/list/assigned_blocks[STRUCDNASIZE]
if(on)
val=rand(BOUNDS[DNA_ON_LOWERBOUND],BOUNDS[DNA_ON_UPPERBOUND])
else
- val=rand(BOUNDS[DNA_OFF_LOWERBOUND],BOUNDS[DNA_OFF_UPPERBOUND])
+ val=rand(1,BOUNDS[DNA_OFF_UPPERBOUND])
SetSEValue(block,val,defer)
// Get hex-encoded SE block.
@@ -310,7 +349,7 @@ var/global/list/assigned_blocks[STRUCDNASIZE]
if(UI.len != DNA_UI_LENGTH)
ResetUIFrom(character)
- if(length(struc_enzymes)!= 3*STRUCDNASIZE)
+ if(length(struc_enzymes)!= 3*DNA_SE_LENGTH)
ResetSE()
if(length(unique_enzymes) != 32)
@@ -318,7 +357,7 @@ var/global/list/assigned_blocks[STRUCDNASIZE]
else
if(length(uni_identity) != 3*DNA_UI_LENGTH)
uni_identity = "00600200A00E0110148FC01300B0095BD7FD3F4"
- if(length(struc_enzymes)!= 3*STRUCDNASIZE)
+ if(length(struc_enzymes)!= 3*DNA_SE_LENGTH)
struc_enzymes = "43359156756131E13763334D1C369012032164D4FE4CD61544B6C03F251B6C60A42821D26BA3B0FD6"
// BACK-COMPAT!
@@ -330,4 +369,3 @@ var/global/list/assigned_blocks[STRUCDNASIZE]
unique_enzymes = md5(character.real_name)
reg_dna[unique_enzymes] = character.real_name
-
diff --git a/code/game/dna/dna2_domutcheck.dm b/code/game/dna/dna2_domutcheck.dm
new file mode 100644
index 0000000000..954c86f2a6
--- /dev/null
+++ b/code/game/dna/dna2_domutcheck.dm
@@ -0,0 +1,43 @@
+// (Re-)Apply mutations.
+// TODO: Turn into a /mob proc, change inj to a bitflag for various forms of differing behavior.
+// M: Mob to mess with
+// connected: Machine we're in, type unchecked so I doubt it's used beyond monkeying
+// flags: See below, bitfield.
+#define MUTCHK_FORCED 1
+/proc/domutcheck(var/mob/living/M, var/connected=null, var/flags=0)
+ for(var/datum/dna/gene/gene in dna_genes)
+ if(!M)
+ return
+ if(!gene.block)
+ continue
+
+ // Sanity checks, don't skip.
+ if(!gene.can_activate(M,flags))
+ //testing("[M] - Failed to activate [gene.name] (can_activate fail).")
+ continue
+
+ // Current state
+ var/gene_active = (gene.flags & GENE_ALWAYS_ACTIVATE)
+ if(!gene_active)
+ gene_active = M.dna.GetSEState(gene.block)
+
+ // Prior state
+ var/gene_prior_status = (gene.type in M.active_genes)
+ var/changed = gene_active != gene_prior_status || (gene.flags & GENE_ALWAYS_ACTIVATE)
+
+ // If gene state has changed:
+ if(changed)
+ // Gene active (or ALWAYS ACTIVATE)
+ if(gene_active || (gene.flags & GENE_ALWAYS_ACTIVATE))
+ testing("[gene.name] activated!")
+ gene.activate(M,connected,flags)
+ if(M)
+ M.active_genes |= gene.type
+ M.update_icon = 1
+ // If Gene is NOT active:
+ else
+ testing("[gene.name] deactivated!")
+ gene.deactivate(M,connected,flags)
+ if(M)
+ M.active_genes -= gene.type
+ M.update_icon = 1
diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm
index 08d07ab2e1..4ffa5ea512 100644
--- a/code/game/dna/dna2_helpers.dm
+++ b/code/game/dna/dna2_helpers.dm
@@ -38,7 +38,7 @@
/proc/randmuti(var/mob/living/M)
if(!M) return
M.dna.check_integrity()
- M.dna.SetUIValue(rand(1,UNIDNASIZE),rand(1,4095))
+ M.dna.SetUIValue(rand(1,DNA_UI_LENGTH),rand(1,4095))
// Scramble UI or SE.
/proc/scramble(var/UI, var/mob/M, var/prob)
@@ -52,7 +52,7 @@
M.UpdateAppearance()
else
- for(var/i = 1, i <= STRUCDNASIZE-1, i++)
+ for(var/i = 1, i <= DNA_SE_LENGTH-1, i++)
if(prob(prob))
M.dna.SetSEValue(i,rand(1,4095),1)
M.dna.UpdateSE()
@@ -139,11 +139,15 @@
H.g_facial = dna.GetUIValueRange(DNA_UI_BEARD_G, 255)
H.b_facial = dna.GetUIValueRange(DNA_UI_BEARD_B, 255)
+ H.r_skin = dna.GetUIValueRange(DNA_UI_SKIN_R, 255)
+ H.g_skin = dna.GetUIValueRange(DNA_UI_SKIN_G, 255)
+ H.b_skin = dna.GetUIValueRange(DNA_UI_SKIN_B, 255)
+
H.r_eyes = dna.GetUIValueRange(DNA_UI_EYES_R, 255)
H.g_eyes = dna.GetUIValueRange(DNA_UI_EYES_G, 255)
H.b_eyes = dna.GetUIValueRange(DNA_UI_EYES_B, 255)
- H.s_tone = dna.GetUIValueRange(DNA_UI_SKIN_TONE, 220)
+ H.s_tone = 35 - dna.GetUIValueRange(DNA_UI_SKIN_TONE, 220) // Value can be negative.
if (dna.GetUIState(DNA_UI_GENDER))
H.gender = FEMALE
@@ -170,309 +174,3 @@
// Used below, simple injection modifier.
/proc/probinj(var/pr, var/inj)
return prob(pr+inj*pr)
-
-// (Re-)Apply mutations.
-// TODO: Turn into a /mob proc, change inj to a bitflag for various forms of differing behavior.
-// M: Mob to mess with
-// connected: Machine we're in, type unchecked so I doubt it's used beyond monkeying
-// inj: 1 for if we're checking this from an injector, screws with manifestation probability calc.
-/proc/domutcheck(mob/living/M as mob, connected, inj)
- if (!M) return
-
- M.dna.check_integrity()
-
- M.disabilities = 0
- M.sdisabilities = 0
- var/old_mutations = M.mutations
- M.mutations = list()
- M.pass_flags = 0
-// M.see_in_dark = 2
-// M.see_invisible = 0
-
- if(PLANT in old_mutations)
- M.mutations.Add(PLANT)
- if(SKELETON in old_mutations)
- M.mutations.Add(SKELETON)
- if(FAT in old_mutations)
- M.mutations.Add(FAT)
- if(HUSK in old_mutations)
- M.mutations.Add(HUSK)
-
- /////////////////////////////////////
- // IMPORTANT REMINDER
- // IF A BLOCK IS SET TO 0 (unused)
- // GetSEState(block) WILL RETURN 0
- /////////////////////////////////////
-
- if(M.dna.GetSEState(NOBREATHBLOCK))
- if(probinj(45,inj) || (mNobreath in old_mutations))
- M << "\blue You feel no need to breathe."
- M.mutations.Add(mNobreath)
- if(M.dna.GetSEState(REMOTEVIEWBLOCK))
- if(probinj(45,inj) || (mRemote in old_mutations))
- M << "\blue Your mind expands"
- M.mutations.Add(mRemote)
- M.verbs += /mob/living/carbon/human/proc/remoteobserve
- if(M.dna.GetSEState(REGENERATEBLOCK))
- if(probinj(45,inj) || (mRegen in old_mutations))
- M << "\blue You feel better"
- M.mutations.Add(mRegen)
- if(M.dna.GetSEState(INCREASERUNBLOCK))
- if(probinj(45,inj) || (mRun in old_mutations))
- M << "\blue Your leg muscles pulsate."
- M.mutations.Add(mRun)
- if(M.dna.GetSEState(REMOTETALKBLOCK))
- if(probinj(45,inj) || (mRemotetalk in old_mutations))
- M << "\blue You expand your mind outwards"
- M.mutations.Add(mRemotetalk)
- M.verbs += /mob/living/carbon/human/proc/remotesay
- if(M.dna.GetSEState(MORPHBLOCK))
- if(probinj(45,inj) || (mMorph in old_mutations))
- M.mutations.Add(mMorph)
- M << "\blue Your skin feels strange"
- M.verbs += /mob/living/carbon/human/proc/morph
- if(M.dna.GetSEState(HALLUCINATIONBLOCK))
- if(probinj(45,inj) || (mHallucination in old_mutations))
- M.mutations.Add(mHallucination)
- M << "\red Your mind says 'Hello'"
- if(M.dna.GetSEState(NOPRINTSBLOCK))
- if(probinj(45,inj) || (mFingerprints in old_mutations))
- M.mutations.Add(mFingerprints)
- M << "\blue Your fingers feel numb"
- if(M.dna.GetSEState(SHOCKIMMUNITYBLOCK))
- if(probinj(45,inj) || (mShock in old_mutations))
- M.mutations.Add(mShock)
- M << "\blue Your skin feels strange"
- if(M.dna.GetSEState(SMALLSIZEBLOCK))
- if(probinj(45,inj) || (mSmallsize in old_mutations))
- M << "\blue Your skin feels rubbery"
- M.mutations.Add(mSmallsize)
- M.pass_flags |= 1
-
-
-
- if (M.dna.GetSEState(HULKBLOCK))
- if(probinj(5,inj) || (HULK in old_mutations))
- M << "\blue Your muscles hurt."
- M.mutations.Add(HULK)
- if (M.dna.GetSEState(HEADACHEBLOCK))
- M.disabilities |= EPILEPSY
- M << "\red You get a headache."
- if (M.dna.GetSEState(FAKEBLOCK))
- M << "\red You feel strange."
- if (prob(95))
- if(prob(50))
- randmutb(M)
- else
- randmuti(M)
- else
- randmutg(M)
- if (M.dna.GetSEState(COUGHBLOCK))
- M.disabilities |= COUGHING
- M << "\red You start coughing."
- if (M.dna.GetSEState(CLUMSYBLOCK))
- M << "\red You feel lightheaded."
- M.mutations.Add(CLUMSY)
- if (M.dna.GetSEState(TWITCHBLOCK))
- M.disabilities |= TOURETTES
- M << "\red You twitch."
- if (M.dna.GetSEState(XRAYBLOCK))
- if(probinj(30,inj) || (XRAY in old_mutations))
- M << "\blue The walls suddenly disappear."
-// M.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS)
-// M.see_in_dark = 8
-// M.see_invisible = 2
- M.mutations.Add(XRAY)
- if (M.dna.GetSEState(NERVOUSBLOCK))
- M.disabilities |= NERVOUS
- M << "\red You feel nervous."
- if (M.dna.GetSEState(FIREBLOCK))
- if(probinj(30,inj) || (COLD_RESISTANCE in old_mutations))
- M << "\blue Your body feels warm."
- M.mutations.Add(COLD_RESISTANCE)
- if (M.dna.GetSEState(BLINDBLOCK))
- M.sdisabilities |= BLIND
- M << "\red You can't seem to see anything."
- if (M.dna.GetSEState(TELEBLOCK))
- if(probinj(15,inj) || (TK in old_mutations))
- M << "\blue You feel smarter."
- M.mutations.Add(TK)
- if (M.dna.GetSEState(DEAFBLOCK))
- M.sdisabilities |= DEAF
- M.ear_deaf = 1
- M << "\red Its kinda quiet.."
- if (M.dna.GetSEState(GLASSESBLOCK))
- M.disabilities |= NEARSIGHTED
- M << "Your eyes feel weird..."
-
- /* If you want the new mutations to work, UNCOMMENT THIS.
- if(istype(M, /mob/living/carbon))
- for (var/datum/mutations/mut in global_mutations)
- mut.check_mutation(M)
- */
-
-//////////////////////////////////////////////////////////// Monkey Block
- if (M.dna.GetSEState(MONKEYBLOCK) && istype(M, /mob/living/carbon/human))
- // human > monkey
- var/mob/living/carbon/human/H = M
- H.monkeyizing = 1
- var/list/implants = list() //Try to preserve implants.
- for(var/obj/item/weapon/implant/W in H)
- implants += W
- W.loc = null
-
- if(!connected)
- for(var/obj/item/W in (H.contents-implants))
- if (W==H.w_uniform) // will be teared
- continue
- H.drop_from_inventory(W)
- M.monkeyizing = 1
- M.canmove = 0
- M.icon = null
- M.invisibility = 101
- var/atom/movable/overlay/animation = new( M.loc )
- animation.icon_state = "blank"
- animation.icon = 'icons/mob/mob.dmi'
- animation.master = src
- flick("h2monkey", animation)
- sleep(48)
- del(animation)
-
-
- var/mob/living/carbon/monkey/O = null
- if(H.species.primitive)
- O = new H.species.primitive(src)
- else
- H.gib() //Trying to change the species of a creature with no primitive var set is messy.
- return
-
- if(M)
- if (M.dna)
- O.dna = M.dna
- M.dna = null
-
- if (M.suiciding)
- O.suiciding = M.suiciding
- M.suiciding = null
-
-
- for(var/datum/disease/D in M.viruses)
- O.viruses += D
- D.affected_mob = O
- M.viruses -= D
-
-
- for(var/obj/T in (M.contents-implants))
- del(T)
-
- O.loc = M.loc
-
- if(M.mind)
- M.mind.transfer_to(O) //transfer our mind to the cute little monkey
-
- if (connected) //inside dna thing
- var/obj/machinery/dna_scannernew/C = connected
- O.loc = C
- C.occupant = O
- connected = null
- O.real_name = text("monkey ([])",copytext(md5(M.real_name), 2, 6))
- O.take_overall_damage(M.getBruteLoss() + 40, M.getFireLoss())
- O.adjustToxLoss(M.getToxLoss() + 20)
- O.adjustOxyLoss(M.getOxyLoss())
- O.stat = M.stat
- O.a_intent = "hurt"
- for (var/obj/item/weapon/implant/I in implants)
- I.loc = O
- I.implanted = O
-// O.update_icon = 1 //queue a full icon update at next life() call
- del(M)
- return
-
- if (!M.dna.GetSEState(MONKEYBLOCK) && !istype(M, /mob/living/carbon/human))
- // monkey > human,
- var/mob/living/carbon/monkey/Mo = M
- Mo.monkeyizing = 1
- var/list/implants = list() //Still preserving implants
- for(var/obj/item/weapon/implant/W in Mo)
- implants += W
- W.loc = null
- if(!connected)
- for(var/obj/item/W in (Mo.contents-implants))
- Mo.drop_from_inventory(W)
- M.monkeyizing = 1
- M.canmove = 0
- M.icon = null
- M.invisibility = 101
- var/atom/movable/overlay/animation = new( M.loc )
- animation.icon_state = "blank"
- animation.icon = 'icons/mob/mob.dmi'
- animation.master = src
- flick("monkey2h", animation)
- sleep(48)
- del(animation)
-
- var/mob/living/carbon/human/O = new( src )
- if(Mo.greaterform)
- O.set_species(Mo.greaterform)
-
- if (M.dna.GetUIState(DNA_UI_GENDER))
- O.gender = FEMALE
- else
- O.gender = MALE
-
- if (M)
- if (M.dna)
- O.dna = M.dna
- M.dna = null
-
- if (M.suiciding)
- O.suiciding = M.suiciding
- M.suiciding = null
-
- for(var/datum/disease/D in M.viruses)
- O.viruses += D
- D.affected_mob = O
- M.viruses -= D
-
- //for(var/obj/T in M)
- // del(T)
-
- O.loc = M.loc
-
- if(M.mind)
- M.mind.transfer_to(O) //transfer our mind to the human
-
- if (connected) //inside dna thing
- var/obj/machinery/dna_scannernew/C = connected
- O.loc = C
- C.occupant = O
- connected = null
-
- var/i
- while (!i)
- var/randomname
- if (O.gender == MALE)
- randomname = capitalize(pick(first_names_male) + " " + capitalize(pick(last_names)))
- else
- randomname = capitalize(pick(first_names_female) + " " + capitalize(pick(last_names)))
- if (findname(randomname))
- continue
- else
- O.real_name = randomname
- i++
- O.UpdateAppearance()
- O.take_overall_damage(M.getBruteLoss(), M.getFireLoss())
- O.adjustToxLoss(M.getToxLoss())
- O.adjustOxyLoss(M.getOxyLoss())
- O.stat = M.stat
- for (var/obj/item/weapon/implant/I in implants)
- I.loc = O
- I.implanted = O
-// O.update_icon = 1 //queue a full icon update at next life() call
- del(M)
- return
-//////////////////////////////////////////////////////////// Monkey Block
- if(M)
- M.update_icon = 1 //queue a full icon update at next life() call
- return null
-/////////////////////////// DNA MISC-PROCS
\ No newline at end of file
diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm
index 37ad94e3f5..eadbfb06e1 100644
--- a/code/game/dna/dna_modifier.dm
+++ b/code/game/dna/dna_modifier.dm
@@ -1,5 +1,38 @@
#define DNA_BLOCK_SIZE 3
+// Buffer datatype flags.
+#define DNA2_BUF_UI 1
+#define DNA2_BUF_UE 2
+#define DNA2_BUF_SE 4
+
+//list("data" = null, "owner" = null, "label" = null, "type" = null, "ue" = 0),
+/datum/dna2/record
+ var/datum/dna/dna = null
+ var/types=0
+ var/name="Empty"
+
+ // Stuff for cloners
+ var/id=null
+ var/implant=null
+ var/ckey=null
+ var/mind=null
+
+/datum/dna2/record/proc/GetData()
+ var/list/ser=list("data" = null, "owner" = null, "label" = null, "type" = null, "ue" = 0)
+ if(dna)
+ ser["ue"] = (types & DNA2_BUF_UE) == DNA2_BUF_UE
+ if(types & DNA2_BUF_SE)
+ ser["data"] = dna.SE
+ else
+ ser["data"] = dna.UI
+ ser["owner"] = src.dna.real_name
+ ser["label"] = name
+ if(types & DNA2_BUF_UI)
+ ser["type"] = "ui"
+ else
+ ser["type"] = "se"
+ return ser
+
/////////////////////////// DNA MACHINES
/obj/machinery/dna_scannernew
name = "\improper DNA modifier"
@@ -14,6 +47,7 @@
var/locked = 0
var/mob/living/carbon/occupant = null
var/obj/item/weapon/reagent_containers/glass/beaker = null
+ var/opened = 0
/obj/machinery/dna_scannernew/New()
..()
@@ -80,12 +114,6 @@
usr.loc = src
src.occupant = usr
src.icon_state = "scanner_1"
- /*
- for(var/obj/O in src) // THIS IS P. STUPID -- LOVE, DOOHL
- //O = null
- del(O)
- //Foreach goto(124)
- */
src.add_fingerprint(usr)
return
@@ -111,7 +139,12 @@
if (G.affecting.abiotic())
user << "\blue Subject cannot have abiotic items on."
return
- var/mob/M = G.affecting
+ put_in(G.affecting)
+ src.add_fingerprint(user)
+ del(G)
+ return
+
+/obj/machinery/dna_scannernew/proc/put_in(var/mob/M)
if(M.client)
M.client.perspective = EYE_PERSPECTIVE
M.client.eye = src
@@ -119,8 +152,6 @@
src.occupant = M
src.icon_state = "scanner_1"
- src.add_fingerprint(user)
-
// search for ghosts, if the corpse is empty and the scanner is connected to a cloner
if(locate(/obj/machinery/computer/cloning, get_step(src, NORTH)) \
|| locate(/obj/machinery/computer/cloning, get_step(src, SOUTH)) \
@@ -132,19 +163,11 @@
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)"
break
- del(G)
return
/obj/machinery/dna_scannernew/proc/go_out()
if ((!( src.occupant ) || src.locked))
return
-/*
-// it's like this was -just- here to break constructed dna scanners -Pete
-// if that's not the case, slap my shit and uncomment this.
-// for(var/obj/O in src)
-// O.loc = src.loc
-*/
- //Foreach goto(30)
if (src.occupant.client)
src.occupant.client.eye = src.occupant.client.mob
src.occupant.client.perspective = MOB_PERSPECTIVE
@@ -205,11 +228,7 @@
var/selected_ui_target_hex = 1
var/radiation_duration = 2.0
var/radiation_intensity = 1.0
- var/list/buffers = list(
- list("data" = null, "owner" = null, "label" = null, "type" = null, "ue" = 0),
- list("data" = null, "owner" = null, "label" = null, "type" = null, "ue" = 0),
- list("data" = null, "owner" = null, "label" = null, "type" = null, "ue" = 0)
- )
+ var/list/datum/dna2/record/buffers[3]
var/irradiating = 0
var/injector_ready = 0 //Quick fix for issue 286 (screwdriver the screen twice to restore injector) -Pete
var/obj/machinery/dna_scannernew/connected = null
@@ -219,6 +238,7 @@
use_power = 1
idle_power_usage = 10
active_power_usage = 400
+ var/waiting_for_user_input=0 // Fix for #274 (Mash create block injector without answering dialog to make unlimited injectors) - N3X
/obj/machinery/computer/scan_consolenew/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/weapon/screwdriver))
@@ -253,7 +273,7 @@
I.loc = src
src.disk = I
user << "You insert [I]."
- nanomanager.update_uis(src) // update all UIs attached to src()
+ nanomanager.update_uis(src) // update all UIs attached to src
return
else
src.attack_hand(user)
@@ -292,6 +312,8 @@
/obj/machinery/computer/scan_consolenew/New()
..()
+ for(var/i=0;i<3;i++)
+ buffers[i+1]=new /datum/dna2/record
spawn(5)
for(dir in list(NORTH,EAST,SOUTH,WEST))
connected = locate(/obj/machinery/dna_scannernew, get_step(src, dir))
@@ -308,13 +330,13 @@
arr += "[i]:[EncodeDNABlock(buffer[i])]"
return arr
-/obj/machinery/computer/scan_consolenew/proc/setInjectorBlock(var/obj/item/weapon/dnainjector/I, var/blk, var/list/buffer)
+/obj/machinery/computer/scan_consolenew/proc/setInjectorBlock(var/obj/item/weapon/dnainjector/I, var/blk, var/datum/dna2/record/buffer)
var/pos = findtext(blk,":")
if(!pos) return 0
var/id = text2num(copytext(blk,1,pos))
if(!id) return 0
I.block = id
- I.dna = list(buffer[id])
+ I.buf = buffer
return 1
/obj/machinery/computer/scan_consolenew/attackby(obj/item/W as obj, mob/user as mob)
@@ -323,7 +345,7 @@
W.loc = src
src.disk = W
user << "You insert [W]."
- nanomanager.update_uis(src) // update all UIs attached to src()
+ nanomanager.update_uis(src) // update all UIs attached to src
/*
/obj/machinery/computer/scan_consolenew/process() //not really used right now
if(stat & (NOPOWER|BROKEN))
@@ -336,6 +358,7 @@
ui_interact(user)
/obj/machinery/computer/scan_consolenew/attack_ai(user as mob)
+ src.add_hiddenprint(user)
ui_interact(user)
/obj/machinery/computer/scan_consolenew/attack_hand(user as mob)
@@ -345,7 +368,7 @@
/**
* The ui_interact proc is used to open and update Nano UIs
* If ui_interact is not used then the UI will not update correctly
- * ui_interact is currently defined for /atom/movable
+ * ui_interact is currently defined for /atom/movable (which is inherited by /obj and /mob)
*
* @param user /mob The mob who is interacting with this ui
* @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main")
@@ -363,27 +386,26 @@
data["selectedMenuKey"] = selected_menu_key
data["locked"] = src.connected.locked
data["hasOccupant"] = connected.occupant ? 1 : 0
-
+
data["isInjectorReady"] = injector_ready
data["hasDisk"] = disk ? 1 : 0
var/diskData[0]
- if (!disk)
+ if (!disk || !disk.buf)
diskData["data"] = null
diskData["owner"] = null
diskData["label"] = null
diskData["type"] = null
diskData["ue"] = null
else
- diskData["data"] = disk.data
- diskData["owner"] = disk.owner
- diskData["label"] = disk.name
- diskData["type"] = disk.data_type
- diskData["ue"] = disk.ue
+ diskData = disk.buf.GetData()
data["disk"] = diskData
- data["buffers"] = buffers
+ var/list/new_buffers = list()
+ for(var/datum/dna2/record/buf in src.buffers)
+ new_buffers += list(buf.GetData())
+ data["buffers"]=new_buffers
data["radiationIntensity"] = radiation_intensity
data["radiationDuration"] = radiation_duration
@@ -432,23 +454,19 @@
if (connected.beaker.reagents && connected.beaker.reagents.reagent_list.len)
for(var/datum/reagent/R in connected.beaker.reagents.reagent_list)
data["beakerVolume"] += R.volume
-
- if (!ui) // no ui has been passed, so we'll search for one
- {
- ui = nanomanager.get_open_ui(user, src, ui_key)
- }
+
+ // update the ui if it exists, returns null if no ui is passed/found
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
if (!ui)
- // the ui does not exist, so we'll create a new one
+ // the ui does not exist, so we'll create a new() one
+ // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
ui = new(user, src, ui_key, "dna_modifier.tmpl", "DNA Modifier Console", 660, 700)
- // When the UI is first opened this is the data it will use
- ui.set_initial_data(data)
+ // when the ui is first opened this is the data it will use
+ ui.set_initial_data(data)
+ // open the new ui window
ui.open()
- // Auto update every Master Controller tick
+ // auto update every Master Controller tick
ui.set_auto_update(1)
- else
- // The UI is already open so push the new data to it
- ui.push_data(data)
- return
/obj/machinery/computer/scan_consolenew/Topic(href, href_list)
if(..())
@@ -620,14 +638,17 @@
if (href_list["selectSEBlock"] && href_list["selectSESubblock"]) // This chunk of code updates selected block / sub-block based on click (se stands for strutural enzymes)
var/select_block = text2num(href_list["selectSEBlock"])
var/select_subblock = text2num(href_list["selectSESubblock"])
- if ((select_block <= STRUCDNASIZE) && (select_block >= 1))
+ if ((select_block <= DNA_SE_LENGTH) && (select_block >= 1))
src.selected_se_block = select_block
if ((select_subblock <= DNA_BLOCK_SIZE) && (select_subblock >= 1))
src.selected_se_subblock = select_subblock
+ //testing("User selected block [selected_se_block] (sent [select_block]), subblock [selected_se_subblock] (sent [select_block]).")
return 1 // return 1 forces an update to all Nano uis attached to src
if (href_list["pulseSERadiation"])
var/block = src.connected.occupant.dna.GetSESubBlock(src.selected_se_block,src.selected_se_subblock)
+ //var/original_block=block
+ //testing("Irradiating SE block [src.selected_se_block]:[src.selected_se_subblock] ([block])...")
irradiating = src.radiation_duration
var/lock_state = src.connected.locked
@@ -645,28 +666,32 @@
var/real_SE_block=selected_se_block
block = miniscramble(block, src.radiation_intensity, src.radiation_duration)
if(prob(20))
- if (src.selected_se_block > 1 && src.selected_se_block < STRUCDNASIZE/2)
+ if (src.selected_se_block > 1 && src.selected_se_block < DNA_SE_LENGTH/2)
real_SE_block++
- else if (src.selected_se_block > STRUCDNASIZE/2 && src.selected_se_block < STRUCDNASIZE)
+ else if (src.selected_se_block > DNA_SE_LENGTH/2 && src.selected_se_block < DNA_SE_LENGTH)
real_SE_block--
+ //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)
- domutcheck(src.connected.occupant,src.connected)
src.connected.occupant.radiation += (src.radiation_intensity+src.radiation_duration)
+ domutcheck(src.connected.occupant,src.connected)
else
+ src.connected.occupant.radiation += ((src.radiation_intensity*2)+src.radiation_duration)
if (prob(80-src.radiation_duration))
+ //testing("Random bad mut!")
randmutb(src.connected.occupant)
domutcheck(src.connected.occupant,src.connected)
else
randmuti(src.connected.occupant)
+ //testing("Random identity mut!")
src.connected.occupant.UpdateAppearance()
- src.connected.occupant.radiation += ((src.radiation_intensity*2)+src.radiation_duration)
src.connected.locked = lock_state
return 1 // return 1 forces an update to all Nano uis attached to src
if(href_list["ejectBeaker"])
if(connected.beaker)
- connected.beaker.loc = connected.loc
+ var/obj/item/weapon/reagent_containers/glass/B = connected.beaker
+ B.loc = connected.loc
connected.beaker = null
return 1
@@ -677,18 +702,14 @@
// Transfer Buffer Management
if(href_list["bufferOption"])
var/bufferOption = href_list["bufferOption"]
-
+
// These bufferOptions do not require a bufferId
if (bufferOption == "wipeDisk")
if ((isnull(src.disk)) || (src.disk.read_only))
//src.temphtml = "Invalid disk. Please try again."
return 0
- src.disk.data = null
- src.disk.data_type = null
- src.disk.ue = null
- src.disk.owner = null
- src.disk.name = null
+ src.disk.buf=null
//src.temphtml = "Data saved."
return 1
@@ -702,7 +723,7 @@
// All bufferOptions from here on require a bufferId
if (!href_list["bufferId"])
return 0
-
+
var/bufferId = text2num(href_list["bufferId"])
if (bufferId < 1 || bufferId > 3)
@@ -710,56 +731,52 @@
if (bufferOption == "saveUI")
if(src.connected.occupant && src.connected.occupant.dna)
- src.buffers[bufferId]["ue"] = 0
- src.buffers[bufferId]["data"] = src.connected.occupant.dna.UI
- if (!istype(src.connected.occupant,/mob/living/carbon/human))
- src.buffers[bufferId]["owner"] = src.connected.occupant.name
- else
- src.buffers[bufferId]["owner"] = src.connected.occupant.real_name
- src.buffers[bufferId]["label"] = "Unique Identifier"
- src.buffers[bufferId]["type"] = "ui"
+ var/datum/dna2/record/databuf=new
+ databuf.types = DNA2_BUF_UE
+ databuf.dna = src.connected.occupant.dna.Clone()
+ if(ishuman(connected.occupant))
+ databuf.dna.real_name=connected.occupant.name
+ databuf.name = "Unique Identifier"
+ src.buffers[bufferId] = databuf
return 1
if (bufferOption == "saveUIAndUE")
if(src.connected.occupant && src.connected.occupant.dna)
- src.buffers[bufferId]["data"] = src.connected.occupant.dna.UI
- if (!istype(src.connected.occupant,/mob/living/carbon/human))
- src.buffers[bufferId]["owner"] = src.connected.occupant.name
- else
- src.buffers[bufferId]["owner"] = src.connected.occupant.real_name
- src.buffers[bufferId]["label"] = "Unique Identifier + Unique Enzymes"
- src.buffers[bufferId]["type"] = "ui"
- src.buffers[bufferId]["ue"] = 1
+ var/datum/dna2/record/databuf=new
+ databuf.types = DNA2_BUF_UI|DNA2_BUF_UE
+ databuf.dna = src.connected.occupant.dna.Clone()
+ if(ishuman(connected.occupant))
+ databuf.dna.real_name=connected.occupant.name
+ databuf.name = "Unique Identifier + Unique Enzymes"
+ src.buffers[bufferId] = databuf
return 1
if (bufferOption == "saveSE")
if(src.connected.occupant && src.connected.occupant.dna)
- src.buffers[bufferId]["ue"] = 0
- src.buffers[bufferId]["data"] = src.connected.occupant.dna.SE
- if (!istype(src.connected.occupant,/mob/living/carbon/human))
- src.buffers[bufferId]["owner"] = src.connected.occupant.name
- else
- src.buffers[bufferId]["owner"] = src.connected.occupant.real_name
- src.buffers[bufferId]["label"] = "Structural Enzymes"
- src.buffers[bufferId]["type"] = "se"
+ var/datum/dna2/record/databuf=new
+ databuf.types = DNA2_BUF_SE
+ databuf.dna = src.connected.occupant.dna.Clone()
+ if(ishuman(connected.occupant))
+ databuf.dna.real_name=connected.occupant.name
+ databuf.name = "Structural Enzymes"
+ src.buffers[bufferId] = databuf
return 1
if (bufferOption == "clear")
- src.buffers[bufferId]["data"] = null
- src.buffers[bufferId]["owner"] = null
- src.buffers[bufferId]["label"] = null
- src.buffers[bufferId]["ue"] = null
+ src.buffers[bufferId]=new /datum/dna2/record()
return 1
if (bufferOption == "changeLabel")
- var/label = src.buffers[bufferId]["label"] ? src.buffers[bufferId]["label"] : "New Label"
- src.buffers[bufferId]["label"] = sanitize(input("New Label:", "Edit Label", label))
+ var/datum/dna2/record/buf = src.buffers[bufferId]
+ var/text = sanitize(input(usr, "New Label:", "Edit Label", buf.name) as text|null)
+ buf.name = text
+ src.buffers[bufferId] = buf
return 1
if (bufferOption == "transfer")
if (!src.connected.occupant || (NOCLONE in src.connected.occupant.mutations) || !src.connected.occupant.dna)
return
-
+
irradiating = 2
var/lock_state = src.connected.locked
src.connected.locked = 1//lock it
@@ -769,33 +786,42 @@
irradiating = 0
src.connected.locked = lock_state
-
- if (src.buffers[bufferId]["type"] == "ui")
- if (src.buffers[bufferId]["ue"])
- src.connected.occupant.real_name = src.buffers[bufferId]["owner"]
- src.connected.occupant.name = src.buffers[bufferId]["owner"]
- src.connected.occupant.UpdateAppearance(src.buffers[bufferId]["data"])
- else if (src.buffers[bufferId]["type"] == "se")
- src.connected.occupant.dna.SE = src.buffers[bufferId]["data"]
+
+ var/datum/dna2/record/buf = src.buffers[bufferId]
+
+ if ((buf.types & DNA2_BUF_UI))
+ if ((buf.types & DNA2_BUF_UE))
+ src.connected.occupant.real_name = buf.dna.real_name
+ src.connected.occupant.name = buf.dna.real_name
+ src.connected.occupant.UpdateAppearance(buf.dna.UI.Copy())
+ else if (buf.types & DNA2_BUF_SE)
+ 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)
return 1
if (bufferOption == "createInjector")
- if (src.injector_ready)
+ if (src.injector_ready || waiting_for_user_input)
+
var/success = 1
var/obj/item/weapon/dnainjector/I = new /obj/item/weapon/dnainjector
- I.dnatype = src.buffers[bufferId]["type"]
+ var/datum/dna2/record/buf = src.buffers[bufferId]
if(href_list["createBlockInjector"])
- var/blk = input(usr,"Select Block","Block") in all_dna_blocks(src.buffers[bufferId]["data"])
- success = setInjectorBlock(I,blk,src.buffers[bufferId]["data"])
+ waiting_for_user_input=1
+ var/list/selectedbuf
+ if(buf.types & DNA2_BUF_SE)
+ selectedbuf=buf.dna.SE
+ else
+ selectedbuf=buf.dna.UI
+ var/blk = input(usr,"Select Block","Block") in all_dna_blocks(selectedbuf)
+ success = setInjectorBlock(I,blk,buf)
else
- I.dna = src.buffers[bufferId]["data"]
+ I.buf = buf
+ waiting_for_user_input=0
if(success)
I.loc = src.loc
- I.name += " ([src.buffers[bufferId]["label"]])"
- if (src.buffers[bufferId]["ue"]) I.ue = src.buffers[bufferId]["owner"] //lazy haw haw
+ I.name += " ([buf.name])"
//src.temphtml = "Injector created."
src.injector_ready = 0
spawn(300)
@@ -807,14 +833,11 @@
return 1
if (bufferOption == "loadDisk")
- if ((isnull(src.disk)) || (!src.disk.data) || (src.disk.data == ""))
+ if ((isnull(src.disk)) || (!src.disk.buf))
//src.temphtml = "Invalid disk. Please try again."
return 0
- src.buffers[bufferId]["data"] = src.disk.data
- src.buffers[bufferId]["type"] = src.disk.data_type
- src.buffers[bufferId]["ue"] = src.disk.ue
- src.buffers[bufferId]["owner"] = src.disk.owner
+ src.buffers[bufferId]=src.disk.buf
//src.temphtml = "Data loaded."
return 1
@@ -823,11 +846,10 @@
//src.temphtml = "Invalid disk. Please try again."
return 0
- src.disk.data = buffers[bufferId]["data"]
- src.disk.data_type = src.buffers[bufferId]["type"]
- src.disk.ue = src.buffers[bufferId]["ue"]
- src.disk.owner = src.buffers[bufferId]["owner"]
- src.disk.name = "data disk - '[src.buffers[bufferId]["owner"]]'"
+ var/datum/dna2/record/buf = src.buffers[bufferId]
+
+ src.disk.buf = buf
+ src.disk.name = "data disk - '[buf.dna.real_name]'"
//src.temphtml = "Data saved."
return 1
diff --git a/code/game/dna/genes/disabilities.dm b/code/game/dna/genes/disabilities.dm
new file mode 100644
index 0000000000..a119a0cf4b
--- /dev/null
+++ b/code/game/dna/genes/disabilities.dm
@@ -0,0 +1,129 @@
+/////////////////////
+// DISABILITY GENES
+//
+// These activate either a mutation, disability, or sdisability.
+//
+// Gene is always activated.
+/////////////////////
+
+/datum/dna/gene/disability
+ name="DISABILITY"
+
+ // Mutation to give (or 0)
+ var/mutation=0
+
+ // Disability to give (or 0)
+ var/disability=0
+
+ // SDisability to give (or 0)
+ var/sdisability=0
+
+ // Activation message
+ var/activation_message=""
+
+ // Yay, you're no longer growing 3 arms
+ var/deactivation_message=""
+
+/datum/dna/gene/disability/can_activate(var/mob/M,var/flags)
+ return 1 // Always set!
+
+/datum/dna/gene/disability/activate(var/mob/M, var/connected, var/flags)
+ if(mutation && !(mutation in M.mutations))
+ M.mutations.Add(mutation)
+ if(disability)
+ M.disabilities|=disability
+ if(mutation)
+ M.sdisabilities|=sdisability
+ if(activation_message)
+ M << "\red [activation_message]"
+ else
+ testing("[name] has no activation message.")
+
+/datum/dna/gene/disability/deactivate(var/mob/M, var/connected, var/flags)
+ if(mutation && (mutation in M.mutations))
+ M.mutations.Remove(mutation)
+ if(disability)
+ M.disabilities-=disability
+ if(mutation)
+ M.sdisabilities-=sdisability
+ if(deactivation_message)
+ M << "\red [deactivation_message]"
+ else
+ testing("[name] has no deactivation message.")
+
+// Note: Doesn't seem to do squat, at the moment.
+/datum/dna/gene/disability/hallucinate
+ name="Hallucinate"
+ activation_message="Your mind says 'Hello'."
+ mutation=mHallucination
+
+ New()
+ block=HALLUCINATIONBLOCK
+
+/datum/dna/gene/disability/epilepsy
+ name="Epilepsy"
+ activation_message="You get a headache."
+ disability=EPILEPSY
+
+ New()
+ block=HEADACHEBLOCK
+
+/datum/dna/gene/disability/cough
+ name="Coughing"
+ activation_message="You start coughing."
+ disability=COUGHING
+
+ New()
+ block=COUGHBLOCK
+
+/datum/dna/gene/disability/clumsy
+ name="Clumsiness"
+ activation_message="You feel lightheaded."
+ mutation=CLUMSY
+
+ New()
+ block=CLUMSYBLOCK
+
+/datum/dna/gene/disability/tourettes
+ name="Tourettes"
+ activation_message="You twitch."
+ disability=TOURETTES
+
+ New()
+ block=TWITCHBLOCK
+
+/datum/dna/gene/disability/nervousness
+ name="Nervousness"
+ activation_message="You feel nervous."
+ disability=NERVOUS
+
+ New()
+ block=NERVOUSBLOCK
+
+/datum/dna/gene/disability/blindness
+ name="Blindness"
+ activation_message="You can't seem to see anything."
+ sdisability=BLIND
+
+ New()
+ block=BLINDBLOCK
+
+/datum/dna/gene/disability/deaf
+ name="Deafness"
+ activation_message="It's kinda quiet."
+ sdisability=DEAF
+
+ New()
+ block=DEAFBLOCK
+
+ activate(var/mob/M, var/connected, var/flags)
+ ..(M,connected,flags)
+ M.ear_deaf = 1
+
+/datum/dna/gene/disability/nearsighted
+ name="Nearsightedness"
+ activation_message="Your eyes feel weird..."
+ disability=NEARSIGHTED
+
+ New()
+ block=GLASSESBLOCK
diff --git a/code/game/dna/genes/gene.dm b/code/game/dna/genes/gene.dm
new file mode 100644
index 0000000000..21eec348bd
--- /dev/null
+++ b/code/game/dna/genes/gene.dm
@@ -0,0 +1,122 @@
+/**
+* Gene Datum
+*
+* domutcheck was getting pretty hairy. This is the solution.
+*
+* All genes are stored in a global variable to cut down on memory
+* usage.
+*
+* @author N3X15
+*/
+
+/datum/dna/gene
+ // Display name
+ var/name="BASE GENE"
+
+ // Probably won't get used but why the fuck not
+ var/desc="Oh god who knows what this does."
+
+ // Set in initialize()!
+ // What gene activates this?
+ var/block=0
+
+ // Any of a number of GENE_ flags.
+ var/flags=0
+
+/**
+* Is the gene active in this mob's DNA?
+*/
+/datum/dna/gene/proc/is_active(var/mob/M)
+ return M.active_genes && type in M.active_genes
+
+// Return 1 if we can activate.
+// HANDLE MUTCHK_FORCED HERE!
+/datum/dna/gene/proc/can_activate(var/mob/M, var/flags)
+ return 0
+
+// Called when the gene activates. Do your magic here.
+/datum/dna/gene/proc/activate(var/mob/M, var/connected, var/flags)
+ return
+
+/**
+* Called when the gene deactivates. Undo your magic here.
+* Only called when the block is deactivated.
+*/
+/datum/dna/gene/proc/deactivate(var/mob/M, var/connected, var/flags)
+ return
+
+// This section inspired by goone's bioEffects.
+
+/**
+* Called in each life() tick.
+*/
+/datum/dna/gene/proc/OnMobLife(var/mob/M)
+ return
+
+/**
+* Called when the mob dies
+*/
+/datum/dna/gene/proc/OnMobDeath(var/mob/M)
+ return
+
+/**
+* Called when the mob says shit
+*/
+/datum/dna/gene/proc/OnSay(var/mob/M, var/message)
+ return message
+
+/**
+* Called after the mob runs update_icons.
+*
+* @params M The subject.
+* @params g Gender (m or f)
+* @params fat Fat? (0 or 1)
+*/
+/datum/dna/gene/proc/OnDrawUnderlays(var/mob/M, var/g, var/fat)
+ return 0
+
+
+/////////////////////
+// BASIC GENES
+//
+// These just chuck in a mutation and display a message.
+//
+// Gene is activated:
+// 1. If mutation already exists in mob
+// 2. If the probability roll succeeds
+// 3. Activation is forced (done in domutcheck)
+/////////////////////
+
+
+/datum/dna/gene/basic
+ name="BASIC GENE"
+
+ // Mutation to give
+ var/mutation=0
+
+ // Activation probability
+ var/activation_prob=45
+
+ // Possible activation messages
+ var/list/activation_messages=list()
+
+ // Possible deactivation messages
+ var/list/deactivation_messages=list()
+
+/datum/dna/gene/basic/can_activate(var/mob/M,var/flags)
+ if(flags & MUTCHK_FORCED)
+ return 1
+ // Probability check
+ return probinj(activation_prob,(flags&MUTCHK_FORCED))
+
+/datum/dna/gene/basic/activate(var/mob/M)
+ M.mutations.Add(mutation)
+ if(activation_messages.len)
+ var/msg = pick(activation_messages)
+ M << "\blue [msg]"
+
+/datum/dna/gene/basic/deactivate(var/mob/M)
+ M.mutations.Remove(mutation)
+ if(deactivation_messages.len)
+ var/msg = pick(deactivation_messages)
+ M << "\red [msg]"
\ No newline at end of file
diff --git a/code/game/dna/genes/monkey.dm b/code/game/dna/genes/monkey.dm
new file mode 100644
index 0000000000..444e56a587
--- /dev/null
+++ b/code/game/dna/genes/monkey.dm
@@ -0,0 +1,174 @@
+/datum/dna/gene/monkey
+ name="Monkey"
+
+/datum/dna/gene/monkey/New()
+ block=MONKEYBLOCK
+
+/datum/dna/gene/monkey/can_activate(var/mob/M,var/flags)
+ return istype(M, /mob/living/carbon/human) || istype(M,/mob/living/carbon/monkey)
+
+/datum/dna/gene/monkey/activate(var/mob/living/M, var/connected, var/flags)
+ if(!istype(M,/mob/living/carbon/human))
+ //testing("Cannot monkey-ify [M], type is [M.type].")
+ return
+ var/mob/living/carbon/human/H = M
+ H.monkeyizing = 1
+ var/list/implants = list() //Try to preserve implants.
+ for(var/obj/item/weapon/implant/W in H)
+ implants += W
+ W.loc = null
+
+ if(!connected)
+ for(var/obj/item/W in (H.contents-implants))
+ if (W==H.w_uniform) // will be teared
+ continue
+ H.drop_from_inventory(W)
+ M.monkeyizing = 1
+ M.canmove = 0
+ M.icon = null
+ M.invisibility = 101
+ var/atom/movable/overlay/animation = new( M.loc )
+ animation.icon_state = "blank"
+ animation.icon = 'icons/mob/mob.dmi'
+ animation.master = src
+ flick("h2monkey", animation)
+ sleep(48)
+ del(animation)
+
+
+ var/mob/living/carbon/monkey/O = null
+ if(H.species.primitive)
+ O = new H.species.primitive(src)
+ else
+ H.gib() //Trying to change the species of a creature with no primitive var set is messy.
+ return
+
+ if(M)
+ if (M.dna)
+ O.dna = M.dna.Clone()
+ M.dna = null
+
+ if (M.suiciding)
+ O.suiciding = M.suiciding
+ M.suiciding = null
+
+
+ for(var/datum/disease/D in M.viruses)
+ O.viruses += D
+ D.affected_mob = O
+ M.viruses -= D
+
+
+ for(var/obj/T in (M.contents-implants))
+ del(T)
+
+ O.loc = M.loc
+
+ if(M.mind)
+ M.mind.transfer_to(O) //transfer our mind to the cute little monkey
+
+ if (connected) //inside dna thing
+ var/obj/machinery/dna_scannernew/C = connected
+ O.loc = C
+ C.occupant = O
+ connected = null
+ O.real_name = text("monkey ([])",copytext(md5(M.real_name), 2, 6))
+ O.take_overall_damage(M.getBruteLoss() + 40, M.getFireLoss())
+ O.adjustToxLoss(M.getToxLoss() + 20)
+ O.adjustOxyLoss(M.getOxyLoss())
+ O.stat = M.stat
+ O.a_intent = "hurt"
+ for (var/obj/item/weapon/implant/I in implants)
+ I.loc = O
+ I.implanted = O
+// O.update_icon = 1 //queue a full icon update at next life() call
+ del(M)
+ return
+
+/datum/dna/gene/monkey/deactivate(var/mob/living/M, var/connected, var/flags)
+ if(!istype(M,/mob/living/carbon/monkey))
+ //testing("Cannot humanize [M], type is [M.type].")
+ return
+ var/mob/living/carbon/monkey/Mo = M
+ Mo.monkeyizing = 1
+ var/list/implants = list() //Still preserving implants
+ for(var/obj/item/weapon/implant/W in Mo)
+ implants += W
+ W.loc = null
+ if(!connected)
+ for(var/obj/item/W in (Mo.contents-implants))
+ Mo.drop_from_inventory(W)
+ M.monkeyizing = 1
+ M.canmove = 0
+ M.icon = null
+ M.invisibility = 101
+ var/atom/movable/overlay/animation = new( M.loc )
+ animation.icon_state = "blank"
+ animation.icon = 'icons/mob/mob.dmi'
+ animation.master = src
+ flick("monkey2h", animation)
+ sleep(48)
+ del(animation)
+
+ var/mob/living/carbon/human/O
+ if(Mo.greaterform)
+ O = new(src, Mo.greaterform)
+ else
+ O = new(src)
+
+ if (M.dna.GetUIState(DNA_UI_GENDER))
+ O.gender = FEMALE
+ else
+ O.gender = MALE
+
+ if (M)
+ if (M.dna)
+ O.dna = M.dna.Clone()
+ M.dna = null
+
+ if (M.suiciding)
+ O.suiciding = M.suiciding
+ M.suiciding = null
+
+ for(var/datum/disease/D in M.viruses)
+ O.viruses += D
+ D.affected_mob = O
+ M.viruses -= D
+
+ //for(var/obj/T in M)
+ // del(T)
+
+ O.loc = M.loc
+
+ if(M.mind)
+ M.mind.transfer_to(O) //transfer our mind to the human
+
+ if (connected) //inside dna thing
+ var/obj/machinery/dna_scannernew/C = connected
+ O.loc = C
+ C.occupant = O
+ connected = null
+
+ var/i
+ while (!i)
+ var/randomname
+ if (O.gender == MALE)
+ randomname = capitalize(pick(first_names_male) + " " + capitalize(pick(last_names)))
+ else
+ randomname = capitalize(pick(first_names_female) + " " + capitalize(pick(last_names)))
+ if (findname(randomname))
+ continue
+ else
+ O.real_name = randomname
+ i++
+ O.UpdateAppearance()
+ O.take_overall_damage(M.getBruteLoss(), M.getFireLoss())
+ O.adjustToxLoss(M.getToxLoss())
+ O.adjustOxyLoss(M.getOxyLoss())
+ O.stat = M.stat
+ for (var/obj/item/weapon/implant/I in implants)
+ I.loc = O
+ I.implanted = O
+// O.update_icon = 1 //queue a full icon update at next life() call
+ del(M)
+ return
\ No newline at end of file
diff --git a/code/game/dna/genes/powers.dm b/code/game/dna/genes/powers.dm
new file mode 100644
index 0000000000..3381894f8a
--- /dev/null
+++ b/code/game/dna/genes/powers.dm
@@ -0,0 +1,195 @@
+///////////////////////////////////
+// POWERS
+///////////////////////////////////
+
+/datum/dna/gene/basic/nobreath
+ name="No Breathing"
+ activation_messages=list("You feel no need to breathe.")
+ mutation=mNobreath
+
+ New()
+ block=NOBREATHBLOCK
+
+/datum/dna/gene/basic/remoteview
+ name="Remote Viewing"
+ activation_messages=list("Your mind expands.")
+ mutation=mRemote
+
+ New()
+ block=REMOTEVIEWBLOCK
+
+ activate(var/mob/M, var/connected, var/flags)
+ ..(M,connected,flags)
+ M.verbs += /mob/living/carbon/human/proc/remoteobserve
+
+/datum/dna/gene/basic/regenerate
+ name="Regenerate"
+ activation_messages=list("You feel better.")
+ mutation=mRegen
+
+ New()
+ block=REGENERATEBLOCK
+
+/datum/dna/gene/basic/increaserun
+ name="Super Speed"
+ activation_messages=list("Your leg muscles pulsate.")
+ mutation=mRun
+
+ New()
+ block=INCREASERUNBLOCK
+
+/datum/dna/gene/basic/remotetalk
+ name="Telepathy"
+ activation_messages=list("You expand your mind outwards.")
+ mutation=mRemotetalk
+
+ New()
+ block=REMOTETALKBLOCK
+
+ activate(var/mob/M, var/connected, var/flags)
+ ..(M,connected,flags)
+ M.verbs += /mob/living/carbon/human/proc/remotesay
+
+/datum/dna/gene/basic/morph
+ name="Morph"
+ activation_messages=list("Your skin feels strange.")
+ mutation=mMorph
+
+ New()
+ block=MORPHBLOCK
+
+ activate(var/mob/M)
+ ..(M)
+ M.verbs += /mob/living/carbon/human/proc/morph
+
+/* Not used on bay
+/datum/dna/gene/basic/heat_resist
+ name="Heat Resistance"
+ activation_messages=list("Your skin is icy to the touch.")
+ mutation=mHeatres
+
+ New()
+ block=COLDBLOCK
+
+ can_activate(var/mob/M,var/flags)
+ if(flags & MUTCHK_FORCED)
+ return !(/datum/dna/gene/basic/cold_resist in M.active_genes)
+ // Probability check
+ var/_prob = 15
+ if(COLD_RESISTANCE in M.mutations)
+ _prob=5
+ if(probinj(_prob,(flags&MUTCHK_FORCED)))
+ return 1
+
+ OnDrawUnderlays(var/mob/M,var/g,var/fat)
+ return "cold[fat]_s"
+*/
+
+/datum/dna/gene/basic/cold_resist
+ name="Cold Resistance"
+ activation_messages=list("Your body is filled with warmth.")
+ mutation=COLD_RESISTANCE
+
+ New()
+ block=FIREBLOCK
+
+ can_activate(var/mob/M,var/flags)
+ if(flags & MUTCHK_FORCED)
+ return 1
+ // return !(/datum/dna/gene/basic/heat_resist in M.active_genes)
+ // Probability check
+ var/_prob=30
+ //if(mHeatres in M.mutations)
+ // _prob=5
+ if(probinj(_prob,(flags&MUTCHK_FORCED)))
+ return 1
+
+ OnDrawUnderlays(var/mob/M,var/g,var/fat)
+ return "fire[fat]_s"
+
+/datum/dna/gene/basic/noprints
+ name="No Prints"
+ activation_messages=list("Your fingers feel numb.")
+ mutation=mFingerprints
+
+ New()
+ block=NOPRINTSBLOCK
+
+/datum/dna/gene/basic/noshock
+ name="Shock Immunity"
+ activation_messages=list("Your skin feels strange.")
+ mutation=mShock
+
+ New()
+ block=SHOCKIMMUNITYBLOCK
+
+/datum/dna/gene/basic/midget
+ name="Midget"
+ activation_messages=list("Your skin feels rubbery.")
+ mutation=mSmallsize
+
+ New()
+ block=SMALLSIZEBLOCK
+
+ can_activate(var/mob/M,var/flags)
+ // Can't be big and small.
+ if(HULK in M.mutations)
+ return 0
+ return ..(M,flags)
+
+ activate(var/mob/M, var/connected, var/flags)
+ ..(M,connected,flags)
+ M.pass_flags |= 1
+
+ deactivate(var/mob/M, var/connected, var/flags)
+ ..(M,connected,flags)
+ M.pass_flags &= ~1 //This may cause issues down the track, but offhand I can't think of any other way for humans to get passtable short of varediting so it should be fine. ~Z
+
+/datum/dna/gene/basic/hulk
+ name="Hulk"
+ activation_messages=list("Your muscles hurt.")
+ mutation=HULK
+
+ New()
+ block=HULKBLOCK
+
+ can_activate(var/mob/M,var/flags)
+ // Can't be big and small.
+ if(mSmallsize in M.mutations)
+ return 0
+ return ..(M,flags)
+
+ OnDrawUnderlays(var/mob/M,var/g,var/fat)
+ if(fat)
+ return "hulk_[fat]_s"
+ else
+ return "hulk_[g]_s"
+ return 0
+
+ OnMobLife(var/mob/living/carbon/human/M)
+ if(!istype(M)) return
+ if(M.health <= 25)
+ M.mutations.Remove(HULK)
+ M.update_mutations() //update our mutation overlays
+ M << "\red You suddenly feel very weak."
+ M.Weaken(3)
+ M.emote("collapse")
+
+/datum/dna/gene/basic/xray
+ name="X-Ray Vision"
+ activation_messages=list("The walls suddenly disappear.")
+ mutation=XRAY
+
+ New()
+ block=XRAYBLOCK
+
+/datum/dna/gene/basic/tk
+ name="Telekenesis"
+ activation_messages=list("You feel smarter.")
+ mutation=TK
+ activation_prob=15
+
+ New()
+ block=TELEBLOCK
+ OnDrawUnderlays(var/mob/M,var/g,var/fat)
+ return "telekinesishead[fat]_s"
diff --git a/code/game/gamemodes/autotraitor/autotraitor.dm b/code/game/gamemodes/autotraitor/autotraitor.dm
index a6da766b4e..43dea8c32f 100644
--- a/code/game/gamemodes/autotraitor/autotraitor.dm
+++ b/code/game/gamemodes/autotraitor/autotraitor.dm
@@ -123,7 +123,8 @@
var/mob/living/newtraitor = pick(possible_traitors)
//message_admins("[newtraitor.real_name] is the new Traitor.")
- forge_traitor_objectives(newtraitor.mind)
+ if (!config.objectives_disabled)
+ forge_traitor_objectives(newtraitor.mind)
if(istype(newtraitor, /mob/living/silicon))
add_law_zero(newtraitor)
@@ -134,11 +135,15 @@
newtraitor << "\red ATTENTION: \black It is time to pay your debt to the Syndicate..."
newtraitor << "You are now a traitor."
newtraitor.mind.special_role = "traitor"
+ newtraitor.hud_updateflag |= 1 << SPECIALROLE_HUD
var/obj_count = 1
newtraitor << "\blue Your current objectives:"
- for(var/datum/objective/objective in newtraitor.mind.objectives)
- newtraitor << "Objective #[obj_count]: [objective.explanation_text]"
- obj_count++
+ if(!config.objectives_disabled)
+ for(var/datum/objective/objective in newtraitor.mind.objectives)
+ newtraitor << "Objective #[obj_count]: [objective.explanation_text]"
+ obj_count++
+ else
+ newtraitor << "You have been selected this round as an antagonist- Within the rules, try to act as an opposing force to the crew- This can be via corporate payoff, personal motives, or maybe just being a dick. Further RP and try to make sure other players have fun! If you are confused or at a loss, always adminhelp, and before taking extreme actions, please try to also contact the administration! Think through your actions and make the roleplay immersive! Please remember all rules aside from those without explicit exceptions apply to antagonist."
//else
//message_admins("No new traitor being added.")
//else
@@ -188,11 +193,14 @@
traitors += character.mind
character << "\red You are the traitor."
character.mind.special_role = "traitor"
- var/obj_count = 1
- character << "\blue Your current objectives:"
- for(var/datum/objective/objective in character.mind.objectives)
- character << "Objective #[obj_count]: [objective.explanation_text]"
- obj_count++
+ if (config.objectives_disabled)
+ character << "You have been selected this round as an antagonist- Within the rules, try to act as an opposing force to the crew- This can be via corporate payoff, personal motives, or maybe just being a dick. Further RP and try to make sure other players have fun! If you are confused or at a loss, always adminhelp, and before taking extreme actions, please try to also contact the administration! Think through your actions and make the roleplay immersive! Please remember all rules aside from those without explicit exceptions apply to antagonist."
+ else
+ var/obj_count = 1
+ character << "\blue Your current objectives:"
+ for(var/datum/objective/objective in character.mind.objectives)
+ character << "Objective #[obj_count]: [objective.explanation_text]"
+ obj_count++
//else
//message_admins("New traitor roll failed. No new traitor.")
//else
diff --git a/code/game/gamemodes/blob/blobs/shield.dm b/code/game/gamemodes/blob/blobs/shield.dm
index 4c77520846..0e1b6c07eb 100644
--- a/code/game/gamemodes/blob/blobs/shield.dm
+++ b/code/game/gamemodes/blob/blobs/shield.dm
@@ -6,7 +6,7 @@
density = 1
opacity = 0
anchored = 1
- health = 100
+ health = 60
brute_resist = 1
fire_resist = 2
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index 6a3bbd19c8..8a3b7d075e 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -72,7 +72,8 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
for(var/datum/mind/changeling in changelings)
grant_changeling_powers(changeling.current)
changeling.special_role = "Changeling"
- forge_changeling_objectives(changeling)
+ if(!config.objectives_disabled)
+ forge_changeling_objectives(changeling)
greet_changeling(changeling)
spawn (rand(waittime_l, waittime_h))
@@ -120,18 +121,24 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
if (you_are)
changeling.current << "\red You are a changeling!"
changeling.current << "\red Use say \":g message\" to communicate with your fellow changelings. Remember: you get all of their absorbed DNA if you absorb them."
- changeling.current << "You must complete the following tasks:"
+
+ if(config.objectives_disabled)
+ changeling.current << "Within the rules, try to act as an opposing force to the crew. Further RP and try to make sure other players have fun! If you are confused or at a loss, always adminhelp, and before taking extreme actions, please try to also contact the administration! Think through your actions and make the roleplay immersive! Please remember all rules aside from those without explicit exceptions apply to antagonists."
+
+ if (!config.objectives_disabled)
+ changeling.current << "You must complete the following tasks:"
if (changeling.current.mind)
if (changeling.current.mind.assigned_role == "Clown")
changeling.current << "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself."
changeling.current.mutations.Remove(CLUMSY)
- var/obj_count = 1
- for(var/datum/objective/objective in changeling.objectives)
- changeling.current << "Objective #[obj_count]: [objective.explanation_text]"
- obj_count++
- return
+ if (!config.objectives_disabled)
+ var/obj_count = 1
+ for(var/datum/objective/objective in changeling.objectives)
+ changeling.current << "Objective #[obj_count]: [objective.explanation_text]"
+ obj_count++
+ return
/*/datum/game_mode/changeling/check_finished()
var/changelings_alive = 0
@@ -181,25 +188,25 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
//Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed.
text += " Changeling ID: [changeling.changeling.changelingID]."
text += " Genomes Absorbed: [changeling.changeling.absorbedcount]"
-
- if(changeling.objectives.len)
- var/count = 1
- for(var/datum/objective/objective in changeling.objectives)
- if(objective.check_completion())
- text += " Objective #[count]: [objective.explanation_text] Success!"
- feedback_add_details("changeling_objective","[objective.type]|SUCCESS")
+ if(!config.objectives_disabled)
+ if(changeling.objectives.len)
+ var/count = 1
+ for(var/datum/objective/objective in changeling.objectives)
+ if(objective.check_completion())
+ text += " Objective #[count]: [objective.explanation_text] Success!"
+ feedback_add_details("changeling_objective","[objective.type]|SUCCESS")
+ else
+ text += " Objective #[count]: [objective.explanation_text] Fail."
+ feedback_add_details("changeling_objective","[objective.type]|FAIL")
+ changelingwin = 0
+ count++
+ if(!config.objectives_disabled)
+ if(changelingwin)
+ text += " The changeling was successful!"
+ feedback_add_details("changeling_success","SUCCESS")
else
- text += " Objective #[count]: [objective.explanation_text] Fail."
- feedback_add_details("changeling_objective","[objective.type]|FAIL")
- changelingwin = 0
- count++
-
- if(changelingwin)
- text += " The changeling was successful!"
- feedback_add_details("changeling_success","SUCCESS")
- else
- text += " The changeling has failed."
- feedback_add_details("changeling_success","FAIL")
+ text += " The changeling has failed."
+ feedback_add_details("changeling_success","FAIL")
world << text
@@ -208,6 +215,8 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
/datum/changeling //stores changeling powers, changeling recharge thingie, changeling absorbed DNA and changeling ID (for changeling hivemind)
var/list/absorbed_dna = list()
+ var/list/absorbed_species = list()
+ var/list/absorbed_languages = list()
var/absorbedcount = 0
var/chem_charges = 20
var/chem_recharge_rate = 0.5
diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm
index 96deb59554..53b2c36ea8 100644
--- a/code/game/gamemodes/changeling/changeling_powers.dm
+++ b/code/game/gamemodes/changeling/changeling_powers.dm
@@ -1,5 +1,6 @@
//Restores our verbs. It will only restore verbs allowed during lesser (monkey) form if we are not human
/mob/proc/make_changeling()
+
if(!mind) return
if(!mind.changeling) mind.changeling = new /datum/changeling(gender)
verbs += /datum/changeling/proc/EvolutionMenu
@@ -23,6 +24,15 @@
src.verbs += P.verbpath
mind.changeling.absorbed_dna |= dna
+
+ var/mob/living/carbon/human/H = src
+ if(istype(H))
+ mind.changeling.absorbed_species += H.species.name
+
+ for(var/language in languages)
+ if(!(language in mind.changeling.absorbed_languages))
+ mind.changeling.absorbed_languages += language
+
return 1
//removes our changeling verbs
@@ -57,12 +67,60 @@
return
if(changeling.geneticdamage > max_genetic_damage)
- src << "Our geneomes are still reassembling. We need time to recover first."
+ src << "Our genomes are still reassembling. We need time to recover first."
return
return changeling
+//Used to dump the languages from the changeling datum into the actual mob.
+/mob/proc/changeling_update_languages(var/updated_languages)
+
+ languages = list()
+ for(var/language in updated_languages)
+ languages += language
+
+ return
+
+//Used to switch species based on the changeling datum.
+/mob/proc/changeling_change_species()
+
+ set category = "Changeling"
+ set name = "Change Species (5)"
+
+ var/mob/living/carbon/human/H = src
+ if(!istype(H))
+ src << "We may only use this power while in humanoid form."
+ return
+
+ var/datum/changeling/changeling = changeling_power(5,1,0)
+ if(!changeling) return
+
+ if(changeling.absorbed_species.len < 2)
+ src << "We do not know of any other species genomes to use."
+ return
+
+ var/S = input("Select the target species: ", "Target Species", null) as null|anything in changeling.absorbed_species
+ if(!S) return
+
+ domutcheck(src, null)
+
+ changeling.chem_charges -= 5
+ changeling.geneticdamage = 30
+
+ src.visible_message("[src] transforms!")
+
+ src.verbs -= /mob/proc/changeling_change_species
+ spawn(10) src.verbs += /mob/proc/changeling_change_species
+
+ H.set_species(S)
+
+ changeling_update_languages(changeling.absorbed_languages)
+
+ feedback_add_details("changeling_powers","TR")
+
+ return 1
+
//Absorbs the victim's DNA making them uncloneable. Requires a strong grip on the victim.
//Doesn't cost anything as it's the most basic ability.
/mob/proc/changeling_absorb_dna()
@@ -82,6 +140,10 @@
src << "[T] is not compatible with our biology."
return
+ if(T.species.flags & NO_SCAN)
+ src << "We do not know how to parse this creature's DNA!"
+ return
+
if(NOCLONE in T.mutations)
src << "This creature's DNA is ruined beyond useability!"
return
@@ -127,6 +189,17 @@
changeling.chem_charges += 10
changeling.geneticpoints += 2
+ //Steal all of their languages!
+ for(var/language in T.languages)
+ if(!(language in changeling.absorbed_languages))
+ changeling.absorbed_languages += language
+
+ changeling_update_languages(changeling.absorbed_languages)
+
+ //Steal their species!
+ if(T.species && !(T.species.name in changeling.absorbed_species))
+ changeling.absorbed_species += T.species.name
+
if(T.mind && T.mind.changeling)
if(T.mind.changeling.absorbed_dna)
for(var/dna_data in T.mind.changeling.absorbed_dna) //steal all their loot
@@ -184,7 +257,7 @@
changeling.chem_charges -= 5
src.visible_message("[src] transforms!")
changeling.geneticdamage = 30
- src.dna = chosen_dna
+ src.dna = chosen_dna.Clone()
src.real_name = chosen_dna.real_name
src.flavor_text = ""
src.UpdateAppearance()
@@ -205,6 +278,10 @@
var/datum/changeling/changeling = changeling_power(1,0,0)
if(!changeling) return
+ if(src.has_brain_worms())
+ src << "We cannot perform this ability at the present time!"
+ return
+
var/mob/living/carbon/C = src
changeling.chem_charges--
C.remove_changeling_powers()
@@ -232,7 +309,7 @@
del(animation)
var/mob/living/carbon/monkey/O = new /mob/living/carbon/monkey(src)
- O.dna = C.dna
+ O.dna = C.dna.Clone()
C.dna = null
for(var/obj/item/W in C)
@@ -256,6 +333,8 @@
O.make_changeling(1)
O.verbs += /mob/proc/changeling_lesser_transform
+ O.changeling_update_languages(changeling.absorbed_languages)
+
feedback_add_details("changeling_powers","LF")
del(C)
return 1
@@ -285,7 +364,7 @@
changeling.chem_charges--
C.remove_changeling_powers()
C.visible_message("[C] transforms!")
- C.dna = chosen_dna
+ C.dna = chosen_dna.Clone()
var/list/implants = list()
for (var/obj/item/weapon/implant/I in C) //Still preserving implants
@@ -318,7 +397,7 @@
O.gender = FEMALE
else
O.gender = MALE
- O.dna = C.dna
+ O.dna = C.dna.Clone()
C.dna = null
O.real_name = chosen_dna.real_name
@@ -340,6 +419,7 @@
C.mind.transfer_to(O)
O.make_changeling()
+ O.changeling_update_languages(changeling.absorbed_languages)
feedback_add_details("changeling_powers","LFT")
del(C)
@@ -370,24 +450,24 @@
if(changeling_power(20,1,100,DEAD))
// charge the changeling chemical cost for stasis
changeling.chem_charges -= 20
-
+
// restore us to health
C.rejuvenate()
-
+
// remove our fake death flag
C.status_flags &= ~(FAKEDEATH)
-
+
// let us move again
C.update_canmove()
-
+
// re-add out changeling powers
- C.make_changeling()
-
+ C.make_changeling()
+
// sending display messages
C << "We have regenerated."
C.visible_message("[src] appears to wake from the dead, having healed all wounds.")
-
-
+
+
feedback_add_details("changeling_powers","FD")
return 1
@@ -717,7 +797,7 @@ var/list/datum/dna/hivemind_bank = list()
src << "Our sting appears ineffective against its DNA."
return 0
T.visible_message("[T] transforms!")
- T.dna = chosen_dna
+ T.dna = chosen_dna.Clone()
T.real_name = chosen_dna.real_name
T.UpdateAppearance()
domutcheck(T, null)
diff --git a/code/game/gamemodes/changeling/modularchangling.dm b/code/game/gamemodes/changeling/modularchangling.dm
index 2395e63b27..5048977789 100644
--- a/code/game/gamemodes/changeling/modularchangling.dm
+++ b/code/game/gamemodes/changeling/modularchangling.dm
@@ -26,6 +26,12 @@ var/list/datum/power/changeling/powerinstances = list()
genomecost = 0
verbpath = /mob/proc/changeling_transform
+/datum/power/changeling/change_species
+ name = "Change Species"
+ desc = "We take on the apperance of a species that we have absorbed."
+ genomecost = 0
+ verbpath = /mob/proc/changeling_change_species
+
/datum/power/changeling/fakedeath
name = "Regenerative Stasis"
desc = "We become weakened to a death-like state, where we will rise again from death."
@@ -53,7 +59,7 @@ var/list/datum/power/changeling/powerinstances = list()
/datum/power/changeling/lesser_form
name = "Lesser Form"
desc = "We debase ourselves and become lesser. We become a monkey."
- genomecost = 1
+ genomecost = 4
verbpath = /mob/proc/changeling_lesser_form
/datum/power/changeling/deaf_sting
@@ -74,7 +80,7 @@ var/list/datum/power/changeling/powerinstances = list()
name = "Silence Sting"
desc = "We silently sting a human, completely silencing them for a short time."
helptext = "Does not provide a warning to a victim that they have been stung, until they try to speak and cannot."
- genomecost = 2
+ genomecost = 3
allowduringlesserform = 1
verbpath = /mob/proc/changeling_silence_sting
@@ -82,14 +88,14 @@ var/list/datum/power/changeling/powerinstances = list()
name = "Mimic Voice"
desc = "We shape our vocal glands to sound like a desired voice."
helptext = "Will turn your voice into the name that you enter. We must constantly expend chemicals to maintain our form like this"
- genomecost = 3
+ genomecost = 1
verbpath = /mob/proc/changeling_mimicvoice
/datum/power/changeling/extractdna
name = "Extract DNA"
desc = "We stealthily sting a target and extract the DNA from them."
helptext = "Will give you the DNA of your target, allowing you to transform into them. Does not count towards absorb objectives."
- genomecost = 4
+ genomecost = 2
allowduringlesserform = 1
verbpath = /mob/proc/changeling_extract_dna_sting
@@ -103,7 +109,7 @@ var/list/datum/power/changeling/powerinstances = list()
/datum/power/changeling/paralysis_sting
name = "Paralysis Sting"
desc = "We silently sting a human, paralyzing them for a short time."
- genomecost = 3
+ genomecost = 8
verbpath = /mob/proc/changeling_paralysis_sting
/datum/power/changeling/LSDSting
@@ -119,11 +125,11 @@ var/list/datum/power/changeling/powerinstances = list()
genomecost = 10
verbpath = /mob/proc/changeling_DEATHsting
-/datum/power/changeling/unfat_sting
- name = "Unfat Sting"
- desc = "We silently sting a human, forcing them to rapidly metobolize their fat."
- genomecost = 1
- verbpath = /mob/proc/changeling_unfat_sting
+///datum/power/changeling/unfat_sting
+// name = "Unfat Sting"
+// desc = "We silently sting a human, forcing them to rapidly metabolize their fat."
+// genomecost = 1
+// verbpath = /mob/proc/changeling_unfat_sting
/datum/power/changeling/boost_range
name = "Boost Range"
@@ -136,7 +142,7 @@ var/list/datum/power/changeling/powerinstances = list()
name = "Epinephrine sacs"
desc = "We evolve additional sacs of adrenaline throughout our body."
helptext = "Gives the ability to instantly recover from stuns. High chemical cost."
- genomecost = 4
+ genomecost = 3
verbpath = /mob/proc/changeling_unstun
/datum/power/changeling/ChemicalSynth
@@ -167,7 +173,7 @@ var/list/datum/power/changeling/powerinstances = list()
name = "Digital Camoflauge"
desc = "We evolve the ability to distort our form and proprtions, defeating common altgorthms used to detect lifeforms on cameras."
helptext = "We cannot be tracked by camera while using this skill. However, humans looking at us will find us.. uncanny. We must constantly expend chemicals to maintain our form like this."
- genomecost = 3
+ genomecost = 1
allowduringlesserform = 1
verbpath = /mob/proc/changeling_digitalcamo
@@ -175,7 +181,7 @@ var/list/datum/power/changeling/powerinstances = list()
name = "Rapid Regeneration"
desc = "We evolve the ability to rapidly regenerate, negating the need for stasis."
helptext = "Heals a moderate amount of damage every tick."
- genomecost = 8
+ genomecost = 7
verbpath = /mob/proc/changeling_rapidregen
diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm
index 12a5525428..2dbec4fa60 100644
--- a/code/game/gamemodes/changeling/traitor_chan.dm
+++ b/code/game/gamemodes/changeling/traitor_chan.dm
@@ -37,7 +37,8 @@
for(var/datum/mind/changeling in changelings)
grant_changeling_powers(changeling.current)
changeling.special_role = "Changeling"
- forge_changeling_objectives(changeling)
+ if(!config.objectives_disabled)
+ forge_changeling_objectives(changeling)
greet_changeling(changeling)
..()
return
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index e0e81a647e..b1e3442d34 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -54,12 +54,13 @@
/datum/game_mode/cult/pre_setup()
- if(prob(50))
- objectives += "survive"
- objectives += "sacrifice"
- else
- objectives += "eldergod"
- objectives += "sacrifice"
+ if(!config.objectives_disabled)
+ if(prob(50))
+ objectives += "survive"
+ objectives += "sacrifice"
+ else
+ objectives += "eldergod"
+ objectives += "sacrifice"
if(config.protect_roles_from_antagonist)
restricted_jobs += protected_jobs
@@ -98,7 +99,10 @@
grant_runeword(cult_mind.current)
update_cult_icons_added(cult_mind)
cult_mind.current << "\blue You are a member of the cult!"
- memoize_cult_objectives(cult_mind)
+ if(!config.objectives_disabled)
+ memoize_cult_objectives(cult_mind)
+ else
+ cult_mind.current << "Within the rules, try to act as an opposing force to the crew. Further RP and try to make sure other players have fun! If you are confused or at a loss, always adminhelp, and before taking extreme actions, please try to also contact the administration! Think through your actions and make the roleplay immersive! Please remember all rules aside from those without explicit exceptions apply to antagonists."
cult_mind.special_role = "Cultist"
spawn (rand(waittime_l, waittime_h))
@@ -192,7 +196,8 @@
/datum/game_mode/cult/add_cultist(datum/mind/cult_mind) //INHERIT
if (!..(cult_mind))
return
- memoize_cult_objectives(cult_mind)
+ if (!config.objectives_disabled)
+ memoize_cult_objectives(cult_mind)
/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = 1)
@@ -367,7 +372,8 @@
/datum/game_mode/cult/declare_completion()
-
+ if(config.objectives_disabled)
+ return 1
if(!check_cult_victory())
feedback_set_details("round_end_result","win - cult win")
feedback_set("round_end_result",acolytes_survived)
@@ -378,38 +384,38 @@
world << "\red The staff managed to stop the cult!"
var/text = "Cultists escaped: [acolytes_survived]"
-
- if(objectives.len)
- text += " The cultists' objectives were:"
- for(var/obj_count=1, obj_count <= objectives.len, obj_count++)
- var/explanation
- switch(objectives[obj_count])
- if("survive")
- if(!check_survive())
- explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. Success!"
- feedback_add_details("cult_objective","cult_survive|SUCCESS|[acolytes_needed]")
- else
- explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. Fail."
- feedback_add_details("cult_objective","cult_survive|FAIL|[acolytes_needed]")
- if("sacrifice")
- if(sacrifice_target)
- if(sacrifice_target in sacrificed)
- explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Success!"
- feedback_add_details("cult_objective","cult_sacrifice|SUCCESS")
- else if(sacrifice_target && sacrifice_target.current)
- explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail."
- feedback_add_details("cult_objective","cult_sacrifice|FAIL")
+ if(!config.objectives_disabled)
+ if(objectives.len)
+ text += " The cultists' objectives were:"
+ for(var/obj_count=1, obj_count <= objectives.len, obj_count++)
+ var/explanation
+ switch(objectives[obj_count])
+ if("survive")
+ if(!check_survive())
+ explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. Success!"
+ feedback_add_details("cult_objective","cult_survive|SUCCESS|[acolytes_needed]")
+ else
+ explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. Fail."
+ feedback_add_details("cult_objective","cult_survive|FAIL|[acolytes_needed]")
+ if("sacrifice")
+ if(sacrifice_target)
+ if(sacrifice_target in sacrificed)
+ explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Success!"
+ feedback_add_details("cult_objective","cult_sacrifice|SUCCESS")
+ else if(sacrifice_target && sacrifice_target.current)
+ explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail."
+ feedback_add_details("cult_objective","cult_sacrifice|FAIL")
else
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail (Gibbed)."
feedback_add_details("cult_objective","cult_sacrifice|FAIL|GIBBED")
- if("eldergod")
- if(!eldergod)
- explanation = "Summon Nar-Sie. Success!"
- feedback_add_details("cult_objective","cult_narsie|SUCCESS")
- else
- explanation = "Summon Nar-Sie. Fail."
+ if("eldergod")
+ if(!eldergod)
+ explanation = "Summon Nar-Sie. Success!"
+ feedback_add_details("cult_objective","cult_narsie|SUCCESS")
+ else
+ explanation = "Summon Nar-Sie. Fail."
feedback_add_details("cult_objective","cult_narsie|FAIL")
- text += " Objective #[obj_count]: [explanation]"
+ text += " Objective #[obj_count]: [explanation]"
world << text
..()
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index 014371cabf..4e38f4fe44 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -37,7 +37,7 @@
flags = FPRINT|TABLEPASS|HEADCOVERSEYES
armor = list(melee = 30, bullet = 10, laser = 5,energy = 5, bomb = 0, bio = 0, rad = 0)
cold_protection = HEAD
- min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECITON_TEMPERATURE
+ min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index 2760a66d49..33a7b905d8 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -242,7 +242,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology",
Drain Blood
This rune instantly heals you of some brute damage at the expense of a person placed on top of the rune. Whenever you invoke a drain rune, ALL drain runes on the station are activated, draining blood from anyone located on top of those runes. This includes yourself, though the blood you drain from yourself just comes back to you. This might help you identify this rune when studying words. One drain gives up to 25HP per each victim, but you can repeat it if you need more. Draining only works on living people, so you might need to recharge your "Battery" once its empty. Drinking too much blood at once might cause blood hunger.
Raise Dead
- This rune allows for the resurrection of any dead person. You will need a dead human body and a living human sacrifice. Make 2 raise dead runes. Put a living non-braindead human on top of one, and a dead body on the other one. When you invoke the rune, the life force of the living human will be transferred into the dead body, allowing a ghost standing on top of the dead body to enter it, instantly and fully healing it. Use other runes to ensure there is a ghost ready to be resurrected.
+ This rune allows for the resurrection of any dead person. You will need a dead human body and a living human sacrifice. Make 2 raise dead runes. Put a living, awake human on top of one, and a dead body on the other one. When you invoke the rune, the life force of the living human will be transferred into the dead body, allowing a ghost standing on top of the dead body to enter it, instantly and fully healing it. Use other runes to ensure there is a ghost ready to be resurrected.
Hide runes
This rune makes all nearby runes completely invisible. They are still there and will work if activated somehow, but you cannot invoke them directly if you do not see them.
Reveal runes
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index e7f1e2ff26..d78c3333ea 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -392,6 +392,11 @@ var/list/sacrificed = list()
D.real_name = "[pick(first_names_male)] [pick(last_names)]"
D.universal_speak = 1
D.status_flags &= ~GODMODE
+ D.s_tone = 35
+ D.b_eyes = 200
+ D.r_eyes = 200
+ D.g_eyes = 200
+ D.underwear = 0
D.key = ghost.key
@@ -839,7 +844,7 @@ var/list/sacrificed = list()
if (cultist == user) //just to be sure.
return
if(cultist.buckled || cultist.handcuffed || (!isturf(cultist.loc) && !istype(cultist.loc, /obj/structure/closet)))
- user << "\red You cannot summon the [cultist], for his shackles of blood are strong"
+ user << "\red You cannot summon \the [cultist], for his shackles of blood are strong."
return fizzle()
cultist.loc = src.loc
cultist.lying = 1
diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm
index 5b1b1494b5..51bcc39a37 100644
--- a/code/game/gamemodes/events.dm
+++ b/code/game/gamemodes/events.dm
@@ -163,8 +163,8 @@
continue
var/datum/disease/dnaspread/D = new
D.strain_data["name"] = H.real_name
- D.strain_data["UI"] = H.dna.UI
- D.strain_data["SE"] = H.dna.SE
+ D.strain_data["UI"] = H.dna.uni_identity
+ D.strain_data["SE"] = H.dna.struc_enzymes
D.carrier = 1
D.holder = H
D.affected_mob = H
@@ -233,10 +233,10 @@
if (prob(25))
if (prob(75))
randmutb(H)
- domutcheck(H,null,1)
+ domutcheck(H,null,MUTCHK_FORCED)
else
randmutg(H)
- domutcheck(H,null,1)
+ domutcheck(H,null,MUTCHK_FORCED)
for(var/mob/living/carbon/monkey/M in living_mob_list)
var/turf/T = get_turf(M)
if(!T)
diff --git a/code/game/gamemodes/events/holidays/Christmas.dm b/code/game/gamemodes/events/holidays/Christmas.dm
index 2ee79e7c65..72d42318e6 100644
--- a/code/game/gamemodes/events/holidays/Christmas.dm
+++ b/code/game/gamemodes/events/holidays/Christmas.dm
@@ -4,8 +4,8 @@
for(var/turf/simulated/floor/T in orange(1,xmas))
for(var/i=1,i<=rand(1,5),i++)
new /obj/item/weapon/a_gift(T)
- for(var/mob/living/simple_animal/corgi/Ian/Ian in mob_list)
- Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian))
+ //for(var/mob/living/simple_animal/corgi/Ian/Ian in mob_list)
+ // Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian))
/proc/ChristmasEvent()
for(var/obj/structure/flora/tree/pine/xmas in world)
diff --git a/code/game/gamemodes/events/ninja_abilities.dm b/code/game/gamemodes/events/ninja_abilities.dm
index 641bdf77ce..11109af279 100644
--- a/code/game/gamemodes/events/ninja_abilities.dm
+++ b/code/game/gamemodes/events/ninja_abilities.dm
@@ -69,12 +69,12 @@ Not sure why this would be useful (it's not) but whatever. Ninjas need their smo
//=======//RIGHT CLICK TELEPORT//=======//
//Right click to teleport somewhere, almost exactly like admin jump to turf.
/obj/item/clothing/suit/space/space_ninja/proc/ninjashift(turf/T in oview())
- set name = "Phase Shift (1E)"
+ set name = "Phase Shift (400E)"
set desc = "Utilizes the internal VOID-shift device to rapidly transit to a destination in view."
set category = null//So it does not show up on the panel but can still be right-clicked.
set src = usr.contents//Fixes verbs not attaching properly for objects. Praise the DM reference guide!
- var/C = 200
+ var/C = 40
if(!ninjacost(C,1))
var/mob/living/carbon/human/U = affecting
var/turf/mobloc = get_turf(U.loc)//To make sure that certain things work properly below.
@@ -83,6 +83,7 @@ Not sure why this would be useful (it's not) but whatever. Ninjas need their smo
playsound(U.loc, 'sound/effects/sparks4.ogg', 50, 1)
anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,U.dir)
+ cell.use(C*10)
handle_teleport_grab(T, U)
U.loc = T
@@ -92,19 +93,19 @@ Not sure why this would be useful (it's not) but whatever. Ninjas need their smo
playsound(U.loc, 'sound/effects/sparks2.ogg', 50, 1)
anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
else
- U << "\red You cannot teleport into solid walls or from solid matter"
+ U << "\red You cannot teleport into solid walls or from solid matter."
return
//=======//EM PULSE//=======//
//Disables nearby tech equipment.
/obj/item/clothing/suit/space/space_ninja/proc/ninjapulse()
- set name = "EM Burst (1,000E)"
+ set name = "EM Burst (2,000E)"
set desc = "Disable any nearby technology with a electro-magnetic pulse."
set category = "Ninja Ability"
set popup_menu = 0
- var/C = 250
- if(!ninjacost(C,100)) // EMP's now cost 1,000Energy about 30%
+ var/C = 200
+ if(!ninjacost(C,0)) // EMP's now cost 1,000Energy about 30%
var/mob/living/carbon/human/U = affecting
playsound(U.loc, 'sound/effects/EMPulse.ogg', 60, 2)
empulse(U, 2, 3) //Procs sure are nice. Slightly weaker than wizard's disable tch.
@@ -115,13 +116,13 @@ Not sure why this would be useful (it's not) but whatever. Ninjas need their smo
//=======//ENERGY BLADE//=======//
//Summons a blade of energy in active hand.
/obj/item/clothing/suit/space/space_ninja/proc/ninjablade()
- set name = "Energy Blade (20E)"
+ set name = "Energy Blade (500E)"
set desc = "Create a focused beam of energy in your active hand."
set category = "Ninja Ability"
set popup_menu = 0
var/C = 50
- if(!ninjacost(C, 800)) //Same spawn cost but higher upkeep cost
+ if(!ninjacost(C,0)) //Same spawn cost but higher upkeep cost
var/mob/living/carbon/human/U = affecting
if(!kamikaze)
if(!U.get_active_hand()&&!istype(U.get_inactive_hand(), /obj/item/weapon/melee/energy/blade))
@@ -148,12 +149,12 @@ Not sure why this would be useful (it's not) but whatever. Ninjas need their smo
/*Shoots ninja stars at random people.
This could be a lot better but I'm too tired atm.*/
/obj/item/clothing/suit/space/space_ninja/proc/ninjastar()
- set name = "Energy Star (1,000E)"
+ set name = "Energy Star (800E)"
set desc = "Launches an energy star at a random living target."
set category = "Ninja Ability"
set popup_menu = 0
- var/C = 50
+ var/C = 80
if(!ninjacost(C,1))
var/mob/living/carbon/human/U = affecting
var/targets[] = list()//So yo can shoot while yo throw dawg
@@ -173,7 +174,7 @@ This could be a lot better but I'm too tired atm.*/
A.current = curloc
A.yo = targloc.y - curloc.y
A.xo = targloc.x - curloc.x
- cell.use(C*100)// Ninja stars now cost 100 energy, stil la fair chunk to avoid spamming, will run out of power quickly if used 3 or more times
+ cell.use(C*10)
A.process()
else
U << "\red There are no targets in view."
@@ -183,13 +184,13 @@ This could be a lot better but I'm too tired atm.*/
/*Allows the ninja to capture people, I guess.
Must right click on a mob to activate.*/
/obj/item/clothing/suit/space/space_ninja/proc/ninjanet(mob/living/carbon/M in oview())//Only living carbon mobs.
- set name = "Energy Net (8,000E)"
+ set name = "Energy Net (7,000E)"
set desc = "Captures a fallen opponent in a net of energy. Will teleport them to a holding facility after 30 seconds."
set category = null
set src = usr.contents
- var/C = 500
- if(!ninjacost(C,80)&&iscarbon(M)) // Nets now cost 8,000
+ var/C = 700
+ if(!ninjacost(C,0)&&iscarbon(M))
var/mob/living/carbon/human/U = affecting
if(M.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame.
//if(M)//DEBUG
@@ -200,7 +201,7 @@ Must right click on a mob to activate.*/
return
spawn(0)
U.Beam(M,"n_beam",,15)
- M.anchored = 1//Anchors them so they can't move.
+ M.captured = 1
U.say("Get over here!")
var/obj/effect/energy_net/E = new /obj/effect/energy_net(M.loc)
E.layer = M.layer+1//To have it appear one layer above the mob.
@@ -210,7 +211,7 @@ Must right click on a mob to activate.*/
E.master = U
spawn(0)//Parallel processing.
E.process(M)
- cell.use(C*100) // Nets now cost what should be most of a standard battery, since your taking someone out of the round
+ cell.use(C*10) // Nets now cost what should be most of a standard battery, since your taking someone out of the round
else
U << "They are already trapped inside an energy net."
else
diff --git a/code/game/gamemodes/events/ninja_equipment.dm b/code/game/gamemodes/events/ninja_equipment.dm
index d25dabe21b..d9f3801902 100644
--- a/code/game/gamemodes/events/ninja_equipment.dm
+++ b/code/game/gamemodes/events/ninja_equipment.dm
@@ -323,13 +323,13 @@ ________________________________________________________________________________
var/o2_level = environment.oxygen/total_moles
var/n2_level = environment.nitrogen/total_moles
var/co2_level = environment.carbon_dioxide/total_moles
- var/plasma_level = environment.toxins/total_moles
- var/unknown_level = 1-(o2_level+n2_level+co2_level+plasma_level)
+ var/phoron_level = environment.phoron/total_moles
+ var/unknown_level = 1-(o2_level+n2_level+co2_level+phoron_level)
dat += "
"
dat += "
Nitrogen: [round(n2_level*100)]%
"
dat += "
Oxygen: [round(o2_level*100)]%
"
dat += "
Carbon Dioxide: [round(co2_level*100)]%
"
- dat += "
Plasma: [round(plasma_level*100)]%
"
+ dat += "
Phoron: [round(phoron_level*100)]%
"
dat += "
"
if(unknown_level > 0.01)
dat += "OTHER: [round(unknown_level)]% "
@@ -1385,7 +1385,8 @@ It is possible to destroy the net by the occupant or someone else.
if(!isnull(master))//As long as they still exist.
master << "\blue SUCCESS: \black transport procedure of \the [affecting] complete."
- M.anchored = 0//Important.
+ M.captured = 0 //Important.
+ M.anchored = initial(M.anchored) //Changes the mob's anchored status to the original one; this is not handled by the can_move proc.
else//And they are free.
M << "\blue You are free of the net!"
diff --git a/code/game/gamemodes/events/power_failure.dm b/code/game/gamemodes/events/power_failure.dm
index c8848cd3ee..dbebc649f5 100644
--- a/code/game/gamemodes/events/power_failure.dm
+++ b/code/game/gamemodes/events/power_failure.dm
@@ -61,7 +61,7 @@
if(C.cell && C.z == 1)
C.cell.charge = C.cell.maxcharge
for(var/obj/machinery/power/smes/S in world)
- if(S.z != 1)
+ if(istype(get_area(S), /area/turret_protected) || S.z != 1)
continue
S.charge = S.last_charge
S.output = S.last_output
diff --git a/code/game/gamemodes/events/space_ninja.dm b/code/game/gamemodes/events/space_ninja.dm
index c3b77d5f87..4d0df9c3f7 100644
--- a/code/game/gamemodes/events/space_ninja.dm
+++ b/code/game/gamemodes/events/space_ninja.dm
@@ -547,7 +547,7 @@ As such, it's hard-coded for now. No reason for it not to be, really.
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_belt)
equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_r_store)
equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_l_store)
- equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen(src), slot_s_store)
+ equip_to_slot_or_del(new /obj/item/weapon/tank/oxygen(src), slot_s_store)
return 1
//=======//HELPER PROCS//=======//
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 39be77978e..fe252c3ab3 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -22,7 +22,7 @@
var/explosion_in_progress = 0 //sit back and relax
var/list/datum/mind/modePlayer = new
var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist
- var/list/protected_jobs = list() // Jobs that can't be tratiors because
+ var/list/protected_jobs = list() // Jobs that can't be traitors because
var/required_players = 0
var/required_players_secret = 0 //Minimum number of players for that game mode to be chose in Secret
var/required_enemies = 0
@@ -44,7 +44,7 @@ Stealthy and Inconspicuous Weapons;
/obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge;
Whitespace:Seperator;
Stealth and Camouflage Items;
-/obj/item/clothing/under/chameleon:3:Chameleon Jumpsuit;
+/obj/item/weapon/storage/box/syndie_kit/chameleon:3:Chameleon Kit;
/obj/item/clothing/shoes/syndigaloshes:2:No-Slip Syndicate Shoes;
/obj/item/weapon/card/id/syndicate:2:Agent ID card;
/obj/item/clothing/mask/gas/voice:4:Voice Changer;
@@ -213,7 +213,7 @@ Implants;
for(var/mob/living/carbon/human/man in player_list) if(man.client && man.mind)
// NT relation option
var/special_role = man.mind.special_role
- if (special_role == "Wizard" || special_role == "Ninja" || special_role == "Syndicate")
+ if (special_role == "Wizard" || special_role == "Ninja" || special_role == "Syndicate" || special_role == "Vox Raider")
continue //NT intelligence ruled out possiblity that those are too classy to pretend to be a crew.
if(man.client.prefs.nanotrasen_relation == "Opposed" && prob(50) || \
man.client.prefs.nanotrasen_relation == "Skeptical" && prob(20))
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index a834a3cc0b..d42f88e891 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -56,7 +56,13 @@ var/global/datum/controller/gameticker/ticker
vote.process()
if(going)
pregame_timeleft--
-
+ if(pregame_timeleft == config.vote_autogamemode_timeleft)
+ if(!vote.time_remaining)
+ vote.autogamemode() //Quit calling this over and over and over and over.
+ while(vote.time_remaining)
+ for(var/i=0, i<10, i++)
+ sleep(1)
+ vote.process()
if(pregame_timeleft <= 0)
current_state = GAME_STATE_SETTING_UP
while (!setup())
@@ -149,6 +155,7 @@ var/global/datum/controller/gameticker/ticker
master_controller.process() //Start master_controller.process()
lighting_controller.process() //Start processing DynamicAreaLighting updates
+ for(var/obj/multiz/ladder/L in world) L.connect() //Lazy hackfix for ladders. TODO: move this to an actual controller. ~ Z
if(config.sql_enabled)
spawn(3000)
diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm
index 4dfff4fc4c..f556f43b4a 100644
--- a/code/game/gamemodes/heist/heist.dm
+++ b/code/game/gamemodes/heist/heist.dm
@@ -2,11 +2,6 @@
VOX HEIST ROUNDTYPE
*/
-#define MAX_VOX_KILLS 10 //Number of kills during the round before the Inviolate is broken.
- //Would be nice to use vox-specific kills but is currently not feasible.
-
-var/global/vox_kills = 0 //Used to check the Inviolate.
-
/datum/game_mode/
var/list/datum/mind/raiders = list() //Antags.
@@ -74,7 +69,8 @@ var/global/vox_kills = 0 //Used to check the Inviolate.
continue
//Generate objectives for the group.
- raid_objectives = forge_vox_objectives()
+ if(!config.objectives_disabled)
+ raid_objectives = forge_vox_objectives()
var/index = 1
@@ -163,10 +159,7 @@ var/global/vox_kills = 0 //Used to check the Inviolate.
objs += new /datum/objective/heist/inviolate_crew
objs += new /datum/objective/heist/inviolate_death
- for(var/datum/objective/heist/O in raid_objectives)
- O.choose_target()
-
- return raid_objectives
+ return objs
/datum/game_mode/heist/proc/greet_vox(var/datum/mind/raider)
raider.current << "\blue You are a Vox Raider, fresh from the Shoal!"
@@ -175,9 +168,12 @@ var/global/vox_kills = 0 //Used to check the Inviolate.
raider.current << "\blue Use :V to voxtalk, :H to talk on your encrypted channel, and don't forget to turn on your nitrogen internals!"
raider.current << "\red IF YOU HAVE NOT PLAYED A VOX BEFORE, REVIEW THIS THREAD: http://baystation12.net/forums/viewtopic.php?f=6&t=8657."
var/obj_count = 1
- for(var/datum/objective/objective in raider.objectives)
- raider.current << "Objective #[obj_count]: [objective.explanation_text]"
- obj_count++
+ if(!config.objectives_disabled)
+ for(var/datum/objective/objective in raider.objectives)
+ raider.current << "Objective #[obj_count]: [objective.explanation_text]"
+ obj_count++
+ else
+ raider.current << "Within the rules, try to act as an opposing force to the crew or come up with other fun ideas. Further RP and try to make sure other players have fun! If you are confused or at a loss, always adminhelp, and before taking extreme actions, please try to also contact the administration! Think through your actions and make the roleplay immersive! Please remember all rules aside from those without explicit exceptions apply to antagonists."
/datum/game_mode/heist/declare_completion()
@@ -245,28 +241,6 @@ var/global/vox_kills = 0 //Used to check the Inviolate.
feedback_add_details("traitor_objective","[objective.type]|FAIL")
count++
- var/text = "The vox raiders were:"
-
- for(var/datum/mind/vox in raiders)
- text += " [vox.key] was [vox.name] ("
- var/obj/stack = raiders[vox]
- if(get_area(stack) != locate(/area/shuttle/vox/station))
- text += "left behind)"
- continue
- else if(vox.current)
- if(vox.current.stat == DEAD)
- text += "died"
- else
- text += "survived"
- if(vox.current.real_name != vox.name)
- text += " as [vox.current.real_name]"
- else
- text += "body destroyed"
- text += ")"
-
- world << text
- return 1
-
..()
datum/game_mode/proc/auto_declare_completion_heist()
diff --git a/code/game/gamemodes/intercept_report.dm b/code/game/gamemodes/intercept_report.dm
index 54c1ac6b07..2ee0fe7d91 100644
--- a/code/game/gamemodes/intercept_report.dm
+++ b/code/game/gamemodes/intercept_report.dm
@@ -213,11 +213,11 @@
if(prob(prob_right_job))
if(correct_person)
if(correct_person:assigned_role=="MODE")
- changeling_job = pick(get_all_jobs())
+ changeling_job = pick(joblist)
else
changeling_job = correct_person:assigned_role
else
- changeling_job = pick(get_all_jobs())
+ changeling_job = pick(joblist)
if(prob(prob_right_dude) && ticker.mode == "changeling")
if(correct_person:assigned_role=="MODE")
changeling_name = correct_person:current
diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm
index 1fb1aff61a..eccf013fff 100644
--- a/code/game/gamemodes/malfunction/malfunction.dm
+++ b/code/game/gamemodes/malfunction/malfunction.dm
@@ -30,7 +30,7 @@
/datum/game_mode/malfunction/pre_setup()
for(var/mob/new_player/player in player_list)
- if(player.mind && player.mind.assigned_role == "AI")
+ if(player.mind && player.mind.assigned_role == "AI" && (player.client.prefs.be_special & BE_MALF))
malf_ai+=player.mind
if(malf_ai.len)
return 1
diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm
index deb28d7689..712512bd47 100644
--- a/code/game/gamemodes/meteor/meteor.dm
+++ b/code/game/gamemodes/meteor/meteor.dm
@@ -6,6 +6,7 @@
var/const/meteordelay = 2000
var/nometeors = 1
required_players = 0
+ votable = 0
uplink_welcome = "EVIL METEOR Uplink Console:"
uplink_uses = 10
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index c3720275ee..55191067e1 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -1,5 +1,3 @@
-#define METEOR_TEMPERATURE
-
/var/const/meteor_wave_delay = 625 //minimum wait between waves in tenths of seconds
//set to at least 100 unless you want evarr ruining every round
@@ -95,18 +93,9 @@
icon_state = "smallf"
pass_flags = PASSTABLE | PASSGRILLE
-/obj/effect/meteor/Move()
- var/turf/T = src.loc
- if (istype(T, /turf))
- T.hotspot_expose(METEOR_TEMPERATURE, 1000)
- ..()
- return
-
/obj/effect/meteor/Bump(atom/A)
spawn(0)
- for(var/mob/M in range(10, src))
- if(!M.stat && !istype(M, /mob/living/silicon/ai)) //bad idea to shake an ai's view
- shake_camera(M, 3, 1)
+
if (A)
A.meteorhit(src)
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1)
@@ -117,9 +106,7 @@
if(!istype(A,/obj/machinery/power/emitter) && \
!istype(A,/obj/machinery/field_generator) && \
prob(15))
-
explosion(src.loc, 4, 5, 6, 7, 0)
- playsound(src.loc, "explosion", 50, 1)
del(src)
return
@@ -146,16 +133,18 @@
if(--src.hits <= 0)
del(src) //Dont blow up singularity containment if we get stuck there.
- for(var/mob/M in range(10, src))
- if(!M.stat && !istype(M, /mob/living/silicon/ai)) //bad idea to shake an ai's view
- shake_camera(M, 3, 1)
if (A)
+ for(var/mob/M in player_list)
+ var/turf/T = get_turf(M)
+ if(!T || T.z != src.z)
+ continue
+ shake_camera(M, 3, get_dist(M.loc, src.loc) > 20 ? 1 : 3)
+ playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1)
explosion(src.loc, 0, 1, 2, 3, 0)
- playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1)
+
if (--src.hits <= 0)
if(prob(15) && !istype(A, /obj/structure/grille))
explosion(src.loc, 1, 2, 3, 4, 0)
- playsound(src.loc, "explosion", 50, 1)
del(src)
return
diff --git a/code/game/gamemodes/newobjective.dm b/code/game/gamemodes/newobjective.dm
index 9f26b049b8..30791aefcc 100644
--- a/code/game/gamemodes/newobjective.dm
+++ b/code/game/gamemodes/newobjective.dm
@@ -604,7 +604,7 @@ datum
var/list/all_items = owner.current.get_contents()
for(var/obj/item/I in all_items)
if(!istype(I, steal_target)) continue//If it's not actually that item.
- if(I:air_contents:toxins) return 1 //If they got one with plasma
+ if(I:air_contents:phoron) return 1 //If they got one with plasma
return 0
diff --git a/code/game/gamemodes/ninja/ninja.dm b/code/game/gamemodes/ninja/ninja.dm
index 026253a73b..42f5b69d7f 100644
--- a/code/game/gamemodes/ninja/ninja.dm
+++ b/code/game/gamemodes/ninja/ninja.dm
@@ -54,7 +54,10 @@
/datum/game_mode/ninja/post_setup()
for(var/datum/mind/ninja in ninjas)
if(ninja.current && !(istype(ninja.current,/mob/living/carbon/human))) return 0
- forge_ninja_objectives(ninja)
+ if(!config.objectives_disabled)
+ forge_ninja_objectives(ninja)
+ else
+ ninja.current << "Within the rules, try to act as an opposing force to the crew. Further RP and try to make sure other players have fun! If you are confused or at a loss, always adminhelp, and before taking extreme actions, please try to also contact the administration! Think through your actions and make the roleplay immersive! Please remember all rules aside from those without explicit exceptions apply to antagonists."
var/mob/living/carbon/human/N = ninja.current
N.internal = N.s_store
N.internals.icon_state = "internal1"
@@ -128,6 +131,7 @@
var/datum/objective/survive/ninja_objective = new
ninja_objective.owner = ninja
ninja.objectives += ninja_objective
+ ninja.current.mind = ninja
var/directive = generate_ninja_directive("heel")//Only hired by antags, not NT
ninja.current << "You are an elite mercenary assassin of the Spider Clan, [ninja.current.real_name]. You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor.\nYour current directive is: \red [directive]\n \blue Try your best to adhere to this."
@@ -175,12 +179,13 @@
else
special_role_text = "antagonist"
- if(ninjawin)
- text += " The [special_role_text] was successful!"
- feedback_add_details("traitor_success","SUCCESS")
- else
- text += " The [special_role_text] has failed!"
- feedback_add_details("traitor_success","FAIL")
+ if(!config.objectives_disabled)
+ if(ninjawin)
+ text += " The [special_role_text] was successful!"
+ feedback_add_details("traitor_success","SUCCESS")
+ else
+ text += " The [special_role_text] has failed!"
+ feedback_add_details("traitor_success","FAIL")
world << text
return 1
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index be68855414..5674ea9098 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -5,9 +5,9 @@
/datum/game_mode/nuclear
name = "nuclear emergency"
config_tag = "nuclear"
- required_players = 6
+ required_players = 15
required_players_secret = 25 // 25 players - 5 players to be the nuke ops = 20 players remaining
- required_enemies = 5
+ required_enemies = 1
recommended_enemies = 5
uplink_welcome = "Corporate Backed Uplink Console:"
@@ -34,17 +34,25 @@
var/list/possible_syndicates = get_players_for_role(BE_OPERATIVE)
var/agent_number = 0
+ /*
+ * if(possible_syndicates.len > agents_possible)
+ * agent_number = agents_possible
+ * else
+ * agent_number = possible_syndicates.len
+ *
+ * if(agent_number > n_players)
+ * agent_number = n_players/2
+ */
+
if(possible_syndicates.len < 1)
return 0
- if(possible_syndicates.len > agents_possible)
- agent_number = agents_possible
- else
- agent_number = possible_syndicates.len
-
+ //Antag number should scale to active crew.
var/n_players = num_players()
- if(agent_number > n_players)
- agent_number = n_players/2
+ agent_number = Clamp((n_players/5), 2, 6)
+
+ if(possible_syndicates.len < agent_number)
+ agent_number = possible_syndicates.len
while(agent_number > 0)
var/datum/mind/new_syndicate = pick(possible_syndicates)
@@ -121,7 +129,6 @@
var/nuke_code = "[rand(10000, 99999)]"
var/leader_selected = 0
- var/agent_number = 1
var/spawnpos = 1
for(var/datum/mind/synd_mind in syndicates)
@@ -129,16 +136,18 @@
spawnpos = 1
synd_mind.current.loc = synd_spawn[spawnpos]
- forge_syndicate_objectives(synd_mind)
+ synd_mind.current.real_name = "[syndicate_name()] Operative" // placeholder while we get their actual name
+ spawn(0)
+ NukeNameAssign(synd_mind)
+ if(!config.objectives_disabled)
+ forge_syndicate_objectives(synd_mind)
greet_syndicate(synd_mind)
equip_syndicate(synd_mind.current)
if(!leader_selected)
prepare_syndicate_leader(synd_mind, nuke_code)
leader_selected = 1
- else
- synd_mind.current.real_name = "[syndicate_name()] Operative #[agent_number]"
- agent_number++
+
spawnpos++
update_synd_icons_added(synd_mind)
@@ -157,10 +166,6 @@
/datum/game_mode/proc/prepare_syndicate_leader(var/datum/mind/synd_mind, var/nuke_code)
-// var/leader_title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")
- spawn(1)
-// NukeNameAssign(nukelastname(synd_mind.current),syndicates) //allows time for the rest of the syndies to be chosen
- synd_mind.current.real_name = "[pick(first_names_male)] [pick(last_names)]"
if (nuke_code)
synd_mind.store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0)
synd_mind.current << "The nuclear authorization code is: [nuke_code]"
@@ -190,9 +195,12 @@
if (you_are)
syndicate.current << "\blue You are a [syndicate_name()] agent!"
var/obj_count = 1
- for(var/datum/objective/objective in syndicate.objectives)
- syndicate.current << "Objective #[obj_count]: [objective.explanation_text]"
- obj_count++
+ if(!config.objectives_disabled)
+ for(var/datum/objective/objective in syndicate.objectives)
+ syndicate.current << "Objective #[obj_count]: [objective.explanation_text]"
+ obj_count++
+ else
+ syndicate.current << "Within the rules, try to act as an opposing force to the crew. Further RP and try to make sure other players have fun! If you are confused or at a loss, always adminhelp, and before taking extreme actions, please try to also contact the administration! Think through your actions and make the roleplay immersive! Please remember all rules aside from those without explicit exceptions apply to antagonists."
return
@@ -209,9 +217,7 @@
synd_mob.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(synd_mob), slot_w_uniform)
synd_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(synd_mob), slot_shoes)
- synd_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(synd_mob), slot_wear_suit)
synd_mob.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(synd_mob), slot_gloves)
- synd_mob.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/swat(synd_mob), slot_head)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/card/id/syndicate(synd_mob), slot_wear_id)
if(synd_mob.backbag == 2) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(synd_mob), slot_back)
if(synd_mob.backbag == 3) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(synd_mob), slot_back)
@@ -221,6 +227,26 @@
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/pill/cyanide(synd_mob), slot_in_backpack)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/automatic/c20r(synd_mob), slot_belt)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(synd_mob.back), slot_in_backpack)
+
+ if(synd_mob.species)
+ var/race = synd_mob.species.name
+
+ if(race == "Unathi")
+ synd_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/syndi/unathi(synd_mob), slot_wear_suit)
+ synd_mob.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/syndi/unathi(synd_mob), slot_head)
+ else if(race == "Tajaran")
+ synd_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/syndi/tajara(synd_mob), slot_wear_suit)
+ synd_mob.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/syndi/tajara(synd_mob), slot_head)
+ else if(race == "Skrell")
+ synd_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/syndi/skrell(synd_mob), slot_wear_suit)
+ synd_mob.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/syndi/skrell(synd_mob), slot_head)
+ else
+ synd_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/syndi/human(synd_mob), slot_wear_suit)
+ synd_mob.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/syndi/human(synd_mob), slot_head)
+ else
+ synd_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/syndi/human(synd_mob), slot_wear_suit)
+ synd_mob.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/syndi/human(synd_mob), slot_head)
+
var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(synd_mob)
E.imp_in = synd_mob
E.implanted = 1
@@ -244,6 +270,8 @@
/datum/game_mode/nuclear/declare_completion()
+ if(config.objectives_disabled)
+ return
var/disk_rescued = 1
for(var/obj/item/weapon/disk/nuclear/D in world)
var/disk_area = get_area(D)
@@ -344,12 +372,14 @@
return newname
*/
-/proc/NukeNameAssign(var/lastname,var/list/syndicates)
- for(var/datum/mind/synd_mind in syndicates)
- switch(synd_mind.current.gender)
- if(MALE)
- synd_mind.name = "[pick(first_names_male)] [pick(last_names)]"
- if(FEMALE)
- synd_mind.name = "[pick(first_names_female)] [pick(last_names)]"
- synd_mind.current.real_name = synd_mind.name
- return
\ No newline at end of file
+
+/proc/NukeNameAssign(var/datum/mind/synd_mind)
+ var/choose_name = input(synd_mind.current, "You are a [syndicate_name()] agent! What is your name?", "Choose a name") as text
+
+ if(!choose_name)
+ return
+
+ else
+ synd_mind.current.name = choose_name
+ synd_mind.current.real_name = choose_name
+ return
\ No newline at end of file
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index 24a3df847a..a58e8b553f 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -82,6 +82,10 @@ var/bomb_set
flick("nuclearbombc", src)
return
+ if (istype(O, /obj/item/weapon/wirecutters) || istype(O, /obj/item/device/multitool))
+ if (src.opened == 1)
+ nukehack_win(user)
+ return
if (src.extended)
if (istype(O, /obj/item/weapon/disk/nuclear))
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 12ac544784..848f247db9 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -1,4 +1,5 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
+var/global/list/all_objectives = list()
datum/objective
var/datum/mind/owner = null //Who owns the objective.
@@ -8,9 +9,14 @@ datum/objective
var/completed = 0 //currently only used for custom objectives.
New(var/text)
+ all_objectives |= src
if(text)
explanation_text = text
+ Del()
+ all_objectives -= src
+ ..()
+
proc/check_completion()
return completed
@@ -352,7 +358,7 @@ datum/objective/escape
if(!location)
return 0
- if(istype(location, /turf/simulated/shuttle/floor4)) // Fails tratiors if they are in the shuttle brig -- Polymorph
+ if(istype(location, /turf/simulated/shuttle/floor4)) // Fails traitors if they are in the shuttle brig -- Polymorph
if(istype(owner.current, /mob/living/carbon))
var/mob/living/carbon/C = owner.current
if (!C.handcuffed)
@@ -483,7 +489,7 @@ datum/objective/steal
"a pair of magboots" = /obj/item/clothing/shoes/magboots,
"the station blueprints" = /obj/item/blueprints,
"a nasa voidsuit" = /obj/item/clothing/suit/space/nasavoid,
- "28 moles of plasma (full tank)" = /obj/item/weapon/tank,
+ "28 moles of phoron (full tank)" = /obj/item/weapon/tank,
"a sample of slime extract" = /obj/item/slime_extract,
"a piece of corgi meat" = /obj/item/weapon/reagent_containers/food/snacks/meat/corgi,
"a research director's jumpsuit" = /obj/item/clothing/under/rank/research_director,
@@ -545,13 +551,13 @@ datum/objective/steal
if(!isliving(owner.current)) return 0
var/list/all_items = owner.current.get_contents()
switch (target_name)
- if("28 moles of plasma (full tank)","10 diamonds","50 gold bars","25 refined uranium bars")
+ if("28 moles of phoron (full tank)","10 diamonds","50 gold bars","25 refined uranium bars")
var/target_amount = text2num(target_name)//Non-numbers are ignored.
var/found_amount = 0.0//Always starts as zero.
- for(var/obj/item/I in all_items) //Check for plasma tanks
+ for(var/obj/item/I in all_items) //Check for phoron tanks
if(istype(I, steal_target))
- found_amount += (target_name=="28 moles of plasma (full tank)" ? (I:air_contents:toxins) : (I:amount))
+ found_amount += (target_name=="28 moles of phoron (full tank)" ? (I:air_contents:phoron) : (I:amount))
return found_amount>=target_amount
if("50 coins (in bag)")
@@ -861,7 +867,7 @@ datum/objective/heist/salvage
target = "plasteel"
target_amount = 100
if(4)
- target = "plasma"
+ target = "phoron"
target_amount = 100
if(5)
target = "silver"
@@ -916,8 +922,12 @@ datum/objective/heist/inviolate_crew
if(H.is_raider_crew_safe()) return 1
return 0
+#define MAX_VOX_KILLS 10 //Number of kills during the round before the Inviolate is broken.
+ //Would be nice to use vox-specific kills but is currently not feasible.
+var/global/vox_kills = 0 //Used to check the Inviolate.
+
datum/objective/heist/inviolate_death
explanation_text = "Follow the Inviolate. Minimise death and loss of resources."
check_completion()
- if(vox_kills>5) return 0
+ if(vox_kills > MAX_VOX_KILLS) return 0
return 1
\ No newline at end of file
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index e94baa3ede..f6199dcb16 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -21,7 +21,7 @@
recommended_enemies = 3
- uplink_welcome = "Revolutionary Uplink Console:"
+ uplink_welcome = "AntagCorp Uplink Console:"
uplink_uses = 10
var/finished = 0
@@ -73,14 +73,14 @@
/datum/game_mode/revolution/post_setup()
var/list/heads = get_living_heads()
-
for(var/datum/mind/rev_mind in head_revolutionaries)
- for(var/datum/mind/head_mind in heads)
- var/datum/objective/mutiny/rev_obj = new
- rev_obj.owner = rev_mind
- rev_obj.target = head_mind
- rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]."
- rev_mind.objectives += rev_obj
+ if(!config.objectives_disabled)
+ for(var/datum/mind/head_mind in heads)
+ var/datum/objective/mutiny/rev_obj = new
+ rev_obj.owner = rev_mind
+ rev_obj.target = head_mind
+ rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]."
+ rev_mind.objectives += rev_obj
// equip_traitor(rev_mind.current, 1) //changing how revs get assigned their uplink so they can get PDA uplinks. --NEO
// Removing revolutionary uplinks. -Pete
@@ -107,22 +107,26 @@
/datum/game_mode/proc/forge_revolutionary_objectives(var/datum/mind/rev_mind)
- var/list/heads = get_living_heads()
- for(var/datum/mind/head_mind in heads)
- var/datum/objective/mutiny/rev_obj = new
- rev_obj.owner = rev_mind
- rev_obj.target = head_mind
- rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]."
- rev_mind.objectives += rev_obj
+ if(!config.objectives_disabled)
+ var/list/heads = get_living_heads()
+ for(var/datum/mind/head_mind in heads)
+ var/datum/objective/mutiny/rev_obj = new
+ rev_obj.owner = rev_mind
+ rev_obj.target = head_mind
+ rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]."
+ rev_mind.objectives += rev_obj
/datum/game_mode/proc/greet_revolutionary(var/datum/mind/rev_mind, var/you_are=1)
var/obj_count = 1
if (you_are)
rev_mind.current << "\blue You are a member of the revolutionaries' leadership!"
- for(var/datum/objective/objective in rev_mind.objectives)
- rev_mind.current << "Objective #[obj_count]: [objective.explanation_text]"
- rev_mind.special_role = "Head Revolutionary"
- obj_count++
+ if(!config.objectives_disabled)
+ for(var/datum/objective/objective in rev_mind.objectives)
+ rev_mind.current << "Objective #[obj_count]: [objective.explanation_text]"
+ rev_mind.special_role = "Head Revolutionary"
+ obj_count++
+ else
+ rev_mind.current << "Within the rules, try to act as an opposing force to the crew. Further RP and try to make sure other players have fun! If you are confused or at a loss, always adminhelp, and before taking extreme actions, please try to also contact the administration! Think through your actions and make the roleplay immersive! Please remember all rules aside from those without explicit exceptions apply to antagonists."
/////////////////////////////////////////////////////////////////////////////////
//This are equips the rev heads with their gear, and makes the clown not clumsy//
@@ -193,6 +197,8 @@
revolutionaries += rev_mind
rev_mind.current << "\red You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!"
rev_mind.special_role = "Revolutionary"
+ if(config.objectives_disabled)
+ rev_mind.current << "Within the rules, try to act as an opposing force to the crew. Further RP and try to make sure other players have fun! If you are confused or at a loss, always adminhelp, and before taking extreme actions, please try to also contact the administration! Think through your actions and make the roleplay immersive! Please remember all rules aside from those without explicit exceptions apply to antagonists."
update_rev_icons_added(rev_mind)
return 1
//////////////////////////////////////////////////////////////////////////////
@@ -202,6 +208,7 @@
if(rev_mind in revolutionaries)
revolutionaries -= rev_mind
rev_mind.special_role = null
+ rev_mind.current.hud_updateflag |= 1 << SPECIALROLE_HUD
if(beingborged)
rev_mind.current << "\red The frame's firmware detects and deletes your neural reprogramming! You remember nothing from the moment you were flashed until now."
@@ -342,13 +349,14 @@
//Announces the end of the game with all relavent information stated//
//////////////////////////////////////////////////////////////////////
/datum/game_mode/revolution/declare_completion()
- if(finished == 1)
- feedback_set_details("round_end_result","win - heads killed")
- world << "\red The heads of staff were killed or abandoned the station! The revolutionaries win!"
- else if(finished == 2)
- feedback_set_details("round_end_result","loss - rev heads killed")
- world << "\red The heads of staff managed to stop the revolution!"
- ..()
+ if(!config.objectives_disabled)
+ if(finished == 1)
+ feedback_set_details("round_end_result","win - heads killed")
+ world << "\red The heads of staff were killed or abandoned the station! The revolutionaries win!"
+ else if(finished == 2)
+ feedback_set_details("round_end_result","loss - rev heads killed")
+ world << "\red The heads of staff managed to stop the revolution!"
+ ..()
return 1
/datum/game_mode/proc/auto_declare_completion_revolution()
diff --git a/code/game/gamemodes/revolution/rp-revolution.dm b/code/game/gamemodes/revolution/rp-revolution.dm
index 7456e73403..963579af7c 100644
--- a/code/game/gamemodes/revolution/rp-revolution.dm
+++ b/code/game/gamemodes/revolution/rp-revolution.dm
@@ -304,4 +304,4 @@ mob/living/carbon/human/proc
else if(choice == "No!")
M << "\red You reject this traitorous cause!"
src << "\red [M] does not support the revolution!"
- M.mind.rev_cooldown = world.time+50
\ No newline at end of file
+ M.mind.rev_cooldown = world.time+50
diff --git a/code/game/gamemodes/revolution/rp_revolution.dm b/code/game/gamemodes/revolution/rp_revolution.dm
index d00b58d23b..70fd1387f0 100644
--- a/code/game/gamemodes/revolution/rp_revolution.dm
+++ b/code/game/gamemodes/revolution/rp_revolution.dm
@@ -8,7 +8,7 @@
required_enemies = 3
recommended_enemies = 3
- uplink_welcome = "Revolutionary Uplink Console:"
+ uplink_welcome = "AntagCorp Uplink Console:"
uplink_uses = 5
newscaster_announcements = /datum/news_announcement/revolution_inciting_event
@@ -57,14 +57,14 @@
/datum/game_mode/revolution/rp_revolution/post_setup()
heads = get_living_heads()
-
for(var/datum/mind/rev_mind in head_revolutionaries)
- for(var/datum/mind/head_mind in heads)
- var/datum/objective/mutiny/rp/rev_obj = new
- rev_obj.owner = rev_mind
- rev_obj.target = head_mind
- rev_obj.explanation_text = "Assassinate, convert or capture [head_mind.name], the [head_mind.assigned_role]."
- rev_mind.objectives += rev_obj
+ if(!config.objectives_disabled)
+ for(var/datum/mind/head_mind in heads)
+ var/datum/objective/mutiny/rp/rev_obj = new
+ rev_obj.owner = rev_mind
+ rev_obj.target = head_mind
+ rev_obj.explanation_text = "Assassinate, convert or capture [head_mind.name], the [head_mind.assigned_role]."
+ rev_mind.objectives += rev_obj
update_rev_icons_added(rev_mind)
@@ -81,10 +81,13 @@
var/obj_count = 1
if (you_are)
rev_mind.current << "\blue You are a member of the revolutionaries' leadership!"
- for(var/datum/objective/objective in rev_mind.objectives)
- rev_mind.current << "Objective #[obj_count]: [objective.explanation_text]"
- rev_mind.special_role = "Head Revolutionary"
- obj_count++
+ if(!config.objectives_disabled)
+ for(var/datum/objective/objective in rev_mind.objectives)
+ rev_mind.current << "Objective #[obj_count]: [objective.explanation_text]"
+ rev_mind.special_role = "Head Revolutionary"
+ obj_count++
+ else
+ rev_mind.current << "Within the rules, try to act as an opposing force to the crew. Further RP and try to make sure other players have fun! If you are confused or at a loss, always adminhelp, and before taking extreme actions, please try to also contact the administration! Think through your actions and make the roleplay immersive! Please remember all rules aside from those without explicit exceptions apply to antagonists."
// Show each head revolutionary up to 3 candidates
var/list/already_considered = list()
@@ -110,7 +113,10 @@
revolutionaries += rev_mind
rev_mind.current << "\red You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill, capture or convert the heads to win the revolution!"
rev_mind.special_role = "Revolutionary"
+ if(config.objectives_disabled)
+ rev_mind.current << "Within the rules, try to act as an opposing force to the crew. Further RP and try to make sure other players have fun! If you are confused or at a loss, always adminhelp, and before taking extreme actions, please try to also contact the administration! Think through your actions and make the roleplay immersive! Please remember all rules aside from those without explicit exceptions apply to antagonists."
update_rev_icons_added(rev_mind)
+ H.hud_updateflag |= 1 << SPECIALROLE_HUD
return 1
/////////////////////////////
@@ -140,13 +146,14 @@
//Announces the end of the game with all relavent information stated//
//////////////////////////////////////////////////////////////////////
/datum/game_mode/revolution/rp_revolution/declare_completion()
- if(finished == 1)
- feedback_set_details("round_end_result","win - heads overthrown")
- world << "\red The heads of staff were overthrown! The revolutionaries win!"
- else if(finished == 2)
- feedback_set_details("round_end_result","loss - revolution stopped")
- world << "\red The heads of staff managed to stop the revolution!"
- ..()
+ if(!config.objectives_disabled)
+ if(finished == 1)
+ feedback_set_details("round_end_result","win - heads overthrown")
+ world << "\red The heads of staff were overthrown! The revolutionaries win!"
+ else if(finished == 2)
+ feedback_set_details("round_end_result","loss - revolution stopped")
+ world << "\red The heads of staff managed to stop the revolution!"
+ ..()
return 1
/datum/game_mode/revolution/proc/is_convertible(mob/M)
@@ -156,9 +163,17 @@
return 1
-/mob/living/carbon/human/proc/RevConvert(mob/M as mob in oview(src))
+/mob/living/carbon/human/proc/RevConvert()
set name = "Rev-Convert"
set category = "IC"
+ var/list/Possible = list()
+ for (var/mob/living/carbon/human/P in oview(src))
+ if(!stat && P.client && P.mind && !P.mind.special_role)
+ Possible += P
+ if(!Possible.len)
+ src << "\red There doesn't appear to be anyone available for you to convert here."
+ return
+ var/mob/living/carbon/human/M = input("Select a person to convert", "Viva la revolution!", null) as mob in Possible
if(((src.mind in ticker.mode:head_revolutionaries) || (src.mind in ticker.mode:revolutionaries)))
if((M.mind in ticker.mode:head_revolutionaries) || (M.mind in ticker.mode:revolutionaries))
src << "\red [M] is already be a revolutionary!"
@@ -187,7 +202,7 @@
tried_to_add_revheads = world.time+50
var/active_revs = 0
for(var/datum/mind/rev_mind in head_revolutionaries)
- if(rev_mind.current.client && rev_mind.current.client.inactivity <= 10*60*20) // 20 minutes inactivity are OK
+ if(rev_mind.current && rev_mind.current.client && rev_mind.current.client.inactivity <= 10*60*20) // 20 minutes inactivity are OK
active_revs++
if(active_revs == 0)
@@ -251,4 +266,4 @@
rev_obj.target = M.mind
rev_obj.explanation_text = "Assassinate, convert or capture [M.real_name], the [M.mind.assigned_role]."
rev_mind.objectives += rev_obj
- rev_mind.current << "\red A new Head of Staff, [M.real_name], the [M.mind.assigned_role] has appeared. Your objectives have been updated."
\ No newline at end of file
+ rev_mind.current << "\red A new Head of Staff, [M.real_name], the [M.mind.assigned_role] has appeared. Your objectives have been updated."
diff --git a/code/game/gamemodes/setupgame.dm b/code/game/gamemodes/setupgame.dm
index c72f56f8cf..d2b54fe5ba 100644
--- a/code/game/gamemodes/setupgame.dm
+++ b/code/game/gamemodes/setupgame.dm
@@ -2,10 +2,13 @@
// (mostly) DNA2 SETUP
/////////////////////////
-// Randomize block, assign a reference name, and optionally define difficulty (by making activation zone smaller or bigger)
+// Randomize block, assign a reference name, and optionally define difficulty (by making activation zone smaller or bigger)
// The name is used on /vg/ for species with predefined genetic traits,
// and for the DNA panel in the player panel.
/proc/getAssignedBlock(var/name,var/list/blocksLeft, var/activity_bounds=DNA_DEFAULT_BOUNDS)
+ if(blocksLeft.len==0)
+ warning("[name]: No more blocks left to assign!")
+ return 0
var/assigned = pick(blocksLeft)
blocksLeft.Remove(assigned)
assigned_blocks[assigned]=name
@@ -60,7 +63,7 @@
BLINDBLOCK = tempnum
*/
var/list/numsToAssign=new()
- for(var/i=1;iYou are the traitor."
- var/obj_count = 1
- for(var/datum/objective/objective in traitor.objectives)
- traitor.current << "Objective #[obj_count]: [objective.explanation_text]"
- obj_count++
+ if (!config.objectives_disabled)
+ var/obj_count = 1
+ for(var/datum/objective/objective in traitor.objectives)
+ traitor.current << "Objective #[obj_count]: [objective.explanation_text]"
+ obj_count++
+ else
+ traitor.current << "You have been selected this round as an antagonist- Within the rules, try to act as an opposing force to the crew- This can be via corporate payoff, personal motives, or maybe just being a dick. Further RP and try to make sure other players have fun! If you are confused or at a loss, always adminhelp, and before taking extreme actions, please try to also contact the administration! Think through your actions and make the roleplay immersive! Please remember all rules aside from those without explicit exceptions apply to antagonist."
return
@@ -216,19 +220,20 @@
special_role_text = lowertext(traitor.special_role)
else
special_role_text = "antagonist"
-
- if(traitorwin)
- text += " The [special_role_text] was successful!"
- feedback_add_details("traitor_success","SUCCESS")
- else
- text += " The [special_role_text] has failed!"
- feedback_add_details("traitor_success","FAIL")
+ if(!config.objectives_disabled)
+ if(traitorwin)
+ text += " The [special_role_text] was successful!"
+ feedback_add_details("traitor_success","SUCCESS")
+ else
+ text += " The [special_role_text] has failed!"
+ feedback_add_details("traitor_success","FAIL")
world << text
return 1
/datum/game_mode/proc/equip_traitor(mob/living/carbon/human/traitor_mob, var/safety = 0)
+
if (!istype(traitor_mob))
return
. = 1
@@ -239,12 +244,38 @@
// find a radio! toolbox(es), backpack, belt, headset
var/loc = ""
- var/obj/item/R = locate(/obj/item/device/pda) in traitor_mob.contents //Hide the uplink in a PDA if available, otherwise radio
- if(!R)
+ var/obj/item/R = locate() //Hide the uplink in a PDA if available, otherwise radio
+
+ if(traitor_mob.client.prefs.uplinklocation == "Headset")
R = locate(/obj/item/device/radio) in traitor_mob.contents
+ if(!R)
+ R = locate(/obj/item/device/pda) in traitor_mob.contents
+ traitor_mob << "Could not locate a Radio, installing in PDA instead!"
+ if (!R)
+ traitor_mob << "Unfortunately, neither a radio or a PDA relay could be installed."
+
+ else if(traitor_mob.client.prefs.uplinklocation == "PDA")
+ R = locate(/obj/item/device/pda) in traitor_mob.contents
+ if(!R)
+ R = locate(/obj/item/device/radio) in traitor_mob.contents
+ traitor_mob << "Could not locate a PDA, installing into a Radio instead!"
+ if (!R)
+ traitor_mob << "Unfortunately, neither a radio or a PDA relay could be installed."
+
+ else if(traitor_mob.client.prefs.uplinklocation == "None")
+ traitor_mob << "You have elected to not have an AntagCorp portable teleportation relay installed!"
+ R = null
+
+ else
+ traitor_mob << "You have not selected a location for your relay in the antagonist options! Defaulting to PDA!"
+ R = locate(/obj/item/device/pda) in traitor_mob.contents
+ if (!R)
+ R = locate(/obj/item/device/radio) in traitor_mob.contents
+ traitor_mob << "Could not locate a PDA, installing into a Radio instead!"
+ if (!R)
+ traitor_mob << "Unfortunately, neither a radio or a PDA relay could be installed."
if (!R)
- traitor_mob << "Unfortunately, the Syndicate wasn't able to get you a radio."
. = 0
else
if (istype(R, /obj/item/device/radio))
@@ -263,7 +294,7 @@
var/obj/item/device/uplink/hidden/T = new(R)
target_radio.hidden_uplink = T
target_radio.traitor_frequency = freq
- traitor_mob << "The Syndicate have cunningly disguised a Syndicate Uplink as your [R.name] [loc]. Simply dial the frequency [format_frequency(freq)] to unlock its hidden features."
+ traitor_mob << "A portable object teleportation relay has been installed in your [R.name] [loc]. Simply dial the frequency [format_frequency(freq)] to unlock its hidden features."
traitor_mob.mind.store_memory("Radio Freq: [format_frequency(freq)] ([R.name] [loc]).")
else if (istype(R, /obj/item/device/pda))
// generate a passcode if the uplink is hidden in a PDA
@@ -274,7 +305,7 @@
var/obj/item/device/pda/P = R
P.lock_code = pda_pass
- traitor_mob << "The Syndicate have cunningly disguised a Syndicate Uplink as your [R.name] [loc]. Simply enter the code \"[pda_pass]\" into the ringtone select to unlock its hidden features."
+ traitor_mob << "A portable object teleportation relay has been installed in your [R.name] [loc]. Simply enter the code \"[pda_pass]\" into the ringtone select to unlock its hidden features."
traitor_mob.mind.store_memory("Uplink Passcode: [pda_pass] ([R.name] [loc]).")
//Begin code phrase.
if(!safety)//If they are not a rev. Can be added on to.
diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm
index 70c655ce57..ddda65952e 100644
--- a/code/game/gamemodes/wizard/soulstone.dm
+++ b/code/game/gamemodes/wizard/soulstone.dm
@@ -19,6 +19,10 @@
if(istype(M, /mob/living/carbon/human/dummy))
return..()
+ if(M.has_brain_worms()) //Borer stuff - RR
+ user << "This being is corrupted by an alien intelligence and cannot be soul trapped."
+ return..()
+
M.attack_log += text("\[[time_stamp()]\] Has had their soul captured with [src.name] by [user.name] ([user.ckey])")
user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to capture the soul of [M.name] ([M.ckey])")
msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to capture the soul of [M.name] ([M.ckey]) (JMP)")
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index ff19ce7764..cd70a392de 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -5,7 +5,7 @@
icon_state ="book"
throw_speed = 1
throw_range = 5
- w_class = 1.0
+ w_class = 2.0
flags = FPRINT | TABLEPASS
var/uses = 5
var/temp = null
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index add8ee00a6..751092f388 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -50,7 +50,8 @@
/datum/game_mode/wizard/post_setup()
for(var/datum/mind/wizard in wizards)
- forge_wizard_objectives(wizard)
+ if(!config.objectives_disabled)
+ forge_wizard_objectives(wizard)
//learn_basic_spells(wizard.current)
equip_wizard(wizard.current)
name_wizard(wizard.current)
@@ -132,11 +133,13 @@
if (you_are)
wizard.current << "\red You are the Space Wizard!"
wizard.current << "The Space Wizards Federation has given you the following tasks:"
-
- var/obj_count = 1
- for(var/datum/objective/objective in wizard.objectives)
- wizard.current << "Objective #[obj_count]: [objective.explanation_text]"
- obj_count++
+ if(!config.objectives_disabled)
+ var/obj_count = 1
+ for(var/datum/objective/objective in wizard.objectives)
+ wizard.current << "Objective #[obj_count]: [objective.explanation_text]"
+ obj_count++
+ else
+ wizard.current << "Within the rules, try to act as an opposing force to the crew. Further RP and try to make sure other players have fun! If you are confused or at a loss, always adminhelp, and before taking extreme actions, please try to also contact the administration! Think through your actions and make the roleplay immersive! Please remember all rules aside from those without explicit exceptions apply to antagonists."
return
@@ -231,22 +234,23 @@
var/count = 1
var/wizardwin = 1
- for(var/datum/objective/objective in wizard.objectives)
- if(objective.check_completion())
- text += " Objective #[count]: [objective.explanation_text] Success!"
- feedback_add_details("wizard_objective","[objective.type]|SUCCESS")
- else
- text += " Objective #[count]: [objective.explanation_text] Fail."
- feedback_add_details("wizard_objective","[objective.type]|FAIL")
- wizardwin = 0
- count++
+ if(!config.objectives_disabled)
+ for(var/datum/objective/objective in wizard.objectives)
+ if(objective.check_completion())
+ text += " Objective #[count]: [objective.explanation_text] Success!"
+ feedback_add_details("wizard_objective","[objective.type]|SUCCESS")
+ else
+ text += " Objective #[count]: [objective.explanation_text] Fail."
+ feedback_add_details("wizard_objective","[objective.type]|FAIL")
+ wizardwin = 0
+ count++
- if(wizard.current && wizard.current.stat!=2 && wizardwin)
- text += " The wizard was successful!"
- feedback_add_details("wizard_success","SUCCESS")
- else
- text += " The wizard has failed!"
- feedback_add_details("wizard_success","FAIL")
+ if(wizard.current && wizard.current.stat!=2 && wizardwin)
+ text += " The wizard was successful!"
+ feedback_add_details("wizard_success","SUCCESS")
+ else
+ text += " The wizard has failed!"
+ feedback_add_details("wizard_success","FAIL")
world << text
return 1
diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm
index 22037996ce..a6a5c38d30 100644
--- a/code/game/jobs/access.dm
+++ b/code/game/jobs/access.dm
@@ -90,29 +90,6 @@
/obj/var/list/req_one_access = null
/obj/var/req_one_access_txt = "0"
-/obj/New()
- ..()
- //NOTE: If a room requires more than one access (IE: Morgue + medbay) set the req_acesss_txt to "5;6" if it requires 5 and 6
- if(src.req_access_txt)
- var/list/req_access_str = text2list(req_access_txt,";")
- if(!req_access)
- req_access = list()
- for(var/x in req_access_str)
- var/n = text2num(x)
- if(n)
- req_access += n
-
- if(src.req_one_access_txt)
- var/list/req_one_access_str = text2list(req_one_access_txt,";")
- if(!req_one_access)
- req_one_access = list()
- for(var/x in req_one_access_str)
- var/n = text2num(x)
- if(n)
- req_one_access += n
-
-
-
//returns 1 if this mob has sufficient access to use this object
/obj/proc/allowed(mob/M)
//check if it doesn't require any access at all
@@ -140,9 +117,25 @@
return null
/obj/proc/check_access(obj/item/I)
+ //These generations have been moved out of /obj/New() because they were slowing down the creation of objects that never even used the access system.
+ if(!src.req_access)
+ src.req_access = list()
+ if(src.req_access_txt)
+ var/list/req_access_str = text2list(req_access_txt,";")
+ for(var/x in req_access_str)
+ var/n = text2num(x)
+ if(n)
+ req_access += n
+
+ if(!src.req_one_access)
+ src.req_one_access = list()
+ if(src.req_one_access_txt)
+ var/list/req_one_access_str = text2list(req_one_access_txt,";")
+ for(var/x in req_one_access_str)
+ var/n = text2num(x)
+ if(n)
+ req_one_access += n
- if(!src.req_access && !src.req_one_access) //no requirements
- return 1
if(!istype(src.req_access, /list)) //something's very wrong
return 1
@@ -440,10 +433,10 @@
rank = src:rank
assignment = src:assignment
- if( rank in get_all_jobs() )
+ if( rank in joblist )
return rank
- if( assignment in get_all_jobs() )
+ if( assignment in joblist )
return assignment
return "Unknown"
@@ -496,7 +489,7 @@ proc/FindNameFromID(var/mob/living/carbon/human/H)
return ID.registered_name
proc/get_all_job_icons() //For all existing HUD icons
- return get_all_jobs() + list("Prisoner")
+ return joblist + list("Prisoner")
/obj/proc/GetJobName() //Used in secHUD icon generation
if (!istype(src, /obj/item/device/pda) && !istype(src,/obj/item/weapon/card/id))
diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm
index ec7028d99c..acc7c3e853 100644
--- a/code/game/jobs/job/captain.dm
+++ b/code/game/jobs/job/captain.dm
@@ -21,7 +21,8 @@
if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
var/obj/item/clothing/under/U = new /obj/item/clothing/under/rank/captain(H)
- U.hastie = new /obj/item/clothing/tie/medal/gold/captain(U)
+ if(H.age>49)
+ U.hastie = new /obj/item/clothing/tie/medal/gold/captain(U)
H.equip_to_slot_or_del(U, slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/device/pda/captain(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes)
diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm
index 7e3d8c215a..d8192c5096 100644
--- a/code/game/jobs/job/civilian.dm
+++ b/code/game/jobs/job/civilian.dm
@@ -19,7 +19,6 @@
if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), slot_shoes)
- H.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/bartender(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/device/pda/bar(H), slot_belt)
@@ -92,7 +91,9 @@
H.equip_to_slot_or_del(new /obj/item/clothing/suit/apron(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/device/analyzer/plant_analyzer(H), slot_s_store)
H.equip_to_slot_or_del(new /obj/item/device/pda/botanist(H), slot_belt)
- if(H.backbag == 1)
+ if(H.backbag == 3)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_hyd(H), slot_back)
+ else if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
@@ -362,4 +363,4 @@
var/datum/organ/external/affected = H.organs_by_name["head"]
affected.implants += L
L.part = affected
- return 1
+ return 1
diff --git a/code/game/jobs/job/civilian_chaplain.dm b/code/game/jobs/job/civilian_chaplain.dm
index 84360efe58..d7b4b1f96c 100644
--- a/code/game/jobs/job/civilian_chaplain.dm
+++ b/code/game/jobs/job/civilian_chaplain.dm
@@ -51,9 +51,9 @@
B.name = "Toolbox Manifesto"
if("homosexuality")
B.name = "Guys Gone Wild"
- if("lol", "wtf", "gay", "penis", "ass", "poo", "badmin", "shitmin", "deadmin", "cock", "cocks")
- B.name = pick("Woodys Got Wood: The Aftermath", "War of the Cocks", "Sweet Bro and Hella Jef: Expanded Edition")
- H.setBrainLoss(100) // starts off retarded as fuck
+ //if("lol", "wtf", "gay", "penis", "ass", "poo", "badmin", "shitmin", "deadmin", "cock", "cocks")
+ // B.name = pick("Woodys Got Wood: The Aftermath", "War of the Cocks", "Sweet Bro and Hella Jef: Expanded Edition")
+ // H.setBrainLoss(100) // starts off retarded as fuck
if("science")
B.name = pick("Principle of Relativity", "Quantum Enigma: Physics Encounters Consciousness", "Programming the Universe", "Quantum Physics and Theology", "String Theory for Dummies", "How To: Build Your Own Warp Drive", "The Mysteries of Bluespace", "Playing God: Collector's Edition")
else
@@ -152,4 +152,4 @@
ticker.Bible_deity_name = B.deity_name
feedback_set_details("religion_deity","[new_deity]")
feedback_set_details("religion_book","[new_book_style]")
- return 1
\ No newline at end of file
+ return 1
diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm
index 1303976b13..d8a60f7b12 100644
--- a/code/game/jobs/job/medical.dm
+++ b/code/game/jobs/job/medical.dm
@@ -15,7 +15,7 @@
minimal_access = list(access_medical, access_morgue, access_genetics, access_heads,
access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce,
access_keycard_auth, access_sec_doors, access_psychiatrist)
- minimal_player_age = 7
+ minimal_player_age = 10
equip(var/mob/living/carbon/human/H)
if(!H) return 0
@@ -71,6 +71,8 @@
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/virologist(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/virologist(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(H), slot_wear_mask)
+ if(H.backbag == 3)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_vir(H), slot_back)
if("Medical Doctor")
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit)
@@ -120,7 +122,9 @@
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/device/pda/chemist(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/chemist(H), slot_wear_suit)
- if(H.backbag == 1)
+ if(H.backbag == 3)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_chem(H), slot_back)
+ else if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
@@ -133,8 +137,8 @@
flag = GENETICIST
department_flag = MEDSCI
faction = "Station"
- total_positions = 2
- spawn_positions = 2
+ total_positions = 0
+ spawn_positions = 0
supervisors = "the chief medical officer and research director"
selection_color = "#ffeef0"
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics, access_research)
@@ -149,7 +153,9 @@
H.equip_to_slot_or_del(new /obj/item/device/pda/geneticist(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/genetics(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/device/flashlight/pen(H), slot_s_store)
- if(H.backbag == 1)
+ if(H.backbag == 3)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_gen(H), slot_back)
+ else if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm
index c4c117b260..385b3fadbc 100644
--- a/code/game/jobs/job/science.dm
+++ b/code/game/jobs/job/science.dm
@@ -27,7 +27,9 @@
H.equip_to_slot_or_del(new /obj/item/device/pda/heads/rd(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/weapon/clipboard(H), slot_l_hand)
- if(H.backbag == 1)
+ if(H.backbag == 3)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
+ else if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
@@ -46,16 +48,18 @@
selection_color = "#ffeeff"
access = list(access_robotics, access_tox, access_tox_storage, access_research, access_xenobiology, access_xenoarch)
minimal_access = list(access_tox, access_tox_storage, access_research, access_xenoarch)
- alt_titles = list("Xenoarcheologist", "Anomalist", "Plasma Researcher")
+ alt_titles = list("Xenoarcheologist", "Anomalist", "Phoron Researcher")
equip(var/mob/living/carbon/human/H)
if(!H) return 0
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sci(H), slot_l_ear)
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/scientist(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes)
- H.equip_to_slot_or_del(new /obj/item/device/pda/toxins(H), slot_belt)
+ H.equip_to_slot_or_del(new /obj/item/device/pda/science(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/science(H), slot_wear_suit)
- if(H.backbag == 1)
+ if(H.backbag == 3)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
+ else if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
@@ -80,9 +84,11 @@
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sci(H), slot_l_ear)
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/scientist(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes)
- H.equip_to_slot_or_del(new /obj/item/device/pda/toxins(H), slot_belt)
+ H.equip_to_slot_or_del(new /obj/item/device/pda/science(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/science(H), slot_wear_suit)
- if(H.backbag == 1)
+ if(H.backbag == 3)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
+ else if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm
index 4d0488f122..69e9babb0a 100644
--- a/code/game/jobs/job/security.dm
+++ b/code/game/jobs/job/security.dm
@@ -60,7 +60,7 @@
selection_color = "#ffeeee"
access = list(access_security, access_sec_doors, access_brig, access_armory, access_court, access_maint_tunnels, access_morgue)
minimal_access = list(access_security, access_sec_doors, access_brig, access_armory, access_court, access_maint_tunnels)
- minimal_player_age = 7
+ minimal_player_age = 5
equip(var/mob/living/carbon/human/H)
if(!H) return 0
@@ -100,7 +100,7 @@
access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court)
minimal_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court)
alt_titles = list("Forensic Technician")
- minimal_player_age = 7
+ minimal_player_age = 3
equip(var/mob/living/carbon/human/H)
if(!H) return 0
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sec(H), slot_l_ear)
@@ -146,7 +146,7 @@
selection_color = "#ffeeee"
access = list(access_security, access_sec_doors, access_brig, access_court, access_maint_tunnels, access_morgue)
minimal_access = list(access_security, access_sec_doors, access_brig, access_court, access_maint_tunnels)
- minimal_player_age = 7
+ minimal_player_age = 3
equip(var/mob/living/carbon/human/H)
if(!H) return 0
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sec(H), slot_l_ear)
diff --git a/code/game/jobs/job/silicon.dm b/code/game/jobs/job/silicon.dm
index f1a0fd2e26..5e067d8556 100644
--- a/code/game/jobs/job/silicon.dm
+++ b/code/game/jobs/job/silicon.dm
@@ -8,7 +8,7 @@
selection_color = "#ccffcc"
supervisors = "your laws"
req_admin_notify = 1
- minimal_player_age = 30
+ minimal_player_age = 7
equip(var/mob/living/carbon/human/H)
if(!H) return 0
@@ -25,7 +25,7 @@
spawn_positions = 2
supervisors = "your laws and the AI" //Nodrak
selection_color = "#ddffdd"
- minimal_player_age = 21
+ minimal_player_age = 1
alt_titles = list("Android", "Robot")
equip(var/mob/living/carbon/human/H)
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index 95a6ec439b..83603ce838 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -67,7 +67,7 @@ var/global/datum/controller/occupations/job_master
proc/FreeRole(var/rank) //making additional slot on the fly
var/datum/job/job = GetJob(rank)
- if(job && job.current_positions >= job.total_positions)
+ if(job && job.current_positions >= job.total_positions && job.total_positions != -1)
job.total_positions++
return 1
return 0
@@ -439,6 +439,10 @@ var/global/datum/controller/occupations/job_master
var/obj/item/clothing/glasses/G = H.glasses
G.prescription = 1
// H.update_icons()
+
+ H.hud_updateflag |= (1 << ID_HUD)
+ H.hud_updateflag |= (1 << IMPLOYAL_HUD)
+ H.hud_updateflag |= (1 << SPECIALROLE_HUD)
return 1
diff --git a/code/game/jobs/whitelist.dm b/code/game/jobs/whitelist.dm
index 98efaf9273..2aaad4bde6 100644
--- a/code/game/jobs/whitelist.dm
+++ b/code/game/jobs/whitelist.dm
@@ -26,7 +26,7 @@ var/list/whitelist = list()
/proc/load_alienwhitelist()
var/text = file2text("config/alienwhitelist.txt")
if (!text)
- diary << "Failed to load config/alienwhitelist.txt\n"
+ log_misc("Failed to load config/alienwhitelist.txt")
else
alien_whitelist = text2list(text, "\n")
@@ -36,6 +36,8 @@ var/list/whitelist = list()
return 1
if(species == "human" || species == "Human")
return 1
+ if(species == "machine" || species == "Machine")
+ return 1
if(check_rights(R_ADMIN, 0))
return 1
if(!alien_whitelist)
@@ -49,4 +51,4 @@ var/list/whitelist = list()
return 0
-#undef WHITELISTFILE
\ No newline at end of file
+#undef WHITELISTFILE
diff --git a/code/game/machinery/Freezer.dm b/code/game/machinery/Freezer.dm
index 319c7a8900..7de58c6f22 100644
--- a/code/game/machinery/Freezer.dm
+++ b/code/game/machinery/Freezer.dm
@@ -1,5 +1,5 @@
/obj/machinery/atmospherics/unary/cold_sink/freezer
- name = "Freezer"
+ name = "gas cooling system"
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "freezer_0"
density = 1
@@ -8,84 +8,91 @@
current_heat_capacity = 1000
- New()
- ..()
- initialize_directions = dir
+/obj/machinery/atmospherics/unary/cold_sink/freezer/New()
+ ..()
+ initialize_directions = dir
- initialize()
- if(node) return
+/obj/machinery/atmospherics/unary/cold_sink/freezer/initialize()
+ if(node) return
- var/node_connect = dir
-
- for(var/obj/machinery/atmospherics/target in get_step(src,node_connect))
- if(target.initialize_directions & get_dir(target,src))
- node = target
- break
-
- update_icon()
+ var/node_connect = dir
+ for(var/obj/machinery/atmospherics/target in get_step(src,node_connect))
+ if(target.initialize_directions & get_dir(target,src))
+ node = target
+ break
update_icon()
- if(src.node)
- if(src.on)
- icon_state = "freezer_1"
- else
- icon_state = "freezer"
+
+
+/obj/machinery/atmospherics/unary/cold_sink/freezer/update_icon()
+ if(src.node)
+ if(src.on)
+ icon_state = "freezer_1"
else
- icon_state = "freezer_0"
- return
+ icon_state = "freezer"
+ else
+ icon_state = "freezer_0"
+ return
- attack_ai(mob/user as mob)
- return src.attack_hand(user)
+/obj/machinery/atmospherics/unary/cold_sink/freezer/attack_ai(mob/user as mob)
+ src.ui_interact(user)
- attack_paw(mob/user as mob)
- return src.attack_hand(user)
+/obj/machinery/atmospherics/unary/cold_sink/freezer/attack_paw(mob/user as mob)
+ src.ui_interact(user)
- attack_hand(mob/user as mob)
- user.set_machine(src)
- var/temp_text = ""
- if(air_contents.temperature > (T0C - 20))
- temp_text = "[air_contents.temperature]"
- else if(air_contents.temperature < (T0C - 20) && air_contents.temperature > (T0C - 100))
- temp_text = "[air_contents.temperature]"
+/obj/machinery/atmospherics/unary/cold_sink/freezer/attack_hand(mob/user as mob)
+ src.ui_interact(user)
+
+/obj/machinery/atmospherics/unary/cold_sink/freezer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
+ // this is the data which will be sent to the ui
+ var/data[0]
+ data["on"] = on ? 1 : 0
+ data["gasPressure"] = round(air_contents.return_pressure())
+ data["gasTemperature"] = round(air_contents.temperature)
+ data["minGasTemperature"] = round(T0C - 200)
+ data["maxGasTemperature"] = round(T20C)
+ data["targetGasTemperature"] = round(current_temperature)
+
+ var/temp_class = "good"
+ if (air_contents.temperature > (T0C - 20))
+ temp_class = "bad"
+ else if (air_contents.temperature < (T0C - 20) && air_contents.temperature > (T0C - 100))
+ temp_class = "average"
+ data["gasTemperatureClass"] = temp_class
+
+ // update the ui if it exists, returns null if no ui is passed/found
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
+ if (!ui)
+ // the ui does not exist, so we'll create a new() one
+ // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
+ ui = new(user, src, ui_key, "freezer.tmpl", "Gas Cooling System", 440, 300)
+ // when the ui is first opened this is the data it will use
+ ui.set_initial_data(data)
+ // open the new ui window
+ ui.open()
+ // auto update every Master Controller tick
+ ui.set_auto_update(1)
+
+/obj/machinery/atmospherics/unary/cold_sink/freezer/Topic(href, href_list)
+ if (href_list["toggleStatus"])
+ src.on = !src.on
+ update_icon()
+ if(href_list["temp"])
+ var/amount = text2num(href_list["temp"])
+ if(amount > 0)
+ src.current_temperature = min(T20C, src.current_temperature+amount)
else
- temp_text = "[air_contents.temperature]"
-
- var/dat = {"Cryo gas cooling system
- Current status: [ on ? "OffOn" : "OffOn"]
- Current gas temperature: [temp_text]
- Current air pressure: [air_contents.return_pressure()]
- Target gas temperature: --- [current_temperature] +++
- "}
-
- user << browse(dat, "window=freezer;size=400x500")
- onclose(user, "freezer")
-
- Topic(href, href_list)
- if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai)))
- usr.set_machine(src)
- if (href_list["start"])
- src.on = !src.on
- update_icon()
- if(href_list["temp"])
- var/amount = text2num(href_list["temp"])
- if(amount > 0)
- src.current_temperature = min(T20C, src.current_temperature+amount)
- else
- src.current_temperature = max((T0C - 200), src.current_temperature+amount)
- src.updateUsrDialog()
- src.add_fingerprint(usr)
- return
-
- process()
- ..()
- src.updateUsrDialog()
-
+ src.current_temperature = max((T0C - 200), src.current_temperature+amount)
+ src.add_fingerprint(usr)
+ return 1
+/obj/machinery/atmospherics/unary/cold_sink/freezer/process()
+ ..()
/obj/machinery/atmospherics/unary/heat_reservoir/heater
- name = "Heater"
+ name = "gas heating system"
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "freezer_0"
density = 1
@@ -94,73 +101,83 @@
current_heat_capacity = 1000
- New()
- ..()
- initialize_directions = dir
+/obj/machinery/atmospherics/unary/heat_reservoir/heater/New()
+ ..()
+ initialize_directions = dir
- initialize()
- if(node) return
+/obj/machinery/atmospherics/unary/heat_reservoir/heater/initialize()
+ if(node) return
- var/node_connect = dir
-
- for(var/obj/machinery/atmospherics/target in get_step(src,node_connect))
- if(target.initialize_directions & get_dir(target,src))
- node = target
- break
-
- update_icon()
+ var/node_connect = dir
+ for(var/obj/machinery/atmospherics/target in get_step(src,node_connect))
+ if(target.initialize_directions & get_dir(target,src))
+ node = target
+ break
update_icon()
- if(src.node)
- if(src.on)
- icon_state = "heater_1"
- else
- icon_state = "heater"
+
+
+/obj/machinery/atmospherics/unary/heat_reservoir/heater/update_icon()
+ if(src.node)
+ if(src.on)
+ icon_state = "heater_1"
else
- icon_state = "heater_0"
- return
+ icon_state = "heater"
+ else
+ icon_state = "heater_0"
+ return
- attack_ai(mob/user as mob)
- return src.attack_hand(user)
+/obj/machinery/atmospherics/unary/heat_reservoir/heater/attack_ai(mob/user as mob)
+ src.ui_interact(user)
- attack_paw(mob/user as mob)
- return src.attack_hand(user)
+/obj/machinery/atmospherics/unary/heat_reservoir/heater/attack_paw(mob/user as mob)
+ src.ui_interact(user)
- attack_hand(mob/user as mob)
- user.set_machine(src)
- var/temp_text = ""
- if(air_contents.temperature > (T20C+40))
- temp_text = "[air_contents.temperature]"
+/obj/machinery/atmospherics/unary/heat_reservoir/heater/attack_hand(mob/user as mob)
+ src.ui_interact(user)
+
+/obj/machinery/atmospherics/unary/heat_reservoir/heater/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
+ // this is the data which will be sent to the ui
+ var/data[0]
+ data["on"] = on ? 1 : 0
+ data["gasPressure"] = round(air_contents.return_pressure())
+ data["gasTemperature"] = round(air_contents.temperature)
+ data["minGasTemperature"] = round(T20C)
+ data["maxGasTemperature"] = round(T20C+280)
+ data["targetGasTemperature"] = round(current_temperature)
+
+ var/temp_class = "normal"
+ if (air_contents.temperature > (T20C+40))
+ temp_class = "bad"
+ data["gasTemperatureClass"] = temp_class
+
+ // update the ui if it exists, returns null if no ui is passed/found
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
+ if (!ui)
+ // the ui does not exist, so we'll create a new() one
+ // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
+ ui = new(user, src, ui_key, "freezer.tmpl", "Gas Heating System", 440, 300)
+ // when the ui is first opened this is the data it will use
+ ui.set_initial_data(data)
+ // open the new ui window
+ ui.open()
+ // auto update every Master Controller tick
+ ui.set_auto_update(1)
+
+/obj/machinery/atmospherics/unary/heat_reservoir/heater/Topic(href, href_list)
+ if (href_list["toggleStatus"])
+ src.on = !src.on
+ update_icon()
+ if(href_list["temp"])
+ var/amount = text2num(href_list["temp"])
+ if(amount > 0)
+ src.current_temperature = min((T20C+280), src.current_temperature+amount)
else
- temp_text = "[air_contents.temperature]"
+ src.current_temperature = max(T20C, src.current_temperature+amount)
+
+ src.add_fingerprint(usr)
+ return 1
- var/dat = {"Heating system
- Current status: [ on ? "OffOn" : "OffOn"]
- Current gas temperature: [temp_text]
- Current air pressure: [air_contents.return_pressure()]
- Target gas temperature: --- [current_temperature] +++
- "}
-
- user << browse(dat, "window=heater;size=400x500")
- onclose(user, "heater")
-
- Topic(href, href_list)
- if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai)))
- usr.set_machine(src)
- if (href_list["start"])
- src.on = !src.on
- update_icon()
- if(href_list["temp"])
- var/amount = text2num(href_list["temp"])
- if(amount > 0)
- src.current_temperature = min((T20C+280), src.current_temperature+amount)
- else
- src.current_temperature = max(T20C, src.current_temperature+amount)
- src.updateUsrDialog()
- src.add_fingerprint(usr)
- return
-
- process()
- ..()
- src.updateUsrDialog()
\ No newline at end of file
+/obj/machinery/atmospherics/unary/heat_reservoir/heater/process()
+ ..()
\ No newline at end of file
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index 4b2fb50c54..c400185a45 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -181,10 +181,12 @@
return
return
+/*
+
/obj/machinery/body_scanconsole/process() //not really used right now
if(stat & (NOPOWER|BROKEN))
return
- use_power(250) // power stuff
+ //use_power(250) // power stuff
// var/mob/M //occupant
// if (!( src.status )) //remove this
@@ -200,6 +202,8 @@
// src.updateDialog()
// return
+*/
+
/obj/machinery/body_scanconsole/attack_paw(user as mob)
return src.attack_hand(user)
@@ -250,6 +254,9 @@
dat += text("Paralysis Summary %: [] ([] seconds left!) ", occupant.paralysis, round(occupant.paralysis / 4))
dat += text("Body Temperature: [occupant.bodytemperature-T0C]°C ([occupant.bodytemperature*1.8-459.67]°F) ")
+ if(occupant.has_brain_worms())
+ dat += "Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended. "
+
if(occupant.vessel)
var/blood_volume = round(occupant.vessel.get_reagent_amount("blood"))
var/blood_percent = blood_volume / 560
@@ -275,6 +282,7 @@
dat += ""
for(var/datum/organ/external/e in occupant.organs)
+
dat += "
"
var/AN = ""
var/open = ""
@@ -300,13 +308,15 @@
robot = "Prosthetic:"
if(e.open)
open = "Open:"
+
var/unknown_body = 0
for(var/I in e.implants)
if(is_type_in_list(I,known_implants))
imp += "[I] implanted:"
else
unknown_body++
- if(unknown_body)
+
+ if(unknown_body || e.hidden)
imp += "Unknown body present:"
if(!AN && !open && !infected & !imp)
AN = "None:"
diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/airlock_control.dm
index ae60ec8cb3..a5de183a92 100644
--- a/code/game/machinery/airlock_control.dm
+++ b/code/game/machinery/airlock_control.dm
@@ -90,7 +90,7 @@ obj/machinery/door/airlock/Bumped(atom/AM)
radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK)
return
-
+
obj/machinery/door/airlock/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
if(new_frequency)
@@ -124,13 +124,14 @@ obj/machinery/airlock_sensor
var/id_tag
var/master_tag
- var/frequency = 1449
+ var/frequency = 1379
+ var/command = "cycle"
var/datum/radio_frequency/radio_connection
var/on = 1
var/alert = 0
-
+ var/previousPressure
obj/machinery/airlock_sensor/update_icon()
if(on)
@@ -145,28 +146,30 @@ obj/machinery/airlock_sensor/attack_hand(mob/user)
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.data["tag"] = master_tag
- signal.data["command"] = "cycle"
+ signal.data["command"] = command
radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK)
flick("airlock_sensor_cycle", src)
obj/machinery/airlock_sensor/process()
if(on)
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.data["tag"] = id_tag
- signal.data["timestamp"] = world.time
-
var/datum/gas_mixture/air_sample = return_air()
-
var/pressure = round(air_sample.return_pressure(),0.1)
- alert = (pressure < ONE_ATMOSPHERE*0.8)
- signal.data["pressure"] = num2text(pressure)
+ if(abs(pressure - previousPressure) > 0.001 || previousPressure == null)
+ var/datum/signal/signal = new
+ signal.transmission_method = 1 //radio signal
+ signal.data["tag"] = id_tag
+ signal.data["timestamp"] = world.time
+ signal.data["pressure"] = num2text(pressure)
- radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK)
+ radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK)
- update_icon()
+ previousPressure = pressure
+
+ alert = (pressure < ONE_ATMOSPHERE*0.8)
+
+ update_icon()
obj/machinery/airlock_sensor/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
@@ -178,12 +181,15 @@ obj/machinery/airlock_sensor/initialize()
obj/machinery/airlock_sensor/New()
..()
-
if(radio_controller)
set_frequency(frequency)
+obj/machinery/airlock_sensor/airlock_interior
+ command = "cycle_interior"
+obj/machinery/airlock_sensor/airlock_exterior
+ command = "cycle_exterior"
obj/machinery/access_button
icon = 'icons/obj/airlock_machines.dmi'
@@ -238,4 +244,12 @@ obj/machinery/access_button/New()
..()
if(radio_controller)
- set_frequency(frequency)
\ No newline at end of file
+ set_frequency(frequency)
+
+obj/machinery/access_button/airlock_interior
+ frequency = 1379
+ command = "cycle_interior"
+
+obj/machinery/access_button/airlock_exterior
+ frequency = 1379
+ command = "cycle_exterior"
\ No newline at end of file
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index f2a069c454..726de7ad81 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -103,7 +103,7 @@
req_access = list(access_rd, access_atmospherics, access_engine_equip)
TLV["oxygen"] = list(-1.0, -1.0,-1.0,-1.0) // Partial pressure, kpa
TLV["carbon dioxide"] = list(-1.0, -1.0, 5, 10) // Partial pressure, kpa
- TLV["plasma"] = list(-1.0, -1.0, 0.2, 0.5) // Partial pressure, kpa
+ TLV["phoron"] = list(-1.0, -1.0, 0.2, 0.5) // Partial pressure, kpa
TLV["other"] = list(-1.0, -1.0, 0.5, 1.0) // Partial pressure, kpa
TLV["pressure"] = list(0,ONE_ATMOSPHERE*0.10,ONE_ATMOSPHERE*1.40,ONE_ATMOSPHERE*1.60) /* kpa */
TLV["temperature"] = list(20, 40, 140, 160) // K
@@ -143,7 +143,7 @@
// breathable air according to human/Life()
TLV["oxygen"] = list(16, 19, 135, 140) // Partial pressure, kpa
TLV["carbon dioxide"] = list(-1.0, -1.0, 5, 10) // Partial pressure, kpa
- TLV["plasma"] = list(-1.0, -1.0, 0.2, 0.5) // Partial pressure, kpa
+ TLV["phoron"] = list(-1.0, -1.0, 0.2, 0.5) // Partial pressure, kpa
TLV["other"] = list(-1.0, -1.0, 0.5, 1.0) // Partial pressure, kpa
TLV["pressure"] = list(ONE_ATMOSPHERE*0.80,ONE_ATMOSPHERE*0.90,ONE_ATMOSPHERE*1.10,ONE_ATMOSPHERE*1.20) /* kpa */
TLV["temperature"] = list(T0C-26, T0C, T0C+40, T0C+66) // K
@@ -183,24 +183,25 @@
var/datum/gas_mixture/gas
gas = location.remove_air(0.25*environment.total_moles)
- var/heat_capacity = gas.heat_capacity()
- var/energy_used = min( abs( heat_capacity*(gas.temperature - target_temperature) ), MAX_ENERGY_CHANGE)
+ if(gas)
+ var/heat_capacity = gas.heat_capacity()
+ var/energy_used = min( abs( heat_capacity*(gas.temperature - target_temperature) ), MAX_ENERGY_CHANGE)
- //Use power. Assuming that each power unit represents 1000 watts....
- use_power(energy_used/1000, ENVIRON)
+ //Use power. Assuming that each power unit represents 1 watts....
+ use_power(energy_used, ENVIRON)
- //We need to cool ourselves.
- if(environment.temperature > target_temperature)
- gas.temperature -= energy_used/heat_capacity
- else
- gas.temperature += energy_used/heat_capacity
+ //We need to cool ourselves.
+ if(environment.temperature > target_temperature)
+ gas.temperature -= energy_used/heat_capacity
+ else
+ gas.temperature += energy_used/heat_capacity
- environment.merge(gas)
+ environment.merge(gas)
- if(abs(environment.temperature - target_temperature) <= 0.5)
- regulating_temperature = 0
- visible_message("\The [src] clicks quietly as it stops [environment.temperature > target_temperature ? "cooling" : "heating"] the room.",\
- "You hear a click as a faint electronic humming stops.")
+ if(abs(environment.temperature - target_temperature) <= 0.5)
+ regulating_temperature = 0
+ visible_message("\The [src] clicks quietly as it stops [environment.temperature > target_temperature ? "cooling" : "heating"] the room.",\
+ "You hear a click as a faint electronic humming stops.")
var/old_level = danger_level
danger_level = overall_danger_level()
@@ -244,7 +245,7 @@
var/pressure_dangerlevel = get_danger_level(environment_pressure, TLV["pressure"])
var/oxygen_dangerlevel = get_danger_level(environment.oxygen*partial_pressure, TLV["oxygen"])
var/co2_dangerlevel = get_danger_level(environment.carbon_dioxide*partial_pressure, TLV["carbon dioxide"])
- var/plasma_dangerlevel = get_danger_level(environment.toxins*partial_pressure, TLV["plasma"])
+ var/phoron_dangerlevel = get_danger_level(environment.phoron*partial_pressure, TLV["phoron"])
var/temperature_dangerlevel = get_danger_level(environment.temperature, TLV["temperature"])
var/other_dangerlevel = get_danger_level(other_moles*partial_pressure, TLV["other"])
@@ -252,7 +253,7 @@
pressure_dangerlevel,
oxygen_dangerlevel,
co2_dangerlevel,
- plasma_dangerlevel,
+ phoron_dangerlevel,
other_dangerlevel,
temperature_dangerlevel
)
@@ -699,7 +700,7 @@
/obj/machinery/alarm/proc/return_status()
var/turf/location = get_turf(src)
var/datum/gas_mixture/environment = location.return_air()
- var/total = environment.oxygen + environment.carbon_dioxide + environment.toxins + environment.nitrogen
+ var/total = environment.oxygen + environment.carbon_dioxide + environment.phoron + environment.nitrogen
var/output = "Air Status: "
if(total == 0)
@@ -728,9 +729,9 @@
var/co2_dangerlevel = get_danger_level(environment.carbon_dioxide*partial_pressure, current_settings)
var/co2_percent = round(environment.carbon_dioxide / total * 100, 2)
- current_settings = TLV["plasma"]
- var/plasma_dangerlevel = get_danger_level(environment.toxins*partial_pressure, current_settings)
- var/plasma_percent = round(environment.toxins / total * 100, 2)
+ current_settings = TLV["phoron"]
+ var/phoron_dangerlevel = get_danger_level(environment.phoron*partial_pressure, current_settings)
+ var/phoron_percent = round(environment.phoron / total * 100, 2)
current_settings = TLV["other"]
var/other_moles = 0.0
@@ -745,7 +746,7 @@
Pressure: [environment_pressure]kPa
Oxygen: [oxygen_percent]%
Carbon dioxide: [co2_percent]%
-Toxins: [plasma_percent]%
+Toxins: [phoron_percent]%
"}
if (other_dangerlevel==2)
output += "Notice: High Concentration of Unknown Particles Detected "
@@ -756,7 +757,7 @@ Toxins: [plasma_percent]%
//Overall status
output += "Local Status: "
- switch(max(pressure_dangerlevel,oxygen_dangerlevel,co2_dangerlevel,plasma_dangerlevel,other_dangerlevel,temperature_dangerlevel))
+ switch(max(pressure_dangerlevel,oxygen_dangerlevel,co2_dangerlevel,phoron_dangerlevel,other_dangerlevel,temperature_dangerlevel))
if(2)
output += "DANGER: Internals Required"
if(1)
@@ -880,7 +881,7 @@ siphoning
Carbon Dioxide
[data["filter_co2"]?"on":"off"];
Toxins
-[data["filter_toxins"]?"on":"off"];
+[data["filter_phoron"]?"on":"off"];
Nitrous Oxide
[data["filter_n2o"]?"on":"off"]
@@ -929,7 +930,7 @@ table tr:first-child th:first-child { border: none;}
var/list/gases = list(
"oxygen" = "O2",
"carbon dioxide" = "CO2",
- "plasma" = "Toxin",
+ "phoron" = "Toxin",
"other" = "Other",)
var/list/selected
@@ -1683,4 +1684,4 @@ Code shamelessly copied from apc_frame
else
usr << browse(null, "window=partyalarm")
return
- return
\ No newline at end of file
+ return
diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm
index 81074ca235..d803f49657 100644
--- a/code/game/machinery/atmo_control.dm
+++ b/code/game/machinery/atmo_control.dm
@@ -16,7 +16,7 @@ obj/machinery/air_sensor
// 2 for temperature
// Output >= 4 includes gas composition
// 4 for oxygen concentration
- // 8 for toxins concentration
+ // 8 for phoron concentration
// 16 for nitrogen concentration
// 32 for carbon dioxide concentration
@@ -45,14 +45,14 @@ obj/machinery/air_sensor
if(output&4)
signal.data["oxygen"] = round(100*air_sample.oxygen/total_moles,0.1)
if(output&8)
- signal.data["toxins"] = round(100*air_sample.toxins/total_moles,0.1)
+ signal.data["phoron"] = round(100*air_sample.phoron/total_moles,0.1)
if(output&16)
signal.data["nitrogen"] = round(100*air_sample.nitrogen/total_moles,0.1)
if(output&32)
signal.data["carbon_dioxide"] = round(100*air_sample.carbon_dioxide/total_moles,0.1)
else
signal.data["oxygen"] = 0
- signal.data["toxins"] = 0
+ signal.data["phoron"] = 0
signal.data["nitrogen"] = 0
signal.data["carbon_dioxide"] = 0
signal.data["sigtype"]="status"
@@ -151,7 +151,7 @@ obj/machinery/computer/general_air_control
sensor_part += " Pressure: [data["pressure"]] kPa "
if(data["temperature"])
sensor_part += " Temperature: [data["temperature"]] K "
- if(data["oxygen"]||data["toxins"]||data["nitrogen"]||data["carbon_dioxide"])
+ if(data["oxygen"]||data["phoron"]||data["nitrogen"]||data["carbon_dioxide"])
sensor_part += " Gas Composition :"
if(data["oxygen"])
sensor_part += "[data["oxygen"]]% O2; "
@@ -159,8 +159,8 @@ obj/machinery/computer/general_air_control
sensor_part += "[data["nitrogen"]]% N; "
if(data["carbon_dioxide"])
sensor_part += "[data["carbon_dioxide"]]% CO2; "
- if(data["toxins"])
- sensor_part += "[data["toxins"]]% TX; "
+ if(data["phoron"])
+ sensor_part += "[data["phoron"]]% TX; "
sensor_part += ""
else
diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm
index 1d5f210dd3..f6d12ea4c7 100644
--- a/code/game/machinery/atmoalter/canister.dm
+++ b/code/game/machinery/atmoalter/canister.dm
@@ -17,6 +17,7 @@
volume = 1000
use_power = 0
var/release_log = ""
+ var/update_flag = 0
/obj/machinery/portable_atmospherics/canister/sleeping_agent
name = "Canister: \[N2O\]"
@@ -33,8 +34,8 @@
icon_state = "blue"
canister_color = "blue"
can_label = 0
-/obj/machinery/portable_atmospherics/canister/toxins
- name = "Canister \[Toxin (Bio)\]"
+/obj/machinery/portable_atmospherics/canister/phoron
+ name = "Canister \[Phoron\]"
icon_state = "orange"
canister_color = "orange"
can_label = 0
@@ -49,30 +50,64 @@
canister_color = "grey"
can_label = 0
+/obj/machinery/portable_atmospherics/canister/proc/check_change()
+ var/old_flag = update_flag
+ update_flag = 0
+ if(holding)
+ update_flag |= 1
+ if(connected_port)
+ update_flag |= 2
+
+ var/tank_pressure = air_contents.return_pressure()
+ if(tank_pressure < 10)
+ update_flag |= 4
+ else if(tank_pressure < ONE_ATMOSPHERE)
+ update_flag |= 8
+ else if(tank_pressure < 15*ONE_ATMOSPHERE)
+ update_flag |= 16
+ else
+ update_flag |= 32
+
+ if(update_flag == old_flag)
+ return 1
+ else
+ return 0
+
/obj/machinery/portable_atmospherics/canister/update_icon()
- src.overlays = 0
+/*
+update_flag
+1 = holding
+2 = connected_port
+4 = tank_pressure < 10
+8 = tank_pressure < ONE_ATMOS
+16 = tank_pressure < 15*ONE_ATMOS
+32 = tank_pressure go boom.
+*/
if (src.destroyed)
+ src.overlays = 0
src.icon_state = text("[]-1", src.canister_color)
- else
+ if(icon_state != "[canister_color]")
icon_state = "[canister_color]"
- if(holding)
- overlays += "can-open"
+
+ if(check_change()) //Returns 1 if no change needed to icons.
+ return
- if(connected_port)
- overlays += "can-connector"
+ src.overlays = 0
- var/tank_pressure = air_contents.return_pressure()
-
- if (tank_pressure < 10)
- overlays += image('icons/obj/atmos.dmi', "can-o0")
- else if (tank_pressure < ONE_ATMOSPHERE)
- overlays += image('icons/obj/atmos.dmi', "can-o1")
- else if (tank_pressure < 15*ONE_ATMOSPHERE)
- overlays += image('icons/obj/atmos.dmi', "can-o2")
- else
- overlays += image('icons/obj/atmos.dmi', "can-o3")
+ if(update_flag & 1)
+ overlays += "can-open"
+ if(update_flag & 2)
+ overlays += "can-connector"
+ if(update_flag & 4)
+ overlays += "can-o0"
+ if(update_flag & 8)
+ overlays += "can-o1"
+ else if(update_flag & 16)
+ overlays += "can-o2"
+ else if(update_flag & 32)
+ overlays += "can-o3"
return
/obj/machinery/portable_atmospherics/canister/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
@@ -136,10 +171,8 @@
else
can_label = 0
- if(air_contents.temperature > PLASMA_FLASHPOINT)
+ if(air_contents.temperature > PHORON_FLASHPOINT)
air_contents.zburn()
-
- src.updateDialog()
return
/obj/machinery/portable_atmospherics/canister/return_air()
@@ -194,6 +227,10 @@
return
..()
+
+ nanomanager.update_uis(src) // Update all NanoUIs attached to src
+
+
/obj/machinery/portable_atmospherics/canister/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
@@ -202,98 +239,100 @@
return src.attack_hand(user)
/obj/machinery/portable_atmospherics/canister/attack_hand(var/mob/user as mob)
- return src.interact(user)
+ return src.ui_interact(user)
-/obj/machinery/portable_atmospherics/canister/interact(var/mob/user as mob)
+/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
if (src.destroyed)
return
- user.set_machine(src)
- var/holding_text
- if(holding)
- holding_text = {" Tank Pressure: [holding.air_contents.return_pressure()] KPa
-Remove Tank
-"}
- var/output_text = {"[name][can_label?" relabel":""]
-Pressure: [air_contents.return_pressure()] KPa
-Port Status: [(connected_port)?("Connected"):("Disconnected")]
-[holding_text]
-
-Release Valve: [valve_open?("Open"):("Closed")]
-Release Pressure: ---- [release_pressure] ++++
-
-Close
-"}
+ // this is the data which will be sent to the ui
+ var/data[0]
+ data["name"] = name
+ data["canLabel"] = can_label ? 1 : 0
+ data["portConnected"] = connected_port ? 1 : 0
+ data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
+ data["releasePressure"] = round(release_pressure ? release_pressure : 0)
+ data["minReleasePressure"] = round(ONE_ATMOSPHERE/10)
+ data["maxReleasePressure"] = round(10*ONE_ATMOSPHERE)
+ data["valveOpen"] = valve_open ? 1 : 0
+
+ data["hasHoldingTank"] = holding ? 1 : 0
+ if (holding)
+ data["holdingTank"] = list("name" = holding.name, "tankPressure" = round(holding.air_contents.return_pressure()))
- user << browse("[src][output_text]", "window=canister;size=600x300")
- onclose(user, "canister")
- return
+ // update the ui if it exists, returns null if no ui is passed/found
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
+ if (!ui)
+ // the ui does not exist, so we'll create a new() one
+ // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
+ ui = new(user, src, ui_key, "canister.tmpl", "Canister", 480, 400)
+ // when the ui is first opened this is the data it will use
+ ui.set_initial_data(data)
+ // open the new ui window
+ ui.open()
+ // auto update every Master Controller tick
+ ui.set_auto_update(1)
/obj/machinery/portable_atmospherics/canister/Topic(href, href_list)
- //Do not use "if(..()) return" here, canisters will stop working in unpowered areas like space or on the derelict.
- if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
- usr << browse(null, "window=canister")
- onclose(usr, "canister")
- return
-
- if (((get_dist(src, usr) <= 1) && istype(src.loc, /turf)))
- usr.set_machine(src)
-
- if(href_list["toggle"])
- if (valve_open)
- if (holding)
- release_log += "Valve was closed by [usr], stopping the transfer into the [holding] "
- else
- release_log += "Valve was closed by [usr], stopping the transfer into the air "
+ //Do not use "if(..()) return" here, canisters will stop working in unpowered areas like space or on the derelict.
+ if (!istype(src.loc, /turf))
+ return 0
+
+ if(href_list["toggle"])
+ if (valve_open)
+ if (holding)
+ release_log += "Valve was closed by [usr] ([usr.ckey]), stopping the transfer into the [holding] "
else
- if (holding)
- release_log += "Valve was opened by [usr], starting the transfer into the [holding] "
- else
- release_log += "Valve was opened by [usr], starting the transfer into the air "
- valve_open = !valve_open
-
- if (href_list["remove_tank"])
- if(holding)
- holding.loc = loc
- holding = null
-
- if (href_list["pressure_adj"])
- var/diff = text2num(href_list["pressure_adj"])
- if(diff > 0)
- release_pressure = min(10*ONE_ATMOSPHERE, release_pressure+diff)
+ release_log += "Valve was closed by [usr] ([usr.ckey]), stopping the transfer into the air "
+ else
+ if (holding)
+ release_log += "Valve was opened by [usr] ([usr.ckey]), starting the transfer into the [holding] "
else
- release_pressure = max(ONE_ATMOSPHERE/10, release_pressure+diff)
+ release_log += "Valve was opened by [usr] ([usr.ckey]), starting the transfer into the air "
+ valve_open = !valve_open
- if (href_list["relabel"])
- if (can_label)
- var/list/colors = list(\
- "\[N2O\]" = "redws", \
- "\[N2\]" = "red", \
- "\[O2\]" = "blue", \
- "\[Toxin (Bio)\]" = "orange", \
- "\[CO2\]" = "black", \
- "\[Air\]" = "grey", \
- "\[CAUTION\]" = "yellow", \
- )
- var/label = input("Choose canister label", "Gas canister") as null|anything in colors
- if (label)
- src.canister_color = colors[label]
- src.icon_state = colors[label]
- src.name = "Canister: [label]"
- src.updateUsrDialog()
- src.add_fingerprint(usr)
- update_icon()
- else
- usr << browse(null, "window=canister")
- return
- return
+ if (href_list["remove_tank"])
+ if(holding)
+ if(istype(holding, /obj/item/weapon/tank))
+ holding.manipulated_by = usr.real_name
+ holding.loc = loc
+ holding = null
-/obj/machinery/portable_atmospherics/canister/toxins/New()
+ if (href_list["pressure_adj"])
+ var/diff = text2num(href_list["pressure_adj"])
+ if(diff > 0)
+ release_pressure = min(10*ONE_ATMOSPHERE, release_pressure+diff)
+ else
+ release_pressure = max(ONE_ATMOSPHERE/10, release_pressure+diff)
+
+ if (href_list["relabel"])
+ if (can_label)
+ var/list/colors = list(\
+ "\[N2O\]" = "redws", \
+ "\[N2\]" = "red", \
+ "\[O2\]" = "blue", \
+ "\[Toxin (Bio)\]" = "orange", \
+ "\[CO2\]" = "black", \
+ "\[Air\]" = "grey", \
+ "\[CAUTION\]" = "yellow", \
+ )
+ var/label = input("Choose canister label", "Gas canister") as null|anything in colors
+ if (label)
+ src.canister_color = colors[label]
+ src.icon_state = colors[label]
+ src.name = "Canister: [label]"
+
+ src.add_fingerprint(usr)
+ update_icon()
+
+ return 1
+
+/obj/machinery/portable_atmospherics/canister/phoron/New()
..()
- src.air_contents.toxins = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
+ src.air_contents.phoron = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
air_contents.update_values()
src.update_icon()
diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm
index be38255146..b73e2cbde2 100644
--- a/code/game/machinery/atmoalter/meter.dm
+++ b/code/game/machinery/atmoalter/meter.dm
@@ -10,7 +10,7 @@
var/id
use_power = 1
idle_power_usage = 2
- active_power_usage = 4
+ active_power_usage = 5
/obj/machinery/meter/New()
..()
@@ -30,7 +30,7 @@
icon_state = "meter0"
return 0
- use_power(5)
+ //use_power(5)
var/datum/gas_mixture/environment = target.return_air()
if(!environment)
diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm
index d8e45dab06..43f836f301 100644
--- a/code/game/machinery/atmoalter/portable_atmospherics.dm
+++ b/code/game/machinery/atmoalter/portable_atmospherics.dm
@@ -125,15 +125,15 @@
var/o2_concentration = air_contents.oxygen/total_moles
var/n2_concentration = air_contents.nitrogen/total_moles
var/co2_concentration = air_contents.carbon_dioxide/total_moles
- var/plasma_concentration = air_contents.toxins/total_moles
+ var/phoron_concentration = air_contents.phoron/total_moles
- var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+plasma_concentration)
+ var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+phoron_concentration)
user << "\blue Pressure: [round(pressure,0.1)] kPa"
user << "\blue Nitrogen: [round(n2_concentration*100)]%"
user << "\blue Oxygen: [round(o2_concentration*100)]%"
user << "\blue CO2: [round(co2_concentration*100)]%"
- user << "\blue Plasma: [round(plasma_concentration*100)]%"
+ user << "\blue Phoron: [round(phoron_concentration*100)]%"
if(unknown_concentration>0.01)
user << "\red Unknown: [round(unknown_concentration*100)]%"
user << "\blue Temperature: [round(air_contents.temperature-T0C)]°C"
diff --git a/code/game/machinery/atmoalter/scrubber.dm b/code/game/machinery/atmoalter/scrubber.dm
index 6432aa755b..cb92e4096a 100644
--- a/code/game/machinery/atmoalter/scrubber.dm
+++ b/code/game/machinery/atmoalter/scrubber.dm
@@ -114,8 +114,8 @@
filtered_out.temperature = removed.temperature
- filtered_out.toxins = removed.toxins
- removed.toxins = 0
+ filtered_out.phoron = removed.phoron
+ removed.phoron = 0
filtered_out.carbon_dioxide = removed.carbon_dioxide
removed.carbon_dioxide = 0
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index d3fb30d371..6a65e4812a 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -17,6 +17,7 @@ var/global/list/autolathe_recipes = list( \
new /obj/item/weapon/airlock_electronics(), \
new /obj/item/weapon/airalarm_electronics(), \
new /obj/item/weapon/firealarm_electronics(), \
+ new /obj/item/weapon/module/power_control(), \
new /obj/item/stack/sheet/metal(), \
new /obj/item/stack/sheet/glass(), \
new /obj/item/stack/sheet/rglass(), \
@@ -261,9 +262,42 @@ var/global/list/autolathe_recipes_hidden = list( \
if (!busy)
if(href_list["make"])
var/turf/T = get_step(src.loc, get_dir(src,usr))
- var/obj/template = locate(href_list["make"])
+
+ // critical exploit fix start -walter0o
+ var/obj/item/template = null
+ var/attempting_to_build = locate(href_list["make"])
+
+ if(!attempting_to_build)
+ return
+
+ if(locate(attempting_to_build, src.L) || locate(attempting_to_build, src.LL)) // see if the requested object is in one of the construction lists, if so, it is legit -walter0o
+ template = attempting_to_build
+
+ else // somebody is trying to exploit, alert admins -walter0o
+
+ var/turf/LOC = get_turf(usr)
+ message_admins("[key_name_admin(usr)] tried to exploit an autolathe to duplicate [attempting_to_build] ! ([LOC ? "JMP" : "null"])", 0)
+ log_admin("EXPLOIT : [key_name(usr)] tried to exploit an autolathe to duplicate [attempting_to_build] !")
+ return
+
+ // now check for legit multiplier, also only stacks should pass with one to prevent raw-materials-manipulation -walter0o
+
var/multiplier = text2num(href_list["multiplier"])
+
if (!multiplier) multiplier = 1
+ var/max_multiplier = 1
+
+ if(istype(template, /obj/item/stack)) // stacks are the only items which can have a multiplier higher than 1 -walter0o
+ var/obj/item/stack/S = template
+ max_multiplier = min(S.max_amount, S.m_amt?round(m_amount/S.m_amt):INFINITY, S.g_amt?round(g_amount/S.g_amt):INFINITY) // pasta from regular_win() to make sure the numbers match -walter0o
+
+ if( (multiplier > max_multiplier) || (multiplier <= 0) ) // somebody is trying to exploit, alert admins-walter0o
+
+ var/turf/LOC = get_turf(usr)
+ message_admins("[key_name_admin(usr)] tried to exploit an autolathe with multiplier set to [multiplier] on [template] ! ([LOC ? "JMP" : "null"])" , 0)
+ log_admin("EXPLOIT : [key_name(usr)] tried to exploit an autolathe with multiplier set to [multiplier] on [template] !")
+ return
+
var/power = max(2000, (template.m_amt+template.g_amt)*multiplier/5)
if(src.m_amount >= template.m_amt*multiplier && src.g_amount >= template.g_amt*multiplier)
busy = 1
diff --git a/code/game/machinery/bees_items.dm b/code/game/machinery/bees_items.dm
index 01ed5bfa40..e02a0a1a23 100644
--- a/code/game/machinery/bees_items.dm
+++ b/code/game/machinery/bees_items.dm
@@ -102,21 +102,22 @@
h1 {font-size: 18px; margin: 15px 0px 5px;}
h2 {font-size: 15px; margin: 15px 0px 5px;}
li {margin: 2px 0px 2px 15px;}
- ul {list-style: none; margin: 5px; padding: 0px;}
+ ul {margin: 5px; padding: 0px;}
ol {margin: 5px; padding: 0px 15px;}
+ body {font-size: 13px; font-family: Verdana;}
-
Raising Bees
+
Raising Bees
Bees are loving but fickle creatures. Don't mess with their hive and stay away from any clusters of them, and you'll avoid their ire.
Sometimes, you'll need to dig around in there for those delicious sweeties though - in that case make sure you wear sealed protection gear
and carry an extinguisher or smoker with you - any bees chasing you, once calmed down, can thusly be netted and returned safely to the hive.
- Beezeez is a cure-all panacea for them, but use it too much and the hive may grow to apocalyptic proportions. Other than that, bees are excellent pets
+ BeezEez is a cure-all panacea for them, but use it too much and the hive may grow to apocalyptic proportions. Other than that, bees are excellent pets
for all the family and are excellent caretakers of one's garden: having a hive or two around will aid in the longevity and growth rate of plants,
and aid them in fighting off poisons and disease.
-