Merge branch 'master' into logging-improvements

This commit is contained in:
farie82
2020-05-22 07:16:23 +02:00
committed by GitHub
319 changed files with 17089 additions and 15784 deletions
+23 -56
View File
@@ -1,74 +1,41 @@
#pretending we're C because otherwise ruby will initialize, even with "language: dm".
language: generic
sudo: false
dist: xenial
os: linux
git:
depth: 1
cache:
directories:
- $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}
addons:
apt:
packages:
- libc6-i386
- libgcc1:i386
- libstdc++6:i386
env:
global:
- BYOND_MAJOR="513"
- BYOND_MINOR="1505"
- BYOND_MACRO_COUNT=4
matrix:
- DM_MAPFILE="cyberiad"
- DM_MAPFILE="metastation"
- DM_MAPFILE="delta"
- DM_MAPFILE="test_all_maps"
stages:
- File Checks
- test
before_script:
- chmod +x ./install-byond.sh
- ./install-byond.sh
script:
- source $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}/byond/bin/byondsetup
- bash dm.sh -M${DM_MAPFILE} paradise.dme
jobs:
include:
# Basic styling/functionality checks
- stage: File Checks
env:
- name: "Run Linters"
addons:
apt:
packages:
- python3
- python3-pip
- python3-setuptools
install:
- pip install --user PyYaml -q
- pip install --user beautifulsoup4 -q
- tools/travis/install_build_deps.sh
- tools/travis/install_dreamchecker.sh
before_script: skip
script:
- shopt -s globstar
- find . -name "*.php" -print0 | xargs -0 -n1 php -l
- find . -name "*.json" -not -path "./nano/node_modules/*" -print0 | xargs -0 python3 ./tools/travis/json_verifier.py
- tools/travis/build_nanoui.sh
- tools/travis/check_grep.sh
- python3 tools/travis/check_line_endings.py
- (num=$(grep -Ern '\\(red|blue|green|black|italic|bold|b|i[^mc])' code/ | wc -l); echo "$num BYOND text macros (expecting ${BYOND_MACRO_COUNT} or fewer)"; [ $num -le ${BYOND_MACRO_COUNT} ])
- md5sum -c - <<< "6dc1b6bf583f3bd4176b6df494caa5f1 *html/changelogs/example.yml"
- python tools/ss13_genchangelog.py html/changelog.html html/changelogs
- ~/dreamchecker
# Compile NanoUI to make sure it works
- stage: NanoUI
language: node_js
node_js:
- "9"
env:
- name: "Compile All Maps"
addons:
before_install:
- npm install -g gulp-cli
- cd ./nano/
apt:
packages:
- libstdc++6:i386
cache:
directories:
- $HOME/BYOND
install:
- npm install --loglevel=error
before_script:
- tools/travis/install_byond.sh
- source $HOME/BYOND/byond/bin/byondsetup
script:
- node node_modules/gulp/bin/gulp.js --require less-loader
- tools/travis/dm.sh -Mtravis_map_testing paradise.dme
+10
View File
@@ -70,6 +70,16 @@ Make sure to set the port to the one you specified in the config.txt,
and set the Security box to 'Trusted'.
Then press GO and the server should start up and be ready to join.
### Installation (Linux)
The code is able to run on Linux server side, however the libraries for MySQL and logging do require extra packages.
For MySQL, run the following: `apt-get install libmysqlclient-dev:i386`
For RustG, run the following: `apt-get install libssl-dev:i386 pkg-config:i386 zlib1g-dev:i386`
After installing these packages, these libraries should function as intended.
---
### UPDATING
+15 -1
View File
@@ -594,4 +594,18 @@ CREATE TABLE `connection_log` (
`ip` varchar(32) NOT NULL,
`computerid` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Table structure for table `changelog`
--
DROP TABLE IF EXISTS `changelog`;
CREATE TABLE `changelog` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`pr_number` INT(11) NOT NULL,
`date_merged` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`author` VARCHAR(32) NOT NULL,
`cl_type` ENUM('FIX','WIP','TWEAK','SOUNDADD','SOUNDDEL','CODEADD','CODEDEL','IMAGEADD','IMAGEDEL','SPELLCHECK','EXPERIMENT') NOT NULL,
`cl_entry` TEXT NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+15 -1
View File
@@ -591,4 +591,18 @@ CREATE TABLE `SS13_connection_log` (
`ip` varchar(32) NOT NULL,
`computerid` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Table structure for table `SS13_changelog`
--
DROP TABLE IF EXISTS `SS13_changelog`;
CREATE TABLE `SS13_changelog` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`pr_number` INT(11) NOT NULL,
`date_merged` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`author` VARCHAR(32) NOT NULL,
`cl_type` ENUM('FIX','WIP','TWEAK','SOUNDADD','SOUNDDEL','CODEADD','CODEDEL','IMAGEADD','IMAGEDEL','SPELLCHECK','EXPERIMENT') NOT NULL,
`cl_entry` TEXT NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+1 -1
View File
@@ -38,4 +38,4 @@ ALTER TABLE feedback.population CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4
ALTER TABLE feedback.privacy CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.vpn_whitelist CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.watch CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.whitelist CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.whitelist CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+13
View File
@@ -0,0 +1,13 @@
#Updating the SQL from version 11 to version 12. -AffectedArc07
#Creating a table for the new changelog system
DROP TABLE IF EXISTS `changelog`;
CREATE TABLE IF NOT EXISTS `changelog` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`pr_number` INT(11) NOT NULL,
`date_merged` TIMESTAMP NOT NULL DEFAULT current_timestamp(),
`author` VARCHAR(32) NOT NULL,
`cl_type` ENUM('FIX','WIP','TWEAK','SOUNDADD','SOUNDDEL','CODEADD','CODEDEL','IMAGEADD','IMAGEDEL','SPELLCHECK','EXPERIMENT') NOT NULL,
`cl_entry` TEXT NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+9
View File
@@ -1,2 +1,11 @@
# This file has all the information on what versions of libraries are thrown into the code
# For dreamchecker
export SPACEMANDMM_TAG=suite-1.2
# For NanoUI
export NODE_VERSION=9
# For the scripts in tools
export PHP_VERSION=5.6
# Byond Major
export BYOND_MAJOR=513
# Byond Minor
export BYOND_MINOR=1505
@@ -2017,7 +2017,7 @@
/obj/machinery/vending/sustenance{
desc = "A vending machine normally reserved for work camps.";
name = "\improper sustenance vendor";
product_slogans = "Enjoy your meal.;Enough calories to support any worker."
slogan_list = list("Enjoy your meal.","Enough calories to support any worker.")
},
/turf/simulated/floor/plasteel{
icon_state = "floorgrime"
@@ -832,6 +832,10 @@
/obj/item/shard,
/turf/space,
/area/space/nearstation)
"Hv" = (
/obj/item/gps/ruin,
/turf/simulated/wall/r_wall,
/area/ruin/unpowered)
(1,1,1) = {"
aa
@@ -973,7 +977,7 @@ aa
at
at
aF
at
Hv
aU
ay
ay
@@ -269,6 +269,10 @@
icon_state = "freezerfloor"
},
/area/ruin/powered)
"Y" = (
/obj/item/gps/ruin,
/turf/simulated/wall/r_wall,
/area/ruin/powered)
(1,1,1) = {"
a
@@ -960,7 +964,7 @@ b
f
f
p
f
Y
f
f
j
@@ -240,6 +240,13 @@
/obj/structure/shuttle/engine/propulsion,
/turf/simulated/shuttle/plating,
/area/ruin/powered)
"U" = (
/obj/item/gps/ruin,
/turf/simulated/shuttle/wall{
tag = "icon-swall12";
icon_state = "swall12"
},
/area/ruin/powered)
(1,1,1) = {"
a
@@ -313,7 +320,7 @@ a
c
g
l
q
U
r
u
t
@@ -209,7 +209,6 @@
"aI" = (
/obj/structure/table/wood,
/obj/item/toy/character/wizard,
/obj/item/paper/spells,
/turf/simulated/floor/carpet,
/area/ruin/unpowered)
"aJ" = (
+36 -17
View File
@@ -2060,7 +2060,16 @@
icon_opened = "cabinet_open";
icon_state = "cabinet_closed"
},
/obj/item/clothing/under/color/lightpurple,
/obj/item/clothing/under/color/purple,
/obj/item/storage/backpack/satchel,
/obj/item/storage/backpack/satchel,
/obj/item/clothing/head/wizard/red,
/obj/item/clothing/suit/wizrobe/red,
/obj/item/clothing/head/wizard,
/obj/item/clothing/suit/wizrobe,
/obj/item/clothing/shoes/sandal,
/obj/item/clothing/shoes/sandal,
/turf/unsimulated/floor{
dir = 9;
icon_state = "carpetside"
@@ -2148,8 +2157,6 @@
/area/wizard_station)
"fC" = (
/obj/structure/table/wood,
/obj/item/trash/tray,
/obj/item/paper/spells,
/turf/unsimulated/floor{
dir = 10;
icon_state = "carpetside"
@@ -3248,10 +3255,10 @@
/area/shuttle/assault_pod)
"iw" = (
/obj/structure/rack,
/obj/item/clothing/under/plasmaman/wizard,
/obj/item/clothing/head/helmet/space/plasmaman/wizard,
/obj/item/clothing/mask/breath,
/obj/item/clothing/mask/breath/vox,
/obj/item/tank/plasma/plasmaman,
/obj/item/tank/emergency_oxygen/vox,
/obj/item/tank/plasma/plasmaman/belt/full,
/turf/unsimulated/floor{
icon_state = "grimy"
},
@@ -3895,10 +3902,8 @@
/area/centcom/gamma)
"ke" = (
/obj/structure/rack,
/obj/item/clothing/suit/wizrobe/red,
/obj/item/clothing/shoes/sandal,
/obj/item/clothing/head/wizard/red,
/obj/item/twohanded/staff,
/obj/item/tank/emergency_oxygen/vox,
/obj/item/clothing/mask/breath/vox,
/turf/unsimulated/floor{
icon_state = "grimy"
},
@@ -5006,6 +5011,20 @@
name = "grass"
},
/area/centcom/control)
"nc" = (
/obj/machinery/door/airlock/centcom{
name = "Gamma Armory";
opacity = 1;
req_access_txt = "114"
},
/obj/machinery/door/poddoor/impassable{
id_tag = "CCGAMMA";
name = "Gamma Security"
},
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
/area/centcom/gamma)
"nd" = (
/obj/structure/flora/ausbushes/lavendergrass,
/turf/unsimulated/floor{
@@ -5381,7 +5400,7 @@
},
/area/syndicate_mothership)
"nQ" = (
/obj/machinery/door/poddoor{
/obj/machinery/door/poddoor/impassable{
id_tag = "GRAVPULTS";
name = "Gravity Catapults"
},
@@ -5391,7 +5410,7 @@
},
/area/centcom/specops)
"nR" = (
/obj/machinery/door/poddoor{
/obj/machinery/door/poddoor/impassable{
id_tag = "GRAVPULTS";
name = "Gravity Catapults"
},
@@ -5408,7 +5427,7 @@
},
/area/syndicate_mothership)
"nT" = (
/obj/machinery/door/poddoor{
/obj/machinery/door/poddoor/impassable{
id_tag = "ASSAULT";
name = "Assault Armor"
},
@@ -5854,7 +5873,7 @@
},
/area/centcom/gamma)
"oR" = (
/obj/machinery/door/poddoor{
/obj/machinery/door/poddoor/impassable{
id_tag = "SPECOPS";
name = "Ready Room"
},
@@ -5979,7 +5998,7 @@
opacity = 1;
req_access_txt = "114"
},
/obj/machinery/door/poddoor{
/obj/machinery/door/poddoor/impassable{
id_tag = "specopsoffice";
name = "Super Privacy Shutters"
},
@@ -6118,7 +6137,7 @@
/turf/simulated/floor/mech_bay_recharge_floor,
/area/shuttle/gamma/space)
"pv" = (
/obj/machinery/door/poddoor{
/obj/machinery/door/poddoor/impassable{
id_tag = "CCTELE";
name = "Specops Teleporter"
},
@@ -6365,7 +6384,7 @@
/area/centcom/specops)
"pX" = (
/obj/machinery/door_control{
desc = "A remote control switch to block view of the singularity.";
desc = "A remote control switch to connect the ready room to the rest of Centcom.";
icon_state = "doorctrl0";
id = "SPECOPS";
name = "Ready Room";
@@ -29642,7 +29661,7 @@ fm
fm
md
md
oO
nc
fm
pv
sX
+16 -46
View File
@@ -761,7 +761,7 @@
/area/derelict/bridge)
"bK" = (
/obj/machinery/vending/cigarette/free{
product_slogans = "Just remember! No capitalist.;Best enjoyed with Vodka!.;Smoke!;Nine out of ten USSP scientists agree, smoking reduces stress!;There's no cigarette like a Russian cigarette!;Cigarettes! Now with 100% less capitalism."
slogan_list = list("Just remember! No capitalist.","Best enjoyed with Vodka!.","Smoke!","Nine out of ten USSP scientists agree, smoking reduces stress!","There's no cigarette like a Russian cigarette!","Cigarettes! Now with 100% less capitalism.")
},
/turf/simulated/floor/plasteel{
dir = 9;
@@ -1441,7 +1441,7 @@
pixel_y = 32
},
/obj/machinery/vending/cigarette/free{
product_slogans = "Just remember! No capitalist.;Best enjoyed with Vodka!.;Smoke!;Nine out of ten USSP scientists agree, smoking reduces stress!;There's no cigarette like a Russian cigarette!;Cigarettes! Now with 100% less capitalism."
slogan_list = list("Just remember! No capitalist.","Best enjoyed with Vodka!.","Smoke!","Nine out of ten USSP scientists agree, smoking reduces stress!","There's no cigarette like a Russian cigarette!","Cigarettes! Now with 100% less capitalism.")
},
/obj/effect/decal/cleanable/dirt,
/turf/simulated/floor/plasteel{
@@ -4163,7 +4163,7 @@
name = "suspicious button"
},
/obj/machinery/vending/cigarette/free{
product_slogans = "Just remember! No capitalist.;Best enjoyed with Vodka!.;Smoke!;Nine out of ten USSP scientists agree, smoking reduces stress!;There's no cigarette like a Russian cigarette!;Cigarettes! Now with 100% less capitalism."
slogan_list = list("Just remember! No capitalist.","Best enjoyed with Vodka!.","Smoke!","Nine out of ten USSP scientists agree, smoking reduces stress!","There's no cigarette like a Russian cigarette!","Cigarettes! Now with 100% less capitalism.")
},
/turf/simulated/floor/wood{
broken = 1;
@@ -5186,7 +5186,7 @@
"kW" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/vending/cigarette/free{
product_slogans = "Just remember! No capitalist.;Best enjoyed with Vodka!.;Smoke!;Nine out of ten USSP scientists agree, smoking reduces stress!;There's no cigarette like a Russian cigarette!;Cigarettes! Now with 100% less capitalism."
slogan_list = list("Just remember! No capitalist.","Best enjoyed with Vodka!.","Smoke!","Nine out of ten USSP scientists agree, smoking reduces stress!","There's no cigarette like a Russian cigarette!","Cigarettes! Now with 100% less capitalism.")
},
/turf/simulated/floor/plasteel{
dir = 5;
@@ -6363,7 +6363,7 @@
icon_state = "sink";
pixel_x = 12
},
/turf/simulated/floor/mineral/plasma,
/turf/simulated/floor/mineral/silver,
/area/syndicate_depot/core)
"of" = (
/obj/structure/closet/secure_closet/syndicate/depot,
@@ -6448,26 +6448,9 @@
icon_state = "wood"
},
/area/derelict/crew_quarters)
"oo" = (
/obj/effect/spawner/random_spawners/syndicate/layout/door/secret,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
/area/syndicate_depot/core)
"op" = (
/turf/simulated/floor/mineral/silver,
/area/syndicate_depot/core)
"oq" = (
/obj/machinery/door/airlock/plasma{
welded = 1
},
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
/area/syndicate_depot/core)
"or" = (
/turf/simulated/floor/mineral/plasma,
/area/syndicate_depot/core)
"os" = (
/obj/structure/table,
/obj/effect/spawner/random_spawners/syndicate/loot/stetchkin,
@@ -6543,7 +6526,7 @@
/area/syndicate_depot/core)
"oB" = (
/obj/effect/spawner/random_spawners/syndicate/mob,
/turf/simulated/floor/mineral/plasma,
/turf/simulated/floor/mineral/silver,
/area/syndicate_depot/core)
"oC" = (
/obj/effect/landmark{
@@ -6706,27 +6689,14 @@
icon_state = "dark"
},
/area/syndicate_depot/core)
"oZ" = (
/obj/structure/mirror{
pixel_x = -32
},
/turf/simulated/floor/mineral/plasma,
/area/syndicate_depot/core)
"pa" = (
/obj/structure/toilet{
dir = 8
},
/turf/simulated/floor/mineral/silver,
/area/syndicate_depot/core)
"pb" = (
/obj/machinery/portable_atmospherics/canister/toxins,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
/area/syndicate_depot/core)
"pc" = (
/obj/machinery/light,
/obj/effect/spawner/random_spawners/syndicate/loot/level3,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
@@ -9114,7 +9084,7 @@
})
"tY" = (
/obj/machinery/vending/cigarette/free{
product_slogans = "Just remember! No capitalist.;Best enjoyed with Vodka!.;Smoke!;Nine out of ten USSP scientists agree, smoking reduces stress!;There's no cigarette like a Russian cigarette!;Cigarettes! Now with 100% less capitalism."
slogan_list = list("Just remember! No capitalist.","Best enjoyed with Vodka!.","Smoke!","Nine out of ten USSP scientists agree, smoking reduces stress!","There's no cigarette like a Russian cigarette!","Cigarettes! Now with 100% less capitalism.")
},
/turf/simulated/floor/plasteel{
icon_state = "bar"
@@ -10678,7 +10648,7 @@
/area/derelict/arrival)
"xe" = (
/obj/machinery/vending/cigarette/free{
product_slogans = "Just remember! No capitalist.;Best enjoyed with Vodka!.;Smoke!;Nine out of ten USSP scientists agree, smoking reduces stress!;There's no cigarette like a Russian cigarette!;Cigarettes! Now with 100% less capitalism."
slogan_list = list("Just remember! No capitalist.","Best enjoyed with Vodka!.","Smoke!","Nine out of ten USSP scientists agree, smoking reduces stress!","There's no cigarette like a Russian cigarette!","Cigarettes! Now with 100% less capitalism.")
},
/turf/simulated/floor/plasteel{
dir = 2;
@@ -11582,10 +11552,10 @@
},
/area/space/nearstation)
"zR" = (
/obj/machinery/portable_atmospherics/canister/toxins,
/obj/machinery/light/small{
dir = 1
},
/obj/effect/decal/cleanable/blood,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
@@ -57707,7 +57677,7 @@ of
ot
mA
mA
pb
nX
pi
mA
py
@@ -59251,7 +59221,7 @@ oE
oR
oE
oz
pb
mA
mA
mA
mm
@@ -61558,7 +61528,7 @@ mm
mB
mm
mm
oo
mm
mm
lV
mA
@@ -61816,7 +61786,7 @@ mA
zP
mm
zR
oo
mm
oL
ns
mA
@@ -62072,7 +62042,7 @@ mA
mA
mt
mm
oq
mm
mm
mm
mm
@@ -62332,7 +62302,7 @@ mm
op
oB
oM
oZ
oM
ob
mA
pu
@@ -62586,7 +62556,7 @@ zP
mA
mA
ob
or
op
nJ
oe
pa
-145
View File
@@ -1,145 +0,0 @@
// This is for Travis testing. DO NOT SET THIS AS THE GAME'S MAP NORMALLY!
#if !defined(USING_MAP_DATUM)
// Away missions
#include "map_files\RandomZLevels\academy.dmm"
#include "map_files\RandomZLevels\beach.dmm"
#include "map_files\RandomZLevels\blackmarketpackers.dmm"
#include "map_files\RandomZLevels\centcomAway.dmm"
#include "map_files\RandomZLevels\evil_santa.dmm"
#include "map_files\RandomZLevels\example.dmm"
#include "map_files\RandomZLevels\moonoutpost19.dmm"
#include "map_files\RandomZLevels\spacebattle.dmm"
#include "map_files\RandomZLevels\spacehotel.dmm"
#include "map_files\RandomZLevels\stationCollision.dmm"
#include "map_files\RandomZLevels\terrorspiders.dmm"
#include "map_files\RandomZLevels\undergroundoutpost45.dmm"
#include "map_files\RandomZLevels\wildwest.dmm"
// Lavaland Ruins
#include "map_files\RandomRuins\LavaRuins\lavaland_biodome_beach.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_biodome_clown_planet.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_biodome_winter.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_animal_hospital.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_ash_walker1.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_blooddrunk1.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_blooddrunk2.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_blooddrunk3.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_cube.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_cultaltar.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_dead_ratvar.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_envy.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_fountain_hall.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_gluttony.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_greed.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_hermit.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_hierophant.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_pizzaparty.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_pride.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_puzzle.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_random_ripley.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_seed_vault.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_sloth.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_survivalpod.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_swarmer_crash.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_syndicate_base1.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_ufo_crash.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_xeno_nest.dmm"
// Space Ruins
#include "map_files\RandomRuins\SpaceRuins\abandonedzoo.dmm"
#include "map_files\RandomRuins\SpaceRuins\asteroid1.dmm"
#include "map_files\RandomRuins\SpaceRuins\asteroid2.dmm"
#include "map_files\RandomRuins\SpaceRuins\asteroid3.dmm"
#include "map_files\RandomRuins\SpaceRuins\asteroid4.dmm"
#include "map_files\RandomRuins\SpaceRuins\asteroid5.dmm"
#include "map_files\RandomRuins\SpaceRuins\deepstorage.dmm"
#include "map_files\RandomRuins\SpaceRuins\derelict1.dmm"
#include "map_files\RandomRuins\SpaceRuins\derelict2.dmm"
#include "map_files\RandomRuins\SpaceRuins\derelict3.dmm"
#include "map_files\RandomRuins\SpaceRuins\derelict4.dmm"
#include "map_files\RandomRuins\SpaceRuins\derelict5.dmm"
#include "map_files\RandomRuins\SpaceRuins\emptyshell.dmm"
#include "map_files\RandomRuins\SpaceRuins\gasthelizards.dmm"
#include "map_files\RandomRuins\SpaceRuins\intactemptyship.dmm"
#include "map_files\RandomRuins\SpaceRuins\listeningpost.dmm"
#include "map_files\RandomRuins\SpaceRuins\mechtransport.dmm"
#include "map_files\RandomRuins\SpaceRuins\oldstation.dmm"
#include "map_files\RandomRuins\SpaceRuins\onehalf.dmm"
#include "map_files\RandomRuins\SpaceRuins\spacebar.dmm"
#include "map_files\RandomRuins\SpaceRuins\turretedoutpost.dmm"
#include "map_files\RandomRuins\SpaceRuins\way_home.dmm"
// Shuttle Templates
#include "map_files\shuttles\cargo_base.dmm"
#include "map_files\shuttles\emergency_bar.dmm"
#include "map_files\shuttles\emergency_clown.dmm"
#include "map_files\shuttles\emergency_cramped.dmm"
#include "map_files\shuttles\emergency_cyb.dmm"
#include "map_files\shuttles\emergency_dept.dmm"
#include "map_files\shuttles\emergency_meta.dmm"
#include "map_files\shuttles\emergency_mil.dmm"
#include "map_files\shuttles\emergency_narnar.dmm"
#include "map_files\shuttles\emergency_old.dmm"
#include "map_files\shuttles\ferry_base.dmm"
#include "map_files\shuttles\ferry_meat.dmm"
// Other templates
#include "map_files\templates\spacehotel\n_01.dmm"
#include "map_files\templates\spacehotel\n_02.dmm"
#include "map_files\templates\spacehotel\n_03.dmm"
#include "map_files\templates\spacehotel\n_04.dmm"
#include "map_files\templates\spacehotel\n_05.dmm"
#include "map_files\templates\spacehotel\n_06.dmm"
#include "map_files\templates\spacehotel\n_07.dmm"
#include "map_files\templates\spacehotel\n_08.dmm"
#include "map_files\templates\spacehotel\n_09.dmm"
#include "map_files\templates\spacehotel\n_10.dmm"
#include "map_files\templates\spacehotel\n_11.dmm"
#include "map_files\templates\spacehotel\n_12.dmm"
#include "map_files\templates\spacehotel\n_13.dmm"
#include "map_files\templates\spacehotel\n_14.dmm"
#include "map_files\templates\spacehotel\n_15.dmm"
#include "map_files\templates\spacehotel\n_16.dmm"
#include "map_files\templates\spacehotel\n_17.dmm"
#include "map_files\templates\spacehotel\n_18.dmm"
#include "map_files\templates\spacehotel\n_19.dmm"
#include "map_files\templates\spacehotel\s_01.dmm"
#include "map_files\templates\spacehotel\s_02.dmm"
#include "map_files\templates\spacehotel\s_03.dmm"
#include "map_files\templates\spacehotel\s_04.dmm"
#include "map_files\templates\spacehotel\s_05.dmm"
#include "map_files\templates\spacehotel\s_06.dmm"
#include "map_files\templates\light_floor_1.dmm"
#include "map_files\templates\light_floor_2.dmm"
#include "map_files\templates\light_floor_3.dmm"
#include "map_files\templates\medium_shuttle1.dmm"
#include "map_files\templates\medium_shuttle2.dmm"
#include "map_files\templates\medium_shuttle3.dmm"
#include "map_files\templates\shelter_1.dmm"
#include "map_files\templates\shelter_2.dmm"
#include "map_files\templates\small_asteroid_1.dmm"
#include "map_files\templates\small_shuttle_1.dmm"
// This is pointless, we don't run the server
/*#define MAP_TRANSITION_CONFIG list(AWAY_MISSION = UNAFFECTED,
AWAY_MISSION = UNAFFECTED,
AWAY_MISSION = UNAFFECTED,
AWAY_MISSION = UNAFFECTED,
AWAY_MISSION = UNAFFECTED,
AWAY_MISSION = UNAFFECTED,
AWAY_MISSION = UNAFFECTED,
AWAY_MISSION = UNAFFECTED,
AWAY_MISSION = UNAFFECTED,
AWAY_MISSION = UNAFFECTED)
#define USING_MAP_DATUM /datum/map*/
#elif !defined(MAP_OVERRIDE)
#warn a map has already been included.
#endif
+157
View File
@@ -0,0 +1,157 @@
// This is for Travis testing. DO NOT SET THIS AS THE GAME'S MAP NORMALLY!
#if !defined(USING_MAP_DATUM)
// Cyberiad
#include "map_files/Cyberiad/cyberiad.dmm"
#include "map_files/Cyberiad/z2.dmm"
#include "map_files/Cyberiad/z3.dmm"
#include "map_files/Cyberiad/z4.dmm"
#include "map_files/Cyberiad/z6.dmm"
// Debug Maps
#include "map_files/Debug/singletile.dmm"
#include "map_files/Debug/smoothing.dmm"
// Delta
#include "map_files/Delta/delta.dmm"
// Generic Z Levels
#include "map_files/Generic/Lavaland.dmm"
#include "map_files/Generic/z6.dmm"
#include "map_files/Generic/z7.dmm"
// MetaStation
#include "map_files/MetaStation/MetaStation.v41A.II.dmm"
#include "map_files/MetaStation/z2.dmm"
#include "map_files/MetaStation/z3.dmm"
#include "map_files/MetaStation/z4.dmm"
// Lavaland Ruins
#include "map_files/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_cube.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_dead_ratvar.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_envy.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_fountain_hall.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_greed.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_hierophant.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_pride.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_puzzle.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_sloth.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_swarmer_crash.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm"
#include "map_files/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm"
// Space Ruins
#include "map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm"
#include "map_files/RandomRuins/SpaceRuins/asteroid1.dmm"
#include "map_files/RandomRuins/SpaceRuins/asteroid2.dmm"
#include "map_files/RandomRuins/SpaceRuins/asteroid3.dmm"
#include "map_files/RandomRuins/SpaceRuins/asteroid4.dmm"
#include "map_files/RandomRuins/SpaceRuins/asteroid5.dmm"
#include "map_files/RandomRuins/SpaceRuins/deepstorage.dmm"
#include "map_files/RandomRuins/SpaceRuins/derelict1.dmm"
#include "map_files/RandomRuins/SpaceRuins/derelict2.dmm"
#include "map_files/RandomRuins/SpaceRuins/derelict3.dmm"
#include "map_files/RandomRuins/SpaceRuins/derelict4.dmm"
#include "map_files/RandomRuins/SpaceRuins/derelict5.dmm"
#include "map_files/RandomRuins/SpaceRuins/emptyshell.dmm"
#include "map_files/RandomRuins/SpaceRuins/gasthelizards.dmm"
#include "map_files/RandomRuins/SpaceRuins/intactemptyship.dmm"
#include "map_files/RandomRuins/SpaceRuins/listeningpost.dmm"
#include "map_files/RandomRuins/SpaceRuins/mechtransport.dmm"
#include "map_files/RandomRuins/SpaceRuins/oldstation.dmm"
#include "map_files/RandomRuins/SpaceRuins/onehalf.dmm"
#include "map_files/RandomRuins/SpaceRuins/spacebar.dmm"
#include "map_files/RandomRuins/SpaceRuins/turretedoutpost.dmm"
#include "map_files/RandomRuins/SpaceRuins/way_home.dmm"
#include "map_files/RandomRuins/SpaceRuins/wizardcrash.dmm"
// Gateway Missions
#include "map_files/RandomZLevels/academy.dmm"
#include "map_files/RandomZLevels/beach.dmm"
#include "map_files/RandomZLevels/blackmarketpackers.dmm"
#include "map_files/RandomZLevels/centcomAway.dmm"
#include "map_files/RandomZLevels/evil_santa.dmm"
#include "map_files/RandomZLevels/example.dmm"
#include "map_files/RandomZLevels/moonoutpost19.dmm"
#include "map_files/RandomZLevels/spacebattle.dmm"
#include "map_files/RandomZLevels/spacehotel.dmm"
#include "map_files/RandomZLevels/stationCollision.dmm"
#include "map_files/RandomZLevels/terrorspiders.dmm"
#include "map_files/RandomZLevels/undergroundoutpost45.dmm"
#include "map_files/RandomZLevels/wildwest.dmm"
// Shuttles
#include "map_files/shuttles/admin_admin.dmm"
#include "map_files/shuttles/admin_hospital.dmm"
#include "map_files/shuttles/cargo_base.dmm"
#include "map_files/shuttles/emergency_bar.dmm"
#include "map_files/shuttles/emergency_clown.dmm"
#include "map_files/shuttles/emergency_cramped.dmm"
#include "map_files/shuttles/emergency_cyb.dmm"
#include "map_files/shuttles/emergency_dept.dmm"
#include "map_files/shuttles/emergency_meta.dmm"
#include "map_files/shuttles/emergency_mil.dmm"
#include "map_files/shuttles/emergency_narnar.dmm"
#include "map_files/shuttles/emergency_old.dmm"
#include "map_files/shuttles/ferry_base.dmm"
#include "map_files/shuttles/ferry_meat.dmm"
// Templates
#include "map_files/templates/light_floor_1.dmm"
#include "map_files/templates/light_floor_2.dmm"
#include "map_files/templates/light_floor_3.dmm"
#include "map_files/templates/medium_shuttle1.dmm"
#include "map_files/templates/medium_shuttle2.dmm"
#include "map_files/templates/medium_shuttle3.dmm"
#include "map_files/templates/shelter_1.dmm"
#include "map_files/templates/shelter_2.dmm"
#include "map_files/templates/small_asteroid_1.dmm"
#include "map_files/templates/small_shuttle_1.dmm"
// Spacehotel Rooms
#include "map_files/templates/spacehotel/n_01.dmm"
#include "map_files/templates/spacehotel/n_02.dmm"
#include "map_files/templates/spacehotel/n_03.dmm"
#include "map_files/templates/spacehotel/n_04.dmm"
#include "map_files/templates/spacehotel/n_05.dmm"
#include "map_files/templates/spacehotel/n_06.dmm"
#include "map_files/templates/spacehotel/n_07.dmm"
#include "map_files/templates/spacehotel/n_08.dmm"
#include "map_files/templates/spacehotel/n_09.dmm"
#include "map_files/templates/spacehotel/n_10.dmm"
#include "map_files/templates/spacehotel/n_11.dmm"
#include "map_files/templates/spacehotel/n_12.dmm"
#include "map_files/templates/spacehotel/n_13.dmm"
#include "map_files/templates/spacehotel/n_14.dmm"
#include "map_files/templates/spacehotel/n_15.dmm"
#include "map_files/templates/spacehotel/n_16.dmm"
#include "map_files/templates/spacehotel/n_17.dmm"
#include "map_files/templates/spacehotel/n_18.dmm"
#include "map_files/templates/spacehotel/n_19.dmm"
#include "map_files/templates/spacehotel/s_01.dmm"
#include "map_files/templates/spacehotel/s_02.dmm"
#include "map_files/templates/spacehotel/s_03.dmm"
#include "map_files/templates/spacehotel/s_04.dmm"
#include "map_files/templates/spacehotel/s_05.dmm"
#include "map_files/templates/spacehotel/s_06.dmm"
#elif !defined(MAP_OVERRIDE)
#warn a map has already been included.
#endif
-1
View File
@@ -35,7 +35,6 @@
#define CANPUSH 8
#define PASSEMOTES 16 //Mob has a cortical borer or holders inside of it that need to see emotes.
#define GOTTAGOFAST 32
#define GOTTAGOFAST_METH 64
#define IGNORESLOWDOWN 128
#define GODMODE 4096
#define FAKEDEATH 8192 //Replaces stuff like changeling.changeling_fakedeath
+24
View File
@@ -90,3 +90,27 @@
#define FLASH_LIGHT_DURATION 2
#define FLASH_LIGHT_POWER 3
#define FLASH_LIGHT_RANGE 3.8
/// Returns the red part of a #RRGGBB hex sequence as number
#define GETREDPART(hexa) hex2num(copytext(hexa, 2, 4))
/// Returns the green part of a #RRGGBB hex sequence as number
#define GETGREENPART(hexa) hex2num(copytext(hexa, 4, 6))
/// Returns the blue part of a #RRGGBB hex sequence as number
#define GETBLUEPART(hexa) hex2num(copytext(hexa, 6, 8))
/// Parse the hexadecimal color into lumcounts of each perspective.
#define PARSE_LIGHT_COLOR(source) \
do { \
if (source.light_color) { \
var/__light_color = source.light_color; \
source.lum_r = GETREDPART(__light_color) / 255; \
source.lum_g = GETGREENPART(__light_color) / 255; \
source.lum_b = GETBLUEPART(__light_color) / 255; \
} else { \
source.lum_r = 1; \
source.lum_g = 1; \
source.lum_b = 1; \
}; \
} while (FALSE)
+1 -1
View File
@@ -3,4 +3,4 @@
#define CONVERSION_LOG "Conversion"
#define SAY_LOG "Say"
#define EMOTE_LOG "Emote"
#define MISC_LOG "Misc"
#define MISC_LOG "Misc"
+2 -2
View File
@@ -319,7 +319,7 @@
#define INVESTIGATE_BOMB "bombs"
// The SQL version required by this version of the code
#define SQL_VERSION 11
#define SQL_VERSION 12
// Vending machine stuff
#define CAT_NORMAL 1
@@ -345,7 +345,7 @@
#define MOUSE_OPACITY_OPAQUE 2
// Defib stats
#define DEFIB_TIME_LIMIT 120
#define DEFIB_TIME_LIMIT 300
#define DEFIB_TIME_LOSS 60
//different types of atom colorations
+4 -4
View File
@@ -48,7 +48,7 @@
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
//(in game days played) to play that role
var/global/list/special_roles = list(
GLOBAL_LIST_INIT(special_roles, list(
ROLE_ABDUCTOR = /datum/game_mode/abduction, // Abductor
ROLE_BLOB = /datum/game_mode/blob, // Blob
ROLE_CHANGELING = /datum/game_mode/changeling, // Changeling
@@ -72,10 +72,10 @@ var/global/list/special_roles = list(
ROLE_VAMPIRE = /datum/game_mode/vampire, // Vampire
ROLE_RAIDER = /datum/game_mode/heist, // Vox raider
ROLE_ALIEN, // Xenomorph
ROLE_WIZARD = /datum/game_mode/wizard, // Wizard
ROLE_WIZARD = /datum/game_mode/wizard // Wizard
// UNUSED/BROKEN ANTAGS
// ROLE_HOG_GOD = /datum/game_mode/hand_of_god,
// ROLE_HOG_CULTIST = /datum/game_mode/hand_of_god,
// ROLE_MONKEY = /datum/game_mode/monkey, Sooner or later these are going to get ported
// ROLE_GANG = /datum/game_mode/gang,
)
// ROLE_GANG = /datum/game_mode/gang
))
-17
View File
@@ -417,16 +417,6 @@
return 0
return 1
/proc/GetRedPart(const/hexa)
return hex2num(copytext(hexa, 2, 4))
/proc/GetGreenPart(const/hexa)
return hex2num(copytext(hexa, 4, 6))
/proc/GetBluePart(const/hexa)
return hex2num(copytext(hexa, 6, 8))
/proc/lavaland_equipment_pressure_check(turf/T)
. = FALSE
if(!istype(T))
@@ -438,13 +428,6 @@
if(pressure <= LAVALAND_EQUIPMENT_EFFECT_PRESSURE)
. = TRUE
/proc/GetHexColors(const/hexa)
return list(
GetRedPart(hexa),
GetGreenPart(hexa),
GetBluePart(hexa),
)
/proc/MinutesToTicks(var/minutes as num)
return minutes * 60 * 10
+1 -1
View File
@@ -580,7 +580,7 @@ world
var/B = RGB[2]
var/Y = (0.2126 * R) + (0.7152 * G) + (0.0722 * B)
return clamp((Y * 0.01), 0, 1) //Returns the brightness of a color in decimal percentage format. Can multiply light_power by this to receive 100% brightness or a lower brightness. Not a higher brightness.
return Clamp((Y * 0.01), 0, 1) //Returns the brightness of a color in decimal percentage format. Can multiply light_power by this to receive 100% brightness or a lower brightness. Not a higher brightness.
/proc/HueToAngle(hue)
// normalize hsv in case anything is screwy
+3 -3
View File
@@ -19,10 +19,10 @@ GLOBAL_VAR(command_name)
/proc/command_name()
return GLOB.using_map.dock_name
var/religion_name = null
GLOBAL_VAR(religion_name)
/proc/religion_name()
if(religion_name)
return religion_name
if(GLOB.religion_name)
return GLOB.religion_name
var/name = ""
-1
View File
@@ -4,7 +4,6 @@ GLOBAL_VAR(host)
GLOBAL_VAR(join_motd)
GLOBAL_VAR(join_tos)
GLOBAL_VAR_INIT(game_version, "ParaCode")
GLOBAL_VAR_INIT(changelog_hash, md5('html/changelog.html')) //used to check if the CL changed
GLOBAL_VAR_INIT(game_year, (text2num(time2text(world.realtime, "YYYY")) + 544))
GLOBAL_VAR_INIT(aliens_allowed, 1)
+2
View File
@@ -64,3 +64,5 @@ GLOBAL_LIST_INIT(safe_chem_list, list("antihol", "charcoal", "epinephrine", "ins
"omnizine", "stimulants", "synaptizine", "potass_iodide", "oculine", "mannitol", "styptic_powder",
"spaceacillin", "salglu_solution", "sal_acid", "cryoxadone", "blood", "synthflesh", "hydrocodone",
"mitocholide", "rezadone"))
GLOBAL_LIST_INIT(safe_chem_applicator_list, list("silver_sulfadiazine", "styptic_powder", "synthflesh"))
+6 -6
View File
@@ -261,12 +261,12 @@
if(incapacitated())
return
var/face_dir = get_cardinal_dir(src, A)
if(forced_look == face_dir)
if(!face_dir || forced_look == face_dir || A == src)
forced_look = null
to_chat(src, "<span class='notice'>You are no longer facing any direction.</span>")
to_chat(src, "<span class='notice'>Cancelled direction lock.</span>")
return
forced_look = face_dir
to_chat(src, "<span class='notice'>You are now facing [dir2text(forced_look)].</span>")
to_chat(src, "<span class='userdanger'>You are now facing [dir2text(forced_look)]. To cancel this, shift-middleclick yourself.</span>")
/*
Middle shift-control-click
@@ -274,12 +274,12 @@
*/
/mob/proc/MiddleShiftControlClickOn(atom/A)
var/face_uid = A.UID()
if(forced_look == face_uid)
if(forced_look == face_uid || A == src)
forced_look = null
to_chat(src, "<span class='notice'>You are no longer facing [A].</span>")
to_chat(src, "<span class='notice'>Cancelled direction lock.</span>")
return
forced_look = face_uid
to_chat(src, "<span class='notice'>You are now facing [A].</span>")
to_chat(src, "<span class='userdanger'>You are now facing [A]. To cancel this, shift-middleclick yourself.</span>")
// In case of use break glass
/*
+1 -1
View File
@@ -58,7 +58,7 @@
else
return 1
var/obj/item/organ/external/O = M.get_organ(user.zone_selected)
if((is_sharp(src) || (isscrewdriver(src) && O.is_robotic())) && user.a_intent == INTENT_HELP)
if((is_sharp(src) || (isscrewdriver(src) && O?.is_robotic())) && user.a_intent == INTENT_HELP)
if(!attempt_initiate_surgery(src, M, user))
return FALSE
else
+1 -1
View File
@@ -146,7 +146,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
msg = "The [BadBoy.name] subsystem was the last to fire for 2 controller restarts. It will be recovered now and disabled if it happens again."
FireHim = TRUE
if(3)
msg = "The [BadBoy.name] subsystem seems to be destabilizing the MC and will be offlined."
msg = "The [BadBoy.name] subsystem seems to be destabilizing the MC and will be offlined. <span class='info'>The following implications are now in effect: [BadBoy.offline_implications]</span>"
BadBoy.flags |= SS_NO_FIRE
if(msg)
to_chat(GLOB.admins, "<span class='boldannounce'>[msg]</span>")
+2
View File
@@ -35,6 +35,8 @@
var/static/list/failure_strikes //How many times we suspect a subsystem type has crashed the MC, 3 strikes and you're out!
var/offline_implications = "None" // What are the implications of this SS being offlined?
//Do not override
///datum/controller/subsystem/New()
+1
View File
@@ -3,6 +3,7 @@ SUBSYSTEM_DEF(acid)
priority = FIRE_PRIORITY_ACID
flags = SS_NO_INIT|SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
offline_implications = "Objects will no longer react to acid. No immediate action is needed."
var/list/currentrun = list()
var/list/processing = list()
+9 -8
View File
@@ -5,6 +5,7 @@ SUBSYSTEM_DEF(afk)
name = "AFK Watcher"
wait = 300
flags = SS_BACKGROUND
offline_implications = "Players will no longer be marked as AFK. No immediate action is needed."
var/list/afk_players = list() // Associative list. ckey as key and AFK state as value
@@ -17,27 +18,27 @@ SUBSYSTEM_DEF(afk)
for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
if(!H.ckey) // Useless non ckey creatures
continue
var/turf/T
var/turf/T
// Only players and players with the AFK watch enabled
// No dead, unconcious, restrained, people without jobs, people on other Z levels than the station or antags
if(!H.client || !H.client.prefs.afk_watch || !H.mind || \
H.stat || H.restrained() || !H.job || H.mind.special_role || \
!is_station_level((T = get_turf(H)).z)) // Assign the turf as last. Small optimization
if(afk_players[H.ckey])
if(afk_players[H.ckey])
toRemove += H.ckey
continue
var/mins_afk = round(H.client.inactivity / 600)
if(mins_afk < config.warn_afk_minimum)
if(afk_players[H.ckey])
toRemove += H.ckey
continue
if(!afk_players[H.ckey])
afk_players[H.ckey] = AFK_WARNED
warn(H, "<span class='danger'>You are AFK for [mins_afk] minutes. You will be cryod after [config.auto_cryo_afk] total minutes and fully despawned after [config.auto_despawn_afk] total minutes. Please move or click in game if you want to avoid being despawned.</span>")
else
else
var/area/A = T.loc // Turfs loc is the area
if(afk_players[H.ckey] == AFK_WARNED)
if(mins_afk >= config.auto_cryo_afk && A.can_get_auto_cryod)
@@ -50,14 +51,14 @@ SUBSYSTEM_DEF(afk)
afk_players[H.ckey] = AFK_CRYOD
msg_admins(H, mins_afk, T, "put into cryostorage")
warn(H, "<span class='danger'>You are AFK for [mins_afk] minutes and have been moved to cryostorage. After being AFK for [config.auto_despawn_afk] total minutes you will be fully despawned. Please eject yourself (right click, eject) out of the cryostorage if you want to avoid being despawned.</span>")
else if(mins_afk >= config.auto_despawn_afk)
var/obj/machinery/cryopod/P = H.loc
msg_admins(H, mins_afk, T, "forcefully despawned")
warn(H, "<span class='danger'>You are have been despawned after being AFK for [mins_afk] minutes.</span>")
toRemove += H.ckey
P.despawn_occupant()
removeFromWatchList(toRemove)
/datum/controller/subsystem/afk/proc/warn(mob/living/carbon/human/H, text)
+1
View File
@@ -14,6 +14,7 @@ SUBSYSTEM_DEF(air)
wait = 5
flags = SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
offline_implications = "Turfs will no longer process atmos, and all atmospheric machines (including cryotubes) will no longer function. Shuttle call recommended."
var/cost_turfs = 0
var/cost_groups = 0
var/cost_highpressure = 0
+1
View File
@@ -1,6 +1,7 @@
SUBSYSTEM_DEF(alarms)
name = "Alarms"
init_order = INIT_ORDER_ALARMS // 2
offline_implications = "Alarms (Power, camera, fire, etc) will no longer be checked. No immediate action is needed."
var/datum/alarm_handler/atmosphere/atmosphere_alarm = new()
var/datum/alarm_handler/burglar/burglar_alarm = new()
var/datum/alarm_handler/camera/camera_alarm = new()
+263
View File
@@ -0,0 +1,263 @@
/*
Subsystem core for ParadiseSS13 changelogs
Author: AffectedArc07
Basically this SS extracts changelogs from the past 30 days from the database, and cleanly formats them into HTML that the players can see
It only runs the extraction on initialize to ensure that the changelog doesnt change mid round, and to reduce the amount of DB calls that need to be done
The changelog entries are generated from the PHP scripts in tools/githubChangelogProcessor.php
This SS also handles the checking of player CL dates and informing them if it has changed
*/
SUBSYSTEM_DEF(changelog)
name = "Changelog"
flags = SS_NO_FIRE
var/current_cl_timestamp = "0" // Timestamp is seconds since UNIX epoch (1st January 1970). ITs also a string because BYOND doesnt like big numbers.
var/ss_ready = FALSE // Is the SS ready? We dont want to run procs if we have not generated yet
var/list/startup_clients_button = list() // Clients who connected before initialization who need their button color updating
var/list/startup_clients_open = list() // Clients who connected before initialization who need the CL opening
var/changelogHTML = "" // HTML that the changelog will use to display
/datum/controller/subsystem/changelog/Initialize()
// This entire subsystem relies on SQL being here.
if(!GLOB.dbcon.IsConnected())
return ..()
var/DBQuery/latest_cl_date = GLOB.dbcon.NewQuery("SELECT UNIX_TIMESTAMP(date_merged) AS ut FROM [format_table_name("changelog")] ORDER BY date_merged DESC LIMIT 1")
if(!latest_cl_date.Execute())
var/err = latest_cl_date.ErrorMsg()
log_game("SQL ERROR during SSchangelog initialization L24. Error: \[[err]\]\n")
message_admins("SQL ERROR during SSchangelog initialization L24. Error: \[[err]\]\n")
// Abort if we cant do this
return ..()
while(latest_cl_date.NextRow())
current_cl_timestamp = latest_cl_date.item[1]
if(!GenerateChangelogHTML()) // if this failed to generate
to_chat(world, "<span class='alert'>WARNING: Changelog failed to generate. Please inform a coder/server dev</span>")
return ..()
ss_ready = TRUE
// Now we can alert anyone who wanted to check the changelog
for(var/x in startup_clients_button)
var/client/C = x
UpdatePlayerChangelogButton(C)
// Now we can alert anyone who wanted to check the changelog
for(var/client/C in startup_clients_open)
OpenChangelog(C)
return ..()
/datum/controller/subsystem/changelog/proc/UpdatePlayerChangelogDate(client/C)
if(!ss_ready)
return // Only return here, we dont have to worry about a queue list because this will be called from ShowChangelog()
// Technically this is only for the date but we can also do the UI button at the same time
var/datum/preferences/P = GLOB.preferences_datums[C.ckey]
if(P.toggles & UI_DARKMODE)
winset(C, "rpane.changelog", "background-color=#40628a;font-color=#ffffff;font-style=none")
else
winset(C, "rpane.changelog", "background-color=none;font-style=none")
C.prefs.lastchangelog = current_cl_timestamp
var/DBQuery/updatePlayerCLTime = GLOB.dbcon.NewQuery("UPDATE [format_table_name("player")] SET lastchangelog='[sanitizeSQL(current_cl_timestamp)]' WHERE ckey='[C.ckey]'")
if(!updatePlayerCLTime.Execute())
var/err = updatePlayerCLTime.ErrorMsg()
log_game("SQL ERROR during lastchangelog updating. Error: \[[err]\]\n")
message_admins("SQL ERROR during lastchangelog updating. Error: \[[err]\]\n")
to_chat(C, "Couldn't update your last seen changelog, please try again later.")
return FALSE
return TRUE
/datum/controller/subsystem/changelog/proc/UpdatePlayerChangelogButton(client/C)
// If SQL aint even enabled, just set the button to default style
if(!GLOB.dbcon.IsConnected())
if(C.prefs.toggles & UI_DARKMODE)
winset(C, "rpane.changelog", "background-color=#40628a;text-color=#FFFFFF")
else
winset(C, "rpane.changelog", "background-color=none;text-color=#000000")
return
// If SQL is enabled but we aint ready, queue them up, and use the default style
if(!ss_ready)
startup_clients_button |= C
if(C.prefs.toggles & UI_DARKMODE)
winset(C, "rpane.changelog", "background-color=#40628a;text-color=#FFFFFF")
else
winset(C, "rpane.changelog", "background-color=none;text-color=#000000")
return
// Sanity check to ensure clients still exist (If a client DCs mid startup this would runtime)
if(C && C.prefs)
// If we are ready, process the button style
if(C.prefs.lastchangelog != current_cl_timestamp)
winset(C, "rpane.changelog", "background-color=#bb7700;text-color=#FFFFFF;font-style=bold")
to_chat(C, "<span class='info'>Changelog has changed since your last visit.</span>")
else
if(C.prefs.toggles & UI_DARKMODE)
winset(C, "rpane.changelog", "background-color=#40628a;text-color=#FFFFFF")
else
winset(C, "rpane.changelog", "background-color=none;text-color=#000000")
/datum/controller/subsystem/changelog/proc/OpenChangelog(client/C)
// If SQL isnt enabled, dont even queue them, just tell them it wont work
if(!GLOB.dbcon.IsConnected())
to_chat(C, "<span class='notice'>This server is not running with an SQL backend. Changelog is unavailable.</span>")
return
// If SQL is enabled but we aint ready, queue them up
if(!ss_ready)
startup_clients_open |= C
to_chat(C, "<span class='notice'>The changelog system is still initializing. The changelog will open for you once it has initialized.</span>")
return
UpdatePlayerChangelogDate(C)
UpdatePlayerChangelogButton(C)
var/datum/browser/cl_popup = new(C.mob, "changelog", "Changelog", 700, 800)
cl_popup.set_content(changelogHTML)
cl_popup.open()
/client/verb/changes()
set name = "Changelog"
set desc = "View the changelog."
set category = "OOC"
// Just invoke the actual CL thing
SSchangelog.OpenChangelog(src)
// Helper to turn CL types into a fontawesome icon instead of an image
// The colors are #28a745 for green, #fd7e14 for orange, and #dc3545 for red.
// These colours are from bootstrap and look good with black and white
/datum/controller/subsystem/changelog/proc/Text2Icon(text)
switch(text)
if("FIX")
return "<i title='Fix' class='fas fa-tools'></i></span>" // Fixes are white because while they are good, they have no negative coutnerpart
if("WIP")
return "<span style='color: #fd7e14;'><i title='Work In Progress' class='fas fa-hard-hat'></i></span>" // WIP stuff is orange because new code is good but its not done yet
if("TWEAK")
return "<i title='Tweak' class='fas fa-sliders-h'></i>" // Tweaks are white because they could be good or bad, and theres no specific add or remove
if("SOUNDADD")
return "<span style='color: #28a745;'><i title='Sound Added' class='fas fa-volume-up'></i></span>" // Sound additions are green because its something new
if("SOUNDDEL")
return "<span style='color: #dc3545;'><i title='Sound Removed' class='fas fa-volume-mute'></i></span>" // Sound removals are red because something has been removed
if("CODEADD")
return "<span style='color: #28a745;'><i title='Code Addition' class='fas fa-plus'></i></span>" // Code additions are green because its something new
if("CODEDEL")
return "<span style='color: #dc3545;'><i title='Code Removal' class='fas fa-minus'></i></span>" // Code removals are red becuase someting has been removed
if("IMAGEADD")
return "<span style='color: #28a745;'><i title='Image/Sprite Addition' class='fas fa-folder-plus'></i></span>" // Image additions are green because something has been added
if("IMAGEDEL")
return "<span style='color: #dc3545;'><i title='Image/Sprite Removal' class='fas fa-folder-minus'></i></span>" // Image removals are red because something has been removed
if("SPELLCHECK")
return "<i title='Spelling/Grammar Fix' class='fas fa-font'></i>" // Spellcheck is white because theres no dedicated negative to it, so theres no red for it to collate with
if("EXPERIMENT")
return "<span style='color: #fd7e14;'><i title='Experimental' class='fas fa-exclamation-triangle'></i></span>" // Experimental stuff is orange because while its a new feature, its unstable
else // Just incase the DB somehow breaks
return "<span style='color: #28a745;'><i title='Code Addition' class='fas fa-plus'></i></span>" // Same here
// This proc is the star of the show
/datum/controller/subsystem/changelog/proc/GenerateChangelogHTML()
// Modify the code below to modify the header of the changelog
var/changelog_header = {"
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" rel="stylesheet">
<title>ParadiseSS13 Changelog</title>
<link rel='styelsheet' href='fontawesome.min.css'>
<center>
<p style='font-size: 20px'><b>Paradise Station Changelog</b></p>
<p><a href='?src=[UID()];openPage=forum'>Forum</a> - <a href='?src=[UID()];openPage=wiki'>Wiki</a> - <a href='?src=[UID()];openPage=github'>GitHub</a></p>
</center>
"}
var/list/prs_to_process = list()
// Grab all from last 30 days
var/DBQuery/pr_list_query = GLOB.dbcon.NewQuery("SELECT DISTINCT pr_number FROM changelog WHERE date_merged BETWEEN NOW() - INTERVAL 30 DAY AND NOW() ORDER BY date_merged DESC")
if(!pr_list_query.Execute())
var/err = pr_list_query.ErrorMsg()
log_game("SQL ERROR during CL generation L143. Error: \[[err]\]\n")
message_admins("SQL ERROR during CL generation L143. Error: \[[err]\]\n")
return FALSE
while(pr_list_query.NextRow())
prs_to_process += text2num(pr_list_query.item[1])
// Load in the header
changelogHTML += changelog_header
// Make blocks for all the PRs
for(var/pr_number in prs_to_process)
// Initial declarations
var/pr_block = "" // HTML for the changelog section
var/author = "" // Author of the PR
var/merge_date = "" // Timestamp of when the PR was merged
// Now we gather the data from the DB
// Also we probably dont need to sanitize the PR number but you never know
var/DBQuery/pr_meta = GLOB.dbcon.NewQuery("SELECT author,DATE(date_merged) AS date FROM changelog WHERE pr_number = [sanitizeSQL(pr_number)] LIMIT 1")
if(!pr_meta.Execute())
var/err = pr_meta.ErrorMsg()
log_game("SQL ERROR during CL generation L190. Error: \[[err]\]\n")
message_admins("SQL ERROR during CL generation L190. Error: \[[err]\]\n")
return FALSE
while(pr_meta.NextRow())
author = pr_meta.item[1]
merge_date = pr_meta.item[2]
// Now for each actual entry
var/DBQuery/db_entries = GLOB.dbcon.NewQuery("SELECT cl_type, cl_entry FROM changelog WHERE pr_number = [sanitizeSQL(pr_number)]")
if(!db_entries.Execute())
var/err = db_entries.ErrorMsg()
log_game("SQL ERROR during CL generation L204. Error: \[[err]\]\n")
message_admins("SQL ERROR during CL generation L204. Error: \[[err]\]\n")
return FALSE
// Now we make a changelog block
pr_block += "<div class='statusDisplay'>"
// If the github URL in the config has a trailing slash, it doesnt matter here, thankfully github accepts having a double slash: https://github.com/org/repo//pull/1
pr_block += "<p class='white'><a href='?src=[UID()];openPR=[pr_number]'>#[pr_number]</a> by <b>[author]</b> (Merged on [merge_date])</span>"
while(db_entries.NextRow())
pr_block += "<p>[Text2Icon(db_entries.item[1])] [db_entries.item[2]]</p>"
pr_block += "</div><br>"
changelogHTML += pr_block
// Make sure we return TRUE so we know it worked
return TRUE
// Topic handler so that PRs and forums and stuff open in another window
/datum/controller/subsystem/changelog/Topic(href, href_list)
// Handler to open pages in your browser instead of inside the CL window
// Yes usr.client is gross here but src is the subsystem
// Takes the page to open as an argument
if(href_list["openPage"])
switch(href_list["openPage"])
if("forum")
usr.client.forum()
if("wiki")
// Wiki needs snowflake because it has no cancel button
if(config.wikiurl)
if(alert("This will open the wiki in your browser. Are you sure?",,"Yes","No")=="No")
return
usr.client.wiki("") // Blank arg is important here
else
to_chat(usr, "<span class='danger'>The Wiki URL is not set in the server configuration. Please inform the server host.</span>")
if("github")
usr.client.github()
// Takes a PR number as argument
if(href_list["openPR"])
if(config.githuburl)
if(alert("This will open PR #[href_list["openPR"]] in your browser. Are you sure?",,"Yes","No")=="No")
return
var/url = "[config.githuburl]/pull/[href_list["openPR"]]"
usr << link(url)
else
to_chat(usr, "<span class='danger'>The GitHub URL is not set in the server configuration. PRs cannot be opened from changelog view. Please inform the server host.</span>")
+1
View File
@@ -4,6 +4,7 @@ SUBSYSTEM_DEF(chat)
wait = 1
priority = FIRE_PRIORITY_CHAT
init_order = INIT_ORDER_CHAT
offline_implications = "Chat messages will no longer be cleanly queued. No immediate action is needed."
var/list/payload = list()
+1
View File
@@ -2,6 +2,7 @@ SUBSYSTEM_DEF(events)
name = "Events"
init_order = INIT_ORDER_EVENTS
runlevels = RUNLEVEL_GAME
offline_implications = "Random events will no longer happen. No immediate action is needed."
// Report events at the end of the rouund
var/report_at_round_end = 0
+1
View File
@@ -3,6 +3,7 @@ SUBSYSTEM_DEF(fires)
priority = FIRE_PRIOTITY_BURNING
flags = SS_NO_INIT|SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
offline_implications = "Objects will no longer react to fires. No immediate action is needed."
var/list/currentrun = list()
var/list/processing = list()
+1
View File
@@ -5,6 +5,7 @@ SUBSYSTEM_DEF(garbage)
flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
init_order = INIT_ORDER_GARBAGE
offline_implications = "Garbage collection is no longer functional, and objects will not be qdel'd. Immediate server restart recommended."
var/list/collection_timeout = list(0, 2 MINUTES, 10 SECONDS) // deciseconds to wait before moving something up in the queue to the next level
@@ -4,6 +4,7 @@ SUBSYSTEM_DEF(icon_smooth)
wait = 1
priority = FIRE_PRIOTITY_SMOOTHING
flags = SS_TICKER
offline_implications = "Objects will no longer smooth together properly. No immediate action is needed."
var/list/smooth_queue = list()
+2 -1
View File
@@ -4,6 +4,7 @@ SUBSYSTEM_DEF(idlenpcpool)
priority = FIRE_PRIORITY_IDLE_NPC
wait = 60
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
offline_implications = "Idle simple animals will no longer process. Shuttle call recommended."
var/list/currentrun = list()
var/static/list/idle_mobs_by_zlevel[][]
@@ -39,4 +40,4 @@ SUBSYSTEM_DEF(idlenpcpool)
if(SA.stat != DEAD)
SA.consider_wakeup()
if(MC_TICK_CHECK)
return
return
+2 -1
View File
@@ -5,6 +5,7 @@ SUBSYSTEM_DEF(input)
flags = SS_TICKER
priority = FIRE_PRIORITY_INPUT
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
offline_implications = "Player input will no longer be recognised. Immediate server restart recommended."
var/list/macro_sets
var/list/movement_keys
@@ -24,7 +25,7 @@ SUBSYSTEM_DEF(input)
// This is for when macro sets are eventualy datumized
/datum/controller/subsystem/input/proc/setup_default_macro_sets()
var/list/static/default_macro_sets
if(default_macro_sets)
macro_sets = default_macro_sets
return
+1
View File
@@ -3,6 +3,7 @@ SUBSYSTEM_DEF(jobs)
init_order = INIT_ORDER_JOBS // 12
wait = 3000 // 5 minutes (Deciseconds)
runlevels = RUNLEVEL_GAME
offline_implications = "Job playtime hours will no longer be logged. No immediate action is needed."
//List of all jobs
var/list/occupations = list()
+1
View File
@@ -7,6 +7,7 @@ SUBSYSTEM_DEF(lighting)
wait = 2
init_order = INIT_ORDER_LIGHTING
flags = SS_TICKER
offline_implications = "Lighting will no longer update. Shuttle call recommended."
/datum/controller/subsystem/lighting/stat_entry()
..("L:[GLOB.lighting_update_lights.len]|C:[GLOB.lighting_update_corners.len]|O:[GLOB.lighting_update_objects.len]")
+1
View File
@@ -6,6 +6,7 @@ SUBSYSTEM_DEF(machines)
name = "Machines"
init_order = INIT_ORDER_MACHINES
flags = SS_KEEP_TIMING
offline_implications = "Machinery will no longer process. Shuttle call recommended."
var/list/processing = list()
var/list/currentrun = list()
+1
View File
@@ -3,6 +3,7 @@ SUBSYSTEM_DEF(mobs)
priority = FIRE_PRIORITY_MOBS
flags = SS_KEEP_TIMING
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
offline_implications = "Mobs will no longer process. Immediate server restart recommended."
var/list/currentrun = list()
var/static/list/clients_by_zlevel[][]
@@ -2,6 +2,7 @@ SUBSYSTEM_DEF(mob_hunt)
name = "Nano-Mob Hunter GO Server"
init_order = INIT_ORDER_NANOMOB
priority = FIRE_PRIORITY_NANOMOB // Low priority, no need for MC_TICK_CHECK due to extremely low performance impact.
offline_implications = "Nano-Mob Hunter will no longer spawn mobs. No immediate action is needed."
var/max_normal_spawns = 15 //change this to adjust the number of normal spawns that can exist at one time. trapped spawns (from traitors) don't count towards this
var/list/normal_spawns = list()
var/max_trap_spawns = 15 //change this to adjust the number of trap spawns that can exist at one time. traps spawned beyond this point clear the oldest traps
+1
View File
@@ -4,6 +4,7 @@ SUBSYSTEM_DEF(nanoui)
flags = SS_NO_INIT
priority = FIRE_PRIORITY_NANOUI
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
offline_implications = "All NanoUIs will no longer process. Shuttle call recommended."
var/list/currentrun = list()
var/list/open_uis = list() // A list of open UIs, grouped by src_object and ui_key.
+1
View File
@@ -4,6 +4,7 @@ SUBSYSTEM_DEF(nightshift)
priority = FIRE_PRIORITY_NIGHTSHIFT
wait = 600
flags = SS_NO_TICK_CHECK
offline_implications = "The game will no longer shift between day and night lighting. No immediate action is needed."
var/nightshift_active = FALSE
var/nightshift_start_time = 702000 //7:30 PM, station time
+1
View File
@@ -3,6 +3,7 @@ SUBSYSTEM_DEF(npcpool)
flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
priority = FIRE_PRIORITY_NPC
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
offline_implications = "Simple animals will no longer process. Shuttle call recommended."
var/list/currentrun = list()
+1
View File
@@ -4,6 +4,7 @@ SUBSYSTEM_DEF(overlays)
wait = 1
priority = FIRE_PRIORITY_OVERLAYS
init_order = INIT_ORDER_OVERLAY
offline_implications = "Overlays may look strange. No immediate action is needed."
var/list/queue
var/list/stats
+1
View File
@@ -4,6 +4,7 @@ SUBSYSTEM_DEF(parallax)
flags = SS_POST_FIRE_TIMING | SS_BACKGROUND
priority = FIRE_PRIORITY_PARALLAX
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
offline_implications = "Space parallax will no longer move around. No immediate action is needed."
var/list/currentrun
var/planet_x_offset = 128
var/planet_y_offset = 128
+1
View File
@@ -6,6 +6,7 @@ SUBSYSTEM_DEF(shuttle)
init_order = INIT_ORDER_SHUTTLE
flags = SS_KEEP_TIMING|SS_NO_TICK_CHECK
runlevels = RUNLEVEL_SETUP | RUNLEVEL_GAME
offline_implications = "Shuttles will no longer function and cargo will not generate points. Immediate server restart recommended."
var/list/mobile = list()
var/list/stationary = list()
var/list/transit = list()
+1
View File
@@ -4,6 +4,7 @@ SUBSYSTEM_DEF(spacedrift)
wait = 5
flags = SS_NO_INIT|SS_KEEP_TIMING
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
offline_implications = "Mobs will no longer respect a lack of gravity. No immediate action is needed."
var/list/currentrun = list()
var/list/processing = list()
+1
View File
@@ -3,6 +3,7 @@ SUBSYSTEM_DEF(sun)
wait = 600
flags = SS_NO_TICK_CHECK
init_order = INIT_ORDER_SUN
offline_implications = "Solar panels will no longer rotate. No immediate action is needed."
var/angle
var/dx
var/dy
+1
View File
@@ -7,6 +7,7 @@ SUBSYSTEM_DEF(throwing)
wait = 1
flags = SS_NO_INIT|SS_KEEP_TIMING|SS_TICKER
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
offline_implications = "Thrown objects may not react properly. Shuttle call recommended."
var/list/currentrun
var/list/processing = list()
+7 -6
View File
@@ -5,6 +5,7 @@ SUBSYSTEM_DEF(ticker)
priority = FIRE_PRIORITY_TICKER
flags = SS_KEEP_TIMING
runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME
offline_implications = "The game is no longer aware of when the round ends. Immediate server restart recommended."
var/round_start_time = 0
var/const/restart_timeout = 600
@@ -97,7 +98,7 @@ SUBSYSTEM_DEF(ticker)
mode.check_finished() // some modes contain var-changing code in here, so call even if we don't uses result
else
game_finished |= mode.check_finished()
if(game_finished)
if(game_finished || force_ending)
current_state = GAME_STATE_FINISHED
if(GAME_STATE_FINISHED)
current_state = GAME_STATE_FINISHED
@@ -309,15 +310,12 @@ SUBSYSTEM_DEF(ticker)
cinematic.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
cinematic.screen_loc = "1,0"
var/obj/structure/bed/temp_buckle = new(src)
if(station_missed)
for(var/mob/M in GLOB.mob_list)
M.buckled = temp_buckle //buckles the mob so it can't do anything
if(M.client)
M.client.screen += cinematic //show every client the cinematic
else //nuke kills everyone on z-level 1 to prevent "hurr-durr I survived"
for(var/mob/M in GLOB.mob_list)
M.buckled = temp_buckle
if(M.stat != DEAD)
var/turf/T = get_turf(M)
if(T && is_station_level(T.z) && !istype(M.loc, /obj/structure/closet/secure_closet/freezer))
@@ -387,8 +385,6 @@ SUBSYSTEM_DEF(ticker)
//Otherwise if its a verb it will continue on afterwards.
spawn(300)
QDEL_NULL(cinematic) //end the cinematic
if(temp_buckle)
qdel(temp_buckle) //release everybody
@@ -518,6 +514,11 @@ SUBSYSTEM_DEF(ticker)
//Ask the event manager to print round end information
SSevents.RoundEnd()
//make big obvious note in game logs that round ended
log_game("///////////////////////////////////////////////////////")
log_game("///////////////////// ROUND ENDED /////////////////////")
log_game("///////////////////////////////////////////////////////")
// Add AntagHUD to everyone, see who was really evil the whole time!
for(var/datum/atom_hud/antag/H in GLOB.huds)
for(var/m in GLOB.player_list)
+1
View File
@@ -9,6 +9,7 @@ SUBSYSTEM_DEF(timer)
init_order = INIT_ORDER_TIMER
flags = SS_TICKER|SS_NO_INIT
offline_implications = "The game will no longer process timers. Immediate server restart recommended."
var/list/second_queue = list() //awe, yes, you've had first queue, but what about second queue?
var/list/hashes = list()
+1
View File
@@ -3,6 +3,7 @@ SUBSYSTEM_DEF(vote)
wait = 10
flags = SS_KEEP_TIMING|SS_NO_INIT
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
offline_implications = "Votes (Endround shuttle) will no longer function. Shuttle call recommended."
var/initiator = null
var/started_time = null
+1
View File
@@ -9,6 +9,7 @@ SUBSYSTEM_DEF(weather)
flags = SS_BACKGROUND
wait = 10
runlevels = RUNLEVEL_GAME
offline_implications = "Ash storms will no longer trigger. No immediate action is needed."
var/list/processing = list()
var/list/eligible_zlevels = list()
var/list/next_hit_by_zlevel = list() //Used by barometers to know when the next storm is coming
+10 -10
View File
@@ -62,15 +62,15 @@
if(sorted_laws.len)
return
for(var/ion_law in ion_laws)
sorted_laws += ion_law
for(var/evil_law in devil_laws)
sorted_laws += evil_law
if(zeroth_law)
sorted_laws += zeroth_law
for(var/ion_law in ion_laws)
sorted_laws += ion_law
for(var/evil_law in devil_laws)
sorted_laws += evil_law
var/index = 1
for(var/datum/ai_law/inherent_law in inherent_laws)
inherent_law.index = index++
@@ -133,12 +133,12 @@
for(var/datum/ai_law/AL in devil_laws)
if(AL.law == law)
return
var/new_law = new/datum/ai_law/sixsixsix(law)
devil_laws += new_law
if(state_devil.len < devil_laws.len)
state_devil += 1
sorted_laws.Cut()
/datum/ai_laws/proc/add_ion_law(var/law)
@@ -209,9 +209,9 @@
/datum/ai_law/ion/delete_law(var/datum/ai_laws/laws)
laws.internal_delete_law(laws.ion_laws, laws.state_ion, src)
/datum/ai_law/sixsixsix/delete_law(var/datum/ai_laws/laws)
laws.internal_delete_law(laws.devil_laws, laws.state_devil, src)
laws.internal_delete_law(laws.devil_laws, laws.state_devil, src)
/datum/ai_law/inherent/delete_law(var/datum/ai_laws/laws)
laws.internal_delete_law(laws.inherent_laws, laws.state_inherent, src)
@@ -62,4 +62,4 @@ Bonus
M.reagents.add_reagent("oculine", 20)
else
if(prob(SYMPTOM_ACTIVATION_PROB * 5))
to_chat(M, "<span class='notice'>[pick("Your eyes feel great.","You feel like your eyes can focus more clearly.", "You don't feel the need to blink.","Your ears feel great.","Your healing feels more acute.")]</span>")
to_chat(M, "<span class='notice'>[pick("Your eyes feel great.","You feel like your eyes can focus more clearly.", "You don't feel the need to blink.","Your ears feel great.","Your hearing feels more acute.")]</span>")
+1 -1
View File
@@ -199,4 +199,4 @@
affected_mob.emote("collapse")
if(prob(12))
to_chat(affected_mob, "<span class='warning'>You feel [pick("tired", "exhausted", "sluggish")].</span>")
affected_mob.Slowed(rand(4, 16))
affected_mob.Slowed(rand(4, 16))
+1 -1
View File
@@ -645,7 +645,7 @@ What are the archived variables for?
((nitrogen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen) || (nitrogen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen)))
return 0
if((abs(carbon_dioxide-sample.carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && \
((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide)))
((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (carbon_dioxide > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide)))
return 0
if((abs(toxins-sample.toxins) > MINIMUM_AIR_TO_SUSPEND) && \
((toxins < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins) || (toxins > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins)))
+3
View File
@@ -120,6 +120,9 @@
dat += "<span>Mobs being used:</span>"
for(var/i in selected_mobs)
var/mob/M = i
if(QDELETED(M))
selected_mobs -= i
continue
dat += "<a href='?src=[UID()];remove_mob=\ref[M]'>[get_display_name(M)]</a>"
dat += "<a href='?src=[UID()];add_mob=1'>Add Mob</a>"
dat += "<a href='?src=[UID()];add_mob_ckey=1'>Add Mob (by ckey)</a>"
-2
View File
@@ -63,8 +63,6 @@
var/datum/mind/soulOwner //who owns the soul. Under normal circumstances, this will point to src
var/hasSoul = TRUE
var/rev_cooldown = 0
var/isholy = FALSE // is this person a chaplain or admin role allowed to use bibles
var/isblessed = FALSE // is this person blessed by a chaplain?
var/num_blessed = 0 // for prayers
+6
View File
@@ -176,3 +176,9 @@
head = /obj/item/clothing/head/helmet/space/plasmaman/blueshield
uniform = /obj/item/clothing/under/plasmaman/blueshield
/datum/outfit/plasmaman/wizard
name = "Wizard Plasmaman"
head = /obj/item/clothing/head/helmet/space/plasmaman/wizard
uniform = /obj/item/clothing/under/plasmaman/wizard
+2
View File
@@ -79,6 +79,8 @@
target.forceMove(pick(L))
playsound(get_turf(user), sound2, 50,1)
user.update_action_buttons_icon() //Update action buttons as some spells might now be castable
return
/obj/effect/proc_holder/spell/targeted/area_teleport/invocation(area/chosenarea = null)
+11 -11
View File
@@ -28,7 +28,7 @@
config.continuous_rounds = 0
return ..()
/obj/effect/proc_holder/spell/targeted/lichdom/cast(list/targets,mob/user = usr)
/obj/effect/proc_holder/spell/targeted/lichdom/cast(list/targets, mob/user = usr)
if(!config.continuous_rounds)
existence_stops_round_end = 1
config.continuous_rounds = 1
@@ -36,7 +36,7 @@
for(var/mob/M in targets)
var/list/hand_items = list()
if(iscarbon(M))
hand_items = list(M.get_active_hand(),M.get_inactive_hand())
hand_items = list(M.get_active_hand(), M.get_inactive_hand())
if(marked_item && !stat_allowed) //sanity, shouldn't happen without badminry
marked_item = null
@@ -74,12 +74,9 @@
var/mob/old_body = current_body
var/turf/body_turf = get_turf(old_body)
current_body = lich
lich.Weaken(10+10*resurrections)
lich.Weaken(10 + 10 * resurrections)
++resurrections
lich.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(lich), slot_shoes)
lich.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(lich), slot_w_uniform)
lich.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(lich), slot_wear_suit)
lich.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/black(lich), slot_head)
equip_lich(lich)
if(old_body && old_body.loc)
if(iscarbon(old_body))
@@ -127,7 +124,10 @@
H.unEquip(H.head)
H.unEquip(H.shoes)
H.unEquip(H.head)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/black(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(H), slot_w_uniform)
equip_lich(H)
/obj/effect/proc_holder/spell/targeted/lichdom/proc/equip_lich(mob/living/carbon/human/H)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/black(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(H), slot_w_uniform)
+1 -1
View File
@@ -165,4 +165,4 @@
/obj/item/spellbook/oneuse/mime/greaterwall
spell = /obj/effect/proc_holder/spell/targeted/forcewall/mime
spellname = "Invisible Greater Wall"
desc = "It contains illustrations of the great walls of human history."
desc = "It contains illustrations of the great walls of human history."
@@ -41,6 +41,9 @@
LAZYREMOVE(owner.status_effects, src)
on_remove()
owner = null
if(linked_alert)
linked_alert.attached_effect = null
linked_alert = null
return ..()
/datum/status_effect/process()
@@ -85,6 +88,13 @@
desc = "You don't feel any different..."
var/datum/status_effect/attached_effect
/obj/screen/alert/status_effect/Destroy()
if(attached_effect)
attached_effect.linked_alert = null
attached_effect = null
return ..()
//////////////////
// HELPER PROCS //
//////////////////
+1 -1
View File
@@ -1204,7 +1204,7 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
containername = "hydroponics crate"
announce_beacons = list("Hydroponics" = list("Hydroponics"))
/datum/supply_packs/misc/hydroponics/hydrotank
/datum/supply_packs/organic/hydroponics/hydrotank
name = "Hydroponics Watertank Crate"
contains = list(/obj/item/watertank)
cost = 10
+7 -9
View File
@@ -3,16 +3,14 @@
var/obj/machinery/camera/motioncamera = null
/area/ai_monitored/New()
..()
/area/ai_monitored/LateInitialize()
. = ..()
// locate and store the motioncamera
spawn (20) // spawn on a delay to let turfs/objs load
for(var/obj/machinery/camera/M in src)
if(M.isMotion())
motioncamera = M
M.area_motion = src
return
return
for(var/obj/machinery/camera/M in src)
if(M.isMotion())
motioncamera = M
M.area_motion = src
break
/area/ai_monitored/Entered(atom/movable/O)
..()
+16 -5
View File
@@ -1,6 +1,7 @@
/atom/movable
layer = 3
appearance_flags = TILE_BOUND
glide_size = 8 // Default, adjusted when mobs move based on their movement delays
var/last_move = null
var/anchored = 0
var/move_resist = MOVE_RESIST_DEFAULT
@@ -131,13 +132,14 @@
/atom/movable/proc/setLoc(var/T, var/teleported=0)
loc = T
/atom/movable/Move(atom/newloc, direct = 0)
/atom/movable/Move(atom/newloc, direct = 0, movetime)
if(!loc || !newloc) return 0
var/atom/oldloc = loc
if(loc != newloc)
glide_for(movetime)
if(!(direct & (direct - 1))) //Cardinal move
. = ..()
. = ..(newloc, direct) // don't pass up movetime
else //Diagonal move, split it into cardinal moves
moving_diagonally = FIRST_DIAG_STEP
var/first_step_dir
@@ -203,7 +205,7 @@
src.move_speed = world.time - src.l_move_time
src.l_move_time = world.time
if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc, direct)) //movement failed due to buckled mob
if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc, direct, movetime)) //movement failed due to buckled mob
. = 0
// Called after a successful Move(). By this point, we've already moved
@@ -216,6 +218,15 @@
update_parallax_contents()
return TRUE
// Change glide size for the duration of one movement
/atom/movable/proc/glide_for(movetime)
if(movetime)
glide_size = world.icon_size/max(DS2TICKS(movetime), 1)
spawn(movetime)
glide_size = initial(glide_size)
else
glide_size = initial(glide_size)
// Previously known as HasEntered()
// This is automatically called when something enters your square
/atom/movable/Crossed(atom/movable/AM, oldloc)
@@ -428,10 +439,10 @@
/atom/movable/proc/water_act(volume, temperature, source, method = REAGENT_TOUCH) //amount of water acting : temperature of water in kelvin : object that called it (for shennagins)
return TRUE
/atom/movable/proc/handle_buckled_mob_movement(newloc,direct)
/atom/movable/proc/handle_buckled_mob_movement(newloc,direct,movetime)
for(var/m in buckled_mobs)
var/mob/living/buckled_mob = m
if(!buckled_mob.Move(newloc, direct))
if(!buckled_mob.Move(newloc, direct, movetime))
forceMove(buckled_mob.loc)
last_move = buckled_mob.last_move
inertia_dir = last_move
@@ -23,7 +23,7 @@
return
// HIVE MIND UPLOAD/DOWNLOAD DNA
var/list/datum/dna/hivemind_bank = list()
GLOBAL_LIST_EMPTY(hivemind_bank)
/datum/action/changeling/hivemind_upload
name = "Hive Channel DNA"
@@ -36,7 +36,7 @@ var/list/datum/dna/hivemind_bank = list()
var/datum/changeling/changeling = user.mind.changeling
var/list/names = list()
for(var/datum/dna/DNA in (changeling.absorbed_dna+changeling.protected_dna))
if(!(DNA in hivemind_bank))
if(!(DNA in GLOB.hivemind_bank))
names += DNA.real_name
if(names.len <= 0)
@@ -51,7 +51,7 @@ var/list/datum/dna/hivemind_bank = list()
if(!chosen_dna)
return
hivemind_bank += chosen_dna
GLOB.hivemind_bank += chosen_dna
to_chat(user, "<span class='notice'>We channel the DNA of [chosen_name] to the air.</span>")
feedback_add_details("changeling_powers","HU")
return 1
@@ -75,7 +75,7 @@ var/list/datum/dna/hivemind_bank = list()
/datum/action/changeling/hivemind_download/sting_action(var/mob/user)
var/datum/changeling/changeling = user.mind.changeling
var/list/names = list()
for(var/datum/dna/DNA in hivemind_bank)
for(var/datum/dna/DNA in GLOB.hivemind_bank)
if(!(DNA in changeling.absorbed_dna))
names[DNA.real_name] = DNA
+2 -2
View File
@@ -155,12 +155,12 @@
/datum/game_mode/cult/proc/get_possible_sac_targets()
var/list/possible_sac_targets = list()
for(var/mob/living/carbon/human/player in GLOB.player_list)
if(player.mind && !is_convertable_to_cult(player.mind) && (player.stat != DEAD))
if(player.mind && !is_convertable_to_cult(player.mind) && (player.stat != DEAD) && (!player.mind.offstation_role) )
possible_sac_targets += player.mind
if(!possible_sac_targets.len)
//There are no living Unconvertables on the station. Looking for a Sacrifice Target among the ordinary crewmembers
for(var/mob/living/carbon/human/player in GLOB.player_list)
if(is_secure_level(player.z)) //We can't sacrifice people that are on the centcom z-level
if(is_secure_level(player.z) || player.mind.offstation_role) //We can't sacrifice people that are on the centcom z-level or offstation roles
continue
if(player.mind && !(player.mind in cult) && (player.stat != DEAD))//make DAMN sure they are not dead
possible_sac_targets += player.mind
+7 -4
View File
@@ -332,10 +332,12 @@ GLOBAL_LIST_EMPTY(teleport_runes)
user.forceMove(get_turf(actual_selected_rune))
var/mob/living/carbon/human/H = user
if(user.z != T.z)
H.bleed(5)
if(istype(H))
H.bleed(5)
user.apply_damage(5, BRUTE)
else
H.bleed(rand(5,10))
if(istype(H))
H.bleed(rand(5,10))
else
fail_invoke()
@@ -832,7 +834,8 @@ GLOBAL_LIST_EMPTY(teleport_runes)
fail_invoke()
log_game("Summon Cultist rune failed - target in away mission")
return
if((cultist_to_summon.reagents.has_reagent("holywater") || cultist_to_summon.restrained()) && invokers.len < 3)
var/hard_summon = (cultist_to_summon.reagents && cultist_to_summon.reagents.has_reagent("holywater")) || cultist_to_summon.restrained()
if(hard_summon && invokers.len < 3)
to_chat(user, "<span class='cultitalic'>The summoning of [cultist_to_summon] is being blocked somehow! You need 3 chanters to counter it!</span>")
fail_invoke()
new /obj/effect/temp_visual/cult/sparks(get_turf(cultist_to_summon)) //observer warning
@@ -840,7 +843,7 @@ GLOBAL_LIST_EMPTY(teleport_runes)
return
..()
if(cultist_to_summon.reagents.has_reagent("holywater") || cultist_to_summon.restrained())
if(hard_summon)
summontime = 20
if(do_after(user, summontime, target = loc))
+4 -4
View File
@@ -1,4 +1,4 @@
var/global/list/whiteness = list (
GLOBAL_LIST_INIT(whiteness, list(
/obj/item/clothing/under/color/white = 2,
/obj/item/clothing/under/rank/bartender = 1,
/obj/item/clothing/under/rank/chef = 1,
@@ -21,7 +21,7 @@ var/global/list/whiteness = list (
/obj/item/clothing/under/noble_clothes = 1,
/obj/item/clothing/under/sl_suit = 1,
/obj/item/clothing/under/burial = 1
)
))
@@ -32,9 +32,9 @@ var/global/list/whiteness = list (
var/mob/living/carbon/human/H = attacker
if(H.w_uniform && istype(H.w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = H.w_uniform
if(whiteness[U.type])
if(GLOB.whiteness[U.type])
src.visible_message("<span class='warning'>[src] seems to have been harmed by the purity of [attacker]'s clothes.</span>", "<span class='notice'>Unsullied white clothing is disrupting your form.</span>")
return whiteness[U.type] + 1
return GLOB.whiteness[U.type] + 1
if(BANE_TOOLBOX)
if(istype(weapon,/obj/item/storage/toolbox))
src.visible_message("<span class='warning'>The [weapon] seems unusually robust this time.</span>", "<span class='notice'>The [weapon] is your unmaking!</span>")
@@ -282,4 +282,4 @@
/datum/game_mode/proc/update_abductor_icons_removed(datum/mind/alien_mind)
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_ABDUCTOR]
hud.leave_hud(alien_mind.current)
set_antag_hud(alien_mind.current, null)
set_antag_hud(alien_mind.current, null)
@@ -421,13 +421,13 @@
return FALSE
/obj/structure/lattice/catwalk/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
. = ..()
var/turf/here = get_turf(src)
for(var/A in here.contents)
var/obj/structure/cable/C = A
if(istype(C))
to_chat(S, "<span class='warning'>Disrupting the power grid would bring no benefit to us. Aborting.</span>")
return FALSE
return ..()
/obj/item/deactivated_swarmer/IntegrateAmount()
return 50
@@ -13,9 +13,9 @@
/datum/event/spawn_swarmer/start()
if(find_swarmer())
return 0
if(!the_gateway)
if(!GLOB.the_gateway)
return 0
new /obj/effect/mob_spawn/swarmer(get_turf(the_gateway))
new /obj/effect/mob_spawn/swarmer(get_turf(GLOB.the_gateway))
/datum/event/spawn_swarmer/proc/find_swarmer()
@@ -296,11 +296,12 @@
if(used == TRUE)
to_chat(user, "[used_message]")
return
used = TRUE // Set this BEFORE the popup to prevent people using the injector more than once, polling ghosts multiple times, and receiving multiple guardians.
var/choice = alert(user, "[confirmation_message]",, "Yes", "No")
if(choice == "No")
to_chat(user, "<span class='warning'>You decide against using the [name].</span>")
used = FALSE
return
used = TRUE
to_chat(user, "[use_message]")
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the [mob_name] of [user.real_name]?", ROLE_GUARDIAN, 0, 100)
var/mob/dead/observer/theghost = null
+4 -5
View File
@@ -231,7 +231,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective)
return 0
/datum/objective/block
explanation_text = "Do not allow any lifeforms, be it organic or synthetic to escape on the shuttle alive. AIs, Cyborgs, and pAIs are not considered alive."
explanation_text = "Do not allow any lifeforms, be it organic or synthetic to escape on the shuttle alive. AIs, Cyborgs, Maintenance drones, and pAIs are not considered alive."
martyr_compatible = 1
/datum/objective/block/check_completion()
@@ -243,15 +243,14 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective)
return 0
var/area/A = SSshuttle.emergency.areaInstance
var/list/protected_mobs = list(/mob/living/silicon/ai, /mob/living/silicon/pai, /mob/living/silicon/robot)
for(var/mob/living/player in GLOB.player_list)
if(player.type in protected_mobs)
continue
if(issilicon(player))
continue // If they're silicon, they're not considered alive, skip them.
if(player.mind && player.stat != DEAD)
if(get_area(player) == A)
return 0
return 0 // If there are any other organic mobs on the shuttle, you failed the objective.
return 1
+2 -2
View File
@@ -76,12 +76,12 @@ datum/theft_objective/ai/check_special_completion(var/obj/item/aicard/C)
/datum/theft_objective/blueprints
name = "the station blueprints"
typepath = /obj/item/areaeditor/blueprints
typepath = /obj/item/areaeditor/blueprints/ce
protected_jobs = list("Chief Engineer")
altitems = list(/obj/item/photo)
/datum/objective_item/steal/blueprints/check_special_completion(obj/item/I)
if(istype(I, /obj/item/areaeditor/blueprints))
if(istype(I, /obj/item/areaeditor/blueprints/ce))
return 1
if(istype(I, /obj/item/photo))
var/obj/item/photo/P = I
+1 -1
View File
@@ -168,4 +168,4 @@ GLOBAL_VAR_INIT(summon_magic_triggered, FALSE)
if(summon_type == SUMMON_MAGIC)
give_magic(H)
else
give_guns(H)
give_guns(H)
+93 -37
View File
@@ -6,34 +6,36 @@
var/category = "Offensive"
var/log_name = "XX" //What it shows up as in logs
var/cost = 2
var/refundable = 1
var/refundable = TRUE
var/surplus = -1 // -1 for infinite, not used by anything atm
var/obj/effect/proc_holder/spell/S = null //Since spellbooks can be used by only one person anyway we can track the actual spell
var/buy_word = "Learn"
var/limit //used to prevent a spellbook_entry from being bought more than X times with one wizard spellbook
/datum/spellbook_entry/proc/IsSpellAvailable() // For config prefs / gamemode restrictions - these are round applied
return 1
return TRUE
/datum/spellbook_entry/proc/CanBuy(mob/living/carbon/human/user, obj/item/spellbook/book) // Specific circumstances
if(book.uses<cost || limit == 0)
return 0
return 1
if(book.uses < cost || limit == 0)
return FALSE
return TRUE
/datum/spellbook_entry/proc/Buy(mob/living/carbon/human/user, obj/item/spellbook/book) //return 1 on success
/datum/spellbook_entry/proc/Buy(mob/living/carbon/human/user, obj/item/spellbook/book) //return TRUE on success
if(!S)
S = new spell_type()
//Check if we got the spell already
return LearnSpell(user, book, S)
/datum/spellbook_entry/proc/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, obj/effect/proc_holder/spell/newspell)
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
if(initial(S.name) == initial(aspell.name)) // Not using directly in case it was learned from one spellbook then upgraded in another
if(initial(newspell.name) == initial(aspell.name)) // Not using directly in case it was learned from one spellbook then upgraded in another
if(aspell.spell_level >= aspell.level_max)
to_chat(user, "<span class='warning'>This spell cannot be improved further.</span>")
return 0
return FALSE
else
aspell.name = initial(aspell.name)
aspell.spell_level++
aspell.charge_max = round(initial(aspell.charge_max) - aspell.spell_level * (initial(aspell.charge_max) - aspell.cooldown_min)/ aspell.level_max)
aspell.charge_max = round(initial(aspell.charge_max) - aspell.spell_level * (initial(aspell.charge_max) - aspell.cooldown_min) / aspell.level_max)
if(aspell.charge_max < aspell.charge_counter)
aspell.charge_counter = aspell.charge_max
switch(aspell.spell_level)
@@ -51,37 +53,39 @@
aspell.name = "Instant [aspell.name]"
if(aspell.spell_level >= aspell.level_max)
to_chat(user, "<span class='notice'>This spell cannot be strengthened any further.</span>")
return 1
return TRUE
//No same spell found - just learn it
feedback_add_details("wizard_spell_learned",log_name)
user.mind.AddSpell(S)
to_chat(user, "<span class='notice'>You have learned [S.name].</span>")
return 1
feedback_add_details("wizard_spell_learned", log_name)
user.mind.AddSpell(newspell)
to_chat(user, "<span class='notice'>You have learned [newspell.name].</span>")
return TRUE
/datum/spellbook_entry/proc/CanRefund(mob/living/carbon/human/user, obj/item/spellbook/book)
if(!refundable)
return 0
return FALSE
if(!S)
S = new spell_type()
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
if(initial(S.name) == initial(aspell.name))
return 1
return 0
return TRUE
return FALSE
/datum/spellbook_entry/proc/Refund(mob/living/carbon/human/user, obj/item/spellbook/book) //return point value or -1 for failure
var/area/wizard_station/A = locate()
if(!(user in A.contents))
to_chat(user, "<span clas=='warning'>You can only refund spells at the wizard lair</span>")
to_chat(user, "<span class='warning'>You can only refund spells at the wizard lair.</span>")
return -1
if(!S)
if(!S) //This happens when the spell's source is from another spellbook, from loadouts, or adminery, this create a new template temporary spell
S = new spell_type()
var/spell_levels = 0
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
if(initial(S.name) == initial(aspell.name))
spell_levels = aspell.spell_level
user.mind.spell_list.Remove(aspell)
QDEL_NULL(S)
return cost * (spell_levels+1)
qdel(aspell)
if(S) //If we created a temporary spell above, delete it now.
qdel(S)
return cost * (spell_levels + 1)
return -1
/datum/spellbook_entry/proc/GetInfo()
@@ -571,6 +575,48 @@
category = "Summons"
limit = 1
//Spell loadouts datum, list of loadouts is in wizloadouts.dm
/datum/spellbook_entry/loadout
name = "Standard Loadout"
cost = 10
category = "Standard"
refundable = FALSE
buy_word = "Summon"
var/list/items_path = list()
var/list/spells_path = list()
var/destroy_spellbook = FALSE //Destroy the spellbook when bought, for loadouts containing non-standard items/spells, otherwise wiz can refund spells
/datum/spellbook_entry/loadout/GetInfo()
var/dat = ""
dat += "<b>[name]</b>"
if(cost > 0)
dat += " Cost:[cost]<br>"
else
dat += " No Cost<br>"
dat += "<i>[desc]</i><br>"
return dat
/datum/spellbook_entry/loadout/Buy(mob/living/carbon/human/user, obj/item/spellbook/book)
if(destroy_spellbook)
var/response = alert(user, "The [src] loadout cannot be refunded once bought. Are you sure this is what you want?", "No refunds!", "No", "Yes")
if(response == "No")
return FALSE
to_chat(user, "<span class='notice'>[book] crumbles to ashes as you acquire its knowledge.</span>")
qdel(book)
else if(items_path.len)
var/response = alert(user, "The [src] loadout contains items that will not be refundable if bought. Are you sure this is what you want?", "No refunds!", "No", "Yes")
if(response == "No")
return FALSE
if(items_path.len)
var/obj/item/storage/box/wizard/B = new(src)
for(var/path in items_path)
new path(B)
user.put_in_hands(B)
for(var/path in spells_path)
var/obj/effect/proc_holder/spell/S = new path()
LearnSpell(user, book, S)
return TRUE
/obj/item/spellbook
name = "spell book"
desc = "The legendary book of spells of the wizard."
@@ -587,12 +633,13 @@
var/mob/living/carbon/human/owner
var/list/datum/spellbook_entry/entries = list()
var/list/categories = list()
var/list/main_categories = list("Spells", "Magical Items")
var/list/main_categories = list("Spells", "Magical Items", "Loadouts")
var/list/spell_categories = list("Offensive", "Defensive", "Mobility", "Assistance", "Rituals")
var/list/item_categories = list("Artefacts", "Weapons and Armors", "Staves", "Summons")
var/list/loadout_categories = list("Standard", "Unique")
/obj/item/spellbook/proc/initialize()
var/entry_types = subtypesof(/datum/spellbook_entry) - /datum/spellbook_entry/item - /datum/spellbook_entry/summon
var/entry_types = subtypesof(/datum/spellbook_entry) - /datum/spellbook_entry/item - /datum/spellbook_entry/summon - /datum/spellbook_entry/loadout
for(var/T in entry_types)
var/datum/spellbook_entry/E = new T
if(E.IsSpellAvailable())
@@ -676,6 +723,12 @@
if("Summons")
dat += "Magical items geared towards bringing in outside forces to aid you.<BR><BR>"
dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.<BR>"
if("Standard")
dat += "These battle-tested spell sets are easy to use and provide good balance between offense and defense.<BR><BR>"
dat += "They all cost, and are worth, 10 spell points. You are able to refund any of the spells included as long as you stay in the wizard den.<BR>"
if("Unique")
dat += "These esoteric loadouts usually contain spells or items that cannot be bought elsewhere in this spellbook.<BR><BR>"
dat += "Recommended for experienced wizards looking for something new. No refunds once purchased!<BR>"
return dat
/obj/item/spellbook/proc/wrap(content)
@@ -720,23 +773,24 @@
cat_dat[main_category] = "<hr>"
dat += "<li><a [main_tab==main_category?"class=selected":""] href='byond://?src=[UID()];mainpage=[main_category]'>[main_category]</a></li>"
dat += "</ul>"
dat += "<ul id=\"tabs\">"
switch(main_tab)
if("Spells")
dat += "<ul id=\"tabs\">"
for(var/category in categories)
if(category in item_categories)
continue
cat_dat[category] = "<hr>"
dat += "<li><a [tab==category?"class=selected":""] href='byond://?src=[UID()];page=[category]'>[category]</a></li>"
dat += "<li><a><b>Points remaining : [uses]</b></a></li>"
if("Magical Items")
dat += "<ul id=\"tabs\">"
for(var/category in categories)
if(category in spell_categories)
continue
cat_dat[category] = "<hr>"
dat += "<li><a [tab==category?"class=selected":""] href='byond://?src=[UID()];page=[category]'>[category]</a></li>"
dat += "<li><a><b>Points remaining : [uses]</b></a></li>"
cat_dat[category] = "<hr>"
dat += "<li><a [tab==category?"class=selected":""] href='byond://?src=[UID()];page=[category]'>[category]</a></li>"
if("Magical Items")
for(var/category in categories)
if(category in item_categories)
cat_dat[category] = "<hr>"
dat += "<li><a [tab==category?"class=selected":""] href='byond://?src=[UID()];page=[category]'>[category]</a></li>"
if("Loadouts")
for(var/category in categories)
if(category in loadout_categories)
cat_dat[category] = "<hr>"
dat += "<li><a [tab==category?"class=selected":""] href='byond://?src=[UID()];page=[category]'>[category]</a></li>"
dat += "<li><a><b>Points remaining : [uses]</b></a></li>"
dat += "</ul>"
var/datum/spellbook_entry/E
@@ -801,6 +855,8 @@
tab = spell_categories[1]
else if(main_tab == "Magical Items")
tab = item_categories[1]
else if(main_tab == "Loadouts")
tab = loadout_categories[1]
else if(href_list["page"])
tab = sanitize(href_list["page"])
attack_self(H)
+18 -9
View File
@@ -135,22 +135,31 @@
qdel(wizard_mob.r_store)
qdel(wizard_mob.l_store)
wizard_mob.equip_to_slot_or_del(new /obj/item/radio/headset(wizard_mob), slot_l_ear)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(wizard_mob), slot_w_uniform)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(wizard_mob), slot_shoes)
if(!isplasmaman(wizard_mob)) //handled in the species file for plasmen on the afterjob equip proc for now
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(wizard_mob), slot_wear_suit)
if(isplasmaman(wizard_mob))
wizard_mob.equipOutfit(new /datum/outfit/plasmaman/wizard)
wizard_mob.internal = wizard_mob.r_hand
wizard_mob.update_action_buttons_icon()
else
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(wizard_mob), slot_w_uniform)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(wizard_mob), slot_head)
wizard_mob.dna.species.after_equip_job(null, wizard_mob)
wizard_mob.rejuvenate() //fix any damage taken by naked vox/plasmamen/etc while round setups
wizard_mob.equip_to_slot_or_del(new /obj/item/radio/headset(wizard_mob), slot_l_ear)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(wizard_mob), slot_shoes)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(wizard_mob), slot_wear_suit)
wizard_mob.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel(wizard_mob), slot_back)
wizard_mob.equip_to_slot_or_del(new /obj/item/storage/box/survival(wizard_mob), slot_in_backpack)
if(wizard_mob.dna.species.speciesbox)
wizard_mob.equip_to_slot_or_del(new wizard_mob.dna.species.speciesbox(wizard_mob), slot_in_backpack)
else
wizard_mob.equip_to_slot_or_del(new /obj/item/storage/box/survival(wizard_mob), slot_in_backpack)
wizard_mob.equip_to_slot_or_del(new /obj/item/teleportation_scroll(wizard_mob), slot_r_store)
var/obj/item/spellbook/spellbook = new /obj/item/spellbook(wizard_mob)
spellbook.owner = wizard_mob
wizard_mob.equip_to_slot_or_del(spellbook, slot_r_hand)
wizard_mob.equip_to_slot_or_del(spellbook, slot_l_hand)
wizard_mob.faction = list("wizard")
wizard_mob.dna.species.after_equip_job(null, wizard_mob)
to_chat(wizard_mob, "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.")
to_chat(wizard_mob, "The spellbook is bound to you, and others cannot use it.")
@@ -158,7 +167,7 @@
wizard_mob.mind.store_memory("<B>Remember:</B> do not forget to prepare your spells.")
wizard_mob.update_icons()
wizard_mob.gene_stability += DEFAULT_GENE_STABILITY //magic
return 1
return TRUE
// Checks if the game should end due to all wizards and apprentices being dead, or MMI'd/Borged
/datum/game_mode/wizard/check_finished()
+71
View File
@@ -0,0 +1,71 @@
//Contains wizard loadouts and associated unique spells
//Standard loadouts, which are meant to be suggestions for beginners. Should always be worth exactly 10 spell points, and only contain standard wizard spells/items.
/datum/spellbook_entry/loadout/mutant
name = "Offense Focus : Mutant"
desc = "A spellset focused around the Mutate spell as its main source of damage, which provides stun protection, laser eyes, and strong punches. <br> \
Ethereal Jaunt and Blink provide escape and mobility, while Magic Missile and Desintegrate can be used together for dangerous or key targets. <br> \
As this set lacks any form of healing or resurrection, healing items should be acquired from the station, and you should be careful to avoid being hurt in the first place. <br><br> \
</i>Provides Mutate, Ethereal Jaunt, Blink, Magic Missile, and Disintegrate.<i>"
log_name = "OM"
spells_path = list(/obj/effect/proc_holder/spell/targeted/genetic/mutate, /obj/effect/proc_holder/spell/targeted/ethereal_jaunt, /obj/effect/proc_holder/spell/targeted/turf_teleport/blink, \
/obj/effect/proc_holder/spell/targeted/projectile/magic_missile, /obj/effect/proc_holder/spell/targeted/touch/disintegrate)
/datum/spellbook_entry/loadout/lich
name = "Defense Focus : Lich"
desc = "This spellset uses the Bind Soul spell to safeguard your life as a lich and allow for more dangerous offensive spells to be used. <br> \
Ethereal Jaunt provides escape, Fireball and Rod Form are your offensive spells, and Disable Tech and Greater Forcewall provides utility in disabling sec equipment or blocking their path. <br> \
Care should be taken in hiding the item you choose as your phylactery after using Bind Soul, as you cannot revive if it destroyed or too far from your body! <br><br> \
</i>Provides Bind Soul, Ethereal Jaunt, Fireball, Rod Form, Disable Tech, and Greater Forcewall.<i>"
log_name = "DL"
spells_path = list(/obj/effect/proc_holder/spell/targeted/lichdom, /obj/effect/proc_holder/spell/targeted/ethereal_jaunt, /obj/effect/proc_holder/spell/fireball, \
/obj/effect/proc_holder/spell/targeted/rod_form, /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech, /obj/effect/proc_holder/spell/targeted/forcewall/greater)
/datum/spellbook_entry/loadout/wands
name = "Utility Focus : Wands"
desc = "This set contain a Belt of Wands, providing offensive, defensive, and utility wands. Wands have limited charges, but can be partially recharged with the Charge spell included. <br> \
Ethereal Jaunt and Blink provide escape and mobility, while Disintegrate and Repulse can be used to annihilate or push away anyone that gets too close to you. <br> \
Do not lose any of your wands to the station's crew, as they are extremely deadly even in their hands. Remember that the Revive wand can be used on yourself for a full heal! <br><br> \
</i>Provides a Belt of Wands, Charge, Ethereal Jaunt, Blink, Repulse, and Desintegrate.<i>"
log_name = "UW"
items_path = list(/obj/item/storage/belt/wands/full)
spells_path = list(/obj/effect/proc_holder/spell/targeted/charge, /obj/effect/proc_holder/spell/targeted/ethereal_jaunt, /obj/effect/proc_holder/spell/targeted/turf_teleport/blink, \
/obj/effect/proc_holder/spell/aoe_turf/repulse, /obj/effect/proc_holder/spell/targeted/touch/disintegrate)
//Unique loadouts, which are more gimmicky. Should contain some unique spell or item that separates it from just buying standard wiz spells, and be balanced around a 10 spell point cost.
/datum/spellbook_entry/loadout/mimewiz
name = "Silencio"
desc = "...<br><br> \
</i>Provides Finger Gun and Invisible Greater Wall manuals, Mime Robes, a Cane and Duct Tape, Ethereal Jaunt, Blink, Teleport, Mime Malaise, Knock, and Stop Time.<i>"
log_name = "SHH"
items_path = list(/obj/item/spellbook/oneuse/mime/fingergun, /obj/item/spellbook/oneuse/mime/greaterwall, /obj/item/clothing/suit/wizrobe/mime, /obj/item/clothing/head/wizard/mime, \
/obj/item/clothing/mask/gas/mime/wizard, /obj/item/clothing/shoes/sandal/marisa, /obj/item/cane, /obj/item/stack/tape_roll)
spells_path = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt, /obj/effect/proc_holder/spell/targeted/turf_teleport/blink, /obj/effect/proc_holder/spell/targeted/area_teleport/teleport, \
/obj/effect/proc_holder/spell/targeted/touch/mime_malaise, /obj/effect/proc_holder/spell/aoe_turf/knock, /obj/effect/proc_holder/spell/aoe_turf/conjure/timestop)
category = "Unique"
destroy_spellbook = TRUE
/datum/spellbook_entry/loadout/mimewiz/Buy(mob/living/carbon/human/user, obj/item/spellbook/book)
if(user.mind)
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mime/speak(null))
user.mind.miming = TRUE
..()
/datum/spellbook_entry/loadout/gunreaper
name = "Gunslinging Reaper"
desc = "Cloned over and over, the souls aboard this station yearn for a deserved rest.<br> \
Bring them to the afterlife, one trigger pull at a time. <br> \
You will likely need to scavenge additional ammo or weapons aboard the station. <br><br>\
</i>Provides a .357 Revolver, 4 speedloaders of ammo, Ethereal Jaunt, Blink, Summon Item, No Clothes, and Bind Soul, with a unique outfit.<i>"
log_name = "GR"
items_path = list(/obj/item/gun/projectile/revolver, /obj/item/ammo_box/a357, /obj/item/ammo_box/a357, /obj/item/ammo_box/a357, /obj/item/ammo_box/a357, /obj/item/clothing/under/syndicate)
spells_path = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt, /obj/effect/proc_holder/spell/targeted/turf_teleport/blink, \
/obj/effect/proc_holder/spell/targeted/summonitem, /obj/effect/proc_holder/spell/noclothes, /obj/effect/proc_holder/spell/targeted/lichdom/gunslinger)
category = "Unique"
destroy_spellbook = TRUE
/obj/effect/proc_holder/spell/targeted/lichdom/gunslinger/equip_lich(mob/living/carbon/human/H)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/det_suit(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(H), slot_gloves)
H.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(H), slot_w_uniform)
+3
View File
@@ -34,6 +34,9 @@
/obj/item/implant/dust
)
backpack = /obj/item/storage/backpack/satchel
backpack_contents = list(
/obj/item/stamp/centcom = 1,
)
box = /obj/item/storage/box/centcomofficer
cybernetic_implants = list(
/obj/item/organ/internal/cyberimp/chest/nutriment/plus
+2 -3
View File
@@ -30,7 +30,7 @@
l_ear = /obj/item/radio/headset/heads/cmo
id = /obj/item/card/id/cmo
suit_store = /obj/item/flashlight/pen
l_hand = /obj/item/storage/firstaid/adv
l_hand = /obj/item/storage/firstaid/doctor
pda = /obj/item/pda/heads/cmo
backpack_contents = list(
/obj/item/melee/classic_baton/telescopic = 1
@@ -68,7 +68,7 @@
l_ear = /obj/item/radio/headset/headset_med
id = /obj/item/card/id/medical
suit_store = /obj/item/flashlight/pen
l_hand = /obj/item/storage/firstaid/adv
l_hand = /obj/item/storage/firstaid/doctor
pda = /obj/item/pda/medical
backpack = /obj/item/storage/backpack/medic
@@ -315,4 +315,3 @@
satchel = /obj/item/storage/backpack/satchel_med
dufflebag = /obj/item/storage/backpack/duffel/medical
box = /obj/item/storage/box/engineer
+1 -1
View File
@@ -217,7 +217,7 @@
glasses = /obj/item/clothing/glasses/hud/health/sunglasses
id = /obj/item/card/id/security
suit_store = /obj/item/flashlight/pen
l_hand = /obj/item/storage/firstaid/adv
l_hand = /obj/item/storage/firstaid/doctor
pda = /obj/item/pda/medical
implants = list(/obj/item/implant/mindshield)
backpack = /obj/item/storage/backpack/medic
+25 -9
View File
@@ -23,6 +23,7 @@
var/initial_bin_rating = 1
var/min_health = -25
var/controls_inside = FALSE
var/auto_eject_dead = FALSE
idle_power_usage = 1250
active_power_usage = 2500
@@ -81,8 +82,19 @@
go_out()
/obj/machinery/sleeper/process()
if(filtering > 0)
if(beaker)
for(var/mob/M as mob in src) // makes sure that simple mobs don't get stuck inside a sleeper when they resist out of occupant's grasp
if(M == occupant)
continue
else
M.forceMove(loc)
if(occupant)
if(auto_eject_dead && occupant.stat == DEAD)
playsound(loc, 'sound/machines/buzz-sigh.ogg', 40)
go_out()
return
if(filtering > 0 && beaker)
// To prevent runtimes from drawing blood from runtime, and to prevent getting IPC blood.
if(!istype(occupant) || !occupant.dna || (NO_BLOOD in occupant.dna.species.species_traits))
filtering = 0
@@ -94,7 +106,6 @@
occupant.reagents.trans_to(beaker, 3)
occupant.transfer_blood_to(beaker, 1)
if(occupant)
for(var/A in occupant.reagents.addiction_list)
var/datum/reagent/R = A
@@ -106,12 +117,6 @@
occupant.reagents.addiction_list.Remove(R)
qdel(R)
for(var/mob/M as mob in src) // makes sure that simple mobs don't get stuck inside a sleeper when they resist out of occupant's grasp
if(M == occupant)
continue
else
M.forceMove(loc)
updateDialog()
return
@@ -201,6 +206,7 @@
data["maxchem"] = max_chem
data["minhealth"] = min_health
data["dialysis"] = filtering
data["auto_eject_dead"] = auto_eject_dead
if(beaker)
data["isBeakerLoaded"] = 1
if(beaker.reagents)
@@ -255,12 +261,22 @@
inject_chemical(usr,href_list["chemical"],text2num(href_list["amount"]))
else
to_chat(usr, "<span class='danger'>This person is not in good enough condition for sleepers to be effective! Use another means of treatment, such as cryogenics!</span>")
if(href_list["removebeaker"])
remove_beaker()
if(href_list["togglefilter"])
toggle_filter()
if(href_list["ejectify"])
eject()
if(href_list["auto_eject_dead_on"])
auto_eject_dead = TRUE
if(href_list["auto_eject_dead_off"])
auto_eject_dead = FALSE
add_fingerprint(usr)
return 1
+8 -8
View File
@@ -2,8 +2,8 @@
// EMP
/obj/machinery/camera/emp_proof/New()
..()
/obj/machinery/camera/emp_proof/Initialize()
. = ..()
upgradeEmpProof()
// X-RAY
@@ -11,20 +11,20 @@
/obj/machinery/camera/xray
icon_state = "xraycam" // Thanks to Krutchen for the icons.
/obj/machinery/camera/xray/New()
..()
/obj/machinery/camera/xray/Initialize()
. = ..()
upgradeXRay()
// MOTION
/obj/machinery/camera/motion/New()
..()
/obj/machinery/camera/motion/Initialize()
. = ..()
upgradeMotion()
// ALL UPGRADES
/obj/machinery/camera/all/New()
..()
/obj/machinery/camera/all/Initialize()
. = ..()
upgradeEmpProof()
upgradeXRay()
upgradeMotion()
+1 -1
View File
@@ -302,7 +302,7 @@
T = get_step(T, direct)
console.jump_on_click(src, T)
return
return ..(n,direct)
return ..()
// Other computer monitors.
/obj/machinery/computer/security/telescreen
+45 -19
View File
@@ -1,3 +1,6 @@
#define AUTO_EJECT_DEAD (1<<0)
#define AUTO_EJECT_HEALTHY (1<<1)
/obj/machinery/atmospherics/unary/cryo_cell
name = "cryo cell"
desc = "Lowers the body temperature so certain medications may take effect."
@@ -10,11 +13,12 @@
interact_offline = 1
max_integrity = 350
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 30, "acid" = 30)
var/on = 0
var/on = FALSE
var/temperature_archived
var/mob/living/carbon/occupant = null
var/obj/item/reagent_containers/glass/beaker = null
var/autoeject = 0
/// Holds two bitflags, AUTO_EJECT_DEAD and AUTO_EJECT_HEALTHY. Used to determine if the cryo cell will auto-eject dead and/or completely health patients.
var/auto_eject_prefs = NONE
var/next_trans = 0
var/current_heat_capacity = 50
@@ -139,18 +143,20 @@
/obj/machinery/atmospherics/unary/cryo_cell/process()
..()
if(autoeject)
if(occupant)
if(!occupant.has_organic_damage() && !occupant.has_mutated_organs())
on = 0
go_out()
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
if(!occupant)
return
if((auto_eject_prefs & AUTO_EJECT_DEAD) && occupant.stat == DEAD)
auto_eject(AUTO_EJECT_DEAD)
return
if((auto_eject_prefs & AUTO_EJECT_HEALTHY) && !occupant.has_organic_damage() && !occupant.has_mutated_organs())
auto_eject(AUTO_EJECT_HEALTHY)
return
if(air_contents)
if(occupant)
process_occupant()
process_occupant()
return 1
return TRUE
/obj/machinery/atmospherics/unary/cryo_cell/process_atmos()
..()
@@ -208,7 +214,7 @@
if(!ui)
// the ui does not exist, so we'll create a new() one
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
ui = new(user, src, ui_key, "cryo.tmpl", "Cryo Cell Control System", 520, 420)
ui = new(user, src, ui_key, "cryo.tmpl", "Cryo Cell Control System", 520, 480)
// open the new ui window
ui.open()
// auto update every Master Controller tick
@@ -249,7 +255,8 @@
for(var/datum/reagent/R in beaker.reagents.reagent_list)
data["beakerVolume"] += R.volume
data["autoeject"] = autoeject
data["auto_eject_healthy"] = (auto_eject_prefs & AUTO_EJECT_HEALTHY) ? TRUE : FALSE
data["auto_eject_dead"] = (auto_eject_prefs & AUTO_EJECT_DEAD) ? TRUE : FALSE
return data
/obj/machinery/atmospherics/unary/cryo_cell/Topic(href, href_list)
@@ -260,18 +267,24 @@
return 0 // don't update UIs attached to this object
if(href_list["switchOn"])
on = 1
on = TRUE
update_icon()
if(href_list["switchOff"])
on = 0
on = FALSE
update_icon()
if(href_list["autoejectOn"])
autoeject = 1
if(href_list["auto_eject_healthy_on"])
auto_eject_prefs |= AUTO_EJECT_HEALTHY
if(href_list["autoejectOff"])
autoeject = 0
if(href_list["auto_eject_healthy_off"])
auto_eject_prefs &= ~AUTO_EJECT_HEALTHY
if(href_list["auto_eject_dead_on"])
auto_eject_prefs |= AUTO_EJECT_DEAD
if(href_list["auto_eject_dead_off"])
auto_eject_prefs &= ~AUTO_EJECT_DEAD
if(href_list["ejectBeaker"])
if(beaker)
@@ -430,6 +443,16 @@
for(var/atom/movable/A in contents - component_parts - list(beaker))
A.forceMove(get_step(loc, SOUTH))
/// Called when either the occupant is dead and the AUTO_EJECT_DEAD flag is present, OR the occupant is alive, has no external damage, and the AUTO_EJECT_HEALTHY flag is present.
/obj/machinery/atmospherics/unary/cryo_cell/proc/auto_eject(eject_flag)
on = FALSE
go_out()
switch(eject_flag)
if(AUTO_EJECT_HEALTHY)
playsound(loc, 'sound/machines/ding.ogg', 50, 1)
if(AUTO_EJECT_DEAD)
playsound(loc, 'sound/machines/buzz-sigh.ogg', 40)
/obj/machinery/atmospherics/unary/cryo_cell/proc/put_mob(mob/living/carbon/M as mob)
if(!istype(M))
to_chat(usr, "<span class='danger'>The cryo cell cannot handle such a lifeform!</span>")
@@ -515,3 +538,6 @@
/obj/machinery/atmospherics/components/unary/cryo_cell/update_remote_sight(mob/living/user)
return //we don't see the pipe network while inside cryo.
#undef AUTO_EJECT_HEALTHY
#undef AUTO_EJECT_DEAD
+6
View File
@@ -275,6 +275,12 @@
return control_computer != null
// So the user can use movement keys to get out of the cryopod
/obj/machinery/cryopod/relaymove(mob/user)
if(user.incapacitated())
return FALSE
go_out()
/obj/machinery/cryopod/proc/check_occupant_allowed(mob/M)
var/correct_type = 0
for(var/type in allow_occupant_types)
+3
View File
@@ -15,6 +15,9 @@
var/obj/item/defibrillator/defib //this mount's defibrillator
var/clamps_locked = FALSE //if true, and a defib is loaded, it can't be removed without unlocking the clamps
/obj/machinery/defibrillator_mount/attack_ai()
return
/obj/machinery/defibrillator_mount/get_cell()
if(defib)
return defib.get_cell()
+3
View File
@@ -30,6 +30,8 @@
new stacktype(get_turf(src), drop_amount)
/obj/structure/barricade/welder_act(mob/user, obj/item/I)
if(bar_material != METAL)
return
if(obj_integrity >= max_integrity)
to_chat(user, "<span class='notice'>[src] does not need repairs.</span>")
return
@@ -71,6 +73,7 @@
bar_material = WOOD
stacktype = /obj/item/stack/sheet/wood
/obj/structure/barricade/wooden/attackby(obj/item/I, mob/user)
if(istype(I,/obj/item/stack/sheet/wood))
var/obj/item/stack/sheet/wood/W = I
+2 -2
View File
@@ -289,8 +289,8 @@ About the new airlock wires panel:
// shock user with probability prb (if all connections & power are working)
// returns 1 if shocked, 0 otherwise
// The preceding comment was borrowed from the grille's shock script
/obj/machinery/door/airlock/shock(mob/user, prb)
if(!arePowerSystemsOn())
/obj/machinery/door/airlock/shock(mob/living/user, prb)
if(!istype(user) || !arePowerSystemsOn())
return FALSE
if(shockCooldown > world.time)
return FALSE //Already shocked someone recently?
+1 -1
View File
@@ -204,7 +204,7 @@
. = TRUE
if(operating)
return
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
if(!I.use_tool(src, user, 0, volume = 0))
return
try_to_crowbar(user, I)

Some files were not shown because too many files have changed in this diff Show More