mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-26 13:37:58 +01:00
Merge branch 'master' into holy-chapel
This commit is contained in:
@@ -2,13 +2,13 @@
|
||||
<!-- You can view Contributing.MD for a detailed description of the pull request process. -->
|
||||
|
||||
## What Does This PR Do
|
||||
<!-- Include a small to medium description of what your PR changes. Document every changes or this may delay review or even discourage maintainers from merging your PR! -->
|
||||
<!-- Include a small to medium description of what your PR changes. Document all changes, as not doing this may delay reviews or even discourage maintainers from merging your PR! -->
|
||||
|
||||
## Why It's Good For The Game
|
||||
<!-- Please add a short description of why you think these changes would benefit the game. If you can't justify it in words, it might not be worth adding. -->
|
||||
<!-- Add a short description of why you think these changes would benefit the game. If you can't justify it in words, it might not be worth adding. -->
|
||||
|
||||
## Images of changes
|
||||
<!-- If you did not make a map or sprite edit, you may delete this section. You may include a gif of your feature if you want -->
|
||||
<!-- If you did not make a map or sprite edit, you may delete this section. You may include a gif or mp4 of your feature if you want. -->
|
||||
|
||||
## Changelog
|
||||
:cl:
|
||||
@@ -27,3 +27,4 @@ experiment: Added an experimental thingy
|
||||
|
||||
<!-- Both :cl:'s are required for the changelog to work! You can put your name to the right of the first :cl: if you want to overwrite your GitHub username as author ingame. -->
|
||||
<!-- You can use multiple of the same prefix (they're only used for the icon ingame) and delete the unneeded ones. Despite some of the tags, changelogs should generally represent how a player might be affected by the changes rather than a summary of the PR's contents. -->
|
||||
<!-- If a PR has no impact on players (i.e. a code refactor that does not change functionality) then the entire Changelog heading and contents can be removed. -->
|
||||
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
tools/ci/install_byond.sh
|
||||
source $HOME/BYOND/byond/bin/byondsetup
|
||||
tools/ci/generate_maplist.sh
|
||||
tools/ci/dm.sh -Mci_map_testing paradise.dme
|
||||
tools/ci/dm.sh -DCIMAP paradise.dme
|
||||
|
||||
unit_tests_and_sql:
|
||||
name: Unit Tests + SQL Validation
|
||||
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"workbench.editorAssociations": {
|
||||
"*.dmi": "imagePreview.previewEditor"
|
||||
}
|
||||
}
|
||||
+22
-8
@@ -99,7 +99,7 @@ CREATE TABLE `customuseritems` (
|
||||
`cuiJobMask` text NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `cuiCKey` (`cuiCKey`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=56 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -126,7 +126,7 @@ CREATE TABLE `death` (
|
||||
`fireloss` int(11) NOT NULL,
|
||||
`oxyloss` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=166546 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=166546 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -241,7 +241,7 @@ CREATE TABLE `feedback` (
|
||||
`version` tinyint(3) UNSIGNED NOT NULL,
|
||||
`json` LONGTEXT NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=257638 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=257638 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -277,6 +277,7 @@ CREATE TABLE `player` (
|
||||
`fupdate` smallint(4) DEFAULT '0',
|
||||
`parallax` tinyint(1) DEFAULT '8',
|
||||
`byond_date` DATE DEFAULT NULL,
|
||||
`2fa_status` ENUM('DISABLED','ENABLED_IP','ENABLED_ALWAYS') NOT NULL DEFAULT 'DISABLED' COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `ckey` (`ckey`),
|
||||
KEY `lastseen` (`lastseen`),
|
||||
@@ -321,7 +322,7 @@ CREATE TABLE `karma` (
|
||||
`spenderip` text NOT NULL,
|
||||
`time` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=73614 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=73614 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -338,7 +339,7 @@ CREATE TABLE `karmatotals` (
|
||||
`karmaspent` int(11) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `byondkey` (`byondkey`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=25715 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=25715 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -359,7 +360,7 @@ CREATE TABLE `library` (
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ckey` (`ckey`),
|
||||
KEY `flagged` (`flagged`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=4537 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4537 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -375,7 +376,7 @@ CREATE TABLE `legacy_population` (
|
||||
`admincount` int(11) DEFAULT NULL,
|
||||
`time` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=2550 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2550 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -392,7 +393,7 @@ CREATE TABLE `whitelist` (
|
||||
`species` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ckey` (`ckey`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=4080 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4080 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
@@ -585,3 +586,16 @@ CREATE TABLE `round` (
|
||||
`station_name` VARCHAR(80) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
|
||||
--
|
||||
-- Table structure for table `2fa_secrets`
|
||||
--
|
||||
CREATE TABLE `2fa_secrets` (
|
||||
`ckey` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`secret` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`date_setup` DATETIME NOT NULL DEFAULT current_timestamp(),
|
||||
`last_time` DATETIME NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`ckey`) USING BTREE
|
||||
)
|
||||
COLLATE='utf8mb4_general_ci' ENGINE=InnoDB;
|
||||
|
||||
@@ -98,7 +98,7 @@ CREATE TABLE `SS13_customuseritems` (
|
||||
`cuiPropAdjust` text,
|
||||
`cuiJobMask` text NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=56 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8mb4;
|
||||
ALTER TABLE `SS13_customuseritems` ADD INDEX(`cuiCKey`);
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
@@ -126,7 +126,7 @@ CREATE TABLE `SS13_death` (
|
||||
`fireloss` int(11) NOT NULL,
|
||||
`oxyloss` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=166546 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=166546 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -240,7 +240,7 @@ CREATE TABLE `SS13_feedback` (
|
||||
`version` tinyint(3) UNSIGNED NOT NULL,
|
||||
`json` LONGTEXT NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=257638 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=257638 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -276,6 +276,7 @@ CREATE TABLE `SS13_player` (
|
||||
`fupdate` smallint(4) DEFAULT '0',
|
||||
`parallax` tinyint(1) DEFAULT '8',
|
||||
`byond_date` DATE DEFAULT NULL,
|
||||
`2fa_status` ENUM('DISABLED','ENABLED_IP','ENABLED_ALWAYS') NOT NULL DEFAULT 'DISABLED' COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `ckey` (`ckey`),
|
||||
KEY `lastseen` (`lastseen`),
|
||||
@@ -320,7 +321,7 @@ CREATE TABLE `SS13_karma` (
|
||||
`spenderip` text NOT NULL,
|
||||
`time` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=73614 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=73614 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -337,7 +338,7 @@ CREATE TABLE `SS13_karmatotals` (
|
||||
`karmaspent` int(11) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `byondkey` (`byondkey`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=25715 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=25715 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -358,7 +359,7 @@ CREATE TABLE `SS13_library` (
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ckey` (`ckey`),
|
||||
KEY `flagged` (`flagged`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=4537 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4537 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -374,7 +375,7 @@ CREATE TABLE `SS13_legacy_population` (
|
||||
`admincount` int(11) DEFAULT NULL,
|
||||
`time` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=2550 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2550 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -391,7 +392,7 @@ CREATE TABLE `SS13_whitelist` (
|
||||
`species` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ckey` (`ckey`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=4080 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4080 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
@@ -582,3 +583,15 @@ CREATE TABLE `SS13_round` (
|
||||
`station_name` VARCHAR(80) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- Table structure for table `2fa_secrets`
|
||||
--
|
||||
CREATE TABLE `SS13_2fa_secrets` (
|
||||
`ckey` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`secret` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`date_setup` DATETIME NOT NULL DEFAULT current_timestamp(),
|
||||
`last_time` DATETIME NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`ckey`) USING BTREE
|
||||
)
|
||||
COLLATE='utf8mb4_general_ci' ENGINE=InnoDB;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# Updating SQL from version 22 to 23 -AffectedArc07
|
||||
# Converts existing MyISAM tables to InnoDB
|
||||
|
||||
ALTER TABLE `customuseritems` ENGINE=InnoDB;
|
||||
ALTER TABLE `death` ENGINE=InnoDB;
|
||||
ALTER TABLE `feedback` ENGINE=InnoDB;
|
||||
ALTER TABLE `karma` ENGINE=InnoDB;
|
||||
ALTER TABLE `karmatotals` ENGINE=InnoDB;
|
||||
ALTER TABLE `legacy_population` ENGINE=InnoDB;
|
||||
ALTER TABLE `library` ENGINE=InnoDB;
|
||||
ALTER TABLE `whitelist` ENGINE=InnoDB;
|
||||
@@ -0,0 +1,13 @@
|
||||
# Updates DB from 23 to 24 -AffectedArc07
|
||||
# Add new column to player table for 2FA status
|
||||
ALTER TABLE `player` ADD COLUMN `2fa_status` ENUM('DISABLED','ENABLED_IP','ENABLED_ALWAYS') NOT NULL DEFAULT 'DISABLED' AFTER `byond_date`;
|
||||
|
||||
# Create new table for 2FA tokens
|
||||
CREATE TABLE `2fa_secrets` (
|
||||
`ckey` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`secret` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`date_setup` DATETIME NOT NULL DEFAULT current_timestamp(),
|
||||
`last_time` DATETIME NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`ckey`) USING BTREE
|
||||
)
|
||||
COLLATE='utf8mb4_general_ci' ENGINE=InnoDB;
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "map_files\generic\centcomm.dmm"
|
||||
#define CC_TRANSITION_CONFIG DECLARE_LEVEL(CENTCOMM, SELFLOOPING, list(ADMIN_LEVEL, BLOCK_TELEPORT, IMPEDES_MAGIC))
|
||||
#ifdef CIMAP
|
||||
#include "ci_map_testing.dm"
|
||||
#endif
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
All z-levels should be identical in size. Their numbers should not matter.
|
||||
The order of z-levels should not matter as long as their attributes are properly defined at MAP_TRANSITION_CONFIG.
|
||||
Old code checked for the number of the z-level (for example whether there are any revheads on Z1),
|
||||
currently it should check for the define (for example whether there are any revheads on any z-levels defined as STATION_LEVEL).
|
||||
z1 = centcomm
|
||||
z2 = station
|
||||
z3 = lavaland
|
||||
*/
|
||||
|
||||
#if !defined(USING_MAP_DATUM)
|
||||
#include "map_files\generic\centcomm.dmm"
|
||||
#include "map_files\cyberiad\cyberiad.dmm"
|
||||
#include "map_files\generic\Lavaland.dmm"
|
||||
|
||||
#define MAP_TRANSITION_CONFIG list(\
|
||||
DECLARE_LEVEL(CENTCOMM, SELFLOOPING, list(ADMIN_LEVEL, BLOCK_TELEPORT, IMPEDES_MAGIC)),\
|
||||
DECLARE_LEVEL(MAIN_STATION, CROSSLINKED, list(STATION_LEVEL, STATION_CONTACT, REACHABLE, AI_OK)),\
|
||||
DECLARE_LEVEL(MINING, SELFLOOPING, list(ORE_LEVEL, REACHABLE, STATION_CONTACT, HAS_WEATHER, AI_OK)))
|
||||
|
||||
#define USING_MAP_DATUM /datum/map/cyberiad
|
||||
|
||||
#elif !defined(MAP_OVERRIDE)
|
||||
|
||||
#warn a map has already been included, ignoring Cyberiad.
|
||||
|
||||
#endif
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
All z-levels should be identical in size. Their numbers should not matter.
|
||||
The order of z-levels should not matter as long as their attributes are properly defined at MAP_TRANSITION_CONFIG.
|
||||
Old code checked for the number of the z-level (for example whether there are any revheads on Z1),
|
||||
currently it should check for the define (for example whether there are any revheads on any z-levels defined as STATION_LEVEL).
|
||||
z1 = centcomm
|
||||
z2 = station
|
||||
z3 = lavaland
|
||||
|
||||
Original design by Okand37 of TG Station
|
||||
Lovingly ported by Purpose2 to Paradise
|
||||
*/
|
||||
|
||||
#if !defined(USING_MAP_DATUM)
|
||||
#include "map_files\generic\centcomm.dmm"
|
||||
#include "map_files\delta\delta.dmm"
|
||||
#include "map_files\generic\Lavaland.dmm"
|
||||
|
||||
#define MAP_TRANSITION_CONFIG list(\
|
||||
DECLARE_LEVEL(CENTCOMM, SELFLOOPING, list(ADMIN_LEVEL, BLOCK_TELEPORT, IMPEDES_MAGIC)),\
|
||||
DECLARE_LEVEL(MAIN_STATION, CROSSLINKED, list(STATION_LEVEL, STATION_CONTACT, REACHABLE, AI_OK)),\
|
||||
DECLARE_LEVEL(MINING, SELFLOOPING, list(ORE_LEVEL, REACHABLE, STATION_CONTACT, HAS_WEATHER, AI_OK)))
|
||||
|
||||
#define USING_MAP_DATUM /datum/map/delta
|
||||
|
||||
#elif !defined(MAP_OVERRIDE)
|
||||
|
||||
#warn a map has already been included, ignoring Delta.
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1 @@
|
||||
// See code/modules/mapping for map datums
|
||||
+10494
-17177
File diff suppressed because it is too large
Load Diff
@@ -132,7 +132,7 @@
|
||||
/area/ruin/powered/beach)
|
||||
"ax" = (
|
||||
/obj/machinery/disco/immobile,
|
||||
/turf/simulated/floor/light/colour_cycle,
|
||||
/turf/simulated/floor/light,
|
||||
/area/ruin/powered/beach)
|
||||
"ay" = (
|
||||
/obj/machinery/door/airlock/sandstone{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -133,7 +133,7 @@
|
||||
},
|
||||
/area/derelict/bridge)
|
||||
"av" = (
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 1;
|
||||
icon_state = "darkblue"
|
||||
@@ -3697,7 +3697,7 @@
|
||||
name = "Derelict Annex"
|
||||
})
|
||||
"hD" = (
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "caution";
|
||||
dir = 5
|
||||
@@ -6735,7 +6735,7 @@
|
||||
})
|
||||
"nS" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/reagent_containers/food/snacks/beetsoup,
|
||||
/obj/item/reagent_containers/food/snacks/soup/beetsoup,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "bar"
|
||||
},
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
},
|
||||
/turf/simulated/floor/beach/away/water/deep/sand_floor,
|
||||
/area/awaymission/undersea)
|
||||
"af" = (
|
||||
/obj/structure/constructshell,
|
||||
/turf/simulated/floor/beach/away/water/deep/wood_floor,
|
||||
/area/awaymission/undersea)
|
||||
"ag" = (
|
||||
/obj/structure/chair/wood/wings,
|
||||
/turf/simulated/floor/beach/away/water/deep/wood_floor,
|
||||
@@ -46312,7 +46308,7 @@ ad
|
||||
ad
|
||||
ad
|
||||
ah
|
||||
af
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ar
|
||||
@@ -46823,7 +46819,7 @@ av
|
||||
av
|
||||
ad
|
||||
ad
|
||||
af
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
@@ -48108,7 +48104,7 @@ av
|
||||
av
|
||||
ad
|
||||
ad
|
||||
af
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
@@ -48625,7 +48621,7 @@ ad
|
||||
ad
|
||||
ad
|
||||
ah
|
||||
af
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
|
||||
@@ -2536,7 +2536,7 @@
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/obj/effect/decal/warning_stripes/west,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/awaymission/BMPship/Aft)
|
||||
|
||||
@@ -2785,7 +2785,7 @@
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "yellow"
|
||||
},
|
||||
|
||||
@@ -1308,7 +1308,7 @@
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
@@ -5160,7 +5160,7 @@
|
||||
/turf/simulated/floor/plating,
|
||||
/area/awaycontent/a7)
|
||||
"hm" = (
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/obj/structure/cable,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/awaycontent/a7)
|
||||
|
||||
@@ -666,7 +666,7 @@
|
||||
/area/awaymission/spacebattle/cruiser)
|
||||
"cS" = (
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/item/reagent_containers/food/snacks/stew,
|
||||
/obj/item/reagent_containers/food/snacks/soup/stew,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "cafeteria";
|
||||
dir = 2
|
||||
|
||||
@@ -7975,7 +7975,7 @@
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "primary power monitoring console"
|
||||
},
|
||||
/obj/structure/sign/nosmoking_2{
|
||||
@@ -10652,7 +10652,7 @@
|
||||
/turf/simulated/floor/plating/asteroid/airless,
|
||||
/area/awaymission/UO71/outside)
|
||||
"vV" = (
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/awaymission/UO71/bridge)
|
||||
"vW" = (
|
||||
@@ -11805,7 +11805,7 @@
|
||||
},
|
||||
/area/awaymission/UO71/eng)
|
||||
"yc" = (
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "primary power monitoring console"
|
||||
},
|
||||
/obj/structure/cable,
|
||||
|
||||
@@ -11078,7 +11078,7 @@
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "primary power monitoring console"
|
||||
},
|
||||
/obj/structure/sign/nosmoking_2{
|
||||
@@ -15909,7 +15909,7 @@
|
||||
name = "UO45 Engineering"
|
||||
})
|
||||
"xg" = (
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "primary power monitoring console"
|
||||
},
|
||||
/obj/structure/cable,
|
||||
|
||||
@@ -1217,7 +1217,7 @@
|
||||
},
|
||||
/area/awaymission/wwgov)
|
||||
"dy" = (
|
||||
/obj/item/reagent_containers/food/snacks/stew,
|
||||
/obj/item/reagent_containers/food/snacks/soup/stew,
|
||||
/turf/simulated/floor/plasteel{
|
||||
tag = "icon-stage_bleft";
|
||||
icon_state = "stage_bleft"
|
||||
|
||||
@@ -11168,6 +11168,9 @@
|
||||
icon_state = "tube1";
|
||||
tag = "icon-tube1 (WEST)"
|
||||
},
|
||||
/obj/structure/chair/comfy/shuttle{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/specops)
|
||||
"QL" = (
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
All z-levels should be identical in size. Their numbers should not matter.
|
||||
The order of z-levels should not matter as long as their attributes are properly defined at MAP_TRANSITION_CONFIG.
|
||||
Old code checked for the number of the z-level (for example whether there are any revheads on Z1),
|
||||
currently it should check for the define (for example whether there are any revheads on any z-levels defined as STATION_LEVEL).
|
||||
z1 = centcomm
|
||||
z2 = station
|
||||
z3 = lavaland
|
||||
*/
|
||||
|
||||
#if !defined(USING_MAP_DATUM)
|
||||
#include "map_files\generic\centcomm.dmm"
|
||||
#include "map_files\MetaStation\MetaStation.dmm"
|
||||
#include "map_files\generic\Lavaland.dmm"
|
||||
|
||||
#define MAP_TRANSITION_CONFIG list(\
|
||||
DECLARE_LEVEL(CENTCOMM, SELFLOOPING, list(ADMIN_LEVEL, BLOCK_TELEPORT, IMPEDES_MAGIC)),\
|
||||
DECLARE_LEVEL(MAIN_STATION, CROSSLINKED, list(STATION_LEVEL, STATION_CONTACT, REACHABLE, AI_OK)),\
|
||||
DECLARE_LEVEL(MINING, SELFLOOPING, list(ORE_LEVEL, REACHABLE, STATION_CONTACT, HAS_WEATHER, AI_OK)))
|
||||
|
||||
#define USING_MAP_DATUM /datum/map/metastation
|
||||
|
||||
#elif !defined(MAP_OVERRIDE)
|
||||
|
||||
#warn a map has already been included, ignoring MetaStation.
|
||||
|
||||
#endif
|
||||
@@ -81,3 +81,4 @@
|
||||
#define NO_INTORGANS "no_internal_organs"
|
||||
#define CAN_WINGDINGS "can_wingdings"
|
||||
#define NO_CLONESCAN "no_clone_scan"
|
||||
#define NO_HAIR "no_hair"
|
||||
|
||||
@@ -363,7 +363,7 @@
|
||||
#define INVESTIGATE_BOMB "bombs"
|
||||
|
||||
// The SQL version required by this version of the code
|
||||
#define SQL_VERSION 22
|
||||
#define SQL_VERSION 24
|
||||
|
||||
// Vending machine stuff
|
||||
#define CAT_NORMAL 1
|
||||
|
||||
@@ -55,8 +55,9 @@
|
||||
// Yes I know this being an "enable to disable" is misleading, but it avoids having to tweak all existing pref entries
|
||||
#define PREFTOGGLE_2_REVERB_DISABLE 512
|
||||
#define PREFTOGGLE_2_FORCE_WHITE_RUNECHAT 1024
|
||||
#define PREFTOGGLE_2_SIMPLE_STAT_PANEL 2048
|
||||
|
||||
#define TOGGLES_2_TOTAL 2047 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined.
|
||||
#define TOGGLES_2_TOTAL 4095 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined.
|
||||
|
||||
#define TOGGLES_2_DEFAULT (PREFTOGGLE_2_FANCYUI|PREFTOGGLE_2_ITEMATTACK|PREFTOGGLE_2_WINDOWFLASHING|PREFTOGGLE_2_RUNECHAT|PREFTOGGLE_2_DEATHMESSAGE|PREFTOGGLE_2_EMOTE_BUBBLE)
|
||||
|
||||
@@ -94,7 +95,7 @@
|
||||
#define EXP_TYPE_SERVICE "Service"
|
||||
#define EXP_TYPE_WHITELIST "Whitelist"
|
||||
|
||||
#define EXP_DEPT_TYPE_LIST list(EXP_TYPE_SERVICE, EXP_TYPE_MEDICAL, EXP_TYPE_ENGINEERING, EXP_TYPE_SCIENCE, EXP_TYPE_SECURITY, EXP_TYPE_COMMAND, EXP_TYPE_SILICON, EXP_TYPE_SPECIAL)
|
||||
#define EXP_DEPT_TYPE_LIST list(EXP_TYPE_SUPPLY, EXP_TYPE_SERVICE, EXP_TYPE_MEDICAL, EXP_TYPE_ENGINEERING, EXP_TYPE_SCIENCE, EXP_TYPE_SECURITY, EXP_TYPE_COMMAND, EXP_TYPE_SILICON, EXP_TYPE_SPECIAL, EXP_TYPE_GHOST)
|
||||
|
||||
// Defines just for parallax because its levels make storing it in the regular prefs a pain in the ass
|
||||
// These dont need to be bitflags because there isnt going to be more than one at a time of these active
|
||||
@@ -104,3 +105,12 @@
|
||||
#define PARALLAX_MED 4
|
||||
#define PARALLAX_HIGH 8
|
||||
#define PARALLAX_INSANE 16
|
||||
|
||||
// 2FA Defines. These are the same as the schema DB enums //
|
||||
|
||||
/// Client has 2FA disabled
|
||||
#define _2FA_DISABLED "DISABLED"
|
||||
/// Client will be prompted for 2FA on IP changes
|
||||
#define _2FA_ENABLED_IP "ENABLED_IP"
|
||||
/// Client will be prompted for 2FA always
|
||||
#define _2FA_ENABLED_ALWAYS "ENABLED_ALWAYS"
|
||||
|
||||
@@ -6,11 +6,14 @@
|
||||
#define CHANNEL_HEARTBEAT 1020 //sound channel for heartbeats
|
||||
#define CHANNEL_BUZZ 1019
|
||||
#define CHANNEL_AMBIENCE 1018
|
||||
#define CHANNEL_ENGINE 1017 // Engine ambient sounds
|
||||
|
||||
#define USER_VOLUME(M, C) M?.client?.prefs.get_channel_volume(C)
|
||||
|
||||
//THIS SHOULD ALWAYS BE THE LOWEST ONE!
|
||||
//KEEP IT UPDATED
|
||||
|
||||
#define CHANNEL_HIGHEST_AVAILABLE 1017
|
||||
#define CHANNEL_HIGHEST_AVAILABLE 1016
|
||||
|
||||
#define MAX_INSTRUMENT_CHANNELS (128 * 6)
|
||||
|
||||
|
||||
@@ -134,9 +134,6 @@ GLOBAL_PROTECT(log_end)
|
||||
/proc/log_href(text)
|
||||
rustg_log_write(GLOB.world_href_log, "HREF: [html_decode(text)][GLOB.log_end]")
|
||||
|
||||
/proc/log_asset(text)
|
||||
rustg_log_write(GLOB.world_asset_log, "ASSET: [text][GLOB.log_end]")
|
||||
|
||||
/proc/log_runtime_summary(text)
|
||||
rustg_log_write(GLOB.runtime_summary_log, "[text][GLOB.log_end]")
|
||||
|
||||
@@ -147,6 +144,9 @@ GLOBAL_PROTECT(log_end)
|
||||
rustg_log_write(GLOB.sql_log, "[text][GLOB.log_end]")
|
||||
SEND_TEXT(world.log, text) // Redirect it to DD too
|
||||
|
||||
/proc/log_chat_debug(text)
|
||||
rustg_log_write(GLOB.chat_debug_log, "[text][GLOB.log_end]")
|
||||
|
||||
// A logging proc that only outputs after setup is done, to
|
||||
// help devs test initialization stuff that happens a lot
|
||||
/proc/log_after_setup(message)
|
||||
|
||||
@@ -84,13 +84,13 @@
|
||||
continue
|
||||
|
||||
if(!use_name)
|
||||
error("Loadout - Missing display name: [G]")
|
||||
stack_trace("Loadout - Missing display name: [G]")
|
||||
continue
|
||||
if(!initial(G.cost))
|
||||
error("Loadout - Missing cost: [G]")
|
||||
stack_trace("Loadout - Missing cost: [G]")
|
||||
continue
|
||||
if(!initial(G.path))
|
||||
error("Loadout - Missing path definition: [G]")
|
||||
stack_trace("Loadout - Missing path definition: [G]")
|
||||
continue
|
||||
|
||||
if(!GLOB.loadout_categories[use_category])
|
||||
|
||||
@@ -15,9 +15,9 @@ GLOBAL_VAR(church_name)
|
||||
|
||||
return name
|
||||
|
||||
GLOBAL_VAR(command_name)
|
||||
// TODO: Remove this. Its always gonna be NAS Trurl
|
||||
/proc/command_name()
|
||||
return GLOB.using_map.dock_name
|
||||
return "NAS Trurl"
|
||||
|
||||
GLOBAL_VAR(religion_name)
|
||||
/proc/religion_name()
|
||||
@@ -31,11 +31,8 @@ GLOBAL_VAR(religion_name)
|
||||
|
||||
return capitalize(name)
|
||||
|
||||
/proc/system_name()
|
||||
return GLOB.using_map.starsys_name
|
||||
|
||||
/proc/station_name()
|
||||
return GLOB.using_map.station_name
|
||||
return SSmapping.map_datum.fluff_name
|
||||
|
||||
/proc/new_station_name()
|
||||
var/random = rand(1,5)
|
||||
|
||||
@@ -513,6 +513,8 @@
|
||||
text = replacetext(text, "\[cell\]", "<td>")
|
||||
text = replacetext(text, "\[logo\]", "​<img src = ntlogo.png>")
|
||||
text = replacetext(text, "\[time\]", "[station_time_timestamp()]") // TO DO
|
||||
text = replacetext(text, "\[date\]", "[GLOB.current_date_string]")
|
||||
text = replacetext(text, "\[station\]", "[SSmapping.map_datum.fluff_name]")
|
||||
if(!no_font)
|
||||
if(P)
|
||||
text = "<font face=\"[deffont]\" color=[P ? P.colour : "black"]>[text]</font>"
|
||||
@@ -651,3 +653,79 @@
|
||||
|
||||
// return the split html object to the caller
|
||||
return s
|
||||
|
||||
//Used for applying byonds text macros to strings that are loaded at runtime
|
||||
/proc/apply_text_macros(string)
|
||||
var/next_backslash = findtext(string, "\\")
|
||||
if(!next_backslash)
|
||||
return string
|
||||
|
||||
var/leng = length(string)
|
||||
|
||||
var/next_space = findtext(string, " ", next_backslash + length(string[next_backslash]))
|
||||
if(!next_space)
|
||||
next_space = leng - next_backslash
|
||||
|
||||
if(!next_space) //trailing bs
|
||||
return string
|
||||
|
||||
var/base = next_backslash == 1 ? "" : copytext(string, 1, next_backslash)
|
||||
var/macro = lowertext(copytext(string, next_backslash + length(string[next_backslash]), next_space))
|
||||
var/rest = next_backslash > leng ? "" : copytext(string, next_space + length(string[next_space]))
|
||||
|
||||
//See https://secure.byond.com/docs/ref/info.html#/DM/text/macros
|
||||
switch(macro)
|
||||
//prefixes/agnostic
|
||||
if("the")
|
||||
rest = text("\the []", rest)
|
||||
if("a")
|
||||
rest = text("\a []", rest)
|
||||
if("an")
|
||||
rest = text("\an []", rest)
|
||||
if("proper")
|
||||
rest = text("\proper []", rest)
|
||||
if("improper")
|
||||
rest = text("\improper []", rest)
|
||||
if("roman")
|
||||
rest = text("\roman []", rest)
|
||||
//postfixes
|
||||
if("th")
|
||||
base = text("[]\th", rest)
|
||||
if("s")
|
||||
base = text("[]\s", rest)
|
||||
if("he")
|
||||
base = text("[]\he", rest)
|
||||
if("she")
|
||||
base = text("[]\she", rest)
|
||||
if("his")
|
||||
base = text("[]\his", rest)
|
||||
if("himself")
|
||||
base = text("[]\himself", rest)
|
||||
if("herself")
|
||||
base = text("[]\herself", rest)
|
||||
if("hers")
|
||||
base = text("[]\hers", rest)
|
||||
|
||||
. = base
|
||||
if(rest)
|
||||
. += .(rest)
|
||||
|
||||
/**
|
||||
* Proc to generate a "rank colour" from a client
|
||||
*
|
||||
* This takes the client and looks at various factors in order, such as patreon status, staff rank, and more
|
||||
* Arguments:
|
||||
* * C - The client were looking up
|
||||
*/
|
||||
/proc/client2rankcolour(client/C)
|
||||
// First check if end user is an admin
|
||||
if(C.holder)
|
||||
if(C.holder.rank in GLOB.rank_colour_map)
|
||||
// Return their rank colour if they are in here
|
||||
return GLOB.rank_colour_map[C.holder.rank]
|
||||
|
||||
// If they arent an admin, see if they are a patreon. Just accept any level
|
||||
if(C.donator_level)
|
||||
return "#e67e22" // Patreon orange
|
||||
return null
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
Remember to update _globalvars/traits.dm if you're adding/removing/renaming traits.
|
||||
*/
|
||||
|
||||
//mob traits
|
||||
//***** MOB TRAITS *****//
|
||||
#define TRAIT_BLIND "blind"
|
||||
#define TRAIT_MUTE "mute"
|
||||
#define TRAIT_DEAF "deaf"
|
||||
@@ -152,8 +152,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_NOEXAMINE "no_examine"
|
||||
#define TRAIT_NOPAIN "no_pain"
|
||||
|
||||
/// Blowing kisses actually does damage to the victim
|
||||
#define TRAIT_KISS_OF_DEATH "kiss_of_death"
|
||||
//***** ITEM TRAITS *****//
|
||||
/// Show what machine/door wires do when held.
|
||||
#define TRAIT_SHOW_WIRE_INFO "show_wire_info"
|
||||
|
||||
//
|
||||
// common trait sources
|
||||
|
||||
@@ -2072,7 +2072,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
return _list
|
||||
|
||||
/// Waits at a line of code until X is true
|
||||
#define UNTIL(X) while(!(X)) stoplag()
|
||||
#define UNTIL(X) while(!(X)) sleep(world.tick_lag)
|
||||
|
||||
// Check if the source atom contains another atom
|
||||
/atom/proc/contains(atom/location)
|
||||
@@ -2116,6 +2116,8 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
return "White Noise"
|
||||
if(CHANNEL_AMBIENCE)
|
||||
return "Ambience"
|
||||
if(CHANNEL_ENGINE)
|
||||
return "Engine Ambience"
|
||||
|
||||
/proc/slot_bitfield_to_slot(input_slot_flags) // Kill off this garbage ASAP; slot flags and clothing flags should be IDENTICAL. GOSH DARN IT. Doesn't work with ears or pockets, either.
|
||||
switch(input_slot_flags)
|
||||
|
||||
@@ -54,4 +54,7 @@ GLOBAL_LIST_INIT(cooking_recipes, list(RECIPE_MICROWAVE = list(), RECIPE_OVEN =
|
||||
GLOBAL_LIST_INIT(cooking_ingredients, list(RECIPE_MICROWAVE = list(), RECIPE_OVEN = list(), RECIPE_GRILL = list(), RECIPE_CANDY = list()))
|
||||
GLOBAL_LIST_INIT(cooking_reagents, list(RECIPE_MICROWAVE = list(), RECIPE_OVEN = list(), RECIPE_GRILL = list(), RECIPE_CANDY = list()))
|
||||
|
||||
/// Associative list of admin rank to colour. Set in config/rank_colours.txt
|
||||
GLOBAL_LIST_EMPTY(rank_colour_map)
|
||||
|
||||
#define EGG_LAYING_MESSAGES list("lays an egg.", "squats down and croons.", "begins making a huge racket.", "begins clucking raucously.")
|
||||
|
||||
@@ -18,6 +18,7 @@ GLOBAL_LIST_INIT(cell_logs, list())
|
||||
GLOBAL_LIST_INIT(navigation_computers, list())
|
||||
|
||||
GLOBAL_LIST_INIT(all_areas, list())
|
||||
GLOBAL_LIST_INIT(all_unique_areas, list()) // List of all unique areas. AKA areas with there_can_be_many = FALSE
|
||||
GLOBAL_LIST_INIT(machines, list())
|
||||
GLOBAL_LIST_INIT(rcd_list, list()) //list of Rapid Construction Devices.
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@ GLOBAL_VAR(world_qdel_log)
|
||||
GLOBAL_PROTECT(world_qdel_log)
|
||||
GLOBAL_VAR(world_href_log)
|
||||
GLOBAL_PROTECT(world_href_log)
|
||||
GLOBAL_VAR(world_asset_log)
|
||||
GLOBAL_PROTECT(world_asset_log)
|
||||
GLOBAL_VAR(runtime_summary_log)
|
||||
GLOBAL_PROTECT(runtime_summary_log)
|
||||
GLOBAL_VAR(tgui_log)
|
||||
@@ -21,6 +19,8 @@ GLOBAL_VAR(http_log)
|
||||
GLOBAL_PROTECT(http_log)
|
||||
GLOBAL_VAR(sql_log)
|
||||
GLOBAL_PROTECT(sql_log)
|
||||
GLOBAL_VAR(chat_debug_log)
|
||||
GLOBAL_PROTECT(chat_debug_log)
|
||||
GLOBAL_VAR(round_id)
|
||||
GLOBAL_PROTECT(round_id)
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@ GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, S
|
||||
GLOBAL_LIST_INIT(alldirs2, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST, NORTH, SOUTH, EAST, WEST))
|
||||
GLOBAL_LIST_INIT(diagonals, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
|
||||
|
||||
// This must exist early on or shit breaks bad
|
||||
GLOBAL_DATUM_INIT(using_map, /datum/map, new USING_MAP_DATUM)
|
||||
|
||||
GLOBAL_LIST(global_map) // This is the array of zlevels | list(list(1,5),list(4,3)) | becomes a 2D array of zlevels
|
||||
//Resulting sector map looks like
|
||||
//|_1_|_4_|
|
||||
|
||||
@@ -86,13 +86,9 @@ GLOBAL_VAR_INIT(copier_items_printed, 0)
|
||||
GLOBAL_VAR_INIT(copier_max_items, 300)
|
||||
GLOBAL_VAR_INIT(copier_items_printed_logged, FALSE)
|
||||
|
||||
|
||||
GLOBAL_VAR(map_name) // Self explanatory
|
||||
|
||||
GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) // Station datacore, manifest, etc
|
||||
|
||||
GLOBAL_VAR_INIT(panic_bunker_enabled, FALSE) // Is the panic bunker enabled
|
||||
GLOBAL_VAR_INIT(pending_server_update, FALSE)
|
||||
|
||||
GLOBAL_LIST_EMPTY(ability_verbs) // Create-level abilities
|
||||
GLOBAL_LIST_INIT(pipe_colors, list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_RED, "blue" = PIPE_COLOR_BLUE, "cyan" = PIPE_COLOR_CYAN, "green" = PIPE_COLOR_GREEN, "yellow" = PIPE_COLOR_YELLOW, "purple" = PIPE_COLOR_PURPLE))
|
||||
|
||||
@@ -45,7 +45,6 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_DWARF" = TRAIT_DWARF,
|
||||
"TRAIT_SILENT_FOOTSTEPS" = TRAIT_SILENT_FOOTSTEPS,
|
||||
"TRAIT_ALCOHOL_TOLERANCE" = TRAIT_ALCOHOL_TOLERANCE,
|
||||
"TRAIT_KISS_OF_DEATH" = TRAIT_KISS_OF_DEATH,
|
||||
|
||||
"TRAIT_COMIC_SANS" = TRAIT_COMIC_SANS,
|
||||
"TRAIT_NOFINGERPRINTS" = TRAIT_NOFINGERPRINTS,
|
||||
@@ -57,7 +56,12 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_NOGERMS" = TRAIT_NOGERMS,
|
||||
"TRAIT_NODECAY" = TRAIT_NODECAY,
|
||||
"TRAIT_NOEXAMINE" = TRAIT_NOEXAMINE,
|
||||
"TRAIT_NOPAIN" = TRAIT_NOPAIN)))
|
||||
"TRAIT_NOPAIN" = TRAIT_NOPAIN
|
||||
),
|
||||
/obj/item = list(
|
||||
"TRAIT_SHOW_WIRE_INFO" = TRAIT_SHOW_WIRE_INFO
|
||||
)
|
||||
))
|
||||
|
||||
/// value -> trait name, generated on use from trait_by_type global
|
||||
GLOBAL_LIST(trait_name_map)
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
|
||||
/obj/item/badminBook/attack_self(mob/living/user as mob)
|
||||
if(user.middleClickOverride)
|
||||
to_chat(user, "<span class='warning'>You try to draw power from the [src], but you cannot hold the power at this time!</span>")
|
||||
to_chat(user, "<span class='warning'>You try to draw power from [src], but you cannot hold the power at this time!</span>")
|
||||
return
|
||||
user.middleClickOverride = clickBehavior
|
||||
to_chat(user, "<span class='notice'>You draw a bit of power from the [src], you can use <b>middle click</b> or <b>alt click</b> to release the power!</span>")
|
||||
to_chat(user, "<span class='notice'>You draw a bit of power from [src], you can use <b>middle click</b> or <b>alt click</b> to release the power!</span>")
|
||||
|
||||
/datum/middleClickOverride/badminClicker
|
||||
var/summon_path = /obj/item/reagent_containers/food/snacks/cookie
|
||||
|
||||
@@ -122,12 +122,12 @@
|
||||
icon_state = "too_much_oxy"
|
||||
|
||||
/obj/screen/alert/not_enough_nitro
|
||||
name = "Choking (No N)"
|
||||
name = "Choking (No N2)"
|
||||
desc = "You're not getting enough nitrogen. Find some good air before you pass out!"
|
||||
icon_state = "not_enough_nitro"
|
||||
|
||||
/obj/screen/alert/too_much_nitro
|
||||
name = "Choking (N)"
|
||||
name = "Choking (N2)"
|
||||
desc = "There's too much nitrogen in the air, and you're breathing it in! Find some good air before you pass out!"
|
||||
icon_state = "too_much_nitro"
|
||||
|
||||
|
||||
@@ -132,6 +132,8 @@
|
||||
if(isovermind(usr))
|
||||
var/mob/camera/blob/B = usr
|
||||
B.split_consciousness()
|
||||
if(B.split_used) // Destroys split proc if the split is succesfully used
|
||||
qdel(src)
|
||||
|
||||
/datum/hud/blob_overmind/New(mob/user)
|
||||
..()
|
||||
@@ -194,6 +196,8 @@
|
||||
using.screen_loc = ui_storage2
|
||||
static_inventory += using
|
||||
|
||||
using = new /obj/screen/blob/Split()
|
||||
using.screen_loc = ui_acti
|
||||
static_inventory += using
|
||||
var/mob/camera/blob/B = user
|
||||
if(!B.is_offspring) // Checks if the blob is an offspring, to not create split button if it is
|
||||
using = new /obj/screen/blob/Split()
|
||||
using.screen_loc = ui_acti
|
||||
static_inventory += using
|
||||
|
||||
@@ -78,15 +78,6 @@
|
||||
var/mob/living/silicon/robot/R = usr
|
||||
R.toggle_ionpulse()
|
||||
|
||||
/obj/screen/robot/panel
|
||||
name = "installed modules"
|
||||
icon_state = "panel"
|
||||
|
||||
/obj/screen/robot/panel/Click()
|
||||
if(issilicon(usr))
|
||||
var/mob/living/silicon/robot/R = usr
|
||||
R.installed_modules()
|
||||
|
||||
/obj/screen/robot/mov_intent
|
||||
name = "fast/slow toggle"
|
||||
icon_state = "running"
|
||||
@@ -224,16 +215,6 @@
|
||||
var/x = -4 //Start at CENTER-4,SOUTH+1
|
||||
var/y = 1
|
||||
|
||||
//Unfortunately adding the emag module to the list of modules has to be here. This is because a borg can
|
||||
//be emagged before they actually select a module. - or some situation can cause them to get a new module
|
||||
// - or some situation might cause them to get de-emagged or something.
|
||||
if(R.emagged || R.weapons_unlock)
|
||||
if(!(R.module.emag in R.module.modules))
|
||||
R.module.modules.Add(R.module.emag)
|
||||
else
|
||||
if(R.module.emag in R.module.modules)
|
||||
R.module.modules.Remove(R.module.emag)
|
||||
|
||||
for(var/atom/movable/A in R.module.modules)
|
||||
if( (A != R.module_state_1) && (A != R.module_state_2) && (A != R.module_state_3) )
|
||||
//Module is not currently active
|
||||
|
||||
@@ -275,6 +275,12 @@
|
||||
/// Enable auto profiler of rounds
|
||||
var/auto_profile = FALSE
|
||||
|
||||
// Enable map voting
|
||||
var/map_voting_enabled = FALSE
|
||||
|
||||
// 2FA auth host
|
||||
var/_2fa_auth_host = null
|
||||
|
||||
/datum/configuration/New()
|
||||
for(var/T in subtypesof(/datum/game_mode))
|
||||
var/datum/game_mode/M = T
|
||||
@@ -770,6 +776,10 @@
|
||||
max_client_cid_history = text2num(value)
|
||||
if("enable_auto_profiler")
|
||||
auto_profile = TRUE
|
||||
if("enable_map_voting")
|
||||
map_voting_enabled = TRUE
|
||||
if("2fa_host")
|
||||
_2fa_auth_host = value
|
||||
else
|
||||
log_config("Unknown setting in configuration: '[name]'")
|
||||
|
||||
@@ -925,3 +935,34 @@
|
||||
runnable_modes[M] = probabilities[M.config_tag]
|
||||
// to_chat(world, "DEBUG: runnable_mode\[[runnable_modes.len]\] = [M.config_tag]")
|
||||
return runnable_modes
|
||||
|
||||
/datum/configuration/proc/load_rank_colour_map()
|
||||
var/list/lines = file2list("config/rank_colours.txt")
|
||||
|
||||
for(var/line in lines)
|
||||
// Skip newlines
|
||||
if(!length(line))
|
||||
continue
|
||||
// Skip comments
|
||||
if(line[1] == "#")
|
||||
continue
|
||||
|
||||
//Split the line at every " - "
|
||||
var/list/split_holder = splittext(line, " - ")
|
||||
if(!length(split_holder))
|
||||
continue
|
||||
|
||||
// Rank is before the " - "
|
||||
var/rank = split_holder[1]
|
||||
if(!rank)
|
||||
continue
|
||||
|
||||
// Color is after the " - "
|
||||
var/colour = ""
|
||||
if(length(split_holder) >= 2)
|
||||
colour = split_holder[2]
|
||||
|
||||
if(rank && colour)
|
||||
GLOB.rank_colour_map[rank] = colour
|
||||
else
|
||||
stack_trace("Invalid colour for rank '[rank]' in config/rank_colours.txt")
|
||||
|
||||
@@ -65,7 +65,7 @@ SUBSYSTEM_DEF(blackbox)
|
||||
sqlversion = versions[FV.key]
|
||||
|
||||
var/datum/db_query/query_feedback_save = SSdbcore.NewQuery({"
|
||||
INSERT DELAYED IGNORE INTO [format_table_name("feedback")] (datetime, round_id, key_name, key_type, version, json)
|
||||
INSERT IGNORE INTO [format_table_name("feedback")] (datetime, round_id, key_name, key_type, version, json)
|
||||
VALUES (NOW(), :rid, :keyname, :keytype, :version, :json)"}, list(
|
||||
"rid" = text2num(GLOB.round_id),
|
||||
"keyname" = FV.key,
|
||||
|
||||
@@ -193,7 +193,7 @@ SUBSYSTEM_DEF(dbcore)
|
||||
if(!IsConnected())
|
||||
return
|
||||
var/datum/db_query/query_round_end = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("round")] SET end_datetime = Now(), game_mode_result = :game_mode_result, station_name = :station_name WHERE id = :round_id",
|
||||
"UPDATE [format_table_name("round")] SET end_datetime = Now(), game_mode_result = :game_mode_result WHERE id = :round_id",
|
||||
list("game_mode_result" = SSticker.mode_result, "station_name" = station_name(), "round_id" = GLOB.round_id)
|
||||
)
|
||||
query_round_end.Execute()
|
||||
|
||||
@@ -12,8 +12,11 @@ SUBSYSTEM_DEF(http)
|
||||
/// Total requests the SS has processed in a round
|
||||
var/total_requests
|
||||
|
||||
/datum/controller/subsystem/http/Initialize(start_timeofday)
|
||||
/datum/controller/subsystem/http/PreInit()
|
||||
. = ..()
|
||||
rustg_create_async_http_client() // Open the door
|
||||
|
||||
/datum/controller/subsystem/http/Initialize(start_timeofday)
|
||||
active_async_requests = list()
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -1,31 +1,51 @@
|
||||
SUBSYSTEM_DEF(mapping)
|
||||
name = "Mapping"
|
||||
init_order = INIT_ORDER_MAPPING // 9
|
||||
flags = SS_NO_FIRE
|
||||
name = "Mapping"
|
||||
init_order = INIT_ORDER_MAPPING // 9
|
||||
flags = SS_NO_FIRE
|
||||
/// What map datum are we using
|
||||
var/datum/map/map_datum
|
||||
/// What map will be used next round
|
||||
var/datum/map/next_map
|
||||
|
||||
// This has to be here because world/New() uses [station_name()], which looks this datum up
|
||||
/datum/controller/subsystem/mapping/PreInit()
|
||||
. = ..()
|
||||
if(map_datum) // Dont do this again if we are recovering
|
||||
return
|
||||
if(fexists("data/next_map.txt"))
|
||||
var/list/lines = file2list("data/next_map.txt")
|
||||
// Check its valid
|
||||
try
|
||||
map_datum = text2path(lines[1])
|
||||
map_datum = new map_datum
|
||||
catch
|
||||
map_datum = new /datum/map/cyberiad // Assume cyberiad if non-existent
|
||||
fdel("data/next_map.txt") // Remove to avoid the same map existing forever
|
||||
else
|
||||
map_datum = new /datum/map/cyberiad // Assume cyberiad if non-existent
|
||||
|
||||
/datum/controller/subsystem/mapping/Shutdown()
|
||||
if(next_map) // Save map for next round
|
||||
var/F = file("data/next_map.txt")
|
||||
F << next_map.type
|
||||
|
||||
/datum/controller/subsystem/mapping/Initialize(timeofday)
|
||||
// Load all Z level templates
|
||||
preloadTemplates()
|
||||
|
||||
// Load the station
|
||||
loadStation()
|
||||
|
||||
// Load lavaland
|
||||
loadLavaland()
|
||||
|
||||
// Pick a random away mission.
|
||||
if(!config.disable_away_missions)
|
||||
load_away_mission()
|
||||
|
||||
// Seed space ruins
|
||||
if(!config.disable_space_ruins)
|
||||
// load in extra levels of space ruins
|
||||
var/load_zlevels_timer = start_watch()
|
||||
log_startup_progress("Creating random space levels...")
|
||||
var/num_extra_space = rand(config.extra_space_ruin_levels_min, config.extra_space_ruin_levels_max)
|
||||
for(var/i = 1, i <= num_extra_space, i++)
|
||||
GLOB.space_manager.add_new_zlevel("Ruin Area #[i]", linkage = CROSSLINKED, traits = list(REACHABLE, SPAWN_RUINS))
|
||||
log_startup_progress("Loaded random space levels in [stop_watch(load_zlevels_timer)]s.")
|
||||
|
||||
// Now spawn ruins, random budget between 20 and 30 for all zlevels combined.
|
||||
// While this may seem like a high number, the amount of ruin Z levels can be anywhere between 3 and 7.
|
||||
// Note that this budget is not split evenly accross all zlevels
|
||||
log_startup_progress("Seeding ruins...")
|
||||
var/seed_ruins_timer = start_watch()
|
||||
seedRuins(levels_by_trait(SPAWN_RUINS), rand(20, 30), /area/space, GLOB.space_ruins_templates)
|
||||
log_startup_progress("Successfully seeded ruins in [stop_watch(seed_ruins_timer)]s.")
|
||||
handleRuins()
|
||||
|
||||
// Makes a blank space level for the sake of randomness
|
||||
GLOB.space_manager.add_new_zlevel("Empty Area", linkage = CROSSLINKED, traits = list(REACHABLE))
|
||||
@@ -63,12 +83,6 @@ SUBSYSTEM_DEF(mapping)
|
||||
|
||||
GLOB.ghostteleportlocs = sortAssoc(GLOB.ghostteleportlocs)
|
||||
|
||||
// Map name. Break these down into SSmapping controller vars instaed of GLOBs at some point
|
||||
if(GLOB.using_map && GLOB.using_map.name)
|
||||
GLOB.map_name = "[GLOB.using_map.name]"
|
||||
else
|
||||
GLOB.map_name = "Unknown"
|
||||
|
||||
// World name
|
||||
if(config && config.server_name)
|
||||
world.name = "[config.server_name]: [station_name()]"
|
||||
@@ -77,6 +91,56 @@ SUBSYSTEM_DEF(mapping)
|
||||
|
||||
return ..()
|
||||
|
||||
// Do not confuse with seedRuins()
|
||||
/datum/controller/subsystem/mapping/proc/handleRuins()
|
||||
// load in extra levels of space ruins
|
||||
var/load_zlevels_timer = start_watch()
|
||||
log_startup_progress("Creating random space levels...")
|
||||
var/num_extra_space = rand(config.extra_space_ruin_levels_min, config.extra_space_ruin_levels_max)
|
||||
for(var/i in 1 to num_extra_space)
|
||||
GLOB.space_manager.add_new_zlevel("Ruin Area #[i]", linkage = CROSSLINKED, traits = list(REACHABLE, SPAWN_RUINS))
|
||||
log_startup_progress("Loaded random space levels in [stop_watch(load_zlevels_timer)]s.")
|
||||
|
||||
// Now spawn ruins, random budget between 20 and 30 for all zlevels combined.
|
||||
// While this may seem like a high number, the amount of ruin Z levels can be anywhere between 3 and 7.
|
||||
// Note that this budget is not split evenly accross all zlevels
|
||||
log_startup_progress("Seeding ruins...")
|
||||
var/seed_ruins_timer = start_watch()
|
||||
seedRuins(levels_by_trait(SPAWN_RUINS), rand(20, 30), /area/space, GLOB.space_ruins_templates)
|
||||
log_startup_progress("Successfully seeded ruins in [stop_watch(seed_ruins_timer)]s.")
|
||||
|
||||
// Loads in the station
|
||||
/datum/controller/subsystem/mapping/proc/loadStation()
|
||||
ASSERT(map_datum.map_path)
|
||||
if(!fexists(map_datum.map_path))
|
||||
// Make a VERY OBVIOUS error
|
||||
to_chat(world, "<span class='narsie'>ERROR: The path specified for the map to load is invalid. No station has been loaded!</span>")
|
||||
return
|
||||
|
||||
var/watch = start_watch()
|
||||
log_startup_progress("Loading [map_datum.fluff_name]...")
|
||||
// This should always be Z2, but you never know
|
||||
var/map_z_level = GLOB.space_manager.add_new_zlevel(MAIN_STATION, linkage = CROSSLINKED, traits = list(STATION_LEVEL, STATION_CONTACT, REACHABLE, AI_OK))
|
||||
GLOB.maploader.load_map(file(map_datum.map_path), z_offset = map_z_level)
|
||||
log_startup_progress("Loaded [map_datum.fluff_name] in [stop_watch(watch)]s")
|
||||
|
||||
// Save station name in the DB
|
||||
if(!SSdbcore.IsConnected())
|
||||
return
|
||||
var/datum/db_query/query_set_map = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("round")] SET start_datetime=NOW(), map_name=:mapname, station_name=:stationname WHERE id=:round_id",
|
||||
list("mapname" = map_datum.technical_name, "stationname" = map_datum.fluff_name, "round_id" = GLOB.round_id)
|
||||
)
|
||||
query_set_map.Execute(async = FALSE) // This happens during a time of intense server lag, so should be non-async
|
||||
qdel(query_set_map)
|
||||
|
||||
// Loads in lavaland
|
||||
/datum/controller/subsystem/mapping/proc/loadLavaland()
|
||||
var/watch = start_watch()
|
||||
log_startup_progress("Loading Lavaland...")
|
||||
var/lavaland_z_level = GLOB.space_manager.add_new_zlevel(MINING, linkage = SELFLOOPING, traits = list(ORE_LEVEL, REACHABLE, STATION_CONTACT, HAS_WEATHER, AI_OK))
|
||||
GLOB.maploader.load_map(file("_maps/map_files/generic/Lavaland.dmm"), z_offset = lavaland_z_level)
|
||||
log_startup_progress("Loaded Lavaland in [stop_watch(watch)]s")
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/seedRuins(list/z_levels = null, budget = 0, whitelist = /area/space, list/potentialRuins)
|
||||
if(!z_levels || !z_levels.len)
|
||||
|
||||
@@ -135,8 +135,6 @@ SUBSYSTEM_DEF(shuttle)
|
||||
to_chat(user, "The emergency shuttle has been disabled by Centcom.")
|
||||
return
|
||||
|
||||
call_reason = trim(html_encode(call_reason))
|
||||
|
||||
if(length(call_reason) < CALL_SHUTTLE_REASON_LENGTH)
|
||||
to_chat(user, "Reason is too short. [CALL_SHUTTLE_REASON_LENGTH] character minimum.")
|
||||
return
|
||||
|
||||
@@ -16,8 +16,6 @@ SUBSYSTEM_DEF(title)
|
||||
else if(L.len > 1)
|
||||
if(use_rare_screens && lowertext(L[1]) == "rare")
|
||||
title_screens += S
|
||||
else if(GLOB.using_map && (lowertext(L[1]) == lowertext(GLOB.using_map.name)))
|
||||
title_screens += S
|
||||
|
||||
if(!isemptylist(title_screens))
|
||||
if(length(title_screens) > 1)
|
||||
|
||||
@@ -177,6 +177,16 @@ SUBSYSTEM_DEF(vote)
|
||||
if("crew_transfer")
|
||||
if(. == "Initiate Crew Transfer")
|
||||
init_shift_change(null, 1)
|
||||
if("map")
|
||||
// Find target map.
|
||||
var/datum/map/top_voted_map
|
||||
for(var/x in subtypesof(/datum/map))
|
||||
var/datum/map/M = x
|
||||
// Set top voted map
|
||||
if(. == "[initial(M.fluff_name)] ([initial(M.technical_name)])")
|
||||
top_voted_map = M
|
||||
to_chat(world, "<font color='purple'>Map for next round: [initial(top_voted_map.fluff_name)] ([initial(top_voted_map.technical_name)])</font>")
|
||||
SSmapping.next_map = new top_voted_map
|
||||
|
||||
|
||||
if(restart)
|
||||
@@ -197,7 +207,7 @@ SUBSYSTEM_DEF(vote)
|
||||
return vote
|
||||
return 0
|
||||
|
||||
/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key)
|
||||
/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, code_invoked = FALSE)
|
||||
if(!mode)
|
||||
if(started_time != null && !check_rights(R_ADMIN))
|
||||
var/next_allowed_time = (started_time + config.vote_delay)
|
||||
@@ -223,6 +233,14 @@ SUBSYSTEM_DEF(vote)
|
||||
return 0
|
||||
question = "End the shift?"
|
||||
choices.Add("Initiate Crew Transfer", "Continue The Round")
|
||||
if("map")
|
||||
if(!(check_rights(R_SERVER) || code_invoked))
|
||||
return FALSE
|
||||
question = "Map for next round"
|
||||
for(var/x in subtypesof(/datum/map))
|
||||
var/datum/map/M = x
|
||||
choices.Add("[initial(M.fluff_name)] ([initial(M.technical_name)])")
|
||||
|
||||
if("custom")
|
||||
question = html_encode(input(usr,"What is the vote for?") as text|null)
|
||||
if(!question) return 0
|
||||
@@ -248,11 +266,7 @@ SUBSYSTEM_DEF(vote)
|
||||
<a href='?src=[UID()];vote=open'>Click here or type vote to place your vote.</a>
|
||||
You have [config.vote_period/10] seconds to vote.</font>"})
|
||||
switch(vote_type)
|
||||
if("crew_transfer")
|
||||
SEND_SOUND(world, sound('sound/ambience/alarm4.ogg'))
|
||||
if("gamemode")
|
||||
SEND_SOUND(world, sound('sound/ambience/alarm4.ogg'))
|
||||
if("custom")
|
||||
if("crew_transfer", "gamemode", "custom", "map")
|
||||
SEND_SOUND(world, sound('sound/ambience/alarm4.ogg'))
|
||||
if(mode == "gamemode" && SSticker.ticker_going)
|
||||
SSticker.ticker_going = FALSE
|
||||
@@ -321,6 +335,12 @@ SUBSYSTEM_DEF(vote)
|
||||
if(admin)
|
||||
dat += "\t(<a href='?src=[UID()];vote=toggle_gamemode'>[config.allow_vote_mode?"Allowed":"Disallowed"]</a>)"
|
||||
|
||||
dat += "</li><li>"
|
||||
if(admin)
|
||||
dat += "<a href='?src=[UID()];vote=map'>Map</a>"
|
||||
else
|
||||
dat += "<font color='grey'>Map (Disallowed)</font>"
|
||||
|
||||
dat += "</li>"
|
||||
//custom
|
||||
if(admin)
|
||||
@@ -381,6 +401,9 @@ SUBSYSTEM_DEF(vote)
|
||||
if("gamemode")
|
||||
if(config.allow_vote_mode || admin)
|
||||
initiate_vote("gamemode",usr.key)
|
||||
if("map")
|
||||
if(admin)
|
||||
initiate_vote("map", usr.key)
|
||||
if("crew_transfer")
|
||||
if(config.allow_vote_restart || admin)
|
||||
initiate_vote("crew_transfer",usr.key)
|
||||
|
||||
@@ -383,6 +383,9 @@
|
||||
/datum/action/item_action/hands_free/activate
|
||||
name = "Activate"
|
||||
|
||||
/datum/action/item_action/hands_free/activate/always
|
||||
check_flags = null
|
||||
|
||||
/datum/action/item_action/toggle_research_scanner
|
||||
name = "Toggle Research Scanner"
|
||||
button_icon_state = "scan_mode"
|
||||
@@ -426,6 +429,7 @@
|
||||
desc = "Activates the jump boot's internal propulsion system, allowing the user to dash over 4-wide gaps."
|
||||
icon_icon = 'icons/mob/actions/actions.dmi'
|
||||
button_icon_state = "jetboot"
|
||||
use_itemicon = FALSE
|
||||
|
||||
///prset for organ actions
|
||||
/datum/action/item_action/organ_action
|
||||
|
||||
@@ -130,13 +130,13 @@
|
||||
|
||||
/datum/component/material_container/proc/insert_stack(obj/item/stack/S, amt, multiplier = 1)
|
||||
if(isnull(amt))
|
||||
amt = S.amount
|
||||
amt = S.get_amount()
|
||||
|
||||
if(amt <= 0)
|
||||
return FALSE
|
||||
|
||||
if(amt > S.amount)
|
||||
amt = S.amount
|
||||
if(amt > S.get_amount())
|
||||
amt = S.get_amount()
|
||||
|
||||
var/material_amt = get_item_material_amount(S)
|
||||
if(!material_amt)
|
||||
|
||||
@@ -5,129 +5,6 @@
|
||||
//This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
|
||||
var/list/locked = list()
|
||||
|
||||
/datum/datacore/proc/get_manifest(monochrome, OOC)
|
||||
var/list/heads = new()
|
||||
var/list/sec = new()
|
||||
var/list/eng = new()
|
||||
var/list/med = new()
|
||||
var/list/sci = new()
|
||||
var/list/ser = new()
|
||||
var/list/sup = new()
|
||||
var/list/bot = new()
|
||||
var/list/misc = new()
|
||||
var/list/isactive = new()
|
||||
var/dat = {"
|
||||
<head><style>
|
||||
.manifest {border-collapse:collapse;}
|
||||
.manifest td, th {border:1px solid [monochrome?"black":"#DEF; background-color:white; color:black"]; padding:.25em}
|
||||
.manifest th {height: 2em; [monochrome?"border-top-width: 3px":"background-color: #48C; color:white"]}
|
||||
.manifest tr.head th { [monochrome?"border-top-width: 1px":"background-color: #488;"] }
|
||||
.manifest td:first-child {text-align:right}
|
||||
.manifest tr.alt td {[monochrome?"border-top-width: 2px":"background-color: #DEF"]}
|
||||
</style></head>
|
||||
<table class="manifest" width='350px'>
|
||||
<tr class='head'><th>Name</th><th>Rank</th><th>Activity</th></tr>
|
||||
"}
|
||||
var/even = 0
|
||||
// sort mobs
|
||||
for(var/datum/data/record/t in GLOB.data_core.general)
|
||||
var/name = t.fields["name"]
|
||||
var/rank = t.fields["rank"]
|
||||
var/real_rank = t.fields["real_rank"]
|
||||
if(OOC)
|
||||
var/activetext = "Inactive"
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
if(H.real_name != name)
|
||||
continue
|
||||
if(H.client && H.client.inactivity <= 6000)
|
||||
activetext = "Active"
|
||||
break
|
||||
if(isLivingSSD(H))
|
||||
activetext = "SSD"
|
||||
break
|
||||
isactive[name] = activetext
|
||||
else
|
||||
isactive[name] = t.fields["p_stat"]
|
||||
var/department = 0
|
||||
if(real_rank in GLOB.command_positions)
|
||||
heads[name] = rank
|
||||
department = 1
|
||||
if(real_rank in GLOB.security_positions)
|
||||
sec[name] = rank
|
||||
department = 1
|
||||
if(real_rank in GLOB.engineering_positions)
|
||||
eng[name] = rank
|
||||
department = 1
|
||||
if(real_rank in GLOB.medical_positions)
|
||||
med[name] = rank
|
||||
department = 1
|
||||
if(real_rank in GLOB.science_positions)
|
||||
sci[name] = rank
|
||||
department = 1
|
||||
if(real_rank in GLOB.service_positions)
|
||||
ser[name] = rank
|
||||
department = 1
|
||||
if(real_rank in GLOB.supply_positions)
|
||||
sup[name] = rank
|
||||
department = 1
|
||||
if(real_rank in GLOB.nonhuman_positions)
|
||||
bot[name] = rank
|
||||
department = 1
|
||||
if(!department && !(name in heads))
|
||||
misc[name] = rank
|
||||
if(heads.len > 0)
|
||||
dat += "<tr><th colspan=3>Heads</th></tr>"
|
||||
for(var/name in heads)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[heads[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(sec.len > 0)
|
||||
dat += "<tr><th colspan=3>Security</th></tr>"
|
||||
for(var/name in sec)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sec[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(eng.len > 0)
|
||||
dat += "<tr><th colspan=3>Engineering</th></tr>"
|
||||
for(var/name in eng)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[eng[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(med.len > 0)
|
||||
dat += "<tr><th colspan=3>Medical</th></tr>"
|
||||
for(var/name in med)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[med[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(sci.len > 0)
|
||||
dat += "<tr><th colspan=3>Science</th></tr>"
|
||||
for(var/name in sci)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sci[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(ser.len > 0)
|
||||
dat += "<tr><th colspan=3>Service</th></tr>"
|
||||
for(var/name in ser)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[ser[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(sup.len > 0)
|
||||
dat += "<tr><th colspan=3>Supply</th></tr>"
|
||||
for(var/name in sup)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sup[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(bot.len > 0)
|
||||
dat += "<tr><th colspan=3>Silicon</th></tr>"
|
||||
for(var/name in bot)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[bot[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(misc.len > 0)
|
||||
dat += "<tr><th colspan=3>Miscellaneous</th></tr>"
|
||||
for(var/name in misc)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[misc[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
|
||||
dat += "</table>"
|
||||
dat = replacetext(dat, "\n", "") // so it can be placed on paper correctly
|
||||
dat = replacetext(dat, "\t", "")
|
||||
return dat
|
||||
|
||||
|
||||
/*
|
||||
We can't just insert in HTML into the TGUI so we need the raw data to play with.
|
||||
Instead of creating this list over and over when someone leaves their PDA open to the page
|
||||
|
||||
@@ -31,6 +31,8 @@ BONUS
|
||||
to_chat(M, "<span class='warning'>[pick("Your scalp itches.", "Your skin feels flakey.")]</span>")
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(NO_HAIR in H.dna.species.species_traits)
|
||||
return // Hair can't fall out if you don't have any
|
||||
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
|
||||
switch(A.stage)
|
||||
if(3, 4)
|
||||
|
||||
@@ -124,6 +124,10 @@
|
||||
name = "Pyromancer REAL_NAME"
|
||||
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU", "ONI SOMA!")
|
||||
|
||||
/datum/dog_fashion/head/black_wizard
|
||||
name = "Necromancer REAL_NAME"
|
||||
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU")
|
||||
|
||||
/datum/dog_fashion/head/cardborg
|
||||
name = "Borgi"
|
||||
speak = list("Ping!","Beep!","Woof!")
|
||||
@@ -148,6 +152,8 @@
|
||||
name = "Corgi Tech REAL_NAME"
|
||||
desc = "The reason your yellow gloves have chew-marks."
|
||||
|
||||
/datum/dog_fashion/head/softcap
|
||||
|
||||
/datum/dog_fashion/head/reindeer
|
||||
name = "REAL_NAME the red-nosed Corgi"
|
||||
emote_hear = list("lights the way!", "illuminates.", "yaps!")
|
||||
@@ -208,3 +214,38 @@
|
||||
/datum/dog_fashion/head/fried_vox_empty
|
||||
name = "Colonel REAL_NAME"
|
||||
desc = "Keep away from live vox."
|
||||
|
||||
/datum/dog_fashion/head/HoS
|
||||
name = "Head of Security REAL_NAME"
|
||||
desc = "Probably better than the last HoS."
|
||||
|
||||
/datum/dog_fashion/head/beret/sec
|
||||
name = "Officer REAL_NAME"
|
||||
desc = "Ever-loyal, ever-vigilant."
|
||||
|
||||
/datum/dog_fashion/head/bowlerhat
|
||||
name = "REAL_NAME"
|
||||
desc = "A sophisticated city gent."
|
||||
|
||||
/datum/dog_fashion/head/surgery
|
||||
name = "Nurse-in-Training REAL_NAME"
|
||||
desc = "The most adorable bed-side manner ever."
|
||||
|
||||
/datum/dog_fashion/head/bucket
|
||||
name = "REAL_NAME"
|
||||
desc = "A janitor's best friend."
|
||||
|
||||
/datum/dog_fashion/head/justice_wig
|
||||
name = "Arbiter REAL_NAME"
|
||||
desc = "Head of the High Court of Cute."
|
||||
|
||||
/datum/dog_fashion/head/wizard/magus
|
||||
name = "Battlemage REAL_NAME"
|
||||
|
||||
/datum/dog_fashion/head/wizard/marisa
|
||||
name = "Witch REAL_NAME"
|
||||
desc = "Flying broom not included."
|
||||
|
||||
/datum/dog_fashion/head/roman
|
||||
name = "Imperator REAL_NAME"
|
||||
desc = "For the Senate and the people of Rome!"
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
/datum/construction/proc/custom_action(step, used_atom, user)
|
||||
if(istype(used_atom, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = used_atom
|
||||
if(C.amount<4)
|
||||
if(C.get_amount() < 4)
|
||||
to_chat(user, ("<span class='warning'>There's not enough cable to finish the task.</span>"))
|
||||
return 0
|
||||
else
|
||||
@@ -55,7 +55,7 @@
|
||||
playsound(holder, C.usesound, 50, 1)
|
||||
else if(istype(used_atom, /obj/item/stack))
|
||||
var/obj/item/stack/S = used_atom
|
||||
if(S.amount < 5)
|
||||
if(S.get_amount() < 5)
|
||||
to_chat(user, ("<span class='warning'>There's not enough material in this stack.</span>"))
|
||||
return 0
|
||||
else
|
||||
@@ -113,7 +113,7 @@
|
||||
// STACKS
|
||||
if(istype(used_atom,/obj/item/stack))
|
||||
var/obj/item/stack/stack=used_atom
|
||||
if(stack.amount < amount)
|
||||
if(stack.get_amount() < amount)
|
||||
to_chat(user, "<span class='warning'>You don't have enough [stack]! You need at least [amount].</span>")
|
||||
return 0
|
||||
stack.use(amount)
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
var/falloff_exponent
|
||||
var/muted = TRUE
|
||||
var/falloff_distance
|
||||
/// Channel of the audio, random otherwise
|
||||
var/channel
|
||||
|
||||
/datum/looping_sound/New(list/_output_atoms = list(), start_immediately = FALSE, _direct = FALSE)
|
||||
if(!mid_sounds)
|
||||
@@ -75,14 +77,16 @@
|
||||
var/list/atoms_cache = output_atoms
|
||||
var/sound/S = sound(soundfile)
|
||||
if(direct)
|
||||
S.channel = SSsounds.random_available_channel()
|
||||
S.volume = volume
|
||||
S.channel = channel || SSsounds.random_available_channel()
|
||||
for(var/i in 1 to atoms_cache.len)
|
||||
var/atom/thing = atoms_cache[i]
|
||||
if(direct)
|
||||
if(ismob(thing))
|
||||
var/mob/M = thing
|
||||
S.volume = volume * (USER_VOLUME(M, channel) || 1)
|
||||
SEND_SOUND(thing, S)
|
||||
else
|
||||
playsound(thing, S, volume, vary, extra_range, falloff_exponent = falloff_exponent, falloff_distance = falloff_distance)
|
||||
playsound(thing, S, volume, vary, extra_range, falloff_exponent = falloff_exponent, falloff_distance = falloff_distance, channel = channel)
|
||||
|
||||
/datum/looping_sound/proc/get_sound(looped, _mid_sounds)
|
||||
if(!_mid_sounds)
|
||||
|
||||
@@ -16,3 +16,4 @@
|
||||
falloff_exponent = 10
|
||||
falloff_distance = 5
|
||||
vary = TRUE
|
||||
channel = CHANNEL_ENGINE
|
||||
|
||||
+12
-38
@@ -1375,46 +1375,20 @@
|
||||
switch(href_list["silicon"])
|
||||
if("unemag")
|
||||
var/mob/living/silicon/robot/R = current
|
||||
if(istype(R))
|
||||
R.emagged = 0
|
||||
if(R.module)
|
||||
if(R.activated(R.module.emag))
|
||||
R.module_active = null
|
||||
if(R.module_state_1 == R.module.emag)
|
||||
R.module_state_1 = null
|
||||
R.contents -= R.module.emag
|
||||
else if(R.module_state_2 == R.module.emag)
|
||||
R.module_state_2 = null
|
||||
R.contents -= R.module.emag
|
||||
else if(R.module_state_3 == R.module.emag)
|
||||
R.module_state_3 = null
|
||||
R.contents -= R.module.emag
|
||||
R.clear_supplied_laws()
|
||||
R.laws = new /datum/ai_laws/crewsimov
|
||||
log_admin("[key_name(usr)] has un-emagged [key_name(current)]")
|
||||
message_admins("[key_name_admin(usr)] has un-emagged [key_name_admin(current)]")
|
||||
if(!istype(R))
|
||||
return
|
||||
R.unemag()
|
||||
log_admin("[key_name(usr)] has un-emagged [key_name(current)]")
|
||||
message_admins("[key_name_admin(usr)] has un-emagged [key_name_admin(current)]")
|
||||
|
||||
if("unemagcyborgs")
|
||||
if(isAI(current))
|
||||
var/mob/living/silicon/ai/ai = current
|
||||
for(var/mob/living/silicon/robot/R in ai.connected_robots)
|
||||
R.emagged = 0
|
||||
if(R.module)
|
||||
if(R.activated(R.module.emag))
|
||||
R.module_active = null
|
||||
if(R.module_state_1 == R.module.emag)
|
||||
R.module_state_1 = null
|
||||
R.contents -= R.module.emag
|
||||
else if(R.module_state_2 == R.module.emag)
|
||||
R.module_state_2 = null
|
||||
R.contents -= R.module.emag
|
||||
else if(R.module_state_3 == R.module.emag)
|
||||
R.module_state_3 = null
|
||||
R.contents -= R.module.emag
|
||||
R.clear_supplied_laws()
|
||||
R.laws = new /datum/ai_laws/crewsimov
|
||||
log_admin("[key_name(usr)] has unemagged [key_name(ai)]'s cyborgs")
|
||||
message_admins("[key_name_admin(usr)] has unemagged [key_name_admin(ai)]'s cyborgs")
|
||||
if(!isAI(current))
|
||||
return
|
||||
var/mob/living/silicon/ai/ai = current
|
||||
for(var/mob/living/silicon/robot/R in ai.connected_robots)
|
||||
R.unemag()
|
||||
log_admin("[key_name(usr)] has unemagged [key_name(ai)]'s cyborgs")
|
||||
message_admins("[key_name_admin(usr)] has unemagged [key_name_admin(ai)]'s cyborgs")
|
||||
|
||||
else if(href_list["common"])
|
||||
switch(href_list["common"])
|
||||
|
||||
@@ -111,6 +111,8 @@
|
||||
|
||||
for(var/path in backpack_contents)
|
||||
var/number = backpack_contents[path]
|
||||
if(!number)
|
||||
number = 1
|
||||
for(var/i in 1 to number)
|
||||
H.equip_or_collect(new path(H), slot_in_backpack)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
/datum/outfit/admin/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
. = ..()
|
||||
if(!visualsOnly)
|
||||
if(!visualsOnly && H.mind)
|
||||
H.mind.assigned_role = name
|
||||
H.job = name
|
||||
|
||||
@@ -627,6 +627,10 @@
|
||||
/obj/item/implanter/death_alarm = 1,
|
||||
)
|
||||
|
||||
implants = list(/obj/item/implant/mindshield,
|
||||
/obj/item/implant/death_alarm
|
||||
)
|
||||
|
||||
/datum/outfit/admin/solgov_rep/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
. = ..()
|
||||
if(visualsOnly)
|
||||
@@ -634,33 +638,44 @@
|
||||
|
||||
var/obj/item/card/id/I = H.wear_id
|
||||
if(istype(I))
|
||||
apply_to_card(I, H, get_all_accesses(), name, "lifetimeid")
|
||||
apply_to_card(I, H, get_all_centcom_access(), name, "lifetimeid")
|
||||
I.assignment = "Solar Federation Representative"
|
||||
H.sec_hud_set_ID()
|
||||
|
||||
|
||||
/datum/outfit/admin/solgov
|
||||
name = "Solar Federation Marine"
|
||||
|
||||
uniform = /obj/item/clothing/under/solgov
|
||||
suit = /obj/item/clothing/suit/armor/bulletproof
|
||||
back = /obj/item/storage/backpack/security
|
||||
belt = /obj/item/storage/belt/military/assault
|
||||
head = /obj/item/clothing/head/soft/solgov
|
||||
glasses = /obj/item/clothing/glasses/hud/security/night
|
||||
belt = /obj/item/storage/belt/military/assault/marines/full
|
||||
head = /obj/item/clothing/head/soft/solgov/marines
|
||||
glasses = /obj/item/clothing/glasses/night
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
shoes = /obj/item/clothing/shoes/combat
|
||||
l_ear = /obj/item/radio/headset/ert
|
||||
id = /obj/item/card/id
|
||||
l_hand = /obj/item/gun/projectile/automatic/ar
|
||||
l_hand = /obj/item/gun/projectile/automatic/shotgun/bulldog
|
||||
suit_store = /obj/item/gun/projectile/automatic/pistol/m1911
|
||||
r_pocket = /obj/item/flashlight/seclite
|
||||
pda = /obj/item/pda
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/responseteam = 1,
|
||||
/obj/item/ammo_box/magazine/m556 = 3,
|
||||
/obj/item/clothing/shoes/magboots = 1,
|
||||
/obj/item/gun/projectile/automatic/pistol/m1911 = 1,
|
||||
/obj/item/ammo_box/magazine/m45 = 2
|
||||
/obj/item/whetstone = 1,
|
||||
/obj/item/clothing/mask/gas/explorer/marines = 1,
|
||||
/obj/item/reagent_containers/hypospray/autoinjector/survival = 1
|
||||
)
|
||||
var/is_tsf_lieutenant = FALSE
|
||||
cybernetic_implants = list(
|
||||
/obj/item/organ/internal/cyberimp/arm/flash,
|
||||
/obj/item/organ/internal/cyberimp/chest/nutriment,
|
||||
/obj/item/organ/internal/cyberimp/eyes/hud/security
|
||||
)
|
||||
implants = list(/obj/item/implant/mindshield,
|
||||
/obj/item/implant/death_alarm
|
||||
)
|
||||
|
||||
var/is_solgov_lieutenant = FALSE
|
||||
|
||||
|
||||
/datum/outfit/admin/solgov/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
@@ -668,31 +683,80 @@
|
||||
if(visualsOnly)
|
||||
return
|
||||
|
||||
if(is_tsf_lieutenant)
|
||||
if(is_solgov_lieutenant)
|
||||
H.real_name = "Lieutenant [pick(GLOB.last_names)]"
|
||||
else
|
||||
H.real_name = "[pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant First Class", "Master Sergeant", "Sergeant Major")] [pick(GLOB.last_names)]"
|
||||
H.name = H.real_name
|
||||
var/obj/item/card/id/I = H.wear_id
|
||||
if(istype(I))
|
||||
apply_to_card(I, H, get_all_accesses(), name, "lifetimeid")
|
||||
I.assignment = name
|
||||
if(istype(I) && is_solgov_lieutenant)
|
||||
apply_to_card(I, H, get_centcom_access("Emergency Response Team Leader"), name, "lifetimeid")
|
||||
else if(istype(I))
|
||||
apply_to_card(I, H, get_centcom_access("Emergency Response Team Member"), name, "lifetimeid")
|
||||
H.sec_hud_set_ID()
|
||||
|
||||
/datum/outfit/admin/solgov/lieutenant
|
||||
name = "Solar Federation Lieutenant"
|
||||
|
||||
uniform = /obj/item/clothing/under/solgov/command
|
||||
head = /obj/item/clothing/head/soft/solgov/command
|
||||
head = /obj/item/clothing/head/beret/solgov/command
|
||||
glasses = /obj/item/clothing/glasses/night
|
||||
back = /obj/item/storage/backpack/satchel
|
||||
l_ear = /obj/item/radio/headset/ert/alt/commander
|
||||
l_hand = null
|
||||
belt = /obj/item/melee/baton/loaded
|
||||
suit_store = /obj/item/gun/projectile/automatic/pistol/deagle
|
||||
l_pocket = /obj/item/pinpointer/advpinpointer
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/responseteam = 1,
|
||||
/obj/item/melee/classic_baton/telescopic = 1,
|
||||
/obj/item/storage/box/handcuffs = 1,
|
||||
/obj/item/clothing/shoes/magboots/advance = 1,
|
||||
/obj/item/gun/projectile/automatic/pistol/deagle = 1,
|
||||
/obj/item/ammo_box/magazine/m50 = 2
|
||||
/obj/item/reagent_containers/hypospray/autoinjector/survival = 1,
|
||||
/obj/item/clothing/mask/gas/explorer/marines = 1,
|
||||
/obj/item/ammo_box/magazine/m50 = 3
|
||||
)
|
||||
is_tsf_lieutenant = TRUE
|
||||
is_solgov_lieutenant = TRUE
|
||||
|
||||
/datum/outfit/admin/solgov/elite
|
||||
name = "Solar Federation Specops Marine"
|
||||
uniform = /obj/item/clothing/under/solgov/elite
|
||||
head = /obj/item/clothing/head/soft/solgov/marines/elite
|
||||
belt = /obj/item/storage/belt/military/assault/marines/elite/full
|
||||
l_hand = /obj/item/gun/projectile/automatic/ar
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/responseteam = 1,
|
||||
/obj/item/clothing/shoes/magboots/advance = 1,
|
||||
/obj/item/whetstone = 1,
|
||||
/obj/item/clothing/mask/gas/explorer/marines = 1,
|
||||
/obj/item/reagent_containers/hypospray/autoinjector/survival = 1
|
||||
)
|
||||
cybernetic_implants = list(
|
||||
/obj/item/organ/internal/cyberimp/eyes/hud/security,
|
||||
/obj/item/organ/internal/cyberimp/chest/nutriment,
|
||||
/obj/item/organ/internal/cyberimp/brain/anti_stun/hardened,
|
||||
/obj/item/organ/internal/cyberimp/arm/flash,
|
||||
/obj/item/organ/internal/eyes/cybernetic/shield
|
||||
)
|
||||
/datum/outfit/admin/solgov/elite/lieutenant
|
||||
name = "Solar Federation Specops Lieutenant"
|
||||
uniform = /obj/item/clothing/under/solgov/command/elite
|
||||
head = /obj/item/clothing/head/beret/solgov/command/elite
|
||||
glasses = /obj/item/clothing/glasses/night
|
||||
back = /obj/item/storage/backpack/satchel
|
||||
belt = /obj/item/melee/baton/loaded
|
||||
l_hand = null
|
||||
suit_store = /obj/item/gun/projectile/automatic/pistol/deagle
|
||||
l_pocket = /obj/item/pinpointer/advpinpointer
|
||||
l_ear = /obj/item/radio/headset/ert/alt/commander
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/responseteam = 1,
|
||||
/obj/item/storage/box/handcuffs = 1,
|
||||
/obj/item/clothing/shoes/magboots/advance = 1,
|
||||
/obj/item/clothing/mask/gas/explorer/marines = 1,
|
||||
/obj/item/reagent_containers/hypospray/autoinjector/survival = 1,
|
||||
/obj/item/ammo_box/magazine/m50 = 3
|
||||
)
|
||||
is_solgov_lieutenant = TRUE
|
||||
|
||||
/datum/outfit/admin/sol_trader
|
||||
name = "Sol Trader"
|
||||
@@ -720,6 +784,7 @@
|
||||
var/obj/item/card/id/I = H.wear_id
|
||||
if(istype(I))
|
||||
apply_to_card(I, H, list(ACCESS_TRADE_SOL, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS), name)
|
||||
H.sec_hud_set_ID()
|
||||
|
||||
/datum/outfit/admin/chrono
|
||||
name = "Chrono Legionnaire"
|
||||
|
||||
@@ -51,14 +51,6 @@
|
||||
cost = 20
|
||||
allow_duplicates = FALSE
|
||||
|
||||
/datum/map_template/ruin/lavaland/syndicate_base
|
||||
name = "Syndicate Lava Base"
|
||||
id = "lava-base"
|
||||
description = "A secret base researching illegal bioweapons, it is closely guarded by an elite team of syndicate agents."
|
||||
suffix = "lavaland_surface_syndicate_base1.dmm"
|
||||
cost = 20
|
||||
allow_duplicates = FALSE
|
||||
|
||||
/datum/map_template/ruin/lavaland/free_golem
|
||||
name = "Free Golem Ship"
|
||||
id = "golem-ship"
|
||||
|
||||
@@ -258,6 +258,15 @@
|
||||
always_place = TRUE
|
||||
cost = 0
|
||||
|
||||
/datum/map_template/ruin/space/syndicate_space_base
|
||||
name = "Syndicate Space Base"
|
||||
id = "syndie-space-base"
|
||||
description = "A secret base researching illegal bioweapons, it is closely guarded by an elite team of syndicate agents."
|
||||
suffix = "syndie_space_base.dmm"
|
||||
cost = 0
|
||||
always_place = TRUE
|
||||
allow_duplicates = FALSE
|
||||
|
||||
/datum/map_template/ruin/space/syndiecakesfactory
|
||||
id = "Syndiecakes Factory"
|
||||
suffix = "syndiecakesfactory.dmm"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/perform(list/targets, recharge = 1, mob/living/user = usr)
|
||||
var/thearea = before_cast(targets)
|
||||
if(!thearea || !cast_check(TRUE, FALSE, user))
|
||||
if(!thearea || !cast_check(FALSE, FALSE, user))
|
||||
revert_cast()
|
||||
return
|
||||
invocation(thearea)
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone
|
||||
name = "Summon Soulstone"
|
||||
desc = "This spell reaches into Nar'Sie's realm, summoning one of the legendary fragments across time and space"
|
||||
desc = "This spell reaches into Redspace, summoning one of the legendary fragments across time and space"
|
||||
action_icon_state = "summonsoulstone"
|
||||
action_background_icon_state = "bg_cult"
|
||||
school = "conjuration"
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/pylon
|
||||
name = "Cult Pylon"
|
||||
desc = "This spell conjures a fragile crystal from Nar'Sie's realm. Makes for a convenient light source."
|
||||
desc = "This spell conjures a fragile crystal from Redspace. Makes for a convenient light source."
|
||||
action_icon_state = "pylon"
|
||||
action_background_icon_state = "bg_cult"
|
||||
school = "conjuration"
|
||||
@@ -125,7 +125,12 @@
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/do_jaunt(mob/living/target)
|
||||
target.set_light(0)
|
||||
..()
|
||||
target.set_light(2, 3, l_color = SSticker.cultdat ? SSticker.cultdat.construct_glow : LIGHT_COLOR_BLOOD_MAGIC)
|
||||
if(isconstruct(target))
|
||||
var/mob/living/simple_animal/hostile/construct/C = target
|
||||
if(C.holy)
|
||||
C.set_light(3, 5, LIGHT_COLOR_DARK_BLUE)
|
||||
else
|
||||
C.set_light(2, 3, l_color = SSticker.cultdat ? SSticker.cultdat.construct_glow : LIGHT_COLOR_BLOOD_MAGIC)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/jaunt_steam(mobloc)
|
||||
return
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
if((ABSTRACT in item.flags) || (NODROP in item.flags))
|
||||
continue
|
||||
marked_item = item
|
||||
to_chat(M, "<span class='warning'>You begin to focus your very being into the [item.name]...</span>")
|
||||
to_chat(M, "<span class='warning'>You begin to focus your very being into [item]...</span>")
|
||||
break
|
||||
|
||||
if(!marked_item)
|
||||
@@ -104,7 +104,7 @@
|
||||
|
||||
spawn(50)
|
||||
if(marked_item.loc != M) //I changed my mind I don't want to put my soul in a cheeseburger!
|
||||
to_chat(M, "<span class='warning'>Your soul snaps back to your body as you drop the [marked_item.name]!</span>")
|
||||
to_chat(M, "<span class='warning'>Your soul snaps back to your body as you drop [marked_item]!</span>")
|
||||
marked_item = null
|
||||
return
|
||||
name = "RISE!"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
if(!usr.mind.miming)
|
||||
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
|
||||
return
|
||||
invocation = "<B>[usr.real_name]</B> looks as if a wall is in front of [usr.p_them()]."
|
||||
invocation = "<B>[usr.name]</B> looks as if a wall is in front of [usr.p_them()]."
|
||||
else
|
||||
invocation_type ="none"
|
||||
..()
|
||||
@@ -86,7 +86,7 @@
|
||||
if(!usr.mind.miming)
|
||||
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
|
||||
return
|
||||
invocation = "<B>[usr.real_name]</B> looks as if a blockade is in front of [usr.p_them()]."
|
||||
invocation = "<B>[usr.name]</B> looks as if a blockade is in front of [usr.p_them()]."
|
||||
else
|
||||
invocation_type ="none"
|
||||
..()
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
var/obj/item/organ/external/part = X
|
||||
if(item_to_retrieve in part.embedded_objects)
|
||||
part.embedded_objects -= item_to_retrieve
|
||||
to_chat(C, "<span class='warning'>The [item_to_retrieve] that was embedded in your [part] has mysteriously vanished. How fortunate!</span>")
|
||||
to_chat(C, "<span class='warning'>\The [item_to_retrieve] that was embedded in your [part] has mysteriously vanished. How fortunate!</span>")
|
||||
if(!C.has_embedded_objects())
|
||||
C.clear_alert("embeddedobject")
|
||||
break
|
||||
@@ -99,7 +99,7 @@
|
||||
if(!item_to_retrieve)
|
||||
return
|
||||
|
||||
item_to_retrieve.loc.visible_message("<span class='warning'>The [item_to_retrieve.name] suddenly disappears!</span>")
|
||||
item_to_retrieve.loc.visible_message("<span class='warning'>\The [item_to_retrieve] suddenly disappears!</span>")
|
||||
|
||||
|
||||
if(target.hand) //left active hand
|
||||
@@ -112,10 +112,10 @@
|
||||
butterfingers = 1
|
||||
if(butterfingers)
|
||||
item_to_retrieve.loc = target.loc
|
||||
item_to_retrieve.loc.visible_message("<span class='caution'>The [item_to_retrieve.name] suddenly appears!</span>")
|
||||
item_to_retrieve.loc.visible_message("<span class='caution'>\The [item_to_retrieve] suddenly appears!</span>")
|
||||
playsound(get_turf(target),'sound/magic/summonitems_generic.ogg',50,1)
|
||||
else
|
||||
item_to_retrieve.loc.visible_message("<span class='caution'>The [item_to_retrieve.name] suddenly appears in [target]'s hand!</span>")
|
||||
item_to_retrieve.loc.visible_message("<span class='caution'>\The [item_to_retrieve] suddenly appears in [target]'s hand!</span>")
|
||||
playsound(get_turf(target),'sound/magic/summonitems_generic.ogg',50,1)
|
||||
|
||||
if(message)
|
||||
|
||||
@@ -374,7 +374,7 @@
|
||||
|
||||
for(var/am in thrownatoms)
|
||||
var/atom/movable/AM = am
|
||||
if(AM == user || AM.anchored)
|
||||
if(AM == user || AM.anchored || AM.move_resist == INFINITY)
|
||||
continue
|
||||
|
||||
throwtarget = get_edge_target_turf(user, get_dir(user, get_step_away(AM, user)))
|
||||
|
||||
@@ -935,6 +935,14 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
|
||||
containername = "surgery crate"
|
||||
access = ACCESS_MEDICAL
|
||||
|
||||
/datum/supply_packs/medical/gloves
|
||||
name = "Nitrile Glove Crate"
|
||||
contains = list(/obj/item/clothing/gloves/color/latex/nitrile,
|
||||
/obj/item/clothing/gloves/color/latex/nitrile,
|
||||
/obj/item/clothing/gloves/color/latex/nitrile,
|
||||
/obj/item/clothing/gloves/color/latex/nitrile)
|
||||
cost = 50
|
||||
containername = "nitrile glove crate"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////// Science /////////////////////////////////////////
|
||||
|
||||
@@ -1,39 +1,53 @@
|
||||
/// Will our restart be slower?
|
||||
GLOBAL_VAR_INIT(slower_restart, FALSE)
|
||||
|
||||
/proc/server_announce_global(announcement_text)
|
||||
to_chat(world, "<span style='color: #ff00ff'>\[Server] [announcement_text]</span>")
|
||||
|
||||
/proc/server_announce_adminonly(announcement_text)
|
||||
to_chat(GLOB.admins, "<span style='color: #ff00ff'>\[Server] \[Admin] [announcement_text]</span>")
|
||||
|
||||
/datum/tgs_event_handler/impl
|
||||
var/datum/timedevent/reattach_timer
|
||||
|
||||
|
||||
/datum/tgs_event_handler/impl/HandleEvent(event_code, ...)
|
||||
switch(event_code)
|
||||
if(TGS_EVENT_REBOOT_MODE_CHANGE)
|
||||
var/list/reboot_mode_lookup = list ("[TGS_REBOOT_MODE_NORMAL]" = "be normal", "[TGS_REBOOT_MODE_SHUTDOWN]" = "shutdown the server", "[TGS_REBOOT_MODE_RESTART]" = "hard restart the server")
|
||||
var/old_reboot_mode = args[2]
|
||||
var/new_reboot_mode = args[3]
|
||||
message_admins("\[Server]\[Info] Reboot will no longer [reboot_mode_lookup["[old_reboot_mode]"]], it will instead [reboot_mode_lookup["[new_reboot_mode]"]]")
|
||||
if(new_reboot_mode == TGS_REBOOT_MODE_SHUTDOWN)
|
||||
GLOB.slower_restart = TRUE
|
||||
else
|
||||
GLOB.slower_restart = FALSE
|
||||
server_announce_adminonly("\[Info] Reboot will no longer [reboot_mode_lookup["[old_reboot_mode]"]], it will instead [reboot_mode_lookup["[new_reboot_mode]"]]")
|
||||
if(TGS_EVENT_PORT_SWAP)
|
||||
message_admins("\[Server]\[Info] Changing port from [world.port] to [args[2]]")
|
||||
server_announce_adminonly("\[Info] Changing port from [world.port] to [args[2]]")
|
||||
if(TGS_EVENT_INSTANCE_RENAMED)
|
||||
message_admins("\[Server]\[Info] Instance renamed to from [world.TgsInstanceName()] to [args[2]]")
|
||||
server_announce_adminonly("\[Info] Instance renamed to from [world.TgsInstanceName()] to [args[2]]")
|
||||
if(TGS_EVENT_COMPILE_START)
|
||||
message_admins("\[Server]\[Info] Code deployment started, new game version incoming next round...")
|
||||
server_announce_adminonly("\[Info] Code deployment started, new game version incoming next round...")
|
||||
if(TGS_EVENT_COMPILE_CANCELLED)
|
||||
message_admins("\[Server]\[Warning] Code deployment cancelled!")
|
||||
server_announce_adminonly("\[Warning] Code deployment cancelled! Consult a maintainer/host to see if this was intentional!")
|
||||
if(TGS_EVENT_COMPILE_FAILURE)
|
||||
message_admins("\[Server]\[Error] Code deployment failed! Inform a maintainer/host immediately!")
|
||||
server_announce_adminonly("\[Error] Code deployment failed! Inform a maintainer/host immediately!")
|
||||
if(TGS_EVENT_DEPLOYMENT_COMPLETE)
|
||||
message_admins("\[Server]\[Info] Code deployment complete!")
|
||||
to_chat(world, "<span class='boldannounce'>Server updated, changes will be applied on the next round...</span>")
|
||||
server_announce_adminonly("\[Info] Code deployment complete!")
|
||||
server_announce_global("Server update complete. Changes will be applied on the next round.")
|
||||
if(TGS_EVENT_WATCHDOG_DETACH)
|
||||
message_admins("\[Server]\[Info] Server manager restarting...")
|
||||
server_announce_adminonly("\[Info] Server manager restarting...")
|
||||
reattach_timer = addtimer(CALLBACK(src, .proc/LateOnReattach), 1 MINUTES, TIMER_STOPPABLE)
|
||||
if(TGS_EVENT_WATCHDOG_REATTACH)
|
||||
var/datum/tgs_version/old_version = world.TgsVersion()
|
||||
var/datum/tgs_version/new_version = args[2]
|
||||
if(!old_version.Equals(new_version))
|
||||
message_admins("\[Server]\[Info] Manager back online. TGS has been updated to v[new_version.deprefixed_parameter]")
|
||||
server_announce_adminonly("\[Info] Server manager back online. TGS has been updated to v[new_version.deprefixed_parameter]")
|
||||
else
|
||||
message_admins("\[Server]\[Info] Manager back online")
|
||||
server_announce_adminonly("\[Info] Server manager back online")
|
||||
if(reattach_timer)
|
||||
deltimer(reattach_timer)
|
||||
reattach_timer = null
|
||||
|
||||
/datum/tgs_event_handler/impl/proc/LateOnReattach()
|
||||
message_admins("\[Server]\[Warning] TGS hasn't notified us of it coming back for a full minute! Is there a problem?")
|
||||
server_announce_adminonly("\[Warning] TGS hasn't notified us of it coming back for a full minute! Is there a problem?")
|
||||
|
||||
@@ -864,6 +864,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "CQC"
|
||||
item = /obj/item/CQC_manual
|
||||
cost = 13
|
||||
cant_discount = TRUE
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/cameraflash
|
||||
name = "Camera Flash"
|
||||
@@ -952,6 +953,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
item = /obj/item/toy/carpplushie/dehy_carp
|
||||
cost = 2
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/combat_plus
|
||||
name = "Combat Gloves Plus"
|
||||
desc = "Combat gloves with installed nanochips that teach you Krav Maga when worn, great as a cheap backup weapon. Warning, the nanochips will override any other fighting styles such as CQC."
|
||||
reference = "CGP"
|
||||
item = /obj/item/clothing/gloves/color/black/krav_maga/combat
|
||||
cost = 5
|
||||
gamemodes = list(/datum/game_mode/nuclear)
|
||||
|
||||
// GRENADES AND EXPLOSIVES
|
||||
|
||||
/datum/uplink_item/explosives
|
||||
@@ -1417,7 +1426,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
name = "Power Sink"
|
||||
desc = "When screwed to wiring attached to an electric grid, then activated, this large device places excessive load on the grid, causing a stationwide blackout. The sink cannot be carried because of its excessive size. Ordering this sends you a small beacon that will teleport the power sink to your location on activation."
|
||||
reference = "PS"
|
||||
item = /obj/item/powersink
|
||||
item = /obj/item/radio/beacon/syndicate/power_sink
|
||||
cost = 10
|
||||
|
||||
/datum/uplink_item/device_tools/singularity_beacon
|
||||
|
||||
@@ -209,7 +209,7 @@
|
||||
/**
|
||||
* Proc called to determine if the user can see wire define information, such as "Contraband", "Door Bolts", etc.
|
||||
*
|
||||
* If the user is an admin, or has a multitool which reveals wire information in their active hand, the proc returns TRUE.
|
||||
* If the user is an admin, or has an item which reveals wire information in their active hand, the proc returns TRUE.
|
||||
*
|
||||
* Arguments:
|
||||
* * user - the mob who is interacting with the wires.
|
||||
@@ -217,10 +217,9 @@
|
||||
/datum/wires/proc/can_see_wire_info(mob/user)
|
||||
if(user.can_admin_interact())
|
||||
return TRUE
|
||||
else if(istype(user.get_active_hand(), /obj/item/multitool))
|
||||
var/obj/item/multitool/M = user.get_active_hand()
|
||||
if(M.shows_wire_information)
|
||||
return TRUE
|
||||
var/obj/item/held_item = user.get_active_hand()
|
||||
if(istype(held_item) && HAS_TRAIT(held_item, TRAIT_SHOW_WIRE_INFO))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
|
||||
@@ -75,6 +75,12 @@
|
||||
///Used to decide what the maximum time between ambience is
|
||||
var/max_ambience_cooldown = 90 SECONDS
|
||||
|
||||
/area/New(loc, ...)
|
||||
if(!there_can_be_many) // Has to be done in New else the maploader will fuck up and find subtypes for the parent
|
||||
GLOB.all_unique_areas[type] = src
|
||||
..()
|
||||
|
||||
|
||||
/area/Initialize(mapload)
|
||||
GLOB.all_areas += src
|
||||
icon_state = ""
|
||||
|
||||
@@ -37,45 +37,6 @@
|
||||
/area/ruin/powered/seedvault
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
/area/ruin/unpowered/syndicate_lava_base
|
||||
name = "Secret Base"
|
||||
icon_state = "dk_yellow"
|
||||
ambientsounds = HIGHSEC_SOUNDS
|
||||
report_alerts = FALSE
|
||||
hide_attacklogs = TRUE
|
||||
|
||||
/area/ruin/unpowered/syndicate_lava_base/engineering
|
||||
name = "Syndicate Lavaland Engineering"
|
||||
|
||||
/area/ruin/unpowered/syndicate_lava_base/medbay
|
||||
name = "Syndicate Lavaland Medbay"
|
||||
|
||||
/area/ruin/unpowered/syndicate_lava_base/arrivals
|
||||
name = "Syndicate Lavaland Arrivals"
|
||||
|
||||
/area/ruin/unpowered/syndicate_lava_base/bar
|
||||
name = "Syndicate Lavaland Bar"
|
||||
|
||||
/area/ruin/unpowered/syndicate_lava_base/main
|
||||
name = "Syndicate Lavaland Primary Hallway"
|
||||
|
||||
/area/ruin/unpowered/syndicate_lava_base/cargo
|
||||
name = "Syndicate Lavaland Cargo Bay"
|
||||
|
||||
/area/ruin/unpowered/syndicate_lava_base/chemistry
|
||||
name = "Syndicate Lavaland Chemistry"
|
||||
|
||||
/area/ruin/unpowered/syndicate_lava_base/virology
|
||||
name = "Syndicate Lavaland Virology"
|
||||
|
||||
/area/ruin/unpowered/syndicate_lava_base/testlab
|
||||
name = "Syndicate Lavaland Experimentation Lab"
|
||||
|
||||
/area/ruin/unpowered/syndicate_lava_base/dormitories
|
||||
name = "Syndicate Lavaland Dormitories"
|
||||
|
||||
/area/ruin/unpowered/syndicate_lava_base/telecomms
|
||||
name = "Syndicate Lavaland Telecommunications"
|
||||
|
||||
//Xeno Nest
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/area/ruin/unpowered/syndicate_space_base
|
||||
name = "Secret Base"
|
||||
icon_state = "dk_yellow"
|
||||
ambientsounds = HIGHSEC_SOUNDS
|
||||
report_alerts = FALSE
|
||||
hide_attacklogs = TRUE
|
||||
|
||||
/area/ruin/unpowered/syndicate_space_base/engineering
|
||||
name = "Syndicate Space Base Engineering"
|
||||
icon_state = "engine"
|
||||
|
||||
/area/ruin/unpowered/syndicate_space_base/medbay
|
||||
name = "Syndicate Space Base Medbay"
|
||||
icon_state = "medbay2"
|
||||
|
||||
/area/ruin/unpowered/syndicate_space_base/arrivals
|
||||
name = "Syndicate Space Base Arrivals"
|
||||
icon_state = "teleporter"
|
||||
|
||||
|
||||
/area/ruin/unpowered/syndicate_space_base/bar
|
||||
name = "Syndicate Space Base Bar"
|
||||
icon_state = "bar"
|
||||
|
||||
/area/ruin/unpowered/syndicate_space_base/main
|
||||
name = "Syndicate Space Base Primary Hallway"
|
||||
|
||||
/area/ruin/unpowered/syndicate_space_base/cargo
|
||||
name = "Syndicate Space Base Cargo Bay"
|
||||
icon_state = "storage"
|
||||
|
||||
/area/ruin/unpowered/syndicate_space_base/chemistry
|
||||
name = "Syndicate Space Base Chemistry"
|
||||
icon_state = "chem"
|
||||
|
||||
/area/ruin/unpowered/syndicate_space_base/virology
|
||||
name = "Syndicate Space Base Virology"
|
||||
icon_state = "virology"
|
||||
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab
|
||||
name = "Syndicate Space Base Experimentation Lab"
|
||||
icon_state = "toxtest"
|
||||
|
||||
/area/ruin/unpowered/syndicate_space_base/dormitories
|
||||
name = "Syndicate Space Base Dormitories"
|
||||
icon_state = "dorms"
|
||||
|
||||
/area/ruin/unpowered/syndicate_space_base/telecomms
|
||||
name = "Syndicate Space Base Telecommunications"
|
||||
icon_state = "tcomsatcham"
|
||||
+81
-124
@@ -607,53 +607,75 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "fpmaint"
|
||||
|
||||
/area/maintenance/fpmaint
|
||||
name = "EVA Maintenance"
|
||||
name = "Fore-Port Maintenance"
|
||||
icon_state = "fpmaint"
|
||||
|
||||
/area/maintenance/fpmaint2
|
||||
name = "Arrivals North Maintenance"
|
||||
name = "Fore-Port Secondary Maintenance"
|
||||
icon_state = "fpmaint"
|
||||
|
||||
/area/maintenance/fsmaint
|
||||
name = "Dormitory Maintenance"
|
||||
name = "Fore-Starboard Maintenance"
|
||||
icon_state = "fsmaint"
|
||||
|
||||
/area/maintenance/fsmaint2
|
||||
name = "Bar Maintenance"
|
||||
name = "Fore-Starboard Secondary Maintenance"
|
||||
icon_state = "fsmaint"
|
||||
|
||||
/area/maintenance/asmaint
|
||||
name = "Medbay Maintenance"
|
||||
name = "Aft-Starboard Maintenance"
|
||||
icon_state = "asmaint"
|
||||
|
||||
/area/maintenance/asmaint2
|
||||
name = "Science Maintenance"
|
||||
name = "Aft-Starboard Secondary Maintenance"
|
||||
icon_state = "asmaint"
|
||||
|
||||
/area/maintenance/apmaint
|
||||
name = "Cargo Maintenance"
|
||||
name = "Aft-Port Maintenance"
|
||||
icon_state = "apmaint"
|
||||
|
||||
/area/maintenance/apmaint2
|
||||
name = "Aft-Port Secondary Maintenance"
|
||||
icon_state = "apmaint"
|
||||
|
||||
/area/maintenance/maintcentral
|
||||
name = "Bridge Maintenance"
|
||||
name = "Central Maintenance"
|
||||
icon_state = "maintcentral"
|
||||
|
||||
/area/maintenance/maintcentral2
|
||||
name = "Central Secondary Maintenance"
|
||||
icon_state = "maintcentral"
|
||||
/area/maintenance/fore
|
||||
name = "Fore Maintenance"
|
||||
icon_state = "fmaint"
|
||||
|
||||
/area/maintenance/fore2
|
||||
name = "Fore Secondary Maintenance"
|
||||
icon_state = "fmaint"
|
||||
|
||||
/area/maintenance/aft
|
||||
name = "Aft Maintenance"
|
||||
icon_state = "amaint"
|
||||
|
||||
/area/maintenance/aft2
|
||||
name = "Aft Secondary Maintenance"
|
||||
icon_state = "amaint"
|
||||
|
||||
/area/maintenance/starboard
|
||||
name = "Starboard Maintenance"
|
||||
icon_state = "smaint"
|
||||
|
||||
/area/maintenance/starboard2
|
||||
name = "Starboard Secondary Maintenance"
|
||||
icon_state = "smaint"
|
||||
|
||||
/area/maintenance/port
|
||||
name = "Locker Room Maintenance"
|
||||
name = "Port Maintenance"
|
||||
icon_state = "pmaint"
|
||||
|
||||
/area/maintenance/aft
|
||||
name = "Engineering Maintenance"
|
||||
icon_state = "amaint"
|
||||
|
||||
/area/maintenance/port2
|
||||
name = "Port Secondary Maintenance"
|
||||
icon_state = "pmaint"
|
||||
/area/maintenance/storage
|
||||
name = "Atmospherics Maintenance"
|
||||
icon_state = "green"
|
||||
@@ -677,18 +699,18 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/maintenance/electrical
|
||||
name = "Electrical Maintenance"
|
||||
icon_state = "yellow"
|
||||
icon_state = "elec"
|
||||
|
||||
/area/maintenance/abandonedbar
|
||||
name = "Maintenance Bar"
|
||||
icon_state = "yellow"
|
||||
icon_state = "oldbar"
|
||||
power_equip = 0
|
||||
power_light = 0
|
||||
power_environ = 0
|
||||
|
||||
/area/maintenance/electrical_shop
|
||||
name ="Electronics Den"
|
||||
icon_state = "yellow"
|
||||
icon_state = "elec"
|
||||
|
||||
/area/maintenance/gambling_den
|
||||
name = "Gambling Den"
|
||||
@@ -696,7 +718,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/maintenance/consarea
|
||||
name = "Alternate Construction Area"
|
||||
icon_state = "yellow"
|
||||
icon_state = "construction"
|
||||
|
||||
|
||||
//Hallway
|
||||
@@ -836,7 +858,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/comms
|
||||
name = "\improper Communications Relay"
|
||||
icon_state = "tcomsatcham"
|
||||
icon_state = "tcomms"
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/server
|
||||
@@ -846,11 +868,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/ntrep
|
||||
name = "\improper Nanotrasen Representative's Office"
|
||||
icon_state = "bluenew"
|
||||
icon_state = "ntrep"
|
||||
|
||||
/area/blueshield
|
||||
name = "\improper Blueshield's Office"
|
||||
icon_state = "blueold"
|
||||
icon_state = "blueshield"
|
||||
|
||||
/area/centcomdocks
|
||||
name = "\improper Central Command Docks"
|
||||
@@ -919,7 +941,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/crew_quarters/bar
|
||||
name = "\improper Bar"
|
||||
icon_state = "bar"
|
||||
icon_state = "barstation"
|
||||
sound_environment = SOUND_AREA_WOODFLOOR
|
||||
|
||||
/area/crew_quarters/bar/atrium
|
||||
@@ -1049,45 +1071,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/holodeck/source_knightarena
|
||||
name = "\improper Holodeck - Knight Arena"
|
||||
|
||||
|
||||
//Embassies
|
||||
/area/embassy/
|
||||
name = "\improper Embassy Hallway"
|
||||
|
||||
/area/embassy/tajaran
|
||||
name = "\improper Tajaran Embassy"
|
||||
icon_state = "tajaran"
|
||||
|
||||
/area/embassy/skrell
|
||||
name = "\improper Skrell Embassy"
|
||||
icon_state = "skrell"
|
||||
|
||||
/area/embassy/unathi
|
||||
name = "\improper Unathi Embassy"
|
||||
icon_state = "unathi"
|
||||
|
||||
/area/embassy/kidan
|
||||
name = "\improper Kidan Embassy"
|
||||
icon_state = "kidan"
|
||||
|
||||
/area/embassy/diona
|
||||
name = "\improper Diona Embassy"
|
||||
icon_state = "diona"
|
||||
|
||||
/area/embassy/slime
|
||||
name = "\improper Slime Person Embassy"
|
||||
icon_state = "slime"
|
||||
|
||||
/area/embassy/grey
|
||||
name = "\improper Grey Embassy"
|
||||
icon_state = "grey"
|
||||
|
||||
/area/embassy/vox
|
||||
name = "\improper Vox Embassy"
|
||||
icon_state = "vox"
|
||||
|
||||
|
||||
|
||||
//Engineering
|
||||
/area/engine
|
||||
ambientsounds = ENGINEERING_SOUNDS
|
||||
@@ -1109,7 +1092,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/engine/equipmentstorage
|
||||
name = "\improper Engineering Equipment Storage"
|
||||
name = "Engineering Equipment Storage"
|
||||
icon_state = "storage"
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
@@ -1261,7 +1244,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
|
||||
/area/medical/biostorage
|
||||
name = "\improper Medical Storage"
|
||||
name = "Medical Storage"
|
||||
icon_state = "medbaysecstorage"
|
||||
|
||||
/area/medical/reception
|
||||
@@ -1286,19 +1269,19 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "patientsward"
|
||||
|
||||
/area/medical/patient_a
|
||||
name = "\improper Isolation A"
|
||||
name = "Isolation A"
|
||||
icon_state = "medbayisoa"
|
||||
|
||||
/area/medical/patient_b
|
||||
name = "\improper Isolation B"
|
||||
name = "Isolation B"
|
||||
icon_state = "medbayisob"
|
||||
|
||||
/area/medical/patient_c
|
||||
name = "\improper Isolation C"
|
||||
name = "Isolation C"
|
||||
icon_state = "medbayisoc"
|
||||
|
||||
/area/medical/iso_access
|
||||
name = "\improper Isolation Access"
|
||||
name = "Isolation Access"
|
||||
icon_state = "medbayisoaccess"
|
||||
|
||||
/area/medical/cmo
|
||||
@@ -1306,23 +1289,19 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "CMO"
|
||||
|
||||
/area/medical/cmostore
|
||||
name = "\improper Medical Secondary Storage"
|
||||
name = "Medical Secondary Storage"
|
||||
icon_state = "medbaysecstorage"
|
||||
|
||||
/area/medical/robotics
|
||||
name = "\improper Robotics"
|
||||
icon_state = "medresearch"
|
||||
name = "Robotics"
|
||||
icon_state = "research"
|
||||
|
||||
/area/medical/research
|
||||
name = "\improper Medical Research"
|
||||
icon_state = "medresearch"
|
||||
|
||||
/area/medical/research_shuttle_dock
|
||||
name = "\improper Research Shuttle Dock"
|
||||
icon_state = "medresearch"
|
||||
name = "Research Division"
|
||||
icon_state = "research"
|
||||
|
||||
/area/medical/virology
|
||||
name = "\improper Virology"
|
||||
name = "Virology"
|
||||
icon_state = "virology"
|
||||
|
||||
/area/medical/virology/lab
|
||||
@@ -1337,7 +1316,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/medical/chemistry
|
||||
name = "\improper Chemistry"
|
||||
name = "Chemistry"
|
||||
icon_state = "chem"
|
||||
|
||||
/area/medical/surgery
|
||||
@@ -1345,19 +1324,19 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "surgery"
|
||||
|
||||
/area/medical/surgery1
|
||||
name = "\improper Surgery 1"
|
||||
name = "Surgery 1"
|
||||
icon_state = "surgery1"
|
||||
|
||||
/area/medical/surgery2
|
||||
name = "\improper Surgery 2"
|
||||
name = "Surgery 2"
|
||||
icon_state = "surgery2"
|
||||
|
||||
/area/medical/surgeryobs
|
||||
name = "\improper Surgery Observation"
|
||||
name = "Surgery Observation"
|
||||
icon_state = "surgery"
|
||||
|
||||
/area/medical/cryo
|
||||
name = "\improper Cryogenics"
|
||||
name = "Cryogenics"
|
||||
icon_state = "cryo"
|
||||
|
||||
/area/medical/exam_room
|
||||
@@ -1377,7 +1356,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "exam_room"
|
||||
|
||||
/area/medical/paramedic
|
||||
name = "\improper Paramedic"
|
||||
name = "Paramedic"
|
||||
icon_state = "medbay"
|
||||
|
||||
//Security
|
||||
@@ -1442,35 +1421,31 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "brig"
|
||||
|
||||
/area/security/execution
|
||||
name = "\improper Execution"
|
||||
name = "Execution"
|
||||
icon_state = "execution"
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
/area/security/processing
|
||||
name = "\improper Prisoner Processing"
|
||||
name = "Prisoner Processing"
|
||||
icon_state = "prisonerprocessing"
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
/area/security/interrogation
|
||||
name = "\improper Interrogation"
|
||||
name = "Interrogation"
|
||||
icon_state = "interrogation"
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
/area/security/seceqstorage
|
||||
name = "\improper Security Equipment Storage"
|
||||
name = "Security Equipment Storage"
|
||||
icon_state = "securityequipmentstorage"
|
||||
|
||||
/area/security/interrogationhallway
|
||||
name = "\improper Interrogation Hallway"
|
||||
icon_state = "interrogationhall"
|
||||
|
||||
/area/security/courtroomdandp
|
||||
name = "\improper Courtroom Defense and Prosecution"
|
||||
icon_state = "seccourt"
|
||||
sound_environment = SOUND_AREA_LARGE_ENCLOSED
|
||||
|
||||
/area/security/interrogationobs
|
||||
name = "\improper Interrogation Observation"
|
||||
name = "Interrogation Observation"
|
||||
icon_state = "security"
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
@@ -1506,7 +1481,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "secarmory"
|
||||
|
||||
/area/security/securehallway
|
||||
name = "\improper Security Secure Hallway"
|
||||
name = "\improper Brig Secure Hallway"
|
||||
icon_state = "securehall"
|
||||
|
||||
/area/security/hos
|
||||
@@ -1531,11 +1506,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "nuke_storage"
|
||||
|
||||
/area/security/customs
|
||||
name = "\improper Customs"
|
||||
name = "Customs"
|
||||
icon_state = "checkpoint1"
|
||||
|
||||
/area/security/customs2
|
||||
name = "\improper Customs"
|
||||
name = "Customs"
|
||||
icon_state = "security"
|
||||
|
||||
/area/security/checkpoint
|
||||
@@ -1602,7 +1577,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "mining"
|
||||
|
||||
/area/quartermaster/miningstorage
|
||||
name = "\improper Mining Storage"
|
||||
name = "Mining Storage"
|
||||
icon_state = "green"
|
||||
|
||||
/area/quartermaster/mechbay
|
||||
@@ -1615,7 +1590,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/hydroponics
|
||||
name = "\improper Hydroponics"
|
||||
name = "Hydroponics"
|
||||
icon_state = "hydro"
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
@@ -1630,7 +1605,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/toxins/lab
|
||||
name = "\improper Research and Development"
|
||||
name = "Research and Development"
|
||||
icon_state = "toxlab"
|
||||
|
||||
/area/toxins/hallway
|
||||
@@ -1651,7 +1626,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
xenobiology_compatible = TRUE
|
||||
|
||||
/area/toxins/xenobiology/xenoflora_storage
|
||||
name = "\improper Xenoflora Storage"
|
||||
name = "Xenoflora Storage"
|
||||
icon_state = "toxlab"
|
||||
|
||||
/area/toxins/xenobiology/xenoflora
|
||||
@@ -1659,7 +1634,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "toxlab"
|
||||
|
||||
/area/toxins/storage
|
||||
name = "\improper Toxins Storage"
|
||||
name = "Toxins Storage"
|
||||
icon_state = "toxstorage"
|
||||
|
||||
/area/toxins/test_area
|
||||
@@ -1672,7 +1647,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "toxmix"
|
||||
|
||||
/area/toxins/launch
|
||||
name = "Toxins Launch Room"
|
||||
name = "\improper Toxins Launch Room"
|
||||
icon_state = "toxlaunch"
|
||||
|
||||
/area/toxins/misc_lab
|
||||
@@ -1740,7 +1715,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "auxstorage"
|
||||
|
||||
/area/storage/office
|
||||
name = "\improper Office Supplies"
|
||||
name = "Office Supplies"
|
||||
icon_state = "office_supplies"
|
||||
|
||||
// ENGIE OUTPOST
|
||||
@@ -2062,45 +2037,27 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/tcommsat/chamber
|
||||
name = "\improper Telecoms Central Compartment"
|
||||
icon_state = "tcomsatcham"
|
||||
icon_state = "tcomms"
|
||||
|
||||
// These areas are needed for MetaStation's AI sat
|
||||
/area/turret_protected/tcomsat
|
||||
name = "\improper Telecoms Satellite"
|
||||
icon_state = "tcomsatlob"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/turret_protected/tcomfoyer
|
||||
name = "\improper Telecoms Foyer"
|
||||
icon_state = "tcomsatentrance"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/turret_protected/tcomwest
|
||||
name = "\improper Telecoms West Wing"
|
||||
icon_state = "tcomsatwest"
|
||||
icon_state = "tcomms"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/turret_protected/tcomeast
|
||||
name = "\improper Telecoms East Wing"
|
||||
icon_state = "tcomsateast"
|
||||
icon_state = "tcomms"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/tcommsat/computer
|
||||
name = "\improper Telecoms Control Room"
|
||||
icon_state = "tcomsatcomp"
|
||||
icon_state = "tcomms"
|
||||
sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR
|
||||
|
||||
/area/tcommsat/server
|
||||
name = "\improper Telecoms Server Room"
|
||||
icon_state = "tcomsatcham"
|
||||
|
||||
/area/tcommsat/lounge
|
||||
name = "\improper Telecoms Lounge"
|
||||
icon_state = "tcomsatlounge"
|
||||
|
||||
/area/tcommsat/powercontrol
|
||||
name = "\improper Telecoms Power Control"
|
||||
icon_state = "tcomsatwest"
|
||||
icon_state = "tcomms"
|
||||
|
||||
// Away Missions
|
||||
/area/awaymission
|
||||
|
||||
+3
-3
@@ -413,6 +413,9 @@
|
||||
/atom/proc/emag_act()
|
||||
return
|
||||
|
||||
/atom/proc/unemag()
|
||||
return
|
||||
|
||||
/**
|
||||
* Respond to a radioactive wave hitting this atom
|
||||
*
|
||||
@@ -941,9 +944,6 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
/atom/proc/narsie_act()
|
||||
return
|
||||
|
||||
/atom/proc/ratvar_act()
|
||||
return
|
||||
|
||||
/**
|
||||
* Respond to an electric bolt action on our item
|
||||
*
|
||||
|
||||
@@ -178,14 +178,19 @@
|
||||
/mob/living/carbon/med_hud_set_status()
|
||||
var/image/holder = hud_list[STATUS_HUD]
|
||||
var/mob/living/simple_animal/borer/B = has_brain_worms()
|
||||
var/dead = stat == DEAD || HAS_TRAIT(src, TRAIT_FAKEDEATH)
|
||||
// To the right of health bar
|
||||
if(dead)
|
||||
var/revivable = timeofdeath && (round(world.time - timeofdeath) < DEFIB_TIME_LIMIT)
|
||||
if(stat == DEAD || HAS_TRAIT(src, TRAIT_FAKEDEATH))
|
||||
var/revivable
|
||||
if(!ghost_can_reenter()) // DNR or AntagHUD
|
||||
revivable = FALSE
|
||||
else if(timeofdeath && (round(world.time - timeofdeath) < DEFIB_TIME_LIMIT))
|
||||
revivable = TRUE
|
||||
|
||||
if(revivable)
|
||||
holder.icon_state = "hudflatline"
|
||||
else
|
||||
holder.icon_state = "huddead"
|
||||
|
||||
else if(HAS_TRAIT(src, TRAIT_XENO_HOST))
|
||||
holder.icon_state = "hudxeno"
|
||||
else if(B && B.controlling)
|
||||
|
||||
@@ -14,6 +14,7 @@ GLOBAL_LIST_INIT(assigned_mutation_blocks, new(DNA_SE_LENGTH))
|
||||
// Used to determine what each block means (admin hax and species stuff on /vg/, mostly)
|
||||
GLOBAL_LIST_INIT(assigned_blocks, new(DNA_SE_LENGTH))
|
||||
|
||||
/// Assoc list. Key = type of the mutation, value = the mutation
|
||||
GLOBAL_LIST_EMPTY(dna_mutations)
|
||||
|
||||
GLOBAL_LIST_EMPTY(good_blocks)
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
// M: Mob to mess with
|
||||
// flags: See below, bitfield.
|
||||
/proc/domutcheck(mob/living/M, flags = 0)
|
||||
for(var/datum/mutation/mutation in GLOB.dna_mutations)
|
||||
for(var/mutation_type in GLOB.dna_mutations)
|
||||
var/datum/mutation/mutation = GLOB.dna_mutations[mutation_type]
|
||||
if(!M || !M.dna)
|
||||
return
|
||||
if(!mutation.block)
|
||||
@@ -32,7 +33,7 @@
|
||||
var/mutation_active = M.dna.GetSEState(mutation.block)
|
||||
|
||||
// Sanity checks, don't skip.
|
||||
if(!mutation.can_activate(M, flags) && mutation_active)
|
||||
if(mutation_active && !mutation.can_activate(M, flags))
|
||||
//testing("[M] - Failed to activate [gene.name] (can_activate fail).")
|
||||
return FALSE
|
||||
|
||||
@@ -46,11 +47,7 @@
|
||||
if(mutation_active)
|
||||
//testing("[gene.name] activated!")
|
||||
mutation.activate(M)
|
||||
if(M)
|
||||
M.active_mutations |= mutation.type
|
||||
// If Gene is NOT active:
|
||||
else
|
||||
//testing("[gene.name] deactivated!")
|
||||
mutation.deactivate(M)
|
||||
if(M)
|
||||
M.active_mutations -= mutation.type
|
||||
|
||||
@@ -150,16 +150,16 @@
|
||||
if(usr.incapacitated() || usr.buckled) //are you cuffed, dying, lying, stunned or other
|
||||
return
|
||||
if(!ishuman(usr)) //Make sure they're a mob that has dna
|
||||
to_chat(usr, "<span class='notice'>Try as you might, you can not climb up into the [src].</span>")
|
||||
to_chat(usr, "<span class='notice'>Try as you might, you can not climb up into [src].</span>")
|
||||
return
|
||||
if(occupant)
|
||||
to_chat(usr, "<span class='boldnotice'>The [src] is already occupied!</span>")
|
||||
to_chat(usr, "<span class='boldnotice'>[src] is already occupied!</span>")
|
||||
return
|
||||
if(usr.abiotic())
|
||||
to_chat(usr, "<span class='boldnotice'>Subject cannot have abiotic items on.</span>")
|
||||
return
|
||||
if(usr.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(usr, "<span class='warning'>[usr] will not fit into the [src] because [usr.p_they()] [usr.p_have()] a slime latched onto [usr.p_their()] head.</span>")
|
||||
to_chat(usr, "<span class='warning'>[usr] will not fit into [src] because [usr.p_they()] [usr.p_have()] a slime latched onto [usr.p_their()] head.</span>")
|
||||
return
|
||||
usr.stop_pulling()
|
||||
usr.forceMove(src)
|
||||
@@ -188,7 +188,7 @@
|
||||
if(!istype(user.loc, /turf) || !istype(O.loc, /turf)) // are you in a container/closet/pod/etc?
|
||||
return
|
||||
if(occupant)
|
||||
to_chat(user, "<span class='boldnotice'>The [src] is already occupied!</span>")
|
||||
to_chat(user, "<span class='boldnotice'>[src] is already occupied!</span>")
|
||||
return
|
||||
var/mob/living/L = O
|
||||
if(!istype(L) || L.buckled)
|
||||
@@ -200,9 +200,9 @@
|
||||
to_chat(user, "<span class='warning'>[L] will not fit into [src] because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.</span>")
|
||||
return
|
||||
if(L == user)
|
||||
visible_message("[user] climbs into the [src].")
|
||||
visible_message("<span class='notice'>[user] climbs into [src].</span>")
|
||||
else
|
||||
visible_message("[user] puts [L.name] into the [src].")
|
||||
visible_message("<span class='notice'>[user] puts [L.name] into [src].</span>")
|
||||
put_in(L)
|
||||
if(user.pulling == L)
|
||||
user.stop_pulling()
|
||||
@@ -235,7 +235,7 @@
|
||||
to_chat(user, "<span class='boldnotice'>Subject cannot have abiotic items on.</span>")
|
||||
return
|
||||
if(G.affecting.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(user, "<span class='warning'>will not fit into the [src] because [G.affecting.p_they()] [G.affecting.p_have()] a slime latched onto [G.affecting.p_their()] head.</span>")
|
||||
to_chat(user, "<span class='warning'>[G] will not fit into [src] because [G.affecting.p_they()] [G.affecting.p_have()] a slime latched onto [G.affecting.p_their()] head.</span>")
|
||||
return
|
||||
if(panel_open)
|
||||
to_chat(usr, "<span class='boldnotice'>Close the maintenance panel first.</span>")
|
||||
|
||||
@@ -31,7 +31,9 @@
|
||||
|
||||
// Called when the gene activates. Do your magic here.
|
||||
/datum/mutation/proc/activate(mob/living/M)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
M.gene_stability -= instability
|
||||
M.active_mutations |= type // |= is probably not required but just in case
|
||||
for(var/thing in traits_to_add)
|
||||
ADD_TRAIT(M, thing, GENETIC_MUTATION)
|
||||
if(length(activation_messages))
|
||||
@@ -42,7 +44,9 @@
|
||||
// Called when the gene deactivates. Undo your magic here.
|
||||
// Only called when the block is deactivated.
|
||||
/datum/mutation/proc/deactivate(mob/living/M)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
M.gene_stability += instability
|
||||
M.active_mutations -= type
|
||||
for(var/thing in traits_to_add)
|
||||
REMOVE_TRAIT(M, thing, GENETIC_MUTATION)
|
||||
if(length(deactivation_messages))
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
return ishuman(M)
|
||||
|
||||
/datum/mutation/monkey/activate(mob/living/carbon/human/H)
|
||||
..()
|
||||
if(!istype(H))
|
||||
return
|
||||
if(issmall(H))
|
||||
@@ -42,6 +43,7 @@
|
||||
return H
|
||||
|
||||
/datum/mutation/monkey/deactivate(mob/living/carbon/human/H)
|
||||
..()
|
||||
if(!istype(H))
|
||||
return
|
||||
if(!issmall(H))
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
/datum/mutation/noprints
|
||||
name = "No Prints"
|
||||
activation_messages = list("Your fingers feel numb.")
|
||||
deactivation_messages = list("your fingers no longer feel numb.")
|
||||
deactivation_messages = list("Your fingers no longer feel numb.")
|
||||
instability = GENE_INSTABILITY_MINOR
|
||||
traits_to_add = list(TRAIT_NOFINGERPRINTS)
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
/datum/mutation/xray
|
||||
name = "X-Ray Vision"
|
||||
activation_messages = list("The walls suddenly disappear.")
|
||||
deactivation_messages = list("the walls around you re-appear.")
|
||||
deactivation_messages = list("The walls around you re-appear.")
|
||||
instability = GENE_INSTABILITY_MAJOR
|
||||
traits_to_add = list(TRAIT_XRAY_VISION)
|
||||
activation_prob = 15
|
||||
|
||||
@@ -15,7 +15,6 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
recommended_enemies = 1
|
||||
restricted_jobs = list("Cyborg", "AI")
|
||||
|
||||
var/declared = 0
|
||||
var/burst = 0
|
||||
|
||||
var/cores_to_spawn = 1
|
||||
@@ -75,8 +74,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
log_game("[key_name(blob)] has been selected as a Blob")
|
||||
greet_blob(blobmind)
|
||||
to_chat(blob, "<span class='userdanger'>You feel very tired and bloated! You don't have long before you burst!</span>")
|
||||
spawn(600)
|
||||
burst_blob(blobmind)
|
||||
addtimer(CALLBACK(src, .proc/burst_blob, blobmind), 60 SECONDS)
|
||||
return 1
|
||||
|
||||
/datum/game_mode/blob/proc/make_blobs(count)
|
||||
@@ -103,6 +101,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
to_chat(blob.current, "<b>Find a good location to spawn the core and then take control and overwhelm the station!</b>")
|
||||
to_chat(blob.current, "<b>When you have found a location, wait until you spawn; this will happen automatically and you cannot speed up the process.</b>")
|
||||
to_chat(blob.current, "<b>If you go outside of the station level, or in space, then you will die; make sure your location has lots of ground to cover.</b>")
|
||||
to_chat(blob.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Blob)</span>")
|
||||
SEND_SOUND(blob.current, sound('sound/magic/mutate.ogg'))
|
||||
return
|
||||
|
||||
@@ -127,8 +126,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
if(!warned)
|
||||
to_chat(C, "<span class='userdanger'>You feel ready to burst, but this isn't an appropriate place! You must return to the station!</span>")
|
||||
message_admins("[key_name_admin(C)] was in space when the blobs burst, and will die if [C.p_they()] [C.p_do()] not return to the station.")
|
||||
spawn(300)
|
||||
burst_blob(blob, 1)
|
||||
addtimer(CALLBACK(src, .proc/burst_blob, blob, 1), 30 SECONDS)
|
||||
else
|
||||
burst++
|
||||
log_admin("[key_name(C)] was in space when attempting to burst as a blob.")
|
||||
@@ -172,33 +170,22 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
|
||||
show_message("<span class='userdanger'>You feel like you are about to burst.</span>")
|
||||
|
||||
sleep(wait_time / 2)
|
||||
|
||||
burst_blobs()
|
||||
|
||||
// Stage 0
|
||||
sleep(wait_time)
|
||||
stage(0)
|
||||
addtimer(CALLBACK(src, .proc/burst_blobs), (wait_time / 2))
|
||||
|
||||
// Stage 1
|
||||
sleep(wait_time)
|
||||
stage(1)
|
||||
addtimer(CALLBACK(src, .proc/stage, 1), (wait_time * 2 + wait_time / 2))
|
||||
|
||||
// Stage 2
|
||||
sleep(30000)
|
||||
stage(2)
|
||||
addtimer(CALLBACK(src, .proc/stage, 2), 50 MINUTES)
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/game_mode/blob/proc/stage(stage)
|
||||
switch(stage)
|
||||
if(0)
|
||||
send_intercept(1)
|
||||
declared = 1
|
||||
if(1)
|
||||
GLOB.event_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg')
|
||||
if(2)
|
||||
send_intercept(2)
|
||||
send_intercept(1)
|
||||
|
||||
/datum/game_mode/proc/update_blob_icons_added(datum/mind/mob_mind)
|
||||
var/datum/atom_hud/antag/antaghud = GLOB.huds[ANTAG_HUD_BLOB]
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
to_chat(world, "<FONT size = 3><B>The staff has won!</B></FONT>")
|
||||
to_chat(world, "<B>The alien organism has been eradicated from the station</B>")
|
||||
log_game("Blob mode completed with a crew victory.")
|
||||
to_chat(world, "<span class='notice'>Rebooting in 30s</span>")
|
||||
..()
|
||||
return 1
|
||||
|
||||
|
||||
@@ -5,19 +5,6 @@
|
||||
if(0)
|
||||
return
|
||||
if(1)
|
||||
interceptname = "Level 5-6 Biohazard Response Procedures"
|
||||
intercepttext += "<FONT size = 3><B>Nanotrasen Update</B>: Biohazard Alert.</FONT><HR>"
|
||||
intercepttext += "Reports indicate the probable transfer of a biohazardous agent onto [station_name()] during the last crew deployment cycle.<BR>"
|
||||
intercepttext += "Preliminary analysis of the organism classifies it as a level 5 biohazard. Its origin is unknown.<BR>"
|
||||
intercepttext += "Nanotrasen has issued a directive 7-10 for [station_name()]. The station is to be considered quarantined.<BR>"
|
||||
intercepttext += "Orders for all [station_name()] personnel follows:<BR>"
|
||||
intercepttext += " 1. Do not leave the quarantine area.<BR>"
|
||||
intercepttext += " 2. Locate any outbreaks of the organism on the station.<BR>"
|
||||
intercepttext += " 3. If found, use any neccesary means to contain the organism.<BR>"
|
||||
intercepttext += " 4. Avoid damage to the capital infrastructure of the station.<BR>"
|
||||
intercepttext += "<BR>Note in the event of a quarantine breach or uncontrolled spread of the biohazard, the directive 7-10 may be upgraded to a directive 7-12.<BR>"
|
||||
intercepttext += "Message ends."
|
||||
if(2)
|
||||
var/nukecode = rand(10000, 99999)
|
||||
for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines)
|
||||
if(bomb && bomb.r_code)
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
icon = H.icon
|
||||
speak_emote = list("groans")
|
||||
icon_state = "zombie2_s"
|
||||
if(head_organ)
|
||||
if(head_organ && !(NO_HAIR in H.dna.species.species_traits))
|
||||
head_organ.h_style = null
|
||||
H.update_hair()
|
||||
human_overlays = H.overlays
|
||||
|
||||
@@ -117,13 +117,13 @@
|
||||
|
||||
if(C && !QDELETED(src))
|
||||
var/mob/camera/blob/B = new(loc)
|
||||
B.is_offspring = is_offspring
|
||||
B.key = C.key
|
||||
B.blob_core = src
|
||||
overmind = B
|
||||
color = overmind.blob_reagent_datum.color
|
||||
if(B.mind && !B.mind.special_role)
|
||||
B.mind.make_Overmind()
|
||||
B.is_offspring = is_offspring
|
||||
|
||||
/obj/structure/blob/core/proc/lateblobtimer()
|
||||
addtimer(CALLBACK(src, .proc/lateblobcheck), 50)
|
||||
|
||||
@@ -147,6 +147,7 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","E
|
||||
for(var/datum/objective/objective in changeling.objectives)
|
||||
to_chat(changeling.current, "<B>Objective #[obj_count]</B>: [objective.explanation_text]")
|
||||
obj_count++
|
||||
to_chat(changeling.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Changeling)</span>")
|
||||
return
|
||||
|
||||
/datum/game_mode/proc/remove_changeling(datum/mind/changeling_mind)
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
to_chat(user, "<span class='notice'>We stealthily stab [target] with a minor proboscis...</span>")
|
||||
to_chat(target, "<span class='userdanger'>You experience a stabbing sensation and your ears begin to ring...</span>")
|
||||
if(3)
|
||||
to_chat(user, "<span class='notice'>You mold the [target]'s mind like clay, [target.p_they()] can now speak in the hivemind!</span>")
|
||||
to_chat(user, "<span class='notice'>You mold [target]'s mind like clay, [target.p_they()] can now speak in the hivemind!</span>")
|
||||
to_chat(target, "<span class='userdanger'>A migraine throbs behind your eyes, you hear yourself screaming - but your mouth has not opened!</span>")
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
if(GLOB.all_languages["Changeling"] in M.languages)
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
/datum/action/changeling/weapon/sting_action(mob/user)
|
||||
if(!user.drop_item())
|
||||
to_chat(user, "The [user.get_active_hand()] is stuck to your hand, you cannot grow a [weapon_name_simple] over it!")
|
||||
to_chat(user, "[user.get_active_hand()] is stuck to your hand, you cannot grow a [weapon_name_simple] over it!")
|
||||
return
|
||||
var/obj/item/W = new weapon_type(user, silent)
|
||||
user.put_in_hands(W)
|
||||
@@ -173,8 +173,11 @@
|
||||
name = "Tentacle"
|
||||
desc = "We ready a tentacle to grab items or victims with. Costs 10 chemicals."
|
||||
helptext = "We can use it once to retrieve a distant item. If used on living creatures, the effect depends on the intent: \
|
||||
Help will simply drag them closer, Disarm will grab whatever they are holding instead of them, Grab will put the victim in our hold after catching it, \
|
||||
and Harm will stun it, and stab it if we are also holding a sharp weapon. Cannot be used while in lesser form."
|
||||
Help will drag the target closer. \
|
||||
Disarm will grab whatever the target is holding. \
|
||||
Grab will put the target in our grip after we catch it. \
|
||||
Harm will drag the target closer and stab it if we are holding a sharp weapon in our other hand. \
|
||||
Cannot be used while in our lesser form."
|
||||
button_icon_state = "tentacle"
|
||||
chemical_cost = 10
|
||||
dna_cost = 2
|
||||
@@ -209,7 +212,7 @@
|
||||
to_chat(loc, "<span class='notice'>You prepare to extend a tentacle.</span>")
|
||||
|
||||
/obj/item/gun/magic/tentacle/shoot_with_empty_chamber(mob/living/user as mob|obj)
|
||||
to_chat(user, "<span class='warning'>The [name] is not ready yet.</span>")
|
||||
to_chat(user, "<span class='warning'>[src] is not ready yet.</span>")
|
||||
|
||||
/obj/item/gun/magic/tentacle/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] coils [src] tightly around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide.</span>")
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
/datum/action/changeling/sting/transformation/can_sting(mob/user, mob/target)
|
||||
if(!..())
|
||||
return
|
||||
if(HAS_TRAIT(target, TRAIT_HUSK) || (!ishuman(target)))
|
||||
if(HAS_TRAIT(target, TRAIT_HUSK) || !ishuman(target) || (NOTRANSSTING in target.dna.species.species_traits))
|
||||
to_chat(user, "<span class='warning'>Our sting appears ineffective against its DNA.</span>")
|
||||
return FALSE
|
||||
if(ishuman(target))
|
||||
|
||||
@@ -253,7 +253,7 @@
|
||||
/datum/action/innate/cult/blood_spell/horror/Destroy()
|
||||
var/obj/effect/proc_holder/horror/destroy = PH
|
||||
. = ..()
|
||||
if(destroy && !QDELETED(destroy))
|
||||
if(!QDELETED(destroy))
|
||||
QDEL_NULL(destroy)
|
||||
|
||||
/datum/action/innate/cult/blood_spell/horror/Activate()
|
||||
@@ -268,7 +268,7 @@
|
||||
/obj/effect/proc_holder/horror/Destroy()
|
||||
var/datum/action/innate/cult/blood_spell/AA = attached_action
|
||||
. = ..()
|
||||
if(AA && !QDELETED(AA))
|
||||
if(!QDELETED(AA))
|
||||
QDEL_NULL(AA)
|
||||
|
||||
/obj/effect/proc_holder/horror/proc/toggle(mob/user)
|
||||
@@ -476,9 +476,15 @@
|
||||
var/list/potential_runes = list()
|
||||
var/list/teleportnames = list()
|
||||
var/list/duplicaterunecount = list()
|
||||
var/atom/movable/teleportee
|
||||
if(!iscultist(target) || !proximity)
|
||||
to_chat(user, "<span class='warning'>You can only teleport adjacent cultists with this spell!</span>")
|
||||
return
|
||||
if(user != target) // So that the teleport effect shows on the correct mob
|
||||
teleportee = target
|
||||
else
|
||||
teleportee = user
|
||||
|
||||
for(var/R in GLOB.teleport_runes)
|
||||
var/obj/effect/rune/teleport/T = R
|
||||
var/resultkey = T.listkey
|
||||
@@ -499,16 +505,15 @@
|
||||
log_game("Teleport spell failed - user in away mission")
|
||||
return
|
||||
|
||||
var/mob/living/L = target
|
||||
var/input_rune_key = input(user, "Choose a rune to teleport to.", "Rune to Teleport to") as null|anything in potential_runes //we know what key they picked
|
||||
var/obj/effect/rune/teleport/actual_selected_rune = potential_runes[input_rune_key] //what rune does that key correspond to?
|
||||
if(!src || QDELETED(src) || !user || user.l_hand != src && user.r_hand != src || user.incapacitated() || !actual_selected_rune)
|
||||
if(QDELETED(src) || !user || user.l_hand != src && user.r_hand != src || user.incapacitated() || !actual_selected_rune)
|
||||
return
|
||||
uses--
|
||||
|
||||
var/turf/origin = get_turf(user)
|
||||
var/turf/origin = get_turf(teleportee)
|
||||
var/turf/destination = get_turf(actual_selected_rune)
|
||||
INVOKE_ASYNC(actual_selected_rune, /obj/effect/rune/.proc/teleport_effect, user, origin, destination)
|
||||
INVOKE_ASYNC(actual_selected_rune, /obj/effect/rune/.proc/teleport_effect, teleportee, origin, destination)
|
||||
|
||||
if(is_mining_level(user.z) && !is_mining_level(destination.z)) //No effect if you stay on lavaland
|
||||
actual_selected_rune.handle_portal("lava")
|
||||
@@ -522,7 +527,7 @@
|
||||
target.visible_message("<span class='warning'>Dust flows from [user]'s hand, and [target] disappears in a flash of red light!</span>", \
|
||||
"<span class='cultitalic'>You suddenly find yourself somewhere else!</span>")
|
||||
destination.visible_message("<span class='warning'>There is a boom of outrushing air as something appears above the rune!</span>", null, "<i>You hear a boom.</i>")
|
||||
L.forceMove(destination)
|
||||
teleportee.forceMove(destination)
|
||||
return ..()
|
||||
|
||||
//Shackles
|
||||
@@ -678,7 +683,7 @@
|
||||
return
|
||||
if(proximity_flag)
|
||||
|
||||
//Shielded suit
|
||||
// Shielded suit
|
||||
if(istype(target, /obj/item/clothing/suit/hooded/cultrobes/cult_shield))
|
||||
var/obj/item/clothing/suit/hooded/cultrobes/cult_shield/C = target
|
||||
if(C.current_charges < 3)
|
||||
@@ -692,7 +697,7 @@
|
||||
to_chat(user, "<span class='warning'>[target] is already at full charge!</span>")
|
||||
return
|
||||
|
||||
//Plasteel to runed metal
|
||||
// Veil Shifter
|
||||
else if(istype(target, /obj/item/cult_shift))
|
||||
var/obj/item/cult_shift/S = target
|
||||
if(S.uses < 4)
|
||||
@@ -870,39 +875,6 @@
|
||||
var/list/options = list("Blood Orb (50)", "Blood Recharge (75)", "Blood Spear (150)", "Blood Bolt Barrage (300)")
|
||||
var/choice = input(user, "Choose a greater blood rite...", "Greater Blood Rites") as null|anything in options
|
||||
switch(choice)
|
||||
if("Blood Spear (150)")
|
||||
if(uses < BLOOD_SPEAR_COST)
|
||||
to_chat(user, "<span class='warning'>You need [BLOOD_SPEAR_COST] charges to perform this rite.</span>")
|
||||
else
|
||||
uses -= BLOOD_SPEAR_COST
|
||||
var/turf/T = get_turf(user)
|
||||
qdel(src)
|
||||
var/datum/action/innate/cult/spear/S = new(user)
|
||||
var/obj/item/twohanded/cult_spear/rite = new(T)
|
||||
S.Grant(user, rite)
|
||||
rite.spear_act = S
|
||||
if(user.put_in_hands(rite))
|
||||
to_chat(user, "<span class='cult'>A [rite.name] appears in your hand!</span>")
|
||||
else
|
||||
user.visible_message("<span class='warning'>A [rite.name] appears at [user]'s feet!</span>", \
|
||||
"<span class='cult'>A [rite.name] materializes at your feet.</span>")
|
||||
|
||||
if("Blood Bolt Barrage (300)")
|
||||
if(uses < BLOOD_BARRAGE_COST)
|
||||
to_chat(user, "<span class='cultitalic'>You need [BLOOD_BARRAGE_COST] charges to perform this rite.</span>")
|
||||
else
|
||||
var/obj/rite = new /obj/item/gun/projectile/shotgun/boltaction/enchanted/arcane_barrage/blood()
|
||||
uses -= BLOOD_BARRAGE_COST
|
||||
qdel(src)
|
||||
user.swap_hand()
|
||||
user.drop_item()
|
||||
if(user.put_in_hands(rite))
|
||||
to_chat(user, "<span class='cult'>Both of your hands glow with power!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need a free hand for this rite!</span>")
|
||||
uses += BLOOD_BARRAGE_COST // Refund the charges
|
||||
qdel(rite)
|
||||
|
||||
if("Blood Orb (50)")
|
||||
if(uses < BLOOD_ORB_COST)
|
||||
to_chat(user, "<span class='warning'>You need [BLOOD_ORB_COST] charges to perform this rite.</span>")
|
||||
@@ -922,7 +894,7 @@
|
||||
if(user.put_in_hands(rite))
|
||||
to_chat(user, "<span class='cult'>A [rite.name] appears in your hand!</span>")
|
||||
else
|
||||
user.visible_message("<span class='warning'>A [rite.name] appears at [user]'s feet!</span>", \
|
||||
user.visible_message("<span class='warning'>A [rite.name] appears at [user]'s feet!</span>",
|
||||
"<span class='cult'>A [rite.name] materializes at your feet.</span>")
|
||||
|
||||
if("Blood Recharge (75)")
|
||||
@@ -938,3 +910,36 @@
|
||||
to_chat(user, "<span class='warning'>You need a free hand for this rite!</span>")
|
||||
uses += BLOOD_RECHARGE_COST // Refund the charges
|
||||
qdel(rite)
|
||||
|
||||
if("Blood Spear (150)")
|
||||
if(uses < BLOOD_SPEAR_COST)
|
||||
to_chat(user, "<span class='warning'>You need [BLOOD_SPEAR_COST] charges to perform this rite.</span>")
|
||||
else
|
||||
uses -= BLOOD_SPEAR_COST
|
||||
var/turf/T = get_turf(user)
|
||||
qdel(src)
|
||||
var/datum/action/innate/cult/spear/S = new(user)
|
||||
var/obj/item/twohanded/cult_spear/rite = new(T)
|
||||
S.Grant(user, rite)
|
||||
rite.spear_act = S
|
||||
if(user.put_in_hands(rite))
|
||||
to_chat(user, "<span class='cult'>A [rite.name] appears in your hand!</span>")
|
||||
else
|
||||
user.visible_message("<span class='warning'>A [rite.name] appears at [user]'s feet!</span>",
|
||||
"<span class='cult'>A [rite.name] materializes at your feet.</span>")
|
||||
|
||||
if("Blood Bolt Barrage (300)")
|
||||
if(uses < BLOOD_BARRAGE_COST)
|
||||
to_chat(user, "<span class='cultitalic'>You need [BLOOD_BARRAGE_COST] charges to perform this rite.</span>")
|
||||
else
|
||||
var/obj/rite = new /obj/item/gun/projectile/shotgun/boltaction/enchanted/arcane_barrage/blood()
|
||||
uses -= BLOOD_BARRAGE_COST
|
||||
qdel(src)
|
||||
user.swap_hand()
|
||||
user.drop_item()
|
||||
if(user.put_in_hands(rite))
|
||||
to_chat(user, "<span class='cult'>Both of your hands glow with power!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need a free hand for this rite!</span>")
|
||||
uses += BLOOD_BARRAGE_COST // Refund the charges
|
||||
qdel(rite)
|
||||
|
||||
@@ -85,6 +85,9 @@ GLOBAL_LIST_EMPTY(all_cults)
|
||||
to_chat(cult_mind.current, CULT_GREETING)
|
||||
equip_cultist(cult_mind.current)
|
||||
cult_mind.current.faction |= "cult"
|
||||
var/datum/objective/servecult/obj = new
|
||||
obj.owner = cult_mind
|
||||
cult_mind.objectives += obj
|
||||
|
||||
if(cult_mind.assigned_role == "Clown")
|
||||
to_chat(cult_mind.current, "<span class='cultitalic'>A dark power has allowed you to overcome your clownish nature, letting you wield weapons without harming yourself.</span>")
|
||||
@@ -96,54 +99,11 @@ GLOBAL_LIST_EMPTY(all_cults)
|
||||
add_cult_actions(cult_mind)
|
||||
update_cult_icons_added(cult_mind)
|
||||
cult_objs.study(cult_mind.current)
|
||||
to_chat(cult_mind.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Cultist)</span>")
|
||||
cult_threshold_check()
|
||||
addtimer(CALLBACK(src, .proc/cult_threshold_check), 2 MINUTES) // Check again in 2 minutes for latejoiners
|
||||
..()
|
||||
|
||||
/**
|
||||
* Decides at the start of the round how many conversions are needed to rise/ascend.
|
||||
*
|
||||
* The number is decided by (Percentage * (Players - Cultists)), so for example at 110 players it would be 11 conversions for rise. (0.1 * (110 - 4))
|
||||
* These values change based on population because 20 cultists are MUCH more powerful if there's only 50 players, compared to 120.
|
||||
*
|
||||
* Below 100 players, [CULT_RISEN_LOW] and [CULT_ASCENDANT_LOW] are used.
|
||||
* Above 100 players, [CULT_RISEN_HIGH] and [CULT_ASCENDANT_HIGH] are used.
|
||||
*/
|
||||
/datum/game_mode/proc/cult_threshold_check()
|
||||
var/players = length(GLOB.player_list)
|
||||
var/cultists = get_cultists() // Don't count the starting cultists towards the number of needed conversions
|
||||
if(players >= CULT_POPULATION_THRESHOLD)
|
||||
// Highpop
|
||||
ascend_percent = CULT_ASCENDANT_HIGH
|
||||
rise_number = round(CULT_RISEN_HIGH * (players - cultists))
|
||||
ascend_number = round(CULT_ASCENDANT_HIGH * (players - cultists))
|
||||
else
|
||||
// Lowpop
|
||||
ascend_percent = CULT_ASCENDANT_LOW
|
||||
rise_number = round(CULT_RISEN_LOW * (players - cultists))
|
||||
ascend_number = round(CULT_ASCENDANT_LOW * (players - cultists))
|
||||
|
||||
/**
|
||||
* Returns the current number of cultists and constructs.
|
||||
*
|
||||
* Returns the number of cultists and constructs in a list ([1] = Cultists, [2] = Constructs), or as one combined number.
|
||||
*
|
||||
* * separate - Should the number be returned in two separate values (Humans and Constructs) or as one?
|
||||
*/
|
||||
/datum/game_mode/proc/get_cultists(separate = FALSE)
|
||||
var/cultists = 0
|
||||
var/constructs = 0
|
||||
for(var/I in cult)
|
||||
var/datum/mind/M = I
|
||||
if(ishuman(M.current) && !M.current.has_status_effect(STATUS_EFFECT_SUMMONEDGHOST))
|
||||
cultists++
|
||||
else if(isconstruct(M.current))
|
||||
constructs++
|
||||
if(separate)
|
||||
return list(cultists, constructs)
|
||||
else
|
||||
return cultists + constructs
|
||||
|
||||
/datum/game_mode/proc/equip_cultist(mob/living/carbon/human/H, metal = TRUE)
|
||||
if(!istype(H))
|
||||
return
|
||||
@@ -207,8 +167,84 @@ GLOBAL_LIST_EMPTY(all_cults)
|
||||
ascend(cult_mind.current)
|
||||
check_cult_size()
|
||||
cult_objs.study(cult_mind.current)
|
||||
to_chat(cult_mind.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Cultist)</span>")
|
||||
return TRUE
|
||||
|
||||
/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = TRUE, remove_gear = FALSE)
|
||||
if(!(cult_mind in cult)) // Not actually a cultist in the first place
|
||||
return
|
||||
|
||||
var/mob/cultist = cult_mind.current
|
||||
cult -= cult_mind
|
||||
cultist.faction -= "cult"
|
||||
cult_mind.special_role = null
|
||||
for(var/datum/objective/servecult/S in cult_mind.objectives)
|
||||
cult_mind.objectives -= S
|
||||
qdel(S)
|
||||
for(var/datum/action/innate/cult/C in cultist.actions)
|
||||
qdel(C)
|
||||
update_cult_icons_removed(cult_mind)
|
||||
|
||||
if(ishuman(cultist))
|
||||
var/mob/living/carbon/human/H = cultist
|
||||
REMOVE_TRAIT(H, CULT_EYES, null)
|
||||
H.change_eye_color(H.original_eye_color, FALSE)
|
||||
H.update_eyes()
|
||||
H.remove_overlay(HALO_LAYER)
|
||||
H.update_body()
|
||||
if(remove_gear) // No flagellants robe for non-cultists
|
||||
for(var/I in H.contents)
|
||||
if(is_type_in_list(I, CULT_CLOTHING))
|
||||
H.unEquip(I)
|
||||
check_cult_size()
|
||||
if(show_message)
|
||||
cultist.visible_message("<span class='cult'>[cultist] looks like [cultist.p_they()] just reverted to [cultist.p_their()] old faith!</span>",
|
||||
"<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of [SSticker.cultdat ? SSticker.cultdat.entity_title1 : "Nar'Sie"] and the memories of your time as their servant with it.</span>")
|
||||
|
||||
|
||||
/**
|
||||
* Decides at the start of the round how many conversions are needed to rise/ascend.
|
||||
*
|
||||
* The number is decided by (Percentage * (Players - Cultists)), so for example at 110 players it would be 11 conversions for rise. (0.1 * (110 - 4))
|
||||
* These values change based on population because 20 cultists are MUCH more powerful if there's only 50 players, compared to 120.
|
||||
*
|
||||
* Below 100 players, [CULT_RISEN_LOW] and [CULT_ASCENDANT_LOW] are used.
|
||||
* Above 100 players, [CULT_RISEN_HIGH] and [CULT_ASCENDANT_HIGH] are used.
|
||||
*/
|
||||
/datum/game_mode/proc/cult_threshold_check()
|
||||
var/players = length(GLOB.player_list)
|
||||
var/cultists = get_cultists() // Don't count the starting cultists towards the number of needed conversions
|
||||
if(players >= CULT_POPULATION_THRESHOLD)
|
||||
// Highpop
|
||||
ascend_percent = CULT_ASCENDANT_HIGH
|
||||
rise_number = round(CULT_RISEN_HIGH * (players - cultists))
|
||||
ascend_number = round(CULT_ASCENDANT_HIGH * (players - cultists))
|
||||
else
|
||||
// Lowpop
|
||||
ascend_percent = CULT_ASCENDANT_LOW
|
||||
rise_number = round(CULT_RISEN_LOW * (players - cultists))
|
||||
ascend_number = round(CULT_ASCENDANT_LOW * (players - cultists))
|
||||
|
||||
/**
|
||||
* Returns the current number of cultists and constructs.
|
||||
*
|
||||
* Returns the number of cultists and constructs in a list ([1] = Cultists, [2] = Constructs), or as one combined number.
|
||||
*
|
||||
* * separate - Should the number be returned as a list with two separate values (Humans and Constructs) or as one number.
|
||||
*/
|
||||
/datum/game_mode/proc/get_cultists(separate = FALSE)
|
||||
var/cultists = 0
|
||||
var/constructs = 0
|
||||
for(var/I in cult)
|
||||
var/datum/mind/M = I
|
||||
if(ishuman(M.current) && !M.current.has_status_effect(STATUS_EFFECT_SUMMONEDGHOST))
|
||||
cultists++
|
||||
else if(isconstruct(M.current))
|
||||
constructs++
|
||||
if(separate)
|
||||
return list(cultists, constructs)
|
||||
else
|
||||
return cultists + constructs
|
||||
|
||||
/datum/game_mode/proc/check_cult_size()
|
||||
if(cult_ascendant)
|
||||
@@ -238,6 +274,8 @@ GLOBAL_LIST_EMPTY(all_cults)
|
||||
/datum/game_mode/proc/rise(cultist)
|
||||
if(ishuman(cultist) && iscultist(cultist))
|
||||
var/mob/living/carbon/human/H = cultist
|
||||
if(!H.original_eye_color)
|
||||
H.original_eye_color = H.get_eye_color()
|
||||
H.change_eye_color(BLOODCULT_EYE, FALSE)
|
||||
H.update_eyes()
|
||||
ADD_TRAIT(H, CULT_EYES, CULT_TRAIT)
|
||||
@@ -249,29 +287,6 @@ GLOBAL_LIST_EMPTY(all_cults)
|
||||
new /obj/effect/temp_visual/cult/sparks(get_turf(H), H.dir)
|
||||
H.update_halo_layer()
|
||||
|
||||
|
||||
/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = TRUE)
|
||||
if(cult_mind in cult)
|
||||
var/mob/cultist = cult_mind.current
|
||||
cult -= cult_mind
|
||||
cultist.faction -= "cult"
|
||||
cult_mind.special_role = null
|
||||
for(var/datum/action/innate/cult/C in cultist.actions)
|
||||
qdel(C)
|
||||
update_cult_icons_removed(cult_mind)
|
||||
|
||||
if(ishuman(cultist))
|
||||
var/mob/living/carbon/human/H = cultist
|
||||
REMOVE_TRAIT(H, CULT_EYES, null)
|
||||
H.change_eye_color(H.original_eye_color, FALSE)
|
||||
H.update_eyes()
|
||||
H.remove_overlay(HALO_LAYER)
|
||||
H.update_body()
|
||||
check_cult_size()
|
||||
if(show_message)
|
||||
cultist.visible_message("<span class='cult'>[cultist] looks like [cultist.p_they()] just reverted to [cultist.p_their()] old faith!</span>",
|
||||
"<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of [SSticker.cultdat ? SSticker.cultdat.entity_title1 : "Nar'Sie"] and the memories of your time as their servant with it.</span>")
|
||||
|
||||
/datum/game_mode/proc/update_cult_icons_added(datum/mind/cult_mind)
|
||||
var/datum/atom_hud/antag/culthud = GLOB.huds[ANTAG_HUD_CULT]
|
||||
if(cult_mind.current)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user