diff --git a/.travis.yml b/.travis.yml
index b353761b2d..3095262290 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -21,15 +21,12 @@ cache:
addons:
apt:
- sources:
- - sourceline: 'ppa:ondrej/php'
packages:
- libc6-i386
- libgcc1:i386
- libstdc++6:i386
- python
- python-pip
- - php5.6
install:
- tools/travis/install_build_tools.sh
diff --git a/_maps/boxstation.json b/_maps/boxstation.json
index 65689d946c..edf5f993d3 100644
--- a/_maps/boxstation.json
+++ b/_maps/boxstation.json
@@ -1,8 +1,5 @@
{
"map_name": "Box Station",
"map_path": "map_files/BoxStation",
- "map_file": "BoxStation.dmm",
- "minetype": "lavaland",
- "transition_config": "default",
- "allow_custom_shuttles": "yes"
+ "map_file": "BoxStation.dmm"
}
diff --git a/_maps/deltastation.json b/_maps/deltastation.json
index 3cfd2d5290..dde878a26b 100644
--- a/_maps/deltastation.json
+++ b/_maps/deltastation.json
@@ -1,8 +1,5 @@
{
"map_name": "Delta Station",
"map_path": "map_files/Deltastation",
- "map_file": "DeltaStation2.dmm",
- "minetype": "lavaland",
- "transition_config": "default",
- "allow_custom_shuttles": "yes"
+ "map_file": "DeltaStation2.dmm"
}
diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index 1dfc193284..988afb163f 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -39983,7 +39983,9 @@
/turf/open/floor/engine,
/area/science/misc_lab)
"bTm" = (
-/obj/machinery/atmospherics/pipe/simple/general/visible,
+/obj/machinery/atmospherics/components/trinary/mixer/flipped{
+ dir = 1
+ },
/turf/open/floor/engine,
/area/science/misc_lab)
"bTn" = (
@@ -48489,12 +48491,8 @@
},
/area/ai_monitored/security/armory)
"coT" = (
-/obj/item/pipe{
- dir = 4;
- icon_state = "mixer";
- name = "gas mixer fitting";
- pipe_type = 14
- },
+/obj/machinery/atmospherics/pipe/simple/general/visible,
+/obj/machinery/meter,
/turf/open/floor/engine,
/area/science/misc_lab)
"coZ" = (
@@ -53801,7 +53799,7 @@
/turf/open/floor/plasteel,
/area/engine/engineering)
"cCW" = (
-/obj/machinery/portable_atmospherics/canister/freon,
+/obj/machinery/portable_atmospherics/canister/nitrous_oxide,
/turf/open/floor/plating,
/area/engine/engineering)
"cCY" = (
@@ -86228,7 +86226,7 @@ bVI
cay
ccw
chY
-cCW
+ciZ
ciW
ckB
ckB
@@ -108055,7 +108053,7 @@ cBE
bOE
bEC
bQV
-bSi
+coT
bTm
bUn
bXr
@@ -108312,8 +108310,8 @@ bNu
bMv
bEC
bQT
-bSh
-coT
+bSi
+bUn
bTl
bXr
bNZ
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 885a0926e8..1308cf7c87 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -57403,7 +57403,6 @@
dir = 8
},
/obj/effect/turf_decal/bot,
-/obj/machinery/portable_atmospherics/canister/freon,
/turf/open/floor/plasteel,
/area/engine/engineering)
"cqt" = (
@@ -81845,7 +81844,7 @@
},
/area/science/mixing)
"dqG" = (
-/obj/machinery/atmospherics/components/unary/vent_pump,
+/obj/machinery/atmospherics/components/unary/vent_pump/on,
/turf/open/floor/plasteel/neutral,
/area/science/mixing)
"dqH" = (
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index aa5a62d079..0e2ebb0c62 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -37410,18 +37410,12 @@
/obj/machinery/light{
dir = 1
},
-/obj/structure/table,
-/obj/item/paper_bin{
- pixel_x = -3;
- pixel_y = 7
- },
-/obj/item/pen,
+/obj/machinery/computer/atmos_alert,
/turf/open/floor/plasteel/caution{
dir = 1
},
/area/engine/atmos)
"byT" = (
-/obj/machinery/computer/atmos_alert,
/obj/structure/sign/map/left{
desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown).";
icon_state = "map-left-MS";
@@ -37431,6 +37425,7 @@
c_tag = "Atmospherics - Control Room";
network = list("SS13")
},
+/obj/machinery/computer/station_alert,
/turf/open/floor/plasteel/caution{
dir = 1
},
@@ -37441,7 +37436,6 @@
icon_state = "map-right-MS";
pixel_y = 32
},
-/obj/machinery/computer/station_alert,
/turf/open/floor/plasteel/caution{
dir = 1
},
@@ -38222,13 +38216,12 @@
/turf/open/floor/plating,
/area/engine/atmos)
"bAB" = (
-/obj/item/clothing/mask/breath{
- pixel_x = 4
- },
-/obj/item/tank/internals/emergency_oxygen{
- pixel_x = -8
- },
/obj/structure/table,
+/obj/item/paper_bin{
+ pixel_x = -3;
+ pixel_y = 7
+ },
+/obj/item/pen,
/turf/open/floor/plasteel/caution{
dir = 8
},
@@ -77655,7 +77648,7 @@
/turf/open/floor/plating,
/area/engine/engineering)
"deZ" = (
-/obj/machinery/portable_atmospherics/canister/freon,
+/obj/machinery/portable_atmospherics/canister/nitrous_oxide,
/turf/open/floor/plating,
/area/engine/engineering)
"dfa" = (
@@ -120449,7 +120442,7 @@ aGS
axY
aJl
aKx
-deZ
+aJu
aNo
axY
aPW
diff --git a/_maps/metastation.json b/_maps/metastation.json
index eae307ea3c..6b023ba02d 100644
--- a/_maps/metastation.json
+++ b/_maps/metastation.json
@@ -1,8 +1,5 @@
{
"map_name": "MetaStation",
"map_path": "map_files/MetaStation",
- "map_file": "MetaStation.dmm",
- "minetype": "lavaland",
- "transition_config": "default",
- "allow_custom_shuttles": "yes"
+ "map_file": "MetaStation.dmm"
}
diff --git a/_maps/omegastation.json b/_maps/omegastation.json
index 0040eac01e..0f3732c36c 100644
--- a/_maps/omegastation.json
+++ b/_maps/omegastation.json
@@ -1,8 +1,5 @@
{
"map_name": "OmegaStation",
"map_path": "map_files/OmegaStation",
- "map_file": "OmegaStation.dmm",
- "minetype": "lavaland",
- "transition_config": "default",
- "allow_custom_shuttles": "yes"
+ "map_file": "OmegaStation.dmm"
}
\ No newline at end of file
diff --git a/_maps/pubbystation.json b/_maps/pubbystation.json
index ddfe706280..b63f196b6c 100644
--- a/_maps/pubbystation.json
+++ b/_maps/pubbystation.json
@@ -1,8 +1,5 @@
{
"map_name": "PubbyStation",
"map_path": "map_files/PubbyStation",
- "map_file": "PubbyStation.dmm",
- "minetype": "lavaland",
- "transition_config": "default",
- "allow_custom_shuttles": "yes"
+ "map_file": "PubbyStation.dmm"
}
\ No newline at end of file
diff --git a/_maps/runtimestation.json b/_maps/runtimestation.json
index 7462ee5b73..c363b67a05 100644
--- a/_maps/runtimestation.json
+++ b/_maps/runtimestation.json
@@ -1,8 +1,5 @@
{
"map_name": "Runtime Station",
"map_path": "map_files/debug",
- "map_file": "runtimestation.dmm",
- "minetype": "lavaland",
- "transition_config": "default",
- "allow_custom_shuttles": "no"
+ "map_file": "runtimestation.dmm"
}
diff --git a/_maps/shuttles/emergency_luxury.dmm b/_maps/shuttles/emergency_luxury.dmm
index cffad6bf58..a9aea3c632 100644
--- a/_maps/shuttles/emergency_luxury.dmm
+++ b/_maps/shuttles/emergency_luxury.dmm
@@ -4,20 +4,20 @@
/area/space)
"ab" = (
/turf/closed/indestructible/riveted/uranium,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"ac" = (
/obj/machinery/door/airlock/external,
/turf/open/floor/plating{
icon_state = "wood-broken2"
},
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"ad" = (
/obj/machinery/door/airlock/gold,
/obj/effect/forcefield/luxury_shuttle{
name = "Ticket Booth"
},
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"ae" = (
/obj/docking_port/mobile/emergency{
dir = 2;
@@ -32,75 +32,75 @@
name = "Ticket Booth"
},
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"af" = (
/turf/open/floor/plating{
icon_state = "wood-broken3"
},
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"ag" = (
/turf/open/floor/plating{
icon_state = "wood"
},
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"ah" = (
/turf/open/floor/plating{
icon_state = "wood-broken"
},
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"ai" = (
/turf/open/floor/plating{
icon_state = "wood-broken5"
},
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aj" = (
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"ak" = (
/obj/item/twohanded/required/kirbyplants{
icon_state = "plant-10"
},
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"al" = (
/obj/structure/mirror{
pixel_y = 32
},
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"am" = (
/turf/open/floor/plating{
icon_state = "wood-broken7"
},
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"an" = (
/obj/machinery/light/small,
/turf/open/floor/plating{
icon_state = "wood-broken2"
},
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"ao" = (
/obj/machinery/light/small,
/turf/open/floor/plating{
icon_state = "wood-broken6"
},
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"ap" = (
/obj/structure/toilet{
dir = 4
},
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aq" = (
/obj/machinery/door/airlock/gold,
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"ar" = (
/obj/structure/shuttle/engine/propulsion{
dir = 8
},
/turf/open/floor/plating/airless,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"as" = (
/obj/structure/shuttle/engine/heater{
dir = 8
@@ -109,198 +109,198 @@
dir = 4
},
/turf/open/floor/plating/airless,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"at" = (
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"au" = (
/obj/structure/chair/comfy,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"av" = (
/obj/structure/chair/comfy{
dir = 4
},
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aw" = (
/obj/machinery/computer/communications,
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"ax" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/meatballspaghetti,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"ay" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/notasandwich,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"az" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/pastatomato,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aA" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/kebab/tofu,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aB" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/honkdae,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aC" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/enchiladas,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aD" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/candiedapple,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aE" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/burger/baconburger,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aF" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/benedict,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aG" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/cakeslice/chocolate,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aH" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/chowmein,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aI" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/dulcedebatataslice,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aJ" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/salad/validsalad,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aK" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/carneburrito,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aL" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/chawanmushi,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aM" = (
/obj/machinery/computer/emergency_shuttle,
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aN" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/melonfruitbowl,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aO" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/khachapuri,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aP" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/grilledcheese,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aQ" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/jelliedtoast/cherry,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aR" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/honeybun,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aS" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/eggplantparm,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aT" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/copypasta,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aU" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/bearsteak,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aV" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/boiledspaghetti,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aW" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/cherrycupcake,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aX" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/customizable/pizza,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aY" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/hotdog,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"aZ" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/pie/grapetart,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"ba" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/burger/superbite,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"bb" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/snacks/cakeslice/slimecake,
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"bc" = (
/obj/machinery/computer/station_alert,
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"bd" = (
/obj/structure/chair/comfy{
dir = 1
},
/turf/open/floor/carpet,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"be" = (
/obj/machinery/computer/crew,
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"bf" = (
/obj/machinery/sleeper{
dir = 4
},
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"bg" = (
/obj/item/twohanded/required/kirbyplants{
icon_state = "plant-21";
@@ -308,26 +308,26 @@
pixel_y = 3
},
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"bh" = (
/turf/open/floor/plating/beach/coastline_b,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"bi" = (
/obj/machinery/light,
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"bj" = (
/obj/machinery/light{
dir = 8
},
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"bk" = (
/obj/machinery/light{
dir = 4
},
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"bl" = (
/obj/item/twohanded/required/kirbyplants{
icon_state = "plant-10"
@@ -336,25 +336,25 @@
dir = 8
},
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"bm" = (
/obj/machinery/light{
dir = 4
},
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"bn" = (
/obj/machinery/light{
dir = 8
},
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"bo" = (
/obj/machinery/light{
dir = 4
},
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"bp" = (
/obj/item/twohanded/required/kirbyplants{
icon_state = "plant-21";
@@ -363,7 +363,7 @@
},
/obj/machinery/light,
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
"bq" = (
/obj/item/twohanded/required/kirbyplants{
icon_state = "plant-21";
@@ -372,7 +372,7 @@
},
/obj/machinery/light,
/turf/open/floor/mineral/gold,
-/area/shuttle/escape)
+/area/shuttle/escape/luxury)
(1,1,1) = {"
aa
diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm
index dd5a25d8ff..a2aa7b1414 100644
--- a/code/__DEFINES/DNA.dm
+++ b/code/__DEFINES/DNA.dm
@@ -135,3 +135,26 @@
#define NOAROUSAL 29 //Stops all arousal effects
#define NOGENITALS 30 //Cannot create, use, or otherwise have genitals
#define NO_DNA_COPY 31
+#define DRINKSBLOOD 32
+
+#define ORGAN_SLOT_BRAIN "brain"
+#define ORGAN_SLOT_APPENDIX "appendix"
+#define ORGAN_SLOT_RIGHT_ARM_AUG "r_arm_device"
+#define ORGAN_SLOT_LEFT_ARM_AUG "l_arm_device"
+#define ORGAN_SLOT_STOMACH "stomach"
+#define ORGAN_SLOT_BREATHING_TUBE "breathing_tube"
+#define ORGAN_SLOT_EARS "ears"
+#define ORGAN_SLOT_EYES "eye_sight"
+#define ORGAN_SLOT_LUNGS "lungs"
+#define ORGAN_SLOT_HEART "heart"
+#define ORGAN_SLOT_ZOMBIE "zombie_infection"
+#define ORGAN_SLOT_THRUSTERS "thrusters"
+#define ORGAN_SLOT_HUD "eye_hud"
+#define ORGAN_SLOT_LIVER "liver"
+#define ORGAN_SLOT_TONGUE "tongue"
+#define ORGAN_SLOT_VOICE "vocal_cords"
+#define ORGAN_SLOT_ADAMANTINE_RESONATOR "adamantine_resonator"
+#define ORGAN_SLOT_HEART_AID "heartdrive"
+#define ORGAN_SLOT_BRAIN_ANTIDROP "brain_antidrop"
+#define ORGAN_SLOT_BRAIN_ANTISTUN "brain_antistun"
+#define ORGAN_SLOT_TAIL "tail"
diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm
index 1273b5e3de..87f16da081 100644
--- a/code/__DEFINES/atmospherics.dm
+++ b/code/__DEFINES/atmospherics.dm
@@ -56,28 +56,16 @@
#define FIRE_MINIMUM_TEMPERATURE_TO_SPREAD 150+T0C
#define FIRE_MINIMUM_TEMPERATURE_TO_EXIST 100+T0C
#define FIRE_SPREAD_RADIOSITY_SCALE 0.85
-#define FIRE_CARBON_ENERGY_RELEASED 500000 //Amount of heat released per mole of burnt carbon into the tile
-#define FIRE_PLASMA_ENERGY_RELEASED 3000000 //Amount of heat released per mole of burnt plasma into the tile
#define FIRE_GROWTH_RATE 40000 //For small fires
#define CARBON_LIFEFORM_FIRE_RESISTANCE 200+T0C //Resistance to fire damage
#define CARBON_LIFEFORM_FIRE_DAMAGE 4 //Fire damage
- //Plasma fire properties
-#define OXYGEN_BURN_RATE_BASE 1.4
-#define PLASMA_BURN_RATE_DELTA 9
-#define PLASMA_MINIMUM_BURN_TEMPERATURE 100+T0C
-#define PLASMA_UPPER_TEMPERATURE 1370+T0C
-#define PLASMA_MINIMUM_OXYGEN_NEEDED 2
-#define PLASMA_MINIMUM_OXYGEN_PLASMA_RATIO 30
-#define PLASMA_OXYGEN_FULLBURN 10
#define MIN_TOXIC_GAS_DAMAGE 1
#define MAX_TOXIC_GAS_DAMAGE 10
-#define MOLES_PLASMA_VISIBLE 0.5 //Moles in a standard cell after which plasma is visible
- //Plasma fusion properties
-#define PLASMA_BINDING_ENERGY 3000000
-#define MAX_CARBON_EFFICENCY 9
-#define PLASMA_FUSED_COEFFICENT 0.08
-#define CARBON_CATALYST_COEFFICENT 0.01
-#define FUSION_PURITY_THRESHOLD 0.9
+#define MOLES_GAS_VISIBLE 0.5 //Moles in a standard cell after which gases are visible
+#define STOP_REACTIONS 2
+#define PLASMA_MINIMUM_BURN_TEMPERATURE 100+T0C
+#define GAS_STIM_MINIMUM 0.002
+
// Pressure limits.
#define HAZARD_HIGH_PRESSURE 550 //This determins at what pressure the ultra-high pressure red icon is displayed. (This one is set as a constant)
#define WARNING_HIGH_PRESSURE 325 //This determins when the orange pressure icon is displayed (it is 0.7 * HAZARD_HIGH_PRESSURE)
@@ -193,8 +181,7 @@
#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity())
#define ADD_GAS(gas_id, out_list)\
- var/list/tmp_gaslist = GLOB.gaslist_cache[gas_id];\
- out_list[gas_id] = tmp_gaslist.Copy();
+ var/list/tmp_gaslist = GLOB.gaslist_cache[gas_id]; out_list[gas_id] = tmp_gaslist.Copy();
//ASSERT_GAS(gas_id, gas_mixture) - used to guarantee that the gas list for this id exists in gas_mixture.gases.
//Must be used before adding to a gas. May be used before reading from a gas.
diff --git a/code/__DEFINES/atom_hud.dm b/code/__DEFINES/atom_hud.dm
index d4b2dfb2db..3c3350d6ab 100644
--- a/code/__DEFINES/atom_hud.dm
+++ b/code/__DEFINES/atom_hud.dm
@@ -40,8 +40,7 @@
#define ANTAG_HUD_SINTOUCHED 16
#define ANTAG_HUD_SOULLESS 17
#define ANTAG_HUD_CLOCKWORK 18
-#define ANTAG_HUD_BORER 19
-#define ANTAG_HUD_BROTHER 20
+#define ANTAG_HUD_BROTHER 19
// Notification action types
#define NOTIFY_JUMP "jump"
diff --git a/code/__DEFINES/callbacks.dm b/code/__DEFINES/callbacks.dm
index 18059a6083..126ef1ea1c 100644
--- a/code/__DEFINES/callbacks.dm
+++ b/code/__DEFINES/callbacks.dm
@@ -1,4 +1,4 @@
#define GLOBAL_PROC "some_magic_bullshit"
#define CALLBACK new /datum/callback
-#define INVOKE_ASYNC ImmediateInvokeAsync
+#define INVOKE_ASYNC world.ImmediateInvokeAsync
diff --git a/code/__DEFINES/cleaning.dm b/code/__DEFINES/cleaning.dm
new file mode 100644
index 0000000000..9f32992eb0
--- /dev/null
+++ b/code/__DEFINES/cleaning.dm
@@ -0,0 +1,7 @@
+//Cleaning tool strength
+#define CLEAN_VERY_WEAK 1 // What are you scrubbing the ground with a toothpick?
+#define CLEAN_WEAK 2
+#define CLEAN_MEDIUM 3 // Acceptable tools
+#define CLEAN_STRONG 4 // Industrial strength
+#define CLEAN_IMPRESSIVE 5 // Cleaning strong enough your granny would be proud
+#define CLEAN_GOD 6 // Cleans things spotless down to the atomic structure
\ No newline at end of file
diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index faf8238b6f..ddfa9942e6 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -2,6 +2,8 @@
#define GET_COMPONENT_FROM(varname, path, target) var##path/##varname = ##target.GetComponent(##path)
#define GET_COMPONENT(varname, path) GET_COMPONENT_FROM(varname, path, src)
+#define COMPONENT_INCOMPATIBLE 1
+
// How multiple components of the exact same type are handled in the same datum
#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default)
@@ -16,6 +18,8 @@
#define COMSIG_COMPONENT_REMOVING "component_removing" //before a component is removed from a datum because of RemoveComponent: (/datum/component)
#define COMSIG_PARENT_QDELETED "parent_qdeleted" //before a datum's Destroy() is called: ()
+#define COMSIG_COMPONENT_CLEAN_ACT "clean_act" //called on an object to clean it of cleanables. Usualy with soap: (num/strength)
+
// /atom signals
#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params)
#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human)
diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm
index ee9e97cbd9..c92cb5f5a7 100644
--- a/code/__DEFINES/layers.dm
+++ b/code/__DEFINES/layers.dm
@@ -33,6 +33,7 @@
#define HIGH_SIGIL_LAYER 2.56
#define BELOW_OPEN_DOOR_LAYER 2.6
+#define SHUTTER_LAYER 2.65 //Prevents shutters from being placed above doors. It's overridden by /obj/machinery/door/New() & poddoor/shutters/New()
#define OPEN_DOOR_LAYER 2.7
#define PROJECTILE_HIT_THRESHHOLD_LAYER 2.75 //projectiles won't hit objects at or below this layer if possible
#define TABLE_LAYER 2.8
diff --git a/code/__DEFINES/math.dm b/code/__DEFINES/math.dm
index 534e0d3608..5b3f51b4e3 100644
--- a/code/__DEFINES/math.dm
+++ b/code/__DEFINES/math.dm
@@ -10,6 +10,8 @@
#define T20C 293.15 // 20degC
#define TCMB 2.7 // -270.3degC
+#define SHORT_REAL_LIMIT 16777216
+
//"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks
//percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio)
//collapsed to percent_of_tick_used * tick_lag
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 66c12adc72..0fdfbaca1c 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -204,6 +204,7 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache)
#define BLOODY_FOOTPRINT_BASE_ALPHA 150
#define BLOOD_GAIN_PER_STEP 100
#define BLOOD_LOSS_PER_STEP 5
+#define BLOOD_LOSS_IN_SPREAD 20
#define BLOOD_FADEOUT_TIME 2
//Bloody shoe blood states
diff --git a/code/__DEFINES/pipe_construction.dm b/code/__DEFINES/pipe_construction.dm
index f5b513312d..a671b548ba 100644
--- a/code/__DEFINES/pipe_construction.dm
+++ b/code/__DEFINES/pipe_construction.dm
@@ -1,33 +1,10 @@
-/*
-PIPE CONSTRUCTION DEFINES
-Update these any time a path is changed
-Construction breaks otherwise
-*/
-
-//Pipes
-#define PIPE_SIMPLE /obj/machinery/atmospherics/pipe/simple
-#define PIPE_MANIFOLD /obj/machinery/atmospherics/pipe/manifold
-#define PIPE_4WAYMANIFOLD /obj/machinery/atmospherics/pipe/manifold4w
-#define PIPE_HE /obj/machinery/atmospherics/pipe/heat_exchanging/simple
-#define PIPE_HE_MANIFOLD /obj/machinery/atmospherics/pipe/heat_exchanging/manifold
-#define PIPE_HE_4WAYMANIFOLD /obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w
-#define PIPE_JUNCTION /obj/machinery/atmospherics/pipe/heat_exchanging/junction
-#define PIPE_LAYER_MANIFOLD /obj/machinery/atmospherics/pipe/layer_manifold
-//Unary
-#define PIPE_CONNECTOR /obj/machinery/atmospherics/components/unary/portables_connector
-#define PIPE_UVENT /obj/machinery/atmospherics/components/unary/vent_pump
-#define PIPE_SCRUBBER /obj/machinery/atmospherics/components/unary/vent_scrubber
-#define PIPE_INJECTOR /obj/machinery/atmospherics/components/unary/outlet_injector
-#define PIPE_HEAT_EXCHANGE /obj/machinery/atmospherics/components/unary/heat_exchanger
-//Binary
-#define PIPE_PUMP /obj/machinery/atmospherics/components/binary/pump
-#define PIPE_PASSIVE_GATE /obj/machinery/atmospherics/components/binary/passive_gate
-#define PIPE_VOLUME_PUMP /obj/machinery/atmospherics/components/binary/volume_pump
-#define PIPE_MVALVE /obj/machinery/atmospherics/components/binary/valve
-#define PIPE_DVALVE /obj/machinery/atmospherics/components/binary/valve/digital
-//Trinary
-#define PIPE_GAS_FILTER /obj/machinery/atmospherics/components/trinary/filter
-#define PIPE_GAS_MIXER /obj/machinery/atmospherics/components/trinary/mixer
+//Construction Categories
+#define PIPE_BINARY 0 //2 directions: N/S, E/W
+#define PIPE_BENDABLE 1 //6 directions: N/S, E/W, N/E, N/W, S/E, S/W
+#define PIPE_TRINARY 2 //4 directions: N/E/S, E/S/W, S/W/N, W/N/E
+#define PIPE_TRIN_M 3 //8 directions: N->S+E, S->N+E, N->S+W, S->N+W, E->W+S, W->E+S, E->W+N, W->E+N
+#define PIPE_UNARY 4 //4 directions: N, S, E, W
+#define PIPE_QUAD 5 //1 directions: N/S/E/W
//Disposal piping numbers - do NOT hardcode these, use the defines
#define DISP_PIPE_STRAIGHT 0
diff --git a/code/__DEFINES/profile.dm b/code/__DEFINES/profile.dm
new file mode 100644
index 0000000000..28fc7782ce
--- /dev/null
+++ b/code/__DEFINES/profile.dm
@@ -0,0 +1,29 @@
+#define PROFILE_START ;PROFILE_STORE = list();PROFILE_SET;
+#define PROFILE_STOP ;PROFILE_STORE = null;
+
+#define PROFILE_SET ;PROFILE_TIME = TICK_USAGE_REAL; PROFILE_LINE = __LINE__; PROFILE_FILE = __FILE__; PROFILE_SLEEPCHECK = world.time;
+
+#define PROFILE_TICK ;\
+ if (PROFILE_STORE) {\
+ var/PROFILE_TICK_USAGE_REAL = TICK_USAGE_REAL;\
+ if (PROFILE_SLEEPCHECK == world.time) {\
+ var/PROFILE_STRING = "[PROFILE_FILE]:[PROFILE_LINE] - [__FILE__]:[__LINE__]";\
+ var/list/PROFILE_ITEM = PROFILE_STORE[PROFILE_STRING];\
+ if (!PROFILE_ITEM) {\
+ PROFILE_ITEM = new(PROFILE_ITEM_LEN);\
+ PROFILE_STORE[PROFILE_STRING] = PROFILE_ITEM;\
+ PROFILE_ITEM[PROFILE_ITEM_TIME] = 0;\
+ PROFILE_ITEM[PROFILE_ITEM_COUNT] = 0;\
+ };\
+ PROFILE_ITEM[PROFILE_ITEM_TIME] += TICK_DELTA_TO_MS(PROFILE_TICK_USAGE_REAL-PROFILE_TIME);\
+ var/PROFILE_INCR_AMOUNT = min(1, 2**round(PROFILE_ITEM[PROFILE_ITEM_COUNT]/SHORT_REAL_LIMIT));\
+ if (prob(100/PROFILE_INCR_AMOUNT)) {\
+ PROFILE_ITEM[PROFILE_ITEM_COUNT] += PROFILE_INCR_AMOUNT;\
+ };\
+ };\
+ PROFILE_SET;\
+ };
+
+#define PROFILE_ITEM_LEN 2
+#define PROFILE_ITEM_TIME 1
+#define PROFILE_ITEM_COUNT 2
\ No newline at end of file
diff --git a/code/__DEFINES/radiation.dm b/code/__DEFINES/radiation.dm
index 196f3cc079..3e9731417a 100644
--- a/code/__DEFINES/radiation.dm
+++ b/code/__DEFINES/radiation.dm
@@ -6,29 +6,30 @@ Ask ninjanomnom if they're around
#define RAD_BACKGROUND_RADIATION 9 // How much radiation is harmless to a mob, this is also when radiation waves stop spreading
// WARNING: Lowering this value significantly increases SSradiation load
-#define RAD_AMOUNT_LOW 50
-#define RAD_AMOUNT_MEDIUM 200
-#define RAD_AMOUNT_HIGH 500
-#define RAD_AMOUNT_EXTREME 1000
-// apply_effect(amount * RAD_MOB_COEFFICIENT, IRRADIATE, blocked)
-#define RAD_MOB_COEFFICIENT 0.25 // Radiation applied is multiplied by this
+// apply_effect((amount*RAD_MOB_COEFFICIENT)/max(1, (radiation**2)*RAD_OVERDOSE_REDUCTION), IRRADIATE, blocked)
+#define RAD_MOB_COEFFICIENT 0.20 // Radiation applied is multiplied by this
+#define RAD_MOB_SKIN_PROTECTION ((1/RAD_MOB_COEFFICIENT)+RAD_BACKGROUND_RADIATION)
-#define RAD_LOSS_PER_TICK 1
+#define RAD_LOSS_PER_TICK 0.5
#define RAD_TOX_COEFFICIENT 0.05 // Toxin damage per tick coefficient
+#define RAD_OVERDOSE_REDUCTION 0.000001 // Coefficient to the reduction in applied rads once the thing, usualy mob, has too much radiation
+ // WARNING: This number is highly sensitive to change, graph is first for best results
+#define RAD_BURN_THRESHOLD 1000 // Applied radiation must be over this to burn
-#define RAD_MOB_SAFE 300 // How much stored radiation in a mob with no ill effects
+#define RAD_MOB_SAFE 500 // How much stored radiation in a mob with no ill effects
+
+#define RAD_MOB_HAIRLOSS 800 // How much stored radiation to check for hair loss
+
+#define RAD_MOB_MUTATE 1250 // How much stored radiation to check for mutation
+
+#define RAD_MOB_VOMIT 2000 // The amount of radiation to check for vomitting
+#define RAD_MOB_VOMIT_PROB 1 // Chance per tick of vomitting
#define RAD_MOB_KNOCKDOWN 2000 // How much stored radiation to check for stunning
#define RAD_MOB_KNOCKDOWN_PROB 1 // Chance of knockdown per tick when over threshold
#define RAD_MOB_KNOCKDOWN_AMOUNT 3 // Amount of knockdown when it occurs
-#define RAD_MOB_VOMIT 1500 // The amount of radiation to check for vomitting
-#define RAD_MOB_VOMIT_PROB 1 // Chance per tick of vomitting
-
-#define RAD_MOB_MUTATE 1000 // How much stored radiation to check for mutation
-#define RAD_MOB_HAIRLOSS 500 // How much stored radiation to check for hair loss
-
#define RAD_NO_INSULATION 1.0 // For things that shouldn't become irradiated for whatever reason
#define RAD_VERY_LIGHT_INSULATION 0.9 // What girders have
#define RAD_LIGHT_INSULATION 0.8
@@ -39,10 +40,10 @@ Ask ninjanomnom if they're around
// WARNING: The deines below could have disastrous consequences if tweaked incorrectly. See: The great SM purge of Oct.6.2017
// contamination_chance = (strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_CHANCE_COEFFICIENT * min(1/(steps*RAD_DISTANCE_COEFFICIENT), 1))
-// contamination_strength = (strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_STR_COEFFICIENT * min(1/(steps*RAD_DISTANCE_COEFFICIENT), 1)
-#define RAD_MINIMUM_CONTAMINATION 300 // How strong does a radiation wave have to be to contaminate objects
-#define RAD_CONTAMINATION_CHANCE_COEFFICIENT 0.0075 // Higher means higher strength scaling contamination chance
-#define RAD_CONTAMINATION_STR_COEFFICIENT 0.5 // Higher means higher strength scaling contamination strength
+// contamination_strength = (strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_STR_COEFFICIENT
+#define RAD_MINIMUM_CONTAMINATION 350 // How strong does a radiation wave have to be to contaminate objects
+#define RAD_CONTAMINATION_CHANCE_COEFFICIENT 0.005 // Higher means higher strength scaling contamination chance
+#define RAD_CONTAMINATION_STR_COEFFICIENT 0.3 // Higher means higher strength scaling contamination strength
#define RAD_DISTANCE_COEFFICIENT 1 // Lower means further rad spread
-#define RAD_HALF_LIFE 150 // The half-life of contaminated objects
\ No newline at end of file
+#define RAD_HALF_LIFE 90 // The half-life of contaminated objects
\ No newline at end of file
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 9ec26b7506..247e1109f8 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -46,8 +46,8 @@
#define INIT_ORDER_DBCORE 18
#define INIT_ORDER_BLACKBOX 17
#define INIT_ORDER_SERVER_MAINT 16
-#define INIT_ORDER_JOBS 15
-#define INIT_ORDER_EVENTS 14
+#define INIT_ORDER_EVENTS 15
+#define INIT_ORDER_JOBS 14
#define INIT_ORDER_TICKER 13
#define INIT_ORDER_MAPPING 12
#define INIT_ORDER_ATOMS 11
diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm
index 1c9c33f21a..a939ab7e90 100644
--- a/code/__HELPERS/cmp.dm
+++ b/code/__HELPERS/cmp.dm
@@ -58,3 +58,13 @@ GLOBAL_VAR_INIT(cmp_field, "name")
. = B.failures - A.failures
if (!.)
. = B.qdels - A.qdels
+
+/proc/cmp_profile_avg_time_dsc(list/A, list/B)
+ return (B[PROFILE_ITEM_TIME]/(B[PROFILE_ITEM_COUNT] || 1)) - (A[PROFILE_ITEM_TIME]/(A[PROFILE_ITEM_COUNT] || 1))
+
+/proc/cmp_profile_time_dsc(list/A, list/B)
+ return B[PROFILE_ITEM_TIME] - A[PROFILE_ITEM_TIME]
+
+/proc/cmp_profile_count_dsc(list/A, list/B)
+ return B[PROFILE_ITEM_COUNT] - A[PROFILE_ITEM_COUNT]
+
diff --git a/code/__HELPERS/radiation.dm b/code/__HELPERS/radiation.dm
index 7cd3a1bbeb..8418cc8505 100644
--- a/code/__HELPERS/radiation.dm
+++ b/code/__HELPERS/radiation.dm
@@ -1,28 +1,28 @@
-/proc/get_rad_contents(atom/location, list/output=list()) // A special GetAllContents that doesn't search past things with rad insulation
- . = output
-
- if(!location)
- return
-
- output += location
-
- var/datum/component/rad_insulation/insulation = location.GetComponent(/datum/component/rad_insulation)
- if(insulation && insulation.protects)
- return
-
- for(var/i in 1 to location.contents.len)
- var/static/list/ignored_things = typecacheof(list( // These types will never have radiation applied to them or be looked inside of
+// A special GetAllContents that doesn't search past things with rad insulation
+// The protection var only protects the things inside from being affected.
+// The protecting object itself will get returned still.
+// The ignore list makes those objects never return at all
+/proc/get_rad_contents(atom/location)
+ var/list/processing_list = list(location)
+ . = list()
+ while(processing_list.len)
+ var/static/list/ignored_things = typecacheof(list(
/mob/dead,
/mob/camera,
/obj/effect,
/obj/docking_port,
- /atom/movable/lighting_object
+ /atom/movable/lighting_object,
+ /obj/item/projectile
))
-
- var/atom/thing = location.contents[i]
+ var/atom/thing = processing_list[1]
+ processing_list -= thing
if(ignored_things[thing.type])
continue
- get_rad_contents(thing, output)
+ . += thing
+ var/datum/component/rad_insulation/insulation = thing.GetComponent(/datum/component/rad_insulation)
+ if(insulation && insulation.protects)
+ continue
+ processing_list += thing.contents
/proc/radiation_pulse(atom/source, intensity, range_modifier, log=FALSE, can_contaminate=TRUE)
if(!SSradiation.can_fire)
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index d94bfb4c5b..c9b392ed76 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -504,21 +504,19 @@ Turf and target are separate in case you want to teleport some distance from a t
return y
/*
-Recursively gets all contents of contents and returns them all in a list.
-
-recursive_depth is useful if you only want a turf and everything on it (recursive_depth=1)
-Do not set recursive depth higher than MAX_PROC_DEPTH as byond breaks when that limit is reached.
+ Gets all contents of contents and returns them all in a list.
*/
-/atom/proc/GetAllContents(list/output=list(), recursive_depth=MAX_PROC_DEPTH, _current_depth=0)
- . = output
- output += src
- if(_current_depth == recursive_depth)
- if(_current_depth == MAX_PROC_DEPTH)
- WARNING("Get all contents reached the max recursive depth of [MAX_PROC_DEPTH]. More and we would break shit. Offending atom: [src]")
- return
- for(var/i in 1 to contents.len)
- var/atom/thing = contents[i]
- thing.GetAllContents(output, recursive_depth, ++_current_depth)
+/atom/proc/GetAllContents()
+ var/list/processing_list = list(src)
+ var/list/assembled = list()
+ while(processing_list.len)
+ var/atom/A = processing_list[1]
+ processing_list.Cut(1, 2)
+ //Byond does not allow things to be in multiple contents, or double parent-child hierarchies, so only += is needed
+ //This is also why we don't need to check against assembled as we go along
+ processing_list += A.contents
+ assembled += A
+ return assembled
//Step-towards method of determining whether one atom can see another. Similar to viewers()
/proc/can_see(atom/source, atom/target, length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate.
@@ -1413,3 +1411,21 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
//checks if a turf is in the planet z list.
/proc/turf_z_is_planet(turf/T)
return GLOB.z_is_planet["[T.z]"]
+
+//returns a GUID like identifier (using a mostly made up record format)
+//guids are not on their own suitable for access or security tokens, as most of their bits are predictable.
+// (But may make a nice salt to one)
+/proc/GUID()
+ var/const/GUID_VERSION = "b"
+ var/const/GUID_VARIANT = "d"
+ var/node_id = copytext(md5("[rand()*rand(1,9999999)][world.name][world.hub][world.hub_password][world.internet_address][world.address][world.contents.len][world.status][world.port][rand()*rand(1,9999999)]"), 1, 13)
+
+ var/time_high = "[num2hex(text2num(time2text(world.realtime,"YYYY")), 2)][num2hex(world.realtime, 6)]"
+
+ var/time_mid = num2hex(world.timeofday, 4)
+
+ var/time_low = num2hex(world.time, 3)
+
+ var/time_clock = num2hex(TICK_DELTA_TO_MS(world.tick_usage), 3)
+
+ return "{[time_high]-[time_mid]-[GUID_VERSION][time_low]-[GUID_VARIANT][time_clock]-[node_id]}"
\ No newline at end of file
diff --git a/code/_compile_options.dm b/code/_compile_options.dm
index 1c1ad2e692..1f20614c17 100644
--- a/code/_compile_options.dm
+++ b/code/_compile_options.dm
@@ -5,8 +5,10 @@
#ifdef TESTING
//#define GC_FAILURE_HARD_LOOKUP //makes paths that fail to GC call find_references before del'ing.
- //Also allows for recursive reference searching of datums.
- //Sets world.loop_checks to false and prevents find references from sleeping
+ //implies FIND_REF_NO_CHECK_TICK
+
+//#define FIND_REF_NO_CHECK_TICK //Sets world.loop_checks to false and prevents find references from sleeping
+
//#define VISUALIZE_ACTIVE_TURFS //Highlights atmos active turfs in green
#endif
@@ -58,6 +60,11 @@
#warn compiling in TESTING mode. testing() debug messages will be visible.
#endif
+
+#ifdef GC_FAILURE_HARD_LOOKUP
+#define FIND_REF_NO_CHECK_TICK
+#endif
+
#ifdef TRAVISTESTING
#define TESTING
#endif
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index 4703300f11..cd812d10a7 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -15,7 +15,7 @@
Override makes it so the alert is not replaced until cleared by a clear_alert with clear_override, and it's used for hallucinations.
*/
- if(!category)
+ if(!category || QDELETED(src))
return
var/obj/screen/alert/thealert
@@ -629,4 +629,5 @@ so as to remain in compliance with the most up-to-date laws."
. = ..()
severity = 0
master = null
+ mob_viewer = null
screen_loc = ""
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index 7cddaf9a6f..79271d1d6d 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -251,7 +251,7 @@
to_chat(C, "You are no longer running on internals.")
icon_state = "internal0"
else
- if(!C.getorganslot("breathing_tube"))
+ if(!C.getorganslot(ORGAN_SLOT_BREATHING_TUBE))
if(!istype(C.wear_mask, /obj/item/clothing/mask))
to_chat(C, "You are not wearing an internals mask!")
return 1
diff --git a/code/citadel/_cit_helpers.dm b/code/citadel/_cit_helpers.dm
index 9ac58122fe..f3db31c228 100644
--- a/code/citadel/_cit_helpers.dm
+++ b/code/citadel/_cit_helpers.dm
@@ -26,7 +26,7 @@ proc/get_racelist(var/mob/user)//This proc returns a list of species that 'user'
var/list/wlist = S.whitelist
if(S.whitelisted && (wlist.Find(user.ckey) || wlist.Find(user.key) || user.client.holder)) //If your ckey is on the species whitelist or you're an admin:
GLOB.whitelisted_species_list[S.id] = S.type //Add the species to their available species list.
- else if(!S.whitelisted && S.roundstart) //Normal roundstart species will be handled here.
+ else if(!S.whitelisted) //Normal roundstart species will be handled here.
GLOB.whitelisted_species_list[S.id] = S.type
return GLOB.whitelisted_species_list
diff --git a/code/citadel/cit_guns.dm b/code/citadel/cit_guns.dm
index bf8d034148..8a90e75a6b 100644
--- a/code/citadel/cit_guns.dm
+++ b/code/citadel/cit_guns.dm
@@ -111,7 +111,7 @@
w_class = WEIGHT_CLASS_BULKY
can_suppress = 0
burst_size = 1
- fire_delay = 20
+ fire_delay = 40
select = 0
actions_types = list()
casing_ejector = 0
@@ -140,14 +140,14 @@
/datum/supply_pack/security/armory/spinfusor
name = "Stormhammer Spinfusor Crate"
- cost = 7000
+ cost = 14000
contains = list(/obj/item/gun/ballistic/automatic/spinfusor,
/obj/item/gun/ballistic/automatic/spinfusor)
crate_name = "spinfusor crate"
/datum/supply_pack/security/armory/spinfusorammo
name = "Spinfusor Disk Crate"
- cost = 4000
+ cost = 7000
contains = list(/obj/item/ammo_box/aspinfusor,
/obj/item/ammo_box/aspinfusor,
/obj/item/ammo_box/aspinfusor,
@@ -210,7 +210,7 @@
/obj/item/projectile/bullet/mags
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "magjectile"
- damage = 25
+ damage = 15
armour_penetration = 10
light_range = 2
light_color = LIGHT_COLOR_RED
@@ -218,9 +218,9 @@
/obj/item/projectile/bullet/nlmags //non-lethal boolets
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "magjectile-nl"
- damage = 2
- knockdown = 15
- stamina = 50
+ damage = 1
+ knockdown = 0
+ stamina = 25
armour_penetration = -10
light_range = 2
light_color = LIGHT_COLOR_BLUE
@@ -378,7 +378,7 @@
/obj/item/projectile/bullet/magrifle
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "magjectile-large"
- damage = 30
+ damage = 25
armour_penetration = 25
light_range = 3
light_color = LIGHT_COLOR_RED
@@ -386,10 +386,10 @@
/obj/item/projectile/bullet/nlmagrifle //non-lethal boolets
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "magjectile-large-nl"
- damage = 5
- knockdown = 30
- stamina = 75
- armour_penetration = 0
+ damage = 2
+ knockdown = 0
+ stamina = 30
+ armour_penetration = -10
light_range = 3
light_color = LIGHT_COLOR_BLUE
@@ -443,7 +443,7 @@
can_suppress = 0
burst_size = 3
fire_delay = 2
- spread = 15
+ spread = 30
recoil = 1
casing_ejector = 0
@@ -719,8 +719,8 @@ obj/item/projectile/bullet/c10mm/soporific
if((blocked != 100) && isliving(target))
var/mob/living/L = target
L.blur_eyes(6)
- if(L.staminaloss >= 60)
- L.Sleeping(250)
+ if(L.getStaminaLoss() >= 60)
+ L.Sleeping(300)
else
L.adjustStaminaLoss(25)
return 1
@@ -753,7 +753,7 @@ obj/item/projectile/bullet/c10mm/soporific
/obj/item/projectile/bullet/cflechettes //shreds flesh and forces bleeding
name = "flechette (serrated)"
- damage = 8
+ damage = 15
dismemberment = 10
armour_penetration = -80
@@ -921,3 +921,294 @@ obj/item/projectile/bullet/c10mm/soporific
materials = list(MAT_METAL = 7500, MAT_GLASS = 1000)
build_path = /obj/item/gun/energy/laser/practice/raygun
category = list("hacked", "Misc")
+
+/*/////////////////////////////////////////////////////////////////////////////////////////////
+ The Recolourable Gun
+*//////////////////////////////////////////////////////////////////////////////////////////////
+
+/obj/item/gun/ballistic/automatic/pistol/p37
+ name = "\improper CX Mk.37P"
+ desc = "A modern reimagining of an old legendary gun, the Mk.37 is a handgun with a toggle-locking mechanism manufactured by CX Armories. \
+ This model is coated with a special polychromic material. \
+ Has a small warning on the receiver that boldly states 'WARNING: WILL DETONATE UPON UNAUTHORIZED USE'. \
+ Uses 9mm bullets loaded into proprietary magazines."
+ icon = 'icons/obj/guns/cit_guns.dmi'
+ icon_state = "p37"
+ w_class = WEIGHT_CLASS_NORMAL
+ spawnwithmagazine = FALSE
+ mag_type = /obj/item/ammo_box/magazine/m9mm/p37
+ can_suppress = FALSE
+ pin = /obj/item/device/firing_pin/dna/dredd //goes boom if whoever isn't DNA locked to it tries to use it
+ actions_types = list(/datum/action/item_action/pick_color)
+
+ var/frame_color = "#808080" //RGB
+ var/receiver_color = "#808080"
+ var/body_color = "#0098FF"
+ var/barrel_color = "#808080"
+ var/tip_color = "#808080"
+ var/arm_color = "#808080"
+ var/grip_color = "#00FFCB" //Does not actually colour the grip, just the lights surrounding it
+ var/energy_color = "#00FFCB"
+
+///Defining all the colourable bits and displaying them///
+
+/obj/item/gun/ballistic/automatic/pistol/p37/update_icon()
+ var/mutable_appearance/frame_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_frame")
+ var/mutable_appearance/receiver_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_receiver")
+ var/mutable_appearance/body_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_body")
+ var/mutable_appearance/barrel_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_barrel")
+ var/mutable_appearance/tip_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_tip")
+ var/mutable_appearance/grip_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_grip")
+ var/mutable_appearance/energy_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_light")
+ var/mutable_appearance/arm_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_arm")
+ var/mutable_appearance/arm_overlay_e = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_arm-e")
+
+ if(frame_color)
+ frame_overlay.color = frame_color
+ if(receiver_color)
+ receiver_overlay.color = receiver_color
+ if(body_color)
+ body_overlay.color = body_color
+ if(barrel_color)
+ barrel_overlay.color = barrel_color
+ if(tip_color)
+ tip_overlay.color = tip_color
+ if(grip_color)
+ grip_overlay.color = grip_color
+ if(energy_color)
+ energy_overlay.color = energy_color
+ if(arm_color)
+ arm_overlay.color = arm_color
+ if(arm_color)
+ arm_overlay_e.color = arm_color
+
+ cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
+
+ add_overlay(frame_overlay)
+ add_overlay(receiver_overlay)
+ add_overlay(body_overlay)
+ add_overlay(barrel_overlay)
+ add_overlay(tip_overlay)
+ add_overlay(grip_overlay)
+ add_overlay(energy_overlay)
+
+ if(magazine) //does not need a cut_overlays proc call here because it's already called further up
+ add_overlay("p37_mag")
+
+ if(chambered)
+ cut_overlay(arm_overlay_e)
+ add_overlay(arm_overlay)
+ else
+ cut_overlay(arm_overlay)
+ add_overlay(arm_overlay_e)
+
+///letting you actually recolor things///
+
+/obj/item/gun/ballistic/automatic/pistol/p37/ui_action_click(mob/user, var/datum/action/A)
+ if(istype(A, /datum/action/item_action/pick_color))
+
+ var/choice = input(user,"Mk.37P polychrome options", "Gun Recolor") in list("Frame Color","Receiver Color","Body Color",
+ "Barrel Color", "Barrel Tip Color", "Grip Light Color",
+ "Light Color", "Arm Color", "*CANCEL*")
+
+ switch(choice)
+
+ if("Frame Color")
+ var/frame_color_input = input(usr,"Choose Frame Color") as color|null
+ if(frame_color_input)
+ frame_color = sanitize_hexcolor(frame_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+
+ if("Receiver Color")
+ var/receiver_color_input = input(usr,"Choose Receiver Color") as color|null
+ if(receiver_color_input)
+ receiver_color = sanitize_hexcolor(receiver_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+
+ if("Body Color")
+ var/body_color_input = input(usr,"Choose Body Color") as color|null
+ if(body_color_input)
+ body_color = sanitize_hexcolor(body_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+
+ if("Barrel Color")
+ var/barrel_color_input = input(usr,"Choose Barrel Color") as color|null
+ if(barrel_color_input)
+ barrel_color = sanitize_hexcolor(barrel_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+
+ if("Barrel Tip Color")
+ var/tip_color_input = input(usr,"Choose Barrel Tip Color") as color|null
+ if(tip_color_input)
+ tip_color = sanitize_hexcolor(tip_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+
+ if("Grip Light Color")
+ var/grip_color_input = input(usr,"Choose Grip Light Color") as color|null
+ if(grip_color_input)
+ grip_color = sanitize_hexcolor(grip_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+
+ if("Light Color")
+ var/energy_color_input = input(usr,"Choose Light Color") as color|null
+ if(energy_color_input)
+ energy_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+
+ if("Arm Color")
+ var/arm_color_input = input(usr,"Choose Arm Color") as color|null
+ if(arm_color_input)
+ arm_color = sanitize_hexcolor(arm_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+
+ else
+ ..()
+
+///boolets///
+
+/obj/item/projectile/bullet/c9mm/frangible
+ name = "9mm frangible bullet"
+ damage = 15
+ stamina = 0
+ armour_penetration = -25
+
+/obj/item/projectile/bullet/c9mm/rubber
+ name = "9mm rubber bullet"
+ damage = 2
+ stamina = 25
+ knockdown = 0
+
+/obj/item/ammo_casing/c9mm/frangible
+ name = "9mm frangible bullet casing"
+ desc = "A 9mm frangible bullet casing."
+ projectile_type = /obj/item/projectile/bullet/c9mm/frangible
+
+/obj/item/ammo_casing/c9mm/rubber
+ name = "9mm rubber bullet casing"
+ desc = "A 9mm rubber bullet casing."
+ projectile_type = /obj/item/projectile/bullet/c9mm/rubber
+
+/obj/item/ammo_box/magazine/m9mm/p37
+ name = "\improper P37 magazine (9mm frangible)"
+ desc = "A gun magazine. Loaded with plastic composite rounds which fragment upon impact to minimize collateral damage."
+ icon = 'icons/obj/guns/cit_guns.dmi'
+ icon_state = "11mm" //topkek
+ ammo_type = /obj/item/ammo_casing/c9mm/frangible
+ caliber = "9mm"
+ max_ammo = 11
+ multiple_sprites = 1
+
+/obj/item/ammo_box/magazine/m9mm/p37/fmj
+ name = "\improper P37 magazine (9mm)"
+ ammo_type = /obj/item/ammo_casing/c9mm
+ desc = "A gun magazine. Loaded with conventional full metal jacket rounds."
+
+/obj/item/ammo_box/magazine/m9mm/p37/rubber
+ name = "\improper P37 magazine (9mm Non-Lethal Rubbershot)"
+ ammo_type = /obj/item/ammo_casing/c9mm/rubber
+ desc = "A gun magazine. Loaded with less-than-lethal rubber bullets."
+
+/obj/item/ammo_box/c9mm/frangible
+ name = "ammo box (9mm frangible)"
+ ammo_type = /obj/item/ammo_casing/c9mm/frangible
+
+/obj/item/ammo_box/c9mm/rubber
+ name = "ammo box (9mm non-lethal rubbershot)"
+ ammo_type = /obj/item/ammo_casing/c9mm/rubber
+
+/datum/design/c9mmfrag
+ name = "Box of 9mm Frangible Bullets"
+ id = "9mm_frag"
+ build_type = AUTOLATHE
+ materials = list(MAT_METAL = 30000)
+ build_path = /obj/item/ammo_box/c9mm/frangible
+ category = list("initial", "Security")
+
+/datum/design/c9mmrubber
+ name = "Box of 9mm Rubber Bullets"
+ id = "9mm_rubber"
+ build_type = AUTOLATHE
+ materials = list(MAT_METAL = 30000)
+ build_path = /obj/item/ammo_box/c9mm/rubber
+ category = list("initial", "Security")
+
+
+///Security Variant///
+
+/obj/item/gun/ballistic/automatic/pistol/p37/sec
+ name = "\improper CX Mk.37S"
+ desc = "A modern reimagining of an old legendary gun, the Mk.37 is a handgun with a toggle-locking mechanism manufactured by CX Armories. Uses 9mm bullets loaded into proprietary magazines."
+ spawnwithmagazine = FALSE
+ pin = /obj/item/device/firing_pin/implant/mindshield
+ actions_types = list() //so you can't recolor it
+
+ frame_color = "#808080" //RGB
+ receiver_color = "#808080"
+ body_color = "#282828"
+ barrel_color = "#808080"
+ tip_color = "#808080"
+ arm_color = "#800000"
+ grip_color = "#FFFF00" //Does not actually colour the grip, just the lights surrounding it
+ energy_color = "#FFFF00"
+
+///Foam Variant because WE NEED MEMES///
+
+/obj/item/gun/ballistic/automatic/pistol/p37/foam
+ name = "\improper Foam Force Mk.37F"
+ desc = "A licensed foam-firing reproduction of a handgun with a toggle-locking mechanism manufactured by CX Armories. This model is coated with a special polychromic material. Uses standard foam pistol magazines."
+ icon_state = "p37_foam"
+ spawnwithmagazine = TRUE
+ mag_type = /obj/item/ammo_box/magazine/toy/pistol
+ can_suppress = FALSE
+ actions_types = list(/datum/action/item_action/pick_color)
+
+/datum/design/foam_p37
+ name = "Foam Force Mk.37F"
+ id = "foam_p37"
+ build_type = AUTOLATHE
+ materials = list(MAT_METAL = 15000, MAT_GLASS = 10000)
+ build_path = /obj/item/gun/ballistic/automatic/pistol/p37/foam
+ category = list("hacked", "Misc")
+
+
+/*/////////////////////////////////////////////////////////////////////////////////////////////
+ The Recolourable Energy Gun
+*//////////////////////////////////////////////////////////////////////////////////////////////
+
+obj/item/gun/energy/e_gun/cx
+ name = "\improper CX Model D Energy Gun"
+ desc = "An overpriced hybrid energy gun with two settings: disable, and kill. Manufactured by CX Armories. Has a polychromic coating."
+ icon = 'icons/obj/guns/cit_guns.dmi'
+ icon_state = "cxe"
+ lefthand_file = 'icons/mob/citadel/guns_lefthand.dmi'
+ righthand_file = 'icons/mob/citadel/guns_righthand.dmi'
+ ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser)
+ origin_tech = "combat=4;magnets=3"
+ flight_x_offset = 15
+ flight_y_offset = 10
+ actions_types = list(/datum/action/item_action/pick_color)
+ var/body_color = "#252528"
+
+obj/item/gun/energy/e_gun/cx/update_icon()
+ ..()
+ var/mutable_appearance/body_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "cxegun_body")
+ if(body_color)
+ body_overlay.color = body_color
+ add_overlay(body_overlay)
+
+obj/item/gun/energy/e_gun/cx/ui_action_click(mob/user, var/datum/action/A)
+ if(istype(A, /datum/action/item_action/pick_color))
+ if(alert("Are you sure you want to repaint your gun?", "Confirm Repaint", "Yes", "No") == "Yes")
+ var/body_color_input = input(usr,"Choose Body Color") as color|null
+ if(body_color_input)
+ body_color = sanitize_hexcolor(body_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+ else
+ ..()
+
+obj/item/gun/energy/e_gun/cx/worn_overlays(isinhands, icon_file)
+ . = ..()
+ if(isinhands)
+ var/mutable_appearance/body_inhand = mutable_appearance(icon_file, "cxe_body")
+ body_inhand.color = body_color
+ . += body_inhand
\ No newline at end of file
diff --git a/code/citadel/cit_miscreants.dm b/code/citadel/cit_miscreants.dm
index ec5ff0156f..7238283dc6 100644
--- a/code/citadel/cit_miscreants.dm
+++ b/code/citadel/cit_miscreants.dm
@@ -7,7 +7,7 @@
return
if(!crewMind.assigned_role)
return
- if(ROLE_MISCREANT in crewMind.current.client.prefs.be_special)
+ if(!(ROLE_MISCREANT in crewMind.current.client.prefs.be_special))
return
if(jobban_isbanned(crewMind, "Syndicate"))
return
diff --git a/code/citadel/cit_weapons.dm b/code/citadel/cit_weapons.dm
new file mode 100644
index 0000000000..466a41e427
--- /dev/null
+++ b/code/citadel/cit_weapons.dm
@@ -0,0 +1,207 @@
+/obj/item/toy/sword/cx
+ name = "\improper DX Non-Euplastic LightSword"
+ desc = "A deluxe toy replica of an energy sword. Realistic visuals and sounds! Ages 8 and up."
+ icon = 'icons/obj/cit_weapons.dmi'
+ icon_state = "cxsword_hilt"
+ item_state = "cxsword"
+ lefthand_file = 'icons/mob/citadel/melee_lefthand.dmi'
+ righthand_file = 'icons/mob/citadel/melee_righthand.dmi'
+ active = FALSE
+ w_class = WEIGHT_CLASS_SMALL
+ attack_verb = list("poked", "jabbed", "hit")
+ light_color = "#37FFF7"
+ var/light_brightness = 3
+ actions_types = list(/datum/action/item_action/pick_color)
+
+/obj/item/toy/sword/cx/attack_self(mob/user)
+ active = !( active )
+
+ if (active)
+ to_chat(user, "You activate the holographic blade with a press of a button.")
+ playsound(user, 'sound/weapons/nebon.ogg', 50, 1)
+ w_class = WEIGHT_CLASS_BULKY
+ attack_verb = list("slashed", "stabbed", "ravaged")
+ set_light(light_brightness)
+ update_icon()
+
+ else
+ to_chat(user, "You deactivate the holographic blade with a press of a button.")
+ playsound(user, 'sound/weapons/neboff.ogg', 50, 1)
+ w_class = WEIGHT_CLASS_SMALL
+ attack_verb = list("poked", "jabbed", "hit")
+ set_light(0)
+ update_icon()
+
+ add_fingerprint(user)
+
+/obj/item/toy/sword/cx/update_icon()
+ var/mutable_appearance/blade_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_blade")
+ var/mutable_appearance/gem_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_gem")
+
+ if(light_color)
+ blade_overlay.color = light_color
+ gem_overlay.color = light_color
+
+ cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
+
+ add_overlay(gem_overlay)
+
+ if(active)
+ add_overlay(blade_overlay)
+
+/obj/item/toy/sword/cx/ui_action_click(mob/user, var/datum/action/A)
+ if(istype(A, /datum/action/item_action/pick_color))
+ if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
+ var/energy_color_input = input(usr,"Choose Energy Color") as color|null
+ if(energy_color_input)
+ light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+ if(ismob(loc))
+ var/mob/M = loc
+ M.update_inv_hands()
+ update_light()
+
+ else
+ ..()
+
+/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file)
+ . = ..()
+ if(active)
+ if(isinhands)
+ var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade")
+ blade_inhand.color = light_color
+ . += blade_inhand
+
+/*///autolathe memes/// I really need to stop doing this and find a proper way of adding in my toys
+
+/datum/design/toyneb
+ name = "Non-Euplastic Blade"
+ id = "toyneb"
+ build_type = AUTOLATHE
+ materials = list(MAT_METAL = 10000, MAT_GLASS = 1000)
+ build_path = /obj/item/toy/sword/cx
+ category = list("hacked", "Misc")
+*/ // There, I stopped doing it
+
+/datum/crafting_recipe/toyneb
+ name = "Non-Euplastic Blade"
+ reqs = list(/obj/item/light/bulb = 1, /obj/item/stack/cable_coil = 1, /obj/item/toy/sword = 1)
+ result = /obj/item/toy/sword/cx
+ category = CAT_MISC
+
+/*/////////////////////////////////////////////////////////////////////////
+///////////// The TRUE Energy Sword ///////////////////////////
+*//////////////////////////////////////////////////////////////////////////
+
+/obj/item/melee/transforming/energy/sword/cx
+ name = "non-eutactic blade"
+ desc = "The CX Armories Type-69 Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable."
+ icon_state = "cxsword_hilt"
+ icon = 'icons/obj/cit_weapons.dmi'
+ item_state = "cxsword"
+ lefthand_file = 'icons/mob/citadel/melee_lefthand.dmi'
+ righthand_file = 'icons/mob/citadel/melee_righthand.dmi'
+ force = 3
+ throwforce = 5
+ hitsound = "swing_hit" //it starts deactivated
+ hitsound_on = 'sound/weapons/nebhit.ogg'
+ attack_verb_off = list("tapped", "poked")
+ throw_speed = 3
+ throw_range = 5
+ sharpness = IS_SHARP
+ embed_chance = 40
+ embedded_impact_pain_multiplier = 10
+ armour_penetration = 0
+ origin_tech = "combat=3;magnets=4"
+ block_chance = 60
+ light_color = "#37FFF7"
+ actions_types = list(/datum/action/item_action/pick_color)
+
+/obj/item/melee/transforming/energy/sword/cx/transform_weapon(mob/living/user, supress_message_text)
+ active = !active //I'd use a ..() here but it'd inherit from the regular esword's proc instead, so SPAGHETTI CODE
+ if(active) //also I need to rip out the iconstate changing bits
+ force = force_on
+ throwforce = throwforce_on
+ hitsound = hitsound_on
+ throw_speed = 4
+ if(attack_verb_on.len)
+ attack_verb = attack_verb_on
+ w_class = w_class_on
+ START_PROCESSING(SSobj, src)
+ set_light(brightness_on)
+ update_icon()
+ else
+ force = initial(force)
+ throwforce = initial(throwforce)
+ hitsound = initial(hitsound)
+ throw_speed = initial(throw_speed)
+ if(attack_verb_off.len)
+ attack_verb = attack_verb_off
+ w_class = initial(w_class)
+ STOP_PROCESSING(SSobj, src)
+ set_light(0)
+ update_icon()
+ transform_messages(user, supress_message_text)
+ add_fingerprint(user)
+ return TRUE
+
+/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text)
+ playsound(user, active ? 'sound/weapons/nebon.ogg' : 'sound/weapons/neboff.ogg', 65, 1)
+ if(!supress_message_text)
+ to_chat(user, "[src] [active ? "is now active":"can now be concealed"].")
+
+/obj/item/melee/transforming/energy/sword/cx/update_icon()
+ var/mutable_appearance/blade_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_blade")
+ var/mutable_appearance/gem_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_gem")
+
+ if(light_color)
+ blade_overlay.color = light_color
+ gem_overlay.color = light_color
+
+ cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
+
+ add_overlay(gem_overlay)
+
+ if(active)
+ add_overlay(blade_overlay)
+
+/obj/item/melee/transforming/energy/sword/cx/ui_action_click(mob/user, var/datum/action/A)
+ if(istype(A, /datum/action/item_action/pick_color))
+ if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
+ var/energy_color_input = input(usr,"Choose Energy Color") as color|null
+ if(energy_color_input)
+ light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+ if(ismob(loc))
+ var/mob/M = loc
+ M.update_inv_hands()
+ update_light()
+
+ else
+ ..()
+
+/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file)
+ . = ..()
+ if(active)
+ if(isinhands)
+ var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade")
+ blade_inhand.color = light_color
+ . += blade_inhand
+
+/obj/item/melee/transforming/energy/sword/cx/traitor
+ name = "\improper Dragon's Tooth Sword"
+ desc = "The Dragon's Tooth sword is a blackmarket modification of the CX Armouries Type-69 NEB, \
+ which utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. \
+ It appears to have a wooden grip and a shaved down guard."
+ icon_state = "cxsword_hilt_traitor"
+ armour_penetration = 35
+ embed_chance = 75
+ block_chance = 50
+ origin_tech = "combat=3;magnets=4;syndicate=4"
+ hitsound_on = 'sound/weapons/blade1.ogg'
+ light_color = "#37F0FF"
+
+/obj/item/melee/transforming/energy/sword/cx/traitor/transform_messages(mob/living/user, supress_message_text)
+ playsound(user, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, 1)
+ if(!supress_message_text)
+ to_chat(user, "[src] [active ? "is now active":"can now be concealed"].")
\ No newline at end of file
diff --git a/code/citadel/crew_objectives/cit_crewobjectives_civilian.dm b/code/citadel/crew_objectives/cit_crewobjectives_civilian.dm
index 9be0e1c028..580038e191 100644
--- a/code/citadel/crew_objectives/cit_crewobjectives_civilian.dm
+++ b/code/citadel/crew_objectives/cit_crewobjectives_civilian.dm
@@ -23,7 +23,7 @@
/datum/objective/crew/druglordbot/check_completion()
var/pillcount = target_amount
- if(owner.current)
+ if(owner && owner.current)
if(owner.current.contents)
for(var/obj/item/reagent_containers/food/snacks/grown/P in owner.current.get_contents())
if(P.reagents.has_reagent(targetchem))
@@ -53,7 +53,7 @@
explanation_text = "Personally deliver at least [target_amount] [initial(foodpath.name)]s to Centcom."
/datum/objective/crew/foodhoard/check_completion()
- if(owner.current && owner.current.check_contents_for(foodpath) && SSshuttle.emergency.shuttle_areas[get_area(owner.current)])
+ if(owner && owner.current && owner.current.check_contents_for(foodpath) && SSshuttle.emergency.shuttle_areas[get_area(owner.current)])
return TRUE
else
return FALSE
@@ -151,8 +151,9 @@
/datum/objective/crew/nullrod/check_completion()
if(owner && owner.current)
- if(owner.current.check_contents_for(typesof(/obj/item/nullrod)))
- return TRUE
+ for(var/nullrodtypes in typesof(/obj/item/nullrod))
+ if(owner.current.check_contents_for(nullrodtypes))
+ return TRUE
if(owner.current.getorgan(/obj/item/organ/genital/penis))
return TRUE
return FALSE
@@ -227,10 +228,11 @@
explanation_text += "on a space suit." replace this if you're making this monstrosity work */
/datum/objective/crew/pwrgame/check_completion()
- if(owner.current && owner.current.check_contents_for(typesof(targettidegarb)))
- return TRUE
- else
- return FALSE
+ if(owner && owner.current)
+ for(var/tidegarbtypes in typesof(targettidegarb))
+ if(owner.current.check_contents_for(tidegarbtypes))
+ return TRUE
+ return FALSE
/datum/objective/crew/promotion //ported from Goon
explanation_text = "Have a non-assistant ID registered to you at the end of the shift."
diff --git a/code/citadel/crew_objectives/cit_crewobjectives_command.dm b/code/citadel/crew_objectives/cit_crewobjectives_command.dm
index b4f0d07c08..f01c887c9f 100644
--- a/code/citadel/crew_objectives/cit_crewobjectives_command.dm
+++ b/code/citadel/crew_objectives/cit_crewobjectives_command.dm
@@ -5,7 +5,7 @@
jobs = "captain"
/datum/objective/crew/caphat/check_completion()
- if(owner.current && owner.current.check_contents_for(/obj/item/clothing/head/caphat))
+ if(owner && owner.current && owner.current.check_contents_for(/obj/item/clothing/head/caphat))
return TRUE
else
return FALSE
@@ -15,7 +15,7 @@
jobs = "captain" //give this to other heads at your own risk.
/datum/objective/crew/datfukkendisk/check_completion()
- if(owner.current && owner.current.check_contents_for(/obj/item/disk/nuclear) && SSshuttle.emergency.shuttle_areas[get_area(owner.current)])
+ if(owner && owner.current && owner.current.check_contents_for(/obj/item/disk/nuclear) && SSshuttle.emergency.shuttle_areas[get_area(owner.current)])
return TRUE
else
return FALSE
@@ -25,7 +25,7 @@
jobs = "headofpersonnel"
/datum/objective/crew/ian/check_completion()
- if(owner.current)
+ if(owner && owner.current)
for(var/mob/living/simple_animal/pet/dog/corgi/Ian/goodboy in GLOB.mob_list)
if(goodboy.stat != DEAD && SSshuttle.emergency.shuttle_areas[get_area(goodboy)])
return TRUE
diff --git a/code/citadel/custom_loadout/custom_items.dm b/code/citadel/custom_loadout/custom_items.dm
index 2c83912d0a..44f672e653 100644
--- a/code/citadel/custom_loadout/custom_items.dm
+++ b/code/citadel/custom_loadout/custom_items.dm
@@ -192,4 +192,9 @@
can_adjust = 0
+/obj/item/clothing/shoes/sneakers/pink
+ icon_state = "pink"
+ item_state = "pink"
+
+
diff --git a/code/citadel/dogborgstuff.dm b/code/citadel/dogborgstuff.dm
index ee67fe96a8..9a6a6581c9 100644
--- a/code/citadel/dogborgstuff.dm
+++ b/code/citadel/dogborgstuff.dm
@@ -768,8 +768,8 @@
icon_state = "compactor"
inject_amount = 0
min_health = -100
- injection_chems = null
- var/max_item_count = 48
+ injection_chems = null //So they don't have all the same chems as the medihound!
+ var/max_item_count = 30
/obj/item/storage/attackby(obj/item/device/dogborg/sleeper/compactor, mob/user, proximity) //GIT CIRCUMVENTED YO!
compactor.afterattack(src, user ,1)
@@ -848,8 +848,8 @@
/mob/living/silicon/robot
var/leaping = 0
var/pounce_cooldown = 0
- var/pounce_cooldown_time = 40 //Nearly doubled, u happy?
- var/pounce_spoolup = 5
+ var/pounce_cooldown_time = 50 //Nearly doubled, u happy?
+ var/pounce_spoolup = 3
var/leap_at
var/disabler
var/laser
@@ -862,11 +862,10 @@
var/mob/living/silicon/robot/R = user
if(R && !R.pounce_cooldown)
R.pounce_cooldown = !R.pounce_cooldown
- playsound(R, 'sound/items/jaws_pry.ogg', 50, 1)
- playsound(R, 'sound/machines/buzz-sigh.ogg', 50, 1)
to_chat(R, "Your targeting systems lock on to [A]...")
- A.visible_message("[R]'s eyes flash brightly, staring directly at [A]!", "[R]'s eyes flash brightly, staring directly at you!'")
addtimer(CALLBACK(R, /mob/living/silicon/robot.proc/leap_at, A), R.pounce_spoolup)
+ spawn(R.pounce_cooldown_time)
+ R.pounce_cooldown = !R.pounce_cooldown
else if(R && R.pounce_cooldown)
to_chat(R, "Your leg actuators are still recharging!")
@@ -891,8 +890,6 @@
throw_at(A, MAX_K9_LEAP_DIST, 1, spin=0, diagonals_first = 1)
cell.use(500) //Doubled the energy consumption
weather_immunities -= "lava"
- spawn(pounce_cooldown_time)
- pounce_cooldown = !pounce_cooldown
/mob/living/silicon/robot/throw_impact(atom/A)
@@ -909,19 +906,20 @@
blocked = 1
if(!blocked)
L.visible_message("[src] pounces on [L]!", "[src] pounces on you!")
- L.Knockdown(40)
+ L.Knockdown(45)
playsound(src, 'sound/weapons/Egloves.ogg', 50, 1)
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
step_towards(src,L)
else
- Knockdown(40, 1, 1)
+ Knockdown(45, 1, 1)
pounce_cooldown = !pounce_cooldown
spawn(pounce_cooldown_time) //3s by default
pounce_cooldown = !pounce_cooldown
else if(A.density && !A.CanPass(src))
visible_message("[src] smashes into [A]!", "You smash into [A]!")
- Knockdown(40, 1, 1)
+ playsound(src, 'sound/items/trayhit1.ogg', 50, 1)
+ Knockdown(45, 1, 1)
if(leaping)
leaping = 0
diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm
index f2c9cd3315..ea79ba81f3 100644
--- a/code/controllers/configuration/entries/game_options.dm
+++ b/code/controllers/configuration/entries/game_options.dm
@@ -110,29 +110,7 @@ CONFIG_DEF(number/shuttle_refuel_delay)
CONFIG_DEF(flag/show_game_type_odds) //if set this allows players to see the odds of each roundtype on the get revision screen
-CONFIG_DEF(flag/join_with_mutant_race) //players can choose their mutant race before joining the game
-
-CONFIG_DEF(keyed_flag_list/roundstart_races) //races you can play as from the get go. If left undefined the game's roundstart var for species is used
- var/first_edit = TRUE
-
-/datum/config_entry/keyed_flag_list/roundstart_races/New()
- for(var/I in subtypesof(/datum/species))
- var/datum/species/S = I
- if(initial(S.roundstart))
- value[initial(S.id)] = TRUE
- ..()
-
-/datum/config_entry/keyed_flag_list/roundstart_races/ValidateAndSet(str_val)
- var/list/old_val
- if(first_edit)
- old_val = value
- old_val = old_val.Copy()
- . = ..()
- if(first_edit)
- if(!.)
- value = old_val
- else
- first_edit = FALSE
+CONFIG_DEF(keyed_flag_list/roundstart_races) //races you can play as from the get go.
CONFIG_DEF(flag/join_with_mutant_humans) //players can pick mutant bodyparts for humans before joining the game
@@ -188,7 +166,7 @@ CONFIG_DEF(number/run_delay) //Used for modifying movement speed for mobs.
CONFIG_DEF(number/walk_delay)
-
+
CONFIG_DEF(number/human_delay) //Mob specific modifiers. NOTE: These will affect different mob types in different ways
CONFIG_DEF(number/robot_delay)
CONFIG_DEF(number/monkey_delay)
diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm
index 689ff83935..ccfc041b21 100644
--- a/code/controllers/subsystem/garbage.dm
+++ b/code/controllers/subsystem/garbage.dm
@@ -362,9 +362,17 @@ SUBSYSTEM_DEF(garbage)
testing("Beginning search for references to a [type].")
last_find_references = world.time
- DoSearchVar(GLOB)
- for(var/datum/thing in world)
- DoSearchVar(thing, "WorldRef: [thing]")
+
+ DoSearchVar(GLOB) //globals
+ for(var/datum/thing in world) //atoms (don't beleive it's lies)
+ DoSearchVar(thing, "World -> [thing]")
+
+ for (var/datum/thing) //datums
+ DoSearchVar(thing, "World -> [thing]")
+
+ for (var/client/thing) //clients
+ DoSearchVar(thing, "World -> [thing]")
+
testing("Completed search for references to a [type].")
if(usr && usr.client)
usr.client.running_find_references = null
@@ -384,35 +392,44 @@ SUBSYSTEM_DEF(garbage)
if(!running_find_references)
find_references(TRUE)
-/datum/proc/DoSearchVar(X, Xname)
+/datum/proc/DoSearchVar(X, Xname, recursive_limit = 64)
if(usr && usr.client && !usr.client.running_find_references)
return
+ if (!recursive_limit)
+ return
+
if(istype(X, /datum))
var/datum/D = X
if(D.last_find_references == last_find_references)
return
+
D.last_find_references = last_find_references
- for(var/V in D.vars)
- for(var/varname in D.vars)
- var/variable = D.vars[varname]
- if(variable == src)
- testing("Found [src.type] \ref[src] in [D.type]'s [varname] var. [Xname]")
- else if(islist(variable))
- if(src in variable)
- testing("Found [src.type] \ref[src] in [D.type]'s [varname] list var. Global: [Xname]")
-#ifdef GC_FAILURE_HARD_LOOKUP
- for(var/I in variable)
- DoSearchVar(I, TRUE)
- else
- DoSearchVar(variable, "[Xname]: [varname]")
-#endif
+ var/list/L = D.vars
+
+ for(var/varname in L)
+ if (varname == "vars")
+ continue
+ var/variable = L[varname]
+
+ if(variable == src)
+ testing("Found [src.type] \ref[src] in [D.type]'s [varname] var. [Xname]")
+
+ else if(islist(variable))
+ DoSearchVar(variable, "[Xname] -> list", recursive_limit-1)
+
else if(islist(X))
- if(src in X)
- testing("Found [src.type] \ref[src] in list [Xname].")
-#ifdef GC_FAILURE_HARD_LOOKUP
+ var/normal = IS_NORMAL_LIST(X)
for(var/I in X)
- DoSearchVar(I, Xname + ": list")
-#else
+ if (I == src)
+ testing("Found [src.type] \ref[src] in list [Xname].")
+
+ else if (I && !isnum(I) && normal && X[I] == src)
+ testing("Found [src.type] \ref[src] in list [Xname]\[[I]\]")
+
+ else if (islist(I))
+ DoSearchVar(I, "[Xname] -> list", recursive_limit-1)
+
+#ifndef FIND_REF_NO_CHECK_TICK
CHECK_TICK
#endif
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index fa6ca7e26b..5645f0527f 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -18,6 +18,7 @@ SUBSYSTEM_DEF(job)
SetupOccupations()
if(CONFIG_GET(flag/load_jobs_from_txt))
LoadJobs()
+ generate_selectable_species()
..()
diff --git a/code/controllers/subsystem/processing/overlays.dm b/code/controllers/subsystem/processing/overlays.dm
index fba4ebcaf0..d7f260be0e 100644
--- a/code/controllers/subsystem/processing/overlays.dm
+++ b/code/controllers/subsystem/processing/overlays.dm
@@ -26,13 +26,32 @@ PROCESSING_SUBSYSTEM_DEF(overlays)
overlay_icon_cache = SSoverlays.overlay_icon_cache
processing = SSoverlays.processing
+#define COMPILE_OVERLAYS(A)\
+ var/list/oo = A.our_overlays;\
+ var/list/po = A.priority_overlays;\
+ if(LAZYLEN(po)){\
+ if(LAZYLEN(oo)){\
+ A.overlays = oo + po;\
+ }\
+ else{\
+ A.overlays = po;\
+ }\
+ }\
+ else if(LAZYLEN(oo)){\
+ A.overlays = oo;\
+ }\
+ else{\
+ A.overlays.Cut();\
+ }\
+ A.flags_1 &= ~OVERLAY_QUEUED_1
+
/datum/controller/subsystem/processing/overlays/fire(resumed = FALSE, mc_check = TRUE)
var/list/processing = src.processing
while(processing.len)
var/atom/thing = processing[processing.len]
processing.len--
if(thing)
- thing.compile_overlays()
+ COMPILE_OVERLAYS(thing)
if(mc_check)
if(MC_TICK_CHECK)
break
@@ -44,19 +63,6 @@ PROCESSING_SUBSYSTEM_DEF(overlays)
testing("Flushing [processing.len] overlays")
fire(mc_check = FALSE) //pair this thread up with the MC to get extra compile time
-/atom/proc/compile_overlays()
- var/list/oo = our_overlays
- var/list/po = priority_overlays
- if(LAZYLEN(po) && LAZYLEN(oo))
- overlays = oo + po
- else if(LAZYLEN(oo))
- overlays = oo
- else if(LAZYLEN(po))
- overlays = po
- else
- overlays.Cut()
- flags_1 &= ~OVERLAY_QUEUED_1
-
/proc/iconstate2appearance(icon, iconstate)
var/static/image/stringbro = new()
var/list/icon_states_cache = SSoverlays.overlay_icon_state_caches
@@ -83,23 +89,24 @@ PROCESSING_SUBSYSTEM_DEF(overlays)
. = iconbro.appearance
icon_cache[icon] = .
-/atom/proc/build_appearance_list(new_overlays)
+/atom/proc/build_appearance_list(old_overlays)
var/static/image/appearance_bro = new()
- if (!islist(new_overlays))
- new_overlays = list(new_overlays)
- else
- listclearnulls(new_overlays)
- for (var/i in 1 to length(new_overlays))
- var/image/cached_overlay = new_overlays[i]
- if (istext(cached_overlay))
- new_overlays[i] = iconstate2appearance(icon, cached_overlay)
- else if(isicon(cached_overlay))
- new_overlays[i] = icon2appearance(cached_overlay)
- else //image/mutable_appearance probable
- appearance_bro.appearance = cached_overlay
- if(!ispath(cached_overlay))
- appearance_bro.dir = cached_overlay.dir
- new_overlays[i] = appearance_bro.appearance
+ var/list/new_overlays = list()
+ if (!islist(old_overlays))
+ old_overlays = list(old_overlays)
+ for (var/overlay in old_overlays)
+ if(!overlay)
+ continue
+ if (istext(overlay))
+ new_overlays += iconstate2appearance(icon, overlay)
+ else if(isicon(overlay))
+ new_overlays += icon2appearance(overlay)
+ else
+ appearance_bro.appearance = overlay //this works for images and atoms too!
+ if(!ispath(overlay))
+ var/image/I = overlay
+ appearance_bro.dir = I.dir
+ new_overlays += appearance_bro.appearance
return new_overlays
#define NOT_QUEUED_ALREADY (!(flags_1 & OVERLAY_QUEUED_1))
@@ -136,7 +143,7 @@ PROCESSING_SUBSYSTEM_DEF(overlays)
if(priority)
LAZYREMOVE(cached_priority, overlays)
- if(NOT_QUEUED_ALREADY && ((init_o_len != LAZYLEN(cached_priority)) || (init_p_len != LAZYLEN(cached_overlays))))
+ if(NOT_QUEUED_ALREADY && ((init_o_len != LAZYLEN(cached_overlays)) || (init_p_len != LAZYLEN(cached_priority))))
QUEUE_FOR_COMPILE
/atom/proc/add_overlay(list/overlays, priority = FALSE)
diff --git a/code/controllers/subsystem/radiation.dm b/code/controllers/subsystem/radiation.dm
index 327d20732d..1dbe564169 100644
--- a/code/controllers/subsystem/radiation.dm
+++ b/code/controllers/subsystem/radiation.dm
@@ -1,4 +1,41 @@
PROCESSING_SUBSYSTEM_DEF(radiation)
name = "Radiation"
flags = SS_NO_INIT | SS_BACKGROUND
- priority = 25
\ No newline at end of file
+ priority = 25
+
+ var/list/warned_atoms = list()
+ var/list/next_warn = list()
+ var/last_warn = 0
+
+/datum/controller/subsystem/processing/radiation/proc/warn(datum/component/radioactive)
+ if(!radioactive || QDELETED(radioactive))
+ return
+ if(warned_atoms["\ref[radioactive.parent]"])
+ return
+ var/atom/master = radioactive.parent
+ SSblackbox.add_details("contaminated", "[master.type]")
+ next_warn["\ref[master]"] = "\ref[radioactive]"
+ var/wait_time = max(0, 500-(world.time-last_warn))+20 // wait at least 20 ticks, longer if we just messaged
+ addtimer(CALLBACK(src, .proc/send_warn), wait_time, TIMER_UNIQUE | TIMER_OVERRIDE)
+
+/datum/controller/subsystem/processing/radiation/proc/send_warn()
+ var/msg = "Atom(s) have become contaminated by radiation and are strong enough they could pass it on:"
+ var/still_alive = FALSE
+ var/list/next_warn = src.next_warn // It's free performance!
+ for(var/i in next_warn)
+ var/atom/parent = locate(i)
+ var/datum/component/radioactive/radioactive = locate(next_warn[i])
+ if(!parent || !istype(parent) || !radioactive || !istype(radioactive))
+ continue
+ if(!still_alive)
+ msg += "\n"
+ still_alive = TRUE
+ else
+ msg += ", "
+ msg += "[parent][ADMIN_VV(parent)]source:[radioactive.source]"
+ if(!still_alive)
+ return
+ warned_atoms += next_warn
+ src.next_warn = list()
+ last_warn = world.time
+ message_admins(msg)
\ No newline at end of file
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index 4b198d1e80..e1828b737a 100755
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -12,7 +12,7 @@ SUBSYSTEM_DEF(ticker)
var/force_ending = 0 //Round was ended by admin intervention
// If true, there is no lobby phase, the game starts immediately.
var/start_immediately = FALSE
- var/setup_done = FALSE //All game setup done including mode post setup and
+ var/setup_done = FALSE //All game setup done including mode post setup and
var/hide_mode = 0
var/datum/game_mode/mode = null
@@ -127,7 +127,7 @@ SUBSYSTEM_DEF(ticker)
login_music = pick(music)
else
login_music = "config/title_music/sounds/[pick(music)]"
-
+
crewobjlist = typesof(/datum/objective/crew)
miscreantobjlist = (typesof(/datum/objective/miscreant) - /datum/objective/miscreant)
@@ -141,6 +141,7 @@ SUBSYSTEM_DEF(ticker)
GLOB.syndicate_code_phrase = generate_code_phrase()
if(!GLOB.syndicate_code_response)
GLOB.syndicate_code_response = generate_code_phrase()
+
..()
start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10)
diff --git a/code/datums/antagonists/revolution.dm b/code/datums/antagonists/revolution.dm
index 79fae52a1d..fc501a55a7 100644
--- a/code/datums/antagonists/revolution.dm
+++ b/code/datums/antagonists/revolution.dm
@@ -84,7 +84,7 @@
hud_type = "rev_head"
var/remove_clumsy = FALSE
var/give_flash = FALSE
- var/give_hud = FALSE
+ var/give_hud = TRUE
/datum/antagonist/rev/proc/update_rev_icons_added(mob/living/M)
var/datum/atom_hud/antag/revhud = GLOB.huds[ANTAG_HUD_REV]
@@ -226,4 +226,4 @@
var/datum/antagonist/rev/rev = new_leader.has_antag_datum(/datum/antagonist/rev)
rev.promote()
- addtimer(CALLBACK(src,.proc/update_heads),HEAD_UPDATE_PERIOD,TIMER_UNIQUE)
\ No newline at end of file
+ addtimer(CALLBACK(src,.proc/update_heads),HEAD_UPDATE_PERIOD,TIMER_UNIQUE)
diff --git a/code/datums/callback.dm b/code/datums/callback.dm
index 0fc500e467..88d9427301 100644
--- a/code/datums/callback.dm
+++ b/code/datums/callback.dm
@@ -56,7 +56,7 @@
if (length(args) > 2)
arguments = args.Copy(3)
-/proc/ImmediateInvokeAsync(thingtocall, proctocall, ...)
+/world/proc/ImmediateInvokeAsync(thingtocall, proctocall, ...)
set waitfor = FALSE
if (!thingtocall)
diff --git a/code/datums/components/README.md b/code/datums/components/README.md
index 81218700c1..eeb6615a63 100644
--- a/code/datums/components/README.md
+++ b/code/datums/components/README.md
@@ -24,6 +24,10 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
## API
+### Defines
+
+1. `COMPONENT_INCOMPATIBLE` Return this from `/datum/component/Initialize` or `datum/component/OnTransfer` to have the component be deleted if it's applied to an incorrect type. `parent` must not be modified if this is to be returned.
+
### Vars
1. `/datum/var/list/datum_components` (private)
@@ -38,12 +42,13 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* `COMPONENT_DUPE_UNIQUE`: New component will be deleted, old component will first have `/datum/component/proc/InheritComponent(datum/component/new, TRUE)` on it
1. `/datum/component/var/dupe_type` (protected, type)
* Definition of a duplicate component type
- * `null` means exact match on `type`
+ * `null` means exact match on `type` (default)
* Any other type means that and all subtypes
1. `/datum/component/var/list/signal_procs` (private)
* Associated lazy list of signals -> `/datum/callback`s that will be run when the parent datum recieves that signal
1. `/datum/component/var/datum/parent` (protected, read-only)
* The datum this component belongs to
+ * Never `null` in child procs
### Procs
@@ -60,6 +65,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* Sends the `COMSIG_COMPONENT_ADDED` signal to the datum
* All components a datum owns are deleted with the datum
* Returns the component that was created. Or the old component in a dupe situation where `COMPONENT_DUPE_UNIQUE` was set
+ * If this tries to add an component to an incompatible type, the component will be deleted and the result will be `null`. This is very unperformant, try not to do it
1. `/datum/proc/LoadComponent(component_type(type), ...) -> datum/component` (public, final)
* Equivalent to calling `GetComponent(component_type)` where, if the result would be `null`, returns `AddComponent(component_type, ...)` instead
1. `/datum/proc/ComponentActivated(datum/component/C)` (abstract, async)
@@ -67,7 +73,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* Will only be called if a component's callback returns `TRUE`
1. `/datum/proc/TakeComponent(datum/component/C)` (public, final)
* Properly transfers ownership of a component from one datum to another
- * Singals `COMSIG_COMPONENT_REMOVING` on the parent
+ * Signals `COMSIG_COMPONENT_REMOVING` on the parent
* Called on the datum you want to own the component with another datum's component
1. `/datum/proc/SendSignal(signal, ...)` (public, final)
* Call to send a signal to the components of the target datum
@@ -80,6 +86,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* Component does not exist in `parent`'s `datum_components` list yet, although `parent` is set and may be used
* Signals will not be recieved while this function is running
* Component may be deleted after this function completes without being attached
+ * Do not call `qdel(src)` from this function
1. `/datum/component/Destroy()` (virtual, no-sleep)
* Sends the `COMSIG_COMPONENT_REMOVING` signal to the parent datum if the `parent` isn't being qdeleted
* Properly removes the component from `parent` and cleans up references
@@ -90,10 +97,13 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
1. `/datum/component/proc/AfterComponentActivated()` (abstract, async)
* Called on a component that was activated after it's `parent`'s `ComponentActivated()` is called
1. `/datum/component/proc/OnTransfer(datum/new_parent)` (abstract, no-sleep)
- * Called before the new `parent` is assigned in `TakeComponent()`, after the remove signal, before the added signal
+ * Called before `new_parent` is assigned to `parent` in `TakeComponent()`
* Allows the component to react to ownership transfers
-1. `/datum/component/proc/_RemoveNoSignal()` (private, final)
- * Internal, clears the parent var and removes the component from the parents component list
+1. `/datum/component/proc/_RemoveFromParent()` (private, final)
+ * Clears `parent` and removes the component from it's component list
+1. `/datum/component/proc/_CheckDupesAndJoinParent` (private, final)
+ * Tries to add the component to it's `parent`s `datum_components` list
+ * Properly handles duplicate situations based on the `dupe_mode` var
1. `/datum/component/proc/RegisterSignal(signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final) (Consider removing for performance gainz)
* If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments
* Makes a component listen for the specified `signal` on it's `parent` datum.
diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm
index a4c85f7816..4e187a6a08 100644
--- a/code/datums/components/_component.dm
+++ b/code/datums/components/_component.dm
@@ -9,29 +9,41 @@
parent = P
var/list/arguments = args.Copy()
arguments.Cut(1, 2)
- Initialize(arglist(arguments))
+ if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE)
+ parent = null
+ qdel(src)
+ return
+
+ _CheckDupesAndJoinParent(P)
+/datum/component/proc/_CheckDupesAndJoinParent()
+ var/datum/P = parent
var/dm = dupe_mode
+
+ var/datum/component/old
if(dm != COMPONENT_DUPE_ALLOWED)
var/dt = dupe_type
- var/datum/component/old
if(!dt)
old = P.GetExactComponent(type)
else
old = P.GetComponent(dt)
if(old)
+ //One or the other has to die
switch(dm)
if(COMPONENT_DUPE_UNIQUE)
old.InheritComponent(src, TRUE)
- parent = null //prevent COMPONENT_REMOVING signal
+ parent = null //prevent COMPONENT_REMOVING signal, no _RemoveFromParent because we aren't in their list yet
qdel(src)
return
if(COMPONENT_DUPE_HIGHLANDER)
InheritComponent(old, FALSE)
+ old._RemoveFromParent()
qdel(old)
-
- //let the others know
- P.SendSignal(COMSIG_COMPONENT_ADDED, src)
+
+ //provided we didn't eat someone
+ if(!old)
+ //let the others know
+ P.SendSignal(COMSIG_COMPONENT_ADDED, src)
//lazy init the parent's dc list
var/list/dc = P.datum_components
@@ -71,29 +83,28 @@
enabled = FALSE
var/datum/P = parent
if(P)
- _RemoveNoSignal()
+ _RemoveFromParent()
P.SendSignal(COMSIG_COMPONENT_REMOVING, src)
LAZYCLEARLIST(signal_procs)
return ..()
-/datum/component/proc/_RemoveNoSignal()
+/datum/component/proc/_RemoveFromParent()
var/datum/P = parent
- if(P)
- var/list/dc = P.datum_components
- var/our_type = type
- for(var/I in _GetInverseTypeList(our_type))
- var/list/components_of_type = dc[I]
- if(islist(components_of_type)) //
- var/list/subtracted = components_of_type - src
- if(subtracted.len == 1) //only 1 guy left
- dc[I] = subtracted[1] //make him special
- else
- dc[I] = subtracted
- else //just us
- dc -= I
- if(!dc.len)
- P.datum_components = null
- parent = null
+ var/list/dc = P.datum_components
+ var/our_type = type
+ for(var/I in _GetInverseTypeList(our_type))
+ var/list/components_of_type = dc[I]
+ if(islist(components_of_type)) //
+ var/list/subtracted = components_of_type - src
+ if(subtracted.len == 1) //only 1 guy left
+ dc[I] = subtracted[1] //make him special
+ else
+ dc[I] = subtracted
+ else //just us
+ dc -= I
+ if(!dc.len)
+ P.datum_components = null
+ parent = null
/datum/component/proc/RegisterSignal(sig_type_or_types, proc_on_self, override = FALSE)
if(QDELETED(src))
@@ -198,7 +209,7 @@
var/nt = new_type
args[1] = src
var/datum/component/C = new nt(arglist(args))
- return QDELING(C) ? GetComponent(new_type) : C
+ return QDELING(C) ? GetExactComponent(new_type) : C
/datum/proc/LoadComponent(component_type, ...)
. = GetComponent(component_type)
@@ -210,10 +221,23 @@
return
var/datum/helicopter = C.parent
if(helicopter == src)
- //wat
+ //if we're taking to the same thing no need for anything
return
- C._RemoveNoSignal()
+ if(C.OnTransfer(src) == COMPONENT_INCOMPATIBLE)
+ qdel(C)
+ return
+ C._RemoveFromParent()
helicopter.SendSignal(COMSIG_COMPONENT_REMOVING, C)
- C.OnTransfer(src)
C.parent = src
- SendSignal(COMSIG_COMPONENT_ADDED, C)
+ C._CheckDupesAndJoinParent()
+
+/datum/proc/TransferComponents(datum/target)
+ var/list/dc = datum_components
+ if(!dc)
+ return
+ var/comps = dc[/datum/component]
+ if(islist(comps))
+ for(var/I in comps)
+ target.TakeComponent(I)
+ else
+ target.TakeComponent(comps)
diff --git a/code/datums/components/radioactive.dm b/code/datums/components/radioactive.dm
index 1661056e8c..b0bf28f163 100644
--- a/code/datums/components/radioactive.dm
+++ b/code/datums/components/radioactive.dm
@@ -27,6 +27,9 @@
CRASH("Something that wasn't an atom was given /datum/component/radioactive")
return
+ if(strength > RAD_MINIMUM_CONTAMINATION)
+ SSradiation.warn(src)
+
START_PROCESSING(SSradiation, src)
/datum/component/radioactive/Destroy()
@@ -34,9 +37,8 @@
return ..()
/datum/component/radioactive/process()
- radiation_pulse(parent,strength,1,FALSE,can_contaminate)
-
if(hl3_release_date && prob(50))
+ radiation_pulse(parent, strength, RAD_DISTANCE_COEFFICIENT*2, FALSE, can_contaminate)
strength -= strength / hl3_release_date
if(strength <= RAD_BACKGROUND_RADIATION)
qdel(src)
@@ -48,7 +50,6 @@
return
var/datum/component/radioactive/other = C
strength = max(strength, other.strength)
- return
/datum/component/radioactive/proc/rad_examine(mob/user, atom/thing)
var/atom/master = parent
@@ -69,6 +70,7 @@
/datum/component/radioactive/proc/rad_attack(atom/movable/target, mob/living/user)
radiation_pulse(parent, strength/20)
target.rad_act(strength/2)
+ strength -= strength / hl3_release_date
#undef RAD_AMOUNT_LOW
#undef RAD_AMOUNT_MEDIUM
diff --git a/code/datums/components/spooky.dm b/code/datums/components/spooky.dm
new file mode 100644
index 0000000000..966baf7c4a
--- /dev/null
+++ b/code/datums/components/spooky.dm
@@ -0,0 +1,60 @@
+/datum/component/spooky
+ var/too_spooky = TRUE //will it spawn a new instrument?
+
+/datum/component/spooky/Initialize()
+ RegisterSignal(COMSIG_ITEM_ATTACK, .proc/spectral_attack)
+
+/datum/component/spooky/proc/spectral_attack(mob/living/carbon/C, mob/user)
+ if(ishuman(user)) //this weapon wasn't meant for mortals.
+ var/mob/living/carbon/human/U = user
+ if(!istype(U.dna.species, /datum/species/skeleton))
+ U.adjustStaminaLoss(35) //Extra Damage
+ U.Jitter(35)
+ U.stuttering = 20
+ if(U.getStaminaLoss() > 95)
+ to_chat(U, "Your ears weren't meant for this spectral sound.")
+ spectral_change(U)
+ return
+
+ if(ishuman(C))
+ var/mob/living/carbon/human/H = C
+ if(istype(H.dna.species, /datum/species/skeleton))
+ return ..() //undeads are unaffected by the spook-pocalypse.
+ if(istype(H.dna.species, /datum/species/zombie))
+ H.adjustStaminaLoss(25)
+ H.Knockdown(15) //zombies can't resist the doot
+ C.Jitter(35)
+ C.stuttering = 20
+ if((!istype(H.dna.species, /datum/species/skeleton)) && (!istype(H.dna.species, /datum/species/golem)) && (!istype(H.dna.species, /datum/species/android)) && (!istype(H.dna.species, /datum/species/jelly)))
+ C.adjustStaminaLoss(25) //boneless humanoids don't lose the will to live
+ to_chat(C, "DOOT")
+ spectral_change(H)
+
+ else //the sound will spook monkeys.
+ C.Jitter(15)
+ C.stuttering = 20
+
+/datum/component/spooky/proc/spectral_change(mob/living/carbon/human/H, mob/user)
+ if((H.getStaminaLoss() > 95) && (!istype(H.dna.species, /datum/species/skeleton)) && (!istype(H.dna.species, /datum/species/golem)) && (!istype(H.dna.species, /datum/species/android)) && (!istype(H.dna.species, /datum/species/jelly)))
+ H.Knockdown(20)
+ H.set_species(/datum/species/skeleton)
+ H.visible_message("[H] has given up on life as a mortal.")
+ var/T = get_turf(H)
+ if(too_spooky)
+ if(prob(30))
+ new/obj/item/device/instrument/saxophone/spectral(T)
+ else if(prob(30))
+ new/obj/item/device/instrument/trumpet/spectral(T)
+ else if(prob(30))
+ new/obj/item/device/instrument/trombone/spectral(T)
+ else
+ to_chat(H, "The spooky gods forgot to ship your instrument. Better luck next unlife.")
+ to_chat(H, "You are the spooky skeleton!")
+ to_chat(H, "A new life and identity has begun. Help your fellow skeletons into bringing out the spooky-pocalypse. You haven't forgotten your past life, and are still beholden to past loyalties.")
+ change_name(H) //time for a new name!
+
+/datum/component/spooky/proc/change_name(mob/living/carbon/human/H)
+ var/t = stripped_input(H, "Enter your new skeleton name", H.real_name, null, MAX_NAME_LEN)
+ if(!t)
+ t = "spooky skeleton"
+ H.fully_replace_character_name(H.real_name, t)
diff --git a/code/datums/components/thermite.dm b/code/datums/components/thermite.dm
new file mode 100644
index 0000000000..7418e5d7b4
--- /dev/null
+++ b/code/datums/components/thermite.dm
@@ -0,0 +1,64 @@
+/datum/component/thermite
+ dupe_mode = COMPONENT_DUPE_UNIQUE
+ var/amount
+ var/overlay
+
+ var/static/list/blacklist = typecacheof(/turf/closed/wall/mineral/diamond)
+ var/static/list/resistlist = typecacheof(/turf/closed/wall/r_wall)
+
+/datum/component/thermite/Initialize(_amount)
+ if(!istype(parent, /turf))
+ return COMPONENT_INCOMPATIBLE
+ if(blacklist[parent.type])
+ _amount*=0 //Yeah the overlay can still go on it and be cleaned but you arent burning down a diamond wall
+ if(resistlist[parent.type])
+ _amount*=0.25
+
+ amount = _amount*10
+
+ var/turf/master = parent
+ overlay = mutable_appearance('icons/effects/effects.dmi', "thermite")
+ master.add_overlay(overlay)
+
+ RegisterSignal(COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
+ RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/attackby_react)
+ RegisterSignal(COMSIG_ATOM_FIRE_ACT, .proc/flame_react)
+
+/datum/component/thermite/Destroy()
+ var/turf/master = parent
+ master.cut_overlay(overlay)
+ return ..()
+
+/datum/component/thermite/InheritComponent(datum/component/thermite/newC, i_am_original)
+ if(!i_am_original)
+ return
+ amount += newC.amount
+
+/datum/component/thermite/proc/thermite_melt(mob/user)
+ var/turf/master = parent
+ master.cut_overlay(overlay)
+ var/obj/effect/overlay/thermite/fakefire = new(master)
+
+ playsound(master, 'sound/items/welder.ogg', 100, 1)
+
+ if(amount >= 50)
+ var/burning_time = max(100, 100-amount)
+ master = master.ChangeTurf(master.baseturf)
+ master.burn_tile()
+ if(user)
+ master.add_hiddenprint(user)
+ QDEL_IN(fakefire, burning_time)
+ else
+ QDEL_IN(fakefire, 50)
+
+/datum/component/thermite/proc/clean_react(strength)
+ //Thermite is just some loose powder, you could probably clean it with your hands. << todo?
+ qdel(src)
+
+/datum/component/thermite/proc/flame_react(exposed_temperature, exposed_volume)
+ if(exposed_temperature > 1922) // This is roughly the real life requirement to ignite thermite
+ thermite_melt()
+
+/datum/component/thermite/proc/attackby_react(obj/item/thing, mob/user, params)
+ if(thing.is_hot())
+ thermite_melt(user)
\ No newline at end of file
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index 5ed8dcf733..5f9cf3ad9a 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -224,8 +224,7 @@
G.fields["name"] = H.real_name
G.fields["rank"] = assignment
G.fields["age"] = H.age
- if(CONFIG_GET(flag/join_with_mutant_race))
- G.fields["species"] = H.dna.species.name
+ G.fields["species"] = H.dna.species.name
G.fields["fingerprint"] = md5(H.dna.uni_identity)
G.fields["p_stat"] = "Active"
G.fields["m_stat"] = "Stable"
diff --git a/code/datums/datum.dm b/code/datums/datum.dm
index cd589fd8c3..f7b15035d1 100644
--- a/code/datums/datum.dm
+++ b/code/datums/datum.dm
@@ -27,11 +27,11 @@
if(islist(all_components))
for(var/I in all_components)
var/datum/component/C = I
- C._RemoveNoSignal()
+ C._RemoveFromParent()
qdel(C)
else
var/datum/component/C = all_components
- C._RemoveNoSignal()
+ C._RemoveFromParent()
qdel(C)
dc.Cut()
return QDEL_HINT_QUEUE
diff --git a/code/datums/diseases/advance/symptoms/deafness.dm b/code/datums/diseases/advance/symptoms/deafness.dm
index c2afb34a9e..cc388f0b59 100644
--- a/code/datums/diseases/advance/symptoms/deafness.dm
+++ b/code/datums/diseases/advance/symptoms/deafness.dm
@@ -49,7 +49,7 @@ Bonus
to_chat(M, "[pick("You hear a ringing in your ear.", "Your ears pop.")]")
if(5)
if(power > 2)
- var/obj/item/organ/ears/ears = M.getorganslot("ears")
+ var/obj/item/organ/ears/ears = M.getorganslot(ORGAN_SLOT_EARS)
if(istype(ears) && ears.ear_damage < UNHEALING_EAR_DAMAGE)
to_chat(M, "Your ears pop painfully and start bleeding!")
ears.ear_damage = max(ears.ear_damage, UNHEALING_EAR_DAMAGE)
diff --git a/code/datums/diseases/advance/symptoms/vision.dm b/code/datums/diseases/advance/symptoms/vision.dm
index 84f9ef49cc..728dfa01d0 100644
--- a/code/datums/diseases/advance/symptoms/vision.dm
+++ b/code/datums/diseases/advance/symptoms/vision.dm
@@ -44,7 +44,7 @@ Bonus
if(!..())
return
var/mob/living/carbon/M = A.affected_mob
- var/obj/item/organ/eyes/eyes = M.getorganslot("eye_sight")
+ var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES)
if(istype(eyes))
switch(A.stage)
if(1, 2)
@@ -106,7 +106,7 @@ Bonus
if(!..())
return
var/mob/living/M = A.affected_mob
- var/obj/item/organ/eyes/eyes = M.getorganslot("eye_sight")
+ var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES)
if (!eyes)
return
switch(A.stage)
diff --git a/code/datums/dna.dm b/code/datums/dna.dm
index 12555ee038..3987b49750 100644
--- a/code/datums/dna.dm
+++ b/code/datums/dna.dm
@@ -263,7 +263,7 @@
/mob/living/carbon/proc/create_dna()
dna = new /datum/dna(src)
if(!dna.species)
- var/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races))
+ var/rando_race = pick(GLOB.roundstart_races)
dna.species = new rando_race()
//proc used to update the mob's appearance after its dna UI has been changed
diff --git a/code/datums/hud.dm b/code/datums/hud.dm
index 60a53967ae..98d2c9258a 100644
--- a/code/datums/hud.dm
+++ b/code/datums/hud.dm
@@ -20,7 +20,6 @@ GLOBAL_LIST_INIT(huds, list(
ANTAG_HUD_SINTOUCHED = new/datum/atom_hud/antag/hidden(),
ANTAG_HUD_SOULLESS = new/datum/atom_hud/antag/hidden(),
ANTAG_HUD_CLOCKWORK = new/datum/atom_hud/antag(),
- ANTAG_HUD_BORER = new/datum/atom_hud/antag(),
ANTAG_HUD_BROTHER = new/datum/atom_hud/antag/hidden(),
))
diff --git a/code/datums/looping_sounds/item_sounds.dm b/code/datums/looping_sounds/item_sounds.dm
new file mode 100644
index 0000000000..2eb897bc13
--- /dev/null
+++ b/code/datums/looping_sounds/item_sounds.dm
@@ -0,0 +1,37 @@
+#define RAD_GEIGER_LOW 100 // Geiger counter sound thresholds
+#define RAD_GEIGER_MEDIUM 500
+#define RAD_GEIGER_HIGH 1000
+
+/datum/looping_sound/geiger
+ mid_sounds = list(
+ list('sound/items/geiger/low1.ogg'=1, 'sound/items/geiger/low2.ogg'=1, 'sound/items/geiger/low3.ogg'=1, 'sound/items/geiger/low4.ogg'=1),
+ list('sound/items/geiger/med1.ogg'=1, 'sound/items/geiger/med2.ogg'=1, 'sound/items/geiger/med3.ogg'=1, 'sound/items/geiger/med4.ogg'=1),
+ list('sound/items/geiger/high1.ogg'=1, 'sound/items/geiger/high2.ogg'=1, 'sound/items/geiger/high3.ogg'=1, 'sound/items/geiger/high4.ogg'=1),
+ list('sound/items/geiger/ext1.ogg'=1, 'sound/items/geiger/ext2.ogg'=1, 'sound/items/geiger/ext3.ogg'=1, 'sound/items/geiger/ext4.ogg'=1)
+ )
+ mid_length = 2
+ volume = 25
+ var/last_radiation
+
+/datum/looping_sound/geiger/get_sound(looped)
+ var/danger
+ switch(last_radiation)
+ if(RAD_BACKGROUND_RADIATION to RAD_GEIGER_LOW)
+ danger = 1
+ if(RAD_GEIGER_LOW to RAD_GEIGER_MEDIUM)
+ danger = 2
+ if(RAD_GEIGER_MEDIUM to RAD_GEIGER_HIGH)
+ danger = 3
+ if(RAD_GEIGER_HIGH to INFINITY)
+ danger = 4
+ else
+ return null
+ return ..(looped, mid_sounds[danger])
+
+/datum/looping_sound/geiger/stop()
+ . = ..()
+ last_radiation = 0
+
+#undef RAD_GEIGER_LOW
+#undef RAD_GEIGER_MEDIUM
+#undef RAD_GEIGER_HIGH
\ No newline at end of file
diff --git a/code/datums/looping_sounds/looping_sound.dm b/code/datums/looping_sounds/looping_sound.dm
index 2374da67b4..aed7c3ace8 100644
--- a/code/datums/looping_sounds/looping_sound.dm
+++ b/code/datums/looping_sounds/looping_sound.dm
@@ -1,5 +1,5 @@
/*
- list/atom/output_atoms
+ output_atoms (list of atoms) The destination(s) for the sounds
mid_sounds (list or soundfile) Since this can be either a list or a single soundfile you can have random sounds. May contain further lists but must contain a soundfile at the end.
mid_length (num) The length to wait between playing mid_sounds
@@ -13,6 +13,7 @@
volume (num) Sound output volume
muted (bool) Private. Used to stop the sound loop.
max_loops (num) The max amount of loops to run for.
+ direct (bool) If true plays directly to provided atoms instead of from them
*/
/datum/looping_sound
var/list/atom/output_atoms
@@ -22,19 +23,18 @@
var/start_length
var/end_sound
var/chance
- var/volume
+ var/volume = 100
var/muted = TRUE
var/max_loops
+ var/direct
-/datum/looping_sound/New(list/_output_atoms, start_immediately=FALSE)
+/datum/looping_sound/New(list/_output_atoms=list(), start_immediately=FALSE, _direct=FALSE)
if(!mid_sounds)
WARNING("A looping sound datum was created without sounds to play.")
return
- if(_output_atoms)
- output_atoms = _output_atoms
- else
- output_atoms = list()
+ output_atoms = _output_atoms
+ direct = _direct
if(start_immediately)
start()
@@ -44,13 +44,17 @@
output_atoms = null
return ..()
-/datum/looping_sound/proc/start()
+/datum/looping_sound/proc/start(atom/add_thing)
+ if(add_thing)
+ output_atoms |= add_thing
if(!muted)
return
muted = FALSE
on_start()
-/datum/looping_sound/proc/stop()
+/datum/looping_sound/proc/stop(atom/remove_thing)
+ if(remove_thing)
+ output_atoms -= remove_thing
if(muted)
return
muted = TRUE
@@ -65,9 +69,16 @@
/datum/looping_sound/proc/play(soundfile)
var/list/atoms_cache = output_atoms
+ var/sound/S = sound(soundfile)
+ if(direct)
+ S.channel = open_sound_channel()
+ S.volume = volume
for(var/i in 1 to atoms_cache.len)
var/atom/thing = atoms_cache[i]
- playsound(thing, soundfile, volume)
+ if(direct)
+ SEND_SOUND(thing, S)
+ else
+ playsound(thing, S, volume)
/datum/looping_sound/proc/get_sound(looped, _mid_sounds)
if(!_mid_sounds)
diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm
index 88b2b06878..e8c2f4f05e 100644
--- a/code/datums/looping_sounds/machinery_sounds.dm
+++ b/code/datums/looping_sounds/machinery_sounds.dm
@@ -6,4 +6,19 @@
end_sound = 'sound/machines/shower/shower_end.ogg'
volume = 25
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/datum/looping_sound/supermatter
+ mid_sounds = list('sound/machines/sm/supermatter1.ogg'=1,'sound/machines/sm/supermatter2.ogg'=1,'sound/machines/sm/supermatter3.ogg'=1)
+ mid_length = 6
+ volume = 1
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/datum/looping_sound/generator
+ start_sound = 'sound/machines/generator/generator_start.ogg'
+ start_length = 4
+ mid_sounds = list('sound/machines/generator/generator_mid1.ogg'=1, 'sound/machines/generator/generator_mid2.ogg'=1, 'sound/machines/generator/generator_mid3.ogg'=1)
+ mid_length = 4
+ end_sound = 'sound/machines/generator/generator_end.ogg'
+ volume = 40
\ No newline at end of file
diff --git a/code/datums/map_config.dm b/code/datums/map_config.dm
index 2fb74abfb9..885407ef90 100644
--- a/code/datums/map_config.dm
+++ b/code/datums/map_config.dm
@@ -13,7 +13,6 @@
//Order matters here.
var/list/transition_config = list(CENTCOM = SELFLOOPING,
- CITY_OF_COGS = SELFLOOPING,
MAIN_STATION = CROSSLINKED,
EMPTY_AREA_1 = CROSSLINKED,
EMPTY_AREA_2 = CROSSLINKED,
@@ -69,12 +68,11 @@
map_path = json["map_path"]
map_file = json["map_file"]
- minetype = json["minetype"]
- allow_custom_shuttles = json["allow_custom_shuttles"]
+ minetype = json["minetype"] || minetype
+ allow_custom_shuttles = json["allow_custom_shuttles"] == TRUE
- var/list/jtcl = json["transition_config"]
-
- if(jtcl != "default")
+ var/jtcl = json["transition_config"]
+ if(jtcl && jtcl != "default")
transition_config.Cut()
for(var/I in jtcl)
@@ -87,25 +85,22 @@
CHECK_EXISTS("map_name")
CHECK_EXISTS("map_path")
CHECK_EXISTS("map_file")
- CHECK_EXISTS("minetype")
- CHECK_EXISTS("transition_config")
- CHECK_EXISTS("allow_custom_shuttles")
var/path = GetFullMapPath(json["map_path"], json["map_file"])
if(!fexists(path))
log_world("Map file ([path]) does not exist!")
return
- if(json["transition_config"] != "default")
- if(!islist(json["transition_config"]))
+ var/tc = json["transition_config"]
+ if(tc != null && tc != "default")
+ if(!islist(tc))
log_world("transition_config is not a list!")
return
- var/list/jtcl = json["transition_config"]
- for(var/I in jtcl)
+ for(var/I in tc)
if(isnull(TransitionStringToEnum(I)))
log_world("Invalid transition_config option: [I]!")
- if(isnull(TransitionStringToEnum(jtcl[I])))
+ if(isnull(TransitionStringToEnum(tc[I])))
log_world("Invalid transition_config option: [I]!")
return TRUE
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 4036aaaf45..7d70940512 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -64,6 +64,7 @@
var/mob/living/enslaved_to //If this mind's master is another mob (i.e. adamantine golems)
var/datum/language_holder/language_holder
var/unconvertable = FALSE
+ var/late_joiner = FALSE
/datum/mind/New(var/key)
src.key = key
@@ -232,8 +233,9 @@
/datum/mind/proc/remove_rev()
var/datum/antagonist/rev/rev = has_antag_datum(/datum/antagonist/rev)
- remove_antag_datum(rev.type)
- special_role = null
+ if(rev)
+ remove_antag_datum(rev.type)
+ special_role = null
/datum/mind/proc/remove_antag_equip()
var/list/Mob_Contents = current.get_contents()
@@ -1037,7 +1039,7 @@
remove_wizard()
log_admin("[key_name(usr)] has de-wizard'ed [current].")
if("wizard")
- if(has_antag_datum(/datum/antagonist/wizard))
+ if(!has_antag_datum(/datum/antagonist/wizard))
special_role = "Wizard"
add_antag_datum(/datum/antagonist/wizard)
message_admins("[key_name_admin(usr)] has wizard'ed [current].")
diff --git a/code/datums/profiling.dm b/code/datums/profiling.dm
new file mode 100644
index 0000000000..49a80d0ede
--- /dev/null
+++ b/code/datums/profiling.dm
@@ -0,0 +1,18 @@
+//these are real globals so you can use profiling to profile early world init stuff.
+GLOBAL_REAL_VAR(list/PROFILE_STORE)
+GLOBAL_REAL_VAR(PROFILE_LINE)
+GLOBAL_REAL_VAR(PROFILE_FILE)
+GLOBAL_REAL_VAR(PROFILE_SLEEPCHECK)
+GLOBAL_REAL_VAR(PROFILE_TIME)
+
+
+/proc/profile_show(user, sort = /proc/cmp_profile_avg_time_dsc)
+ sortTim(PROFILE_STORE, sort, TRUE)
+
+ var/list/lines = list()
+
+ for (var/entry in PROFILE_STORE)
+ var/list/data = PROFILE_STORE[entry]
+ lines += "[entry] => [num2text(data[PROFILE_ITEM_TIME], 10)]ms ([data[PROFILE_ITEM_COUNT]]) (avg:[num2text(data[PROFILE_ITEM_TIME]/(data[PROFILE_ITEM_COUNT] || 1), 99)])"
+
+ user << browse("
", "window=[url_encode(GUID())]")
diff --git a/code/datums/radiation_wave.dm b/code/datums/radiation_wave.dm
index 5a02997b00..ffc6b75fcb 100644
--- a/code/datums/radiation_wave.dm
+++ b/code/datums/radiation_wave.dm
@@ -89,18 +89,24 @@
continue
thing.rad_act(strength)
- var/static/list/blacklisted = typecacheof(list( //These types will never be contaminated
+ // This list should only be for types which don't get contaminated but you want to look in their contents
+ // If you don't want to look in their contents and you don't want to rad_act them:
+ // modify the ignored_things list in __HELPERS/radiation.dm instead
+ var/static/list/blacklisted = typecacheof(list(
/turf,
/mob,
/obj/structure/cable,
- /obj/machinery/atmospherics
+ /obj/machinery/atmospherics,
+ /obj/item/ammo_casing,
+ /obj/item/implant
))
if(!can_contaminate || blacklisted[thing.type])
continue
- if(prob((strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_CHANCE_COEFFICIENT * min(1/(steps*range_modifier), 1))) // Only stronk rads get to have little baby rads
+ var/contamination_chance = (strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_CHANCE_COEFFICIENT * min(1, 1/(steps*range_modifier))
+ if(prob(contamination_chance)) // Only stronk rads get to have little baby rads
var/datum/component/rad_insulation/insulation = thing.GetComponent(/datum/component/rad_insulation)
if(insulation && insulation.contamination_proof)
continue
else
- var/rad_strength = (strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_STR_COEFFICIENT * min(1/(steps*range_modifier), 1)
+ var/rad_strength = (strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_STR_COEFFICIENT
thing.AddComponent(/datum/component/radioactive, rad_strength, source)
\ No newline at end of file
diff --git a/code/datums/spawners_menu.dm b/code/datums/spawners_menu.dm
index cc031d70bb..a9fd77d1e2 100644
--- a/code/datums/spawners_menu.dm
+++ b/code/datums/spawners_menu.dm
@@ -23,8 +23,12 @@
for(var/spawner_obj in GLOB.mob_spawners[spawner])
this["refs"] += "\ref[spawner_obj]"
if(!this["desc"])
- var/obj/effect/mob_spawn/MS = spawner_obj
- this["desc"] = MS.flavour_text
+ if(istype(spawner_obj, /obj/effect/mob_spawn))
+ var/obj/effect/mob_spawn/MS = spawner_obj
+ this["desc"] = MS.flavour_text
+ else
+ var/obj/O = spawner_obj
+ this["desc"] = O.desc
this["amount_left"] = LAZYLEN(GLOB.mob_spawners[spawner])
data["spawners"] += list(this)
diff --git a/code/game/area/Space_Station_13_areas.dm b/code/game/area/Space_Station_13_areas.dm
index c4b5c5caae..66dafe2e8f 100644
--- a/code/game/area/Space_Station_13_areas.dm
+++ b/code/game/area/Space_Station_13_areas.dm
@@ -649,6 +649,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "chapel"
ambientsounds = list('sound/ambience/ambicha1.ogg','sound/ambience/ambicha2.ogg','sound/ambience/ambicha3.ogg','sound/ambience/ambicha4.ogg')
flags_1 = NONE
+ clockwork_warp_allowed = FALSE
+ clockwork_warp_fail = "The consecration here prevents you from warping in."
/area/chapel/main
name = "Chapel"
@@ -706,6 +708,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/engine/gravity_generator
name = "Gravity Generator Room"
icon_state = "grav_gen"
+ clockwork_warp_allowed = FALSE
+ clockwork_warp_fail = "The gravitons generated here could throw off your warp's destination and possibly throw you into deep space."
/area/engine/secure_construction
name = "Secure Construction Area"
@@ -1276,10 +1280,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/storage/eva
name = "EVA Storage"
icon_state = "eva"
+ clockwork_warp_allowed = FALSE
/area/storage/secure
name = "Secure Storage"
icon_state = "storage"
+ clockwork_warp_allowed = FALSE
/area/storage/emergency/starboard
name = "Starboard Emergency Storage"
@@ -1442,6 +1448,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
// Telecommunications Satellite
/area/tcommsat
+ clockwork_warp_allowed = FALSE
+ clockwork_warp_fail = "For safety reasons, warping here is disallowed; the radio and bluespace noise could cause catastrophic results."
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
/area/tcommsat/entrance
diff --git a/code/game/area/ai_monitored.dm b/code/game/area/ai_monitored.dm
index 75548ff81e..e21d4e273b 100644
--- a/code/game/area/ai_monitored.dm
+++ b/code/game/area/ai_monitored.dm
@@ -1,5 +1,6 @@
/area/ai_monitored
name = "AI Monitored Area"
+ clockwork_warp_allowed = FALSE
var/list/obj/machinery/camera/motioncameras = list()
var/list/motionTargets = list()
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index ac2fa4be01..2d372d4c33 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -14,6 +14,8 @@
var/valid_territory = TRUE // If it's a valid territory for gangs to claim
var/blob_allowed = TRUE // Does it count for blobs score? By default, all areas count.
+ var/clockwork_warp_allowed = TRUE // Can servants warp into this area from Reebe?
+ var/clockwork_warp_fail = "The structure there is too dense for warping to pierce. (This is normal in high-security areas.)"
var/eject = null
diff --git a/code/game/area/areas/shuttles.dm b/code/game/area/areas/shuttles.dm
index 68ab30478d..21f74972c9 100644
--- a/code/game/area/areas/shuttles.dm
+++ b/code/game/area/areas/shuttles.dm
@@ -72,6 +72,10 @@
/area/shuttle/escape
name = "Emergency Shuttle"
+/area/shuttle/escape/luxury
+ name = "Luxurious Emergency Shuttle"
+ noteleport = TRUE
+
/area/shuttle/transport
name = "Transport Shuttle"
blob_allowed = FALSE
diff --git a/code/game/gamemodes/antag_spawner_cit.dm b/code/game/gamemodes/antag_spawner_cit.dm
index 34e72d9004..4cdc096072 100644
--- a/code/game/gamemodes/antag_spawner_cit.dm
+++ b/code/game/gamemodes/antag_spawner_cit.dm
@@ -26,7 +26,7 @@ obj/item/antag_spawner/syndi_borer/spawn_antag(client/C, turf/T, mob/owner)
to_chat(B, "You are awake at last! Seek out whoever released you and aid them as best you can!")
if(new_objective)
to_chat(B, "Objective #[1]: [new_objective.explanation_text]")
- SSticker.mode.update_borer_icons_added(B)
+
/obj/item/antag_spawner/syndi_borer/proc/check_usability(mob/user)
if(used)
to_chat(user, "[src] appears to be empty!")
diff --git a/code/game/gamemodes/changeling/evolution_menu.dm b/code/game/gamemodes/changeling/evolution_menu.dm
index 59ed4ab2e8..76a37f9bb1 100644
--- a/code/game/gamemodes/changeling/evolution_menu.dm
+++ b/code/game/gamemodes/changeling/evolution_menu.dm
@@ -75,7 +75,7 @@
var/datum/changelingprofile/prof = mind.changeling.add_new_profile(C, src)
mind.changeling.first_prof = prof
- var/obj/item/organ/brain/B = C.getorganslot("brain")
+ var/obj/item/organ/brain/B = C.getorganslot(ORGAN_SLOT_BRAIN)
if(B)
B.vital = FALSE
B.decoy_override = TRUE
diff --git a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm
index b2ddd022a4..f48464700f 100644
--- a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm
+++ b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm
@@ -10,7 +10,7 @@
active = FALSE
/obj/effect/proc_holder/changeling/augmented_eyesight/on_purchase(mob/user) //The ability starts inactive, so we should be protected from flashes.
- var/obj/item/organ/eyes/E = user.getorganslot("eye_sight")
+ var/obj/item/organ/eyes/E = user.getorganslot(ORGAN_SLOT_EYES)
if (E)
E.flash_protect = 2 //Adjust the user's eyes' flash protection
to_chat(user, "We adjust our eyes to protect them from bright lights.")
@@ -20,7 +20,7 @@
/obj/effect/proc_holder/changeling/augmented_eyesight/sting_action(mob/living/carbon/human/user)
if(!istype(user))
return
- var/obj/item/organ/eyes/E = user.getorganslot("eye_sight")
+ var/obj/item/organ/eyes/E = user.getorganslot(ORGAN_SLOT_EYES)
if(E)
if(!active)
E.sight_flags |= SEE_MOBS | SEE_OBJS | SEE_TURFS //Add sight flags to the user's eyes
@@ -42,7 +42,7 @@
/obj/effect/proc_holder/changeling/augmented_eyesight/on_refund(mob/user) //Get rid of x-ray vision and flash protection when the user refunds this ability
- var/obj/item/organ/eyes/E = user.getorganslot("eye_sight")
+ var/obj/item/organ/eyes/E = user.getorganslot(ORGAN_SLOT_EYES)
if(E)
if (active)
E.sight_flags ^= SEE_MOBS | SEE_OBJS | SEE_TURFS
diff --git a/code/game/gamemodes/changeling/powers/regenerate.dm b/code/game/gamemodes/changeling/powers/regenerate.dm
index a74b966bd8..f2b13a5d09 100644
--- a/code/game/gamemodes/changeling/powers/regenerate.dm
+++ b/code/game/gamemodes/changeling/powers/regenerate.dm
@@ -27,7 +27,7 @@
C.emote("scream")
C.regenerate_limbs(1)
C.regenerate_organs()
- if(!user.getorganslot("brain"))
+ if(!user.getorganslot(ORGAN_SLOT_BRAIN))
var/obj/item/organ/brain/changeling_brain/B = new()
B.Insert(C)
if(ishuman(user))
diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm
index 803514adcb..d9d47bd771 100644
--- a/code/game/gamemodes/clock_cult/clock_cult.dm
+++ b/code/game/gamemodes/clock_cult/clock_cult.dm
@@ -1,3 +1,5 @@
+GLOBAL_VAR_INIT(servants_active, FALSE) //This var controls whether or not a lot of the cult's structures work or not
+
/*
CLOCKWORK CULT: Based off of the failed pull requests from /vg/
@@ -143,11 +145,7 @@ Credit where due:
equip_servant(L)
add_servant_of_ratvar(L, TRUE)
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar //that's a mouthful
- G.initial_activation_delay = ark_time * 60
- G.seconds_until_activation = ark_time * 60 //60 seconds in a minute * number of minutes
- for(var/obj/item/clockwork/construct_chassis/cogscarab/C in GLOB.all_clockwork_objects)
- C.infinite_resources = FALSE
- SSshuttle.registerHostileEnvironment(GLOB.ark_of_the_clockwork_justiciar)
+ G.final_countdown(ark_time)
..()
return 1
diff --git a/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm b/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm
index 0b7738961a..acf6e43974 100644
--- a/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm
@@ -15,11 +15,14 @@
. = ..()
var/area/A = get_area(src)
if(A && construct_type)
- notify_ghosts("A [construct_name] chassis has been created in [A.name]!", 'sound/magic/clockwork/fellowship_armory.ogg', source = src, action = NOTIFY_ORBIT, flashwindow = FALSE)
+ notify_ghosts("A [construct_name] chassis has been created in [A.name]!", 'sound/magic/clockwork/fellowship_armory.ogg', source = src, action = NOTIFY_ATTACK, flashwindow = FALSE)
GLOB.poi_list += src
+ LAZYADD(GLOB.mob_spawners[name], src)
/obj/item/clockwork/construct_chassis/Destroy()
GLOB.poi_list -= src
+ var/list/spawners = GLOB.mob_spawners[name]
+ LAZYREMOVE(spawners, src)
. = ..()
/obj/item/clockwork/construct_chassis/examine(mob/user)
@@ -37,6 +40,7 @@
if(!SSticker.mode)
to_chat(user, "You cannot use that before the game has started.")
return
+ user.forceMove(get_turf(src)) //If we attack through the alert, jump to the chassis so we know what we're getting into
if(alert(user, "Become a [construct_name]? You can no longer be cloned!", construct_name, "Yes", "Cancel") == "Cancel")
return
if(QDELETED(src))
@@ -82,7 +86,7 @@
/obj/item/clockwork/construct_chassis/cogscarab/Initialize()
. = ..()
- if(istype(SSticker.mode, /datum/game_mode/clockwork_cult))
+ if(GLOB.servants_active)
infinite_resources = FALSE //For any that are somehow spawned in late
/obj/item/clockwork/construct_chassis/cogscarab/pre_spawn()
diff --git a/code/game/gamemodes/clock_cult/clock_mobs.dm b/code/game/gamemodes/clock_cult/clock_mobs.dm
index 37933514f8..bd9c52b19f 100644
--- a/code/game/gamemodes/clock_cult/clock_mobs.dm
+++ b/code/game/gamemodes/clock_cult/clock_mobs.dm
@@ -54,8 +54,14 @@
else
msg += "[t_He] look[t_s] severely dented!\n"
msg += ""
+ var/addendum = examine_info()
+ if(addendum)
+ msg += "[addendum]\n"
msg += "*---------*"
to_chat(user, msg)
+/mob/living/simple_animal/hostile/clockwork/proc/examine_info() //Override this on a by-mob basis to have unique examine info
+ return
+
/mob/living/simple_animal/hostile/clockwork/proc/update_values() //This is called by certain things to check GLOB.ratvar_awakens and GLOB.ratvar_approaches
diff --git a/code/game/gamemodes/clock_cult/clock_mobs/clockwork_marauder.dm b/code/game/gamemodes/clock_cult/clock_mobs/clockwork_marauder.dm
index a0396fdec2..1fabeeba3f 100644
--- a/code/game/gamemodes/clock_cult/clock_mobs/clockwork_marauder.dm
+++ b/code/game/gamemodes/clock_cult/clock_mobs/clockwork_marauder.dm
@@ -1,3 +1,6 @@
+#define MARAUDER_SLOWDOWN_PERCENTAGE 0.40 //Below this percentage of health, marauders will become slower
+#define MARAUDER_SHIELD_REGEN_TIME 100 //In deciseconds, how long it takes for shields to regenerate after breaking
+
//Clockwork marauder: A well-rounded frontline construct. Only one can exist for every two human servants.
/mob/living/simple_animal/hostile/clockwork/marauder
name = "clockwork marauder"
@@ -20,9 +23,26 @@
playstyle_string = "You are a clockwork marauder, a well-rounded frontline construct of Ratvar. Although you have no \
unique abilities, you're a fearsome fighter in one-on-one combat, and your shield protects from projectiles!
Obey the Servants and do as they \
tell you. Your primary goal is to defend the Ark from destruction; they are your allies in this, and should be protected from harm."
- empower_string = "The Anima Bulwark's power flows through you! Your weapon will strike harder, your armor is sturdier, and your shield is considerably more \
- likely to deflect shots."
+ empower_string = "The Anima Bulwark's power flows through you! Your weapon will strike harder, your armor is sturdier, and your shield is more durable."
var/deflect_chance = 40 //Chance to deflect any given projectile (non-damaging energy projectiles are always deflected)
+ var/max_shield_health = 3
+ var/shield_health = 3 //Amount of projectiles that can be deflected within
+ var/shield_health_regen = 0 //When world.time equals this, shield health will regenerate
+
+/mob/living/simple_animal/hostile/clockwork/marauder/examine_info()
+ if(!shield_health)
+ return "Its shield has been destroyed!"
+
+/mob/living/simple_animal/hostile/clockwork/marauder/Life()
+ ..()
+ if(!GLOB.ratvar_awakens && health / maxHealth <= MARAUDER_SLOWDOWN_PERCENTAGE)
+ speed = initial(speed) + 1 //Yes, this slows them down
+ else
+ speed = initial(speed)
+ if(shield_health != max_shield_health && world.time >= shield_health_regen)
+ to_chat(src, "Your shield has recovered. [max_shield_health] blocks remaining!")
+ playsound_local(src, "shatter", 75, TRUE, frequency = -1)
+ shield_health = max_shield_health
/mob/living/simple_animal/hostile/clockwork/marauder/update_values()
if(GLOB.ratvar_awakens) //Massive attack damage bonuses and health increase, because Ratvar
@@ -33,6 +53,7 @@
attacktext = "devastates"
speed = -1
obj_damage = 100
+ max_shield_health = INFINITY
else if(GLOB.ratvar_approaches) //Hefty health bonus and slight attack damage increase
health = 200
maxHealth = 200
@@ -40,6 +61,7 @@
melee_damage_lower = 15
attacktext = "carves"
obj_damage = 50
+ max_shield_health = 4
/mob/living/simple_animal/hostile/clockwork/marauder/death(gibbed)
visible_message("[src]'s equipment clatters lifelessly to the ground as the red flames within dissipate.", \
@@ -64,21 +86,21 @@
return ..()
/mob/living/simple_animal/hostile/clockwork/marauder/proc/deflect_projectile(obj/item/projectile/P)
- var/final_deflection_chance = deflect_chance
+ if(!shield_health)
+ return
var/energy_projectile = istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam)
- if(P.nodamage || P.damage_type == STAMINA)
- final_deflection_chance = 100
- else if(!energy_projectile) //Flat 40% chance against energy projectiles; ballistic projectiles are 40% - (damage of projectile)%, min. 10%
- final_deflection_chance = max(10, deflect_chance - P.damage)
- if(GLOB.ratvar_awakens)
- final_deflection_chance = 100
- else if(GLOB.ratvar_approaches)
- final_deflection_chance = min(100, final_deflection_chance + 20) //20% bonus to deflection if the servants heralded Ratvar
- if(prob(final_deflection_chance))
- visible_message("[src] deflects [P] with their shield!", \
- "You block [P] with your shield!")
- if(energy_projectile)
- playsound(src, 'sound/weapons/effects/searwall.ogg', 50, TRUE)
- else
- playsound(src, "ricochet", 50, TRUE)
- . = TRUE
+ visible_message("[src] deflects [P] with their shield!", \
+ "You block [P] with your shield! Blocks left: [shield_health - 1]")
+ if(energy_projectile)
+ playsound(src, 'sound/weapons/effects/searwall.ogg', 50, TRUE)
+ else
+ playsound(src, "ricochet", 50, TRUE)
+ shield_health--
+ if(!shield_health)
+ visible_message("[src]'s shield breaks from deflecting the attack!", "Your shield breaks! Give it some time to recover...")
+ playsound(src, "shatter", 100, TRUE)
+ shield_health_regen = world.time + MARAUDER_SHIELD_REGEN_TIME
+ return TRUE
+
+#undef MARAUDER_SLOWDOWN_PERCENTAGE
+#undef MARAUDER_SHIELD_REGEN_TIME
diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm
index a219d64666..a282ac3067 100644
--- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm
+++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm
@@ -236,7 +236,7 @@
if(A.outdoors || A.map_name == "Space" || !A.blob_allowed)
to_chat(invoker, "Stargazers can't be built off-station.")
return
- return TRUE
+ return ..()
//Integration Cog: Creates an integration cog that can be inserted into APCs to passively siphon power.
diff --git a/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm b/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm
index 2d66739b4e..201ce11cf6 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm
@@ -34,6 +34,16 @@
GLOB.ark_of_the_clockwork_justiciar = src
START_PROCESSING(SSprocessing, src)
+/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/final_countdown(ark_time)
+ if(!ark_time)
+ ark_time = 30 //minutes
+ initial_activation_delay = ark_time * 60
+ seconds_until_activation = ark_time * 60 //60 seconds in a minute * number of minutes
+ for(var/obj/item/clockwork/construct_chassis/cogscarab/C in GLOB.all_clockwork_objects)
+ C.infinite_resources = FALSE
+ GLOB.servants_active = TRUE
+ SSshuttle.registerHostileEnvironment(src)
+
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/cry_havoc()
visible_message("[src] shudders and roars to life, its parts beginning to whirr and screech!")
hierophant_message("The Ark is activating! Get back to the base!")
@@ -235,13 +245,39 @@
sleep(125)
make_glow()
animate(glow, transform = matrix() * 3, alpha = 0, time = 5)
- var/turf/startpoint = get_turf(src)
QDEL_IN(src, 3)
sleep(3)
GLOB.clockwork_gateway_activated = TRUE
- var/obj/structure/destructible/clockwork/massive/ratvar/R = new(startpoint)
var/turf/T = locate(round(world.maxx * 0.5, 1), round(world.maxy * 0.5, 1), ZLEVEL_STATION_PRIMARY) //approximate center of the station
- R.forceMove(T)
+ new /obj/structure/destructible/clockwork/massive/ratvar(T)
+ SSticker.force_ending = TRUE
+ var/x0 = T.x
+ var/y0 = T.y
+ for(var/I in spiral_range_turfs(255, T, tick_checked = TRUE))
+ var/turf/T2 = I
+ if(!T2)
+ continue
+ var/dist = cheap_hypotenuse(T2.x, T2.y, x0, y0)
+ if(dist < 100)
+ dist = TRUE
+ else
+ dist = FALSE
+ T.ratvar_act(dist)
+ CHECK_TICK
+
+/obj/structure/destructible/clockwork/massive/celestial_gateway/attack_ghost(mob/user)
+ if(!user.client || !user.client.holder)
+ return
+ if(GLOB.servants_active)
+ to_chat(user, "The Ark is already counting down.")
+ return
+ if(alert(user, "Activate the Ark's countdown?", name, "Yes", "No") == "Yes")
+ if(alert(user, "REALLY activate the Ark's countdown?", name, "Yes", "No") == "Yes")
+ if(alert(user, "You're REALLY SURE? This cannot be undone.", name, "Yes - Activate the Ark", "No") == "Yes - Activate the Ark")
+ message_admins("Admin [key_name_admin(user)] started the Ark's countdown!")
+ to_chat(user, "The gamemode is now being treated as clockwork cult, and the Ark is counting down from 30 \
+ minutes. You will need to create servant players yourself.")
+ final_countdown(35)
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 128a794bc6..26c3810b42 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -173,7 +173,8 @@
round_converted = 0
return 1
for(var/mob/living/carbon/human/H in antag_candidates)
- replacementmode.make_antag_chance(H)
+ if(H.client)
+ replacementmode.make_antag_chance(H)
round_converted = 2
message_admins("-- IMPORTANT: The roundtype has been converted to [replacementmode.name], antagonists may have been created! --")
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index d2c6da2c60..780be71694 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -98,7 +98,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
var/z_original = ZLEVEL_STATION_PRIMARY
var/threat = 0 // used for determining which meteors are most interesting
var/lifetime = DEFAULT_METEOR_LIFETIME
-
+ var/timerid = null
var/list/meteordrop = list(/obj/item/ore/iron)
var/dropamt = 2
@@ -117,6 +117,8 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
get_hit()
/obj/effect/meteor/Destroy()
+ if (timerid)
+ deltimer(timerid)
GLOB.meteor_list -= src
SSaugury.unregister_doom(src)
walk(src,0) //this cancels the walk_towards() proc
@@ -127,7 +129,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
GLOB.meteor_list += src
SSaugury.register_doom(src, threat)
SpinAnimation()
- QDEL_IN(src, lifetime)
+ timerid = QDEL_IN(src, lifetime)
chase_target(target)
/obj/effect/meteor/Collide(atom/A)
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
index 3a7f99bc8a..8fead855b2 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
@@ -491,7 +491,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
/obj/item/restraints/handcuffs/energy
name = "hard-light energy field"
desc = "A hard-light field restraining the hands."
- icon_state = "cuff_white" // Needs sprite
+ icon_state = "cuff" // Needs sprite
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
breakouttime = 450
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
index 99059e7a25..73a696fb3a 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
@@ -62,7 +62,7 @@
/obj/machinery/abductor/experiment/proc/dissection_icon(mob/living/carbon/human/H)
var/icon/photo = null
var/g = (H.gender == FEMALE) ? "f" : "m"
- if(!CONFIG_GET(flag/join_with_mutant_race) || H.dna.species.use_skintones)
+ if(H.dna.species.use_skintones)
photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.skin_tone]_[g]")
else
photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.dna.species.id]_[g]")
diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm
index aaeee27985..f80a5e3402 100644
--- a/code/game/gamemodes/miniantags/borer/borer.dm
+++ b/code/game/gamemodes/miniantags/borer/borer.dm
@@ -415,7 +415,6 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10)
victim = C
forceMove(victim)
- SSticker.mode.update_borer_icons_added_host(victim.mind)
RemoveBorerActions()
GrantInfestActions()
@@ -591,7 +590,6 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10)
var/mob/living/V = victim
V.verbs -= /mob/living/proc/borer_comm
talk_to_borer_action.Remove(victim)
- SSticker.mode.update_borer_icons_removed_host(victim.mind)
victim = null
return
@@ -1099,27 +1097,3 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10)
/datum/action/innate/borer/jumpstart_host/Activate()
var/mob/living/simple_animal/borer/B = owner
B.jumpstart()
-
-
-//HUD STUFF
-/datum/game_mode/proc/update_borer_icons_added(datum/mind/borer_mind)
- var/datum/atom_hud/antag/borerhud = GLOB.huds[ANTAG_HUD_BORER]
- borerhud.join_hud(borer_mind.current)
- set_antag_hud(borer_mind.current, "hudbrainworm")
-
-/datum/game_mode/proc/update_borer_icons_removed(datum/mind/borer_mind)
- var/datum/atom_hud/antag/borerhud = GLOB.huds[ANTAG_HUD_BORER]
- borerhud.leave_hud(borer_mind.current)
- set_antag_hud(borer_mind.current, null)
-
-/datum/game_mode/proc/update_borer_icons_added_host(datum/mind/host_mind)
- var/datum/atom_hud/antag/hosthud = GLOB.huds[ANTAG_HUD_BORER] //Invisible to self
- hosthud.self_visible = FALSE
- hosthud.join_hud(host_mind.current)
- set_antag_hud(host_mind.current, "hudbrainworm")
-
-/datum/game_mode/proc/update_borer_icons_removed_host(datum/mind/host_mind)
- var/datum/atom_hud/antag/hosthud = GLOB.huds[ANTAG_HUD_BORER] //Invisible to self
- hosthud.self_visible = FALSE //Probably not needed as we're deleting?
- hosthud.leave_hud(host_mind.current)
- set_antag_hud(host_mind.current, null)
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 77e26f026a..cd3b2ba2b2 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -54,9 +54,22 @@
/datum/objective/proc/find_target()
var/list/datum/mind/owners = get_owners()
var/list/possible_targets = list()
+ var/try_target_late_joiners = FALSE
+ for(var/I in owners)
+ var/datum/mind/O = I
+ if(O.late_joiner)
+ try_target_late_joiners = TRUE
for(var/datum/mind/possible_target in get_crewmember_minds())
if(!(possible_target in owners) && ishuman(possible_target.current) && (possible_target.current.stat != DEAD) && is_unique_objective(possible_target))
possible_targets += possible_target
+ if(try_target_late_joiners)
+ var/list/all_possible_targets = possible_targets.Copy()
+ for(var/I in all_possible_targets)
+ var/datum/mind/PT = I
+ if(!PT.late_joiner)
+ possible_targets -= PT
+ if(!possible_targets.len)
+ possible_targets = all_possible_targets
if(possible_targets.len > 0)
target = pick(possible_targets)
update_explanation_text()
diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm
index b38ac384fb..776b5d6981 100644
--- a/code/game/gamemodes/wizard/soulstone.dm
+++ b/code/game/gamemodes/wizard/soulstone.dm
@@ -233,6 +233,7 @@
/obj/item/device/soulstone/proc/init_shade(mob/living/carbon/human/T, mob/U, vic = 0)
new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton
+ T.stop_sound_channel(CHANNEL_HEARTBEAT)
T.invisibility = INVISIBILITY_ABSTRACT
T.dust_animation()
var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade(src)
diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm
index f26b60202e..6ac7e1249d 100644
--- a/code/game/machinery/camera/motion.dm
+++ b/code/game/machinery/camera/motion.dm
@@ -17,7 +17,7 @@
else if (detectTime == -1)
for (var/targetref in getTargetList())
var/mob/target = locate(targetref) in GLOB.mob_list
- if (target.stat == DEAD || QDELETED(target) || (!area_motion && !in_range(src, target)))
+ if (QDELETED(target) || target.stat == DEAD || (!area_motion && !in_range(src, target)))
//If not part of a monitored area and the camera is not in range or the target is dead
lostTarget(target)
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 86e69b8973..cb5ea9df76 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -163,7 +163,7 @@
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
if(clonemind.changeling)
- var/obj/item/organ/brain/B = H.getorganslot("brain")
+ var/obj/item/organ/brain/B = H.getorganslot(ORGAN_SLOT_BRAIN)
B.vital = FALSE
B.decoy_override = TRUE
diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm
index a8e9c7bcca..ca2f6e1cb6 100644
--- a/code/game/machinery/computer/Operating.dm
+++ b/code/game/machinery/computer/Operating.dm
@@ -61,6 +61,14 @@
for(var/datum/surgery/procedure in patient.surgeries)
dat += "[capitalize(procedure.name)]
"
var/datum/surgery_step/surgery_step = procedure.get_surgery_step()
- dat += "Next step: [capitalize(surgery_step.name)]
"
+ dat += "Next step: [capitalize(surgery_step.name)]"
+ if(surgery_step.repeatable)
+ dat += " or "
+ var/datum/surgery_step/next_step = procedure.get_surgery_next_step()
+ if(next_step)
+ dat += "[capitalize(next_step.name)]"
+ else
+ dat += "finish operation"
+ dat += "
"
dat += ""
- return dat
\ No newline at end of file
+ return dat
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 082f1aa895..7748022da1 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -44,7 +44,8 @@
/obj/item/grenade/chem_grenade/glitter/blue = 1,
/obj/item/grenade/chem_grenade/glitter/white = 1,
/obj/item/toy/eightball = 2,
- /obj/item/toy/windupToolbox = 2)
+ /obj/item/toy/windupToolbox = 2,
+ /obj/item/toy/sword/cx = 2)
light_color = LIGHT_COLOR_GREEN
diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm
index 9f252effa6..bf772a157f 100644
--- a/code/game/machinery/computer/camera_advanced.dm
+++ b/code/game/machinery/computer/camera_advanced.dm
@@ -281,7 +281,7 @@
/datum/action/innate/servant_warp/Activate()
if(QDELETED(target) || !(ishuman(owner) || iscyborg(owner)) || !owner.canUseTopic(target) || warping)
return
- if(!istype(SSticker.mode, /datum/game_mode/clockwork_cult)) //No leaving unless there's servants from the get-go
+ if(!GLOB.servants_active) //No leaving unless there's servants from the get-go
return
var/mob/living/carbon/human/user = owner
var/mob/camera/aiEye/remote/remote_eye = user.remote_control
@@ -296,8 +296,8 @@
to_chat(user, "[prob(1) ? "Servant cannot into space." : "You can't teleport into space."]")
return
var/area/AR = get_area(T)
- if(istype(AR, /area/ai_monitored))
- to_chat(user, "The structure there is too dense for [src] to pierce. (This is normal in high-security areas.)")
+ if(!AR.clockwork_warp_allowed)
+ to_chat(user, "[AR.clockwork_warp_fail]")
return
if(alert(user, "Are you sure you want to warp to [AR]?", target.name, "Warp", "Cancel") == "Cancel" || QDELETED(R) || !user.canUseTopic(R))
return
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index 31126a6c08..ee316b3eed 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -470,7 +470,7 @@
// species datums
R.fields["mrace"] = dna.species
else
- var/datum/species/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races))
+ var/datum/species/rando_race = pick(GLOB.roundstart_races)
R.fields["mrace"] = rando_race.type
R.fields["ckey"] = mob_occupant.ckey
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index f13cfe8c00..41b41e536e 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -123,8 +123,7 @@
dat += " "
dat += "ID: [active1.fields["id"]] "
dat += "Sex: [active1.fields["sex"]] "
- if(CONFIG_GET(flag/join_with_mutant_race))
- dat += "Age: [active1.fields["age"]] "
+ dat += "Species: [active1.fields["species"]] "
dat += "Species: [active1.fields["species"]] "
dat += "Fingerprint: [active1.fields["fingerprint"]] "
dat += "Physical Status: [active1.fields["p_stat"]] "
@@ -538,8 +537,7 @@
P.info = "Mental Status: [active1.fields["m_stat"]]
- Step one: PANIC!
- Step two: Get your ass over to engineering! QUICKLY!!!
- Step three: Make sure the SMES is still powering the emitters, if not, setup the generator in secure storage and disconnect the emitters from the SMES.
- Step four: Next, head over to the APC and swipe it with your ID card - if it doesn't unlock, continue with step 15.
- Step five: Open the console and disengage the cover lock.
- Step six: Pry open the APC with a Crowbar.
- Step seven: Take out the empty power cell.
- Step eight: Put in the new, full power cell - if you don't have one, continue with step 15.
- Step nine: Quickly put on a Radiation suit.
- Step ten: Check if the singularity field generators withstood the down-time - if they didn't, continue with step 15.
- Step eleven: Since disaster was averted you now have to ensure it doesn't repeat. If it was a powersink which caused it and if the engineering apc is wired to the same powernet, which the powersink is on, you have to remove the piece of wire which links the apc to the powernet. If it wasn't a powersink which caused it, then skip to step 14.
- Step twelve: Grab your crowbar and pry away the tile closest to the APC.
- Step thirteen: Use the wirecutters to cut the wire which is conecting the grid to the terminal.
- Step fourteen: Go to the bar and tell the guys how you saved them all. Stop reading this guide here.
- Step fifteen: GET THE FUCK OUT OF THERE!!!
-
-
- It really is that easy! Good luck! - - - - "} - -/obj/item/book/manual/medical_cloning - name = "Cloning techniques of the 26th century" - icon_state ="bookCloning" - author = "Medical Journal, volume 3" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned - title = "Cloning techniques of the 26th century" -//big pile of shit below. - - dat = {" -
- - - - -If you’ve gotten this far, congratulations! You have mastered the art of cloning. Now, the real problem is how to resurrect yourself after that traitor had his way with you for cloning his target. - - - - - - "} - - -/obj/item/book/manual/ripley_build_and_repair - name = "APLU \"Ripley\" Construction and Operation Manual" - icon_state ="book" - author = "Weyland-Yutani Corp" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned - title = "APLU \"Ripley\" Construction and Operation Manual" -//big pile of shit below. - - dat = {" -
- - - --
- It really is that easy! Good luck!
-
-
- "}
-
-/obj/item/book/manual/nuclear
- name = "Fission Mailed: Nuclear Sabotage 101"
- icon_state ="bookNuclear"
- author = "Syndicate"
- title = "Fission Mailed: Nuclear Sabotage 101"
- dat = {"
- Nuclear Explosives 101:
- Hello and thank you for choosing the Syndicate for your nuclear information needs.
- Today's crash course will deal with the operation of a Fusion Class Nanotrasen made Nuclear Device.
- First and foremost, DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE.
- Pressing any button on the compacted bomb will cause it to extend and bolt itself into place.
- If this is done to unbolt it one must completely log in which at this time may not be possible.
- To make the nuclear device functional:
-
You start skimming through the manual...
- - - - - - "} - -/obj/item/book/manual/wiki/chemistry - name = "Chemistry Textbook" - icon_state ="chemistrybook" - author = "Nanotrasen" - title = "Chemistry Textbook" - page_link = "Guide_to_chemistry" - -/obj/item/book/manual/wiki/engineering_construction - name = "Station Repairs and Construction" - icon_state ="bookEngineering" - author = "Engineering Encyclopedia" - title = "Station Repairs and Construction" - page_link = "Guide_to_construction" - -/obj/item/book/manual/wiki/engineering_guide - name = "Engineering Textbook" - icon_state ="bookEngineering2" - author = "Engineering Encyclopedia" - title = "Engineering Textbook" - page_link = "Guide_to_engineering" - -/obj/item/book/manual/wiki/security_space_law - name = "Space Law" - desc = "A set of Nanotrasen guidelines for keeping law and order on their space stations." - icon_state = "bookSpaceLaw" - author = "Nanotrasen" - title = "Space Law" - page_link = "Space_Law" - -/obj/item/book/manual/wiki/infections - name = "Infections - Making your own pandemic!" - icon_state = "bookInfections" - author = "Infections Encyclopedia" - title = "Infections - Making your own pandemic!" - page_link = "Infections" - -/obj/item/book/manual/wiki/telescience - name = "Teleportation Science - Bluespace for dummies!" - icon_state = "book7" - author = "University of Bluespace" - title = "Teleportation Science - Bluespace for dummies!" - page_link = "Guide_to_telescience" - -/obj/item/book/manual/wiki/engineering_hacking - name = "Hacking" - icon_state ="bookHacking" - author = "Engineering Encyclopedia" - title = "Hacking" - page_link = "Hacking" +/*********************MANUALS (BOOKS)***********************/ + +//Oh god what the fuck I am not good at computer +/obj/item/book/manual + icon = 'icons/obj/library.dmi' + due_date = 0 // Game time in 1/10th seconds + unique = 1 // 0 - Normal book, 1 - Should not be treated as normal book, unable to be copied, unable to be modified + +/obj/item/book/manual/engineering_particle_accelerator + name = "Particle Accelerator User's Guide" + icon_state ="bookParticleAccelerator" + author = "Engineering Encyclopedia" // Whoever wrote the paper or book, can be changed by pen or PC. It is not automatically assigned. + title = "Particle Accelerator User's Guide" +//book contents below + + dat = {" + + + + + +
+ Step one: PANIC!
+ Step two: Get your ass over to engineering! QUICKLY!!!
+ Step three: Make sure the SMES is still powering the emitters, if not, setup the generator in secure storage and disconnect the emitters from the SMES.
+ Step four: Next, head over to the APC and swipe it with your ID card - if it doesn't unlock, continue with step 15.
+ Step five: Open the console and disengage the cover lock.
+ Step six: Pry open the APC with a Crowbar.
+ Step seven: Take out the empty power cell.
+ Step eight: Put in the new, full power cell - if you don't have one, continue with step 15.
+ Step nine: Quickly put on a Radiation suit.
+ Step ten: Check if the singularity field generators withstood the down-time - if they didn't, continue with step 15.
+ Step eleven: Since disaster was averted you now have to ensure it doesn't repeat. If it was a powersink which caused it and if the engineering apc is wired to the same powernet, which the powersink is on, you have to remove the piece of wire which links the apc to the powernet. If it wasn't a powersink which caused it, then skip to step 14.
+ Step twelve: Grab your crowbar and pry away the tile closest to the APC.
+ Step thirteen: Use the wirecutters to cut the wire which is conecting the grid to the terminal.
+ Step fourteen: Go to the bar and tell the guys how you saved them all. Stop reading this guide here.
+ Step fifteen: GET THE FUCK OUT OF THERE!!!
+
+
+ It really is that easy! Good luck! + + + + "} + +/obj/item/book/manual/medical_cloning + name = "Cloning techniques of the 26th century" + icon_state ="bookCloning" + author = "Medical Journal, volume 3" + title = "Cloning techniques of the 26th century" + dat = {" +
+ + + + +If you've gotten this far, congratulations! You have mastered the art of cloning. Now, the real problem is how to resurrect yourself after that traitor had his way with you for cloning his target. + + + + + + "} + + +/obj/item/book/manual/ripley_build_and_repair + name = "APLU \"Ripley\" Construction and Operation Manual" + icon_state ="book" + author = "Weyland-Yutani Corp" + title = "APLU \"Ripley\" Construction and Operation Manual" + dat = {" +
+ + + ++
+ It really is that easy! Good luck!
+
+
+ "}
+
+/obj/item/book/manual/nuclear
+ name = "Fission Mailed: Nuclear Sabotage 101"
+ icon_state ="bookNuclear"
+ author = "Syndicate"
+ title = "Fission Mailed: Nuclear Sabotage 101"
+ dat = {"
+ Nuclear Explosives 101:
+ Hello and thank you for choosing the Syndicate for your nuclear information needs.
+ Today's crash course will deal with the operation of a Fusion Class Nanotrasen made Nuclear Device.
+ First and foremost, DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE.
+ Pressing any button on the compacted bomb will cause it to extend and bolt itself into place.
+ If this is done to unbolt it one must completely log in which at this time may not be possible.
+ To make the nuclear device functional:
+
You start skimming through the manual...
+ + + + + + "} + +/obj/item/book/manual/wiki/chemistry + name = "Chemistry Textbook" + icon_state ="chemistrybook" + author = "Nanotrasen" + title = "Chemistry Textbook" + page_link = "Guide_to_chemistry" + +/obj/item/book/manual/wiki/engineering_construction + name = "Station Repairs and Construction" + icon_state ="bookEngineering" + author = "Engineering Encyclopedia" + title = "Station Repairs and Construction" + page_link = "Guide_to_construction" + +/obj/item/book/manual/wiki/engineering_guide + name = "Engineering Textbook" + icon_state ="bookEngineering2" + author = "Engineering Encyclopedia" + title = "Engineering Textbook" + page_link = "Guide_to_engineering" + +/obj/item/book/manual/wiki/security_space_law + name = "Space Law" + desc = "A set of Nanotrasen guidelines for keeping law and order on their space stations." + icon_state = "bookSpaceLaw" + author = "Nanotrasen" + title = "Space Law" + page_link = "Space_Law" + +/obj/item/book/manual/wiki/infections + name = "Infections - Making your own pandemic!" + icon_state = "bookInfections" + author = "Infections Encyclopedia" + title = "Infections - Making your own pandemic!" + page_link = "Infections" + +/obj/item/book/manual/wiki/telescience + name = "Teleportation Science - Bluespace for dummies!" + icon_state = "book7" + author = "University of Bluespace" + title = "Teleportation Science - Bluespace for dummies!" + page_link = "Guide_to_telescience" + +/obj/item/book/manual/wiki/engineering_hacking + name = "Hacking" + icon_state ="bookHacking" + author = "Engineering Encyclopedia" + title = "Hacking" + page_link = "Hacking" diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm index 7695eb86c6..f9be38a2fe 100644 --- a/code/game/objects/items/mop.dm +++ b/code/game/objects/items/mop.dm @@ -24,12 +24,10 @@ /obj/item/mop/proc/clean(turf/A) if(reagents.has_reagent("water", 1) || reagents.has_reagent("holywater", 1) || reagents.has_reagent("vodka", 1) || reagents.has_reagent("cleaner", 1)) A.clean_blood() + A.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM) for(var/obj/effect/O in A) if(is_cleanable(O)) qdel(O) - if(isclosedturf(A)) - var/turf/closed/C = A - C.thermite = 0 reagents.reaction(A, TOUCH, 10) //Needed for proper floor wetting. reagents.remove_any(1) //reaction() doesn't use up the reagents diff --git a/code/game/objects/items/sharpener.dm b/code/game/objects/items/sharpener.dm index ce2d73eff0..fb25cb1d76 100644 --- a/code/game/objects/items/sharpener.dm +++ b/code/game/objects/items/sharpener.dm @@ -3,6 +3,7 @@ icon = 'icons/obj/kitchen.dmi' icon_state = "sharpener" desc = "A block that makes things sharp." + force = 5 var/used = 0 var/increment = 4 var/max = 30 diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index a0f4b2a928..89fdc6d694 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -169,6 +169,11 @@ W.ini_dir = W.dir //END: oh fuck i'm so sorry + else if(istype(O, /obj/item/restraints/handcuffs/cable)) + var/obj/item/cuffs = O + cuffs.item_color = item_color + cuffs.update_icon() + if (QDELETED(O)) return //It's a stack and has already been merged @@ -261,7 +266,7 @@ if (user.get_inactive_held_item() == src) if(zero_amount()) return - change_stack(user,1) + return change_stack(user,1) else ..() diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index 8f5d43d51e..513bdd2474 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -31,7 +31,7 @@ H.internal = null H.update_internals_hud_icon(0) else - if(!H.getorganslot("breathing_tube")) + if(!H.getorganslot(ORGAN_SLOT_BREATHING_TUBE)) if(!H.wear_mask) to_chat(H, "You need a mask!") return diff --git a/code/game/objects/items/theft_tools.dm b/code/game/objects/items/theft_tools.dm index 628b731197..5f3e493677 100644 --- a/code/game/objects/items/theft_tools.dm +++ b/code/game/objects/items/theft_tools.dm @@ -157,7 +157,7 @@ /obj/item/nuke_core_container/supermatter name = "supermatter bin" - desc = "A tiny receptacle that releases an inert freon mix upon sealing, allowing a sliver of a supermatter crystal to be safely stored.." + desc = "A tiny receptacle that releases an inert hyper-noblium mix upon sealing, allowing a sliver of a supermatter crystal to be safely stored.." var/obj/item/nuke_core/supermatter_sliver/sliver /obj/item/nuke_core_container/supermatter/Destroy() @@ -193,7 +193,7 @@ /obj/item/scalpel/supermatter name = "supermatter scalpel" - desc = "A scalpel with a tip of condensed freon gas, searingly cold to the touch, that can safely shave a sliver off a supermatter crystal." + desc = "A scalpel with a tip of condensed hyper-noblium gas, searingly cold to the touch, that can safely shave a sliver off a supermatter crystal." icon = 'icons/obj/nuke_tools.dmi' icon_state = "supermatter_scalpel" toolspeed = 0.5 @@ -202,7 +202,7 @@ /obj/item/hemostat/supermatter name = "supermatter extraction tongs" - desc = "A pair of tongs made from condensed freon gas, searingly cold to the touch, that can safely grip a supermatter sliver." + desc = "A pair of tongs made from condensed hyper-noblium gas, searingly cold to the touch, that can safely grip a supermatter sliver." icon = 'icons/obj/nuke_tools.dmi' icon_state = "supermatter_tongs" toolspeed = 0.75 diff --git a/code/game/objects/items/tools.dm b/code/game/objects/items/tools.dm index d18799c681..bd618f217e 100644 --- a/code/game/objects/items/tools.dm +++ b/code/game/objects/items/tools.dm @@ -457,6 +457,15 @@ flamethrower_screwdriver(I, user) else if(istype(I, /obj/item/stack/rods)) flamethrower_rods(I, user) + else if(istype(I, /obj/item/reagent_containers) && I.is_open_container()) + var/amountNeeded = max_fuel - get_fuel() + var/obj/item/reagent_containers/container = I + if(length(container.reagents.reagent_list) > 1) + to_chat(user, "[container] has too many chemicals mixed into it. You wouldn't want to put the wrong chemicals into [src].") + return ..() + if(amountNeeded > 0 && container.reagents.has_reagent("welding_fuel")) + container.reagents.trans_id_to(src, "welding_fuel", amountNeeded) + to_chat(user, "You transfer some fuel from [container] to [src].") else return ..() diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 90a0ec7f99..a8c80e5e83 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -601,12 +601,11 @@ if(ishuman(M)) var/mob/living/carbon/human/L = M L.endTailWag() - if(user.a_intent != INTENT_HARM) - var/aim_for_face = ((user.zone_selected == "mouth") || (user.zone_selected == "eyes") || (user.zone_selected == "head")) + if(user.a_intent != INTENT_HARM && ((user.zone_selected == "mouth") || (user.zone_selected == "eyes") || (user.zone_selected == "head"))) user.do_attack_animation(M) playsound(M, 'sound/weapons/slap.ogg', 50, 1, -1) - user.visible_message("[user] slaps [M] in the [(aim_for_face)?"face":user.zone_selected]!", - "You slap [M] in the [(aim_for_face)?"face":user.zone_selected]! ",\ + user.visible_message("[user] slaps [M]!", + "You slap [M]!",\ "You hear a slap.") return else diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 30fd178f12..86d6b62198 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -28,7 +28,7 @@ new /obj/item/clothing/gloves/color/captain(src) new /obj/item/restraints/handcuffs/cable/zipties(src) new /obj/item/storage/belt/sabre(src) - new /obj/item/gun/energy/e_gun(src) + new /obj/item/gun/energy/e_gun/cx(src) new /obj/item/door_remote/captain(src) /obj/structure/closet/secure_closet/hop @@ -51,7 +51,7 @@ new /obj/item/device/assembly/flash/handheld(src) new /obj/item/clothing/glasses/sunglasses(src) new /obj/item/restraints/handcuffs/cable/zipties(src) - new /obj/item/gun/energy/e_gun(src) + new /obj/item/gun/energy/e_gun/cx(src) new /obj/item/clothing/neck/petcollar(src) new /obj/item/door_remote/civillian(src) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 296e4ba757..711f9baf0b 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -101,8 +101,7 @@ ..() /obj/structure/mirror/magic/lesser/New() - var/list/L = CONFIG_GET(keyed_flag_list/roundstart_races) - choosable_races = L.Copy() + choosable_races = GLOB.roundstart_races.Copy() ..() /obj/structure/mirror/magic/badmin/New() diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm index 1f25c0dbbb..45f9c3614d 100644 --- a/code/game/objects/structures/reflector.dm +++ b/code/game/objects/structures/reflector.dm @@ -58,7 +58,8 @@ playsound(src.loc, W.usesound, 50, 1) to_chat(user, "You dismantle [src].") new framebuildstacktype(loc, framebuildstackamount) - new buildstacktype(loc, buildstackamount) + if(buildstackamount) + new buildstacktype(loc, buildstackamount) qdel(src) else if(istype(W, /obj/item/weldingtool)) var/obj/item/weldingtool/WT = W diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index e22d75f9aa..0cb6451116 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -226,6 +226,7 @@ soundloop.start() wash_turf() for(var/atom/movable/G in loc) + G.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) if(isliving(G)) var/mob/living/L = G wash_mob(L) @@ -295,6 +296,7 @@ /obj/machinery/shower/proc/wash_obj(obj/O) + O.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) . = O.clean_blood() O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) if(isitem(O)) @@ -306,6 +308,7 @@ /obj/machinery/shower/proc/wash_turf() if(isturf(loc)) var/turf/tile = loc + tile.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) tile.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) tile.clean_blood() for(var/obj/effect/E in tile) @@ -314,6 +317,7 @@ /obj/machinery/shower/proc/wash_mob(mob/living/L) + L.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) L.wash_cream() L.ExtinguishMob() L.adjust_fire_stacks(-20) //Douse ourselves with water to avoid fire more easily diff --git a/code/game/turfs/closed.dm b/code/game/turfs/closed.dm index 029bb5b212..9f52c3e035 100644 --- a/code/game/turfs/closed.dm +++ b/code/game/turfs/closed.dm @@ -1,5 +1,4 @@ /turf/closed - var/thermite = 0 layer = CLOSED_TURF_LAYER opacity = 1 density = TRUE diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm index 3f5cb9b27f..d227710b32 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -177,11 +177,6 @@ for(var/obj/effect/O in src) if(is_cleanable(O)) qdel(O) - - var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in src) - if(hotspot && !isspaceturf(src)) - air.temperature = max(min(air.temperature-2000,air.temperature/2),0) - qdel(hotspot) return 1 /turf/open/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube) diff --git a/code/game/turfs/simulated/wall/mineral_walls.dm b/code/game/turfs/simulated/wall/mineral_walls.dm index 5595009778..0578861074 100644 --- a/code/game/turfs/simulated/wall/mineral_walls.dm +++ b/code/game/turfs/simulated/wall/mineral_walls.dm @@ -38,9 +38,6 @@ explosion_block = 3 canSmoothWith = list(/turf/closed/wall/mineral/diamond, /obj/structure/falsewall/diamond) -/turf/closed/wall/mineral/diamond/thermitemelt(mob/user) - return - /turf/closed/wall/mineral/clown name = "bananium wall" desc = "A wall with bananium plating. Honk!" diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 57037de446..d3edd42cec 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -161,12 +161,6 @@ add_fingerprint(user) - //THERMITE related stuff. Calls src.thermitemelt() which handles melting simulated walls and the relevant effects - if( thermite ) - if(W.is_hot()) - thermitemelt(user) - return - var/turf/T = user.loc //get user's location for delay checks //the istype cascade has been spread among various procs for easy overriding @@ -239,31 +233,6 @@ return TRUE return FALSE - -/turf/closed/wall/proc/thermitemelt(mob/user) - cut_overlays() - var/obj/effect/overlay/O = new/obj/effect/overlay( src ) - O.name = "thermite" - O.desc = "Looks hot." - O.icon = 'icons/effects/fire.dmi' - O.icon_state = "2" - O.anchored = TRUE - O.opacity = 1 - O.density = TRUE - O.layer = FLY_LAYER - - playsound(src, 'sound/items/welder.ogg', 100, 1) - - if(thermite >= 50) - var/burning_time = max(100,300 - thermite) - var/turf/open/floor/F = ChangeTurf(/turf/open/floor/plating) - F.burn_tile() - F.add_hiddenprint(user) - QDEL_IN(O, burning_time) - else - thermite = 0 - QDEL_IN(O, 50) - /turf/closed/wall/singularity_pull(S, current_size) ..() if(current_size >= STAGE_FIVE) diff --git a/code/game/turfs/space/transit.dm b/code/game/turfs/space/transit.dm index cf611560c3..2ba08fa2a9 100644 --- a/code/game/turfs/space/transit.dm +++ b/code/game/turfs/space/transit.dm @@ -3,6 +3,7 @@ dir = SOUTH baseturf = /turf/open/space/transit flags_1 = NOJAUNT_1 //This line goes out to every wizard that ever managed to escape the den. I'm sorry. + explosion_block = INFINITY /turf/open/space/transit/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) . = ..() diff --git a/code/modules/admin/create_poll.dm b/code/modules/admin/create_poll.dm index d93b21d7f8..b1cda46ece 100644 --- a/code/modules/admin/create_poll.dm +++ b/code/modules/admin/create_poll.dm @@ -6,7 +6,7 @@ if(!SSdbcore.Connect()) to_chat(src, "Failed to establish database connection.") return - var/polltype = input("Choose poll type.","Poll Type") in list("Single Option","Text Reply","Rating","Multiple Choice", "Instant Runoff Voting")|null + var/polltype = input("Choose poll type.","Poll Type") as null|anything in list("Single Option","Text Reply","Rating","Multiple Choice", "Instant Runoff Voting") var/choice_amount = 0 switch(polltype) if("Single Option") @@ -18,10 +18,14 @@ if("Multiple Choice") polltype = POLLTYPE_MULTI choice_amount = input("How many choices should be allowed?","Select choice amount") as num|null - if(choice_amount == 0) - to_chat(src, "Multiple choice poll must have at least one choice allowed.") - else if (choice_amount == null) - return + switch(choice_amount) + if(0) + to_chat(src, "Multiple choice poll must have at least one choice allowed.") + return + if(1) + polltype = POLLTYPE_OPTION + if(null) + return if ("Instant Runoff Voting") polltype = POLLTYPE_IRV else diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 3889872275..0135bfbfa0 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -237,6 +237,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) . += " (IC)" . += " (CLOSE)" . += " (RSLVE)" + . += " (HANDLE)" //private /datum/admin_help/proc/LinkedReplyName(ref_src) @@ -382,6 +383,22 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) AddInteraction("Marked as IC issue by [key_name]") Resolve(silent = TRUE) +//Let the initiator know their ahelp is being handled +/datum/admin_help/proc/HandleIssue(key_name = key_name_admin(usr)) + if(state != AHELP_ACTIVE) + return + + var/msg = "Your ticket is now being handled by an admin. Please be patient." + + if(initiator) + to_chat(initiator, msg) + + SSblackbox.inc("ahelp_handleissue") + msg = "Ticket [TicketHref("#[id]")] is being handled by [key_name]" + message_admins(msg) + log_admin_private(msg) + AddInteraction("Being handled by [key_name]") + //Show the ticket panel /datum/admin_help/proc/TicketPanel() var/list/dat = list("| "
-
- if(CONFIG_GET(flag/join_with_mutant_race))
- dat += "Species: [pref_species.name] " - else - dat += "Species: Human " - dat += "Underwear: [underwear] " dat += "Undershirt: [undershirt] " dat += "Socks: [socks] " @@ -337,79 +326,79 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += " | "
- if(CONFIG_GET(flag/join_with_mutant_race)) //We don't allow mutant bodyparts for humans either unless this is true.
- if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits))
+ if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits))
- dat += "" + dat += " | "
- dat += "Mutant Color" + dat += "Mutant Color" - dat += " Change" + dat += " Change " - dat += " | "
+ dat += ""
- if("tail_lizard" in pref_species.mutant_bodyparts)
- dat += "" + if("tail_lizard" in pref_species.mutant_bodyparts) + dat += " | "
- dat += "Tail" + dat += "Tail" - dat += "[features["tail_lizard"]]" + dat += "[features["tail_lizard"]] " - dat += " | "
+ dat += ""
- if("snout" in pref_species.mutant_bodyparts)
- dat += "" + if("snout" in pref_species.mutant_bodyparts) + dat += " | "
- dat += "Snout" + dat += "Snout" - dat += "[features["snout"]]" + dat += "[features["snout"]] " - dat += " | "
+ dat += ""
- if("horns" in pref_species.mutant_bodyparts)
- dat += "" + if("horns" in pref_species.mutant_bodyparts) + dat += " | "
- dat += "Horns" + dat += "Horns" - dat += "[features["horns"]]" + dat += "[features["horns"]] " - dat += " | "
+ dat += ""
- if("frills" in pref_species.mutant_bodyparts)
- dat += "" + if("frills" in pref_species.mutant_bodyparts) + dat += " | "
- dat += "Frills" + dat += "Frills" - dat += "[features["frills"]]" + dat += "[features["frills"]] " - dat += " | "
+ dat += ""
- if("spines" in pref_species.mutant_bodyparts)
- dat += "" + if("spines" in pref_species.mutant_bodyparts) + dat += " | "
- dat += "Spines" + dat += "Spines" - dat += "[features["spines"]]" + dat += "[features["spines"]] " - dat += " | "
+ dat += ""
- if("body_markings" in pref_species.mutant_bodyparts)
- dat += "" + if("body_markings" in pref_species.mutant_bodyparts) + dat += " | "
- dat += "Body Markings" + dat += "Body Markings" - dat += "[features["body_markings"]]" + dat += "[features["body_markings"]] " - dat += " | "
- if("legs" in pref_species.mutant_bodyparts)
- dat += "" + dat += " | " + if("legs" in pref_species.mutant_bodyparts) + dat += ""
- dat += "Legs" + dat += "Legs" - dat += "[features["legs"]]" + dat += "[features["legs"]] " + + dat += " | "
- dat += ""
if(CONFIG_GET(flag/join_with_mutant_humans))
if("tail_human" in pref_species.mutant_bodyparts)
@@ -574,61 +563,60 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "[features["flavor_text"]]"
else
dat += "[TextPreview(features["flavor_text"])]..."
@@ -1188,7 +1176,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("species")
- var/result = input(user, "Select a species", "Species Selection") as null|anything in CONFIG_GET(keyed_flag_list/roundstart_races)
+ var/result = input(user, "Select a species", "Species Selection") as null|anything in GLOB.roundstart_races
if(result)
var/newtype = GLOB.species_list[result]
@@ -1826,10 +1814,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
character.dna.features = features.Copy() //Flavor text is now a DNA feature
character.dna.real_name = character.real_name
var/datum/species/chosen_species
- if(pref_species != /datum/species/human && CONFIG_GET(flag/join_with_mutant_race))
+ if(pref_species.id in GLOB.roundstart_races)
chosen_species = pref_species.type
else
chosen_species = /datum/species/human
+ pref_species = new /datum/species/human
+ save_character()
character.set_species(chosen_species, icon_update=0)
//citadel code
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index dddac1e506..48dab29cf6 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -294,14 +294,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//Species
var/species_id
S["species"] >> species_id
- var/list/roundstart_races = CONFIG_GET(keyed_flag_list/roundstart_races)
- if(species_id && (species_id in roundstart_races) && CONFIG_GET(flag/join_with_mutant_race))
+ if(species_id)
var/newtype = GLOB.species_list[species_id]
pref_species = new newtype()
- else if (roundstart_races.len)
- var/rando_race = pick(roundstart_races)
- if (rando_race)
- pref_species = new rando_race()
if(!S["features["mcolor"]"] || S["features["mcolor"]"] == "#000")
WRITE_FILE(S["features["mcolor"]"] , "#FFF")
diff --git a/code/modules/client/verbs/looc.dm b/code/modules/client/verbs/looc.dm
index 42c20a2dc6..5e07134d4f 100644
--- a/code/modules/client/verbs/looc.dm
+++ b/code/modules/client/verbs/looc.dm
@@ -4,12 +4,12 @@
set category = "OOC"
if(GLOB.say_disabled) //This is here to try to identify lag problems
- usr << " Speech is currently admin-disabled."
+ to_chat(usr, " Speech is currently admin-disabled.")
return
if(!mob) return
if(IsGuestKey(key))
- src << "Guests may not use OOC."
+ to_chat(src, "Guests may not use OOC.")
return
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
@@ -17,23 +17,23 @@
return
if(!(prefs.toggles & CHAT_OOC))
- src << " You have OOC muted."
+ to_chat(src, " You have OOC muted.")
return
if(!holder)
if(!GLOB.ooc_allowed)
- src << " OOC is globally muted"
+ to_chat(src, " OOC is globally muted")
return
if(!GLOB.dooc_allowed && (mob.stat == DEAD))
- usr << " OOC for dead mobs has been turned off."
+ to_chat(usr, " OOC for dead mobs has been turned off.")
return
if(prefs.muted & MUTE_OOC)
- src << " You cannot use OOC (muted)."
+ to_chat(src, " You cannot use OOC (muted).")
return
if(handle_spam_prevention(msg,MUTE_OOC))
return
if(findtext(msg, "byond://"))
- src << "Advertising other servers is not allowed."
+ to_chat(src, "Advertising other servers is not allowed.")
log_admin("[key_name(src)] has attempted to advertise in LOOC: [msg]")
return
diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm
index 74e2f70c37..2b66a85fe6 100644
--- a/code/modules/clothing/neck/_neck.dm
+++ b/code/modules/clothing/neck/_neck.dm
@@ -59,8 +59,8 @@
var/heart_strength = "no"
var/lung_strength = "no"
- var/obj/item/organ/heart/heart = M.getorganslot("heart")
- var/obj/item/organ/lungs/lungs = M.getorganslot("lungs")
+ var/obj/item/organ/heart/heart = M.getorganslot(ORGAN_SLOT_HEART)
+ var/obj/item/organ/lungs/lungs = M.getorganslot(ORGAN_SLOT_LUNGS)
if(!(M.stat == DEAD || (M.status_flags&FAKEDEATH)))
if(heart && istype(heart))
@@ -179,4 +179,4 @@
desc = "Damn, it feels good to be a gangster."
icon = 'icons/obj/clothing/neck.dmi'
icon_state = "bling"
- item_color = "bling"
+ item_color = "bling"
\ No newline at end of file
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index a604eae015..75a63352e2 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -13,6 +13,20 @@
item_color = "engineering" //Determines used sprites: hardsuit[on]-[color] and hardsuit[on]-[color]2 (lying down sprite)
actions_types = list(/datum/action/item_action/toggle_helmet_light)
+ var/rad_count = 0
+ var/rad_record = 0
+ var/grace_count = 0
+ var/datum/looping_sound/geiger/soundloop
+
+/obj/item/clothing/head/helmet/space/hardsuit/Initialize()
+ . = ..()
+ soundloop = new(list(), FALSE, TRUE)
+ soundloop.volume = 5
+ START_PROCESSING(SSobj, src)
+
+/obj/item/clothing/head/helmet/space/hardsuit/Destroy()
+ . = ..()
+ STOP_PROCESSING(SSobj, src)
/obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user)
on = !on
@@ -31,6 +45,7 @@
..()
if(suit)
suit.RemoveHelmet()
+ soundloop.stop(user)
/obj/item/clothing/head/helmet/space/hardsuit/item_action_slot_check(slot)
if(slot == slot_head)
@@ -41,8 +56,11 @@
if(slot != slot_head)
if(suit)
suit.RemoveHelmet()
+ soundloop.stop(user)
else
qdel(src)
+ else
+ soundloop.start(user)
/obj/item/clothing/head/helmet/space/hardsuit/proc/display_visor_message(var/msg)
var/mob/wearer = loc
@@ -50,9 +68,22 @@
wearer.show_message("[icon2html(src, wearer)][msg]", 1)
/obj/item/clothing/head/helmet/space/hardsuit/rad_act(severity)
- ..()
- if(severity > RAD_AMOUNT_EXTREME)
- display_visor_message("Radiation pulse detected! Magnitude: [severity] RADs.")
+ . = ..()
+ rad_count += severity
+
+/obj/item/clothing/head/helmet/space/hardsuit/process()
+ if(!rad_count)
+ grace_count++
+ if(grace_count == 2)
+ soundloop.last_radiation = 0
+ return
+
+ grace_count = 0
+ rad_record -= rad_record/5
+ rad_record += rad_count/5
+ rad_count = 0
+
+ soundloop.last_radiation = rad_record
/obj/item/clothing/head/helmet/space/hardsuit/emp_act(severity)
..()
diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm
index 38fbe299f5..c70c4f341c 100644
--- a/code/modules/clothing/suits/utility.dm
+++ b/code/modules/clothing/suits/utility.dm
@@ -112,8 +112,9 @@
item_state = "bombsuit_white"
/*
- * Radiation protection
- */
+* Radiation protection
+*/
+
/obj/item/clothing/head/radiation
name = "radiation hood"
icon_state = "rad"
diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm
index 8b2c85d4e3..3f42b3dfcf 100644
--- a/code/modules/events/_event.dm
+++ b/code/modules/events/_event.dm
@@ -40,7 +40,7 @@
/datum/round_event_control/proc/canSpawnEvent(var/players_amt, var/gamemode)
if(occurrences >= max_occurrences)
return FALSE
- if(earliest_start >= world.time)
+ if(earliest_start >= world.time-SSticker.round_start_time)
return FALSE
if(wizardevent != SSevents.wizardmode)
return FALSE
diff --git a/code/modules/events/holiday/halloween.dm b/code/modules/events/holiday/halloween.dm
index 5415eab386..f83024bd3d 100644
--- a/code/modules/events/holiday/halloween.dm
+++ b/code/modules/events/holiday/halloween.dm
@@ -10,12 +10,8 @@
..()
for(var/mob/living/carbon/human/H in GLOB.mob_list)
var/obj/item/storage/backpack/b = locate() in H.contents
- new /obj/item/storage/spooky(b)
- if(ishuman(H) || islizard(H))
- if(prob(50))
- H.set_species(/datum/species/skeleton)
- else
- H.set_species(/datum/species/zombie)
+ if(b)
+ new /obj/item/storage/spooky(b)
for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_list)
Ian.place_on_head(new /obj/item/bedsheet(Ian))
@@ -26,77 +22,6 @@
/datum/round_event/spooky/announce()
priority_announce(pick("RATTLE ME BONES!","THE RIDE NEVER ENDS!", "A SKELETON POPS OUT!", "SPOOKY SCARY SKELETONS!", "CREWMEMBERS BEWARE, YOU'RE IN FOR A SCARE!") , "THE CALL IS COMING FROM INSIDE THE HOUSE")
-//Eyeball migration
-/datum/round_event_control/carp_migration/eyeballs
- name = "Eyeball Migration"
- typepath = /datum/round_event/carp_migration/eyeballs
- holidayID = HALLOWEEN
- weight = 25
- earliest_start = 0
-
-/datum/round_event/carp_migration/eyeballs/start()
- for(var/obj/effect/landmark/carpspawn/C in GLOB.landmarks_list)
- new /mob/living/simple_animal/hostile/carp/eyeball(C.loc)
-
-//Pumpking meteors waves
-/datum/round_event_control/meteor_wave/spooky
- name = "Pumpkin Wave"
- typepath = /datum/round_event/meteor_wave/spooky
- holidayID = HALLOWEEN
- weight = 20
- max_occurrences = 2
-
-/datum/round_event/meteor_wave/spooky
- endWhen = 40
-
-/datum/round_event/meteor_wave/spooky/tick()
- if(IsMultiple(activeFor, 4))
- spawn_meteors(3, GLOB.meteorsSPOOKY) //meteor list types defined in gamemode/meteor/meteors.dm
-
-//Creepy clown invasion
-/datum/round_event_control/creepy_clowns
- name = "Clowns"
- typepath = /datum/round_event/creepy_clowns
- holidayID = HALLOWEEN
- weight = 20
- earliest_start = 0
-
-/datum/round_event/creepy_clowns
- endWhen = 40
-
-/datum/round_event/creepy_clowns/start()
- for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
- if(!H.client || !istype(H))
- return
- to_chat(H, "Honk...")
- SEND_SOUND(H, sound('sound/spookoween/scary_clown_appear.ogg'))
- var/turf/T = get_turf(H)
- if(T)
- new /obj/effect/hallucination/simple/clown(T, H, 50)
-
-/datum/round_event/creepy_clowns/tick()
- if(IsMultiple(activeFor, 4))
- for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
- if (prob(66))
- playsound(H.loc, pick('sound/spookoween/scary_horn.ogg','sound/spookoween/scary_horn2.ogg', 'sound/spookoween/scary_horn3.ogg'), 100, 1)
- if (prob(33))
- var/turf/T = get_turf(H)
- if(T)
- new /obj/effect/hallucination/simple/clown(T, H, 25)
- else if (prob(25))
- var/turf/T = get_turf(H)
- if(T)
- new /obj/effect/hallucination/simple/clown/scary(T, H, 25)
- else if (prob(5))
- var/turf/T = get_turf(H)
- if(T)
- spawn_atom_to_turf(/obj/effect/mob_spawn/human/clown/corpse, H, 1)
- else if (prob(1))
- spawn_atom_to_turf(/mob/living/simple_animal/hostile/retaliate/clown, H, 1)
-
-/datum/round_event/creepy_clowns/announce()
- priority_announce("Honk... Honk... honk... HONK! HONK! HONKHONKHONKHONKHONK", "HONK!", 'sound/spookoween/scary_horn.ogg')
-
//spooky foods (you can't actually make these when it's not halloween)
/obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull
name = "skull cookie"
@@ -110,7 +35,6 @@
icon = 'icons/obj/halloween_items.dmi'
icon_state = "coffincookie"
-
//spooky items
/obj/item/storage/spooky
diff --git a/code/modules/events/holiday/vday.dm b/code/modules/events/holiday/vday.dm
index 160c42a9a5..2c698cb7dc 100644
--- a/code/modules/events/holiday/vday.dm
+++ b/code/modules/events/holiday/vday.dm
@@ -124,7 +124,14 @@
"You're the vomit to my flyperson.",
"You must be liquid dark matter, because you're pulling me closer.",
"Not even sorium can drive me away from you.",
- "Wanna make like a borg and do some heavy petting?" )
+ "Wanna make like a borg and do some heavy petting?",
+ "Are you powering the station? Because you super matter to me.",
+ "I wish science could make me a bag of holding you.",
+ "Let's call the emergency CUDDLE.",
+ "I must be tripping on BZ, because I saw an angel walk by.",
+ "Wanna empty out my tool storage?",
+ "Did you visit the medbay after you fell from heaven?",
+ "Are you wearing space pants? Wanna not be?" )
/obj/item/valentine/attackby(obj/item/W, mob/user, params)
..()
@@ -174,8 +181,9 @@
"A heart-shaped candy that reads: WAG MY TAIL",
"A heart-shaped candy that reads: VALIDTINES",
"A heart-shaped candy that reads: FACEHUGGER",
- "A heart-shaped candy that reads: DOMINATOR",
- "A heart-shaped candy that reads: GET TESLA'D",
- "A heart-shaped candy that reads: COCK CULT",
- "A heart-shaped candy that reads: PET ME")
+ "A heart-shaped candy that reads: BOX OF HUGS",
+ "A heart-shaped candy that reads: REEBE MINE",
+ "A heart-shaped candy that reads: PET ME",
+ "A heart-shaped candy that reads: TO THE DORMS",
+ "A heart-shaped candy that reads: DIS MEMBER")
icon_state = pick("candyheart", "candyheart2", "candyheart3", "candyheart4")
diff --git a/code/modules/events/meteor_wave.dm b/code/modules/events/meteor_wave.dm
index d46525a0eb..7940eaeec8 100644
--- a/code/modules/events/meteor_wave.dm
+++ b/code/modules/events/meteor_wave.dm
@@ -1,68 +1,72 @@
-// Normal strength
-
-/datum/round_event_control/meteor_wave
- name = "Meteor Wave: Normal"
- typepath = /datum/round_event/meteor_wave
- weight = 4
- min_players = 5
- max_occurrences = 3
-
-/datum/round_event/meteor_wave
- startWhen = 6
- endWhen = 66
- announceWhen = 1
- var/list/wave_type
- var/wave_name = "normal"
-
-/datum/round_event/meteor_wave/New()
- ..()
- if(!wave_type)
- determine_wave_type()
-
-/datum/round_event/meteor_wave/proc/determine_wave_type()
- if(!wave_name)
- wave_name = pickweight(list(
- "normal" = 50,
- "threatening" = 40,
- "catastrophic" = 10))
- switch(wave_name)
- if("normal")
- wave_type = GLOB.meteors_normal
- if("threatening")
- wave_type = GLOB.meteors_threatening
- if("catastrophic")
- wave_type = GLOB.meteors_catastrophic
- if("meaty")
- wave_type = GLOB.meteorsB
- if("space dust")
- wave_type = GLOB.meteorsC
- else
- WARNING("Wave name of [wave_name] not recognised.")
- kill()
-
-/datum/round_event/meteor_wave/announce()
- priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", 'sound/ai/meteors.ogg')
-
-/datum/round_event/meteor_wave/tick()
- if(IsMultiple(activeFor, 3))
- spawn_meteors(5, wave_type) //meteor list types defined in gamemode/meteor/meteors.dm
-
-/datum/round_event_control/meteor_wave/threatening
- name = "Meteor Wave: Threatening"
- typepath = /datum/round_event/meteor_wave/threatening
- weight = 2
- min_players = 5
- max_occurrences = 3
-
-/datum/round_event/meteor_wave/threatening
- wave_name = "threatening"
-
-/datum/round_event_control/meteor_wave/catastrophic
- name = "Meteor Wave: Catastrophic"
- typepath = /datum/round_event/meteor_wave/catastrophic
- weight = 1
- min_players = 5
- max_occurrences = 3
-
-/datum/round_event/meteor_wave/catastrophic
- wave_name = "catastrophic"
+// Normal strength
+
+/datum/round_event_control/meteor_wave
+ name = "Meteor Wave: Normal"
+ typepath = /datum/round_event/meteor_wave
+ weight = 4
+ min_players = 5
+ max_occurrences = 3
+
+/datum/round_event/meteor_wave
+ startWhen = 6
+ endWhen = 66
+ announceWhen = 1
+ var/list/wave_type
+ var/wave_name = "normal"
+
+/datum/round_event/meteor_wave/New()
+ ..()
+ if(!wave_type)
+ determine_wave_type()
+
+/datum/round_event/meteor_wave/proc/determine_wave_type()
+ if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
+ wave_name = "halloween"
+ if(!wave_name)
+ wave_name = pickweight(list(
+ "normal" = 50,
+ "threatening" = 40,
+ "catastrophic" = 10))
+ switch(wave_name)
+ if("normal")
+ wave_type = GLOB.meteors_normal
+ if("threatening")
+ wave_type = GLOB.meteors_threatening
+ if("catastrophic")
+ wave_type = GLOB.meteors_catastrophic
+ if("meaty")
+ wave_type = GLOB.meteorsB
+ if("space dust")
+ wave_type = GLOB.meteorsC
+ if("halloween")
+ wave_type = GLOB.meteorsSPOOKY
+ else
+ WARNING("Wave name of [wave_name] not recognised.")
+ kill()
+
+/datum/round_event/meteor_wave/announce()
+ priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", 'sound/ai/meteors.ogg')
+
+/datum/round_event/meteor_wave/tick()
+ if(IsMultiple(activeFor, 3))
+ spawn_meteors(5, wave_type) //meteor list types defined in gamemode/meteor/meteors.dm
+
+/datum/round_event_control/meteor_wave/threatening
+ name = "Meteor Wave: Threatening"
+ typepath = /datum/round_event/meteor_wave/threatening
+ weight = 2
+ min_players = 5
+ max_occurrences = 3
+
+/datum/round_event/meteor_wave/threatening
+ wave_name = "threatening"
+
+/datum/round_event_control/meteor_wave/catastrophic
+ name = "Meteor Wave: Catastrophic"
+ typepath = /datum/round_event/meteor_wave/catastrophic
+ weight = 1
+ min_players = 5
+ max_occurrences = 3
+
+/datum/round_event/meteor_wave/catastrophic
+ wave_name = "catastrophic"
diff --git a/code/modules/holiday/holidays.dm b/code/modules/holiday/holidays.dm
index c8e9235646..751bc53eac 100644
--- a/code/modules/holiday/holidays.dm
+++ b/code/modules/holiday/holidays.dm
@@ -272,7 +272,7 @@
/datum/holiday/halloween
name = HALLOWEEN
- begin_day = 30
+ begin_day = 28
begin_month = OCTOBER
end_day = 2
end_month = NOVEMBER
diff --git a/code/modules/holodeck/turfs.dm b/code/modules/holodeck/turfs.dm
index 80a7b7a545..680300b404 100644
--- a/code/modules/holodeck/turfs.dm
+++ b/code/modules/holodeck/turfs.dm
@@ -106,7 +106,7 @@
slowdown = 2
/turf/open/floor/holofloor/snow/cold
- initial_gas_mix = "freon=7500;TEMP=0"
+ initial_gas_mix = "nob=7500;TEMP=2.7"
/turf/open/floor/holofloor/asteroid
name = "asteroid sand"
diff --git a/code/modules/jobs/job_types/security.dm b/code/modules/jobs/job_types/security.dm
index 442b75c972..a1b95065c6 100644
--- a/code/modules/jobs/job_types/security.dm
+++ b/code/modules/jobs/job_types/security.dm
@@ -48,7 +48,7 @@ Head of Security
gloves = /obj/item/clothing/gloves/color/black/hos
head = /obj/item/clothing/head/HoS/beret
glasses = /obj/item/clothing/glasses/hud/security/sunglasses
- suit_store = /obj/item/gun/energy/e_gun
+ suit_store = /obj/item/gun/energy/e_gun/cx
r_pocket = /obj/item/device/assembly/flash/handheld
l_pocket = /obj/item/restraints/handcuffs
backpack_contents = list(/obj/item/melee/baton/loaded=1)
diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm
index dd5cd53690..31ddb27b2a 100644
--- a/code/modules/lighting/lighting_source.dm
+++ b/code/modules/lighting/lighting_source.dm
@@ -56,10 +56,11 @@
if (top_atom)
LAZYREMOVE(top_atom.light_sources, src)
-
+
+ if (needs_update)
+ GLOB.lighting_update_lights -= src
+
. = ..()
- if(!force)
- return QDEL_HINT_IWILLGC
// Yes this doesn't align correctly on anything other than 4 width tabs.
// If you want it to go switch everybody to elastic tab stops.
@@ -270,8 +271,6 @@
source_turf.luminosity = Ceiling(light_range)
for(T in view(Ceiling(light_range), source_turf))
for (thing in T.get_corners(source_turf))
- if(!thing)
- continue
C = thing
corners[C] = 0
turfs += T
@@ -293,8 +292,6 @@
LAZYINITLIST(effect_str)
if (needs_update == LIGHTING_VIS_UPDATE)
for (thing in corners - effect_str) // New corners
- if(!thing)
- continue
C = thing
LAZYADD(C.affecting, src)
if (!C.active)
@@ -304,8 +301,6 @@
else
L = corners - effect_str
for (thing in L) // New corners
- if(!thing)
- continue
C = thing
LAZYADD(C.affecting, src)
if (!C.active)
@@ -314,8 +309,6 @@
APPLY_CORNER(C)
for (thing in corners - L) // Existing corners
- if(!thing)
- continue
C = thing
if (!C.active)
effect_str[C] = 0
@@ -324,8 +317,6 @@
L = effect_str - corners
for (thing in L) // Old, now gone, corners.
- if(!thing)
- continue
C = thing
REMOVE_CORNER(C)
LAZYREMOVE(C.affecting, src)
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index 3839c87f08..2b2c50ed17 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -480,6 +480,8 @@
client.prefs.copy_to(H)
H.dna.update_dna_identity()
if(mind)
+ if(transfer_after)
+ mind.late_joiner = TRUE
mind.active = 0 //we wish to transfer the key manually
mind.transfer_to(H) //won't transfer key since the mind is not active
diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm
index 831fde141e..f362f09a65 100644
--- a/code/modules/mob/dead/new_player/preferences_setup.dm
+++ b/code/modules/mob/dead/new_player/preferences_setup.dm
@@ -14,7 +14,7 @@
facial_hair_color = hair_color
eye_color = random_eye_color()
if(!pref_species)
- var/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races))
+ var/rando_race = pick(GLOB.roundstart_races)
pref_species = new rando_race()
features = random_features()
age = rand(AGE_MIN,AGE_MAX)
@@ -59,7 +59,7 @@
if(previewJob && !nude)
mannequin.job = previewJob.title
previewJob.equip(mannequin, TRUE)
- mannequin.compile_overlays()
+ COMPILE_OVERLAYS(mannequin)
CHECK_TICK
preview_icon = icon('icons/effects/effects.dmi', "nothing")
preview_icon.Scale(48+32, 16+32)
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index 30d5652ab4..45f26d55c3 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -216,25 +216,23 @@
. = list()
if(!bloodtype)
return
- switch(bloodtype)
- if("A-")
- return list("A-", "O-")
- if("A+")
- return list("A-", "A+", "O-", "O+")
- if("B-")
- return list("B-", "O-")
- if("B+")
- return list("B-", "B+", "O-", "O+")
- if("AB-")
- return list("A-", "B-", "O-", "AB-")
- if("AB+")
- return list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+")
- if("O-")
- return list("O-")
- if("O+")
- return list("O-", "O+")
- if("L")
- return list("L")
+
+ var/static/list/bloodtypes_safe = list(
+ "A-" = list("A-", "O-"),
+ "A+" = list("A-", "A+", "O-", "O+"),
+ "B-" = list("B-", "O-"),
+ "B+" = list("B-", "B+", "O-", "O+"),
+ "AB-" = list("A-", "B-", "O-", "AB-"),
+ "AB+" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+"),
+ "O-" = list("O-"),
+ "O+" = list("O-", "O+"),
+ "L" = list("L"),
+ "U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U")
+ )
+
+ var/safe = bloodtypes_safe[bloodtype]
+ if(safe)
+ . = safe
//to add a splatter of blood or other mob liquid.
/mob/living/proc/add_splatter_floor(turf/T, small_drip)
diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm
index 94ed0129c7..c175acf9d6 100644
--- a/code/modules/mob/living/brain/brain.dm
+++ b/code/modules/mob/living/brain/brain.dm
@@ -19,7 +19,7 @@
/mob/living/brain/proc/create_dna()
stored_dna = new /datum/dna/stored(src)
if(!stored_dna.species)
- var/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races))
+ var/rando_race = pick(GLOB.roundstart_races)
stored_dna.species = new rando_race()
/mob/living/brain/Destroy()
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index 6ac5ab1bad..a3642684db 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -6,7 +6,7 @@
throw_range = 5
layer = ABOVE_MOB_LAYER
zone = "head"
- slot = "brain"
+ slot = ORGAN_SLOT_BRAIN
vital = TRUE
origin_tech = "biotech=5"
attack_verb = list("attacked", "slapped", "whacked")
@@ -70,7 +70,7 @@
C.dna.copy_dna(brainmob.stored_dna)
if(L.disabilities & NOCLONE)
brainmob.disabilities |= NOCLONE //This is so you can't just decapitate a husked guy and clone them without needing to get a new body
- var/obj/item/organ/zombie_infection/ZI = L.getorganslot("zombie_infection")
+ var/obj/item/organ/zombie_infection/ZI = L.getorganslot(ORGAN_SLOT_ZOMBIE)
if(ZI)
brainmob.set_species(ZI.old_species) //For if the brain is cloned
if(L.mind && L.mind.current)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 218af45c6e..4174b08642 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -224,7 +224,7 @@
internal = null
update_internals_hud_icon(0)
else if(ITEM && istype(ITEM, /obj/item/tank))
- if((wear_mask && (wear_mask.flags_1 & MASKINTERNALS_1)) || getorganslot("breathing_tube"))
+ if((wear_mask && (wear_mask.flags_1 & MASKINTERNALS_1)) || getorganslot(ORGAN_SLOT_BREATHING_TUBE))
internal = ITEM
update_internals_hud_icon(1)
@@ -523,7 +523,7 @@
sight = initial(sight)
lighting_alpha = initial(lighting_alpha)
- var/obj/item/organ/eyes/E = getorganslot("eye_sight")
+ var/obj/item/organ/eyes/E = getorganslot(ORGAN_SLOT_EYES)
if(!E)
update_tint()
else
@@ -580,7 +580,7 @@
if(wear_mask)
. += wear_mask.tint
- var/obj/item/organ/eyes/E = getorganslot("eye_sight")
+ var/obj/item/organ/eyes/E = getorganslot(ORGAN_SLOT_EYES)
if(E)
. += E.tint
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 66f4fc8fb2..1d6f7f6484 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -14,7 +14,7 @@
var/obj/item/clothing/mask/MFP = src.wear_mask
number += MFP.flash_protect
- var/obj/item/organ/eyes/E = getorganslot("eye_sight")
+ var/obj/item/organ/eyes/E = getorganslot(ORGAN_SLOT_EYES)
if(!E)
number = INFINITY //Can't get flashed without eyes
else
@@ -28,7 +28,7 @@
number += 1
if(head && (head.flags_2 & BANG_PROTECT_2))
number += 1
- var/obj/item/organ/ears/E = getorganslot("ears")
+ var/obj/item/organ/ears/E = getorganslot(ORGAN_SLOT_EARS)
if(!E)
number = INFINITY
else
@@ -279,7 +279,7 @@
var/damage = intensity - get_eye_protection()
if(.) // we've been flashed
- var/obj/item/organ/eyes/eyes = getorganslot("eye_sight")
+ var/obj/item/organ/eyes/eyes = getorganslot(ORGAN_SLOT_EYES)
if (!eyes)
return
if(visual)
@@ -323,7 +323,7 @@
/mob/living/carbon/soundbang_act(intensity = 1, stun_pwr = 20, damage_pwr = 5, deafen_pwr = 15)
var/ear_safety = get_ear_protection()
- var/obj/item/organ/ears/ears = getorganslot("ears")
+ var/obj/item/organ/ears/ears = getorganslot(ORGAN_SLOT_EARS)
var/effect_amount = intensity - ear_safety
if(effect_amount > 0)
if(stun_pwr)
@@ -363,6 +363,6 @@
/mob/living/carbon/can_hear()
. = FALSE
- var/obj/item/organ/ears/ears = getorganslot("ears")
+ var/obj/item/organ/ears/ears = getorganslot(ORGAN_SLOT_EARS)
if(istype(ears) && !ears.deaf)
. = TRUE
diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm
index aa37315b13..ed731408d8 100644
--- a/code/modules/mob/living/carbon/carbon_movement.dm
+++ b/code/modules/mob/living/carbon/carbon_movement.dm
@@ -39,7 +39,7 @@
return 1
// Do we have a jetpack implant (and is it on)?
- var/obj/item/organ/cyberimp/chest/thrusters/T = getorganslot("thrusters")
+ var/obj/item/organ/cyberimp/chest/thrusters/T = getorganslot(ORGAN_SLOT_THRUSTERS)
if(istype(T) && movement_dir && T.allow_thrust(0.01))
return 1
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index c3ae5c39c3..4b1afe0780 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -20,7 +20,7 @@
if(stat == DEAD)
return
stop_sound_channel(CHANNEL_HEARTBEAT)
- var/obj/item/organ/heart/H = getorganslot("heart")
+ var/obj/item/organ/heart/H = getorganslot(ORGAN_SLOT_HEART)
if(H)
H.beat = BEAT_NONE
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 1d7b482875..a39b84e47c 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -270,13 +270,13 @@
if(ishuman(usr))
var/mob/living/carbon/human/H = usr
var/perpname = get_face_name(get_id_name(""))
- if(istype(H.glasses, /obj/item/clothing/glasses/hud) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud))
+ if(istype(H.glasses, /obj/item/clothing/glasses/hud) || istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud))
var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.general)
if(href_list["photo_front"] || href_list["photo_side"])
if(R)
if(!H.canUseHUD())
return
- else if(!istype(H.glasses, /obj/item/clothing/glasses/hud) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical))
+ else if(!istype(H.glasses, /obj/item/clothing/glasses/hud) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/medical))
return
var/obj/item/photo/P = null
if(href_list["photo_front"])
@@ -287,13 +287,13 @@
P.show(H)
if(href_list["hud"] == "m")
- if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical))
+ if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/medical))
if(href_list["p_stat"])
var/health_status = input(usr, "Specify a new physical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("Active", "Physically Unfit", "*Unconscious*", "*Deceased*", "Cancel")
if(R)
if(!H.canUseHUD())
return
- else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical))
+ else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/medical))
return
if(health_status && health_status != "Cancel")
R.fields["p_stat"] = health_status
@@ -303,7 +303,7 @@
if(R)
if(!H.canUseHUD())
return
- else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical))
+ else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/medical))
return
if(health_status && health_status != "Cancel")
R.fields["m_stat"] = health_status
@@ -352,7 +352,7 @@
to_chat(usr, "Gathered data is inconsistent with the analysis, possible cause: poisoning.")
if(href_list["hud"] == "s")
- if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
+ if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
if(usr.stat || usr == src) //|| !usr.canmove || usr.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at.
return //Non-fluff: This allows sec to set people to arrest as they get disarmed or beaten
// Checks the user has security clearence before allowing them to change arrest status via hud, comment out to enable all access
@@ -379,7 +379,7 @@
if(setcriminal != "Cancel")
if(R)
if(H.canUseHUD())
- if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
+ if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
investigate_log("[src.key] has been set from [R.fields["criminal"]] to [setcriminal] by [usr.name] ([usr.key]).", INVESTIGATE_RECORDS)
R.fields["criminal"] = setcriminal
sec_hud_set_security_status()
@@ -389,7 +389,7 @@
if(R)
if(!H.canUseHUD())
return
- else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
+ else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
return
to_chat(usr, "Name: [R.fields["name"]] Criminal Status: [R.fields["criminal"]]")
to_chat(usr, "Minor Crimes:")
@@ -418,7 +418,7 @@
return
else if(!H.canUseHUD())
return
- else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
+ else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
return
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, worldtime2text())
GLOB.data_core.addMinorCrime(R.fields["id"], crime)
@@ -433,7 +433,7 @@
return
else if (!H.canUseHUD())
return
- else if (!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
+ else if (!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
return
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, worldtime2text())
GLOB.data_core.addMajorCrime(R.fields["id"], crime)
@@ -444,7 +444,7 @@
if(R)
if(!H.canUseHUD())
return
- else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
+ else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
return
to_chat(usr, "Comments/Log:")
var/counter = 1
@@ -462,7 +462,7 @@
return
else if(!H.canUseHUD())
return
- else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
+ else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
return
var/counter = 1
while(R.fields[text("com_[]", counter)])
@@ -637,7 +637,7 @@
return 0
var/they_breathe = (!(NOBREATH in C.dna.species.species_traits))
- var/they_lung = C.getorganslot("lungs")
+ var/they_lung = C.getorganslot(ORGAN_SLOT_LUNGS)
if(C.health > HEALTH_THRESHOLD_CRIT)
return
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 07bcb484a0..f21f872d0a 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -451,7 +451,7 @@
siemens_coeff = gloves_siemens_coeff
if(undergoing_cardiac_arrest() && !illusion)
if(shock_damage * siemens_coeff >= 1 && prob(25))
- var/obj/item/organ/heart/heart = getorganslot("heart")
+ var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
heart.beating = TRUE
if(stat == CONSCIOUS)
to_chat(src, "You feel your heart beating again!")
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 4fba96df58..51de0c2d91 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -45,14 +45,15 @@
return
else
//No oldFP or it's a different kind of blood
- S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state]-BLOOD_LOSS_PER_STEP)
- var/obj/effect/decal/cleanable/blood/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints(T)
- FP.blood_state = S.blood_state
- FP.entered_dirs |= dir
- FP.bloodiness = S.bloody_shoes[S.blood_state]
- if(S.blood_DNA && S.blood_DNA.len)
- FP.transfer_blood_dna(S.blood_DNA)
- FP.update_icon()
+ S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state] - BLOOD_LOSS_PER_STEP)
+ if (S.bloody_shoes[S.blood_state] > BLOOD_LOSS_IN_SPREAD)
+ var/obj/effect/decal/cleanable/blood/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints(T)
+ FP.blood_state = S.blood_state
+ FP.entered_dirs |= dir
+ FP.bloodiness = S.bloody_shoes[S.blood_state] - BLOOD_LOSS_IN_SPREAD
+ if(S.blood_DNA && S.blood_DNA.len)
+ FP.transfer_blood_dna(S.blood_DNA)
+ FP.update_icon()
update_inv_shoes()
//End bloody footprints
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 1679ff5d42..71c5dedc26 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -225,7 +225,7 @@
/mob/living/carbon/human/wear_mask_update(obj/item/clothing/C, toggle_off = 1)
if((C.flags_inv & (HIDEHAIR|HIDEFACIALHAIR)) || (initial(C.flags_inv) & (HIDEHAIR|HIDEFACIALHAIR)))
update_hair()
- if(toggle_off && internal && !getorganslot("breathing_tube"))
+ if(toggle_off && internal && !getorganslot(ORGAN_SLOT_BREATHING_TUBE))
update_internals_hud_icon(0)
internal = null
if(C.flags_inv & HIDEEYES)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index a17dbd6f75..67843b3e64 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -93,7 +93,7 @@
#define HUMAN_CRIT_MAX_OXYLOSS (SSmobs.wait/30)
/mob/living/carbon/human/check_breath(datum/gas_mixture/breath)
- var/L = getorganslot("lungs")
+ var/L = getorganslot(ORGAN_SLOT_LUNGS)
if(!L)
if(health >= HEALTH_THRESHOLD_CRIT)
@@ -338,7 +338,7 @@
/mob/living/carbon/human/proc/undergoing_cardiac_arrest()
if(!can_heartattack())
return FALSE
- var/obj/item/organ/heart/heart = getorganslot("heart")
+ var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
if(istype(heart) && heart.beating)
return FALSE
return TRUE
@@ -347,7 +347,7 @@
if(!can_heartattack())
return FALSE
- var/obj/item/organ/heart/heart = getorganslot("heart")
+ var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
if(!istype(heart))
return
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index d38fa73761..1374b391ce 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -49,7 +49,7 @@
CHECK_DNA_AND_SPECIES(src)
// how do species that don't breathe talk? magic, that's what.
- if(!(NOBREATH in dna.species.species_traits) && !getorganslot("lungs"))
+ if(!(NOBREATH in dna.species.species_traits) && !getorganslot(ORGAN_SLOT_LUNGS))
return 0
if(mind)
return !mind.miming
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 7a212d371b..f5b339405d 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1,5 +1,7 @@
// This code handles different species in the game.
+GLOBAL_LIST_EMPTY(roundstart_races)
+
#define HEAT_DAMAGE_LEVEL_1 2
#define HEAT_DAMAGE_LEVEL_2 3
#define HEAT_DAMAGE_LEVEL_3 8
@@ -12,7 +14,6 @@
var/id // if the game needs to manually check your race to do something not included in a proc here, it will use this
var/limbs_id //this is used if you want to use a different species limb sprites. Mainly used for angels as they look like humans.
var/name // this is the fluff name. these will be left generic (such as 'Lizardperson' for the lizard race) so servers can change them to whatever
- var/roundstart = 0 // can this mob be chosen at roundstart? (assuming the config option is checked?)
var/default_color = "#FFF" // if alien colors are disabled, this is the color that will be used by that race
var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows
@@ -65,6 +66,7 @@
var/breathid = "o2"
var/obj/item/organ/brain/mutant_brain = /obj/item/organ/brain
+ var/obj/item/organ/heart/mutant_heart = /obj/item/organ/heart
var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes
var/obj/item/organ/ears/mutantears = /obj/item/organ/ears
var/obj/item/mutanthands
@@ -92,6 +94,20 @@
..()
+/proc/generate_selectable_species()
+ for(var/I in subtypesof(/datum/species))
+ var/datum/species/S = new I
+ if(S.check_roundstart_eligible())
+ GLOB.roundstart_races += S.id
+ qdel(S)
+ if(!GLOB.roundstart_races.len)
+ GLOB.roundstart_races += "human"
+
+/datum/species/proc/check_roundstart_eligible()
+ if(id in (CONFIG_GET(keyed_flag_list/roundstart_races)))
+ return TRUE
+ return FALSE
+
/datum/species/proc/random_name(gender,unique,lastname)
if(unique)
return random_unique_name(gender)
@@ -122,15 +138,15 @@
//Will regenerate missing organs
/datum/species/proc/regenerate_organs(mob/living/carbon/C,datum/species/old_species,replace_current=TRUE)
- var/obj/item/organ/brain/brain = C.getorganslot("brain")
- var/obj/item/organ/heart/heart = C.getorganslot("heart")
- var/obj/item/organ/lungs/lungs = C.getorganslot("lungs")
- var/obj/item/organ/appendix/appendix = C.getorganslot("appendix")
- var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight")
- var/obj/item/organ/ears/ears = C.getorganslot("ears")
- var/obj/item/organ/tongue/tongue = C.getorganslot("tongue")
- var/obj/item/organ/liver/liver = C.getorganslot("liver")
- var/obj/item/organ/stomach/stomach = C.getorganslot("stomach")
+ var/obj/item/organ/brain/brain = C.getorganslot(ORGAN_SLOT_BRAIN)
+ var/obj/item/organ/heart/heart = C.getorganslot(ORGAN_SLOT_HEART)
+ var/obj/item/organ/lungs/lungs = C.getorganslot(ORGAN_SLOT_LUNGS)
+ var/obj/item/organ/appendix/appendix = C.getorganslot(ORGAN_SLOT_APPENDIX)
+ var/obj/item/organ/eyes/eyes = C.getorganslot(ORGAN_SLOT_EYES)
+ var/obj/item/organ/ears/ears = C.getorganslot(ORGAN_SLOT_EARS)
+ var/obj/item/organ/tongue/tongue = C.getorganslot(ORGAN_SLOT_TONGUE)
+ var/obj/item/organ/liver/liver = C.getorganslot(ORGAN_SLOT_LIVER)
+ var/obj/item/organ/stomach/stomach = C.getorganslot(ORGAN_SLOT_STOMACH)
var/should_have_brain = TRUE
var/should_have_heart = !(NOBLOOD in species_traits)
@@ -154,7 +170,7 @@
heart.Remove(C,1)
QDEL_NULL(heart)
if(should_have_heart && !heart)
- heart = new()
+ heart = new mutant_heart()
heart.Insert(C)
if(lungs && (replace_current || !should_have_lungs))
@@ -1152,7 +1168,7 @@
if(radiation > RAD_MOB_VOMIT && prob(RAD_MOB_VOMIT_PROB))
H.vomit(10, TRUE)
-
+
if(radiation > RAD_MOB_MUTATE)
if(prob(1))
to_chat(H, "You mutate!")
@@ -1204,7 +1220,7 @@
if(!gravity)
var/obj/item/tank/jetpack/J = H.back
var/obj/item/clothing/suit/space/hardsuit/C = H.wear_suit
- var/obj/item/organ/cyberimp/chest/thrusters/T = H.getorganslot("thrusters")
+ var/obj/item/organ/cyberimp/chest/thrusters/T = H.getorganslot(ORGAN_SLOT_THRUSTERS)
if(!istype(J) && istype(C))
J = C.jetpack
if(istype(J) && J.full_speed && J.allow_thrust(0.01, H)) //Prevents stacking
@@ -1260,7 +1276,7 @@
return 1
else
var/we_breathe = (!(NOBREATH in user.dna.species.species_traits))
- var/we_lung = user.getorganslot("lungs")
+ var/we_lung = user.getorganslot(ORGAN_SLOT_LUNGS)
if(we_breathe && we_lung)
user.do_cpr(target)
diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
index eea5dd8709..4ce338e7bf 100644
--- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm
+++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
@@ -30,6 +30,7 @@
head.flags_1 = HEAR_1
head.throwforce = 25
myhead = new /obj/item/dullahan_relay (head, H)
+ H.put_in_hands(head)
/datum/species/dullahan/on_species_loss(mob/living/carbon/human/H)
if(myhead)
@@ -93,6 +94,10 @@
actions_types = list(/datum/action/item_action/organ_action/dullahan)
zone = "abstract"
+/datum/action/item_action/organ_action/dullahan
+ name = "Toggle Perspective"
+ desc = "Switch between seeing normally from your head, or blindly from your body."
+
/datum/action/item_action/organ_action/dullahan/Trigger()
. = ..()
var/obj/item/organ/eyes/dullahan/DE = target
diff --git a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
index d15280790e..bff4d8554a 100644
--- a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
@@ -8,7 +8,6 @@
attack_verb = "claw"
attack_sound = 'sound/weapons/slash.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
- roundstart = 1
liked_food = MEAT | FRIED
disliked_food = TOXIC
@@ -31,7 +30,6 @@
attack_verb = "peck"
attack_sound = 'sound/weapons/slash.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
- roundstart = 1
liked_food = MEAT | FRUIT
disliked_food = TOXIC
@@ -53,7 +51,6 @@
attack_verb = "bite"
attack_sound = 'sound/weapons/bite.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
- roundstart = 1
liked_food = MEAT
disliked_food = TOXIC
@@ -75,7 +72,6 @@
attack_verb = "flutter" //wat?
attack_sound = 'sound/weapons/slash.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
- roundstart = 1
liked_food = MEAT | FRUIT
disliked_food = TOXIC
@@ -105,7 +101,6 @@
skinned_type = /obj/item/stack/sheet/animalhide/xeno
exotic_bloodtype = "L"
damage_overlay_type = "xeno"
- roundstart = 1
liked_food = MEAT
//Praise the Omnissiah, A challange worthy of my skills - HS
@@ -138,7 +133,6 @@
meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno
skinned_type = /obj/item/stack/sheet/animalhide/xeno
// safe_toxins_max = 32 //Too much of anything is bad.
- roundstart = 0
// whitelisted = 1
// whitelist = list("talkingcactus") //testing whitelisting
@@ -182,7 +176,6 @@
punchdamagehigh = 14
punchstunthreshold = 13
blacklisted = 1
- roundstart = 0
whitelist = 1
whitelist = list("talkingcactus")
@@ -233,7 +226,6 @@
attack_verb = "bite"
attack_sound = 'sound/weapons/bite.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
-// roundstart = 1
whitelisted = 1
whitelist = list("rubyflamewing")
blacklisted = 0
@@ -248,4 +240,3 @@
attack_verb = "claw"
attack_sound = 'sound/weapons/slash.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
- roundstart = 1
diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm
index 97b88d7715..b21f0e2bba 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -22,6 +22,7 @@
limbs_id = "golem"
fixed_mut_color = "aaa"
var/info_text = "As an Iron Golem, you don't have any special traits."
+ var/random_eligible = TRUE //If false, the golem subtype can't be made through golem mutation toxin
var/prefix = "Iron"
var/list/special_names
@@ -44,11 +45,20 @@
name = "Random Golem"
blacklisted = FALSE
dangerous_existence = FALSE
+ var/static/list/random_golem_types
/datum/species/golem/random/on_species_gain(mob/living/carbon/C, datum/species/old_species)
..()
- var/list/golem_types = typesof(/datum/species/golem) - src.type
- var/datum/species/golem/golem_type = pick(golem_types)
+ if(!random_golem_types)
+ random_golem_types = subtypesof(/datum/species/golem) - type
+ for(var/V in random_golem_types)
+ var/datum/species/golem/G = V
+ if(!initial(G.random_eligible))
+ random_golem_types -= G
+ to_chat(world, "Excluding golem type [initial(G.id)]")
+ else
+ to_chat(world, "Allowing golem type [initial(G.id)]")
+ var/datum/species/golem/golem_type = pick(random_golem_types)
var/mob/living/carbon/human/H = C
H.set_species(golem_type)
to_chat(H, "[initial(golem_type.info_text)]")
@@ -419,6 +429,7 @@
if(ishuman(C))
unstable_teleport = new
unstable_teleport.Grant(C)
+ last_teleport = world.time
/datum/species/golem/bluespace/on_species_loss(mob/living/carbon/C)
if(unstable_teleport)
@@ -479,6 +490,11 @@
var/banana_cooldown = 100
var/active = null
+/datum/species/golem/bananium/on_species_gain(mob/living/carbon/C, datum/species/old_species)
+ ..()
+ last_banana = world.time
+ last_honk = world.time
+
/datum/species/golem/bananium/random_name(gender,unique,lastname)
var/clown_name = pick(GLOB.clown_names)
var/golem_name = "[uppertext(clown_name)]"
@@ -553,10 +569,13 @@
. = ..()
C.faction |= "cult"
phase_shift = new
+ phase_shift.charge_counter = 0
C.AddSpell(phase_shift)
abyssal_gaze = new
+ abyssal_gaze.charge_counter = 0
C.AddSpell(abyssal_gaze)
dominate = new
+ dominate.charge_counter = 0
C.AddSpell(dominate)
/datum/species/golem/runic/on_species_loss(mob/living/carbon/C)
@@ -587,7 +606,7 @@
info_text = "As a clockwork golem, you are faster than \
other types of golem (being a machine), and are immune to electric shocks."
species_traits = list(NO_UNDERWEAR, NOTRANSSTING, NOBREATH, NOZOMBIE, VIRUSIMMUNE, RADIMMUNE, NOBLOOD, RESISTCOLD, RESISTPRESSURE, PIERCEIMMUNE)
- armor = 40 //Reinforced, but also slim to allow for fast movement
+ armor = 20 //Reinforced, but much less so to allow for fast movement
attack_verb = "smash"
attack_sound = 'sound/magic/clockwork/anima_fragment_attack.ogg'
sexes = FALSE
@@ -629,7 +648,8 @@
has_corpse = TRUE
blacklisted = TRUE
dangerous_existence = TRUE
-
+ random_eligible = FALSE
+
/datum/species/golem/cloth
name = "Cloth Golem"
id = "cloth golem"
@@ -645,6 +665,11 @@
punchdamagehigh = 8 // not as heavy as stone
prefix = "Cloth"
+/datum/species/golem/cloth/check_roundstart_eligible()
+ if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
+ return TRUE
+ return ..()
+
/datum/species/golem/cloth/random_name(gender,unique,lastname)
var/pharaoh_name = pick("Neferkare", "Hudjefa", "Khufu", "Mentuhotep", "Ahmose", "Amenhotep", "Thutmose", "Hatshepsut", "Tutankhamun", "Ramses", "Seti", \
"Merenptah", "Djer", "Semerkhet", "Nynetjer", "Khafre", "Pepi", "Intef", "Ay") //yes, Ay was an actual pharaoh
diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
index 84bf5bdf80..3881eae6f5 100644
--- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
@@ -13,7 +13,6 @@
disliked_food = NONE
liked_food = NONE
toxic_food = NONE
- roundstart = TRUE
/datum/species/pod/on_species_gain(mob/living/carbon/C, datum/species/old_species)
diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
index 4347a8331c..a326150c60 100644
--- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
@@ -1,4 +1,5 @@
#define HEART_RESPAWN_THRESHHOLD 40
+#define HEART_SPECIAL_SHADOWIFY 2
/datum/species/shadow
// Humans cursed to stay in the darkness, lest their life forces drain. They regain health in shadow and die in light.
@@ -24,6 +25,10 @@
else if (light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD) //heal in the dark
H.heal_overall_damage(1,1)
+/datum/species/shadow/check_roundstart_eligible()
+ if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
+ return TRUE
+ return ..()
/datum/species/shadow/nightmare
name = "Nightmare"
@@ -60,7 +65,8 @@
return -1
return 0
-
+/datum/species/shadow/nightmare/check_roundstart_eligible()
+ return FALSE
//Organs
@@ -111,14 +117,15 @@
/obj/item/organ/heart/nightmare/Insert(mob/living/carbon/M, special = 0)
..()
- blade = new/obj/item/light_eater
- M.put_in_hands(blade)
+ if(special != HEART_SPECIAL_SHADOWIFY)
+ blade = new/obj/item/light_eater
+ M.put_in_hands(blade)
START_PROCESSING(SSobj, src)
/obj/item/organ/heart/nightmare/Remove(mob/living/carbon/M, special = 0)
STOP_PROCESSING(SSobj, src)
respawn_progress = 0
- if(blade)
+ if(blade && special != HEART_SPECIAL_SHADOWIFY)
QDEL_NULL(blade)
M.visible_message("\The [blade] disintegrates!")
..()
@@ -141,6 +148,13 @@
playsound(owner,'sound/effects/singlebeat.ogg',40,1)
if(respawn_progress >= HEART_RESPAWN_THRESHHOLD)
owner.revive(full_heal = TRUE)
+ if(!(owner.dna.species.id == "shadow" || owner.dna.species.id == "nightmare"))
+ var/mob/living/carbon/old_owner = owner
+ Remove(owner, HEART_SPECIAL_SHADOWIFY)
+ old_owner.set_species(/datum/species/shadow)
+ Insert(old_owner, HEART_SPECIAL_SHADOWIFY)
+ to_chat(owner, "You feel the shadows invade your skin, leaping into the center of your chest! You're alive!")
+ SEND_SOUND(owner, sound('sound/effects/ghost.ogg'))
owner.visible_message("[owner] staggers to their feet!")
playsound(owner, 'sound/hallucinations/far_noise.ogg', 50, 1)
respawn_progress = 0
@@ -193,4 +207,5 @@
O.burn()
playsound(src, 'sound/items/welder.ogg', 50, 1)
+#undef HEART_SPECIAL_SHADOWIFY
#undef HEART_RESPAWN_THRESHHOLD
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
index be03e591aa..acaa182ad0 100644
--- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm
+++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
@@ -11,3 +11,8 @@
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
disliked_food = NONE
liked_food = NONE
+
+/datum/species/skeleton/check_roundstart_eligible()
+ if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
+ return TRUE
+ return ..()
diff --git a/code/modules/mob/living/carbon/human/species_types/synths.dm b/code/modules/mob/living/carbon/human/species_types/synths.dm
index 45b4a28bb5..8b21c2a237 100644
--- a/code/modules/mob/living/carbon/human/species_types/synths.dm
+++ b/code/modules/mob/living/carbon/human/species_types/synths.dm
@@ -118,4 +118,4 @@
else
return ..()
else
- return ..()
+ return ..()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm
new file mode 100644
index 0000000000..0d309876c7
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm
@@ -0,0 +1,125 @@
+/datum/species/vampire
+ name = "vampire"
+ id = "vampire"
+ default_color = "FFFFFF"
+ species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,NOHUNGER,NOBREATH,DRINKSBLOOD)
+ mutant_bodyparts = list("tail_human", "ears", "wings")
+ default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "None")
+ exotic_bloodtype = "U"
+ use_skintones = TRUE
+ mutant_heart = /obj/item/organ/heart/vampire
+ mutanttongue = /obj/item/organ/tongue/vampire
+ blacklisted = TRUE
+ limbs_id = "human"
+ skinned_type = /obj/item/stack/sheet/animalhide/human
+ var/info_text = "You are a Vampire. You will slowly but constantly lose blood if outside of a coffin. If inside a coffin, you will slowly heal. You may gain more blood by grabbing a live victim and using your drain ability."
+
+/datum/species/vampire/check_roundstart_eligible()
+ if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
+ return TRUE
+ return FALSE
+
+/datum/species/vampire/on_species_gain(mob/living/carbon/human/C, datum/species/old_species)
+ . = ..()
+ to_chat(C, "[info_text]")
+ C.skin_tone = "albino"
+ C.update_body(0)
+ var/obj/effect/proc_holder/spell/targeted/shapeshift/bat/B = new
+ C.AddSpell(B)
+
+/datum/species/vampire/on_species_loss(mob/living/carbon/C)
+ . = ..()
+ if(C.mind)
+ for(var/S in C.mind.spell_list)
+ var/obj/effect/proc_holder/spell/S2 = S
+ if(S2.type == /obj/effect/proc_holder/spell/targeted/shapeshift/bat)
+ C.mind.spell_list.Remove(S2)
+ qdel(S2)
+
+/datum/species/vampire/spec_life(mob/living/carbon/human/C)
+ . = ..()
+ if(istype(C.loc, /obj/structure/closet/coffin))
+ C.heal_overall_damage(4,4)
+ C.adjustToxLoss(-4)
+ C.adjustOxyLoss(-4)
+ C.adjustCloneLoss(-4)
+ return
+ C.blood_volume -= 0.75
+ if(C.blood_volume <= BLOOD_VOLUME_SURVIVE)
+ to_chat(C, "You ran out of blood!")
+ C.dust()
+ var/area/A = get_area(C)
+ if(istype(A, /area/chapel))
+ to_chat(C, "You don't belong here!")
+ C.adjustFireLoss(20)
+ C.adjust_fire_stacks(6)
+ C.IgniteMob()
+
+/obj/item/organ/tongue/vampire
+ name = "vampire tongue"
+ actions_types = list(/datum/action/item_action/organ_action/vampire)
+ color = "#1C1C1C"
+ var/drain_cooldown = 0
+
+#define VAMP_DRAIN_AMOUNT 50
+
+/datum/action/item_action/organ_action/vampire
+ name = "Drain Victim"
+ desc = "Leech blood from any carbon victim you are passively grabbing."
+
+/datum/action/item_action/organ_action/vampire/Trigger()
+ . = ..()
+ if(iscarbon(owner))
+ var/mob/living/carbon/H = owner
+ var/obj/item/organ/tongue/vampire/V = target
+ if(V.drain_cooldown >= world.time)
+ to_chat(H, "You just drained blood, wait a few seconds.")
+ return
+ if(H.pulling && iscarbon(H.pulling))
+ var/mob/living/carbon/victim = H.pulling
+ if(H.blood_volume >= BLOOD_VOLUME_MAXIMUM)
+ to_chat(H, "You're already full!")
+ return
+ if(victim.stat == DEAD)
+ to_chat(H, "You need a living victim!")
+ return
+ if(!victim.blood_volume || (victim.dna && ((NOBLOOD in victim.dna.species.species_traits) || victim.dna.species.exotic_blood)))
+ to_chat(H, "[victim] doesn't have blood!")
+ return
+ V.drain_cooldown = world.time + 30
+ if(!do_after(H, 30, target = victim))
+ return
+ var/blood_volume_difference = BLOOD_VOLUME_MAXIMUM - H.blood_volume //How much capacity we have left to absorb blood
+ var/drained_blood = min(victim.blood_volume, VAMP_DRAIN_AMOUNT, blood_volume_difference)
+ to_chat(victim, "[H] is draining your blood!")
+ to_chat(H, "You drain some blood!")
+ playsound(H, 'sound/items/drink.ogg', 30, 1, -2)
+ victim.blood_volume = Clamp(victim.blood_volume - drained_blood, 0, BLOOD_VOLUME_MAXIMUM)
+ H.blood_volume = Clamp(H.blood_volume + drained_blood, 0, BLOOD_VOLUME_MAXIMUM)
+ if(!victim.blood_volume)
+ to_chat(H, "You finish off [victim]'s blood supply!")
+
+#undef VAMP_DRAIN_AMOUNT
+
+/obj/item/organ/heart/vampire
+ name = "vampire heart"
+ actions_types = list(/datum/action/item_action/organ_action/vampire_heart)
+ color = "#1C1C1C"
+
+/datum/action/item_action/organ_action/vampire_heart
+ name = "Check Blood Level"
+ desc = "Check how much blood you have remaining."
+
+/datum/action/item_action/organ_action/vampire_heart/Trigger()
+ . = ..()
+ if(iscarbon(owner))
+ var/mob/living/carbon/H = owner
+ to_chat(H, "Current blood level: [H.blood_volume]/[BLOOD_VOLUME_MAXIMUM].")
+
+/obj/effect/proc_holder/spell/targeted/shapeshift/bat
+ name = "Bat Form"
+ desc = "Take on the shape a space bat."
+ invocation = "Squeak!"
+ charge_max = 50
+ cooldown_min = 50
+ shapeshift_type = /mob/living/simple_animal/hostile/retaliate/bat
diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm
index 016a3635ef..8c87e1c9c9 100644
--- a/code/modules/mob/living/carbon/human/species_types/zombies.dm
+++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm
@@ -14,6 +14,11 @@
disliked_food = NONE
liked_food = NONE
+/datum/species/zombie/check_roundstart_eligible()
+ if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
+ return TRUE
+ return ..()
+
/datum/species/zombie/infectious
name = "Infectious Zombie"
id = "memezombies"
@@ -24,6 +29,10 @@
mutanteyes = /obj/item/organ/eyes/night_vision/zombie
var/regen_cooldown = 0
+/datum/species/zombie/infectious/check_roundstart_eligible()
+ return FALSE
+
+
/datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H,amount)
. = min(2, amount)
@@ -52,7 +61,7 @@
// Infection organ needs to be handled separately from mutant_organs
// because it persists through species transitions
var/obj/item/organ/zombie_infection/infection
- infection = C.getorganslot("zombie_infection")
+ infection = C.getorganslot(ORGAN_SLOT_ZOMBIE)
if(!infection)
infection = new()
infection.Insert(C)
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 31f8eb3f73..0d50285859 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -58,7 +58,7 @@
var/datum/gas_mixture/breath
- if(!getorganslot("breathing_tube"))
+ if(!getorganslot(ORGAN_SLOT_BREATHING_TUBE))
if(health <= HEALTH_THRESHOLD_FULLCRIT || (pulledby && pulledby.grab_state >= GRAB_KILL))
losebreath++ //You can't breath at all when in critical or when being choked, so you're going to miss a breath
@@ -110,7 +110,7 @@
if((status_flags & GODMODE))
return
- var/lungs = getorganslot("lungs")
+ var/lungs = getorganslot(ORGAN_SLOT_LUNGS)
if(!lungs)
adjustOxyLoss(2)
@@ -203,6 +203,16 @@
hallucination += 20
else if(bz_partialpressure > 0.01)
hallucination += 5//Removed at 2 per tick so this will slowly build up
+ //TRITIUM
+ if(breath_gases[/datum/gas/tritium])
+ var/tritium_partialpressure = (breath_gases[/datum/gas/tritium][MOLES]/breath.total_moles())*breath_pressure
+ radiation += tritium_partialpressure/10
+ //Brown Gas
+ if (breath_gases[/datum/gas/brown_gas])
+ var/browns_partialpressure = (breath_gases[/datum/gas/brown_gas][MOLES]/breath.total_moles())*breath_pressure
+ adjustFireLoss(browns_partialpressure/4)
+
+
breath.garbage_collect()
@@ -220,7 +230,7 @@
if(internal.loc != src)
internal = null
update_internals_hud_icon(0)
- else if ((!wear_mask || !(wear_mask.flags_1 & MASKINTERNALS_1)) && !getorganslot("breathing_tube"))
+ else if ((!wear_mask || !(wear_mask.flags_1 & MASKINTERNALS_1)) && !getorganslot(ORGAN_SLOT_BREATHING_TUBE))
internal = null
update_internals_hud_icon(0)
else
@@ -391,7 +401,7 @@
/////////
/mob/living/carbon/proc/handle_liver()
- var/obj/item/organ/liver/liver = getorganslot("liver")
+ var/obj/item/organ/liver/liver = getorganslot(ORGAN_SLOT_LIVER)
if((!dna && !liver) || (NOLIVER in dna.species.species_traits))
return
if(liver)
@@ -404,17 +414,17 @@
liver_failure()
/mob/living/carbon/proc/undergoing_liver_failure()
- var/obj/item/organ/liver/liver = getorganslot("liver")
+ var/obj/item/organ/liver/liver = getorganslot(ORGAN_SLOT_LIVER)
if(liver && liver.failing)
return TRUE
/mob/living/carbon/proc/return_liver_damage()
- var/obj/item/organ/liver/liver = getorganslot("liver")
+ var/obj/item/organ/liver/liver = getorganslot(ORGAN_SLOT_LIVER)
if(liver)
return liver.damage
/mob/living/carbon/proc/applyLiverDamage(var/d)
- var/obj/item/organ/liver/L = getorganslot("liver")
+ var/obj/item/organ/liver/L = getorganslot(ORGAN_SLOT_LIVER)
if(L)
L.damage += d
diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm
index 2fcfe97d65..779e7f2f90 100644
--- a/code/modules/mob/living/carbon/monkey/monkey.dm
+++ b/code/modules/mob/living/carbon/monkey/monkey.dm
@@ -140,7 +140,7 @@
return protection
/mob/living/carbon/monkey/IsVocal()
- if(!getorganslot("lungs"))
+ if(!getorganslot(ORGAN_SLOT_LUNGS))
return 0
return 1
diff --git a/code/modules/mob/living/carbon/say.dm b/code/modules/mob/living/carbon/say.dm
index d6ee2ebbfc..526a2ea09b 100644
--- a/code/modules/mob/living/carbon/say.dm
+++ b/code/modules/mob/living/carbon/say.dm
@@ -1,6 +1,6 @@
/mob/living/carbon/treat_message(message)
message = ..(message)
- var/obj/item/organ/tongue/T = getorganslot("tongue")
+ var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE)
if(!T) //hoooooouaah!
var/regex/tongueless_lower = new("\[gdntke]+", "g")
var/regex/tongueless_upper = new("\[GDNTKE]+", "g")
@@ -21,7 +21,7 @@
/mob/living/carbon/get_spans()
. = ..()
- var/obj/item/organ/tongue/T = getorganslot("tongue")
+ var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE)
if(T)
. |= T.get_spans()
@@ -30,7 +30,7 @@
. |= I.get_held_item_speechspans(src)
/mob/living/carbon/could_speak_in_language(datum/language/dt)
- var/obj/item/organ/tongue/T = getorganslot("tongue")
+ var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE)
if(T)
. = T.could_speak_in_language(dt)
else
diff --git a/code/modules/mob/living/carbon/status_procs.dm b/code/modules/mob/living/carbon/status_procs.dm
index 13a97c4407..ccd5f7296b 100644
--- a/code/modules/mob/living/carbon/status_procs.dm
+++ b/code/modules/mob/living/carbon/status_procs.dm
@@ -3,7 +3,7 @@
// eye damage, eye_blind, eye_blurry, druggy, BLIND disability, NEARSIGHT disability, and HUSK disability.
/mob/living/carbon/damage_eyes(amount)
- var/obj/item/organ/eyes/eyes = getorganslot("eye_sight")
+ var/obj/item/organ/eyes/eyes = getorganslot(ORGAN_SLOT_EYES)
if (!eyes)
return
if(amount>0)
@@ -15,7 +15,7 @@
overlay_fullscreen("eye_damage", /obj/screen/fullscreen/impaired, 1)
/mob/living/carbon/set_eye_damage(amount)
- var/obj/item/organ/eyes/eyes = getorganslot("eye_sight")
+ var/obj/item/organ/eyes/eyes = getorganslot(ORGAN_SLOT_EYES)
if (!eyes)
return
eyes.eye_damage = max(amount,0)
@@ -28,7 +28,7 @@
clear_fullscreen("eye_damage")
/mob/living/carbon/adjust_eye_damage(amount)
- var/obj/item/organ/eyes/eyes = getorganslot("eye_sight")
+ var/obj/item/organ/eyes/eyes = getorganslot(ORGAN_SLOT_EYES)
if (!eyes)
return
eyes.eye_damage = max(eyes.eye_damage+amount, 0)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 87092e580c..0cdcd90e61 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -898,14 +898,17 @@
to_chat(G, "Your summoner has changed form!")
/mob/living/rad_act(amount)
- amount = max(amount-RAD_BACKGROUND_RADIATION, 0)
+ if(!amount || amount < RAD_MOB_SKIN_PROTECTION)
+ return
- if(amount)
- var/blocked = getarmor(null, "rad")
+ amount -= RAD_BACKGROUND_RADIATION // This will always be at least 1 because of how skin protection is calculated
- apply_effect(amount * RAD_MOB_COEFFICIENT, IRRADIATE, blocked)
- if(amount > RAD_AMOUNT_EXTREME)
- apply_damage((amount-RAD_AMOUNT_EXTREME)/RAD_AMOUNT_EXTREME, BURN, null, blocked)
+ var/blocked = getarmor(null, "rad")
+
+ if(amount > RAD_BURN_THRESHOLD)
+ apply_damage((amount-RAD_BURN_THRESHOLD)/RAD_BURN_THRESHOLD, BURN, null, blocked)
+
+ apply_effect((amount*RAD_MOB_COEFFICIENT)/max(1, (radiation**2)*RAD_OVERDOSE_REDUCTION), IRRADIATE, blocked)
/mob/living/proc/fakefireextinguish()
return
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index e3f7795f64..f77c65225f 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -338,18 +338,11 @@
/mob/living/ratvar_act()
if(status_flags & GODMODE)
return
-
if(stat != DEAD && !is_servant_of_ratvar(src))
- for(var/obj/item/implant/mindshield/M in implants)
- qdel(M)
- if(!add_servant_of_ratvar(src))
- to_chat(src, "A blinding light boils you alive! Run!")
- adjustFireLoss(35)
- if(src)
- adjust_fire_stacks(1)
- IgniteMob()
- return FALSE
- return TRUE
+ to_chat(src, "A blinding light boils you alive! Run!")
+ adjust_fire_stacks(20)
+ IgniteMob()
+ return FALSE
//called when the mob receives a bright flash
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 9c34ca4dbd..7e3d1cd320 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -362,7 +362,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
if(message_mode == MODE_VOCALCORDS)
if(iscarbon(src))
var/mob/living/carbon/C = src
- var/obj/item/organ/vocal_cords/V = C.getorganslot("vocal_cords")
+ var/obj/item/organ/vocal_cords/V = C.getorganslot(ORGAN_SLOT_VOICE)
if(V && V.can_speak_with())
V.handle_speech(message) //message
V.speak_with(message) //action
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index e3d179b3ff..3758e73688 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -352,10 +352,9 @@
/obj/item/soap/tongue,
/obj/item/device/analyzer/nose,
/obj/item/device/dogborg/sleeper/K9,
- /obj/item/pinpointer/crew)
- emag_modules = list(/obj/item/gun/energy/laser/cyborg,
/obj/item/gun/energy/disabler/cyborg,
- /obj/item/pinpointer/nuke)
+ /obj/item/pinpointer/crew)
+ emag_modules = list(/obj/item/gun/energy/laser/cyborg)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security,
/obj/item/clockwork/weapon/ratvarian_spear)
cyborg_base_icon = "k9"
@@ -408,7 +407,6 @@
/obj/item/robot_module/scrubpup
name = "Janitor"
basic_modules = list(
- /obj/item/device/assembly/flash/cyborg,
/obj/item/dogborg/jaws/small,
/obj/item/device/analyzer/nose,
/obj/item/soap/tongue/scrubpup,
@@ -422,6 +420,7 @@
moduleselect_icon = "scrubpup"
feedback_key = "cyborg_scrubpup"
hat_offset = INFINITY
+ clean_on_move = TRUE
/obj/item/robot_module/scrubpup/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
..()
diff --git a/code/modules/mob/living/simple_animal/corpse.dm b/code/modules/mob/living/simple_animal/corpse.dm
index cf1b9b08cc..73cdd6f866 100644
--- a/code/modules/mob/living/simple_animal/corpse.dm
+++ b/code/modules/mob/living/simple_animal/corpse.dm
@@ -12,6 +12,8 @@
name = "Syndicate Operative"
id_job = "Operative"
id_access_list = list(ACCESS_SYNDICATE)
+ hair_style = "Bald"
+ facial_hair_style = "Shaved"
outfit = /datum/outfit/syndicatesoldiercorpse
/datum/outfit/syndicatesoldiercorpse
@@ -31,6 +33,8 @@
name = "Syndicate Commando"
id_job = "Operative"
id_access_list = list(ACCESS_SYNDICATE)
+ hair_style = "Bald"
+ facial_hair_style = "Shaved"
outfit = /datum/outfit/syndicatecommandocorpse
/datum/outfit/syndicatecommandocorpse
@@ -50,6 +54,8 @@
name = "Syndicate Stormtrooper"
id_job = "Operative"
id_access_list = list(ACCESS_SYNDICATE)
+ hair_style = "Bald"
+ facial_hair_style = "Shaved"
outfit = /datum/outfit/syndicatestormtroopercorpse
/datum/outfit/syndicatestormtroopercorpse
@@ -67,11 +73,16 @@
/obj/effect/mob_spawn/human/clown/corpse
roundstart = FALSE
instant = TRUE
-
+ skin_tone = "caucasian1"
+ hair_style = "Bald"
+ facial_hair_style = "Shaved"
/obj/effect/mob_spawn/human/corpse/pirate
name = "Pirate"
+ skin_tone = "Caucasian1" //all pirates are white because it's easier that way
outfit = /datum/outfit/piratecorpse
+ hair_style = "Bald"
+ facial_hair_style = "Shaved"
/datum/outfit/piratecorpse
name = "Pirate Corpse"
@@ -94,12 +105,17 @@
/obj/effect/mob_spawn/human/corpse/russian
name = "Russian"
outfit = /datum/outfit/russiancorpse
+ hair_style = "Bald"
+ facial_hair_style = "Shaved"
/datum/outfit/russiancorpse
name = "Russian Corpse"
uniform = /obj/item/clothing/under/soviet
shoes = /obj/item/clothing/shoes/jackboots
head = /obj/item/clothing/head/bearpelt
+ gloves = /obj/item/clothing/gloves/color/black
+ mask = /obj/item/clothing/mask/gas
+
/obj/effect/mob_spawn/human/corpse/russian/ranged
@@ -109,6 +125,7 @@
name = "Ranged Russian Corpse"
head = /obj/item/clothing/head/ushanka
+
/obj/effect/mob_spawn/human/corpse/russian/ranged/trooper
outfit = /datum/outfit/russiancorpse/ranged/trooper
@@ -119,8 +136,8 @@
shoes = /obj/item/clothing/shoes/combat
gloves = /obj/item/clothing/gloves/combat
ears = /obj/item/device/radio/headset
- mask = /obj/item/clothing/mask/balaclava
head = /obj/item/clothing/head/helmet/alt
+ mask = /obj/item/clothing/mask/balaclava
/obj/effect/mob_spawn/human/corpse/russian/ranged/officer
@@ -131,7 +148,7 @@
name = "Russian Officer Corpse"
uniform = /obj/item/clothing/under/rank/security/navyblue/russian
suit = /obj/item/clothing/suit/security/officer/russian
- shoes = /obj/item/clothing/shoes/laceup
+ shoes = /obj/item/clothing/shoes/combat
ears = /obj/item/device/radio/headset
head = /obj/item/clothing/head/ushanka
@@ -139,6 +156,9 @@
/obj/effect/mob_spawn/human/corpse/wizard
name = "Space Wizard Corpse"
outfit = /datum/outfit/wizardcorpse
+ hair_style = "Bald"
+ facial_hair_style = "Long Beard"
+ skin_tone = "Caucasian1"
/datum/outfit/wizardcorpse
name = "Space Wizard Corpse"
@@ -153,6 +173,8 @@
id_job = "Private Security Force"
id_access = "Security Officer"
outfit = /datum/outfit/nanotrasensoldiercorpse2
+ hair_style = "Bald"
+ facial_hair_style = "Shaved"
/datum/outfit/nanotrasensoldiercorpse2
name = "NT Private Security Officer Corpse"
diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
index aa288e52d7..3ea1be6f03 100644
--- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
+++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
@@ -206,6 +206,7 @@
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = 1500
+ poison_type = "frost_oil"
color = rgb(114,228,250)
gold_core_spawnable = 0
@@ -214,6 +215,7 @@
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = 1500
+ poison_type = "frost_oil"
color = rgb(114,228,250)
gold_core_spawnable = 0
@@ -222,6 +224,7 @@
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = 1500
+ poison_type = "frost_oil"
color = rgb(114,228,250)
gold_core_spawnable = 0
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
index 7cf68dc401..a214895b83 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -616,7 +616,7 @@ Difficulty: Very Hard
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
ventcrawler = VENTCRAWLER_ALWAYS
mob_size = MOB_SIZE_TINY
- gold_core_spawnable = 0
+ gold_core_spawnable = TRUE
verb_say = "warps"
verb_ask = "floats inquisitively"
verb_exclaim = "zaps"
@@ -634,7 +634,6 @@ Difficulty: Very Hard
environment_smash = ENVIRONMENT_SMASH_NONE
AIStatus = AI_OFF
stop_automated_movement = 1
- gold_core_spawnable = TRUE
var/heal_power = 5
/mob/living/simple_animal/hostile/lightgeist/Initialize()
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm
index 6a96c06978..d75e4acbc5 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm
@@ -34,4 +34,7 @@
//Space bats need no air to fly in.
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
- minbodytemp = 0
\ No newline at end of file
+ minbodytemp = 0
+
+/mob/living/simple_animal/hostile/retaliate/bat/Process_Spacemove(movement_dir = 0)
+ return 1
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm
index d6d46b1a46..d050b4143d 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm
@@ -23,7 +23,7 @@
environment_smash = ENVIRONMENT_SMASH_NONE
del_on_death = 0
-/mob/living/simple_animal/hostile/retaliate/nanotrasenpeace
+/mob/living/simple_animal/hostile/retaliate/nanotrasenpeace //this should be in a different file
name = "Nanotrasen Private Security Officer"
desc = "An officer part of Nanotrasen's private security force."
icon = 'icons/mob/simple_human.dmi'
diff --git a/code/modules/mob/living/taste.dm b/code/modules/mob/living/taste.dm
index 45fdf55fb4..c66168cee4 100644
--- a/code/modules/mob/living/taste.dm
+++ b/code/modules/mob/living/taste.dm
@@ -8,7 +8,7 @@
return DEFAULT_TASTE_SENSITIVITY
/mob/living/carbon/get_taste_sensitivity()
- var/obj/item/organ/tongue/tongue = getorganslot("tongue")
+ var/obj/item/organ/tongue/tongue = getorganslot(ORGAN_SLOT_TONGUE)
if(istype(tongue))
. = tongue.taste_sensitivity
else
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index beb64a9e6e..43f7724af5 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -4,6 +4,8 @@
GLOB.living_mob_list -= src
GLOB.all_clockwork_mobs -= src
GLOB.mob_directory -= tag
+ for (var/alert in alerts)
+ clear_alert(alert, TRUE)
if(observers && observers.len)
for(var/M in observers)
var/mob/dead/observe = M
@@ -31,6 +33,7 @@
continue
var/datum/atom_hud/alternate_appearance/AA = v
AA.onNewMob(src)
+ hook_vr("mob_new",list(src))
. = ..()
/atom/proc/prepare_huds()
@@ -389,7 +392,7 @@
pulling = null
grab_state = 0
update_pull_hud_icon()
-
+
if(isliving(ex_pulled))
var/mob/living/L = ex_pulled
L.update_canmove()// mob gets up if it was lyng down in a chokehold
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index ec63a33568..ec23f5b7f8 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -1,3 +1,14 @@
+GLOBAL_LIST_INIT(cable_colors, list(
+ "yellow" = "#ffff00",
+ "green" = "#00aa00",
+ "blue" = "#1919c8",
+ "pink" = "#ff3cc8",
+ "orange" = "#ff8000",
+ "cyan" = "#00ffff",
+ "white" = "#ffffff",
+ "red" = "#ff0000"
+ ))
+
///////////////////////////////
//CABLE STRUCTURE
///////////////////////////////
@@ -23,61 +34,52 @@ By design, d1 is the smallest direction and d2 is the highest
*/
/obj/structure/cable
- level = 1 //is underfloor
- anchored =1
- on_blueprints = TRUE
- var/datum/powernet/powernet
name = "power cable"
desc = "A flexible, superconducting insulated cable for heavy-duty power transfer."
- icon = 'icons/obj/power_cond/power_cond_red.dmi'
+ icon = 'icons/obj/power_cond/cables.dmi'
icon_state = "0-1"
+ level = 1 //is underfloor
+ layer = WIRE_LAYER //Above hidden pipes, GAS_PIPE_HIDDEN_LAYER
+ anchored = TRUE
+ on_blueprints = TRUE
var/d1 = 0 // cable direction 1 (see above)
var/d2 = 1 // cable direction 2 (see above)
- layer = WIRE_LAYER //Above hidden pipes, GAS_PIPE_HIDDEN_LAYER
- var/cable_color = "red"
+ var/datum/powernet/powernet
var/obj/item/stack/cable_coil/stored
+ var/cable_color = "red"
+
/obj/structure/cable/yellow
cable_color = "yellow"
- icon = 'icons/obj/power_cond/power_cond_yellow.dmi'
/obj/structure/cable/green
cable_color = "green"
- icon = 'icons/obj/power_cond/power_cond_green.dmi'
/obj/structure/cable/blue
cable_color = "blue"
- icon = 'icons/obj/power_cond/power_cond_blue.dmi'
/obj/structure/cable/pink
cable_color = "pink"
- icon = 'icons/obj/power_cond/power_cond_pink.dmi'
/obj/structure/cable/orange
cable_color = "orange"
- icon = 'icons/obj/power_cond/power_cond_orange.dmi'
/obj/structure/cable/cyan
cable_color = "cyan"
- icon = 'icons/obj/power_cond/power_cond_cyan.dmi'
/obj/structure/cable/white
cable_color = "white"
- icon = 'icons/obj/power_cond/power_cond_white.dmi'
// the power cable object
-/obj/structure/cable/Initialize()
+/obj/structure/cable/Initialize(mapload, param_color)
. = ..()
// ensure d1 & d2 reflect the icon_state for entering and exiting cable
var/dash = findtext(icon_state, "-")
-
d1 = text2num( copytext( icon_state, 1, dash ) )
-
d2 = text2num( copytext( icon_state, dash+1 ) )
var/turf/T = get_turf(src) // hide if turf is not intact
-
if(level==1)
hide(T.intact)
GLOB.cable_list += src //add it to the global cable list
@@ -87,6 +89,12 @@ By design, d1 is the smallest direction and d2 is the highest
else
stored = new/obj/item/stack/cable_coil(null,1,cable_color)
+ var/list/cable_colors = GLOB.cable_colors
+ cable_color = param_color || cable_color || pick(cable_colors)
+ if(cable_colors[cable_color])
+ cable_color = cable_colors[cable_color]
+ update_icon()
+
/obj/structure/cable/Destroy() // called when a cable is deleted
if(powernet)
cut_cable_from_powernet() // update the powernets
@@ -115,6 +123,7 @@ By design, d1 is the smallest direction and d2 is the highest
icon_state = "[d1]-[d2]-f"
else
icon_state = "[d1]-[d2]"
+ add_atom_colour(cable_color, FIXED_COLOUR_PRIORITY)
/obj/structure/cable/proc/handlecable(obj/item/W, mob/user, params)
var/turf/T = get_turf(src)
@@ -175,26 +184,6 @@ By design, d1 is the smallest direction and d2 is the highest
if(current_size >= STAGE_FIVE)
deconstruct()
-/obj/structure/cable/proc/cableColor(colorC = "red")
- cable_color = colorC
- switch(colorC)
- if("red")
- icon = 'icons/obj/power_cond/power_cond_red.dmi'
- if("yellow")
- icon = 'icons/obj/power_cond/power_cond_yellow.dmi'
- if("green")
- icon = 'icons/obj/power_cond/power_cond_green.dmi'
- if("blue")
- icon = 'icons/obj/power_cond/power_cond_blue.dmi'
- if("pink")
- icon = 'icons/obj/power_cond/power_cond_pink.dmi'
- if("orange")
- icon = 'icons/obj/power_cond/power_cond_orange.dmi'
- if("cyan")
- icon = 'icons/obj/power_cond/power_cond_cyan.dmi'
- if("white")
- icon = 'icons/obj/power_cond/power_cond_white.dmi'
-
/obj/structure/cable/proc/update_stored(length = 1, colorC = "red")
stored.amount = length
stored.item_color = colorC
@@ -456,8 +445,8 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
name = "cable coil"
gender = NEUTER //That's a cable coil sounds better than that's some cable coils
icon = 'icons/obj/power.dmi'
- icon_state = "coil_red"
- item_state = "coil_red"
+ icon_state = "coil"
+ item_state = "coil"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
max_amount = MAXCOIL
@@ -497,8 +486,12 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
. = ..()
if(new_amount) // MAXCOIL by default
amount = new_amount
- if(param_color)
- item_color = param_color
+
+ var/list/cable_colors = GLOB.cable_colors
+ item_color = param_color || item_color || pick(cable_colors)
+ if(cable_colors[item_color])
+ item_color = cable_colors[item_color]
+
pixel_x = rand(-2,2)
pixel_y = rand(-2,2)
update_icon()
@@ -528,18 +521,9 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
/obj/item/stack/cable_coil/update_icon()
- if(!item_color)
- item_color = pick("red", "yellow", "blue", "green")
- item_state = "coil_[item_color]"
- if(amount == 1)
- icon_state = "coil_[item_color]1"
- name = "cable piece"
- else if(amount == 2)
- icon_state = "coil_[item_color]2"
- name = "cable piece"
- else
- icon_state = "coil_[item_color]"
- name = "cable coil"
+ icon_state = "[initial(item_state)][amount < 3 ? amount : ""]"
+ name = "cable [amount < 3 ? "piece" : "coil"]"
+ add_atom_colour(item_color, FIXED_COLOUR_PRIORITY)
/obj/item/stack/cable_coil/attack_hand(mob/user)
var/obj/item/stack/cable_coil/new_cable = ..()
@@ -562,8 +546,8 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
//////////////////////////////////////////////
/obj/item/stack/cable_coil/proc/get_new_cable(location)
- var/path = "/obj/structure/cable" + (item_color == "red" ? "" : "/" + item_color)
- return new path (location)
+ var/path = /obj/structure/cable
+ return new path(location, item_color)
// called when cable_coil is clicked on a turf
/obj/item/stack/cable_coil/proc/place_turf(turf/T, mob/user, dirnew)
@@ -714,7 +698,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
return
- C.cableColor(item_color)
+ C.update_icon()
C.d1 = nd1
C.d2 = nd2
@@ -750,11 +734,8 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
// Misc.
/////////////////////////////
-/obj/item/stack/cable_coil/cut
- item_state = "coil_red2"
-
/obj/item/stack/cable_coil/cut/Initialize(mapload)
- . =..()
+ . = ..()
amount = rand(1,2)
pixel_x = rand(-2,2)
pixel_y = rand(-2,2)
@@ -762,42 +743,30 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
/obj/item/stack/cable_coil/red
item_color = "red"
- icon_state = "coil_red"
/obj/item/stack/cable_coil/yellow
item_color = "yellow"
- icon_state = "coil_yellow"
/obj/item/stack/cable_coil/blue
item_color = "blue"
- icon_state = "coil_blue"
- item_state = "coil_blue"
/obj/item/stack/cable_coil/green
item_color = "green"
- icon_state = "coil_green"
/obj/item/stack/cable_coil/pink
item_color = "pink"
- icon_state = "coil_pink"
/obj/item/stack/cable_coil/orange
item_color = "orange"
- icon_state = "coil_orange"
/obj/item/stack/cable_coil/cyan
item_color = "cyan"
- icon_state = "coil_cyan"
/obj/item/stack/cable_coil/white
item_color = "white"
- icon_state = "coil_white"
-
-/obj/item/stack/cable_coil/random/Initialize(mapload)
- . = ..()
- item_color = pick("red","orange","yellow","green","cyan","blue","pink","white")
- icon_state = "coil_[item_color]"
+/obj/item/stack/cable_coil/random
+ item_color = null
/obj/item/stack/cable_coil/random/five
amount = 5
diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm
index d927b5c4f1..6031f6edab 100644
--- a/code/modules/power/port_gen.dm
+++ b/code/modules/power/port_gen.dm
@@ -15,6 +15,15 @@
var/power_output = 1
var/consumption = 0
var/base_icon = "portgen0"
+ var/datum/looping_sound/generator/soundloop
+
+/obj/machinery/power/port_gen/Initialize()
+ . = ..()
+ soundloop = new(list(src), active)
+
+/obj/machinery/power/port_gen/Destroy()
+ QDEL_NULL(soundloop)
+ return ..()
/obj/machinery/power/port_gen/proc/HasFuel() //Placeholder for fuel check.
return 1
@@ -36,11 +45,13 @@
add_avail(power_gen * power_output)
UseFuel()
src.updateDialog()
+ soundloop.start()
else
active = 0
handleInactive()
update_icon()
+ soundloop.stop()
/obj/machinery/power/port_gen/attack_hand(mob/user)
if(..())
diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm
index 7f1348d45b..2e92aa92aa 100644
--- a/code/modules/power/singularity/collector.dm
+++ b/code/modules/power/singularity/collector.dm
@@ -60,7 +60,6 @@
else
to_chat(user, "The controls are locked!")
return
-..()
/obj/machinery/power/rad_collector/can_be_unfasten_wrench(mob/user, silent)
if(loaded_tank)
@@ -167,4 +166,4 @@
#undef RAD_COLLECTOR_EFFICIENCY
#undef RAD_COLLECTOR_COEFFICIENT
-#undef RAD_COLLECTOR_STORED_OUT
\ No newline at end of file
+#undef RAD_COLLECTOR_STORED_OUT
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index d9aabd1197..7ce459a712 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -9,7 +9,6 @@
#define OXYGEN_TRANSMIT_MODIFIER 1.5 //Higher == Bigger bonus to power generation.
#define PLASMA_TRANSMIT_MODIFIER 4
-#define FREON_TRANSMIT_PENALTY 0.75 // Scales how much freon reduces total power transmission. 1 equals 1% per 1% of freon in the mix.
#define N2O_HEAT_RESISTANCE 6 //Higher == Gas makes the crystal more resistant against heat damage.
@@ -30,7 +29,7 @@
#define THERMAL_RELEASE_MODIFIER 5 //Higher == less heat released during reaction, not to be confused with the above values
#define PLASMA_RELEASE_MODIFIER 750 //Higher == less plasma released by reaction
#define OXYGEN_RELEASE_MODIFIER 325 //Higher == less oxygen released at high temperature/power
-#define FREON_BREEDING_MODIFIER 100 //Higher == less freon created
+
#define REACTION_POWER_MODIFIER 0.55 //Higher == more overall power
#define MATTER_POWER_CONVERSION 10 //Crystal converts 1/this value of stored matter into energy.
@@ -92,7 +91,6 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
var/power = 0
var/n2comp = 0 // raw composition of each gas in the chamber, ranges from 0 to 1
- var/freoncomp = 0
var/plasmacomp = 0
var/o2comp = 0
@@ -107,7 +105,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
var/powerloss_dynamic_scaling= 0
var/power_transmission_bonus = 0
var/mole_heat_penalty = 0
- var/freon_transmit_modifier = 1
+
var/matter_power = 0
@@ -135,6 +133,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
var/is_main_engine = FALSE
+ var/datum/looping_sound/supermatter/soundloop
+
/obj/machinery/power/supermatter_shard/Initialize()
. = ..()
SSair.atmos_machinery += src
@@ -149,6 +149,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
if(is_main_engine)
GLOB.main_supermatter_engine = src
+ soundloop = new(list(src), TRUE)
+
/obj/machinery/power/supermatter_shard/Destroy()
investigate_log("has been destroyed.", INVESTIGATE_SUPERMATTER)
SSair.atmos_machinery -= src
@@ -157,7 +159,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
QDEL_NULL(countdown)
if(is_main_engine && GLOB.main_supermatter_engine == src)
GLOB.main_supermatter_engine = null
- . = ..()
+ QDEL_NULL(soundloop)
+ return ..()
/obj/machinery/power/supermatter_shard/examine(mob/user)
..()
@@ -251,6 +254,9 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
if(!istype(T)) //We are in a crate or somewhere that isn't turf, if we return to turf resume processing but for now.
return //Yeah just stop.
+ if(power)
+ soundloop.volume = min(50, (round(power, 50)/50)+1) // 5 +1 volume per 20 power. 2500 power is max
+
//Ok, get the air from the turf
var/datum/gas_mixture/env = T.return_air()
@@ -284,7 +290,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
if(damage > damage_archived && prob(10))
playsound(get_turf(src), 'sound/effects/empulse.ogg', 50, 1)
- removed.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/nitrogen, /datum/gas/freon)
+ removed.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/nitrogen)
//calculating gas related values
combined_gas = max(removed.total_moles(), 0)
@@ -294,16 +300,15 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
n2ocomp = max(removed.gases[/datum/gas/nitrous_oxide][MOLES]/combined_gas, 0)
n2comp = max(removed.gases[/datum/gas/nitrogen][MOLES]/combined_gas, 0)
- freoncomp = max(removed.gases[/datum/gas/freon][MOLES]/combined_gas, 0)
- gasmix_power_ratio = min(max(plasmacomp + o2comp + co2comp - n2comp - freoncomp, 0), 1)
+ gasmix_power_ratio = min(max(plasmacomp + o2comp + co2comp - n2comp, 0), 1)
dynamic_heat_modifier = max((plasmacomp * PLASMA_HEAT_PENALTY)+(o2comp * OXYGEN_HEAT_PENALTY)+(co2comp * CO2_HEAT_PENALTY)+(n2comp * NITROGEN_HEAT_MODIFIER), 0.5)
dynamic_heat_resistance = max(n2ocomp * N2O_HEAT_RESISTANCE, 1)
power_transmission_bonus = max((plasmacomp * PLASMA_TRANSMIT_MODIFIER) + (o2comp * OXYGEN_TRANSMIT_MODIFIER), 0)
- freon_transmit_modifier = max(1-(freoncomp * FREON_TRANSMIT_PENALTY), 0)
+
//more moles of gases are harder to heat than fewer, so let's scale heat damage around them
mole_heat_penalty = max(combined_gas / MOLE_HEAT_PENALTY, 0.25)
@@ -332,7 +337,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
power = max( (removed.temperature * temp_factor / T0C) * gasmix_power_ratio + power, 0) //Total laser power plus an overload
if(prob(50))
- radiation_pulse(src, power * (1 + power_transmission_bonus/10 * freon_transmit_modifier))
+ radiation_pulse(src, power * (1 + power_transmission_bonus/10))
var/device_energy = power * REACTION_POWER_MODIFIER
@@ -352,9 +357,6 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
removed.gases[/datum/gas/oxygen][MOLES] += max(((device_energy + removed.temperature * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0)
- if(combined_gas < 50)
- removed.gases[/datum/gas/freon][MOLES] = max((removed.gases[/datum/gas/freon][MOLES] + device_energy) * freoncomp / FREON_BREEDING_MODIFIER, 0)
-
if(produces_gas)
env.merge(removed)
air_update_turf()
diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm
index 7073b98ca1..b7db29084a 100644
--- a/code/modules/projectiles/guns/ballistic.dm
+++ b/code/modules/projectiles/guns/ballistic.dm
@@ -139,7 +139,7 @@
#define BRAINS_BLOWN_THROW_RANGE 3
#define BRAINS_BLOWN_THROW_SPEED 1
/obj/item/gun/ballistic/suicide_act(mob/user)
- var/obj/item/organ/brain/B = user.getorganslot("brain")
+ var/obj/item/organ/brain/B = user.getorganslot(ORGAN_SLOT_BRAIN)
if (B && chambered && chambered.BB && can_trigger_gun(user) && !chambered.BB.nodamage)
user.visible_message("[user] is putting the barrel of [src] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide!")
sleep(25)
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index f3bc7ab9e0..57960fcea7 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -132,16 +132,14 @@
if("monkey")
new_mob = new /mob/living/carbon/monkey(M.loc)
if("robot")
- var/robot = pick("cyborg","syndiborg","drone")
+ var/robot = pick("random_cyborg","syndiborg","drone")
+ var/path
switch(robot)
- if("cyborg")
- new_mob = new /mob/living/silicon/robot(M.loc)
+ if("random_cyborg")
+ path = pick(typesof(/mob/living/silicon/robot/modules) - typesof(/mob/living/silicon/robot/modules/syndicate))
+ new_mob = new path(M.loc)
if("syndiborg")
- var/path
- if(prob(50))
- path = /mob/living/silicon/robot/modules/syndicate
- else
- path = /mob/living/silicon/robot/modules/syndicate/medical
+ path = pick(typesof(/mob/living/silicon/robot/modules/syndicate))
new_mob = new path(M.loc)
if("drone")
new_mob = new /mob/living/simple_animal/drone/polymorphed(M.loc)
@@ -158,9 +156,15 @@
new_mob = new /mob/living/simple_animal/slime/random(M.loc)
if("xeno")
if(prob(50))
- new_mob = new /mob/living/carbon/alien/humanoid/hunter(M.loc)
+ if(!M.ckey) //spawn an AI alien if it isn't a player controlled mob.
+ new_mob = new /mob/living/simple_animal/hostile/alien(M.loc)
+ else
+ new_mob = new /mob/living/carbon/alien/humanoid/hunter(M.loc)
else
- new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc)
+ if(!M.ckey)
+ new_mob = new /mob/living/simple_animal/hostile/alien/sentinel(M.loc)
+ else
+ new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc)
if("animal")
var/path
diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
index a7bdab2d4b..eb1ee87df9 100644
--- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
+++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
@@ -30,6 +30,7 @@
/obj/item/stack/sheet/mineral/silver = list("silver" = 20),
/obj/item/stack/sheet/mineral/gold = list("gold" = 20),
/obj/item/stack/sheet/bluespace_crystal = list("bluespace" = 20),
+ /obj/item/stack/cable_coil = list ("copper" = 5),
/obj/item/ore/bluespace_crystal = list("bluespace" = 20),
/obj/item/grown/nettle/basic = list("sacid" = 0),
/obj/item/grown/nettle/death = list("facid" = 0, "sacid" = 0),
@@ -45,17 +46,39 @@
/obj/item/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0),
/obj/item/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0),
/obj/item/reagent_containers/food/snacks/egg = list("eggyolk" = -5),
+ /obj/item/reagent_containers/food/snacks/deadmouse = list ("blood" = 20, "gibs" = 5), // You monster
//Grinder stuff, but only if dry
/obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0),
/obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0),
/obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0),
/obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0),
+ //Stuff that doesn't quite fit in the other categories
+ /obj/item/electronics = list ("iron" = 10, "silicon" = 10),
+ /obj/item/circuitboard = list ("silicon" = 20, "sacid" = 0.5), // Retrieving acid this way is extremely inefficient
+ /obj/item/match = list ("phosphorus" = 2),
+ /obj/item/device/toner = list ("iodine" = 40, "iron" = 10),
+ /obj/item/photo = list ("iodine" = 4),
+ /obj/item/pen = list ("iodine" = 2, "iron" = 1),
+ /obj/item/reagent_containers/food/drinks/soda_cans = list ("aluminium" = 10),
+ /obj/item/trash/can = list ("aluminium" = 10),
+ /obj/item/device/flashlight/flare = list ("sulfur" = 15),
+ /obj/item/device/flashlight/glowstick = list ("phenol" = 15, "hydrodgen" = 10, "oxygen" = 5),
+ /obj/item/stock_parts/cell = list ("lithium" = 15, "iron" = 5, "silicon" = 5),
+ /obj/item/soap = list ("lye" = 10),
+ /obj/item/device/analyzer = list ("mercury" = 5, "iron" = 5, "silicon" = 5),
+ /obj/item/lighter = list ("iron" = 1, "weldingfuel" = 5, "oil" = 5),
+ /obj/item/light = list ("silicon" = 5, "nitrogen" = 10), //Nitrogen is used as a cheaper alternative to argon in incandescent lighbulbs
+ /obj/item/cigbutt/ = list ("carbon" = 2),
+ /obj/item/trash/coal = list ("carbon" = 20),
+ /obj/item/stack/medical/bruise_pack = list ("styptic_powder" = 5),
+ /obj/item/stack/medical/ointment = list ("silver_sulfadiazine" = 5),
//All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.!
/obj/item/slime_extract = list(),
/obj/item/reagent_containers/pill = list(),
/obj/item/reagent_containers/food = list(),
/obj/item/reagent_containers/honeycomb = list(),
- /obj/item/toy/crayon = list())
+ /obj/item/toy/crayon = list(),
+ /obj/item/clothing/mask/cigarette = list())
var/static/list/juice_items = list(
//Juicer Stuff
diff --git a/code/modules/reagents/chemistry/machinery/smoke_machine.dm b/code/modules/reagents/chemistry/machinery/smoke_machine.dm
index 63f7e48281..2365bb03ed 100644
--- a/code/modules/reagents/chemistry/machinery/smoke_machine.dm
+++ b/code/modules/reagents/chemistry/machinery/smoke_machine.dm
@@ -66,7 +66,7 @@
/obj/machinery/smoke_machine/attackby(obj/item/I, mob/user, params)
add_fingerprint(user)
- if(istype(I, /obj/item/reagent_containers))
+ if(istype(I, /obj/item/reagent_containers) && I.is_open_container())
var/obj/item/reagent_containers/RC = I
var/units = RC.reagents.trans_to(src, RC.amount_per_transfer_from_this)
if(units)
diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index c114f7017b..cc91819611 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -38,7 +38,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
var/mob/living/carbon/human/H = M
if(H.drunkenness < volume * boozepwr * ALCOHOL_THRESHOLD_MODIFIER)
H.drunkenness = max((H.drunkenness + (sqrt(volume) * boozepwr * ALCOHOL_RATE)), 0) //Volume, power, and server alcohol rate effect how quickly one gets drunk
- var/obj/item/organ/liver/L = H.getorganslot("liver")
+ var/obj/item/organ/liver/L = H.getorganslot(ORGAN_SLOT_LIVER)
H.applyLiverDamage((max(sqrt(volume) * boozepwr * L.alcohol_tolerance, 0))/10)
return ..() || .
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index f1b076ca68..d25df998e3 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -550,7 +550,7 @@
if(!M.is_mouth_covered() && !M.is_eyes_covered())
unprotected = TRUE
if(unprotected)
- if(!M.getorganslot("eye_sight")) //can't blind somebody with no eyes
+ if(!M.getorganslot(ORGAN_SLOT_EYES)) //can't blind somebody with no eyes
to_chat(M, "Your eye sockets feel wet.")
else
if(!M.eye_blurry)
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 818ea3d17f..095db17c7f 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -454,7 +454,7 @@
/datum/reagent/medicine/potass_iodide/on_mob_life(mob/living/M)
if(M.radiation > 0)
- M.radiation -= min(M.radiation, 4)
+ M.radiation -= min(M.radiation, 8)
..()
/datum/reagent/medicine/pen_acid
@@ -466,7 +466,7 @@
metabolization_rate = 0.5 * REAGENTS_METABOLISM
/datum/reagent/medicine/pen_acid/on_mob_life(mob/living/M)
- M.radiation -= min(M.radiation-RAD_MOB_SAFE, 0)/100
+ M.radiation -= max(M.radiation-RAD_MOB_SAFE, 0)/50
M.adjustToxLoss(-2*REM, 0)
for(var/datum/reagent/R in M.reagents.reagent_list)
if(R != src)
@@ -671,7 +671,7 @@
taste_description = "dull toxin"
/datum/reagent/medicine/oculine/on_mob_life(mob/living/M)
- var/obj/item/organ/eyes/eyes = M.getorganslot("eyes_sight")
+ var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES)
if (!eyes)
return
if(M.disabilities & BLIND)
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 0a437f120e..c93ca30841 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -24,9 +24,9 @@
else //ingest, patch or inject
M.ForceContractDisease(D)
- if(method == INJECT && iscarbon(M))
+ if(iscarbon(M))
var/mob/living/carbon/C = M
- if(C.get_blood_id() == "blood")
+ if(C.get_blood_id() == "blood" && (method == INJECT || (method == INGEST && C.dna && C.dna.species && (DRINKSBLOOD in C.dna.species.species_traits))))
if(!data || !(data["blood_type"] in get_safe_blood(C.dna.blood_type)))
C.reagents.add_reagent("toxin", reac_volume * 0.5)
else
@@ -1159,6 +1159,34 @@
M.confused = min(M.confused + 2, 5)
..()
+/datum/reagent/stimulum
+ name = "Stimulum"
+ id = "stimulum"
+ description = "An unstable experimental gas that greatly increases the energy of those that inhale it"
+ reagent_state = GAS
+ metabolization_rate = 1.5 * REAGENTS_METABOLISM
+ color = "E1A116"
+ taste_description = "sourness"
+
+/datum/reagent/stimulum/on_mob_life(mob/living/M) // Has a speedup, and the anti-stun effects of nicotine.
+ M.status_flags |= GOTTAGOFAST
+ M.AdjustStun(-20, 0)
+ M.AdjustKnockdown(-20, 0)
+ M.AdjustUnconscious(-20, 0)
+ M.adjustStaminaLoss(-0.5*REM, 0)
+
+/datum/reagent/browngas
+ name = "Brown gas"
+ id = "brown_gas"
+ description = "A strange brown gas that makes you feel faster"
+ reagent_state = GAS
+ metabolization_rate = REAGENTS_METABOLISM
+ color = "90560B"
+ taste_description = "burning"
+
+/datum/reagent/browngas/on_mob_life(mob/living/M) //Has just a speedup
+ M.status_flags |= GOTTAGOFAST
+
/////////////////////////Coloured Crayon Powder////////////////////////////
//For colouring in /proc/mix_color_from_reagents
@@ -1568,7 +1596,7 @@
/datum/reagent/romerol/on_mob_life(mob/living/carbon/human/H)
// Silently add the zombie infection organ to be activated upon death
- if(!H.getorganslot("zombie_infection"))
+ if(!H.getorganslot(ORGAN_SLOT_ZOMBIE))
var/obj/item/organ/zombie_infection/ZI = new()
ZI.Insert(H)
..()
diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
index bec3df0bdd..b41d61be84 100644
--- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
@@ -8,14 +8,8 @@
taste_description = "sweet tasting metal"
/datum/reagent/thermite/reaction_turf(turf/T, reac_volume)
- if(reac_volume >= 1 && iswallturf(T))
- var/turf/closed/wall/Wall = T
- if(istype(Wall, /turf/closed/wall/r_wall))
- Wall.thermite = Wall.thermite+(reac_volume*2.5)
- else
- Wall.thermite = Wall.thermite+(reac_volume*10)
- Wall.overlays = list()
- Wall.add_overlay(mutable_appearance('icons/effects/effects.dmi', "thermite"))
+ if(reac_volume >= 1)
+ T.AddComponent(/datum/component/thermite, reac_volume)
/datum/reagent/thermite/on_mob_life(mob/living/M)
M.adjustFireLoss(1, 0)
diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
index 62e5fd723d..27bf596df0 100644
--- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm
+++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
@@ -243,7 +243,7 @@
if(holder && holder.my_atom)
var/turf/open/T = get_turf(holder.my_atom)
if(istype(T))
- T.atmos_spawn_air("freon=50;TEMP=120")
+ T.atmos_spawn_air("nitrogen=50;TEMP=2.7")
/datum/chemical_reaction/slime/slimefireproof
name = "Slime Fireproof"
diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm
index 2f2ef108ea..d4b8e165ee 100644
--- a/code/modules/reagents/reagent_containers/blood_pack.dm
+++ b/code/modules/reagents/reagent_containers/blood_pack.dm
@@ -65,6 +65,9 @@
/obj/item/reagent_containers/blood/lizard
blood_type = "L"
+/obj/item/reagent_containers/blood/universal
+ blood_type = "U"
+
/obj/item/reagent_containers/blood/empty
name = "blood pack"
icon_state = "empty"
diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm
index 8093a9670a..cca88a0dda 100644
--- a/code/modules/research/xenobiology/xenobiology.dm
+++ b/code/modules/research/xenobiology/xenobiology.dm
@@ -194,7 +194,7 @@
SM.mind.enslave_mind_to_creator(user)
SM.sentience_act()
to_chat(SM, "All at once it makes sense: you know what you are and who you are! Self awareness is yours!")
- to_chat(SM, "You are grateful to be self aware and owe [user] a great debt. Serve [user], and assist [user.p_them()] in completing [user.p_their()] goals at any cost.")
+ to_chat(SM, "You are grateful to be self aware and owe [user.real_name] a great debt. Serve [user.real_name], and assist [user.p_them()] in completing [user.p_their()] goals at any cost.")
to_chat(user, "[SM] accepts [src] and suddenly becomes attentive and aware. It worked!")
qdel(src)
else
diff --git a/code/modules/server_tools/nudge.py b/code/modules/server_tools/nudge.py
deleted file mode 100644
index 3d94ccdad7..0000000000
--- a/code/modules/server_tools/nudge.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env python3
-import sys
-import pickle
-import socket
-
-
-def pack():
- data = sys.argv[1]
-
- nudge(str.encode(data))
-
-
-def nudge(data):
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- with open('config/server_to_tool_bridge_port.txt', 'r') as myfile:
- portstr=myfile.read().replace('\n', '').strip()
- s.connect(("localhost", int(portstr)))
- s.send(data)
- s.close()
-
-if __name__ == "__main__" and len(sys.argv) > 1:
- pack()
diff --git a/code/modules/server_tools/server_tools.dm b/code/modules/server_tools/server_tools.dm
deleted file mode 100644
index 9cacb4542f..0000000000
--- a/code/modules/server_tools/server_tools.dm
+++ /dev/null
@@ -1,93 +0,0 @@
-GLOBAL_VAR_INIT(reboot_mode, REBOOT_MODE_NORMAL) //if the world should request the service to kill it at reboot
-GLOBAL_PROTECT(reboot_mode)
-
-/world/proc/RunningService()
- return params[SERVICE_WORLD_PARAM]
-
-/proc/ServiceVersion()
- if(world.RunningService())
- return world.params[SERVICE_VERSION_PARAM]
-
-/world/proc/ExportService(command)
- return RunningService() && shell("python code/modules/server_tools/nudge.py \"[command]\"") == 0
-
-/world/proc/IRCBroadcast(msg)
- ExportService("[SERVICE_REQUEST_IRC_BROADCAST] [msg]")
-
-/world/proc/ServiceEndProcess()
- log_world("Sending shutdown request!");
- sleep(1) //flush the buffers
- ExportService(SERVICE_REQUEST_KILL_PROCESS)
-
-//called at the exact moment the world is supposed to reboot
-/world/proc/ServiceReboot()
- switch(GLOB.reboot_mode)
- if(REBOOT_MODE_HARD)
- to_chat(src, "Hard reboot triggered, you will automatically reconnect...")
- ServiceEndProcess()
- if(REBOOT_MODE_SHUTDOWN)
- to_chat(src, "The server is shutting down...")
- ServiceEndProcess()
- else
- ExportService(SERVICE_REQUEST_WORLD_REBOOT) //just let em know
-
-/world/proc/ServiceCommand(list/params)
- var/sCK = RunningService()
- var/their_sCK = params[SERVICE_CMD_PARAM_KEY]
-
- if(!their_sCK || their_sCK != sCK)
- return "Invalid comms key!";
-
- var/command = params[SERVICE_CMD_PARAM_COMMAND]
- if(!command)
- return "No command!"
-
- var/static/last_irc_status = 0
- switch(command)
- if(SERVICE_CMD_HARD_REBOOT)
- if(GLOB.reboot_mode != REBOOT_MODE_HARD)
- GLOB.reboot_mode = REBOOT_MODE_HARD
- log_world("Hard reboot requested by service")
- message_admins("The world will hard reboot at the end of the game. Requested by service.")
- SSblackbox.set_val("service_hard_restart", TRUE)
- if(SERVICE_CMD_GRACEFUL_SHUTDOWN)
- if(GLOB.reboot_mode != REBOOT_MODE_SHUTDOWN)
- GLOB.reboot_mode = REBOOT_MODE_SHUTDOWN
- log_world("Shutdown requested by service")
- message_admins("The world will shutdown at the end of the game. Requested by service.")
- SSblackbox.set_val("service_shutdown", TRUE)
- if(SERVICE_CMD_WORLD_ANNOUNCE)
- var/msg = params["message"]
- if(!istext(msg) || !msg)
- return "No message set!"
- to_chat(src, "[html_encode(msg)]")
- return "SUCCESS"
- if(SERVICE_CMD_IRC_STATUS)
- var/rtod = REALTIMEOFDAY
- if(rtod - last_irc_status < IRC_STATUS_THROTTLE)
- return
- last_irc_status = rtod
- var/list/adm = get_admin_counts()
- var/list/allmins = adm["total"]
- var/status = "Admins: [allmins.len] (Active: [english_list(adm["present"])] AFK: [english_list(adm["afk"])] Stealth: [english_list(adm["stealth"])] Skipped: [english_list(adm["noflags"])]). "
- status += "Players: [GLOB.clients.len] (Active: [get_active_player_count(0,1,0)]). Mode: [SSticker.mode ? SSticker.mode.name : "Not started"]."
- return status
- if(SERVICE_CMD_IRC_CHECK)
- var/rtod = REALTIMEOFDAY
- if(rtod - last_irc_status < IRC_STATUS_THROTTLE)
- return
- last_irc_status = rtod
- var/config_server = CONFIG_GET(string/server)
- return "[GLOB.round_id ? "Round #[GLOB.round_id]: " : ""][GLOB.clients.len] players on [SSmapping.config.map_name], Mode: [GLOB.master_mode]; Round [SSticker.HasRoundStarted() ? (SSticker.IsRoundInProgress() ? "Active" : "Finishing") : "Starting"] -- [config_server ? config_server : "[world.internet_address]:[world.port]"]"
- if(SERVICE_CMD_ADMIN_MSG)
- return IrcPm(params[SERVICE_CMD_PARAM_TARGET], params[SERVICE_CMD_PARAM_MESSAGE], params[SERVICE_CMD_PARAM_SENDER])
-
- if(SERVICE_CMD_NAME_CHECK)
- log_admin("IRC Name Check: [params[SERVICE_CMD_PARAM_SENDER]] on [params[SERVICE_CMD_PARAM_TARGET]]")
- message_admins("IRC name checking on [params[SERVICE_CMD_PARAM_TARGET]] from [params[SERVICE_CMD_PARAM_SENDER]]")
- return keywords_lookup(params[SERVICE_CMD_PARAM_TARGET], 1)
- if(SERVICE_CMD_ADMIN_WHO)
- return ircadminwho()
- else
- return "Unknown command: [command]"
-
diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm
index 4e2903ecf1..6af111506d 100644
--- a/code/modules/shuttle/navigation_computer.dm
+++ b/code/modules/shuttle/navigation_computer.dm
@@ -8,8 +8,9 @@
var/shuttlePortId = ""
var/shuttlePortName = ""
var/list/jumpto_ports = list() //hashset of ports to jump to and ignore for collision purposes
- var/list/blacklisted_turfs
- var/obj/docking_port/stationary/my_port
+ var/list/blacklisted_turfs //turfs we cannot go on, by default, any turf covered by a docking port that we did not place and cannot jump to
+ var/obj/docking_port/stationary/my_port //the custom docking port placed by this console
+ var/obj/docking_port/mobile/shuttle_port //the mobile docking port of the connected shuttle
var/view_range = 7
var/x_offset = 0
var/y_offset = 0
@@ -31,21 +32,19 @@
actions += place_action
/obj/machinery/computer/camera_advanced/shuttle_docker/CreateEye()
- var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
- if(QDELETED(M))
+ shuttle_port = SSshuttle.getShuttle(shuttleId)
+ if(QDELETED(shuttle_port))
+ shuttle_port = null
return
+
eyeobj = new /mob/camera/aiEye/remote/shuttle_docker()
var/mob/camera/aiEye/remote/shuttle_docker/the_eye = eyeobj
the_eye.origin = src
- the_eye.dir = M.dir
-
- var/turf/origin = locate(M.x + x_offset, M.y + y_offset, M.z)
-
- for(var/i in M.shuttle_areas)
- var/area/place = i
- if(QDELETED(place))
- continue
- for(var/turf/T in place)
+ the_eye.dir = shuttle_port.dir
+ var/turf/origin = locate(shuttle_port.x + x_offset, shuttle_port.y + y_offset, shuttle_port.z)
+ for(var/V in shuttle_port.shuttle_areas)
+ var/area/A = V
+ for(var/turf/T in A)
if(T.z != origin.z)
continue
var/image/I = image('icons/effects/alphacolors.dmi', origin, "red")
@@ -127,7 +126,7 @@
checkLandingSpot()
/obj/machinery/computer/camera_advanced/shuttle_docker/proc/checkLandingTurf(turf/T)
- return T && (!blacklisted_turfs || !blacklisted_turfs[T]) && (!space_turfs_only || isspaceturf(T)) && (T.x > 1 && T.y > 1 && T.x < world.maxx && T.y < world.maxy)
+ return T && (shuttle_port.shuttle_areas[T.loc] || (!blacklisted_turfs || !blacklisted_turfs[T]) && (!space_turfs_only || isspaceturf(T)) ) && (T.x > 1 && T.y > 1 && T.x < world.maxx && T.y < world.maxy)
/obj/machinery/computer/camera_advanced/shuttle_docker/proc/generateBlacklistedTurfs()
blacklisted_turfs = list()
diff --git a/code/modules/spells/spell_types/shapeshift.dm b/code/modules/spells/spell_types/shapeshift.dm
index c32c45c86a..853aab8b9b 100644
--- a/code/modules/spells/spell_types/shapeshift.dm
+++ b/code/modules/spells/spell_types/shapeshift.dm
@@ -22,6 +22,11 @@
/mob/living/simple_animal/hostile/construct/armored)
/obj/effect/proc_holder/spell/targeted/shapeshift/cast(list/targets,mob/user = usr)
+ if(src in user.mob_spell_list)
+ user.mob_spell_list.Remove(src)
+ user.mind.AddSpell(src)
+ if(user.buckled)
+ user.buckled.unbuckle_mob(src,force=TRUE)
for(var/mob/living/M in targets)
if(!shapeshift_type)
var/list/animal_list = list()
diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm
index cfa95f2d1a..a90b3598ce 100644
--- a/code/modules/station_goals/dna_vault.dm
+++ b/code/modules/station_goals/dna_vault.dm
@@ -253,7 +253,7 @@
if(VAULT_TOXIN)
to_chat(H, "You feel resistant to airborne toxins.")
if(locate(/obj/item/organ/lungs) in H.internal_organs)
- var/obj/item/organ/lungs/L = H.internal_organs_slot["lungs"]
+ var/obj/item/organ/lungs/L = H.internal_organs_slot[ORGAN_SLOT_LUNGS]
L.tox_breath_dam_min = 0
L.tox_breath_dam_max = 0
S.species_traits |= VIRUSIMMUNE
diff --git a/code/modules/surgery/amputation.dm b/code/modules/surgery/amputation.dm
index 7684484a42..f6a2c057d0 100644
--- a/code/modules/surgery/amputation.dm
+++ b/code/modules/surgery/amputation.dm
@@ -4,7 +4,7 @@
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/sever_limb)
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list("r_arm", "l_arm", "l_leg", "r_leg", "head")
- requires_organic_bodypart = 0
+ requires_bodypart_type = 0
/datum/surgery_step/sever_limb
@@ -22,4 +22,4 @@
var/obj/item/bodypart/target_limb = surgery.operated_bodypart
target_limb.drop_limb()
- return 1
\ No newline at end of file
+ return 1
diff --git a/code/modules/surgery/eye_surgery.dm b/code/modules/surgery/eye_surgery.dm
index 2aeadffc65..9099489420 100644
--- a/code/modules/surgery/eye_surgery.dm
+++ b/code/modules/surgery/eye_surgery.dm
@@ -1,38 +1,38 @@
-/datum/surgery/eye_surgery
- name = "eye surgery"
- steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/fix_eyes, /datum/surgery_step/close)
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
- possible_locs = list("eyes")
- requires_organic_bodypart = 0
-
-//fix eyes
-/datum/surgery_step/fix_eyes
- name = "fix eyes"
- implements = list(/obj/item/hemostat = 100, /obj/item/screwdriver = 45, /obj/item/pen = 25)
- time = 64
-
-/datum/surgery/eye_surgery/can_start(mob/user, mob/living/carbon/target)
- var/obj/item/organ/eyes/E = target.getorganslot("eye_sight")
- if(!E)
- to_chat(user, "It's hard to do surgery on someones eyes when they don't have any.")
- return FALSE
-
-/datum/surgery_step/fix_eyes/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- user.visible_message("[user] begins to fix [target]'s eyes.", "You begin to fix [target]'s eyes...")
-
-/datum/surgery_step/fix_eyes/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- user.visible_message("[user] successfully fixes [target]'s eyes!", "You succeed in fixing [target]'s eyes.")
- target.cure_blind()
- target.set_blindness(0)
- target.cure_nearsighted()
- target.blur_eyes(35) //this will fix itself slowly.
- target.set_eye_damage(0)
- return TRUE
-
-/datum/surgery_step/fix_eyes/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- if(target.getorgan(/obj/item/organ/brain))
- user.visible_message("[user] accidentally stabs [target] right in the brain!", "You accidentally stab [target] right in the brain!")
- target.adjustBrainLoss(100)
- else
- user.visible_message("[user] accidentally stabs [target] right in the brain! Or would have, if [target] had a brain.", "You accidentally stab [target] right in the brain! Or would have, if [target] had a brain.")
+/datum/surgery/eye_surgery
+ name = "eye surgery"
+ steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/fix_eyes, /datum/surgery_step/close)
+ species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ possible_locs = list("eyes")
+ requires_bodypart_type = 0
+
+//fix eyes
+/datum/surgery_step/fix_eyes
+ name = "fix eyes"
+ implements = list(/obj/item/hemostat = 100, /obj/item/screwdriver = 45, /obj/item/pen = 25)
+ time = 64
+
+/datum/surgery/eye_surgery/can_start(mob/user, mob/living/carbon/target)
+ var/obj/item/organ/eyes/E = target.getorganslot(ORGAN_SLOT_EYES)
+ if(!E)
+ to_chat(user, "It's hard to do surgery on someones eyes when they don't have any.")
+ return FALSE
+
+/datum/surgery_step/fix_eyes/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] begins to fix [target]'s eyes.", "You begin to fix [target]'s eyes...")
+
+/datum/surgery_step/fix_eyes/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] successfully fixes [target]'s eyes!", "You succeed in fixing [target]'s eyes.")
+ target.cure_blind()
+ target.set_blindness(0)
+ target.cure_nearsighted()
+ target.blur_eyes(35) //this will fix itself slowly.
+ target.set_eye_damage(0)
+ return TRUE
+
+/datum/surgery_step/fix_eyes/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ if(target.getorgan(/obj/item/organ/brain))
+ user.visible_message("[user] accidentally stabs [target] right in the brain!", "You accidentally stab [target] right in the brain!")
+ target.adjustBrainLoss(100)
+ else
+ user.visible_message("[user] accidentally stabs [target] right in the brain! Or would have, if [target] had a brain.", "You accidentally stab [target] right in the brain! Or would have, if [target] had a brain.")
return FALSE
\ No newline at end of file
diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm
index 97426305b5..a4e9b16989 100644
--- a/code/modules/surgery/helpers.dm
+++ b/code/modules/surgery/helpers.dm
@@ -29,7 +29,7 @@
if(affecting)
if(!S.requires_bodypart)
continue
- if(S.requires_organic_bodypart && affecting.status == BODYPART_ROBOTIC)
+ if(S.requires_bodypart_type && affecting.status == BODYPART_ROBOTIC)
continue
if(S.requires_real_bodypart && affecting.is_pseudopart)
continue
@@ -56,7 +56,7 @@
if(affecting)
if(!S.requires_bodypart)
return
- if(S.requires_organic_bodypart && affecting.status == BODYPART_ROBOTIC)
+ if(S.requires_bodypart_type && affecting.status == BODYPART_ROBOTIC)
return
else if(C && S.requires_bodypart)
return
@@ -78,13 +78,23 @@
user.visible_message("[user] removes the drapes from [M]'s [parse_zone(selected_zone)].", \
"You remove the drapes from [M]'s [parse_zone(selected_zone)].")
qdel(current_surgery)
- else if(istype(user.get_inactive_held_item(), /obj/item/cautery) && current_surgery.can_cancel)
- M.surgeries -= current_surgery
- user.visible_message("[user] mends the incision and removes the drapes from [M]'s [parse_zone(selected_zone)].", \
- "You mend the incision and remove the drapes from [M]'s [parse_zone(selected_zone)].")
- qdel(current_surgery)
else if(current_surgery.can_cancel)
- to_chat(user, "You need to hold a cautery in inactive hand to stop [M]'s surgery!")
+ if(current_surgery.requires_bodypart_type == BODYPART_ORGANIC)
+ if(istype(user.get_inactive_held_item(), /obj/item/cautery))
+ M.surgeries -= current_surgery
+ user.visible_message("[user] mends the incision and removes the drapes from [M]'s [parse_zone(selected_zone)].", \
+ "You mend the incision and remove the drapes from [M]'s [parse_zone(selected_zone)].")
+ qdel(current_surgery)
+ else
+ to_chat(user, "You need to hold a cautery in inactive hand to stop [M]'s surgery!")
+ else if(current_surgery.requires_bodypart_type == BODYPART_ROBOTIC)
+ if(istype(user.get_inactive_held_item(), /obj/item/screwdriver))
+ M.surgeries -= current_surgery
+ user.visible_message("[user] screw the shell and removes the drapes from [M]'s [parse_zone(selected_zone)].", \
+ "You screw the shell and remove the drapes from [M]'s [parse_zone(selected_zone)].")
+ qdel(current_surgery)
+ else
+ to_chat(user, "You need to hold a screwdriver in inactive hand to stop [M]'s surgery!")
return 1
@@ -161,4 +171,3 @@
return 0
return 1
-
diff --git a/code/modules/surgery/implant_removal.dm b/code/modules/surgery/implant_removal.dm
index c459748a6c..4a1a8f98eb 100644
--- a/code/modules/surgery/implant_removal.dm
+++ b/code/modules/surgery/implant_removal.dm
@@ -3,7 +3,6 @@
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/extract_implant, /datum/surgery_step/close)
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list("chest")
- requires_organic_bodypart = 0
//extract implant
@@ -43,4 +42,15 @@
else
to_chat(user, "You can't find anything in [target]'s [target_zone]!")
- return 1
\ No newline at end of file
+ return 1
+
+/datum/surgery/implant_removal/mechanic
+ name = "implant removal"
+ requires_bodypart_type = BODYPART_ROBOTIC
+ steps = list(
+ /datum/surgery_step/mechanic_open,
+ /datum/surgery_step/open_hatch,
+ /datum/surgery_step/mechanic_unwrench,
+ /datum/surgery_step/extract_implant,
+ /datum/surgery_step/mechanic_wrench,
+ /datum/surgery_step/mechanic_close)
diff --git a/code/modules/surgery/mechanic_steps.dm b/code/modules/surgery/mechanic_steps.dm
new file mode 100644
index 0000000000..657564f112
--- /dev/null
+++ b/code/modules/surgery/mechanic_steps.dm
@@ -0,0 +1,85 @@
+//open shell
+/datum/surgery_step/mechanic_open
+ name = "unscrew shell"
+ implements = list(
+ /obj/item/screwdriver = 100,
+ /obj/item/scalpel = 75, // med borgs could try to unskrew shell with scalpel
+ /obj/item/kitchen/knife = 50,
+ /obj/item = 10) // 10% success with any sharp item.
+ time = 24
+
+/datum/surgery_step/mechanic_open/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] begins to unscrew the shell of [target]'s [parse_zone(target_zone)].",
+ "You begin to unscrew the shell of [target]'s [parse_zone(target_zone)]...")
+
+/datum/surgery_step/mechanic_incise/tool_check(mob/user, obj/item/tool)
+ if(implement_type == /obj/item && !tool.is_sharp())
+ return FALSE
+
+ return TRUE
+
+//close shell
+/datum/surgery_step/mechanic_close
+ name = "screw shell"
+ implements = list(
+ /obj/item/screwdriver = 100,
+ /obj/item/scalpel = 75,
+ /obj/item/kitchen/knife = 50,
+ /obj/item = 10) // 10% success with any sharp item.
+ time = 24
+
+/datum/surgery_step/mechanic_close/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] begins to screw the shell of [target]'s [parse_zone(target_zone)].",
+ "You begin to screw the shell of [target]'s [parse_zone(target_zone)]...")
+
+/datum/surgery_step/mechanic_close/tool_check(mob/user, obj/item/tool)
+ if(implement_type == /obj/item && !tool.is_sharp())
+ return FALSE
+
+ return TRUE
+
+//prepare electronics
+/datum/surgery_step/prepare_electronics
+ name = "prepare electronics"
+ implements = list(
+ /obj/item/device/multitool = 100,
+ /obj/item/hemostat = 10) // try to reboot internal controllers via short circuit with some conductor
+ time = 24
+
+/datum/surgery_step/prepare_electronics/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] begins to prepare electronics in [target]'s [parse_zone(target_zone)].",
+ "You begin to prepare electronics in [target]'s [parse_zone(target_zone)]...")
+
+//unwrench
+/datum/surgery_step/mechanic_unwrench
+ name = "unwrench bolts"
+ implements = list(
+ /obj/item/wrench = 100,
+ /obj/item/retractor = 10)
+ time = 24
+
+/datum/surgery_step/mechanic_unwrench/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] begins to unwrench some bolts in [target]'s [parse_zone(target_zone)].",
+ "You begin to unwrench some bolts in [target]'s [parse_zone(target_zone)]...")
+
+//wrench
+/datum/surgery_step/mechanic_wrench
+ name = "wrench bolts"
+ implements = list(
+ /obj/item/wrench = 100,
+ /obj/item/retractor = 10)
+ time = 24
+
+/datum/surgery_step/mechanic_wrench/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] begins to wrench some bolts in [target]'s [parse_zone(target_zone)].",
+ "You begin to wrench some bolts in [target]'s [parse_zone(target_zone)]...")
+
+//open hatch
+/datum/surgery_step/open_hatch
+ name = "open the hatch"
+ accept_hand = 1
+ time = 10
+
+/datum/surgery_step/open_hatch/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] begins to open the hatch holders in [target]'s [parse_zone(target_zone)].",
+ "You begin to open the hatch holders in [target]'s [parse_zone(target_zone)]...")
diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm
index a061628203..10e57babcd 100644
--- a/code/modules/surgery/organ_manipulation.dm
+++ b/code/modules/surgery/organ_manipulation.dm
@@ -1,38 +1,79 @@
/datum/surgery/organ_manipulation
name = "organ manipulation"
- steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders,
- /datum/surgery_step/incise, /datum/surgery_step/manipulate_organs)
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list("chest", "head")
- requires_organic_bodypart = FALSE
- requires_real_bodypart = TRUE
+ requires_real_bodypart = 1
+ steps = list(
+ /datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/saw,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/manipulate_organs,
+ //there should be bone fixing
+ /datum/surgery_step/close
+ )
/datum/surgery/organ_manipulation/soft
possible_locs = list("groin", "eyes", "mouth", "l_arm", "r_arm")
- steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/clamp_bleeders,
- /datum/surgery_step/incise, /datum/surgery_step/manipulate_organs)
+ steps = list(
+ /datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/manipulate_organs,
+ /datum/surgery_step/close
+ )
/datum/surgery/organ_manipulation/alien
name = "alien organ manipulation"
possible_locs = list("chest", "head", "groin", "eyes", "mouth", "l_arm", "r_arm")
species = list(/mob/living/carbon/alien/humanoid)
- steps = list(/datum/surgery_step/saw, /datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/manipulate_organs)
-
+ steps = list(
+ /datum/surgery_step/saw,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/saw,
+ /datum/surgery_step/manipulate_organs,
+ /datum/surgery_step/close
+ )
+/datum/surgery/organ_manipulation/mechanic
+ name = "prosthesis organ manipulation"
+ possible_locs = list("chest", "head")
+ requires_bodypart_type = BODYPART_ROBOTIC
+ steps = list(
+ /datum/surgery_step/mechanic_open,
+ /datum/surgery_step/open_hatch,
+ /datum/surgery_step/mechanic_unwrench,
+ /datum/surgery_step/prepare_electronics,
+ /datum/surgery_step/manipulate_organs,
+ /datum/surgery_step/mechanic_wrench,
+ /datum/surgery_step/mechanic_close
+ )
+/datum/surgery/organ_manipulation/mechanic/soft
+ possible_locs = list("groin", "eyes", "mouth", "l_arm", "r_arm")
+ steps = list(
+ /datum/surgery_step/mechanic_open,
+ /datum/surgery_step/open_hatch,
+ /datum/surgery_step/prepare_electronics,
+ /datum/surgery_step/manipulate_organs,
+ /datum/surgery_step/mechanic_close
+ )
/datum/surgery_step/manipulate_organs
time = 64
name = "manipulate organs"
+ repeatable = 1
implements = list(/obj/item/organ = 100, /obj/item/reagent_containers/food/snacks/organ = 0, /obj/item/organ_storage = 100)
var/implements_extract = list(/obj/item/hemostat = 100, /obj/item/crowbar = 55)
- var/implements_mend = list(/obj/item/cautery = 100, /obj/item/weldingtool = 70, /obj/item/lighter = 45, /obj/item/match = 20)
var/current_type
var/obj/item/organ/I = null
/datum/surgery_step/manipulate_organs/New()
..()
- implements = implements + implements_extract + implements_mend
+ implements = implements + implements_extract
/datum/surgery_step/manipulate_organs/tool_check(mob/user, obj/item/tool)
if(istype(tool, /obj/item/weldingtool))
@@ -103,23 +144,12 @@
else
return -1
- else if(implement_type in implements_mend)
- current_type = "mend"
- user.visible_message("[user] begins to mend the incision in [target]'s [parse_zone(target_zone)].",
- "You begin to mend the incision in [target]'s [parse_zone(target_zone)]...")
-
else if(istype(tool, /obj/item/reagent_containers/food/snacks/organ))
to_chat(user, "[tool] was bitten by someone! It's too damaged to use!")
return -1
/datum/surgery_step/manipulate_organs/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- if(current_type == "mend")
- user.visible_message("[user] mends the incision in [target]'s [parse_zone(target_zone)].",
- "You mend the incision in [target]'s [parse_zone(target_zone)].")
- if(locate(/datum/surgery_step/saw) in surgery.steps)
- target.heal_bodypart_damage(45,0)
- return 1
- else if(current_type == "insert")
+ if(current_type == "insert")
if(istype(tool, /obj/item/organ_storage))
I = tool.contents[1]
tool.icon_state = "evidenceobj"
diff --git a/code/modules/surgery/generic_steps.dm b/code/modules/surgery/organic_steps.dm
similarity index 99%
rename from code/modules/surgery/generic_steps.dm
rename to code/modules/surgery/organic_steps.dm
index 5e3c3f33ba..8a4c795c63 100644
--- a/code/modules/surgery/generic_steps.dm
+++ b/code/modules/surgery/organic_steps.dm
@@ -2,7 +2,7 @@
//make incision
/datum/surgery_step/incise
name = "make incision"
- implements = list(/obj/item/scalpel = 100, /obj/item/melee/transforming/energy/sword = 75, /obj/item/kitchen/knife = 65,
+ implements = list(/obj/item/scalpel = 100, /obj/item/melee/transforming/energy/sword = 75, /obj/item/kitchen/knife = 65,
/obj/item/shard = 45, /obj/item = 30) // 30% success with any sharp item.
time = 16
@@ -87,7 +87,7 @@
//saw bone
/datum/surgery_step/saw
name = "saw bone"
- implements = list(/obj/item/circular_saw = 100, /obj/item/melee/transforming/energy/sword/cyborg/saw = 100,
+ implements = list(/obj/item/circular_saw = 100, /obj/item/melee/transforming/energy/sword/cyborg/saw = 100,
/obj/item/melee/arm_blade = 75, /obj/item/mounted_chainsaw = 65, /obj/item/twohanded/required/chainsaw = 50,
/obj/item/twohanded/fireaxe = 50, /obj/item/hatchet = 35, /obj/item/kitchen/knife/butcher = 25)
time = 54
diff --git a/code/modules/surgery/organs/appendix.dm b/code/modules/surgery/organs/appendix.dm
index ad51c48d85..35a2d851e3 100644
--- a/code/modules/surgery/organs/appendix.dm
+++ b/code/modules/surgery/organs/appendix.dm
@@ -2,7 +2,7 @@
name = "appendix"
icon_state = "appendix"
zone = "groin"
- slot = "appendix"
+ slot = ORGAN_SLOT_APPENDIX
var/inflamed = 0
/obj/item/organ/appendix/update_icon()
diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm
index b51fc98f15..aa1ea10cd0 100644
--- a/code/modules/surgery/organs/augments_arms.dm
+++ b/code/modules/surgery/organs/augments_arms.dm
@@ -2,7 +2,6 @@
name = "arm-mounted implant"
desc = "You shouldn't see this! Adminhelp and report this as an issue on github!"
zone = "r_arm"
- slot = "r_arm_device"
icon_state = "implant-toolkit"
w_class = WEIGHT_CLASS_NORMAL
actions_types = list(/datum/action/item_action/organ_action/toggle)
@@ -20,9 +19,18 @@
holder = new holder(src)
update_icon()
- slot = zone + "_device"
+ SetSlotFromZone()
items_list = contents.Copy()
+/obj/item/organ/cyberimp/arm/proc/SetSlotFromZone()
+ switch(zone)
+ if("l_arm")
+ slot = ORGAN_SLOT_LEFT_ARM_AUG
+ if("r_arm")
+ slot = ORGAN_SLOT_RIGHT_ARM_AUG
+ else
+ CRASH("Invalid zone for [type]")
+
/obj/item/organ/cyberimp/arm/update_icon()
if(zone == "r_arm")
transform = null
@@ -40,7 +48,7 @@
zone = "l_arm"
else
zone = "r_arm"
- slot = zone + "_device"
+ SetSlotFromZone()
to_chat(user, "You modify [src] to be installed on the [zone == "r_arm" ? "right" : "left"] arm.")
update_icon()
else if(istype(W, /obj/item/card/emag))
diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm
index 70a8f05b8a..1e93c4df4a 100644
--- a/code/modules/surgery/organs/augments_chest.dm
+++ b/code/modules/surgery/organs/augments_chest.dm
@@ -13,7 +13,7 @@
var/hunger_threshold = NUTRITION_LEVEL_STARVING
var/synthesizing = 0
var/poison_amount = 5
- slot = "stomach"
+ slot = ORGAN_SLOT_STOMACH
origin_tech = "materials=2;powerstorage=2;biotech=2"
/obj/item/organ/cyberimp/chest/nutriment/on_life()
@@ -51,7 +51,7 @@
icon_state = "chest_implant"
implant_color = "#AD0000"
origin_tech = "materials=5;programming=4;biotech=4"
- slot = "heartdrive"
+ slot = ORGAN_SLOT_HEART_AID
var/revive_cost = 0
var/reviving = 0
var/cooldown = 0
@@ -119,8 +119,8 @@
/obj/item/organ/cyberimp/chest/thrusters
name = "implantable thrusters set"
desc = "An implantable set of thruster ports. They use the gas from environment or subject's internals for propulsion in zero-gravity areas. \
- Unlike regular jetpacks, this device has no stabilization system."
- slot = "thrusters"
+ Unlike regular jetpack, this device has no stabilization system."
+ slot = ORGAN_SLOT_THRUSTERS
icon_state = "imp_jetpack"
origin_tech = "materials=4;magnets=4;biotech=4;engineering=5"
implant_overlay = null
diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm
index 62b427f883..f928db5dd6 100644
--- a/code/modules/surgery/organs/augments_eyes.dm
+++ b/code/modules/surgery/organs/augments_eyes.dm
@@ -3,7 +3,7 @@
desc = "artificial photoreceptors with specialized functionality"
icon_state = "eye_implant"
implant_overlay = "eye_implant_overlay"
- slot = "eye_sight"
+ slot = ORGAN_SLOT_EYES
zone = "eyes"
w_class = WEIGHT_CLASS_TINY
@@ -11,7 +11,7 @@
/obj/item/organ/cyberimp/eyes/hud
name = "HUD implant"
desc = "These cybernetic eyes will display a HUD over everything you see. Maybe."
- slot = "eye_hud"
+ slot = ORGAN_SLOT_HUD
var/HUD_type = 0
/obj/item/organ/cyberimp/eyes/hud/Insert(var/mob/living/carbon/M, var/special = 0, drop_if_replaced = FALSE)
diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm
index 9b3c23b3a8..a6c1517faa 100644
--- a/code/modules/surgery/organs/augments_internal.dm
+++ b/code/modules/surgery/organs/augments_internal.dm
@@ -44,7 +44,7 @@
var/active = 0
var/list/stored_items = list()
implant_color = "#DE7E00"
- slot = "brain_antidrop"
+ slot = ORGAN_SLOT_BRAIN_ANTIDROP
origin_tech = "materials=4;programming=5;biotech=4"
actions_types = list(/datum/action/item_action/organ_action/toggle)
@@ -101,7 +101,7 @@
name = "CNS Rebooter implant"
desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned."
implant_color = "#FFFF00"
- slot = "brain_antistun"
+ slot = ORGAN_SLOT_BRAIN_ANTISTUN
origin_tech = "materials=5;programming=4;biotech=5"
/obj/item/organ/cyberimp/brain/anti_stun/on_life()
@@ -133,7 +133,7 @@
name = "breathing tube implant"
desc = "This simple implant adds an internals connector to your back, allowing you to use internals without a mask and protecting you from being choked."
icon_state = "implant_mask"
- slot = "breathing_tube"
+ slot = ORGAN_SLOT_BREATHING_TUBE
w_class = WEIGHT_CLASS_TINY
origin_tech = "materials=2;biotech=3"
diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm
index f8a310c8f7..e3aaec0266 100644
--- a/code/modules/surgery/organs/ears.dm
+++ b/code/modules/surgery/organs/ears.dm
@@ -3,7 +3,7 @@
icon_state = "ears"
desc = "There are three parts to the ear. Inner, middle and outer. Only one of these parts should be normally visible."
zone = "head"
- slot = "ears"
+ slot = ORGAN_SLOT_EARS
gender = PLURAL
// `deaf` measures "ticks" of deafness. While > 0, the person is unable
diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm
index ddb6eb453f..75d4aa0bcc 100644
--- a/code/modules/surgery/organs/eyes.dm
+++ b/code/modules/surgery/organs/eyes.dm
@@ -3,7 +3,7 @@
icon_state = "eyeballs"
desc = "I see you!"
zone = "eyes"
- slot = "eye_sight"
+ slot = ORGAN_SLOT_EYES
gender = PLURAL
var/sight_flags = 0
diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm
index 9308154c48..30825f46bb 100644
--- a/code/modules/surgery/organs/heart.dm
+++ b/code/modules/surgery/organs/heart.dm
@@ -3,7 +3,7 @@
desc = "I feel bad for the heartless bastard who lost this."
icon_state = "heart-on"
zone = "chest"
- slot = "heart"
+ slot = ORGAN_SLOT_HEART
origin_tech = "biotech=5"
// Heart attack code is in code/modules/mob/living/carbon/human/life.dm
var/beating = 1
@@ -63,10 +63,9 @@
H.stop_sound_channel(CHANNEL_HEARTBEAT)
beat = BEAT_NONE
- if(H.jitteriness)
- if(!beat || beat == BEAT_SLOW)
- H.playsound_local(get_turf(H),fastbeat,40,0, channel = CHANNEL_HEARTBEAT)
- beat = BEAT_FAST
+ if(H.jitteriness && H.health > HEALTH_THRESHOLD_FULLCRIT && (!beat || beat == BEAT_SLOW))
+ H.playsound_local(get_turf(H),fastbeat,40,0, channel = CHANNEL_HEARTBEAT)
+ beat = BEAT_FAST
/obj/item/organ/heart/cursed
name = "cursed heart"
diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm
index eae5e8aee8..352958d9b8 100755
--- a/code/modules/surgery/organs/liver.dm
+++ b/code/modules/surgery/organs/liver.dm
@@ -8,7 +8,7 @@
origin_tech = "biotech=3"
w_class = WEIGHT_CLASS_NORMAL
zone = "chest"
- slot = "liver"
+ slot = ORGAN_SLOT_LIVER
desc = "Pairing suggestion: chianti and fava beans."
var/damage = 0 //liver damage, 0 is no damage, damage=maxHealth causes liver failure
var/alcohol_tolerance = ALCOHOL_RATE//affects how much damage the liver takes from alcohol
diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm
index eb1be67af2..65c1e3e1fb 100644
--- a/code/modules/surgery/organs/lungs.dm
+++ b/code/modules/surgery/organs/lungs.dm
@@ -12,7 +12,7 @@
name = "lungs"
icon_state = "lungs"
zone = "chest"
- slot = "lungs"
+ slot = ORGAN_SLOT_LUNGS
gender = PLURAL
w_class = WEIGHT_CLASS_NORMAL
@@ -95,10 +95,10 @@
var/list/breath_gases = breath.gases
- breath.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz, /datum/gas/nitrogen)
+ breath.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz, /datum/gas/nitrogen, /datum/gas/tritium, /datum/gas/brown_gas, /datum/gas/pluoxium, /datum/gas/stimulum)
//Partial pressures in our breath
- var/O2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/oxygen][MOLES])
+ var/O2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/oxygen][MOLES])+(8*breath.get_breath_partial_pressure(breath_gases[/datum/gas/pluoxium][MOLES]))
var/N2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitrogen][MOLES])
var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/plasma][MOLES])
var/CO2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/carbon_dioxide][MOLES])
@@ -252,9 +252,40 @@
H.adjustBrainLoss(3)
else if(bz_pp > 0.01)
H.hallucination += 5//Removed at 2 per tick so this will slowly build up
+
+
+ // Tritium
+ var/trit_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/tritium][MOLES])
+ if (trit_pp > 50)
+ H.radiation += trit_pp/2 //If you're breathing in half an atmosphere of radioactive gas, you fucked up.
+ else
+ H.radiation += trit_pp/10
+
+ //Brown Gas
+ var/brown_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/brown_gas][MOLES])
+ if (prob(brown_pp))
+ to_chat(H, "Your mouth feels like it's burning!")
+ if (brown_pp >40)
+ H.emote("gasp")
+ H.adjustFireLoss(10)
+ if (prob(brown_pp/2))
+ to_chat(H, "Your throat closes up!")
+ H.silent = max(H.silent, 3)
+ else
+ H.adjustFireLoss(brown_pp/4)
+ gas_breathed = breath_gases[/datum/gas/brown_gas][MOLES]
+ if (gas_breathed > GAS_STIM_MINIMUM)
+ H.reagents.add_reagent("brown_gas",1)
+
+ breath_gases[/datum/gas/brown_gas][MOLES]-=gas_breathed
+ gas_breathed = 0
+ //Stimulum
+ gas_breathed = breath_gases[/datum/gas/stimulum][MOLES]
+ if (gas_breathed > GAS_STIM_MINIMUM)
+ H.reagents.add_reagent("stimulum",1)
+ breath_gases[/datum/gas/stimulum][MOLES]-=gas_breathed
handle_breath_temperature(breath, H)
breath.garbage_collect()
-
return TRUE
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index 681dcb21cf..85a6b098e1 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -22,7 +22,7 @@
if(replaced)
replaced.Remove(M, special = 1)
if(drop_if_replaced)
- replaced.forceMove(get_turf(src))
+ replaced.forceMove(get_turf(M))
else
qdel(replaced)
@@ -118,7 +118,7 @@
var/has_liver = (!(NOLIVER in dna.species.species_traits))
var/has_stomach = (!(NOSTOMACH in dna.species.species_traits))
- if(has_liver && !getorganslot("liver"))
+ if(has_liver && !getorganslot(ORGAN_SLOT_LIVER))
var/obj/item/organ/liver/LI
if(dna.species.mutantliver)
@@ -127,7 +127,7 @@
LI = new()
LI.Insert(src)
- if(has_stomach && !getorganslot("stomach"))
+ if(has_stomach && !getorganslot(ORGAN_SLOT_STOMACH))
var/obj/item/organ/stomach/S
if(dna.species.mutantstomach)
@@ -136,15 +136,15 @@
S = new()
S.Insert(src)
- if(breathes && !getorganslot("lungs"))
+ if(breathes && !getorganslot(ORGAN_SLOT_LUNGS))
var/obj/item/organ/lungs/L = new()
L.Insert(src)
- if(blooded && !getorganslot("heart"))
+ if(blooded && !getorganslot(ORGAN_SLOT_HEART))
var/obj/item/organ/heart/H = new()
H.Insert(src)
- if(!getorganslot("tongue"))
+ if(!getorganslot(ORGAN_SLOT_TONGUE))
var/obj/item/organ/tongue/T
if(dna && dna.species && dna.species.mutanttongue)
@@ -155,7 +155,7 @@
// if they have no mutant tongues, give them a regular one
T.Insert(src)
- if(!getorganslot("eye_sight"))
+ if(!getorganslot(ORGAN_SLOT_EYES))
var/obj/item/organ/eyes/E
if(dna && dna.species && dna.species.mutanteyes)
@@ -165,7 +165,7 @@
E = new()
E.Insert(src)
- if(!getorganslot("ears"))
+ if(!getorganslot(ORGAN_SLOT_EARS))
var/obj/item/organ/ears/ears
if(dna && dna.species && dna.species.mutantears)
ears = new dna.species.mutantears
diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm
index 36cd28ac98..2bf34334f4 100755
--- a/code/modules/surgery/organs/stomach.dm
+++ b/code/modules/surgery/organs/stomach.dm
@@ -4,7 +4,7 @@
origin_tech = "biotech=4"
w_class = WEIGHT_CLASS_NORMAL
zone = "chest"
- slot = "stomach"
+ slot = ORGAN_SLOT_STOMACH
attack_verb = list("gored", "squished", "slapped", "digested")
desc = "Onaka ga suite imasu."
var/disgust_metabolism = 1
diff --git a/code/modules/surgery/organs/tails.dm b/code/modules/surgery/organs/tails.dm
index 99d1ed2442..a909463585 100644
--- a/code/modules/surgery/organs/tails.dm
+++ b/code/modules/surgery/organs/tails.dm
@@ -2,7 +2,7 @@
name = "tail"
desc = "What did you cut this off of?"
zone = "groin"
- slot = "tail"
+ slot = ORGAN_SLOT_TAIL
/obj/item/organ/tail/cat
name = "cat tail"
diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm
index 449e88dc58..6420d8610e 100644
--- a/code/modules/surgery/organs/tongue.dm
+++ b/code/modules/surgery/organs/tongue.dm
@@ -3,7 +3,7 @@
desc = "A fleshy muscle mostly used for lying."
icon_state = "tonguenormal"
zone = "mouth"
- slot = "tongue"
+ slot = ORGAN_SLOT_TONGUE
attack_verb = list("licked", "slobbered", "slapped", "frenched", "tongued")
var/list/languages_possible
var/say_mod = null
@@ -83,7 +83,7 @@
var/mob/living/carbon/human/user = usr
var/rendered = "[user.name]: [message]"
for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
- var/obj/item/organ/tongue/T = H.getorganslot("tongue")
+ var/obj/item/organ/tongue/T = H.getorganslot(ORGAN_SLOT_TONGUE)
if(!T || T.type != type)
continue
if(H.dna && H.dna.species.id == "abductor" && user.dna && user.dna.species.id == "abductor")
diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm
index 8b7f325f22..85dc2ae1c3 100644
--- a/code/modules/surgery/organs/vocal_cords.dm
+++ b/code/modules/surgery/organs/vocal_cords.dm
@@ -7,7 +7,7 @@
name = "vocal cords"
icon_state = "appendix"
zone = "mouth"
- slot = "vocal_cords"
+ slot = ORGAN_SLOT_VOICE
gender = PLURAL
var/list/spans = null
@@ -24,15 +24,13 @@
name = "adamantine resonator"
desc = "Fragments of adamantine exist in all golems, stemming from their origins as purely magical constructs. These are used to \"hear\" messages from their leaders."
zone = "head"
- slot = "adamantine_resonator"
+ slot = ORGAN_SLOT_ADAMANTINE_RESONATOR
icon_state = "adamantine_resonator"
/obj/item/organ/vocal_cords/adamantine
name = "adamantine vocal cords"
desc = "When adamantine resonates, it causes all nearby pieces of adamantine to resonate as well. Adamantine golems use this to broadcast messages to nearby golems."
actions_types = list(/datum/action/item_action/organ_action/use/adamantine_vocal_cords)
- zone = "mouth"
- slot = "vocal_cords"
icon_state = "adamantine_cords"
/datum/action/item_action/organ_action/use/adamantine_vocal_cords/Trigger()
@@ -48,7 +46,7 @@
for(var/m in GLOB.player_list)
if(iscarbon(m))
var/mob/living/carbon/C = m
- if(C.getorganslot("adamantine_resonator"))
+ if(C.getorganslot(ORGAN_SLOT_ADAMANTINE_RESONATOR))
to_chat(C, msg)
if(isobserver(m))
var/link = FOLLOW_LINK(m, owner)
@@ -59,8 +57,6 @@
name = "divine vocal cords"
desc = "They carry the voice of an ancient god."
icon_state = "voice_of_god"
- zone = "mouth"
- slot = "vocal_cords"
actions_types = list(/datum/action/item_action/organ_action/colossus)
var/next_command = 0
var/cooldown_mod = 1
diff --git a/code/modules/surgery/prosthetic_replacement.dm b/code/modules/surgery/prosthetic_replacement.dm
index 2dddb95872..e55f3af009 100644
--- a/code/modules/surgery/prosthetic_replacement.dm
+++ b/code/modules/surgery/prosthetic_replacement.dm
@@ -4,6 +4,7 @@
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list("r_arm", "l_arm", "l_leg", "r_leg", "head")
requires_bodypart = FALSE //need a missing limb
+ requires_bodypart_type = 0
/datum/surgery/prosthetic_replacement/can_start(mob/user, mob/living/carbon/target)
if(!iscarbon(target))
@@ -84,4 +85,3 @@
var/obj/item/melee/arm_blade/new_arm = new(target,TRUE,TRUE)
target_zone == "r_arm" ? target.put_in_r_hand(new_arm) : target.put_in_l_hand(new_arm)
return 1
-
diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm
index 03beacf27b..e5c046fac1 100644
--- a/code/modules/surgery/surgery.dm
+++ b/code/modules/surgery/surgery.dm
@@ -6,7 +6,7 @@
var/can_cancel = 1 //Can cancel this surgery after step 1 with cautery
var/list/species = list(/mob/living/carbon/human) //Acceptable Species
var/location = "chest" //Surgery location
- var/requires_organic_bodypart = 1 //Prevents you from performing an operation on robotic limbs
+ var/requires_bodypart_type = BODYPART_ORGANIC //Prevents you from performing an operation on robotic limbs
var/list/possible_locs = list() //Multiple locations
var/ignore_clothes = 0 //This surgery ignores clothes
var/mob/living/carbon/target //Operation target mob
@@ -53,6 +53,13 @@
var/step_type = steps[status]
return new step_type
+/datum/surgery/proc/get_surgery_next_step()
+ if(status < steps.len)
+ var/step_type = steps[status + 1]
+ return new step_type
+ else
+ return null
+
/datum/surgery/proc/complete()
SSblackbox.add_details("surgeries_completed", "[type]")
qdel(src)
diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm
index 7047c50084..577dc6547b 100644
--- a/code/modules/surgery/surgery_step.dm
+++ b/code/modules/surgery/surgery_step.dm
@@ -5,6 +5,7 @@
var/accept_hand = 0 //does the surgery step require an open hand? If true, ignores implements. Compatible with accept_any_item.
var/accept_any_item = 0 //does the surgery step accept any item? If true, ignores implements. Compatible with require_hand.
var/time = 10 //how long does the step take?
+ var/repeatable = 0
/datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -31,8 +32,19 @@
else
to_chat(user, "You need to expose [target]'s [parse_zone(target_zone)] to perform surgery on it!")
return 1 //returns 1 so we don't stab the guy in the dick or wherever.
+
+ if(repeatable)
+ var/datum/surgery_step/next_step = surgery.get_surgery_next_step()
+ if(next_step)
+ surgery.status++
+ if(next_step.try_op(user, target, user.zone_selected, user.get_active_held_item(), surgery))
+ return 1
+ else
+ surgery.status--
+
if(iscyborg(user) && user.a_intent != INTENT_HARM) //to save asimov borgs a LOT of heartache
return 1
+
return 0
@@ -63,7 +75,7 @@
if(failure(user, target, target_zone, tool, surgery))
advance = 1
- if(advance)
+ if(advance && !repeatable)
surgery.status++
if(surgery.status > surgery.steps.len)
surgery.complete()
diff --git a/code/modules/uplink/uplink_item.dm b/code/modules/uplink/uplink_item.dm
index 4cf6700544..6aad347e2a 100644
--- a/code/modules/uplink/uplink_item.dm
+++ b/code/modules/uplink/uplink_item.dm
@@ -375,6 +375,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
organic host as a home base and source of fuel."
item = /obj/item/storage/box/syndie_kit/guardian
cost = 18
+ surplus = 0
exclude_modes = list(/datum/game_mode/nuclear)
player_minimum = 25
diff --git a/code/modules/uplink/uplink_item_cit.dm b/code/modules/uplink/uplink_item_cit.dm
index 40c74269eb..26591c72ef 100644
--- a/code/modules/uplink/uplink_item_cit.dm
+++ b/code/modules/uplink/uplink_item_cit.dm
@@ -160,4 +160,19 @@
new /obj/item/storage/belt/military(src)
new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src)
-///End of Bundle stuff///
\ No newline at end of file
+///End of Bundle stuff///
+
+
+/*/////////////////////////////////////////////////////////////////////////
+///////////// The TRUE Energy Sword ///////////////////////////
+*//////////////////////////////////////////////////////////////////////////
+
+/datum/uplink_item/dangerous/cxneb
+ name = "Dragon's Tooth Non-Eutactic Blade"
+ desc = "An illegal modification of a weapon that is functionally identical to the energy sword, \
+ the Non-Eutactic Blade (NEB) forges a hardlight blade on-demand, \
+ generating an extremely sharp, unbreakable edge that is guaranteed to satisfy your every need. \
+ This particular model has a polychromic hardlight generator, allowing you to murder in style! \
+ The illegal modifications bring this weapon up to par with the classic energy sword, and also gives it the energy sword's distinctive sounds."
+ item = /obj/item/melee/transforming/energy/sword/cx/traitor
+ cost = 8
\ No newline at end of file
diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm
index 8db4e492e4..f203af610a 100644
--- a/code/modules/zombie/items.dm
+++ b/code/modules/zombie/items.dm
@@ -44,7 +44,7 @@
return
var/obj/item/organ/zombie_infection/infection
- infection = target.getorganslot("zombie_infection")
+ infection = target.getorganslot(ORGAN_SLOT_ZOMBIE)
if(!infection)
infection = new()
infection.Insert(target)
diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm
index 81d3457d40..0b7a54ee1f 100644
--- a/code/modules/zombie/organs.dm
+++ b/code/modules/zombie/organs.dm
@@ -2,7 +2,7 @@
name = "festering ooze"
desc = "A black web of pus and viscera."
zone = "head"
- slot = "zombie_infection"
+ slot = ORGAN_SLOT_ZOMBIE
icon_state = "blacktumor"
origin_tech = "biotech=5"
var/datum/species/old_species = /datum/species/human
diff --git a/config/game_options.txt b/config/game_options.txt
index e835a4b1a6..d3fa274ed8 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -395,6 +395,13 @@ JOIN_WITH_MUTANT_RACE
## You probably want humans on your space station, but technically speaking you can turn them off without any ill effect
ROUNDSTART_RACES human
+ROUNDSTART_RACES mammal
+ROUNDSTART_RACES avian
+ROUNDSTART_RACES aquatic
+ROUNDSTART_RACES insect
+ROUNDSTART_RACES xeno
+ROUNDSTART_RACES datashark
+ROUNDSTART_RACES guilmon
## Races that are strictly worse than humans that could probably be turned on without balance concerns
ROUNDSTART_RACES lizard
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 832f808000..a5655f2e03 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
---
2015-04-04:
@@ -10511,3 +10512,13465 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
XDTM:
- bugfix: APCs hacked by a malfunctioning AI are no longer immune to alien attacks.
- bugfix: Fixed bug where flashlight eyes weren't emitting light.
+=======
+DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
+---
+2015-04-04:
+ ACCount:
+ - rscadd: Emergency welding tool added to emergency toolbox.
+ - rscadd: Changed industrial welding tool sprite.
+ - tweak: Replaced welder in syndicate toolbox with industrial one.
+ - tweak: All tools in syndicate toolbox are red. Corporate style!
+ - tweak: Red crowbar is a bit more robust.
+ - bugfix: 'Fixed two bugs: welder icon disappearing and drone toolbox spawning with
+ invisible cable coil.'
+ AnturK:
+ - rscadd: 'Picket signs: table crafted with a rod and two cardboard sheets, write
+ on them with pen or crayon.'
+ Cheridan:
+ - wip: The bar's layout has been changed with a poker table and re-arranged seating.
+ Dannno:
+ - rscadd: Added gun lockers for shotguns and energy guns. Click on the lockers with
+ an item to close them if they're full.
+ Gun Hog:
+ - rscadd: Nanotrasen research has finalized improvements for the experimental Reactive
+ Teleport Armor. The armor is now made of a thinner, lightweight material which
+ will not hinder movement. In addition, the armor shows an increase in responsiveness,
+ activating in at least 50% of tests.
+ Incoming:
+ - rscadd: The iconic blood-red hardsuits of nuke ops can now be purchased for a
+ moderate sum of 8 TC by traitors.
+ Jordie0608:
+ - tweak: Cyborg mining drills now use up their internal battery before drawing power
+ from a borg's cell.
+ - bugfix: Fixes cyborg mining drills not recharging.
+ RemieRichards:
+ - rscadd: Burning mobs will ignite others they bump into or when they are stepped
+ on.
+ Xhuis:
+ - tweak: Malfunctioning AIs can no longer leave the station z-level. Upon doing
+ this, they will fail the round.
+ - tweak: Phazon exosuits now require an anomaly core as the final step in their
+ construction.
+ xxalpha:
+ - rscadd: Added Nutriment Pump, Nutriment Pump Plus and Reviver implants.
+ - tweak: Added origin technologies to all implants.
+ - tweak: 'The following implants are now much harder to obtain: X-ray, Thermals,
+ Anti-Stun, Nutriment Pump Plus, Reviver.'
+ - tweak: Cauterizing a surgery wound will now heal some of the damage done by the
+ bonesaw if it was used as part of the same surgery.
+ - tweak: Added ability for Medical HUDs to detect cybernetic implants in humans.
+2015-04-09:
+ Iamgoofball:
+ - rscadd: Quite a lot of cleanables can now be scooped up with a beaker in order
+ to acquire the contents.
+ - rscadd: Light a piece of paper on fire with a lighter, and scoop up the ashes!
+ - rscadd: Scoop up the flour the clown sprayed everywhere as a 'joke'!
+ - rscadd: Scoop up the oil left behind by exploding robots for re-usage in chemistry!
+ - rscadd: You can splash the contents of a beaker onto the floor to create a Chemical
+ Pile! This pile can be heated or blown up and have the reagents take the effects.
+ Make a string of black powder around a department in maint. and then heat it
+ with a welder today!
+ - rscadd: Reagents now can have processing effects when just sitting in a beaker.
+ - rscadd: Pyrosium and Cryostylane now feed off of oxygen and heat/cool the beaker
+ without having to be inside of a person!
+ - rscadd: Reagents can now respond to explosions!
+ - rscadd: Black Powder now instantly detonates if there is an explosion that effects
+ it.
+ - rscadd: Fire now heats up beakers and their contents!
+ - rscadd: Activate some smoke powder in style by lighting the beaker on fire with
+ a burning hot plasma fire!
+ RemieRichards:
+ - tweak: Ninja stars are summoned to your hand to be thrown rather than automatically
+ targetting nearby mobs.
+ - rscadd: 'Added Sword Recall: pulls your katana towards you, hitting mobs in the
+ way. Free if within sight, cost scales with distance otherwise.'
+ - rscadd: Enemies can be electrocuted by a ninja as the cost of his energy, stunning
+ and injuring them.
+ - rscdel: Removed SpiderOS, functions moved to status panel.
+ - bugfix: Fixed energy nets not anchoring target, katana emag spam and sound delay.
+ optimumtact:
+ - bugfix: Mimes can't use megaphone without breaking their vow anymore.
+ phil235:
+ - tweak: Flying animals no longer triggers mouse traps, bear traps or mines.
+2015-04-11:
+ Gun Hog:
+ - tweak: Nanotrasen has approved an access upgrade for Cargo Technicians! They are
+ now authorized to release minerals from the ore redemption machine, to allow
+ proper inventory management and shipping.
+ Iamgoofball:
+ - tweak: Blobbernauts no longer deal chemical damage, brute damage increased however.
+ Ikarrus:
+ - experiment: Getting converted by a rev or cultist will stun you for a few seconds.
+ Incoming5643:
+ - bugfix: Fixes some AI malf powers being usable when dead.
+ MrPerson:
+ - tweak: Reduces movement speed penalty from being cold.
+ Xhuis:
+ - rscadd: Adds a pizza bomb traitor item for 4 telecrystals. It's a bomb, diguised
+ as a pizza box. You can also attempt to defuse it by using wirecutters.
+ kingofkosmos:
+ - rscadd: Activating internals with an adjusted breath mask will automatically push
+ it up to normal state.
+ - tweak: Masks can now be adjusted when buckled to a chair.
+ optimumtact:
+ - tweak: Stun batons no longer lose charge over time when on.
+ phil235:
+ - tweak: The AI holopads now use a popup window just like computers and other machines.
+ - rscdel: Nerfs kinetic accelerator and plasma cutters. Plasma cutter is no longer
+ in the mining vendor. Reduces the drilling cost of all drills.
+ - rscadd: Adding 40+ new food and drink recipes, mostly using the newest plants.
+ Notably rice recipes, burritos, nachos, salads, pizzas.
+ - tweak: Opening the tablecrafting window can now also be done by dragging the mouse
+ from any food (that's on a table) onto you.
+ - rscadd: The kitchen cabinet starts with one rice pack.
+ - tweak: Glasses with unknown reagent will no longer be always brown but will take
+ the color of their reagents.
+2015-04-13:
+ AnturK:
+ - rscadd: 'Spacemen have learned the basics of martial arts: Boxing, unleash it''s
+ power by wearing Boxing Gloves.'
+ - rscadd: While boxing you can't grab or disarm, but you hit harder with a knockout
+ chance that scales off stamina damage above 50.
+ - rscadd: Rumors have been heard of powerful martial styles avaliable only to the
+ gods themselves.
+ CosmicScientist:
+ - rscadd: Added a dehydrated space carp to traitor items, bought with telecrystals.
+ Use dehydrated space carp in hand to school them on loyalty. Add water to create
+ a vicious murder machine just for the halibut.
+ - tweak: The toy carp plushie now has attack verbs for fun, hit your friend with
+ one today. I put my sole into this mod.
+ - wip: If you can think of a better fish pun let minnow but I shouldn't leave it
+ to salmon else.
+ Ikarrus:
+ - tweak: Gang bosses can no longer purchase certain potent traitor items but instead
+ have access to some of a nuke op's arsenal of weapons.
+ Incoming5643:
+ - rscadd: 'Three new chemical types of blob can occur: Omnizine, Morphine and Space
+ Drugs.'
+ MrPerson:
+ - experiment: New lighting system! Lighting now smoothly transfers from one lighting
+ level to the next.
+ Xhuis:
+ - rscadd: There have been... odd sighting in Space Station 13's sector. Alien organisms
+ have appeared on stations 57, 23, and outlying.
+ - rscadd: Nanotrasen personnel have reason to believe that Space Station 13 is under
+ attack by shadowlings. We have little intel on these creatures, but be on the
+ lookout for odd behavior and dark areas. Use plenty of lights.
+ Zelacks:
+ - tweak: Defibs no longer have a minimum damage requirement for a successful revive.
+ Patients will have 150 total damage on a successful revive.
+ - tweak: Additional feedback is given for several failure states of the defib.
+ xxalpha:
+ - wip: Airlock crushing damage increased.
+2015-04-16:
+ AnturK:
+ - rscadd: Nanotrasen authorities are reporting sightings of unidentified space craft
+ near space station 13. Report any strange sightings or mental breakdowns to
+ central command.
+ - rscadd: 'PS : Abductions are not covered by health insurance.'
+ - rscadd: Shadowlings and their thralls now have HUD icons.
+ - rscadd: Thralls learn their master's objectives when enthralled.
+ - rscadd: Regenerate Chitin ability lets shadowlings re-equip their armor if lost.
+ - tweak: Loyalty implanted people take 25% longer to enthrall, but lose their implant
+ and become immune to re-implanting.
+ - experiment: Shadowlings now have a message in their spawning text which specifies
+ that cooperation is mandatory.
+ - bugfix: Veil now works on equipped lights.
+ - bugfix: Shadowlings now take correct amount of burn damage and in light and heal
+ clone and brain damage in darkness.
+ - bugfix: Fixes 'Round end code broke' displaying every round.
+ - bugfix: Shadowlings who ascend will nore greentext properly.
+ Gun Hog:
+ - rscadd: Thinktronic Systems, LTD. has increased the Value of the Value-PAK PDA
+ cartridge! Standard issue for Captain PDAs, it can now access security bots,
+ medibots, cleanbots, and floorbots ALL AT ONCE! In addition, it can also connect
+ to your station's Newscaster network at NO EXTRA CHARGE! As a Thank you for
+ our contract with them, they have thrown in Newscaster access for the HumanResources9001
+ cartridge, Heads of Personnel rejoice!
+ - tweak: The Newscaster app has also gotten a free upgrade which allows it to display
+ images and comments inside of posts!
+ - bugfix: Nanotrasen has concurrently released a patch for bots which will allow
+ off-station bots to properly patrol.
+ Incoming5643:
+ - rscadd: Changeling head slugs have been given player control, ventcrawling, and
+ a short escape period after egg laying.
+ MrStonedOne:
+ - rscadd: Admin ghosts can now drag ghosts to mobs to put that ghost in control
+ of that mob.
+ Xhuis:
+ - rscadd: Nanotrasen scientists have recently observed a strange genome shift in
+ green slimes. Experiments have shown that injection of radium into an active
+ green slime extract will create a very unstable mutation toxin. Use with caution.
+2015-04-19:
+ AnturK:
+ - bugfix: Observers can now see abductor hivemind messages.
+ - rscadd: 'Adds advanced baton for abductors: Stun, Sleep and Cuff in one tool.'
+ - rscadd: Abductor agents now have vest cameras.
+ - imageadd: New sprites for abductors and their gear made by Ausops.
+ Fayrik:
+ - rscadd: Added jobban options for Abductors and Deathsquads.
+ - tweak: Made admin antag spawning buttons more efficient and less prone to failure.
+ Xhuis:
+ - rscadd: Recent sightings aboard space stations shows that spirits seem to be manifesting
+ as malevolent revenants and draining the life of crew. The chaplain may be helpful
+ in stopping this new threat.
+ kingofkosmos:
+ - wip: Girder and machine frame construction protocols has been changed. They can
+ now be secured/unsecured with a wrench and disassembled with a welder.
+2015-04-20:
+ Fayrik:
+ - rscadd: Abductors now get advanced camera consoles.
+ - tweak: Redesigned Centcom again. There's a bar at the thunderdome now.
+ - rscadd: Headsets can now be locked to a spesific frequency, this only occurs for
+ nuke ops and deathsquads.
+ - rscadd: The Centcom channel is now available over all z-levels, regardless of
+ telecomms status.
+ - tweak: The Deathsquad space suits have been upgraded to hardsuits.
+ - rscadd: The Deathsquad now have thermal imaging huds, which can swap which hud
+ they display on the fly.
+ phil235:
+ - tweak: Reagents are now back to being metabolized every tick. Fixes frost oil
+ and capsaicin not working.
+ - tweak: Fixes not being able to make sterilizine.
+ - rscadd: Adding overdose to space drug, causing mild hallucination and toxin and
+ brain damage.
+ - tweak: Nerfed healing power of stimulant reagent. Buffed ephedrine a bit.
+ - rscadd: Nitroglycerin can now be stabilized with stabilizing agent, and explodes
+ when heated.
+2015-04-21:
+ Ikarrus:
+ - wip: Gang mode has had some considerable work done on it, including a new objective
+ and currency dynamic.
+ - rscadd: New objective: Claim half the station as territory by tagging it
+ with spray cans supplied to gang bosses, but usable by any member.
+ - wip: An area can only be tagged by one gang at a time, remove your opponent's
+ tag or spray over it.
+ - rscadd: New recruitment: Recruiment pens replace flashes, stab people to
+ recruit them.
+ - experiment: Recruitment is silent, but causes brief seizures and has a cooldown
+ that scales upwards with a gang's size.
+ - rscadd: New tool: The Gangtool is used by bosses and lieutenants to recall
+ the shuttle and purchase supplies.
+ - rscadd: Pistols, ammo, spraycans, recruitment pens and additional gangtools can
+ all be bought.
+ - tweak: Gangtools also alert the user of promotions, purchases and territory changes
+ within the gang.
+ - rscadd: Lieutenants are promoted from gang members when given their own gangtool;
+ they're immune to deconversion and able to do anything a boss can except promotion.
+ - rscadd: New currency: Influence is used to purchase with the gangtool and
+ is generated every 5 minutes by each territory owned by the gang.
+ - tweak: Thermite can be cleaned off walls now.
+2015-04-22:
+ Incoming5643:
+ - rscadd: 'Adds a new fun button for admins: ''Set Round End Sound''. You can use
+ the set round end sound button to set the round end sound. Glad we cleared that
+ up!'
+ Miauw62:
+ - wip: Very slightly expanded atmos and added an external airlock.
+ Xhuis:
+ - bugfix: A few issues have been fixed for revenants. In addition, the Mind Blast/Mind
+ Spike sound effect has been removed.
+ - rscadd: Adds the Hypnotize ability to revenants. It will cause a target to fall
+ asleep after a short time.
+ xxalpha:
+ - rscadd: Added an Exosuit Mining Scanner to the robotics fabricator.
+ - tweak: Buffed Ripley's movement and drilling speed in low pressure environments.
+2015-04-25:
+ Boggart:
+ - rscadd: Generalizes handheld instrument code and Ports Nienhaus's guitar, sounds
+ by BartNixon of Tau Ceti.
+ - rscadd: Fixes being unable to build disposal pipes on walls, makes changing the
+ RPD's settings not affect pipes that are currently building, makes the RPD use
+ the datum/browser ui, makes it use categories and makes it show the selected
+ mode.
+ Gun Hog:
+ - rscadd: Nanotrasen has provided designs for fabrication of APC power control modules.
+ You may print them at any autolathe.
+ Ikarrus:
+ - rscadd: Gangs can now purchase switchblades, a relatively cheap and decently robust
+ melee weapon.
+ - tweak: Gangs now require at least 66% control of the station to win.
+ - tweak: Gang spraycan uses reduced to 15.
+ - tweak: Pistol cost increased to 30 Influence
+ - tweak: Promotions now start off cheap at 20 influence but get more expensive the
+ more people you promote.
+ Xhuis:
+ - rscadd: Added a Create Antagonist button for revenants.
+ - rscdel: Removed Mind Blast.
+ - bugfix: Revenants no longer get killed by explosions.
+ - tweak: Mind spike cooldown increased to 4 seconds.
+ - tweak: Harvest now takes 8 seconds and requires you to be adjacent to the target.
+ - tweak: Hypnotise sleeps targets for longer.
+ - tweak: Revenant now starts with 3 strikes.
+ phil235:
+ - tweak: Telecom machines are now deconstructed the same way as all other constructable
+ machines.
+ - tweak: You can no longer overdose on nicotine but you can get addicted (very mild
+ effects).
+2015-04-29:
+ AndroidSFV:
+ - tweak: Dehydrated carp now are friendly to both the imprinter of the plushie as
+ well as any coded-in allies (I.E. Nuke Ops team), and unfriendly to carp of
+ other origin othan than yourself or your coded-in allies. Dehydrated carp that
+ are not imprinted will still have the same behavior as regular carp.
+ AnturK:
+ - rscadd: Advanced cameras now have all functionality of the abductor consoles.
+ - tweak: Pinpoint teleportation takes 8 seconds and spawns a flashy silhouette at
+ the target location. Can be used as distraction since it appears even if teleporter
+ is empty.
+ - bugfix: Abductors are now immune to viruses.
+ - bugfix: Dissection surgery ignores clothes.
+ - bugfix: Non-abductors can escape the ship by fiddling with consoles enough.
+ - rscadd: Three new negative glands.
+ - rscadd: Bloody glands spray blood everywhere and injure the host.
+ - rscadd: Bodysnatch glands turn the host into a cocoon that hatches doppelgangers.
+ - rscadd: Plasma glands cause the host to explode into a cloud of plasma.
+ GoonOnMoon:
+ - rscadd: Added a new assault rifle to the game for use by Nanotrasen fighting forces
+ in special events. Also happens to be available in the Liberation Station vending
+ machine and the summon guns spell usable by the wizard and badminnery.
+ Iamgoofball:
+ - rscdel: Acid blob has been removed.
+ - tweak: Charcoal and Silver Sulf are more powerful now.
+ - tweak: Styptic power and Silver Sulf metabolize at the default rate.
+ Ikarrus:
+ - rscadd: Spraycans and crayons can now draw Poseur Tags, aka Fake Gang Tags, as
+ grafiti.
+ - tweak: Influence income changed to provide weaker gangs a bigger boost, while
+ slowing down stronger gangs to promote opportunity for comebacks.
+ - tweak: Gangs only earn influence on territories they have held on to since the
+ previous Status Report (the income calculation every 5 minutes). This places
+ more significance on defending your existing territory.
+ - bugfix: You must be in the territory physically to tag it now. So no more tagging
+ everything from maint.
+ - tweak: Gang income delay reduced to 3 minutes intervals.
+ - tweak: Gang Capture goal reduced to 50%
+ - tweak: Gang spraycan use increased to 20
+ - tweak: Gang Boss icon is now a red [G] icon to make it stand out better from regular
+ gang icons
+ JJRcop:
+ - tweak: TED's kill duration has been halved.
+ - tweak: Escaping from the TED's field no longer kills you.
+ RemieRichards:
+ - rscadd: Adds Easels and canvases for custom drawings.
+ - imageadd: Place a canvas on an easel and draw on it with crayons, clean one pixel
+ with a rag or soap and activate it in-hand to erase the whole canvas.
+ - rscadd: Ports VG's Ventcrawling overhaul!
+ - tweak: Crawling through vents is no longer instant, you now have to move and navigate
+ manually
+ - rscadd: While inside pipes and other atmos machinery, you now see pipe vision
+ phil235:
+ - bugfix: Podplants are no longer unharvestable.
+ - tweak: Choosing your clown, mime, cyborg and AI name as well as religion and deity
+ is now done in the preferences window. As a chaplain , your bible's icon is
+ now chosen by clicking the bible.
+2015-04-30:
+ Fayrik:
+ - rscadd: Ported NanoUI to most atmospherics equipment.
+ TheVekter:
+ - tweak: Hooch is now made with 2 parts Ethanol, 1 part Welder fuel and 1 part Universal
+ Enzyme as a catalyst.
+ - tweak: No-slip shoes are paintable, painting them doesn't remove no-slip properties.
+2015-05-01:
+ Ikarrus:
+ - rscadd: Gang bosses can now rally their gang to their location with their gangtool.
+ - rscadd: Gangtools can no longer recall the shuttle if station integrity is lower
+ than 70%
+ - rscdel: Removed requirement to be in the territory to tag it.
+ - tweak: Recruitment Pen cost reduced to 40.
+ - bugfix: Communications console should now accurately print the (lack of a) location
+ of the last shuttle call.
+ Xhuis:
+ - rscdel: Revenants will no longer spawn without admin intervention. They are pending
+ a remake.
+2015-05-02:
+ Boggart:
+ - bugfix: Cryo tubes can no longer be used for ventcrawling.
+ Ikarrus:
+ - rscadd: Admins can choose the strength and size of Centcom teams to send, ranging
+ from officials to deathsquads, with the 'Make Centcom Respone Team' button.
+ phil235:
+ - tweak: Space carps can no longer knock down anyone, but they now deal additional
+ stamina damage to humans.
+ - tweak: Radiation effects from uranium walls are nerfed to the level of uranium
+ floor.
+ - rscadd: You can no longer put an inactive MMI in a cyborg shell. Ghosted brains
+ now get an alert when someone puts their brain in a MMI. You can now examine
+ the MMI to see if its brain is active.
+2015-05-03:
+ AnturK:
+ - rscadd: Abductors can purchase spare gear with experimentation points.
+ Ikarrus:
+ - rscadd: Admins can now adjust the pre-game delay time.
+ MrStonedOne:
+ - experiment: MasterController and subsystem rejiggering!
+ - rscadd: The MC can now dynamcially change the rate a subsystem is triggered based
+ on how laggy it's being. This has been applied to atmos to allow for faster
+ air processing without lagging the server
+ - tweak: Pipes and atmos machinery now processes in tune with air, rather than seperately.
+ - bugfix: Fixed hotspots and fire causing more lag than they needed to
+ - bugfix: Fixed some objects not getting garbage collected because they didn't properly
+ clear references in Destory()
+ - tweak: The qdel subsystem will now limit its processing time to a 5th of a second
+ each tick to prevent lag when a lot of deletes happen
+ - bugfix: Fixed the ticker not showing a tip of the round if an admin forces the
+ round to start immediately
+2015-05-04:
+ Firecage:
+ - bugfix: Emagged windoors can now be deconstructed.
+ RemieRichards:
+ - rscadd: Adds Plasmamen, a species that breathes plasma and bursts into flames
+ if they don't wear special suits.
+ - imageadd: New burning icon for all humanoid mobs.
+ - imageadd: New sprite for Skeletons to match Plasmamen.
+ oranges:
+ - tweak: Thanks to recent advances in fork science, you no longer need to aim at
+ your eyes to eat the food off a fork
+ xxalpha:
+ - rscadd: 'Adds a new barsign: ''The Net''.'
+2015-05-05:
+ Firecage:
+ - bugfix: Golems and skeletons no longer fall over when stepping on shards.
+ Gun Hog:
+ - bugfix: Mining borg diamond drill upgrade now functional.
+ Ikarrus:
+ - tweak: Doubled the initial charge of SMESs in Engineering.
+ - tweak: Influence cap for gangs has been increased.
+ incoming5643:
+ - bugfix: All modes now select their antagonists before job selection, this means
+ that a player who prefers roles normally immune to being certain antagonists
+ (implanted roles/silicons) can still have a fair shot at every antagonist roll
+ they opt into. If they're selected they simply will not end up with an incompatible
+ job.
+ - bugfix: As an example if someone loved to play Head of Security (humor me here)
+ and had it set to high, and the only other jobs he had set were security officer
+ at medium and botanist at low but he was selected to be a traitor, he would
+ spawn as a botanist even if there ended up being no Head of Security.
+ - experiment: Please give playing security another chance if you'd written it off
+ because it affected your antag chances.
+ xxalpha:
+ - bugfix: Hulks can now break windoors.
+ - bugfix: Fixed smoking pipe messages. Fixed emptying a smoking pipe with nothing
+ in it.
+2015-05-06:
+ Jordie0608:
+ - bugfix: Borgs can now open lockers with the 'Toggle Open' verb.
+ Thunder12345:
+ - bugfix: Severed the cryo tube's connection to the spirit world. Ghosts will no
+ longer be able to eject people from cryo. Please report further instances of
+ poltergeist activity to your local exorcist.
+ Xhuis:
+ - tweak: Many minor technical changes have been made to cult.
+ - rscadd: Cultist communications now show the name of the person using them. Emergency
+ communications do not do this.
+ - rscadd: Emergency communication does less damage.
+ xxalpha:
+ - rscadd: Engineering cyborgs can now pick their cable coil color whenever they
+ want.
+2015-05-07:
+ Xhuis:
+ - rscadd: Emagged defibrillators will now do burn damage and stop the patient's
+ heart if used in harm intent.
+ - tweak: The previous stunning functionality of the emagged defibrillator has been
+ moved to disarm intent.
+ phil235:
+ - tweak: Temperature effects from frost oil and capsaicin reagents and basilisk
+ have been buffed to be significant again.
+ xxalpha:
+ - tweak: Hulks can now break windoors.
+2015-05-08:
+ Firecage:
+ - tweak: Mobs can now be buckled to operating tables.
+ Gun Hog:
+ - rscadd: 'Top scientists at Nanotrasen have made strong progress in Artificial
+ Intelligence technology, and have completed a design for replicating a human
+ mind: Positronic Brains. Prototypes produced on your research station should
+ be compatible with all Man-Machine Interface compliant machines, be it Mechs,
+ AIs, and even Cyborg bodies. Please note that Cyborgs created from artificial
+ brains are called Androids.'
+ - tweak: The pAI role preference and related jobbans have been renamed to properly
+ reflect that they are not soley for pAI, but include drones and positroinc prains.
+ astralenigma:
+ - tweak: Cargo packages are now delivered with their manifests taped to the outside.
+ Click on them with an open hand to remove them.
+ optimumtact:
+ - tweak: Machine frame and girder deconstruction now uses a screwdriver instead
+ of welding tool.
+2015-05-09:
+ Firecage:
+ - tweak: Increased the manifestation chance of super powers.
+ Ikarrus:
+ - experiment: 'Loyalty implants will no longer survive deconverting a gangster.
+ Security now needs to use two of them if they want the permanent effects: The
+ first to deconvert them, and the second to make them loyal.'
+ KorPhaeron:
+ - tweak: Slime mutation chance now starts at 30%.
+ - rscadd: Baby slimes have a -5% to 5% difference of their parent's mutation chance,
+ allowing you to breed slimes that are more likely to mutate.
+ - rscdel: Plasma and epinephrine no longer affect mutation chance of slimes.
+ - rscadd: Red slime extract and plasma makes a potion that can increase mutation
+ chance, Blue slime extract and plasma potions will decrease it.
+2015-05-10:
+ AnturK:
+ - bugfix: Fixed borg's cells draining much faster than they're meant to.
+ Gun Hog:
+ - tweak: Station bot performance greatly increased.
+ - rscadd: Captain PDA cartridge now includes nearly all utilities and functions,
+ including signaller and all bots! HoP now has janitor and quartermaster functions!
+ The RD and Roboticists now have access to Floor, Clean, and Medibots!
+ - tweak: Bot access on PDA is now one button across all PDAs. You will only see
+ what bots you can access, however.
+ - rscadd: Cartridges that include a signaller have been improved so they will work
+ on a larger frequency range.
+ - tweak: All bots now have Robotics access, so they may be set to patrol and released
+ once constructed.
+ - tweak: Roboticists now have access to bot navigation beacons. They are found under
+ the floor tiles as patrol route nodes.
+2015-05-11:
+ Firecage:
+ - imageadd: New icons for Industrial and Experimental welding tools.
+ Gun Hog:
+ - rscdel: The power mechanic for mining drills and the jackhammer has been removed.
+ They no longer require cells or recharging.
+ - bugfix: The diamond drill upgrade for mining cyborgs has been fixed.
+ Xhuis:
+ - rscadd: Adds the pneumatic cannon, attach an air tank and shoot anything out of
+ it.
+ - rscadd: Improvised pneumatic cannons can be tablecrafted with a wrench, 4 metal,
+ 2 pipes, a pipe manifold, a pipe valve and 8 package wrappers.
+ spasticVerbalizer:
+ - bugfix: False walls no longer stackable.
+2015-05-13:
+ Firecage:
+ - rscadd: Kudzu is now admin-logged in Investigate.
+ GunHog:
+ - tweak: Positronic brains are now entered by clicking on an empty one, in the same
+ manner as drones.
+ - rscadd: Ghosts are alerted when a new posibrain is made.
+ Jordie0608:
+ - rscadd: Borg reagent containers (beakers, spraybottles, shakers etc.) are no longer
+ emptied when stowed.
+ - bugfix: Fixes North and West Mining Outposts having empty SMESs.
+ - bugfix: Aliens and slimes can smash metal foam again.
+ - rscdel: Deconstructing reinforced walls no longer creates additional rods out
+ of nowhere.
+ - imageadd: Pepperspray now has inhand sprites.
+ Xhuis:
+ - bugfix: Fixes the recipe for pneumatic cannons; it now only requires a wrench,
+ 4 metal, 2 pipes and 8 package wrappers .
+2015-05-15:
+ xxalpha:
+ - bugfix: Fixed emitter beams not being reflectable.
+2015-05-16:
+ MartiUK:
+ - bugfix: Fixed a typo when cleaning a Microwave.
+ - bugfix: Fixed a typo when burning someone with a lighter.
+2015-05-20:
+ xxalpha:
+ - rscadd: Added three drone shells to the derelict.
+2015-05-22:
+ Jordie0608:
+ - tweak: Smothering someone with a damp rag when in harm intent will apply reagents
+ onto them, for acid-burning their face; otherwise it will inject them, for drugging
+ with chloral hydrate.
+ - imageadd: The healthdoll is now blue when at full health to make it more clear
+ when a body part is injured.
+2015-05-25:
+ spasticVerbalizer:
+ - tweak: Glass airlocks can now be made heat-proof by using a sheet of reinforced
+ glass to create the window, regular glass creates a normal glass airlock.
+ xxalpha:
+ - bugfix: You can no longer drop items inside mechas nor machinery (this includes
+ gas pipes, disposal pipes, cryopods, sleepers, etc.).
+ - bugfix: Fixed exploit of changelings being able to keep thermal vision after resetting
+ their powers.
+ - bugfix: Fixed being able to implant NODROP items with cavity implant surgery.
+2015-05-26:
+ CosmicScientist:
+ - spellcheck: Corrected wording for the pAI, donksoft riot darts and some tip of
+ the round tips.
+ xxalpha:
+ - bugfix: Fixed changeling revival.
+2015-05-30:
+ duncathan:
+ - bugfix: Fixes passive gates not auto-coloring.
+ spasticVerbalizer:
+ - tweak: Players trying to speak but unable to will now get a message.
+2015-05-31:
+ duncathan:
+ - tweak: Clarified the ability to retract changeling armblades.
+2015-06-04:
+ Cuboos:
+ - rscadd: Added casting and firing sounds for wizard spells and staves.
+ - rscadd: A new title theme has been added.
+ Gun Hog:
+ - rscadd: Nanotrasen has approved the designs for destination taggers and hand labelers
+ in the autolathe.
+ Palpatine213:
+ - tweak: Allows sechuds to have their id locks removed via emag as well as EMP
+2015-06-05:
+ CandyClown:
+ - tweak: Ointments, bruise packs, and gauze are now stacked to 6 instead of 5.
+ CorruptComputer:
+ - bugfix: Security lockers no longer spawn in front of each other on Box.
+ - bugfix: Hooked up the scrubbers in QM's office on Box.
+ - bugfix: Fixed bar disposals on Box
+ - bugfix: Fixed the stacked heater+freezer in expirementor maint on Box
+ - tweak: Made the turbine into Atmos and Engineering access only, and renamed the
+ doors to Turbine on Box.
+ Ikarrus:
+ - rscadd: Gang Bosses will now be able to discreetly send messages to everyone in
+ their gang for 5 influence a message.
+ - tweak: Conversion pens now use a flat 60sec cooldown rate.
+ KorPhaeron:
+ - rscadd: You can now lay tiles on the asteroid. Go nuts building forts.
+2015-06-06:
+ Incoming5643:
+ - rscadd: Antagonists with escape alone can now escape with others on the shuttle,
+ so long as they are also antagonists.
+ - rscadd: Antagonists with escape alone can also win if non-antagonists are on the
+ shuttle provided they are locked in the brig.
+ - rscadd: Escaping to syndicate space on board the nuke op shuttle is now a valid
+ way to escape the station.
+ Jordie0608:
+ - rscadd: Admin-delaying the round now works once it has finished.
+2015-06-07:
+ Aranclanos:
+ - rscadd: Malfunctioning AIs can preview placement of a Robotic Factory.
+ Iamgoofball:
+ - rscadd: Bicardine, Dexalin, Kelotane, Anti-toxin, Inaprovaline and Tricordrazine
+ have been re-added.
+ RemieRichards:
+ - rscadd: Lizards can now wag their tails, emote *wag to start and *stopwag to stop.
+ kingofkosmos:
+ - tweak: Mops can now be wet from normal buckets and sinks.
+2015-06-08:
+ AnturK:
+ - imageadd: Improved the interface of Spellbooks.
+ Cheridan:
+ - tweak: Push-force from Atmospherics now depends on an entity's weight, heavier
+ objects are less prone to being pushed.
+ - rscadd: Magboots and No-Slip shoes now prevent pushing from spacewind.
+ Firecage:
+ - rscadd: Protolathes can now build Experimental Welding Tools.
+2015-06-09:
+ Aranclanos:
+ - wip: Structures and machines can now be built on shuttles.
+ Iamgoofball:
+ - rscadd: 'Adds the Bluespace Rapid Part Exchange Device: holds up to 400 stock
+ parts and can be used to upgrade machines at range without needing to open their
+ maintenance panel.'
+ - rscadd: A new tier of stock parts have been added, they're very expensive to produce
+ but provide ample improvements.
+ - experiment: Many machines can now also be upgraded.
+ - tweak: 'Emitter: Lasers decrease firing delay and Capacitors decrease power consumption.'
+ - tweak: 'Gibber: Matter Bins increase yield of meat and Manipulators speed up operation
+ time, at high level can gib creatures with clothes.'
+ - tweak: 'Seed Extractor: Matter Bins increase storage and Manipulators multiply
+ seed production.'
+ - tweak: 'Monkey Recycler: Matter Bins increase the amount of monkey cubes produced
+ and Manipulators reduce the monkey-to-cubes ratio to a minimum of 1-to-1.'
+ - tweak: 'Crusher: Matter Bins increase material yield and Manipulators increase
+ chance to yield materials, at high level there is a chance for rarer materials.'
+ - tweak: 'Holopad: Capacitors increase an AI''s traversal range from the holopad.'
+ - tweak: 'Smartfridge: Matter Bins increase storage.'
+ - tweak: 'Processor: Matter Bins increase yield and Manipulators speed up operation
+ time.'
+ - tweak: 'Microwave: Matter Bins increase storage.'
+ - tweak: 'Ore Redemption Machine: Matter Bins increase yield per ore, Lasers increase
+ points per ore and Manipulators speed up operation time.'
+ - tweak: 'Hydroponics Tray: Manipulators improve water and nutrients efficiency.'
+ - tweak: 'Biogenerator: Matter Bins increase storage.'
+ bananacreampie:
+ - rscadd: Added several new options to the ghostform sprites
+2015-06-11:
+ Cheridan:
+ - rscdel: Removes the powerdrain for individiual active modules on cyborgs.
+2015-06-12:
+ Ikarrus:
+ - experiment: Gang Updates
+ - rscadd: 'New objective: To win, Gangs must now buy a Dominator machine (50 influence)
+ and defend it for a varying time frame. * The location of the dominator is + broadcasted to the entire station the moment it is activated * The more territories + the gang controls, the less time it will take * Gangs no longer win by capturing + territories' + - rscadd: A choice of gang outfits are now purchasable for 1 influence each + - rscadd: Thompson SMGs aka "tommy guns" are now purchasable for 50 influence + - rscadd: Bulletproof armor vests are now purchasable for 10 influence + - tweak: Gang messages are now free to send + - tweak: Prices of pistols and pens reduced to 20 and 30, respectively + - tweak: Gang spraycans have been made a lot less obvious. They look nearly identical + to regular ones, now. + - rscdel: Gangs will no longer be notified how much territory the enemy controls + Incoming5643: + - rscadd: Growing tired of reports of slain members, the Wizard Federation has cautiously + sactioned the dark path of lichdom. Beware of the powerful lich who hides his + phylactery well, for he is immortal! + - rscadd: The trick to defeating liches is to destroy either their body or their + phylactery item before they can ressurect to it. The more a lich is slain the + longer it will take him to make use of his phylactery and the more likely the + crew is to catch him during a vunerable moment. + - rscremove: Due to the addition of proper liching, skeletons as a choosable race + from magic mirrors has been discontinued. My apologies to the powergamers. A + special admin version of the mirror that allows for skeletons has also been + added to the code. + Miauw: + - tweak: 'AIs have received several minor nerfs in order to increase antagonist + counterplay:' + - tweak: AI tracking is no longer instant, it takes an amount of time that increases + with distance from the AI eye, up to 4 seconds. The AI detector item will light + up when an AI begins tracking. + - tweak: A random camera failure event has been added, which will break one or two + random cameras. + - tweak: You can no longer keep tracking people that are outside of your camera + vision. + - tweak: Camera wires have been removed. Screwdriver a camera to open the panel, + then use wirecutters to disable it or a multitool to change the focus. + - tweak: You can now hit cameras with items to break them. To repair a camera, simply + open the panel and use wirecutters on it. + - tweak: Camera alerts now only happen after a camera is reactivated. + RemieRichards: + - rscadd: New optional explosion effect ported from /vg/'s DeityLink, Explosions + that are affected by Walls and Doors +2015-06-14: + Ikarrus: + - rscadd: White suits added to gang outfits + - tweak: Gang outfits are now free, but are now limited in stock (that replenishes + over time) + - tweak: While attempting a Hostile Takeover, gangs do not gain influence. Instead, + the takeover timer will be reduced by how many territories they control. + - tweak: Spraycan cost reduced to 5 influence. + - tweak: Recruitment Pen cooldown increased to 2 minutes, but is reduced if the + enemy gang has more members than yours. + - tweak: Tommy guns no longer deal stamina damage. + - rscdel: Gangtools can no longer recall the shuttle if the game mode is not Gang + War +2015-06-15: + Incoming5643: + - rscadd: Lizards can now choose from a wide varity of physical appearances in character + creation! Sprites made by WJohn. Hiss Responsibly. + Kor: + - rscadd: A terrible new creature stalks the halls of SS13. + - rscadd: The wizard has a new artefact related to said creature. + - rscadd: Added a new sepia slime plasma reaction. Try it out! + spasticVerbalizer: + - bugfix: Drones can now properly quick-equip. +2015-06-18: + AnturK: + - rscadd: Added new photo-over-pda function. Apply the photo to PDA to send it with + your next message! + Ikarrus: + - rscadd: Department Management consoles have been added to Head of Staff offices. + These will enable heads to modify ID's access to their department, as well as + preform demotions. + Miauw: + - tweak: Bullets can now damage cameras. + - tweak: Camera alarms now trigger 90 seconds after the first EMP pulse, instead + of when all EMP pulses run out. + - tweak: Makes the force required to damage cameras greater than or equal to ten + instead of greater than ten. + - tweak: Camera alarms now trigger when cameras are disabled with brute force or + bullets. + Xhuis: + - rscadd: Nanotrasen scientists have determined that a delaminating supermatter + shard combining with a gravitational singularity is an extremely bad idea. They + advise keeping the two as far apart as possible. + phil235: + - rscdel: Nerfed the xray gun. Its range is now 15 tiles. +2015-06-20: + Dorsisdwarf: + - tweak: Syndicate Bulldog Shotguns now use slug ammo instead of buckshot by default + - rscadd: Nuke Ops can now buy team grab-bags of bulldog ammo at a discount. + Ikarrus: + - rscadd: Wearing your gang's outfit now increases influence and shortens takeover + time faster. + - rscadd: Added several more options for gang outfits + - rscadd: Pinpointers will now point at active dominators. + - tweak: Gang outfits are now slightly armored + - tweak: Gang tags are now named 'graffiti' to make them harder to detect + - tweak: Initial takeover timer is now capped at 5 minutes (50% control) + - tweak: 'Server Operators: The default Delta Alert texts have changed. Please check + if your game_options.txt is up to date.' + - rscdel: Loyalty implants now treat gangs as it treats cultists. Implants can no + longer deconvert gangsters, but it can still prevent recruitments. + - tweak: Replaced tommy guns with 9mm 2-burst 32 mag uzis that costs 40 influence. + Unlike tommy guns gangs will be able to purchase ammo for uzis. + Jordie0608: + - tweak: 'For Admins: Jump-to-Mob (JMP) notification command replaced with Follow + (FLW).' + - rscadd: Message and Follow links added to many notifications. + - rscadd: New buttons to toggle nuke and set security level. + - spellcheck: Flamethrowers are logged in attack_log. + Thunder12345: + - rscadd: Combat shotguns are now semi automatic, and will be pumped automatically + after firing. + - tweak: Combat shotgun capacity has been reduced to six shells. + Xhuis: + - rscadd: You will now trip over securitrons if you run over them whilst they are + chasing a target. + - rscadd: An admin-spawnable drone dispenser has been added that will automatically + create drone shells when supplied with materials. + - rscadd: Airlock charges are available to traitors and will cause a lethal explosion + on the next person to open the door. + - rscadd: Nuclear operatives can now buy drum magazines for their Bulldog shotguns + filled with lethal poison-filled darts. + - rscadd: When a malfunctioning AI declares Delta, all blue tiles in its core will + begin flashing red. + - rscadd: Back-worn cloaks have been added for all heads except the HoP. LARPers + rejoice! + - rscadd: More suicide messages have been added for a few items. +2015-06-21: + GunHog: + - tweak: The Hostile Lockdown ability for Malfunctioning AIs has been nerfed. It + now costs 30 CPU, is much more obvious, and automatically resets in 90 seconds. + - tweak: Buffed the Upgrade Turrets Malfunction ability. Turrets will now fire heavy + lasers instead of simply shooting faster. + - rscadd: Nanotrasen has released an Artificial Intelligence firmware upgrade under + the ID 41ST0L3MYB1K3. It contains drivers for interacting with all variants + of exosuit technology, from the Ripley APLU design to even experimental Phazon + units. Simply upload your AI to the exosuit's internal computer via the InteliCard + device. Per safety regulations, the exosuit must have maintenance protocols + enabled in order to remove an AI from it. + - rscadd: Malfunctioning AIs may wirelessly steal mechs via a new power, Mech Domination. + For 30 CPU, a Malf AI may permanently upload itself to a mech, ejecting any + pilots. Malf AIs will still lose if they leave the Z-level, and the Malf will + be gibbed if the mech is destroyed - they cannot be carded out of the mech or + shunt to an APC. + Iamgoofball: + - rscdel: Blobs can no longer have Morphine as their chemical. + duncathan: + - tweak: Heat exchangers now update their color to match that of the pipe connected + to them. + - tweak: Heat exchangers are on longer dense. +2015-06-22: + Iamgoofball: + - rscdel: Removed failure chance and delay when emagging an APC. + KorPhaeron: + - tweak: Rebalanced armor to be less effective, reducing the melee, bullet and/or + laser damage reduction of all armor suits. + LaharlMontogmmery: + - rscadd: You can now click and drag a storage container to empty it's contents + into another container, disposal bin or floor tile. + Xhuis: + - experiment: Revenants have received a considerable overhaul. + - rscadd: Revenants will no longer share spawn points with space carp and will spawn + in locations like the morgue and prisoner transfer center. + - rscadd: Revenants can no longer cross tiles covered in holy water. + - rscadd: Revenants have a new ability called Defile for 30E. It will cause robots + to malfunction, holy water over tiles to evaporate, and a few other effects. + - rscadd: Upon death, revenants will appear and play a sound before rapidly fading + away and leaving behind glimmering residue as evidence of their demise. + - rscadd: This residue lingers with the essence of the revenant. If left unattended, + it may reform into a new revenant. Simply scattering it is enough to stop this, + but it also has high research levels. + - rscadd: Revenants now have fluff objectives as well as a set essence goal. + - tweak: Revenanants will be revealed for longer when using abilities and also receive + feedback on this revealing. + - tweak: Revenants can now only spawn via random event with a specific amount of + dead mobs on the station. The default for this is 10. + - bugfix: Revenants can no longer use abilities from inside walls. + - rscdel: Directly lethal abilities have been removed from revenants. In addition, + they can no longer harvest unconscious people, only the dead. +2015-06-23: + Fayrik: + - rscadd: NanoUI is now Telekenesis aware, but due to other constraints, NanoUI + interfaces are read only at a distance. + - tweak: Refactored all NanoUI interfaces to use a more universal proc. + - tweak: Adjusted the refresh time of the NanoUI SubSystem. All interfaces will + update less, but register mouse clicks faster. + - bugfix: Removed automatic updates on atmospheric pumps, canisters and tanks, making + them respond to button clicks much faster. + - bugfix: Atmos alarm reset buttons work now. Probably. + Iamgoofball: + - rscadd: Adds a progress bar when performing actions. + Ikarrus: + - rscadd: New gang names with tags created by Joan + - rscadd: C4 explosive can be purchased by gangs for 10 influence. + - tweak: Recruitment pen cost increased to 50. + - rscadd: Lieutenants recieve one free recruitment pen. + - tweak: Recruitment pens are now stealthy and no longer give a tiny prick message. + - tweak: Increased chance of deconversion with head trauma + - tweak: Recalling the shuttle now takes about a minute to work, during which you + won't be able to use your gangtool. + - rscadd: Pinpointers no longer point at dominators. Instead, dominators will beep + while active. + - rscadd: Added puffer jackets and vests. + - tweak: Increased gang outfit armor. It is moderately resistant to bullets now. + - rscdel: Removed bulletproof vests from gangtool menu. + Jordie0608: + - rscadd: Admins can now flag ckeys to be alerted when they connect to the server. + MrStonedOne: + - rscadd: Admins can now reject poor adminhelps. This will tell the player how to + construct a useful adminhelp and give them back their adminhelp verb + RemieRichards: + - tweak: Cumulative armour damage resistance is now capped at 90%, you will now + always take at bare minimum, 10% of the incoming damage. + - rscadd: Added a system for Armour Penetration to items, it works by temporarily + (It does NOT damage the armour or anything) reducing the armour values by the + AP value during the attack instance. + - rscadd: 'The formula for AP is Armour-ArmourPenetration = AdjustedArmour and AdjustedArmour + is used for all the remaining calculations instead of Armour (Eg: 80 Melee - + 15 AP = 65 Melee).' + - rscadd: The Ninja's Energy Katana has 15 AP, Xenomorphs have an inbuilt AP of + 10. + - tweak: You can now unwrench pipes who's internal pressures are greater than that + of their environment... + - rscadd: However it will throw you away from the pipe at extreme speed! (You are + warned beforehand if the pipe will do this, allowing you to cancel) + Vekter: + - bugfix: Finally fixed immovable rods! They will now properly bisect the station + (and crit anyone unlucky enough to be in their path). + - tweak: Increased Meteor activity detected in the vicinity of the station. Be advised + that many storms may be more violent than they once were. + - rscadd: Gravitational anomalies will now throw items at mobs in their vicinity. + Take care while scanning them. + - rscadd: Flux anomalies explode much more violently now. Get there and destroy + them, or risk losing half a department. + xxalpha: + - rscadd: 'Added a new Reviver implant: now it revives you from unconsciousness + rather than death.' + - rscadd: Added cybernetic implants and a cybernetic implants bundle to the Nuke + Ops uplink. + - bugfix: Fixed Nutriment pump implant printing. + - tweak: Health Analyzers now have the ability to detect cybernetic implants. + - tweak: X-Ray implants are now much harder to unlock. +2015-06-24: + Ikarrus: + - rscadd: Request Console message sent to major departments will now be broadcasted + on that department's radio. + - rscadd: Request Consoles can be used to quicly declare a security, medical, or + engineering emergency. +2015-06-25: + Iamgoofball: + - rscadd: Changes up how Explosive Implants work. + - rscadd: They have become Microbomb Implants. They cost 1 TC each. Each implant + you inject increases the size of the explosion. You gib on usage, regardless + of explosion size. + - rscadd: A Macrobomb implant was added for 20 TC. It is the equivalent of injecting + 20 microbombs. + - rscadd: Nuke Ops start with microbomb implants again. +2015-06-26: + Ikarrus: + - imageadd: Added a couple of new gang tag resprites by Joan. + Kor: + - tweak: Summon Guns has returned to its former glory. The spell will once again + create antagonists, now with the objective to steal as many guns as possible. + - tweak: Summon Guns once again costs a spell point, rather than granting one. + phil235: + - tweak: Buffs traitor stimpack (and adrenalin implant) to be more efficient against + stuns/knockdowns. + pudl: + - rscadd: You can now play games of mastermind to unlock abandoned crates found + throughout space. +2015-06-27: + Ikarrus: + - rscadd: Some objects can be burned now. + - rscadd: Bombs will shred your clothes, with respect to their layering and armor + values. Exterior clothing will shield clothing underneath. Storage items will + drop their contents when bombed this way. + Laharl Montogmmery: + - rscadd: 'Storage Content Transfer : Bluespace Boogaloo! You can now transfer the + content of the BoH/BRPED into tiles/bins/bags out of your reach. Range is 7 + tiles.' + MrStonedOne: + - tweak: Admins will now receive a notification when one of them starts to reply + to an adminhelp to cut down on multiple responses to adminhelps and let admins + know when an adminhelp isn't getting replied to. + - rscadd: The keyword finder in admin helps (adds a (?) link next to player names + in the text of adminhelps) has been added for all player to admin pms, as well + as admin say. + NullQuery: + - wip: Introduces html_interface, a module to streamline the management of browser + windows. + - rscadd: Adds playing cards that utilize a new HTML window management system. + Vekter: + - rscadd: Added a new military jacket to the Autodrobe and ClothesMate. +2015-06-28: + Ikarrus: + - rscadd: Gang Lieutenants can buy gang tools now, but at a higher cost than the + original boss + - rscadd: Gang leaders can register additional gangtools to themselves for use as + spares. + - tweak: Number of maximum lieutenants lowered to 2 + - tweak: Pistol cost increased to 25 influence + - tweak: Uzi cost increased to 50 influence + - tweak: Uzi Ammo decreased to 20 influence + - rscadd: Overcoats added to items the biogenerator can produce. + - rscdel: Micro and Macro bomb implants are now restricted to the Nuclear game mode. + phil235: + - tweak: Smoke (and foam) no longer distribute more reagents than they have. The + amount of clouds in a smoke now depends on the amount of smoke created. Acid + no longer melts items on a mob at low volume, and the chances to melt them increases + with the amount applied on the mob. Sprays can now contain acid again. +2015-06-29: + Ikarrus: + - rscadd: Clothing has been separated out of equipment lockers into wardrobes to + reduce clutter. + Incoming5643: + - rscadd: The secrets of the rainbow slimes have finally been revealed. To attain + this rare blob you must breed a slime with a 100% mutation chance! + - rscadd: Rainbow slime cores will generate a randomly colored slime when injected + with plasma. It's a good plan B if the slimes aren't cooperating in terms of + colors. You can get any color slime this way, pray to the RNG! + Xhuis: + - rscadd: The Sleeping Carp clan has made its presence known on Space Station 13. + Some gangs will name themselves after this group and practice martial arts rather + than using traditional gang weaponry. These shadowboxers are not to be taken + lightly. + oranges: + - tweak: Thanks to a breakthrough in directed vector thrusting, all nanotrasen brand + jetpacks have been greatly improved in speed and handling +2015-07-01: + Ikarrus: + - rscadd: Multiple gang leaders are spawned at round start, the number which depends + on server population + - rscdel: Gangsters can no longer be promoted mid-game. + - rscadd: Security can once again deconvert gangsters with loyalty implants + - rscadd: Added an Implant Breaker item to the gangtool as a purchasable item for + 10 influence each * They are a one-use item that destroys all implants in + the target, including loyalty implants * They will also attempt to recruit + the target before destroying itself + - rscdel: Implanters no longer work if the target is wearing headgear. Remove them + first. + NullQuery: + - tweak: The crew monitoring computer, AI crew monitoring popup and the handheld + crew monitor now update automatically. + - tweak: 'Crew monitoring: The health information has been turned into a health + indicator. It goes from green to red. Hovering over the icon shows detailed + information (if available).' + - tweak: 'Crew monitoring: The location coordinates have been hidden. You can see + them by hovering over the ''Location'' column.' + - rscadd: 'Crew monitoring: A minimap has been added so you can easily see where + people are.' + - tweak: 'Crew monitoring: Players who are not in range of a camera are not shown + on the minimap.' + - tweak: 'Crew monitoring: AI players can quickly move to other locations or track + players by clicking the minimap or items in the table.' + - tweak: 'Crew monitoring: For AI players, health information always shows a white + indicator instead of green-to-red. This is a deliberate limitation to prevent + the AI from becoming too omnipresent.' + phil235: + - tweak: Space drug overdose no longer cause brute/brain damage but you hallucinate + more. Space Drug Blob now makes you hallucinate even if you don't overdose on + its space drug. + xxalpha: + - rscadd: 'Added a new traitor objective: steal the station''s self-destruct nuke + plutonium core.' +2015-07-02: + Ikarrus: + - rscadd: Throwing reagent containers such as drinks or beakers may spill their + contents onto whatever they hit + - rscadd: Slipping while carrying items in your hand may cause ~accidents~ + - tweak: Mounted and portable flashers can now only be burned out from overuse, + similar to flashes. + oranges: + - tweak: Thanks to department budget cuts we've had to remove the security cameras + built into officer helmets, Nanotrasen apologies for this inconvenience. +2015-07-03: + Ikarrus: + - experiment: Added support for up to six gangs at a time. Admins may add additional + gangs to any round. + - experiment: Gang mode now has a chance to start with a third gang. + - rscadd: Promotion of lieutenants have been re-added + - rscadd: Every lieutenant promoted will lengthen the gang's recruitment cooldowns + by one minute. + - rscdel: Only gang bosses will be able to recall the shuttle from their gangtool. + - rscadd: A recruitment pen that has not been used for a while will accumilate charges, + so you are no longer punished for waiting to convert people. + - rscadd: Gangs are now fully functional outside of gang mode. + Ricotez: + - rscadd: 'Added two categories of mutant bodyparts for humans with the same system + that lizards use: ears and tails. Right now only admins can edit these.' + - rscadd: Updated the system that checks for which jobs your character qualifies + to be species-dependant. At this moment you won't notice any differences, but + in the future coders can use this to be more specific about which jobs a species + is allowed in under which circumstances. + - imageadd: 'Added one option to both categories, taken from the kitty ears: a cat + tail and cat ears.' + - rscadd: 'Added a new button to the VV menu drop-down list for admins: Toggle Purrbation. + Putting a human on purrbation will give them cat ears and a cat tail, and send + them the message ''You suddenly feel valid.'' Using the button a second time + removes the effects.' + - wip: 'Adding categories for tattoos and scars is in the works. (Read: I need sprites!)' + oranges: + - tweak: Engineers in nanotrasen's safety equipment department announced the release + of a new and improved version of the X25 taser trigger, previous triggers, which + suffered from a long line of misfire problems were recalled enmasse. Nanotrasen + refused to comment on rumours that the previous trigger design was the work + of a saboteur. +2015-07-04: + Gun Hog: + - tweak: The Ore Redemption Machine now allows users to release minerals without + having to insert an ID first. + Ikarrus: + - bugfix: Fixed items that logically shouldn't spill, spilling their contents when + thrown + - bugfix: Fixed Bartender's non-spilling powers + - bugfix: Fixed thrown beakers not applying their contents onto floors + - bugfix: Fixed unable to transfer reagents between beakers you are holding + - bugfix: Fixed bombs shredding clothes that should have been protected by covering + clothes + - bugfix: Fixed gang mode. + MMMiracles: + - rscadd: Added patriotic underwear apparel due to the most god damn american holiday + being just around the corner. + - rscadd: Also adds some other stuff for those inferior countires too, I guess. +2015-07-05: + AlexanderUlanH & Xhuis: + - rscadd: Shadowling Ascendants have a new ability to send messages to the world. + - bugfix: Glare now properly silences targets. + - bugfix: Veil now turns off held lights. + - tweak: Drain Thralls replaced with Drain Life, which targets all nearby humans. + - rscadd: Spatial Relocation replaced with Black Recuperation which lets you revive + a dead thrall every five minutes. + - rscdel: Removed Vortex. + - tweak: Shadowlings can now only enthrall five people before being forced to hatch; + Hatched shadowlings can continue to enthrall however non-hatched ones can't + pass the global limit. + - tweak: Enthralling sends a message to all nearby humans. + - tweak: Removed cooldown on Glacial Freeze. + Ikarrus: + - tweak: Reactive armor may now teleport user to space tiles. Be careful using it + around space. + Razharas: + - tweak: Firing pins can now be removed by tablecrafting a gun with a plasmacutter, + screwdriver and wirecutters. + RemieRichards: + - imageadd: Melee attacks with weapons now display and animation of the weapon over + the target. + - rscadd: Tablecrafting window now shows all recipies and has been split into categorized + tabs. + - rscdel: 30 item limit removed. + Sabbat: + - rscadd: Updated the cult armor rune to let you get additional equipment or abilities + based on what you're wearing or holding. Some nerfed versions of wizard spells + can be used by the cult in exchange for unique clothing, these spells require + the cult robes or armor in order to use. No armor choices are mandatory, you + will always have the option of the default choice. + - rscadd: Zealot - Default armor rune. If none of the required clothing is worn + this will be chosen automatically. Is the same as ever. + - rscadd: Summoner - If you are wearing the wizard robe and hat when using the armor + rune this choice will be available. User will receive magus robes and hat and + nerfed versions of the summon shard and summon shell spells. + - rscadd: Traveler - Available to people wearing EVA suit and helmet. Replaces the + EVA suit and helmet with the cult space suit and space helmet. Gives you a sword. + - rscadd: Marauder - Available to people wearing the captain's space suit and helmet. + Same as Traveler except user is given a spell of summon creature (two creatures). + They can and will attack the user. + - rscadd: Trickster - Available if wearing the RD's reactive teleport armor. Gives + you magus robes, a wand of doors, and a nerfed version of Blink. + - rscadd: Physician - Available if wearing the CMO's labcoat. Gives you a wand of + life. + TheVekter: + - rscadd: Ian now has a dog-bed in the HoP's office. + nukeop: + - rscadd: Uplinks now have a syndicate surgery bag containing surgery tools, a muzzle, + a straightjacket and a syndicate MMI. + - rscadd: Syndicate MMIs can only be placed in cyborgs to create an unlinked cyborg + with syndicate laws. +2015-07-06: + Ikarrus: + - tweak: Increased Uzi SMG cost to 60 influence. + - tweak: Increased Uzi ammo cost to 40 influence. + - tweak: Domination attempt limit is reduced to 1 per gang while the shuttle is + docked with the station. + - tweak: Gang bosses can promote and recall the shuttle using spare gangtools + - bugfix: Fixed Gang bosses getting deconverted with head trauma + - rscadd: Lizard characters can now get random names unique from humans. +2015-07-07: + Ikarrus: + - bugfix: Fixed bug where gang messages would occasionally fail to send. + - bugfix: Fixed bug that prevented implant breakers from recruiting security. + - tweak: Implanters are now only blocked by helmets with THICKMATERIAL + - rscdel: Light severity explosions no longer shred clothes. + MMMiracles: + - rscadd: Adds a new crate to cargo in the security section, for when desperate + times call for desperate measures. + NullQuery: + - bugfix: Crew monitoring computers now sort by department and rank again. + - tweak: 'Crew monitoring computer: Hovering over a dot on the minimap will now + jump to the appropriate entry in the table.' + - bugfix: sNPCs were given ID cards with blank assignments. +2015-07-09: + AlexanderUlanH: + - rscadd: Riot Shotguns now spawn loaded with rubber pellet shells that deal high + stamina damage. + kingofkosmos: + - tweak: Both beakers and drinking glasses can now be be drunk from, fed to mobs + and splashed on mobs, turfs and most objects with harm intent. + nukeop: + - tweak: RCDs have a larger storage and can be loaded with glass, metal and plasteel. + - rscadd: Grilles and Windows can be made with an RCD. + - rscadd: Engi-Vend machine now has three RCDs. + - rscdel: Removed RCD as a steal objective. +2015-07-10: + Ikarrus: + - rscadd: 'New Changeling Ability: False Armblade Sting. It creates an undroppable + armblade on the target temporarily. It will appear exactly like a real one, + except you can''t do anything with it.' + - tweak: Transform stings are no longer stealthy. +2015-07-11: + Dorsidwarf: + - tweak: Due to a new Syndicate budget, uplink implants are now only 14 TC. + - tweak: In order to facilitate inter-agent communication, Syndicate Encryption + Keys have been reduced to 2TC. They retain the ability to intercept all channels + and speak on a private frequency. + Ikarrus: + - tweak: Robotic augmentations have been made a bit more difficult to maintain. +2015-07-13: + Ikarrus: + - imageadd: Loyalty Implant HUD Icon has been updated. + duncathan: + - tweak: Greatly shortened the time it takes to lay pipes with the RPD and to unwrench + pipes in general. + - rscadd: Added Optical T-Ray scanners to R&D and Atmospheric Technician closets. + Optical T-Ray Scanners function identically to a handheld scanner. +2015-07-14: + AnturK: + - rscadd: New species of mimic was spotted in the wilderness of space. Watch out! + Jordie0608: + - rscadd: Added a Local Narrate verb for admins. +2015-07-17: + Ikarrus: + - bugfix: Virology is no longer all-access. + - rscadd: Changelings now have the ability to swap forms with another being. + - tweak: Halved Domination Time. + - tweak: Reinforced windows and windoors are a bit more resistant to fires and blasts. + MrStonedOne: + - tweak: 'Scrubbers now use power: 10w + 10w for every gas its configured to filter. + (60w for siphon)' + - rscadd: Scrubbers can now be configured to operate on a 3x3 range via the air + alarm at a high cost (ranging from 100w to 1000w depending on how many tiles + are near it that aren't blocked and how much power it's using normally) + - tweak: Huge portable scrubbers (like in toxins storage) now use a 3x3 range rather + then a higher volume rate + - bugfix: Fixed issue with atmos not allowing low levels of plasma to spread + - bugfix: Fixed issue with atmos not adding or removing plasma overlays in some + cases + - tweak: Panic siphon now uses a 3x3 area range rather then increasing the scrubbers + intake rate by 8x + - tweak: Replace air uses 3x3 range for the first stage + - rscadd: 'Air alarms now have 3 new environmental modes:' + - rscadd: Siphon - Panic siphon without the panic, operates on a 1 tile range + - rscadd: Contaminated - Activates all gas filters and 3x3 scrubbing mode + - rscadd: Refill Air - 3 times the normal vent output +2015-07-18: + AlexanderUlanH: + - tweak: Reduced stun duration of tabling to be closer to other stuns. + Iamgoofball: + - tweak: The Bioterror Chemical Sprayer is now filled with a more deadly mix of + chemicals. + RemieRichards: + - tweak: Changelings now regenerate chemicals and geneticdamage while dead, but + only up to specific caps (50% of their max chem storage, and 50 geneticdamage) + - tweak: Fakedeath's length has been reduced from 80s dead (1 minute 20) to 40s + dead + - rscadd: Changelings now get to see the last 8 messages the person they absorbed + said, to allow them to better impersonate their victim's speech patterns + Steelpoint: + - tweak: Reduced weight of Sechailer, it now fits in boxes. + phil: + - tweak: Smoke and foam touch reactions gets buffed. + - rscadd: Reagent dispensers (watertank, fueltank) tells you how much reagents they + have left when examined. + - tweak: Liquid dark matter blob spore smoke now cannot throw you. The effects of + sorium, blob sorium, liquid dark matter and blob liquid dark matter are now + scaled by their volume. Sorium/LDM blob's touch now throws the mobs who are + close but simply moves the mobs that are further away. +2015-07-19: + Gun Hog: + - rscadd: Nanotrasen advancements in cyborg technology now allow for integrated + headlamps! As such, the flashlight package normally used as a module is now + seamlessly merged with their systems! + Ikarrus: + - rscadd: Asimov's subject of "human beings" can now be modified by uploaders. + - rscadd: Eaxmining AI modules while adjacent to them will show you what laws it + will upload. + MMMiracles: + - soundadd: Adds a TWANG sound effect when hitting things with a guitar. +2015-07-20: + AnturK: + - tweak: Lightning Bolt now always bounces 5 times and deals 15 to 50 burn damage + to each target depending on the chargeup + KorPaheron: + - rscadd: Added the Multiverse Sword, a new wizard artifact that can summon clones + of yourself from other universes, allowing for dangerous amounts of recursion. + phil235: + - tweak: Mechs no longer use object verbs and the exosuit interface tab. They now + use action buttons. Mechs now have a cycle equipment action button to change + weapon faster than by using the view stats window. Mechs get two special alerts + when their battery or health is low. Mechs now properly consume energy when + moving and having their lights on. Using a mech tool that takes time to act + now shows a progress bar (e.g. mech drill). + - rscadd: Mechs now have a cycle equipment action button to change weapon faster + than by using the view stats window. + - rscadd: Mechs get two special alerts when their battery or health is low. + - tweak: Mechs now properly consume energy when moving and having their lights on. + - rscadd: Using a mech tool that takes time to act now shows a progress bar (e.g. + mech drill). +2015-07-21: + Fayrik: + - tweak: Syndicate Donksoft gear now costs less. + Xhuis: + - rscadd: Firelocks may now be constructed and deconstructed with standard tools. + Circuit boards can be produced at a standard autolathe. + phil235: + - tweak: Thrown things no longer bounces off walls, unless they're in no gravity. + Heavy items and mobs thrown can push the mobs and non anchored objects they + land on. Throwing a mob onto a mob in no gravity will push each one in opposite + direction. Thrown mobs landing on wall, or dense object or mob gets stunned + and a bit injured. The damage when mob hit a wall is nerfed. +2015-07-23: + NullQuery: + - tweak: 'Crew monitoring: The minimap now supports scaling. You can zoom in and + out using the buttons. Hovering over an entry in the table centers the minimap + on that part of the screen.' + - tweak: 'Crew monitoring: If the window is wide enough the health indicator will + expand to show full health data (if available).' + - tweak: 'Crew monitoring: Clicking on the area name will now copy the coordinates + to your clipboard.' + - tweak: 'Crew monitoring: The AI can view health information again, but there is + a 5 second delay between updates for everyone watching.' + freerealestate: + - rscadd: Added resist hotkeys for borgs and humans. With hotkeys mode, use CTRL+C + or C as a human and CTRL+C, C or END as a borg. With hotkeys mode off, use CTRL+C + as a human and END as a borg. + xxalpha: + - bugfix: Changeling augmented eyesight night vision is now working. +2015-07-24: + Incoming5643: + - rscadd: The spells disintegrate and flesh to stone have had their mechanics changed. + Using these spells will spawn a special touch weapon in a free hand (your dominant + hand if possible) that can then be used to inflict the spell on the target of + your choice. Having the touch weapon out is obvious, this is not a stealth based + change. Clicking the spell while the hand is out will let you return the charge + without using it. + - rscdel: The spell won't begin to recharge until the hand attack is either used + or returned. Additionally these changes mean you can no longer use these spells + while stunned or handcuffed. As a suggestion remember that the mutate spell + allows you to break out of cuffs very easily, and warping abilities will keep + you from getting cuffed to begin with! +2015-07-25: + Dorsisdwarf: + - tweak: Due to a fire sale at Syndicate HQ, many of the more interesting traitor + gadgets have been cut in price dramatically. Please take this opportunity to + make full use, as we cannot guarantee that the sale will last! + bgobandit: + - bugfix: Under pressure from the Animal Rights Consortium, Nanotrasen has improved + conditions at its cat and dog breeding facilities. Cats and pugs are now much + more responsive to their owners. + duncathan: + - tweak: Restores RPD delay on disposals machines. + xxalpha: + - tweak: Agent IDs are now rewrittable. +2015-07-26: + Phil235: + - rscadd: Sechailers will now break when used too often. + - imageadd: Mechs now have new action button sprites. + Steelpoint: + - rscadd: Security Officers now spawn with a security breathmask in their internals + box. + - imageadd: Abductor's batons now changes color with modes. + - imageadd: Unique sprites for Abductor hand cuffs and paper. + goosefraba19: + - imageadd: Updated the Power Monitoring Console with better alignment and colorized + readouts. +2015-07-27: + Bgobandit: + - bugfix: Burgers can now be made from corgi meat again. + Ikarrus: + - rscadd: Added shutters to the armory to allow quick access when needed. + - bugfix: Security can now use the Brig external airlocks. + - rscadd: Added a join queue when the server has exceeded the population cap. + - tweak: Decreased the cost of Body Swap and removed it's genetic damage. + kingofkosmos: + - rscadd: Added a link to re-enter corpse to alert when your body is placed in a + cloning scanner. +2015-07-28: + Anonus: + - imageadd: New gang tags for Omni and Prima gangs. + Chiefwaffles: + - rscadd: After realizing how often AIs tend to 'disappear', Central Command has + authorized the shipment of the Automated Announcement System to take over the + AI's responsibility of announcing new arrivals. + - rscadd: In addition, users are able to configure the messages to their liking. + Early testing has shown that this feature may be vulnerable to malicious external + elements! + - rscadd: The station's R&D software has been updated so it can now succesfully + create its own prototype AAS board once the prerequisite levels have been met. + Dorsisdwarf: + - tweak: Increased the cost of Bioterror darts to 6TC. + Incoming5643: + - experiment: Double Agents no longer know they're Double Agents and not just standard + Traitors. + xxalpha: + - rscdel: Removed Anti-Drop and Nutriment Pump implants from Nuclear Operative's + uplink. +2015-07-29: + AnturK: + - rscadd: Aliens can now mine through asteroid rock. + GunHog: + - tweak: Cyborg headlamps have a short cooldown before reactivation when forcibly + deactivated. + - bugfix: Shadowling's Veil now shuts down headlamps for the ability's entire duration. + Kor: + - rscadd: Eating the heart of a Slaughter Demon will grant you dark powers. + freerealestate: + - bugfix: Fixed bug where copying with ctrl+C didn't work due to it being assigned + to resist. + - rscadd: Changed resist to B (hotkeys mode) and ctrl+B (either mode) instead. + - rscdel: Removed End resist from cyborgs. +2015-07-30: + Gun Hog: + - tweak: The Reactivate Camera power for Malfunctining AIs now costs 10 CPU, and + works on the entire camera network, up to 30 cameras fixed. + - tweak: The Upgrade Cameras power now costs 35 CPU, upgrades all cameras in the + network to have EMP proofing, X-ray, and gives the AI night-vision. + Ikarrus: + - rscadd: Door Access buttons can now be emagged to remove access restrictions. + LordPidey: + - rscadd: Added a new medication, Miner's Salve. It heals brute/burn damage over + time, and has the side effect of making the patient think their wounds are fully + healed. It is mixed with water+iron+oil, or grind a twinkie, a sheet of metal, + and a sheet of plasma. + - rscadd: Added a grinder to the mining station. + Midaychi: + - rscadd: Random loot has been added to the derelict as salvage for drones. + Scones: + - rscadd: Adds a Rice Hat to the biogenerator. +2015-08-02: + Incoming5643: + - rscadd: Syndicate toolboxes now come with never before seen red insulated gloves. + Steelpoint: + - bugfix: Fixed multiple mapping errors for Boxstation and the mining base. + - rscadd: A circuit imprinter and exosuit fabrication board have been added to tech + storage. + SvartaSvansen: + - rscadd: Our lizard engineers have worked hard and managed to improve Centcom airlocks + so they no longer disintegrate when the electronics are removed! + - tweak: Put a safety net in place so future airlocks without assemblies produce + the default assembly instead of disintegrating. +2015-08-04: + Kor: + - rscadd: Soulstones will now attempt to pull ghosts from beyond if the targeted + corpse has no soul. + Summoner99: + - rscadd: Added the *roar emote back to Alien Larva + - bugfix: Fixed aliens not being able to do the *hiss and *screech emotes + - tweak: 'Changed how the plural emote system works and now some emotes have plural + versions, example is: *hiss and *hisses.' +2015-08-05: + CoreOverload: + - rscadd: Implants, implant cases and implanters got RnD levels and can be DA'ed + for science. + - rscadd: Surgically removed implant can be placed into an implant case. Remove + implant with empty implant case in inactive hand. + - rscadd: Surgical steps now got progress bars. + - rscadd: You can cancel a surgery by using drape on operable body part again. This + works only before you perform surgery's first step. + - rscadd: Operating computer shows next step for surgeries. No more alt-tabbing + to view next step on wiki while operating. + - tweak: You cannot start two surgeries on one body part at once. You can start + two multiloc surgeries (i.e. two augumentations) on diffirent body parts at + once. + - tweak: Monkey <-> Human transformations now keep your internal organs, cyberimplants + and xeno embryos included. + Ikarrus: + - rscdel: Head beatings no longer deconvert gangsters. + LordPidey: + - rscadd: 'Added a new chemical. Spray tan. It is made by mixing orange juice with + oil or corn oil. Warning: overexposure may result in orange douchebaggery.' + Xhuis: + - rscadd: Shadowling thralls can now be deconverted via surgery or borging. + - rscadd: Thralls can be revealed by examining them. They can hide this by wearing + a mask. + - rscadd: Thralls have a few minor abilities they can use in addition to night vision. + - rscadd: Hatch-exclusive abilities can no longer be used if you are not the shadowling + mutant race. + - rscadd: Ascendants are now immune to bombs and singularities. Honk. + - rscadd: A Centcom report has been added for shadowlings. + - tweak: Ascending no longer kills all shadowling thralls. This allows antagonists + who were enthralled to succeed along with the ascendants. + - tweak: Annihilate now has different sound and a shorter delay before the target + explodes. In addition, it now works on all mobs, instead of just humans. + - bugfix: Glacial Blast now properly has no cooldown if used while phase shifting. + - bugfix: Fixes a runtime if a target with no mind is enthralled. + bgobandit: + - rscadd: Nanotrasen scientists have achieved the tremendous breakthrough of injecting + gold slime extracts with water. Pets ensued. +2015-08-06: + AnturK: + - rscadd: Adds the voodoo doll as a mining treasure, link it with a victim with + an item previously held by them. + - rscadd: Once linked the voodoo doll can be used to injure, confuse and control + the victim. + Core0verlad: + - tweak: Items can now be removed from storage containers inside storage containers. + - imageadd: Beds and bedsheets have new sprites. + - rscdel: MMIs are no longer ID locked. + KorPhaeron: + - tweak: Slaughter Demon's have had their health reduced to 200 and their speed + reduced but they get a speed boost when exiting blood. + MrPerson: + - rscadd: Items stacks now automatically merge unless thrown when moved onto the + same tile. +2015-08-07: + KorPhaeron: + - rscadd: Added a new Guardian Mob that can be summoned to manifest inside a mob. + - rscadd: Guardians can communicate with their host and materialize themselves to + protect their host with magic powers. + - rscadd: Guardians are invincible but cannot live without or too far from their + host, they also relay injuries they suffer to the host. + Phil235: + - bugfix: Fixed being able to run into your own bullet. + RemieRichards: + - rscadd: You no longer need to click on an item in a storage container to remove + it, clicking anywhere around the item works. + bustygoku: + - rscdel: Removed the chance for a disease to make you a carrier on transfer. + phil235: + - tweak: The plasma cutter's fire rate is now a bit lower but its projectile can + pierce multiple asteroid walls and its range isn't lowered in pressurized environment + anymore. +2015-08-09: + RemieRichards: + - rscadd: 'Nanotrasen Mandatory FunCo Subsidiary: CoderbusGames, would like to announce + an update to Orion Trail!' + - rscadd: 'Spaceports: Buy/Sell Crew, Trade Fuel for Food, Trade Food for Fuel, + Buy Spare Electronics, Engine Parts and Hull Plates, or maybe you think you''re + tough enough to attack the spaceport?' + - rscadd: 'Changelings: Changelings can now sneak into your crew, Changelings eat + double the standard food ration and have a chance to Ambush the rest of the + crew!' + - rscadd: 'Kill Crewmembers: Do you suspect changelings? or dont feel you have enough + food rations? Just shoot somebody in the head, at any time!' +2015-08-12: + CosmicScientist: + - rscadd: Added Space Carp costume to the code, get it from an autodrobe near you. + - rscadd: Added Ian costume to the code, take his place under the HoP's hand, get + it from an autodrobe or corgi hide, keep it away from washing machines or it'll + meat its end as clothing. + - rscadd: Added Space Carp spacesuit to the code, I know what I'm praying for. + bgobandit: + - rscadd: After multiple complaints from WaffleCo food activists, Nanotrasen has + added real chocolate, berry juice and blue flavouring to its ice cream products. +2015-08-13: + CoreOverload: + - rscadd: 'Added a new 8TC traitor item: subspace storage implant. It allows you + to store two box-sized items in (almost) undetectable storage. ' + - tweak: Changed the way most of the surgical operations work. See wiki for new + steps. + - tweak: You can cancel step 2+ surgeries with drapes and cautery in inactive hand. + - tweak: Defib no longer works on humans who have no heart. Changeling/thrall/cult/strange + reagent revives are still working, and this is intended. + - rscadd: You can eat all organs raw now, with exception for brains and cyberimplants. + - rscadd: Some xenos abilities are linked to their organs. Play with xenos' guts + for fun and profit! + RemieRichards: + - rscadd: Modifying a string (Text) variable with View Variables or View Variables + Mass Modify now allows you to embed variables like real byond strings, For example + the variable real_name; you could set a text var to [real_name] and it would + be replaced with the actual contents of the var, This allows for Mass fixing + of certain variables but it's also useful for badmin gimmickery +2015-08-15: + Miauw: + - rscadd: Changeling transformations have been upgraded to also include clothing + instead of just DNA. + - tweak: Patches no longer work on dead people. + - rscadd: Added 15-force edaggers that function like pens when off. + MrPerson: + - rscadd: Objects being dragged will no longer get shoved out of your grasp by space + wind. Retrieving dead bodies should be possible. + RemieRichards: + - rscadd: Added Changeling Team Objectives, these are handed out to all lings, with + the chance of a round having one being 20*number_of_lings% (3 lings = 60%) + - rscadd: 'Impersonate Department (Team Objective): As many members of a department + as can reasonably be picked are chosen for the lings to kill, replace and escape + as' + - rscadd: 'Impersonate Heads (Team Objective): 3 to 6 Heads of Staff are chosen + for the lings to kill, replace and escape as' + - tweak: If the Changelings have a Team Objective, their usual Kill, Maroon, Etc. + objectives will not pick other changelings, to discourage backstabbing in teamling + - tweak: Changeling Engorged Glands is now the default storage and regen rate, Engorged + Glands remains for an extra boost + - rscadd: Armblades can now be used to open powered doors, however it takes 10 seconds + of the changeling standing still, Their ability to instantly open unpowered + doors remains unchanged + - rscdel: Debrain objective is no longer handed out to lings, it's as good as broken + these days + - rscadd: Changelings may now purchase a togglable version of the Chameleon Skin + genetics mutation, for 2 DNA +2015-08-16: + Joan: + - rscadd: Revenants will now occasionally spawn as an event. + - tweak: Revenants gain more energy from Harvesting, and can Harvest from people + in crit. + - tweak: Revenant powers are more effective, and no longer freeze you in place, + besides Harvest. + - tweak: Slain Revenants will respawn much faster. + - bugfix: Fixed a whole bunch of revenant bugs, including one that caused the objective + to always fail. + Kor: + - rscadd: The wizard can now stop time. + MMMiracles: + - tweak: Revamps bioterror darts into a less-lethal, syringe form. Removed the coniine + and spore toxins to keep it solely for quiet take-downs. +2015-08-18: + CoreOverload: + - rscadd: Added a new low-tech eye cyberimplant in RnD - welding shield implant. + - rscadd: Implanter and empty implant case added to protolathe. + - rscadd: You can sell tech disks and maxed reliability design disks in cargo for + supply points. + - tweak: DA menu shows current research levels. + - tweak: You can print cyberimplants in updated mech fab. + Supermichael777: + - bugfix: Added an ooc hotkey for borgs = O. They simply didn't have one and it + was a consistency issue + - rscadd: Also added Ctrl+O as an any mode keycombo so you dont have to backspace + and type ooc. Added to hotkey mode to remain consistent with all other Ctrl + combos + bustygoku: + - tweak: Most backpacks now have 21 or more slots, but are still weight restricted. + What this means is that you can have a lot of tiny weight items, but only 7 + medium items just like before. + phil235: + - tweak: Janicart rider no longer slip on wet floor or bananas. Moving on a floor + tile with lube while buckled (chair, roller bed, etc) will make you fall off. +2015-08-19: + Joan: + - rscadd: Added a new revenant ability; Malfunction. It does bad stuff to machines. + - tweak: Defile and Overload Lights now briefly stun the revenant. + - tweak: You can now Harvest a target by clicking on them while next to them. + - bugfix: Harvesting no longer leaves you draining if the target is deleted mid-drain + attempt. + - rscdel: Defile no longer emags bots or disables cyborgs, Malfunction does that + now. + Kor: + - rscadd: The Ranged and Scout guardian types have been merged, and gained a new + surveillance snare ability. + SconesC: + - rscadd: Added Military Belts to traitor uplinks. + bgobandit: + - rscadd: CentComm now offers its cargo department toys, as well as detective gear + so their boss can figure out which tech wasted all the points on them. + phil235: + - rscadd: You can now partially protect yourself from blob attack effects by wearing + impermeable clothes like hardsuits, medical clothes, masks, etc. Max protection + effect is capped at 50%. + - rscdel: Splashing someone with chemicals no longer injects those chemicals in + their body. + - bugfix: Fixes splashing acid on items or floor with items not having any effect. +2015-08-28: + bgobandit: + - bugfix: 'Overheard at CentComm: ''This burn kit said salicyclic acid would heal + my burns! WHO MADE THIS SHIT?'' A muffled honking is heard in the background. + (Burn first-aid kits now contain an appropriate burn pill.)' + - rscadd: Oxandrolone, a new burn healing medication, has been added to burn first-aid + kits and to chemistry. Ingesting 25 units or more causes burn and brute damage. +2015-09-01: + Dorsidwarf: + - tweak: Changelings' Digital Camoflague ability now renders them totally invisible + to the AI + ExcessiveUseOfCobblestone: + - rscadd: Added health analyzer to the autolathe. + - tweak: Moved Cloning board to Medical Machinery section. + - tweak: Moved Telesci stuff to Teleporter section. + Fox P McCloud: + - tweak: Adds the emitter board to to the circuit imprinter for R&D. + Gun Hog: + - tweak: The Disable RCD Malfunction power is now Destroy RCDs! It costs 25 CPU + (down from 50), causes RCDs to explode, can be used multiple times, and no longer + affects cyborgs. + Kor: + - rscadd: Revheads and Gang leaders now spawn with chameleon security HUDs, for + keeping track of loyalty implanted crew. + - rscadd: Syndicate thermals now have a chameleon function as well, allowing you + to disguise the goggles to match your job. + Miauw: + - tweak: Edaggers actually work now and have been buffed to 18 brute and 2 TC. + Oisin100: + - rscadd: Nanotransen discover ancient human knowledge confirming that trees produce + Oxygen From Carbon Dioxide + - tweak: Trees now require Oxygen to live. And will die in extreme temperatures + Xhuis: + - rscadd: The arcade machines have been stocked with a xenomorph action figure that + comes with realistic sounds! + - rscadd: Darksight now has its own icon. + - rscadd: Empowered thralls have been added. While obvious, they are more powerful + and can resist dethralling while conscious. Only 5 can exist at one time. + - rscadd: Shadowlings can now change their night vision radius by using the action + button their eyes (glasses) now provide. + - tweak: Torches are dimmer, being as bright as flashlights, and no longer fit on + belts. + - tweak: Black Recuperation now has a 1 minute cooldown, down from 5. It can also + be used to empower living thralls. + - tweak: Guise can now be used outside of darkness and makes the user more invisible + than before. + - bugfix: Enthrall now functions properly when a shadowling is not hatched, allowing + them to enthrall up to 5 people before hatching. + xxalpha: + - tweak: Blood crawling is now a spell. + - rscadd: Engineering cyborgs now have a constant magpulse. + - tweak: Changed foam spreading to be like gas spreading. +2015-09-05: + Shadowlight213: + - rscadd: The syndicate have taken notice of the camera bug's woeful underuse, and + have managed to combine all of its upgrades into one! +2015-09-06: + Fox P McCloud: + - bugfix: Fixes gold sheets having plasma as their material. + Xhuis: + - bugfix: Nanotrasen inspectors have discovered a fault in the buckles of chairs + and beds. This has been fixed and you are now able to buckle again. +2015-09-07: + xxalpha: + - tweak: Changed xeno weed spread to be like gas spread. +2015-09-09: + Joan: + - rscadd: New blob chemical; Cryogenic Liquid. Cools down targets. + - tweak: Tweaked names, colors, and effects of remaining blob chemicals; + - tweak: Skin Ripper is now Ripping Tendrils and does minor stamina damage, in addition + to the brute damage. + - tweak: Toxic Goop is now Envenomed Filaments and injects targets with spore toxin + and causes hallucinations, in addition to the toxin damage. + - tweak: Lung Destroying Toxin is now Lexorin Jelly and does brute damage instead + of toxin damage. The oxygen loss it causes can also no longer crit you in one + hit. + - tweak: Explosive Gelatin is now Kinetic Gelatin and does random brute damage, + instead of randomly exploding targets. + - rscdel: Skin Melter, Radioactive Liquid, Omnizine, and Space Drugs blob chemicals + are gone. + bgobandit: + - rscadd: Nanotrasen has commissioned two new corporate motivational posters for + your perusal and edification. + - rscadd: Nanotrasen also wishes to remind the crew that non-authorized posters + ARE CONTRABAND. Especially those new ones with Rule 34. Perverts. +2015-09-11: + CosmicScientist: + - tweak: Drone dispenser now has a var for its cooldown, get var editing. +2015-09-13: + Fox P McCloud: + - bugfix: Fixes an exploit and inconsistency issue with a few material amounts on + a few items and designs. + - bugfix: Fixes Bibles/holy books not properly revealing runes. + - bugfix: fixes stimulants not properly applying its speedbuff. + Gun Hog: + - tweak: Nanotrasen scientists have proposed a refined prototype design for the + nuclear powered Advanced Energy guns to include a taser function along with + the disable and kill modes. Addtionally, they have modified the chassis blueprint + to include a hardpoint for attachable seclites. + Iamgoofball: + - tweak: Reduced the cost of changeling armor to 1 and increased it's armor values. + Jordie0608: + - rscadd: You can now view the reason of a jobban from character setup. + xxalpha: + - rscadd: Drying agent splashed on galoshes will turn them into absorbent galoshes + that dry wet floors they walk on. + - rscadd: Drying agent can be made with ethanol, sodium and stable plasma. +2015-09-14: + Fox P McCloud: + - tweak: Adds a mining voucher to the Quartermaster's locker. + Thunder12345: + - rscadd: The captain has been issued with a new jacket for formal occasions. + - tweak: Research has shown that is is possible to build technological shotshells + without the need for silver. The design blueprints supplied to your station + have been updated accordingly. + xxalpha: + - bugfix: Fixed not being able to grab things from storage while inside aliens. + - bugfix: Fixed two progress bars when devouring. + - rscadd: Shields will now block alien hunter pounces. + - tweak: Alien hunters health reduced to 125 from 150. Alien sentinels health increased + to 150 from 125. + - tweak: Alien hunters will no longer be transparent when stalking, this ability + was given to alien sentinels. + - tweak: Alien slashing now deals constant 20 damage but has a chance to miss. + - tweak: Reduced alien disarm stun duration vs cyborgs, from 7 seconds to 2 seconds. + - tweak: Alien sentinels now move as fast as humans. + - tweak: Facehuggers and alien eggs layers increased to be higher than resin walls. +2015-09-16: + Razharas: + - tweak: Replaces the space cube with space torus. Space levels are now each round + randomly placed on the grid with at least one neigbour, any side of the space + level that doesnt have neigbour will loop either onto itself or onto the opposite + side of the furthest straight-connected space level on the same axis. + Supermichael777: + - tweak: The detomax pda cartridge no longer blows its user up. + Xhuis: + - experimental: Cultists will now be able to create all runes without needing to + research or collect words. This is subject to change. + - tweak: Cult code has been significantly improved and will run much faster and + be more responsive. + - tweak: Conversion runes can now be invoked with less than three cultists, but + take a small amount of time to convert the target. + - tweak: Armor runes will only outfit the user with standard armor, rather than + having different loadouts for different worn clothing items. + - tweak: Astral Journey runes will now pull the user back to the rune if they are + moved. The user also has a different color while on the rune. + - tweak: Free Cultist has been removed. Summon Cultist now works even if the target + is restrained. + - tweak: Sacrifice and Raise Dead runes now offer more precise target selection. + - soundadd: Sacrifice runes now have different sounds, and gib rather than dust + (assuming the target is not a silicon). + - tweak: There is no longer a maximum cap on active runes. + - tweak: Runes have been renamed to Rites. For instance, the Teleport rune is now + the Rite of Translocation. The only exception to this is the rune to summon + Nar-Sie, which is a Ritual. + - tweak: Nar-Sie now has a new summon sound. + - tweak: The Nar-Sie summon rune has a new 3x3 sprite. + - tweak: The stun rune no longer stuns cultists. + - rscadd: The Rite of False Truths had been added, that will make all nearby runes + appear as if they were drawn in crayon. + - rscadd: Runes can now be examined by cultists to determine their name, function, + and words. + phil235: + - tweak: Riot and energy shield users now have a chance to block things thrown at + them as well as xeno leaping at them. +2015-09-17: + bgobandit: + - rscadd: Meatspikes can now be constructed and deconstructed with metal and rods, + as well as wrenched and unwrenched! Humans and corgis can be used on them as + well. + xxalpha: + - tweak: 'Reworked nuke deconstruction: Standardized steps, partial reparation (use + metal) to contain radiation.' + - rscadd: New portable nuke, self-destruct terminal, syndie screwdriver sprites + by WJohnston. +2015-09-19: + Xhuis: + - rscadd: Shadowlings are now able to sacrifice a thrall to extend the shuttle timer + by 15 minutes. This will not stack. + - bugfix: Additional abilities granted by Collective Mind will now properly have + icons. + - bugfix: Shadowlings now have their antagonism removed if turned into a silicon. + - tweak: The order of abilities unlocked by Collective Mind has been changed. It + now starts with Sonic Screech. + - tweak: Veil now destroys glowshrooms in a much larger radius than before. +2015-09-20: + Xhuis: + - tweak: Rites have been renamed to their old runes, which reflect their functionality. + - tweak: Examining a talisman no longer opens the paper GUI. + - tweak: Armor talismans have been re-added. + - tweak: EMP talismans now have the same range as their rune counterpart. + - tweak: Some talismans now cost health to use, costing more or less depending on + their effect. + - tweak: Scribing runes now deals 0.1 brute damage instead of 1. + - tweak: Bind Talisman runes no longer deal 5 brute damage when invoking. + - tweak: Rune shapes and colors are now identical to their old versions. + - tweak: Conversion runes can no longer be used by yourself, and require a static + 2 cultists. +2015-09-22: + Kor: + - rscadd: A new admin command, Offer Control to Ghosts, can be found in the view + variables menu. It will randomly select a willing candidate from among dead + players, providing a fair method of replacing antagonists. + Xhuis: + - tweak: When a morph changes form, a message is shown to nearby people. This also + happens upon undisguising. + - tweak: Morphs now have an attack sound and message. + - tweak: The Spawn Morph event now plays a sound to the chosen candidate. + - tweak: Slaughter demons (and other creatures with blood crawl) now take two seconds + to emerge from blood pools. Entering is still instantaneous. + - tweak: The demon heart's sprite has been updated. + - tweak: Eating a demon heart now surgically implants the heart into your chest. + If the heart is removed from you, you lose the ability. Someone else can eat + the heart to gain the ability. + - tweak: Blood Crawl no longer has a 1-second cooldown, instead having none. + - tweak: You can no longer hold items when attempting to Blood Crawl, nor can you + use any items while Blood Crawling. + - tweak: Creatures that can Blood Crawl now take two seconds to emerge from blood + pools. + - tweak: Slaughter demons now store devoured creatures, and will drop them upon + death. + - tweak: Revenants now have the ability to speak to the dead. + - tweak: Revenant abilities now have icons. + - tweak: Malfunction no longer EMPs a specific area - it will instead EMP nearby + machines directly and stun cyborgs. Dominators are immune to this. + - tweak: Revenants now have directional sprites. + - tweak: Overload Lights now has a smaller radius. + - tweak: Defile no longer corrupts tiles. + - tweak: When glimmering residue reforms, the game will attempt to place the old + revenant in control of the new one. If this cannot be done, it will find a random + candidate. + - tweak: Revenants can no longer see ghosts. They can see other revenants, however, + and ghosts can still see revenants. + - tweak: The Spawn Slaughter Demon event now plays a sound to the chosen candidate. + phil235: + - rscdel: Lizards and other non human species can no longer acquire the hulk mutation. + Hulks no longer have red eyes + - bugfix: Monkeys now always have dna and a blood type (compatible with humans). + - bugfix: Monkey transformation no longer deletes the human's clothes. + - bugfix: Space Retrovirus now correctly transfers dna SE to the infected human. + - bugfix: Changeling's Anatomic Panacea removes alien embryo again. + - bugfix: Cloning someone now correctly sets up their dna UE. + - bugfix: Fixes the laser eyes mutation not giving glowing red eyes to the human. + - bugfix: Using changeling readaptation now properly removes all evolutions bought + (arm blade, chameleon skin, organic suit). + xxalpha: + - rscadd: Added a researchable cyborg self-repair module to the robotics fabricator. +2015-09-23: + Xhuis: + - rscadd: Syndicate medical cyborgs have been added. + - rscadd: The Dart Pistol is now available from the uplink for 4 telecrystals. It + functions as a pocket-sized syringe gun with a quieter firing sound. + - tweak: Boxes of riot foam darts now cost 2 telecrystals, down from 10, and are + available to traitors. + - tweak: Foam dart pistols now cost 3 telecrystals, down from 6. + - tweak: Syndicate cyborg teleporters now allow a choice between Assault and Medical + cyborgs. + - tweak: Syndicate cyborgs are now distinguished as Syndicate Assault. + - tweak: Syndicate cyborg energy swords now cost 50 energy per use, down from 500. + - tweak: Airlock charges now cost 2 telecrystals, down from 5. + - tweak: Airlock charges are much more powerful. + - tweak: There is no longer a 25% chance to detonate an airlock charge while removing + it. + - tweak: The description of many uplink items has been changed to better reflect + their use. +2015-09-24: + Jordie0608: + - tweak: Advanced energy guns now only critically fail after successive minor failures. + Cease firing after multiple recent minor failures to avoid critical ones. + Kor: + - rscadd: Guardian Spirit types and powers have been heavily reworked. Full details + of each type are available on the wiki. + - rscadd: Guardian damage transfer to users now deals cloneloss if their user is + in crit. + - rscadd: Guardians are now undergoing a trial run in the traitor uplink, under + the name of Holoparasites. + - rscadd: You can now hang human mobs (dead or alive) from meatspikes. Escaping + the meatspike will further damage the victim. + - rscdel: You can no longer slam humans into the meatspike as an attack. +2015-09-25: + Xhuis: + - rscadd: Changelings have a new ablity, Biodegrade. Costing 30 chemicals and having + an unlock cost of 1, it allows them to dissolve handcuffs and straight jackets + in 3 seconds, and escape from lockers in 7. + - tweak: Fleshmend's effectiveness is now halved each time it is used in a short + time span. + - tweak: Last Resort now blinds and confuses nearby humans and briefly disables + silicons upon use. + - tweak: Headslugs now have 50 health, up from 20. +2015-09-26: + MMMiracles: + - rscadd: Nanotrasen's genetic researchers have rediscovered the inactive dwarfism + genetic defect inside all bipedal humanoids. Suffer not the short to live. + WJohnston: + - tweak: Repiped the entire station. Atmosia and the disposals loop were not touched. + - tweak: Moved mulebot delivery from misc lab to RnD. +2015-09-28: + Feemjmeem: + - bugfix: Rechargers can now be wrenched and unwrenched by cyborgs. + - bugfix: Rechargers no longer stop working forever if you move them from an unpowered + area to a powered area, and now actually look powered off when they are. + - bugfix: Guns and batons can no longer be placed in unwrenched chargers. + Razharas: + - rscadd: Added button to preferences menu that kills all currently playing sounds + when pressed, now you can kill midis and any other sounds for real. + phil235: + - bugfix: Fixed the syndicate cyborg's grenade launcher. + - tweak: You can modify the dna of corpses again. +2015-09-29: + Kor: + - bugfix: The Chaos holoparasite can now actually set people on fire properly. + - tweak: Guardian powers are now used via alt+click rather than shift+click. + - tweak: Added an alert chime for ghosts when someone is summoning a Guardian. +2015-10-04: + Fox P McCloud: + - tweak: Adds a bar of soap to the janitor's locker. + - rscadd: Re-adds the advanced mop as a researchable R&D item. + - rscadd: Adds a bluespace trashbag as a researchable R&D item; can hold large quantities + of garbage. + Jordie0608: + - rscadd: Added Special Verb 'Create Poll', an in-game interface to create server + polls for admins with +permissions. + MrPerson: + - rscdel: Removed NTSL. Sorry. People could write scripts that crashed the server, + and this is the only thing that can be done to prevent them from doing that. + MrStonedOne: + - rscdel: Removed feature where quick consecutive ghost orbits while moving could + be used to fuck with your sprite + - bugfix: Fixed ghosts losing floating animation when returning from an orbit + - bugfix: Fixed logic error that prevented orbit's automatic cancel when the orbiting + thing moved in certain situations. + - rscadd: Ghost Orbit size now changes based on the icon size of the thing they + are orbiting (for that sweet sweet singulo orbiting action) + - tweak: Removed needless checks in ghost orbit, you can now orbit yourself and + restart an orbit around the thing you are already orbiting + Xhuis: + - rscadd: Syndicate Medical cyborgs now have cryptographic sequencers. + - rscdel: Syndicate Medical cyborgs no longer have syringes. + - tweak: Restorative Nanites now heal much more damage per type. + - bugfix: Operative pinpointers now actually point toward the nearest operative. + - bugfix: Syndicate Assault cyborgs no longer start with medical supplies. + - bugfix: Energy saws now have a proper icon. + - bugfix: Non-operatives can now longer use operative pinpointers or Syndicate cyborg + teleporters. + - tweak: Doctor's Delight now requires cryoxadone in its recipe instead of omnizine. + - tweak: Doctor's Delight now restores half a point of brute, burn, toxin, and oxygen + damage per tick. + - tweak: Doctor's Delight now drains nutrition while it's in your system (that is, + unless you're a doctor). + - bugfix: Syndicate roboticists have given Syndicate medical cyborgs sharper hypospray + needles - they are now able to penetrate armor. +2015-10-06: + Gun Hog, for WJohnston: + - rscadd: 'Add new Xenomorph caste: The Praetorian. Drones may become this on their + way to growing into a full queen, and a queen may promote one if there is not + one already.' + - tweak: Xenomorph queens are now GIGANTIC, along with the new Praetorian. Together, + they are considered royals. + - tweak: Queens are now significantly tougher to make up for their huge size. + - bugfix: All forms of dead xenomorph may now be grabbed and placed on a surgery + table for organ harvesting! + Xhuis: + - rscadd: Maintenance drones now have a more descriptive message when examined. + - tweak: A recent Nanotrasen firmware update to drones has increased vulnerability + to foreign influences. Please periodically check drones for abnormal behavior + or status LED malfunction. Note, however, that cryptographic sequencers will + not incur this behavior. + - tweak: In response to complaints about rogue drones, Nanotrasen engineers have + allowed factory resets on all drones by simply using a wrench. + - experiment: Central Command reminds drones to immediately retreat, if possible, + when a law override is begun. Not doing so may anger the gods and incur their + wrath! + - rscadd: Some virus symptoms that had no messages now have them. + - rscadd: 'New virology symptom: Weakness. This will cause stamina damage and fainting + spells.' + - tweak: Many virus symptom messages have been changed to be more threatening. +2015-10-07: + Kor: + - rscadd: The alien queen can now perform a tail sweep attack, throwing back and + stunning all nearby foes. +2015-10-13: + AnturK: + - rscadd: Display cases can now be built using 5 wood planks and 10 glass sheets. + - rscadd: Add airlock electronics to open it with id later, otherwise you'll have + to use crowbar + - tweak: Broken display cases can be fixed with glass sheets or removed using crowbar + - tweak: Added start_showpiece_type variable for mappers to create custom displays + - rscadd: Syndicate Lone Operatives spotted near the nanotrasen stations! Keep the + disk safe! + - tweak: Admin spawned nuclear operatives will now have access to nukeop equipment + Gun Hog: + - rscadd: Nanotrasen's research team has released a new, high tech design for Science + Goggles, which previously did nothing! They new come fitted with a portable + scanning module which will display the potential research data gained from experimenting + with an object. Nanotrasen has also released drivers which shall enable the + prototype hardsuit's built in scan visor. + - rscadd: Supporting this new design, Nanotrasen has seen fit to provide blueprints + for Science Goggles to the station's protolathe. + Kor: + - tweak: Gang implanters now only break implants/deconvert gangsters, meaning you + will have to use a pen to convert them afterwards. + - rscadd: An important function, accessible via alt+click, has been restored to + the detectives hat. + - sounddel: When Nar-Sie is created, they now use the old sound effect. + Steelpoint: + - rscadd: The Chief Medical Officers 'Medical Hardsuit' has been added to the CMO's + office. Boasts the usage of lightweight materials allowing fast movement while + wearing the suit as well as complete biological protection to airborne and similar + pathogens. + - rscadd: The Head of Security's personal 'HoS Hardsuit' has been added to the HoS's + office. This Hardsuit is slightly more armored than the regular Security Hardsuit. + - rscadd: The Research Directors 'Prototype Hardsuit' has been added to the RD's + office. This Hardsuit offers the highest levels of protection against explosive, + as well as biological, attacks, as well as fireproofing. + - rscdel: The Command EVA space suits, due to budget concerns, have been removed + and reloacted to another space station. + Xhuis: + - rscdel: All instances of autorifles have been removed from Security. + - rscadd: The armory has been re-mapped. + - tweak: The spell book has received a rebalancing! There are now ten uses by default, + but most spells cost two uses. Some underused spells, like Blind, Smoke, and + Forcewall, only cost a single use. + - experiment: After searching through the Sleeping Carp's ancient monastery in deep + space, more secrets have been uncovered of their traditional fighting techniques. + - tweak: Members of the Sleeping Carp gang are now able to deflect all ranged projectiles. + - tweak: Members of the Sleeping Carp gang are now uanble to use any type of ranged + weaponry. Doing so would be dishonorable. + - tweak: The Sleeping Carp martial art's effects are more damaging, and many stuns + have been increased in duration. + phil235: + - bugfix: Fixes critical bug causing multiple hits from single projectile. + - bugfix: Fixes not being able to shoot a mob on same tile as the shooter. + - bugfix: Clicking your mob (without targeting your mouth) no longer causes you + to shoot yourself. + - bugfix: Fixes not being able to shoot non human mobs at point blank. + - rscdel: Morphs no longer automatically drop the things they swallowed, you have + to butcher their corpse to retrieve their contents. + - bugfix: butchering a corpse no longer also attacks it. + - rscdel: Dipping cigarette (to asbsorb liquids) in a glass can now only be done + with an unlit cigarette. Lit cigarette now heats up the glass content (like + other heat sources). + - bugfix: Fixes trashbag not being able to pickup drinks and ammo casings. + - tweak: Slimes now attaches themselves to mobs via buckling. +2015-10-16: + MrStonedOne: + - rscadd: Added a reconnect option to the file menu. This will allow you to reconnect + to the game server without closing and re-opening the game window. This should + also prevent another byond ad from playing during reconnections. + Xhuis: + - rscadd: A gamebreaking bug has been fixed with buckets. You can now wear them + on your head. + bgobandit: + - rscadd: The Grape Growers Consortium has complained that Nanotrasen kitchens do + not use their products enough. HQ has come up with a few recipes to pacify them. + Goddamn winos. +2015-10-19: + AnturK: + - rscadd: Handheld T-Ray Scanners now detect critters in pipes. + Kor: + - tweak: Weapons and projectiles that are armour piercing now have an increased + chance to bypass riot shields. + - tweak: Slipping on lube now deals slightly more damage, but is concentrated on + a random body part, rather than spread to your entire body. + - tweak: Slipping on water no longer deals damage + - rscadd: You can now attach grenades and C4 to spears to create explosive lances. + This is done via table crafting. Alt+click the spear to set a war cry. + Shadowlight213: + - rscadd: In response to reports of stranded drones, Nanotrasen has added magnets + to drone legs. They are no longer affected by lack of gravity or spacewind! + - bugfix: Drones can now set Airlock access on RCDs. + bgobandit: + - rscadd: Nanotrasen loves recycling! In the highly unlikely occasion that your + space station accumulates gibs, scoop 'em up and bring them to chemistry to + recycle into soap, candles, or even delicious meat product! + - rscadd: L3 biohazard closets now contain bio-bag satchels for the safe collection + of biowaste products, such as slime extracts. + phil235: + - rscdel: Removing Smile, Swedish, Chav and Elvis mutations from genetics. These + mutation can still be acquired via adminspawned dna injector. + - rscadd: Added a dna injector for laser eyes mutation for admin use. + - bugfix: Fixes winter coat hood sprite appearing as a bucket. + - bugfix: Fixes using razor on non human shaving non existent hair. + - bugfix: Fixes chair deconstruction dropping too much metal. + - bugfix: Fixes snapcorn not giving seeds. + - bugfix: Fixes portable chem dispenser. + - tweak: Changing the transfer amount of all reagent containers (beaker, bucket, + glass) is now done by clicking them, similar to spray. Reagent dispensers (watertank, + fueltank, pepperspray dispenser) no longer have their own transfer amounts and + use the reagent container's transfer amount instead (except for sprays which + get 50u for faster refilling). +2015-10-23: + Incoming5643: + - rscadd: 'Syndicate bomb payloads will now detonate if set on fire long enough. + Note that the casings for the bombs is fireproof, so if you want to set fire + to a bombcore you''ll need to remove it from the case first (cut all wires, + then crowbar it out). A reassurance from our explosives department: it is, and + always has been, impossible to detonate a syndicate bomb that isn''t ticking + with wirecutters alone.' + Xhuis: + - rscadd: Geiger counters have been added and are obtainable from autolathes and + EngiVends. They will measure the severity of radiation pulses while in your + pockets, belt, or hands. One can scan a mob's radiation level by switching to + Help intent and clicking on it. These counters never really discard the radiation + they store, and rumor has it this can be used in nefarious ways... + - tweak: When a mob is impacted by radiation, the radiation is now relayed to all + items on the mob. +2015-10-24: + Kor: + - rscadd: The friendly gold slime reaction now spawns three mobs. + phil235: + - tweak: Changed the effects of alcohol to be more realistic. The effects of alcohol + now appear twice as fast. Drunkenness now scales with how much alcohol is in + you, not how long you've been drinking. This means drinking very little but + continuously no longer makes you very drunk, or confused/slurring for a long + time or give you alcohol poisoning. The dizziness and slurring effects now properly + scale with how drunk you are (and dizziness is generally more pronounced). +2015-10-25: + Incoming5643: + - rscadd: The spell Charge has been added to the spellbook. It can be used to extend + the life of magic and energy weapons and even reset the cooldowns of held wizards! + It cannot reset your own cooldowns. + - rscadd: The Staff of Healing has been added to the spellbook. Heals all damage + and raises the dead! Can't be used on yourself however. + - bugfix: The exploit that allowed you to use the staff of healing on yourself by + suicide has been fixed. + Jordie0608: + - rscadd: You can now selectively mute non-admin players from OOC with the Ignore + verb in the OOC tab. + Tkdrg: + - rscadd: Added chainsaws. They can be tablecrafted using a circular saw, a plasteel + sheet, some cable coil, and a welding tool. Don't forget to turn it on! +2015-10-26: + Fox P McCloud: + - tweak: Standardizes the slowdown of most spacesuits to 1 as opposed to 2. + Incoming5643: + - rscadd: 48x48 pixel mode (x1.5 zoom) has been added to the Icons menu (top left). + While playing in 32x32 or 64x64 will still provide a clearer looking station, + for those of us with resolutions that fall into the gap between the two zooms + this can provide a more consistant looking station than stretch to fit. + - rscadd: 96x96 pixel mode (x3 zoom) has also been added for our players who enjoy + looking at spacemen on their 4k monitors at a crisp and consistent scale. + - tweak: The lich spell has been subjected to some gentle nerfing. When you die + a string of energy will tie your new body to your old body for a short time, + aiding others in determining your location. The duration of this beam scales + with the number of deaths you've avoided. + - tweak: Additionally the post revival stun now also scales in this way. + - tweak: The spell will also fail if the item and the wizard don't share the same + z level, though the nature of space means the odds of the item (or the wizard) + looping around back to the station is pretty high. + - rscadd: The spell is still really good. +2015-10-27: + Joan: + - bugfix: You can now click on things under timestop effects, instead of clicking + the effect and looking like a fool. + Kor: + - rscadd: Added a zombie mob that turns its kills into more zombies. Currently adminspawn + and xenobio only. + - rscadd: Using water with a red slime extract will now yield a speed potion. Using + the speed potion on an item of clothing will paint it red and remove its slowdown. + MrStonedOne: + - rscadd: You may now access the setup character screen when not in the lobby via + the game preferences verb in the preferences tab + - rscadd: The round end restart delay can now be configured by server operators. + New servers will default to 90 seconds while old servers will default to the + old 25 seconds until they import the config option to their server. +2015-10-28: + Tkdrg: + - rscadd: Added a Ghost On-screen HUD. It can be toggled using the "Toggle Ghost + HUD" verb. Thank you Razharas for the sprites! + - rscadd: Ghosts can now use the "Toggle med/sec HUD" verb to see the basic secHUD + (jobs only) or the medHUD of humans. + - rscadd: Ghost will now get clickable icon alerts from events such as being put + in a cloner, drones being created, Nar-sie being summoned, among others. The + older chat messages were kept. These alerts can not be toggled. +2015-10-29: + Kor: + - tweak: Slightly changed what items spawn on the captain vs in his locker, hopefully + saving some annoying inventory shuffle at roundstart. +2015-10-30: + Incoming5643: + - rscadd: Slimepeople can now split if they contain 200 units of slime jelly, and + slimepeople will now slowly generate slime jelly up to 200 units provided they + are very well fed. Split slimepeople are NOT player controlled, but rather the + original slime person can swap between the two mobs at will. If one of the slimepeople + should die under player control, the player won't be able to swap back to their + living body. Splitting only creates a new body, any items you have on you are + not duplicated. + - rscadd: Slimepeople now take half damage from sources of heat, but double damage + from sources of cold. Lasers good, Space bad. +2015-11-01: + Gun Hog: + - rscadd: Nanotrasen listens! After numerous complaints and petitions from Security + personnel regarding energy weapon upkeep, we have authorized the construction + and maintenance of your station's weapon rechargers. As an added bonus, we have + also provided a more modular design for the devices, allowing for greater recharge + rates if fitted with a more efficient capacitor! + - rscadd: Added Diagnostic HUDs! They can be used to view the health and cell status + of borgs and mechs. Silicons have them built in, Roboticists get two in their + locker, and the RD's hardsuit has one built in. + Incoming5643: + - rscadd: The number of roundstart head revolutionaries nows depends on the roundstart + security force as well as the roundstart heads + - rscadd: The maximum number of head revs is 3, the minimum is 1. If there is fewer + than three station heads there will never be more than that number of head revs + at roundstart. For every three vacant security roles (Head of Security/Warden/Security + Officer/Detective) at roundstart the number of starting head revs will be reduced + by 1. + - rscadd: Head revolutionaries can be gained during play if the security/head roles + are filled. They are drawn from existing revolutionaries. + - rscadd: Added dental implant surgery. While targeting the mouth drill a hole in + a tooth then stick a pill in there for hands free later use. + Kor: + - rscadd: Added an experimental control console for Xenobiology. Ask the admins + if you'd like to try it out. It may not work on maps other than Box if they + have renamed the Xenobiology Lab. + - rscadd: Injecting blood into a cerulean slime will yield a special one use set + of blueprints that will allow you to expand the territory your camera can cover. + Kor and Remie: + - rscadd: Added as series of laser reflector structures, the frame of which can + be built with 5 metal sheets. + - rscadd: Completing the frame with 5 glass sheets creates a mirror that will reflect + lasers at a 90 degree angle. + - rscadd: Completing the frame with 10 reinforced glass sheets creates a double + sided mirror that reflects lasers at a 90 degree angle. + - rscadd: Completing the frame with a single diamond sheet creates a box that will + redirect all lasers that hit it from any angle in a single direction. + MMMiracles: + - tweak: Energy Swords can now embed when thrown for a 75% chance. Embedding +2015-11-05: + AnturK: + - rscadd: Added wild shapeshift spell for wizards. +2015-11-08: + Cuboos: + - soundadd: Added a new and better sounding flashbang sound and a ringing sound + for flashbang deaf effect + JJRcop: + - tweak: Chronosuits have had their movement revised, they now take time to teleport + depending on how far you've traveled, and don't teleport automatically anymore + unless you stop moving for a short moment, or press the new ' Teleport Now' + button. + - rscadd: Added new outfit that allows admins to dress people up in the chrono equipment + easier. + Jalleo: + - tweak: Due to a recently discovered report it turns out The Wizard Federation + has devised a way for CEOs to stop having some teas from their Smartfridges + due to this change all smartfridges will temporarily be unable to stack contents. + Joan: + - tweak: Revenant draining now takes about 5 seconds to complete and can be interrupted + by dragging the target away. + - tweak: Revenants can now tell if they are currently visible. + - tweak: Revenant ability costs tweaked; Defile now costs 40 essence to cast, Overload + Lights now costs 45 essence to cast, and Malfunction now costs 50 essence to + cast. + - tweak: Malfunction now affects non-machine objects, even if they're not being + held by a human. + - tweak: Defile does an extremely low amount of toxin damage to humans and confuses, + but does much less stamina damage and stuns the revenant for slightly longer. + - tweak: Overload Lights will no longer shock if the light is broken after a light + is chosen to shock an area. + Kor: + - rscadd: Using water on a dark blue slime extract will now yield a new potion capable + of completely fireproofing clothing items. + - rscadd: You can once again click+drag mobs into disposal units. Xenobiologists + rejoice. + Xhuis: + - tweak: Shadowling abilities now require the user to be human. + - tweak: Enthralling now takes 21 seconds (down from 30). + - tweak: Regenerate Chitin has been renamed to Rapid Re-Hatch. + - tweak: Dethralling surgery's final step now requires a flash, penlight, or flashlight. + - tweak: Dethralling surgery now produces a black tumor, which has a high biological + tech origin but dies quickly in the light. + - rscdel: Shadowlings no longer have Enthrall before hatching. + - rscadd: Shadowling clothing now has icons to better reflect its existence. + - rscdel: Ascendant Broadcast has been removed. + - rscdel: Destroy Engines is now removed from the user after it is used once. +2015-11-11: + AnturK: + - tweak: DNA Injectors now grant temporary powers on every use. Duration dependent + on activated powers and machine upgrades + - rscadd: 'Delayed Transfer added to DNA Scanner - It will activate on the next + closing of scanner door ' + - rscadd: 'UI+UE injectors/buffer transfers added for convinience ' + - tweak: Injector creation timeout cut in half + Firecage: + - rscadd: NanoTrasen specialists has developed a new type of operating table. You + can now make one yourself with only some rods and a sheet of silver! + Kor: + - rscadd: Adds immovable and indestructible reflector structures for badmin use. + - rscadd: The Mjolnir has been added to the wizards spellbook. + - rscadd: The Singularity Hammer has been added to the wizards spellbook. + - rscadd: The Supermatter Sword has been added to the wizards spellbook. + - rscadd: The Veil Render has been added to the wizards spellbook. + - rscadd: Trigger Multiverse War (give the entire crew multiswords) has been added + to the wizards spellbook, at a cost of 8 points. + - rscadd: Converting (to cultist, rev, or gangster) a jobbaned player will now automatically + offer control of their character to ghosts. + - rscadd: Emergency Response Teams and Deathsquads no longer accept non-human members + if the server is configured to bar mutants from being heads of staff. + LordPidey: + - rscadd: Nanotransen doctors have re-approved Saline-Glucose Solution for usage + in IV drips, when blood supplies are low. Simple pills will not suffice. + MMMiracles: + - tweak: Water slips have been nerfed to a more reasonable duration. It is still + a guaranteed way to disarm an opponent and obtain their weapon, but you can + no longer manage to cuff/choke everyone who manages to slip without a problem. + MrStonedOne: + - bugfix: Fixes the smartfridge not stacking items. + Xhuis: + - soundadd: The emergency shuttle now plays unique sounds (thanks to Cuboos for + creating them) when launching from the station and arriving at Central Command. + torger597: + - rscadd: Added a syringe to boxed poison kits. +2015-11-12: + Dunc: + - rscdel: DNA injectors have been restored to their original permanent RNG state + from the impermanent guaranteed state. + Xhuis: + - rscadd: Reagents can no longer be determined by examining a reagent container + without the proper apparatus. Silicons and ghosts can always see reagents. + - rscadd: Science goggles now allow reagents to be seen on examine. In addition, + chemists now start wearing them. The bartender has a pair that looks and functions + like sunglasses. +2015-11-13: + as334: + - rscadd: Nanotrasen has hired a brand new supply of ~~expendable labor~~ *LOYAL + CREW MEMBERS* please welcome them with open arms. + - rscadd: Plasmamen are now a playable race. They require plasma gas to survive + and will ignite in oxygen environments. +2015-11-15: + CosmicScientist: + - tweak: Hopefully made the dehydrated carp's uplink description 100% clear. + - tweak: Made the dehydrated carp cost 1 TC (instead of 3) to help with your traitor + gear combos. + Incoming5643: + - tweak: The supermatter sword was being far too kind in the hands of men. They + should now have the desired effect when swung at people. + Joan: + - tweak: Anomalies move more often, are resistant to explosions and will only be + destroyed if they are in devastation range. You shouldn't bomb them, though. + - tweak: Hyper-energetic flux anomaly will shock mobs that run into it, or if it + runs into them. + - tweak: Bluespace anomaly will occasionally teleport mobs away from it in a small + radius. + - tweak: Vortex anomalies will sometimes throw objects at nearby living mobs. + - tweak: Pyroclastic anomalies will produce bigger, hotter fires, and if not disabled, + it will release an additional burst of flame. In addition, the resulting slime + will be rabid and thus attack much more aggressively. + - bugfix: Gravitational anomalies will now properly throw objects at nearby living + things. + MrStonedOne: + - bugfix: Away mission loading will no longer improperly expand the width of the + game world to two times the size of the away mission map. + - tweak: This should also improve the speed of loading away missions, since the + game doesn't have to resize the world + RemieRichards: + - rscadd: Deities now start off with the ability to place 1 free turret + - tweak: HoG Claymores now do 30 Brute (Down from 40) but now have 15 Armour Penetration + (Up from 0) + - bugfix: Killing the other god objective is fixed + - tweak: Turrets will no longer attack handcuffed people + - rscadd: Followers are now informed of their god's death + - rscadd: Followers are now informed of the location of their god's nexus when it + is placed + - tweak: Gods can no longer place structures near the enemy god's nexus +2015-11-16: + Gun Hog: + - tweak: The Combat tech requirement for Loyalty Firing Pins has been reduced from + 6 to 5. + Joan: + - tweak: Plasmamen can now man the bar. + - tweak: Defile no longer directly affects mobs. Instead, it rips up floors and + opens most machines and lockers. + - rscadd: Blight added. Blight infects humans with a virus that does a set amount + of damage over time and is relatively easily cured. Blight also badly affects + nonhuman mobs and other living things. + - experiment: While the cure to Blight is simple, it's not in this changelog. Use + a medical analyzer to find the cure. + - tweak: Tweaked costs and stuntimes of abilities; + - tweak: Defile now costs 30 essence and stuns for about a second. + - tweak: Overload Lights now costs 40 essence. + - tweak: Malfunction now costs 45 essence. + - rscadd: Blight costs 50 essence and 200 essence to unlock. + - imageadd: Transmit has a new, spookier icon. + - bugfix: Revenant abilities can be given to non-revenants, and will work as normal + spells instead of runtiming. + bgobandit: + - rscadd: Blood packs can now be labeled with a pen. +2015-11-17: + Xhuis: + - tweak: Many medicines have received rebalancing. Expect underused chemicals like + Oxandralone to be much more effective in restoring damage. + - tweak: Many toxins are now more or less efficient. + - tweak: The descriptions of many reagents have been made more accurate. + - rscadd: 'New poison: Heparin. Made from Formaldehyde, Sodium, Chlorine, and Lithium. + Functions as an anticoagulant, inducing uncontrollable bleeding and small amounts + of bruising.' + - rscadd: 'New poison: Teslium. Made from Plasma, Silver, and Black Powder, heated + to 400K. Modifies examine text and induces periodic shocks in the victim as + well as making all shocks against them more damaging.' + - rscadd: Two Chemistry books have been placed in the lab. When used, they will + link to the wiki page for chemistry in the same vein as other wiki books. +2015-11-18: + oranges: + - tweak: Nanotrasen apologies for a recent bad batch of synthflesh that was shipped + to the station, any rumours of death or serious injury are false and should + be reported to your nearest political officer. At most, only light burns would + result. + phil235: + - bugfix: Remotely detonating a planted c4 with a signaler now works again. +2015-11-19: + Joan: + - rscadd: Constructs have action buttons for their spells. + - imageadd: The Juggernaut forcewall now has a new, more cult-appropriate sprite. + - imageadd: Cult floors and walls now have a glow effect when being created. + - bugfix: Nar-Sie and Artificers will properly produce cult flooring. + - spellcheck: Nar-Sie is a she. +2015-11-20: + AnturK: + - tweak: Staff of Doors now creates random types of doors. + Incoming5643: + - bugfix: Setting your species to something other than human (if available) once + again saves properly. Note that if you join a round where your species setting + is no longer valid it will be reset to human. + PKPenguin321: + - tweak: Healing Fountains in Hand of God now give cultists a better and more culty + healing chemical instead of Doctor's Delight. + kingofkosmos: + - rscadd: Added the ability to upgrade your grab by clicking the grabbed mob repeatedly. + octareenroon91: + - rscadd: Add the four-color pen, which writes in black, red, green, and blue. + - rscadd: Adds two such pens to the Bureaucracy supply pack. +2015-11-21: + Joan: + - rscadd: Blobs now have a hud, with jump to node, create storage blob, create resource + blob, create node blob, create factory blob, readapt chemical, relocate core, + and jump to core buttons. + - tweak: Manual blob expansion is now triggered by clicking anything next to a blob + tile, instead of by ctrl-click. + - tweak: 'Rally Spores no longer has a cost. Reminder: You can middle-click anything + you can see to rally spores to it.' + - tweak: Creating a Shield Blob with hotkeys is now ctrl-click instead of alt-click. + - rscadd: Removing a blob now refunds some points based on the blob type, usually + around 40% of initial cost. Hotkey for removal is alt-click. + - rscadd: Blobs now have the *Blob Help* verb which will pull up useful information, + including what your reagent does. + - tweak: Storage Blobs now cost 20, from 40. Storage Blobs also cannot be removed + by blob removal. + - tweak: Readapt Chemical now costs 40, from 50. + octareenroon91: + - rscadd: Add numbers and a star graffiti to crayon/spraycan designs. +2015-11-23: + octareenroon91: + - rscadd: Spilling oxygen or nitrogen will obtain a release of the corresponding + atmospheric gas in the effected tile. + - rscadd: 'Carbon Dioxide has been added as a reagent. Recipe: 2:1 carbon:oxygen, + heated to 777K.' + - rscadd: Spilling CO2 will produce CO2 gas. +2015-11-24: + Kor: + - rscadd: Added a lava turf. Expect to see it in away missions or in admin 'events' +2015-11-25: + Incoming5643: + - experiment: A number of popular stunning spells have undergone balance changes. + Note that for the most part the stuns themselves are untouched. + - experiment: 'Lightning Bolt Changes:' + - rscdel: You can no longer throw the bolt whenever you want, it will fire itself + once it's done charging. + - rscadd: Getting hit by a bolt will do a flat 30 burn now, as opposed to scaling + with how long the wizard spent charging the spell. Unless said wizard made a + habit of charging lightning bolt to near maximum every time this is a buff to + damage. + - rscdel: Every time the bolt jumps the next shock will do five less burn damage. + - rscadd: Lightning bolts can still jump back to the same body, so the maximum number + of bolts you can be hit by in a single casting is three, and the maximum amount + of damage you could take for that is 60 burn. + - experiment: 'Magic Missile Changes:' + - rscdel: Cooldown raised to 20 seconds, up from 15 + - rscadd: Cooldown reduction from taking the spell multiple times raised from 1.5 + seconds to 3.5 seconds. Rank 5 magic missile now has a cooldown of 6 seconds, + down from 9, and is effectively a permastun. + - experiment: 'Time Stop Changes:' + - rscadd: Time Stop field now persists for 10 seconds, up from 9 + - rscdel: Cooldown raised to 50 seconds, up from 40 + - rscadd: Cooldown reduction from taking the spell multiple times raised from 7.75 + seconds to 10 seconds. Rank 5 time stop now has a cooldown of 10 seconds, up + from 9, and is effectively a permastun. + Kor: + - rscadd: Escape pods can now be launched to the asteroid during red and delta level + security alerts. Pods launched in this manner will not travel to Centcomm at + the end of the round. + - rscadd: Each pod is now equipped with a safe that contains two emergency space + suits and mining pickaxes. This safe will only open during red or delta level + security alerts. + MrStonedOne: + - bugfix: fixes interfaces (like the "ready" button) being unresponsive for the + first minute or two after connecting. + - tweak: Burn related code has been changed + - tweak: This will give a small buff to fires by making them burn for longer + - tweak: This will give a massive nerf to plasma related bombs + - tweak: I am actively seeking feedback, if the nerf to bombs is too bad we can + still tweak stuff + PKPenguin321: + - rscadd: Chainsaws (both arm-mounted and not arm-mounted) can now be used in surgeries + as a ghetto sawing tool. Arm-mounted chainsaws are a teeny bit more precise + than regular ol' everyday chainsaws. + YotaXP: + - tweak: Spruced up the preview icons on the Character Setup dialog. + incoming5643: + - rscdel: Citing shenanigan quality concerns the wizard federation has withdrawn + supermatter swords and veil renderers from spellbooks. + neersighted: + - bugfix: Make Airlock Electronics use standard ID checks, allowing Drones to use + them. +2015-11-26: + neersighted: + - tweak: Cyborg Toner is now refilled by recharging stations. + oranges: + - tweak: Removed the 'gloves' from the sailor dress which looked weird since it + was a blouse basically + - tweak: Made the skirt on the blue/red skirts less blocky, + - tweak: Made the striped dress consistent at every direction +2015-11-27: + AnturK: + - rscadd: Turret control panels can now be made through frames available at autolathe. + - rscadd: Unlocked turrets can be linked with built controls with multiool + JJRcop: + - bugfix: Restores golem shock immunity. + Kor and Ausops: + - rscadd: Added four different suits of medieval plate armour. + - rscadd: The Chaplain starts with a suit of Templar armour in his locker. God wills + it! + - rscadd: Rumour has it that Nanotrasen is now training a new elite unit of soldiers + to deal with paranormal threats. Corporate was unable to be reached for comment. + MMMiracles: + - rscadd: Adds a brand new away mission for the gateway called 'Caves'. + - rscadd: The away mission has multiple levels to explore and could be quite dangerous, + running in without proper preparation is unadvised. + YotaXP: + - bugfix: Drones can now use the pick-up verb, and watertanks no longer get jammed + in their internal storage. + bgobandit: + - rscadd: Due to changes in Nanotrasen's mining supply chain, ore redemption machines + now offer a variety of upgraded items! However, certain items are more expensive. + Point values for minerals have been adjusted to reflect their scarcity. + - rscadd: Nanotrasen R&D has discovered how to improve upon the resonator and kinetic + accelerator. + - rscadd: After a colossal tectonic event on Nanotrasen's asteroid, ores are distributed + more randomly. + - rscadd: Bluespace crystals have been discovered to be ore. They will now fit into + satchels and ore boxes. + - rscadd: Mech advanced mining scanners now include meson functionality. + neersighted: + - bugfix: Wooden Barricades now take bullet damage. + - tweak: Rebalance Wooden Barricade damage. +2015-11-28: + TechnoAlchemisto: + - tweak: Cloaks are now worn in your exosuit slot! +2015-11-29: + Firecage: + - rscadd: Hand tools now have variable operating speeds. + GunHog: + - tweak: Nanotrasen has improved the interface for the hand-held teleportation device. + It will now provide the user with the name of the destination tracking beacon. + JJRcop: + - bugfix: Fixes changeling Hive Absorb DNA ability runtime. + Joan: + - imageadd: When sacrificing a target with the sacrifice rune, Nar-Sie herself will + briefly appear to consume them. + - imageadd: When an artificer repairs a construct, there is a visible beam between + it and the target. + - imageadd: When reviving a target with the raise dead rune, there is a visible + beam between the two corpses used. + - imageadd: When draining a target with the blood drain rune, there is a visible + beam between you and the rune. + - imageadd: Construct sprites are now consistent and all bob in the air. + - rscadd: Most cult messages now use the cult span classes, though visible messages + from cult things generally do not. + - bugfix: Examining a cultist talisman as a cultist no longer causes the paper popup + to appear. + - bugfix: You no longer need to press two buttons to read a cultist tome. + - spellcheck: Cult should have a few less typos and grammatical errors. + - spellcheck: The sacrifice rune now uses the proper invocation. + KorPhaeron: + - rscadd: Guardians and holoparasites can now be manually recalled by their master. + - rscadd: The ghost controlling a guardian or holoparasite can be repicked by their + master, only one use which is removed when a new ghost is chosen. + MrStonedOne: + - rscadd: Re-adds 100% chance timed injectors, as it was removed over a misunderstanding. + - bugfix: Fixes bug with injectors having a 100% power chance despite not being + timed + - bugfix: Fixes the excessive amount of time it took the game to initialize. + - bugfix: Fixes some interface bugs. + - rscadd: when an interface window has to send a lot of resources before it can + open, it will now tell you with a "sending resources" line so you know why it's + not opening right away. + PKPenguin321: + - rscadd: Teleprods can now be constructed. Make them via tablecrafting, or by putting + a bluespace crystal onto a stunprod. They warp the target to a random nearby + area (which may include space/the inside of a wall) in addition to giving the + victim a brief stun. Like stunprods, they require a power cell to function. + - rscadd: Teleprods can have their crystal removed and be made back into stunprods + by using them in your hand when they have no cell installed. + - imageadd: Mounted chainsaws now have a unique inhand sprite. + Remie + Kor: + - tweak: Holopads now use AltClick to request the AI + Shadowlight213: + - tweak: Syndie melee mobs have been buffed. + TheNightingale: + - rscadd: Nuclear operatives can now buy the Elite Syndicate Hardsuit for 8 TC that + has better armor and fireproofing. + - tweak: Added throwing stars and Syndicate playing cards to nuclear operative's + uplink. + Yolopanther12: + - rscadd: Added the ability to use a box of lights on a light replacer to more quickly + refill it to capacity. + incoming5643: + - rscadd: OOC will now take steps to try and prevent accidental IC from people who + mistakenly use OOC instead of say. This doesn't catch all mistakes, so please + don't test it. + ktccd: + - bugfix: Blob pieces on some areas no longer count for blob mode victory (Such + as space or asteroid). + - bugfix: Blobcode no longer spawns and destroys blobs uselessly, which fixes other + stuff too. + - bugfix: Asteroid areas are no longer valid gang territory. + neersighted: + - experiment: Nanotrasen would like to announce NanoUI 2.0, now being rolled out + across all our stations. Existing NanoUI devices have been updated, and more + will be added soon. Please report any bugs to Nanotrasen Support. + - tweak: Many NanoUI interfaces have had +/- buttons replaced with input fields. + - tweak: Some NanoUI interfaces have had more information added. + - bugfix: Drones can now interact with NanoUI windows. + swankcookie: + - bugfix: Fixes issue of space-Christians forgetting about the true, humbling values + of space-Christmas. + - rscadd: Adds snowmen outfits +2015-11-30: + neersighted: + - bugfix: Nanotrasen would like to apologize for Chemistry being stuck on NanoUI + 1.0... Please report any further bugs to Nanotrasen Support. + - tweak: NanoUI becomes... difficult to operate with brain damage. Who would have + guessed? + - tweak: Telekinesis enables you to use NanoUI at a distance. + - bugfix: Canisters require physical proximity to actuate... + - bugfix: NanoUI no longer leaks memory on click. +2015-12-01: + Kor: + - rscadd: The away mission Listening Post, originally mapped by Petethegoat, has + removed as a mission. It is now present in normal deep space. + neersighted: + - tweak: Attack animations are now directional! + - rscadd: Nanotrasen brand Airlock Electronics now sport our latest NanoUI interface! + Upgrade your electronics today! + - bugfix: Cryo now knocks you out. + - bugfix: Resisting out of cryo has a delay. + - rscadd: Cryo auto-ejection can now be configured. + - rscdel: Remove Cryo eject verb (resist out). + - bugfix: Cryo works... Love, neersighted + swankcookie: + - tweak: Switches cloak usage to overclothing slot +2015-12-02: + GunHog: + - bugfix: Nanotrasen has discovered a flaw in the weapon recharging station's design + that makes it incompatible with the Rapid Part Exchange Device. This has been + corrected. + neersighted: + - tweak: You can now stop pulling by trying to pull the same object again. + - rscadd: Nanotrasen is proud to announce that even the dead can use our state of + the art NanoUI technology. +2015-12-03: + Joan: + - rscadd: Artificers now have feedback when healing other constructs, showing how + much health the target has. + - tweak: Constructs can move in space. + - imageadd: Fixes cult flooring not lining up with normal floors. + - imageadd: Fixes a juggernaut back spine not glowing where it should. + Spudboy: + - tweak: Realigned the librarian's PDA. + Swankcookie: + - bugfix: Cakehat now creates light + YotaXP: + - rscadd: Rolled out a new line of space heaters around the station. This new model + has the functionality to cool down the environment, as well as heat it. Additionally, + they can be built and upgraded like any other machine. + neersighted: + - bugfix: Dominator now shows the correct area name on non-Box maps. + - bugfix: Unwrenching atmos pipes is less... nuts... + - bugfix: You don't get hopelessly spun when standing on a unwrenched pipe... Don't + try it, though. + - tweak: You can now cancel pulling by Ctrl+Clicking anything else + - tweak: Chemistry Dispensers now have a built-in drain! +2015-12-05: + Joan: + - rscdel: Magic missiles no longer do damage. +2015-12-06: + Gun Hog: + - rscadd: Nanotrasen is proud to announce that it has improved its Diagnostic HUD + firmware to include the station's automated robot population! New features include + integrity tracking, Off/On status, and mode tracking! If your little robot friend + suddenly manages to acquire free will, you will be able to track that as well! + - tweak: Artificial Intelligence units may find that their bot management interface + now shows when a robot gains free will. This is also displayed on the Personal + Data Assistant's bot control interface. + neersighted: + - bugfix: Cryo now properly checks it is on before healing... +2015-12-07: + octareenroon91: + - rscadd: Wallets now use the access of all IDs stored inside them. + - rscadd: As the accesses of all IDs are merged, two IDs in a wallet may grant access + to a door that neither one alone would open. + - bugfix: Wallets used to be useless for access if the first ID card put into it + was taken out, until another ID card was put back in. That should not happen + anymore. +2015-12-08: + Joan: + - experiment: Revenants can no longer move through walls and windows while revealed, + though they can move through tables, plastic flaps, mobs, and other similarly + thin objects. + - tweak: Defile now reveals for 4 seconds, from 8. + - tweak: Overload lights now reveals for 10 seconds, from 8. + - tweak: Blight now reveals for 6 seconds, from 8. + - rscadd: Blight has a higher chance of applying stamina damage to the infected. + Kor: + - rscadd: The blocking system has been completely overhauled. Any held item, exosuit, + or jumpsuit can now have a chance to block, or a custom on hit effect. Different + shields can now have different block chances. + - rscadd: The clowns jumpsuit now honks when you beat the owner. + - rscadd: There is a new (admin only for now) suit of reactive armour that ignites + attackers instead of warping you. + - rscadd: Shields will no longer block hugs. Give peace a chance. + neersighted: + - tweak: MC tab reworked, more items made available. + - rscadd: Admins can now click entries in the MC tab to debug. +2015-12-09: + GunHog: + - tweak: Nanotrasen has discovered new strains of Xenomorph which resist penetration + by known injection devices, including syringes. This seems to only extend to + the large 'Royal' strains, designed 'Queen' and 'Praetorian'. Extreme caution + is advised should these specimens escape containment. + - rscadd: Ghosts may now use Diagnostic HUD. + - tweak: Feedback added for which HUD is active. + Kor: + - rscadd: Security barricades now block gunfire 80% of the time while deployed. + - rscadd: Standing adjacent to barricades will allow you to shoot over them. + MrStonedOne: + - rscadd: noslip floors make you slightly faster + Shadowlight213: + - rscadd: Admins can now interact with mos of the station's machinery as if they + were an AI when ghosting. + incoming5643: + - rscadd: a mutation of glowshrooms, glowcaps, have recently been discovered in + botany. + ktccd: + - bugfix: Blobs now require the correct amount of blobs to win that scales depending + on number of blobs, instead of a set value of 700. +2015-12-12: + Joan: + - tweak: The blob Split Consciousness ability now requires a node under the overmind's + selector, instead of picking the oldest living node to spawn a core on. + - bugfix: Revenant antagonist preference can once again be toggled from the Game + Preferences menu. + Kor: + - rscadd: You now have a chance to flip while attacking with a dualsaber. + - rscadd: Bluespace survival capsules have been added to escape pod safes. + - rscadd: Standing between activating shield generators now has disastrous consequences. + Lo6a4evskiy: + - bugfix: Ninja drains power properly, no more infinite stealth. + RemieRichards: + - rscadd: Adds a Synth Species + - rscadd: Species can now react to being force set by admins, used for Synth species +2015-12-13: + Kor: + - rscadd: Adds reactive stealth armor. Admin spawn only. +2015-12-15: + Incoming5643: + - rscadd: The summon events... event "RPG loot" now allows for items to have bonuses + of up to +15! + - rscadd: The "RPG loot" event now also improves the damage reduction of armor! + - rscadd: |