mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-21 15:42:35 +00:00
Merge branch 'Aurorastation/development' into Map-Development
# Conflicts: # code/TriDimension/controller_presets.dm # code/game/objects/structures/crates_lockers/closets/secure/security.dm # code/game/objects/structures/crates_lockers/closets/wardrobe.dm # code/game/objects/structures/signs.dm # code/game/turfs/simulated/floor_types.dm # code/modules/random_map/mining_distribution.dm # code/modules/random_map/random_map.dm # code/world.dm # icons/obj/barsigns.dmi # icons/obj/decals.dmi # icons/obj/plants.dmi # icons/obj/structures.dmi # icons/turf/floors.dmi # icons/turf/wall_masks.dmi # maps/exodus-2.dmm
This commit is contained in:
114
.github/CONTRIBUTING.md
vendored
Normal file
114
.github/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
# Licensing
|
||||
Aurora Station is licensed under the GNU Affero General Public License version 3, which can be found in full in LICENSE-AGPL3.txt.
|
||||
|
||||
Commits with a git authorship date prior to `1420675200 +0000` (2015/01/08 00:00) are licensed under the GNU General Public License version 3, which can be found in full in LICENSE-GPL3.txt.
|
||||
|
||||
All commits whose authorship dates are not prior to `1420675200 +0000` are assumed to be licensed under AGPL v3, if you wish to license under GPL v3 please make this clear in the commit message and any added files.
|
||||
|
||||
# Coding Standards
|
||||
|
||||
### Absoloute Pathing
|
||||
Absoloute pathing has to be used for type, proc, and verb definitions. This is to make searching and reading easier.
|
||||
|
||||
An example of properly pathed code:
|
||||
```
|
||||
/obj/item/device/cake
|
||||
[cake code here]
|
||||
|
||||
/obj/item/device/cake/proc/eat_cake()
|
||||
[proc code here]
|
||||
```
|
||||
|
||||
An example of badly pathed code:
|
||||
```
|
||||
/obj/item/device/cake
|
||||
[cake code here]
|
||||
|
||||
proc/eat_cake()
|
||||
[proc code here]
|
||||
```
|
||||
|
||||
### qdel() and Destroy() usage
|
||||
All objects with an applicable type need to be deleted by `qdel()`, as opposed to the regular `del()` proc. While conducting this action, make sure you remove all possible references to the object you assign for deletion *after* calling `qdel()`. This will enable the ProcessScheduler controller garbage collector to handle the objects assigned to it at its own pace, thus reducing lag in the long run.
|
||||
|
||||
An example of how to use `qdel()`:
|
||||
```
|
||||
/obj/item/plate
|
||||
var/obj/item/cake/cake
|
||||
|
||||
/obj/item/plate/New()
|
||||
cake = New()
|
||||
|
||||
// Eat the cake and destroy the cake object.
|
||||
/obj/item/plate/proc/eat_cake()
|
||||
qdel(cake) // Call qdel()
|
||||
cake = null // Set local reference to null to assist the GC.
|
||||
```
|
||||
|
||||
The `Destroy()` proc for objects should be defined, if there are any special operations that need to be conducted when an object is assigned for destruction with `qdel()`. Normally, it would set all object references that that specific item may contain to null, and destroy them as necessary. It is important to know that the best case scenario for the garbage collector is this: an object passed to it should not reference, or be referenced by any other ingame object.
|
||||
|
||||
Note that any modified `Destroy()` proc **must always return the original definition (`return ..()`) call!**
|
||||
|
||||
An example of how to define `Destroy()` for an item that needs it:
|
||||
```
|
||||
/obj/item/plate
|
||||
var/obj/item/cake/cake
|
||||
|
||||
/obj/item/plate/New()
|
||||
cake = New()
|
||||
|
||||
/obj/item/plate/Destroy()
|
||||
if (src.cake) // We potentially have a reference.
|
||||
qdel(cake) // Delete the referenced item -- this doesn't always have to be done.
|
||||
cake = null // Set the pointer to null. This is the important bit.
|
||||
// All pointers that the plate item contains are now null. This will speed up the GC.
|
||||
|
||||
return ..() // Return the original definition of the proc.
|
||||
```
|
||||
|
||||
`qdel()` is **not** capable of handling the following types of objects:
|
||||
* file
|
||||
* savefile
|
||||
* SQLLite object
|
||||
* Client object
|
||||
* list objects.
|
||||
|
||||
You will have to use the regular `del()` proc to delete any object of that type.
|
||||
|
||||
### HTML styling for user output
|
||||
All text output to the user, specially if the output operator `<<` is used, should be formatted in proper HTML. DM text macros for styling, such as `\red` and `\blue`, are no longer to be used actively. This will enable the modification of used HTML styling later down the line, via the centralized .css files. It will also enable a switch from an output panel, to other output methods.
|
||||
|
||||
For reference, here are the standard span classes for user output, and the correlation between them and the DM text macros:
|
||||
* `<span class="danger"></span>` corresponds to `\red` and is bold.
|
||||
* `<span class="warning"></span>` also corresponds to `\red` and is not bold.
|
||||
* `<span class="notice"></span>` corresponds to `\blue` and is not bold.
|
||||
|
||||
There exist pre-processor macros for using these spans. `span(class, text)` which is the equivilant of typing a string that looks like this: `"<span class='[class]'>[text]</span>"`.
|
||||
|
||||
The stylesheet available for use within DM can be found in `code/stylesheet.dm`.
|
||||
|
||||
### Usage of forceMove
|
||||
In order to make `Exited()` and `Entered()` procs more reliable, the usage of `forceMove()` when forcibly moving one item to another location, be it another item or turf, is required. Directly changing an item's loc values will skip over calls to the aforementioned procs, thus making them less useful and more unreliable.
|
||||
|
||||
An example of improper item moving:
|
||||
```
|
||||
/proc/some_proc(var/obj/A, var/obj/B)
|
||||
A.loc = B // Simply move A inside B.
|
||||
```
|
||||
|
||||
An example of proper item moving:
|
||||
```
|
||||
/proc/some_proc(var/obj/A, var/obj/B)
|
||||
A.forceMove(B) // This will call A.loc.Exited() and B.Entered().
|
||||
// The first method does not call either of those.
|
||||
```
|
||||
|
||||
### Database prefixing
|
||||
All tables for the database should be prefixed according to the following list:
|
||||
* `ss13_` for tables in which ingame data is held.
|
||||
* `discord_` for tables in which BOREALIS data is held.
|
||||
|
||||
### Regarding the variable usr
|
||||
`usr` should never be defined as a name for a custom variable. It is the name for a specific variable which exists for every proc, though it may not always have a value.
|
||||
|
||||
If at all possible, procs outside of verbs and `Topic()` should avoid reliance on `usr`, and instead use a custom argument to specify the user and its expected type. This makes it easier to reuse procs in chains where `usr` is not always defined.
|
||||
5
.github/ISSUE_TEMPLATE.md
vendored
Normal file
5
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
Checklist before you submit an issue! Feel free to partially or fully delete this in your eventual report.
|
||||
* Do a quick key word search of the git for duplicate reports. If you find any, simply post a reply onto that issue instead!
|
||||
* Please be specific in your description of the issue. Explain the desired result (what should be happening) and the actual result (what is happening). Simply stating that [something happens] is not very helpful at describing what's wrong.
|
||||
* Have you tried reproducing the issue? If yes, steps to reproduce it would help immensely!
|
||||
* All additional details help. Such as round ID, an admin you talked to if the issue required immediate fixing, etcetera, etcetera.
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
* Please describe the intent of your changes in a clear fashion.
|
||||
* Please make sure that, in the case of icon or mapping changes, you include images of these changes in the PR's description.
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -8,5 +8,7 @@ Thumbs.db
|
||||
*.backup
|
||||
data/
|
||||
cfg/
|
||||
build_log.txt
|
||||
|
||||
/.atom-build.json
|
||||
.vscode/
|
||||
|
||||
20
.travis.yml
20
.travis.yml
@@ -1,10 +1,10 @@
|
||||
#pretending we're C because otherwise ruby will initialize, even with "language: dm".
|
||||
language: c
|
||||
language: generic
|
||||
sudo: false
|
||||
|
||||
env:
|
||||
BYOND_MAJOR="510"
|
||||
BYOND_MINOR="1346"
|
||||
MACRO_COUNT=1156
|
||||
|
||||
cache:
|
||||
directories:
|
||||
@@ -16,8 +16,6 @@ addons:
|
||||
- libc6-i386
|
||||
- libgcc1:i386
|
||||
- libstdc++6:i386
|
||||
- python
|
||||
- python-pip
|
||||
|
||||
install:
|
||||
- pip install --user PyYaml -q
|
||||
@@ -31,8 +29,18 @@ script:
|
||||
- shopt -s globstar
|
||||
- (! grep 'step_[xy]' maps/**/*.dmm)
|
||||
- (! find nano/templates/ -type f -exec md5sum {} + | sort | uniq -D -w 32 | grep nano)
|
||||
- (! grep -E "<\s*span\s+class\s*=\s*('[^'>]+|[^'>]+')\s*>" **/*.dm)
|
||||
- (num=`grep -E '\\\\(red|blue|green|black|b|i[^mc])' **/*.dm | wc -l`; echo "$num escapes (expecting ${MACRO_COUNT} or less)"; [ $num -le ${MACRO_COUNT} ])
|
||||
- awk -f tools/indentation.awk **/*.dm
|
||||
- md5sum -c - <<< "0af969f671fba6cf9696c78cd175a14a *baystation12.int"
|
||||
- md5sum -c - <<< "88490b460c26947f5ec1ab1bb9fa9f17 *html/changelogs/example.yml"
|
||||
- python tools/GenerateChangelog/ss13_genchangelog.py html/changelog.html html/changelogs
|
||||
- python tools/TagMatcher/tag-matcher.py ../..
|
||||
- python tools/GenerateChangelog/ss13_genchangelog.py html/changelog.html html/changelogs --dry-run
|
||||
- source $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}/byond/bin/byondsetup
|
||||
- DreamMaker baystation12.dme
|
||||
- cp config/example/* config/
|
||||
- scripts/dm.sh -DUNIT_TEST baystation12.dme
|
||||
- grep "0 warnings" build_log.txt
|
||||
- DreamDaemon baystation12.dmb -invisible -trusted -core 2>&1 | tee log.txt
|
||||
- grep "All Unit Tests Passed" log.txt
|
||||
- (! grep "runtime error:" log.txt)
|
||||
- (! grep 'Process scheduler caught exception processing' log.txt)
|
||||
|
||||
BIN
ByondPOST.dll
Normal file
BIN
ByondPOST.dll
Normal file
Binary file not shown.
@@ -1,5 +0,0 @@
|
||||
Baystation12 is licensed under the GNU Affero General Public License version 3, which can be found in full in LICENSE-AGPL3.txt.
|
||||
|
||||
Commits with a git authorship date prior to `1420675200 +0000` (2015/01/08 00:00) are licensed under the GNU General Public License version 3, which can be found in full in LICENSE-GPL3.txt.
|
||||
|
||||
All commits whose authorship dates are not prior to `1420675200 +0000` are assumed to be licensed under AGPL v3, if you wish to license under GPL v3 please make this clear in the commit message and any added files.
|
||||
@@ -19,6 +19,44 @@ CREATE TABLE `ss13_admin_log` (
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `ss13_api_commands` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`command` VARCHAR(50) NOT NULL COLLATE 'utf8_bin',
|
||||
`description` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_bin',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `UNIQUE command` (`command`)
|
||||
)
|
||||
COLLATE='utf8_bin'
|
||||
ENGINE=InnoDB;
|
||||
|
||||
|
||||
CREATE TABLE `ss13_api_tokens` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`token` VARCHAR(100) NOT NULL COLLATE 'utf8_bin',
|
||||
`ip` VARCHAR(16) NULL DEFAULT NULL COLLATE 'utf8_bin',
|
||||
`creator` VARCHAR(50) NOT NULL COLLATE 'utf8_bin',
|
||||
`description` VARCHAR(100) NOT NULL COLLATE 'utf8_bin',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`deleted_at` DATETIME NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
)
|
||||
COLLATE='utf8_bin'
|
||||
ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE `ss13_api_token_command` (
|
||||
`command_id` INT(11) NOT NULL,
|
||||
`token_id` INT(11) NOT NULL,
|
||||
PRIMARY KEY (`command_id`, `token_id`),
|
||||
INDEX `token_id` (`token_id`),
|
||||
CONSTRAINT `function_id` FOREIGN KEY (`command_id`) REFERENCES `ss13_api_commands` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
CONSTRAINT `token_id` FOREIGN KEY (`token_id`) REFERENCES `ss13_api_tokens` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
)
|
||||
COLLATE='utf8_bin'
|
||||
ENGINE=InnoDB;
|
||||
|
||||
|
||||
|
||||
CREATE TABLE `ss13_ban` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`bantime` datetime NOT NULL,
|
||||
@@ -74,41 +112,43 @@ CREATE TABLE `ss13_player` (
|
||||
CREATE TABLE `ss13_characters` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`name` varchar(128) NOT NULL,
|
||||
`metadata` varchar(512) DEFAULT NULL,
|
||||
`random_name` tinyint(1) DEFAULT '0',
|
||||
`gender` varchar(32) DEFAULT NULL,
|
||||
`age` int(11) DEFAULT NULL,
|
||||
`species` varchar(32) DEFAULT NULL,
|
||||
`language` varchar(128) DEFAULT NULL,
|
||||
`hair_colour` varchar(7) DEFAULT NULL,
|
||||
`facial_colour` varchar(7) DEFAULT NULL,
|
||||
`skin_tone` int(11) DEFAULT NULL,
|
||||
`skin_colour` varchar(7) DEFAULT NULL,
|
||||
`hair_style` varchar(32) DEFAULT NULL,
|
||||
`facial_style` varchar(32) DEFAULT NULL,
|
||||
`eyes_colour` varchar(7) DEFAULT NULL,
|
||||
`underwear` varchar(32) DEFAULT NULL,
|
||||
`undershirt` varchar(32) DEFAULT NULL,
|
||||
`backbag` int(11) DEFAULT NULL,
|
||||
`b_type` varchar(32) DEFAULT NULL,
|
||||
`spawnpoint` varchar(32) DEFAULT NULL,
|
||||
`jobs` text,
|
||||
`name` varchar(128) NULL DEFAULT NULL,
|
||||
`metadata` varchar(512) NULL DEFAULT NULL,
|
||||
`be_special_role` text NULL DEFAULT NULL,
|
||||
`gender` varchar(32) NULL DEFAULT NULL,
|
||||
`age` int(11) NULL DEFAULT NULL,
|
||||
`species` varchar(32) NULL DEFAULT NULL,
|
||||
`language` text NULL DEFAULT NULL,
|
||||
`hair_colour` varchar(7) NULL DEFAULT NULL,
|
||||
`facial_colour` varchar(7) NULL DEFAULT NULL,
|
||||
`skin_tone` int(11) NULL DEFAULT NULL,
|
||||
`skin_colour` varchar(7) NULL DEFAULT NULL,
|
||||
`hair_style` varchar(32) NULL DEFAULT NULL,
|
||||
`facial_style` varchar(32) NULL DEFAULT NULL,
|
||||
`eyes_colour` varchar(7) NULL DEFAULT NULL,
|
||||
`underwear` varchar(32) NULL DEFAULT NULL,
|
||||
`undershirt` varchar(32) NULL DEFAULT NULL,
|
||||
`socks` varchar(32) NULL DEFAULT NULL,
|
||||
`backbag` int(11) NULL DEFAULT NULL,
|
||||
`b_type` varchar(32) NULL DEFAULT NULL,
|
||||
`spawnpoint` varchar(32) NULL DEFAULT NULL,
|
||||
`jobs` text NULL DEFAULT NULL,
|
||||
`alternate_option` tinyint(1) DEFAULT NULL,
|
||||
`alternate_titles` text,
|
||||
`alternate_titles` text NULL DEFAULT NULL,
|
||||
`disabilities` int(11) DEFAULT '0',
|
||||
`skills` text,
|
||||
`skills_specialization` text,
|
||||
`home_system` text,
|
||||
`citizenship` text,
|
||||
`faction` text,
|
||||
`religion` text,
|
||||
`nt_relation` text,
|
||||
`uplink_location` text,
|
||||
`organs_data` text,
|
||||
`organs_robotic` text,
|
||||
`gear` text,
|
||||
`deleted_at` datetime DEFAULT NULL,
|
||||
`skills` text NULL DEFAULT NULL,
|
||||
`skill_specialization` text NULL DEFAULT NULL,
|
||||
`home_system` text NULL DEFAULT NULL,
|
||||
`citizenship` text NULL DEFAULT NULL,
|
||||
`faction` text NULL DEFAULT NULL,
|
||||
`religion` text NULL DEFAULT NULL,
|
||||
`nt_relation` text NULL DEFAULT NULL,
|
||||
`uplink_location` text NULL DEFAULT NULL,
|
||||
`organs_data` text NULL DEFAULT NULL,
|
||||
`organs_robotic` text NULL DEFAULT NULL,
|
||||
`gear` text NULL DEFAULT NULL,
|
||||
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`deleted_at` datetime NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ss13_characters_ckey` (`ckey`),
|
||||
KEY `ss13_characteres_name` (`name`),
|
||||
@@ -117,36 +157,47 @@ CREATE TABLE `ss13_characters` (
|
||||
|
||||
CREATE TABLE `ss13_characters_flavour` (
|
||||
`char_id` int(11) NOT NULL,
|
||||
`records_employment` text,
|
||||
`records_medical` text,
|
||||
`records_security` text,
|
||||
`records_exploit` text,
|
||||
`records_ccia` text,
|
||||
`flavour_general` text,
|
||||
`flavour_head` text,
|
||||
`flavour_face` text,
|
||||
`flavour_eyes` text,
|
||||
`flavour_torso` text,
|
||||
`flavour_arms` text,
|
||||
`flavour_hands` text,
|
||||
`flavour_legs` text,
|
||||
`flavour_feet` text,
|
||||
`robot_default` text,
|
||||
`robot_standard` text,
|
||||
`robot_engineering` text,
|
||||
`robot_construction` text,
|
||||
`robot_surgeon` text,
|
||||
`robot_crisis` text,
|
||||
`robot_miner` text,
|
||||
`robot_janitor` text,
|
||||
`robot_service` text,
|
||||
`robot_clerical` text,
|
||||
`robot_security` text,
|
||||
`robot_research` text,
|
||||
`records_employment` text NULL DEFAULT NULL,
|
||||
`records_medical` text NULL DEFAULT NULL,
|
||||
`records_security` text NULL DEFAULT NULL,
|
||||
`records_exploit` text NULL DEFAULT NULL,
|
||||
`records_ccia` text NULL DEFAULT NULL,
|
||||
`flavour_general` text NULL DEFAULT NULL,
|
||||
`flavour_head` text NULL DEFAULT NULL,
|
||||
`flavour_face` text NULL DEFAULT NULL,
|
||||
`flavour_eyes` text NULL DEFAULT NULL,
|
||||
`flavour_torso` text NULL DEFAULT NULL,
|
||||
`flavour_arms` text NULL DEFAULT NULL,
|
||||
`flavour_hands` text NULL DEFAULT NULL,
|
||||
`flavour_legs` text NULL DEFAULT NULL,
|
||||
`flavour_feet` text NULL DEFAULT NULL,
|
||||
`robot_default` text NULL DEFAULT NULL,
|
||||
`robot_standard` text NULL DEFAULT NULL,
|
||||
`robot_engineering` text NULL DEFAULT NULL,
|
||||
`robot_construction` text NULL DEFAULT NULL,
|
||||
`robot_medical` text NULL DEFAULT NULL,
|
||||
`robot_rescue` text NULL DEFAULT NULL,
|
||||
`robot_miner` text NULL DEFAULT NULL,
|
||||
`robot_custodial` text NULL DEFAULT NULL,
|
||||
`robot_service` text NULL DEFAULT NULL,
|
||||
`robot_clerical` text NULL DEFAULT NULL,
|
||||
`robot_security` text NULL DEFAULT NULL,
|
||||
`robot_research` text NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`char_id`),
|
||||
CONSTRAINT `ss13_flavour_fk_char_id` FOREIGN KEY (`char_id`) REFERENCES `ss13_characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
|
||||
|
||||
CREATE TABLE `ss13_characters_log` (
|
||||
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`char_id` INT(11) NOT NULL,
|
||||
`game_id` VARCHAR(50) NOT NULL,
|
||||
`datetime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`job_name` VARCHAR(32) NOT NULL,
|
||||
`special_role` VARCHAR(32) NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `ss13_charlog_fk_char_id` FOREIGN KEY (`char_id`) REFERENCES `ss13_characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `ss13_connection_log` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
@@ -213,7 +264,7 @@ CREATE TABLE `ss13_directives` (
|
||||
CREATE TABLE `ss13_feedback` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`time` datetime NOT NULL,
|
||||
`round_id` int(8) NOT NULL,
|
||||
`game_id` varchar(32) NOT NULL,
|
||||
`var_name` varchar(32) CHARACTER SET latin1 NOT NULL,
|
||||
`var_value` int(16) DEFAULT NULL,
|
||||
`details` text CHARACTER SET latin1,
|
||||
@@ -287,17 +338,17 @@ CREATE TABLE `ss13_player_linking` (
|
||||
|
||||
CREATE TABLE `ss13_player_preferences` (
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`ooccolor` text NOT NULL,
|
||||
`lastchangelog` text NOT NULL,
|
||||
`UI_style` text NOT NULL,
|
||||
`current_character` int(11) NOT NULL,
|
||||
`toggles` int(11) NOT NULL,
|
||||
`UI_style_color` text NOT NULL,
|
||||
`UI_style_alpha` int(11) NOT NULL,
|
||||
`be_special` int(11) NOT NULL,
|
||||
`asfx_togs` int(11) NOT NULL,
|
||||
`lastmotd` text NOT NULL,
|
||||
`lastmemo` text NOT NULL,
|
||||
`ooccolor` text NULL DEFAULT NULL,
|
||||
`lastchangelog` text NULL DEFAULT NULL,
|
||||
`UI_style` text NULL DEFAULT NULL,
|
||||
`current_character` int(11) NULL DEFAULT NULL,
|
||||
`toggles` int(11) DEFAULT '0',
|
||||
`UI_style_color` text NULL DEFAULT NULL,
|
||||
`UI_style_alpha` int(11) NULL DEFAULT '255',
|
||||
`asfx_togs` int(11) DEFAULT '0',
|
||||
`lastmotd` text NULL DEFAULT NULL,
|
||||
`lastmemo` text NULL DEFAULT NULL,
|
||||
`language_prefixes` text NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`ckey`),
|
||||
CONSTRAINT `player_preferences_fk_ckey` FOREIGN KEY (`ckey`) REFERENCES `ss13_player` (`ckey`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
@@ -446,5 +497,90 @@ CREATE TABLE `ss13_whitelist_log` (
|
||||
CREATE TABLE `ss13_whitelist_statuses` (
|
||||
`flag` int(10) unsigned NOT NULL,
|
||||
`status_name` varchar(32) NOT NULL,
|
||||
`subspecies` tinyint(4) NOT NULL DEFAULT '1',
|
||||
PRIMARY KEY (`status_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE `ss13_stats_ie` (
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`IsIE` tinyint(4) NOT NULL,
|
||||
`IsEdge` tinyint(4) NOT NULL,
|
||||
`EdgeHtmlVersion` int(11) NOT NULL,
|
||||
`TrueVersion` tinyint(4) NOT NULL,
|
||||
`ActingVersion` tinyint(4) NOT NULL,
|
||||
`CompatibilityMode` tinyint(4) NOT NULL,
|
||||
`DateUpdated` datetime DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`ckey`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `ss13_character_incidents` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`char_id` INT(11) NOT NULL,
|
||||
`UID` VARCHAR(32) NOT NULL COLLATE 'utf8_bin',
|
||||
`datetime` VARCHAR(50) NOT NULL COLLATE 'utf8_bin',
|
||||
`notes` TEXT NOT NULL COLLATE 'utf8_bin',
|
||||
`charges` TEXT NOT NULL COLLATE 'utf8_bin',
|
||||
`evidence` TEXT NOT NULL COLLATE 'utf8_bin',
|
||||
`arbiters` TEXT NOT NULL COLLATE 'utf8_bin',
|
||||
`brig_sentence` INT(11) NOT NULL DEFAULT '0',
|
||||
`fine` INT(11) NOT NULL DEFAULT '0',
|
||||
`felony` INT(11) NOT NULL DEFAULT '0',
|
||||
`created_by` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_bin',
|
||||
`deleted_by` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_bin',
|
||||
`game_id` VARCHAR(50) NOT NULL COLLATE 'utf8_bin',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`deleted_at` DATETIME NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `UID_char_id` (`char_id`, `UID`)
|
||||
) COLLATE='utf8_bin' ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE `discord_channels` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`channel_group` varchar(32) NOT NULL,
|
||||
`channel_id` text NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `ss13_ccia_actions` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`title` text COLLATE utf8_unicode_ci NOT NULL,
|
||||
`type` enum('injunction','suspension','warning','other') COLLATE utf8_unicode_ci NOT NULL,
|
||||
`issuedby` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`details` text COLLATE utf8_unicode_ci NOT NULL,
|
||||
`url` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`expires_at` date DEFAULT NULL,
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
CREATE TABLE `ss13_ccia_action_char` (
|
||||
`action_id` int(10) unsigned NOT NULL,
|
||||
`char_id` int(11) NOT NULL,
|
||||
PRIMARY KEY (`action_id`,`char_id`),
|
||||
KEY `ccia_action_char_char_id_foreign` (`char_id`),
|
||||
CONSTRAINT `ccia_action_char_action_id_foreign` FOREIGN KEY (`action_id`) REFERENCES `ss13_ccia_actions` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `ccia_action_char_char_id_foreign` FOREIGN KEY (`char_id`) REFERENCES `ss13_characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
CREATE TABLE `ss13_ccia_general_notice_list` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`message` text COLLATE utf8_unicode_ci NOT NULL,
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
CREATE TABLE `ss13_player_pai` (
|
||||
`ckey` VARCHAR(32) NOT NULL,
|
||||
`name` VARCHAR(50) NULL DEFAULT NULL,
|
||||
`description` TEXT NULL DEFAULT NULL,
|
||||
`role` TEXT NULL DEFAULT NULL,
|
||||
`comments` TEXT NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`ckey`),
|
||||
CONSTRAINT `player_pai_fk_ckey` FOREIGN KEY (`ckey`) REFERENCES `ss13_player` (`ckey`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
494
baystation12.dme
494
baystation12.dme
File diff suppressed because it is too large
Load Diff
@@ -12,14 +12,14 @@
|
||||
#define PIPE_COLOR_CYAN "#00ffff"
|
||||
#define PIPE_COLOR_GREEN "#00ff00"
|
||||
#define PIPE_COLOR_YELLOW "#ffcc00"
|
||||
#define PIPE_COLOR_PURPLE "#5c1ec0"
|
||||
#define PIPE_COLOR_BLACK "#444444"
|
||||
|
||||
#define CONNECT_TYPE_REGULAR 1
|
||||
#define CONNECT_TYPE_SUPPLY 2
|
||||
#define CONNECT_TYPE_SCRUBBER 4
|
||||
#define CONNECT_TYPE_HE 8
|
||||
|
||||
var/global/list/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)
|
||||
var/global/list/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, "black" = PIPE_COLOR_BLACK)
|
||||
|
||||
/proc/pipe_color_lookup(var/color)
|
||||
for(var/C in pipe_colors)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
/obj/machinery/atmospherics/var/debug = 0
|
||||
|
||||
/client/proc/atmos_toggle_debug(var/obj/machinery/atmospherics/M in view())
|
||||
/client/proc/atmos_toggle_debug(var/obj/machinery/atmospherics/M in range(world.view))
|
||||
set name = "Toggle Debug Messages"
|
||||
set category = "Debug"
|
||||
M.debug = !M.debug
|
||||
|
||||
@@ -29,6 +29,8 @@ Pipelines + Other Objects -> Pipe network
|
||||
var/pipe_color
|
||||
|
||||
var/global/datum/pipe_icon_manager/icon_manager
|
||||
var/obj/machinery/atmospherics/node1
|
||||
var/obj/machinery/atmospherics/node2
|
||||
|
||||
/obj/machinery/atmospherics/New()
|
||||
if(!icon_manager)
|
||||
@@ -49,7 +51,7 @@ Pipelines + Other Objects -> Pipe network
|
||||
|
||||
/obj/machinery/atmospherics/proc/add_underlay(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type)
|
||||
if(node)
|
||||
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
if(!T.is_plating() && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
//underlays += icon_manager.get_atmos_icon("underlay_down", direction, color_cache_name(node))
|
||||
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
|
||||
else
|
||||
|
||||
@@ -6,9 +6,6 @@ obj/machinery/atmospherics/binary
|
||||
var/datum/gas_mixture/air1
|
||||
var/datum/gas_mixture/air2
|
||||
|
||||
var/obj/machinery/atmospherics/node1
|
||||
var/obj/machinery/atmospherics/node2
|
||||
|
||||
var/datum/pipe_network/network1
|
||||
var/datum/pipe_network/network2
|
||||
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#define PRESSURE_CHECK_INPUT 2
|
||||
#define PRESSURE_CHECK_OUTPUT 4
|
||||
|
||||
#undefine
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump
|
||||
icon = 'icons/atmos/vent_pump.dmi'
|
||||
icon_state = "map_dp_vent"
|
||||
@@ -69,7 +67,7 @@
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
if(T.intact && node1 && node2 && node1.level == 1 && node2.level == 1 && istype(node1, /obj/machinery/atmospherics/pipe) && istype(node2, /obj/machinery/atmospherics/pipe))
|
||||
if(!T.is_plating() && node1 && node2 && node1.level == 1 && node2.level == 1 && istype(node1, /obj/machinery/atmospherics/pipe) && istype(node2, /obj/machinery/atmospherics/pipe))
|
||||
vent_icon += "h"
|
||||
|
||||
if(!powered())
|
||||
@@ -85,7 +83,7 @@
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(T.intact && node1 && node2 && node1.level == 1 && node2.level == 1 && istype(node1, /obj/machinery/atmospherics/pipe) && istype(node2, /obj/machinery/atmospherics/pipe))
|
||||
if(!T.is_plating() && node1 && node2 && node1.level == 1 && node2.level == 1 && istype(node1, /obj/machinery/atmospherics/pipe) && istype(node2, /obj/machinery/atmospherics/pipe))
|
||||
return
|
||||
else
|
||||
if (node1)
|
||||
@@ -259,3 +257,13 @@
|
||||
spawn(2)
|
||||
broadcast_status()
|
||||
update_icon()
|
||||
|
||||
#undef DEFAULT_PRESSURE_DELTA
|
||||
|
||||
#undef EXTERNAL_PRESSURE_BOUND
|
||||
#undef INTERNAL_PRESSURE_BOUND
|
||||
#undef PRESSURE_CHECKS
|
||||
|
||||
#undef PRESSURE_CHECK_EXTERNAL
|
||||
#undef PRESSURE_CHECK_INPUT
|
||||
#undef PRESSURE_CHECK_OUTPUT
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
#define REGULATE_INPUT 1 //shuts off when input side is below the target pressure
|
||||
#define REGULATE_OUTPUT 2 //shuts off when output side is above the target pressure
|
||||
|
||||
#undefine
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate
|
||||
icon = 'icons/atmos/passive_gate.dmi'
|
||||
icon_state = "map"
|
||||
@@ -13,7 +11,7 @@
|
||||
desc = "A one-way air valve that can be used to regulate input or output pressure, and flow rate. Does not require power."
|
||||
|
||||
use_power = 0
|
||||
|
||||
interact_offline = 1
|
||||
var/unlocked = 0 //If 0, then the valve is locked closed, otherwise it is open(-able, it's a one-way valve so it closes if gas would flow backwards).
|
||||
var/target_pressure = ONE_ATMOSPHERE
|
||||
var/max_pressure_setting = 15000 //kPa
|
||||
@@ -168,7 +166,7 @@
|
||||
return
|
||||
src.add_fingerprint(usr)
|
||||
if(!src.allowed(user))
|
||||
user << "\red Access denied."
|
||||
user << "<span class='warning'>Access denied.</span>"
|
||||
return
|
||||
usr.set_machine(src)
|
||||
ui_interact(user)
|
||||
@@ -189,7 +187,7 @@
|
||||
"output_pressure" = round(air2.return_pressure()*100),
|
||||
"regulate_mode" = regulate_mode,
|
||||
"set_flow_rate" = round(set_flow_rate*10),
|
||||
"last_flow_rate" = round(last_flow_rate*10),
|
||||
"last_flow_rate" = round(last_flow_rate*10)
|
||||
)
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
@@ -242,20 +240,24 @@
|
||||
if (!istype(W, /obj/item/weapon/wrench))
|
||||
return ..()
|
||||
if (unlocked)
|
||||
user << "\red You cannot unwrench this [src], turn it off first."
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], turn it off first.</span>"
|
||||
return 1
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], it too exerted due to internal pressure.</span>"
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "\blue You begin to unfasten \the [src]..."
|
||||
user << "<span class='notice'>You begin to unfasten \the [src]...</span>"
|
||||
if (do_after(user, 40))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"\blue You have unfastened \the [src].", \
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
|
||||
#undef REGULATE_NONE
|
||||
#undef REGULATE_INPUT
|
||||
#undef REGULATE_OUTPUT
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
|
||||
var/dP = 0
|
||||
|
||||
var/obj/machinery/atmospherics/node1
|
||||
var/obj/machinery/atmospherics/node2
|
||||
|
||||
var/datum/pipe_network/network1
|
||||
var/datum/pipe_network/network2
|
||||
|
||||
@@ -91,7 +88,7 @@
|
||||
attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/weapon/wrench))
|
||||
anchored = !anchored
|
||||
user << "\blue You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor."
|
||||
user << "<span class='notice'>You [anchored ? "secure" : "unsecure"] the bolts holding \the [src] to the floor.</span>"
|
||||
|
||||
if(anchored)
|
||||
if(dir & (NORTH|SOUTH))
|
||||
@@ -263,7 +260,7 @@
|
||||
if(istype(W, /obj/item/weapon/wrench))
|
||||
anchored = !anchored
|
||||
turbine = null
|
||||
user << "\blue You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor."
|
||||
user << "<span class='notice'>You [anchored ? "secure" : "unsecure"] the bolts holding \the [src] to the floor.</span>"
|
||||
updateConnection()
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -130,7 +130,7 @@ Thus, the two variables affect pump operation are set in New():
|
||||
"max_pressure" = max_pressure_setting,
|
||||
"last_flow_rate" = round(last_flow_rate*10),
|
||||
"last_power_draw" = round(last_power_draw),
|
||||
"max_power_draw" = power_rating,
|
||||
"max_power_draw" = power_rating
|
||||
)
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
@@ -183,7 +183,7 @@ Thus, the two variables affect pump operation are set in New():
|
||||
return
|
||||
src.add_fingerprint(usr)
|
||||
if(!src.allowed(user))
|
||||
user << "\red Access denied."
|
||||
user << "<span class='warning'>Access denied.</span>"
|
||||
return
|
||||
usr.set_machine(src)
|
||||
ui_interact(user)
|
||||
@@ -219,20 +219,20 @@ Thus, the two variables affect pump operation are set in New():
|
||||
if (!istype(W, /obj/item/weapon/wrench))
|
||||
return ..()
|
||||
if (!(stat & NOPOWER) && use_power)
|
||||
user << "\red You cannot unwrench this [src], turn it off first."
|
||||
user << "<span class='warning'>You cannot unwrench this [src], turn it off first.</span>"
|
||||
return 1
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
|
||||
user << "<span class='warning'>You cannot unwrench this [src], it too exerted due to internal pressure.</span>"
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "\blue You begin to unfasten \the [src]..."
|
||||
user << "<span class='notice'>You begin to unfasten \the [src]...</span>"
|
||||
if (do_after(user, 40))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"\blue You have unfastened \the [src].", \
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
|
||||
@@ -87,15 +87,15 @@
|
||||
int_pressure += P.air.return_pressure()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_pressure - env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
user << "<span class='warning'>You cannot unwrench [src], it is too exerted due to internal pressure.</span>"
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], it is too exerted due to internal pressure.</span>"
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
user << "\blue You begin to unfasten \the [src]..."
|
||||
user << "<span class='notice'>You begin to unfasten \the [src]...</span>"
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
if(do_after(user, 40))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"\blue You have unfastened \the [src].", \
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
@@ -189,7 +189,7 @@
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(T.intact && istype(P.node, /obj/machinery/atmospherics/pipe) && P.node.level == 1 )
|
||||
if(!T.is_plating() && istype(P.node, /obj/machinery/atmospherics/pipe) && P.node.level == 1 )
|
||||
//pipe_state = icon_manager.get_atmos_icon("underlay_down", P.dir, color_cache_name(P.node))
|
||||
pipe_state = icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "down")
|
||||
else
|
||||
|
||||
@@ -134,22 +134,22 @@
|
||||
if (!istype(W, /obj/item/weapon/wrench))
|
||||
return ..()
|
||||
if (connected_device)
|
||||
user << "\red You cannot unwrench this [src], dettach [connected_device] first."
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], dettach \the [connected_device] first.</span>"
|
||||
return 1
|
||||
if (locate(/obj/machinery/portable_atmospherics, src.loc))
|
||||
return 1
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], it too exerted due to internal pressure.</span>"
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "\blue You begin to unfasten \the [src]..."
|
||||
user << "<span class='notice'>You begin to unfasten \the [src]...</span>"
|
||||
if (do_after(user, 40))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"\blue You have unfastened \the [src].", \
|
||||
"You hear ratchet.")
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
..()
|
||||
switch(filter_type)
|
||||
if(0) //removing hydrocarbons
|
||||
filtered_out = list("phoron", "oxygen_agent_b")
|
||||
filtered_out = list("phoron")
|
||||
if(1) //removing O2
|
||||
filtered_out = list("oxygen")
|
||||
if(2) //removing N2
|
||||
@@ -134,16 +134,16 @@
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], it too exerted due to internal pressure.</span>"
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "\blue You begin to unfasten \the [src]..."
|
||||
user << "<span class='notice'>You begin to unfasten \the [src]...</span>"
|
||||
if (do_after(user, 40))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"\blue You have unfastened \the [src].", \
|
||||
"You hear ratchet.")
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
return
|
||||
|
||||
if(!src.allowed(user))
|
||||
user << "\red Access denied."
|
||||
user << "<span class='warning'>Access denied.</span>"
|
||||
return
|
||||
|
||||
var/dat
|
||||
@@ -206,7 +206,6 @@
|
||||
switch(filter_type)
|
||||
if(0) //removing hydrocarbons
|
||||
filtered_out += "phoron"
|
||||
filtered_out += "oxygen_agent_b"
|
||||
if(1) //removing O2
|
||||
filtered_out += "oxygen"
|
||||
if(2) //removing N2
|
||||
|
||||
@@ -109,15 +109,15 @@
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], it too exerted due to internal pressure.</span>"
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "\blue You begin to unfasten \the [src]..."
|
||||
user << "<span class='notice'>You begin to unfasten \the [src]...</span>"
|
||||
if (do_after(user, 40))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"\blue You have unfastened \the [src].", \
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
@@ -127,7 +127,7 @@
|
||||
return
|
||||
src.add_fingerprint(usr)
|
||||
if(!src.allowed(user))
|
||||
user << "\red Access denied."
|
||||
user << "<span class='warning'>Access denied.</span>"
|
||||
return
|
||||
usr.set_machine(src)
|
||||
var/dat = {"<b>Power: </b><a href='?src=\ref[src];power=1'>[use_power?"On":"Off"]</a><br>
|
||||
|
||||
@@ -7,8 +7,6 @@ obj/machinery/atmospherics/trinary
|
||||
var/datum/gas_mixture/air2
|
||||
var/datum/gas_mixture/air3
|
||||
|
||||
var/obj/machinery/atmospherics/node1
|
||||
var/obj/machinery/atmospherics/node2
|
||||
var/obj/machinery/atmospherics/node3
|
||||
|
||||
var/datum/pipe_network/network1
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
var/state = 0 // 0 = go straight, 1 = go to side
|
||||
|
||||
// like a trinary component, node1 is input, node2 is side output, node3 is straight output
|
||||
var/obj/machinery/atmospherics/node1
|
||||
var/obj/machinery/atmospherics/node2
|
||||
var/obj/machinery/atmospherics/node3
|
||||
|
||||
var/datum/pipe_network/network_node1
|
||||
@@ -308,7 +306,7 @@
|
||||
if(!powered())
|
||||
return
|
||||
if(!src.allowed(user))
|
||||
user << "\red Access denied."
|
||||
user << "<span class='warning'>Access denied.</span>"
|
||||
return
|
||||
..()
|
||||
|
||||
@@ -350,21 +348,21 @@
|
||||
if (!istype(W, /obj/item/weapon/wrench))
|
||||
return ..()
|
||||
if (istype(src, /obj/machinery/atmospherics/tvalve/digital))
|
||||
user << "\red You cannot unwrench this [src], it's too complicated."
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], it's too complicated.</span>"
|
||||
return 1
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
|
||||
user << "<span class='warnng'>You cannot unwrench \the [src], it too exerted due to internal pressure.</span>"
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "\blue You begin to unfasten \the [src]..."
|
||||
user << "<span class='notice'>You begin to unfasten \the [src]...</span>"
|
||||
if (do_after(user, 40))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"\blue You have unfastened \the [src].", \
|
||||
"You hear ratchet.")
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
|
||||
@@ -448,7 +446,7 @@
|
||||
if(!powered())
|
||||
return
|
||||
if(!src.allowed(user))
|
||||
user << "\red Access denied."
|
||||
user << "<span class='warning'>Access denied.</span>"
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
@@ -69,21 +69,21 @@
|
||||
if (!istype(W, /obj/item/weapon/wrench))
|
||||
return ..()
|
||||
var/turf/T = src.loc
|
||||
if (level==1 && isturf(T) && T.intact)
|
||||
user << "\red You must remove the plating first."
|
||||
if (level==1 && isturf(T) && !T.is_plating())
|
||||
user << "<span class='warning'>You must remove the plating first.</span>"
|
||||
return 1
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], it is too exerted due to internal pressure.</span>"
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "\blue You begin to unfasten \the [src]..."
|
||||
user << "<span class='notice'>You begin to unfasten \the [src]...</span>"
|
||||
if (do_after(user, 40))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"\blue You have unfastened \the [src].", \
|
||||
"You hear ratchet.")
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
@@ -91,3 +91,13 @@
|
||||
update_underlays()
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/proc/is_welded() // TODO: refactor welding into unary
|
||||
if (welded > 0)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/proc/is_welded()
|
||||
if (welded > 0)
|
||||
return 1
|
||||
return 0
|
||||
@@ -7,8 +7,6 @@
|
||||
#define PRESSURE_CHECK_EXTERNAL 1
|
||||
#define PRESSURE_CHECK_INTERNAL 2
|
||||
|
||||
#undefine
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump
|
||||
icon = 'icons/atmos/vent_pump.dmi'
|
||||
icon_state = "map_vent"
|
||||
@@ -118,7 +116,7 @@
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
if(T.intact && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
if(!T.is_plating() && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
vent_icon += "h"
|
||||
|
||||
if(welded)
|
||||
@@ -136,7 +134,7 @@
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(T.intact && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
if(!T.is_plating() && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
return
|
||||
else
|
||||
if(node)
|
||||
@@ -160,7 +158,7 @@
|
||||
/obj/machinery/atmospherics/unary/vent_pump/process()
|
||||
..()
|
||||
|
||||
if (hibernate)
|
||||
if (hibernate > world.time)
|
||||
return 1
|
||||
|
||||
if (!node)
|
||||
@@ -190,12 +188,8 @@
|
||||
else
|
||||
//If we're in an area that is fucking ideal, and we don't have to do anything, chances are we won't next tick either so why redo these calculations?
|
||||
//JESUS FUCK. THERE ARE LITERALLY 250 OF YOU MOTHERFUCKERS ON ZLEVEL ONE AND YOU DO THIS SHIT EVERY TICK WHEN VERY OFTEN THERE IS NO REASON TO
|
||||
|
||||
if(pump_direction && pressure_checks == PRESSURE_CHECK_EXTERNAL && controller_iteration > 10) //99% of all vents
|
||||
//Fucking hibernate because you ain't doing shit.
|
||||
hibernate = 1
|
||||
spawn(rand(100,200)) //hibernate for 10 or 20 seconds randomly
|
||||
hibernate = 0
|
||||
if(pump_direction && pressure_checks == PRESSURE_CHECK_EXTERNAL) //99% of all vents
|
||||
hibernate = world.time + (rand(100,200))
|
||||
|
||||
|
||||
if (power_draw >= 0)
|
||||
@@ -243,7 +237,7 @@
|
||||
"timestamp" = world.time,
|
||||
"sigtype" = "status",
|
||||
"power_draw" = last_power_draw,
|
||||
"flow_rate" = last_flow_rate,
|
||||
"flow_rate" = last_flow_rate
|
||||
)
|
||||
|
||||
if(!initial_loc.air_vent_names[id_tag])
|
||||
@@ -357,23 +351,25 @@
|
||||
/obj/machinery/atmospherics/unary/vent_pump/attackby(obj/item/W, mob/user)
|
||||
if(istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if (WT.remove_fuel(0,user))
|
||||
user << "\blue Now welding the vent."
|
||||
if (!WT.welding)
|
||||
user << "<span class='danger'>\The [WT] must be turned on!</span>"
|
||||
else if (WT.remove_fuel(0,user))
|
||||
user << "<span class='notice'>Now welding the vent.</span>"
|
||||
if(do_after(user, 20))
|
||||
if(!src || !WT.isOn()) return
|
||||
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
|
||||
if(!welded)
|
||||
user.visible_message("[user] welds the vent shut.", "You weld the vent shut.", "You hear welding.")
|
||||
user.visible_message("<span class='danger'>\The [user] welds \the [src] shut.</span>", "<span class='notice'>You weld \the [src] shut.</span>", "You hear welding.")
|
||||
welded = 1
|
||||
update_icon()
|
||||
else
|
||||
user.visible_message("[user] unwelds the vent.", "You unweld the vent.", "You hear welding.")
|
||||
user.visible_message("<span class='danger'>[user] unwelds \the [src].</span>", "<span class='notice'>You unweld \the [src].</span>", "You hear welding.")
|
||||
welded = 0
|
||||
update_icon()
|
||||
else
|
||||
user << "\blue The welding tool needs to be on to start this task."
|
||||
user << "<span class='notice'>You fail to complete the welding.</span>"
|
||||
else
|
||||
user << "\blue You need more welding fuel to complete this task."
|
||||
user << "<span class='warning'>You need more welding fuel to complete this task.</span>"
|
||||
return 1
|
||||
else
|
||||
..()
|
||||
@@ -396,25 +392,25 @@
|
||||
if (!istype(W, /obj/item/weapon/wrench))
|
||||
return ..()
|
||||
if (!(stat & NOPOWER) && use_power)
|
||||
user << "\red You cannot unwrench this [src], turn it off first."
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], turn it off first.</span>"
|
||||
return 1
|
||||
var/turf/T = src.loc
|
||||
if (node && node.level==1 && isturf(T) && T.intact)
|
||||
user << "\red You must remove the plating first."
|
||||
if (node && node.level==1 && isturf(T) && !T.is_plating())
|
||||
user << "<span class='warning'>You must remove the plating first.</span>"
|
||||
return 1
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], it is too exerted due to internal pressure.</span>"
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "\blue You begin to unfasten \the [src]..."
|
||||
user << "<span class='notice'>You begin to unfasten \the [src]...</span>"
|
||||
if (do_after(user, 40))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"\blue You have unfastened \the [src].", \
|
||||
"You hear ratchet.")
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
|
||||
@@ -424,3 +420,12 @@
|
||||
initial_loc.air_vent_names -= id_tag
|
||||
..()
|
||||
return
|
||||
|
||||
#undef DEFAULT_PRESSURE_DELTA
|
||||
|
||||
#undef EXTERNAL_PRESSURE_BOUND
|
||||
#undef INTERNAL_PRESSURE_BOUND
|
||||
#undef PRESSURE_CHECKS
|
||||
|
||||
#undef PRESSURE_CHECK_EXTERNAL
|
||||
#undef PRESSURE_CHECK_INTERNAL
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
var/radio_filter_out
|
||||
var/radio_filter_in
|
||||
|
||||
var/welded = 0
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/on
|
||||
use_power = 1
|
||||
icon_state = "map_scrubber_on"
|
||||
@@ -53,12 +55,14 @@
|
||||
|
||||
overlays.Cut()
|
||||
|
||||
var/scrubber_icon = "scrubber"
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
var/scrubber_icon = "scrubber"
|
||||
if(welded)
|
||||
scrubber_icon += "weld"
|
||||
else
|
||||
if(!powered())
|
||||
scrubber_icon += "off"
|
||||
else
|
||||
@@ -72,7 +76,7 @@
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(T.intact && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
if(!T.is_plating() && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
return
|
||||
else
|
||||
if(node)
|
||||
@@ -127,7 +131,7 @@
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/process()
|
||||
..()
|
||||
|
||||
if (hibernate)
|
||||
if (hibernate > world.time)
|
||||
return 1
|
||||
|
||||
if (!node)
|
||||
@@ -135,6 +139,8 @@
|
||||
//broadcast_status()
|
||||
if(!use_power || (stat & (NOPOWER|BROKEN)))
|
||||
return 0
|
||||
if(welded)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
|
||||
@@ -150,11 +156,9 @@
|
||||
|
||||
power_draw = pump_gas(src, environment, air_contents, transfer_moles, power_rating)
|
||||
|
||||
if(scrubbing && power_draw < 0 && controller_iteration > 10) //99% of all scrubbers
|
||||
if(scrubbing && power_draw <= 0) //99% of all scrubbers
|
||||
//Fucking hibernate because you ain't doing shit.
|
||||
hibernate = 1
|
||||
spawn(rand(100,200)) //hibernate for 10 or 20 seconds randomly
|
||||
hibernate = 0
|
||||
hibernate = world.time + (rand(100,200))
|
||||
|
||||
if (power_draw >= 0)
|
||||
last_power_draw = power_draw
|
||||
@@ -255,36 +259,62 @@
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
|
||||
if (!istype(W, /obj/item/weapon/wrench))
|
||||
return ..()
|
||||
if (istype(W, /obj/item/weapon/wrench))
|
||||
if (!(stat & NOPOWER) && use_power)
|
||||
user << "\red You cannot unwrench this [src], turn it off first."
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], turn it off first.</span>"
|
||||
return 1
|
||||
var/turf/T = src.loc
|
||||
if (node && node.level==1 && isturf(T) && T.intact)
|
||||
user << "\red You must remove the plating first."
|
||||
if (node && node.level==1 && isturf(T) && !T.is_plating())
|
||||
user << "<span class='warning'>You must remove the plating first.</span>"
|
||||
return 1
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], it is too exerted due to internal pressure.</span>"
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "\blue You begin to unfasten \the [src]..."
|
||||
user << "<span class='notice'>You begin to unfasten \the [src]...</span>"
|
||||
if (do_after(user, 40))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"\blue You have unfastened \the [src].", \
|
||||
"You hear ratchet.")
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
if(istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if (!WT.welding)
|
||||
user << "<span class='danger'>\The [WT] must be turned on!</span>"
|
||||
else if (WT.remove_fuel(0,user))
|
||||
user << "<span class='notice'>Now welding \the [src].</span>"
|
||||
if(do_after(user, 20))
|
||||
if(!src || !WT.isOn()) return
|
||||
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
|
||||
if(!welded)
|
||||
user.visible_message("<span class='danger'>\The [user] welds \the [src] shut.</span>", "<span class='notice'>You weld \the [src] shut.</span>", "You hear welding.")
|
||||
welded = 1
|
||||
update_icon()
|
||||
else
|
||||
user.visible_message("<span class='danger'>[user] unwelds \the [src].</span>", "<span class='notice'>You unweld \the [src].</span>", "You hear welding.")
|
||||
welded = 0
|
||||
update_icon()
|
||||
else
|
||||
user << "<span class='notice'>You fail to complete the welding.</span>"
|
||||
else
|
||||
user << "<span class='warning'>You need more welding fuel to complete this task.</span>"
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/examine(mob/user)
|
||||
if(..(user, 1))
|
||||
user << "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W"
|
||||
else
|
||||
user << "You are too far away to read the gauge."
|
||||
if(welded)
|
||||
user << "It seems welded shut."
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/Destroy()
|
||||
if(initial_loc)
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
var/open = 0
|
||||
var/openDuringInit = 0
|
||||
|
||||
var/obj/machinery/atmospherics/node1
|
||||
var/obj/machinery/atmospherics/node2
|
||||
|
||||
var/datum/pipe_network/network_node1
|
||||
var/datum/pipe_network/network_node2
|
||||
|
||||
@@ -241,10 +238,24 @@
|
||||
if(!powered())
|
||||
return
|
||||
if(!src.allowed(user))
|
||||
user << "\red Access denied."
|
||||
user << "<span class='warning'>Access denied.</span>"
|
||||
return
|
||||
..()
|
||||
|
||||
log_and_message_admins("has [open ? "<font color='red'>OPENED</font>" : "closed"] [name].", user)
|
||||
|
||||
/obj/machinery/atmospherics/valve/digital/AltClick(var/mob/dead/observer/admin)
|
||||
if (istype(admin))
|
||||
if (admin.client && admin.client.holder && ((R_MOD|R_ADMIN) & admin.client.holder.rights))
|
||||
if (open)
|
||||
close()
|
||||
else
|
||||
if (alert(admin, "The valve is currently closed. Do you want to open it?", "Open the valve?", "Yes", "No") == "No")
|
||||
return
|
||||
open()
|
||||
|
||||
log_and_message_admins("has [open ? "opened" : "closed"] [name].", admin)
|
||||
|
||||
/obj/machinery/atmospherics/valve/digital/open
|
||||
open = 1
|
||||
icon_state = "map_valve1"
|
||||
@@ -294,21 +305,21 @@
|
||||
if (!istype(W, /obj/item/weapon/wrench))
|
||||
return ..()
|
||||
if (istype(src, /obj/machinery/atmospherics/valve/digital))
|
||||
user << "\red You cannot unwrench this [src], it's too complicated."
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], it's too complicated.</span>"
|
||||
return 1
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], it is too exerted due to internal pressure.</span>"
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "\blue You begin to unfasten \the [src]..."
|
||||
user << "<span class='notice'>You begin to unfasten \the [src]...</span>"
|
||||
if (do_after(user, 40))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"\blue You have unfastened \the [src].", \
|
||||
"You hear ratchet.")
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ obj/machinery/atmospherics/mains_pipe/simple
|
||||
..() // initialize internal pipes
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
hide(T.intact)
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
hidden
|
||||
@@ -243,7 +243,7 @@ obj/machinery/atmospherics/mains_pipe/manifold
|
||||
..() // initialize internal pipes
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
hide(T.intact)
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
update_icon()
|
||||
@@ -293,7 +293,7 @@ obj/machinery/atmospherics/mains_pipe/manifold4w
|
||||
..() // initialize internal pipes
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
hide(T.intact)
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
update_icon()
|
||||
@@ -354,7 +354,7 @@ obj/machinery/atmospherics/mains_pipe/split
|
||||
N1.merge(N2)
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
hide(T.intact)
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
update_icon()
|
||||
@@ -475,7 +475,7 @@ obj/machinery/atmospherics/mains_pipe/split3
|
||||
N1.merge(N2)
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
hide(T.intact)
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
update_icon()
|
||||
@@ -525,7 +525,7 @@ obj/machinery/atmospherics/mains_pipe/cap
|
||||
..()
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
hide(T.intact)
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
hidden
|
||||
@@ -649,7 +649,7 @@ obj/machinery/atmospherics/mains_pipe/valve
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
if(!src.allowed(user))
|
||||
user << "\red Access denied."
|
||||
user << "<span class='warning'>Access denied.</span>"
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/obj/machinery/atmospherics/pipe
|
||||
|
||||
var/datum/gas_mixture/air_temporary //used when reconstructing a pipeline that broke
|
||||
var/datum/gas_mixture/air_temporary // used when reconstructing a pipeline that broke
|
||||
var/datum/pipeline/parent
|
||||
|
||||
var/volume = 0
|
||||
force = 20
|
||||
|
||||
@@ -20,10 +19,12 @@
|
||||
return -1
|
||||
|
||||
/obj/machinery/atmospherics/pipe/New()
|
||||
..()
|
||||
//so pipes under walls are hidden
|
||||
if(istype(get_turf(src), /turf/simulated/wall) || istype(get_turf(src), /turf/simulated/shuttle/wall) || istype(get_turf(src), /turf/unsimulated/wall))
|
||||
level = 1
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/hides_under_flooring()
|
||||
return level != 2
|
||||
|
||||
/obj/machinery/atmospherics/pipe/proc/pipeline_expansion()
|
||||
return null
|
||||
@@ -81,22 +82,22 @@
|
||||
if (!istype(W, /obj/item/weapon/wrench))
|
||||
return ..()
|
||||
var/turf/T = src.loc
|
||||
if (level==1 && isturf(T) && T.intact)
|
||||
user << "\red You must remove the plating first."
|
||||
if (level==1 && isturf(T) && !T.is_plating())
|
||||
user << "<span class='warning'>You must remove the plating first.</span>"
|
||||
return 1
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
user << "<span class='warning'>You cannot unwrench [src], it is too exerted due to internal pressure.</span>"
|
||||
user << "<span class='warning'>You cannot unwrench \the [src], it is too exerted due to internal pressure.</span>"
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "\blue You begin to unfasten \the [src]..."
|
||||
user << "<span class='notice'>You begin to unfasten \the [src]...</span>"
|
||||
if (do_after(user, 40))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"\blue You have unfastened \the [src].", \
|
||||
"You hear ratchet.")
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
for (var/obj/machinery/meter/meter in T)
|
||||
if (meter.target == src)
|
||||
@@ -153,9 +154,6 @@
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH|NORTH
|
||||
|
||||
var/obj/machinery/atmospherics/node1
|
||||
var/obj/machinery/atmospherics/node2
|
||||
|
||||
var/minimum_temperature_difference = 300
|
||||
var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No
|
||||
|
||||
@@ -188,7 +186,7 @@
|
||||
initialize_directions = SOUTH|WEST
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/hide(var/i)
|
||||
if(level == 1 && istype(loc, /turf/simulated))
|
||||
if(istype(loc, /turf/simulated))
|
||||
invisibility = i ? 101 : 0
|
||||
update_icon()
|
||||
|
||||
@@ -214,7 +212,7 @@
|
||||
else return 1
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/proc/burst()
|
||||
src.visible_message("\red \bold [src] bursts!");
|
||||
src.visible_message("<span class='danger'>\The [src] bursts!</span>");
|
||||
playsound(src.loc, 'sound/effects/bang.ogg', 25, 1)
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new
|
||||
smoke.set_up(1,0, src.loc, 0)
|
||||
@@ -297,9 +295,8 @@
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(istype(T))
|
||||
hide(T.intact)
|
||||
var/turf/T = loc
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/disconnect(obj/machinery/atmospherics/reference)
|
||||
@@ -348,8 +345,8 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/green
|
||||
color = PIPE_COLOR_GREEN
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/purple
|
||||
color = PIPE_COLOR_PURPLE
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/black
|
||||
color = PIPE_COLOR_BLACK
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/red
|
||||
color = PIPE_COLOR_RED
|
||||
@@ -390,8 +387,8 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/green
|
||||
color = PIPE_COLOR_GREEN
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/purple
|
||||
color = PIPE_COLOR_PURPLE
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/black
|
||||
color = PIPE_COLOR_BLACK
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/red
|
||||
color = PIPE_COLOR_RED
|
||||
@@ -423,8 +420,6 @@
|
||||
dir = SOUTH
|
||||
initialize_directions = EAST|NORTH|WEST
|
||||
|
||||
var/obj/machinery/atmospherics/node1
|
||||
var/obj/machinery/atmospherics/node2
|
||||
var/obj/machinery/atmospherics/node3
|
||||
|
||||
level = 1
|
||||
@@ -446,7 +441,7 @@
|
||||
initialize_directions = NORTH|EAST|SOUTH
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/hide(var/i)
|
||||
if(level == 1 && istype(loc, /turf/simulated))
|
||||
if(istype(loc, /turf/simulated))
|
||||
invisibility = i ? 101 : 0
|
||||
update_icon()
|
||||
|
||||
@@ -582,8 +577,7 @@
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(istype(T))
|
||||
hide(T.intact)
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/visible
|
||||
@@ -617,8 +611,8 @@
|
||||
/obj/machinery/atmospherics/pipe/manifold/visible/green
|
||||
color = PIPE_COLOR_GREEN
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/visible/purple
|
||||
color = PIPE_COLOR_PURPLE
|
||||
/obj/machinery/atmospherics/pipe/manifold/visible/black
|
||||
color = PIPE_COLOR_BLACK
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/visible/red
|
||||
color = PIPE_COLOR_RED
|
||||
@@ -659,8 +653,8 @@
|
||||
/obj/machinery/atmospherics/pipe/manifold/hidden/green
|
||||
color = PIPE_COLOR_GREEN
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/hidden/purple
|
||||
color = PIPE_COLOR_PURPLE
|
||||
/obj/machinery/atmospherics/pipe/manifold/hidden/black
|
||||
color = PIPE_COLOR_BLACK
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/hidden/red
|
||||
color = PIPE_COLOR_RED
|
||||
@@ -679,8 +673,6 @@
|
||||
dir = SOUTH
|
||||
initialize_directions = NORTH|SOUTH|EAST|WEST
|
||||
|
||||
var/obj/machinery/atmospherics/node1
|
||||
var/obj/machinery/atmospherics/node2
|
||||
var/obj/machinery/atmospherics/node3
|
||||
var/obj/machinery/atmospherics/node4
|
||||
|
||||
@@ -806,7 +798,7 @@
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/hide(var/i)
|
||||
if(level == 1 && istype(loc, /turf/simulated))
|
||||
if(istype(loc, /turf/simulated))
|
||||
invisibility = i ? 101 : 0
|
||||
update_icon()
|
||||
|
||||
@@ -841,8 +833,7 @@
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(istype(T))
|
||||
hide(T.intact)
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/visible
|
||||
@@ -876,8 +867,8 @@
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/visible/green
|
||||
color = PIPE_COLOR_GREEN
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/visible/purple
|
||||
color = PIPE_COLOR_PURPLE
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/visible/black
|
||||
color = PIPE_COLOR_BLACK
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/visible/red
|
||||
color = PIPE_COLOR_RED
|
||||
@@ -917,8 +908,8 @@
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/hidden/green
|
||||
color = PIPE_COLOR_GREEN
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/hidden/purple
|
||||
color = PIPE_COLOR_PURPLE
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/hidden/black
|
||||
color = PIPE_COLOR_BLACK
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/hidden/red
|
||||
color = PIPE_COLOR_RED
|
||||
@@ -946,7 +937,7 @@
|
||||
initialize_directions = dir
|
||||
|
||||
/obj/machinery/atmospherics/pipe/cap/hide(var/i)
|
||||
if(level == 1 && istype(loc, /turf/simulated))
|
||||
if(istype(loc, /turf/simulated))
|
||||
invisibility = i ? 101 : 0
|
||||
update_icon()
|
||||
|
||||
@@ -997,7 +988,7 @@
|
||||
break
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
hide(T.intact)
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/cap/visible
|
||||
@@ -1061,8 +1052,6 @@
|
||||
initialize_directions = SOUTH
|
||||
density = 1
|
||||
|
||||
var/obj/machinery/atmospherics/node1
|
||||
|
||||
/obj/machinery/atmospherics/pipe/tank/New()
|
||||
icon_state = "air"
|
||||
initialize_directions = dir
|
||||
@@ -1120,20 +1109,8 @@
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/device/analyzer) && in_range(user, src))
|
||||
for (var/mob/O in viewers(user, null))
|
||||
O << "\red [user] has used the analyzer on \icon[icon]"
|
||||
|
||||
var/pressure = parent.air.return_pressure()
|
||||
var/total_moles = parent.air.total_moles
|
||||
|
||||
user << "\blue Results of analysis of \icon[icon]"
|
||||
if (total_moles>0)
|
||||
user << "\blue Pressure: [round(pressure,0.1)] kPa"
|
||||
for(var/g in parent.air.gas)
|
||||
user << "\blue [gas_data.name[g]]: [round((parent.air.gas[g] / total_moles) * 100)]%"
|
||||
user << "\blue Temperature: [round(parent.air.temperature-T0C)]°C"
|
||||
else
|
||||
user << "\blue Tank is empty!"
|
||||
var/obj/item/device/analyzer/A = W
|
||||
A.analyze_gases(src, user)
|
||||
|
||||
/obj/machinery/atmospherics/pipe/tank/air
|
||||
name = "Pressure Tank (Air)"
|
||||
@@ -1237,8 +1214,6 @@
|
||||
|
||||
var/build_killswitch = 1
|
||||
|
||||
var/obj/machinery/atmospherics/node1
|
||||
|
||||
/obj/machinery/atmospherics/pipe/vent/New()
|
||||
initialize_directions = dir
|
||||
..()
|
||||
@@ -1398,7 +1373,7 @@
|
||||
|
||||
/obj/machinery/atmospherics/proc/add_underlay_adapter(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type) //modified from add_underlay, does not make exposed underlays
|
||||
if(node)
|
||||
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
if(!T.is_plating() && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
|
||||
else
|
||||
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
|
||||
|
||||
@@ -1,645 +0,0 @@
|
||||
#define DEBUG
|
||||
|
||||
datum/air_group/var/marker
|
||||
datum/air_group/var/debugging = 0
|
||||
datum/pipe_network/var/marker
|
||||
|
||||
datum/gas_mixture
|
||||
var/turf/parent
|
||||
|
||||
/*
|
||||
turf/simulated
|
||||
New()
|
||||
..()
|
||||
|
||||
if(air)
|
||||
air.parent = src
|
||||
*/
|
||||
obj/machinery/door
|
||||
verb
|
||||
toggle_door()
|
||||
set src in world
|
||||
if(density)
|
||||
open()
|
||||
else
|
||||
close()
|
||||
|
||||
turf/space
|
||||
verb
|
||||
create_floor()
|
||||
set src in world
|
||||
new /turf/simulated/floor(src)
|
||||
|
||||
create_meteor(direction as num)
|
||||
set src in world
|
||||
|
||||
var/obj/effect/meteor/M = new( src )
|
||||
walk(M, direction,10)
|
||||
|
||||
|
||||
turf/simulated/wall
|
||||
verb
|
||||
create_floor()
|
||||
set src in world
|
||||
new /turf/simulated/floor(src)
|
||||
|
||||
obj/item/weapon/tank
|
||||
verb
|
||||
adjust_mixture(temperature as num, target_toxin_pressure as num, target_oxygen_pressure as num)
|
||||
set src in world
|
||||
if(!air_contents)
|
||||
usr << "\red ERROR: no gas_mixture associated with this tank"
|
||||
return null
|
||||
|
||||
air_contents.temperature = temperature
|
||||
air_contents.oxygen = target_oxygen_pressure*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
|
||||
air_contents.toxins = target_toxin_pressure*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
|
||||
|
||||
turf/simulated/floor
|
||||
verb
|
||||
parent_info()
|
||||
set src in world
|
||||
if(parent)
|
||||
usr << "<B>[x],[y] parent:</B> Processing: [parent.group_processing]"
|
||||
if(parent.members)
|
||||
usr << "Members: [parent.members.len]"
|
||||
else
|
||||
usr << "Members: None?"
|
||||
if(parent.borders)
|
||||
usr << "Borders: [parent.borders.len]"
|
||||
else
|
||||
usr << "Borders: None"
|
||||
if(parent.length_space_border)
|
||||
usr << "Space Borders: [parent.space_borders.len], Space Length: [parent.length_space_border]"
|
||||
else
|
||||
usr << "Space Borders: None"
|
||||
else
|
||||
usr << "\blue [x],[y] has no parent air group."
|
||||
|
||||
verb
|
||||
create_wall()
|
||||
set src in world
|
||||
new /turf/simulated/wall(src)
|
||||
verb
|
||||
adjust_mixture(temp as num, tox as num, oxy as num)
|
||||
set src in world
|
||||
var/datum/gas_mixture/stuff = return_air()
|
||||
stuff.temperature = temp
|
||||
stuff.toxins = tox
|
||||
stuff.oxygen = oxy
|
||||
|
||||
verb
|
||||
boom(inner_range as num, middle_range as num, outer_range as num)
|
||||
set src in world
|
||||
explosion(src,inner_range,middle_range,outer_range,outer_range)
|
||||
|
||||
verb
|
||||
flag_parent()
|
||||
set src in world
|
||||
if(parent)
|
||||
parent.debugging = !parent.debugging
|
||||
usr << "[parent.members.len] set to [parent.debugging]"
|
||||
verb
|
||||
small_explosion()
|
||||
set src in world
|
||||
explosion(src, 1, 2, 3, 3)
|
||||
|
||||
verb
|
||||
large_explosion()
|
||||
set src in world
|
||||
explosion(src, 3, 5, 7, 5)
|
||||
|
||||
obj/machinery/portable_atmospherics/canister
|
||||
verb/test_release()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
valve_open = 1
|
||||
release_pressure = 1000
|
||||
/*
|
||||
obj/machinery/atmospherics
|
||||
unary
|
||||
heat_reservoir
|
||||
verb
|
||||
toggle_power()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
adjust_temp(temp as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
current_temperature = temp
|
||||
cold_sink
|
||||
verb
|
||||
toggle_power()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
adjust_temp(temp as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
current_temperature = temp
|
||||
vent_pump
|
||||
verb
|
||||
toggle_power()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
|
||||
toggle_direction()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
pump_direction = !pump_direction
|
||||
|
||||
update_icon()
|
||||
|
||||
change_pressure_parameters()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
usr << "current settings: PC=[pressure_checks], EB=[external_pressure_bound], IB=[internal_pressure_bound]"
|
||||
|
||||
var/mode = input(usr, "Select an option:") in list("Bound External", "Bound Internal", "Bound Both")
|
||||
|
||||
switch(mode)
|
||||
if("Bound External")
|
||||
pressure_checks = 1
|
||||
external_pressure_bound = input(usr, "External Pressure Bound?") as num
|
||||
if("Bound Internal")
|
||||
pressure_checks = 2
|
||||
internal_pressure_bound = input(usr, "Internal Pressure Bound?") as num
|
||||
else
|
||||
pressure_checks = 3
|
||||
external_pressure_bound = input(usr, "External Pressure Bound?") as num
|
||||
internal_pressure_bound = input(usr, "Internal Pressure Bound?") as num
|
||||
|
||||
outlet_injector
|
||||
verb
|
||||
toggle_power()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
verb
|
||||
trigger_inject()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
inject()
|
||||
|
||||
vent_scrubber
|
||||
verb
|
||||
toggle_power()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
|
||||
toggle_scrubbing()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
scrubbing = !scrubbing
|
||||
|
||||
update_icon()
|
||||
|
||||
change_rate(amount as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
volume_rate = amount
|
||||
|
||||
mixer
|
||||
verb
|
||||
toggle()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
|
||||
change_pressure(amount as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
target_pressure = amount
|
||||
|
||||
change_ratios()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
if(node_in1)
|
||||
var/node_ratio = input(usr, "Node 1 Ratio? ([dir2text(get_dir(src, node_in1))])") as num
|
||||
node_ratio = min(max(0,node_ratio),1)
|
||||
|
||||
node1_concentration = node_ratio
|
||||
node2_concentration = 1-node_ratio
|
||||
else
|
||||
node2_concentration = 1
|
||||
node1_concentration = 0
|
||||
|
||||
usr << "Node 1: [node1_concentration], Node 2: [node2_concentration]"
|
||||
|
||||
|
||||
filter
|
||||
verb
|
||||
toggle()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
|
||||
change_pressure(amount as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
target_pressure = amount
|
||||
|
||||
unary/oxygen_generator
|
||||
verb
|
||||
toggle()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
|
||||
change_rate(amount as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
oxygen_content = amount
|
||||
binary/pump
|
||||
verb
|
||||
debug()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
world << "Debugging: [x],[y]"
|
||||
|
||||
if(node1)
|
||||
world << "Input node: [node1.x],[node1.y] [network1]"
|
||||
if(node2)
|
||||
world << "Output node: [node2.x],[node2.y] [network2]"
|
||||
|
||||
toggle()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
change_pressure(amount as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
target_pressure = amount
|
||||
|
||||
valve
|
||||
verb
|
||||
toggle()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
if(open)
|
||||
close()
|
||||
else
|
||||
open()
|
||||
network_data()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
world << "\blue [x],[y]"
|
||||
world << "network 1: [network_node1.normal_members.len], [network_node1.line_members.len]"
|
||||
for(var/obj/O in network_node1.normal_members)
|
||||
world << "member: [O.x], [O.y]"
|
||||
world << "network 2: [network_node2.normal_members.len], [network_node2.line_members.len]"
|
||||
for(var/obj/O in network_node2.normal_members)
|
||||
world << "member: [O.x], [O.y]"
|
||||
pipe
|
||||
verb
|
||||
destroy()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
qdel(src)
|
||||
|
||||
pipeline_data()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
if(parent)
|
||||
usr << "[x],[y] is in a pipeline with [parent.members.len] members ([parent.edges.len] edges)! Volume: [parent.air.volume]"
|
||||
usr << "Pressure: [parent.air.return_pressure()], Temperature: [parent.air.temperature]"
|
||||
usr << "[parent.air.oxygen], [parent.air.toxins], [parent.air.nitrogen], [parent.air.carbon_dioxide] .. [parent.alert_pressure]"
|
||||
*/
|
||||
mob
|
||||
verb
|
||||
flag_all_pipe_networks()
|
||||
set category = "Debug"
|
||||
|
||||
for(var/datum/pipe_network/network in pipe_networks)
|
||||
network.update = 1
|
||||
|
||||
mark_pipe_networks()
|
||||
set category = "Debug"
|
||||
|
||||
for(var/datum/pipe_network/network in pipe_networks)
|
||||
network.marker = rand(1,4)
|
||||
|
||||
for(var/obj/machinery/atmospherics/pipe/P in world)
|
||||
P.overlays.Cut()
|
||||
|
||||
var/datum/pipe_network/master = P.return_network()
|
||||
if(master)
|
||||
P.overlays += icon('icons/Testing/atmos_testing.dmi',"marker[master.marker]")
|
||||
else
|
||||
world << "error"
|
||||
P.overlays += icon('icons/Testing/atmos_testing.dmi',"marker0")
|
||||
|
||||
for(var/obj/machinery/atmospherics/valve/V in world)
|
||||
V.overlays.Cut()
|
||||
|
||||
if(V.network_node1)
|
||||
V.overlays += icon('icons/Testing/atmos_testing.dmi',"marker[V.network_node1.marker]")
|
||||
else
|
||||
V.overlays += icon('icons/Testing/atmos_testing.dmi',"marker0")
|
||||
|
||||
if(V.network_node2)
|
||||
V.overlays += icon('icons/Testing/atmos_testing.dmi',"marker[V.network_node2.marker]")
|
||||
else
|
||||
V.overlays += icon('icons/Testing/atmos_testing.dmi',"marker0")
|
||||
|
||||
turf/simulated
|
||||
var/fire_verbose = 0
|
||||
|
||||
verb
|
||||
mark_direction()
|
||||
set src in world
|
||||
overlays.Cut()
|
||||
for(var/direction in list(NORTH,SOUTH,EAST,WEST))
|
||||
if(group_border&direction)
|
||||
overlays += icon('icons/Testing/turf_analysis.dmi',"red_arrow",direction)
|
||||
else if(air_check_directions&direction)
|
||||
overlays += icon('icons/Testing/turf_analysis.dmi',"arrow",direction)
|
||||
air_status()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
var/datum/gas_mixture/GM = return_air()
|
||||
usr << "\blue @[x],[y] ([GM.group_multiplier]): O:[GM.oxygen] T:[GM.toxins] N:[GM.nitrogen] C:[GM.carbon_dioxide] w [GM.temperature] Kelvin, [GM.return_pressure()] kPa [(active_hotspot)?("\red BURNING"):(null)]"
|
||||
for(var/datum/gas/trace_gas in GM.trace_gases)
|
||||
usr << "[trace_gas.type]: [trace_gas.moles]"
|
||||
|
||||
force_temperature(temp as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
if(parent&&parent.group_processing)
|
||||
parent.suspend_group_processing()
|
||||
|
||||
air.temperature = temp
|
||||
|
||||
spark_temperature(temp as num, volume as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
hotspot_expose(temp, volume)
|
||||
|
||||
fire_verbose()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
fire_verbose = !fire_verbose
|
||||
usr << "[x],[y] now [fire_verbose]"
|
||||
|
||||
add_sleeping_agent(amount as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
if(amount>1)
|
||||
var/datum/gas_mixture/adding = new
|
||||
var/datum/gas/sleeping_agent/trace_gas = new
|
||||
|
||||
trace_gas.moles = amount
|
||||
adding.trace_gases += trace_gas
|
||||
adding.temperature = T20C
|
||||
|
||||
assume_air(adding)
|
||||
|
||||
obj/indicator
|
||||
icon = 'icons/Testing/air_meter.dmi'
|
||||
var/measure = "temperature"
|
||||
anchored = 1
|
||||
|
||||
process()
|
||||
icon_state = measurement()
|
||||
|
||||
proc/measurement()
|
||||
var/turf/T = loc
|
||||
if(!isturf(T)) return
|
||||
var/datum/gas_mixture/GM = T.return_air()
|
||||
switch(measure)
|
||||
if("temperature")
|
||||
if(GM.temperature < 0)
|
||||
return "error"
|
||||
return "[round(GM.temperature/100+0.5)]"
|
||||
if("oxygen")
|
||||
if(GM.oxygen < 0)
|
||||
return "error"
|
||||
return "[round(GM.oxygen/MOLES_CELLSTANDARD*10+0.5)]"
|
||||
if("plasma")
|
||||
if(GM.toxins < 0)
|
||||
return "error"
|
||||
return "[round(GM.toxins/MOLES_CELLSTANDARD*10+0.5)]"
|
||||
if("nitrogen")
|
||||
if(GM.nitrogen < 0)
|
||||
return "error"
|
||||
return "[round(GM.nitrogen/MOLES_CELLSTANDARD*10+0.5)]"
|
||||
else
|
||||
return "[round((GM.total_moles())/MOLES_CELLSTANDARD*10+0.5)]"
|
||||
|
||||
|
||||
Click()
|
||||
process()
|
||||
|
||||
|
||||
obj/window
|
||||
verb
|
||||
destroy()
|
||||
set category = "Minor"
|
||||
set src in world
|
||||
qdel(src)
|
||||
|
||||
mob
|
||||
sight = SEE_OBJS|SEE_TURFS
|
||||
|
||||
verb
|
||||
update_indicators()
|
||||
set category = "Debug"
|
||||
if(!air_master)
|
||||
usr << "Cannot find air_system"
|
||||
return
|
||||
|
||||
for(var/obj/indicator/T in world)
|
||||
T.process()
|
||||
change_indicators()
|
||||
set category = "Debug"
|
||||
if(!air_master)
|
||||
usr << "Cannot find air_system"
|
||||
return
|
||||
|
||||
var/str = input("Select") in list("oxygen", "nitrogen","plasma","all","temperature")
|
||||
|
||||
for(var/obj/indicator/T in world)
|
||||
T.measure = str
|
||||
T.process()
|
||||
|
||||
fire_report()
|
||||
set category = "Debug"
|
||||
usr << "\b \red Fire Report"
|
||||
for(var/obj/effect/hotspot/flame in world)
|
||||
usr << "[flame.x],[flame.y]: [flame.temperature]K, [flame.volume] L - [flame.loc:air:temperature]"
|
||||
|
||||
process_cycle()
|
||||
set category = "Debug"
|
||||
if(!master_controller)
|
||||
usr << "Cannot find master_controller"
|
||||
return
|
||||
|
||||
master_controller.process()
|
||||
update_indicators()
|
||||
|
||||
process_cycles(amount as num)
|
||||
set category = "Debug"
|
||||
if(!master_controller)
|
||||
usr << "Cannot find master_controller"
|
||||
return
|
||||
|
||||
var/start_time = world.timeofday
|
||||
|
||||
for(var/i=1; i<=amount; i++)
|
||||
master_controller.process()
|
||||
|
||||
world << "Ended [amount] cycles in [(world.timeofday-start_time)/10] seconds. [(world.timeofday-start_time)/10-amount] calculation lag"
|
||||
|
||||
update_indicators()
|
||||
|
||||
process_updates_early()
|
||||
set category = "Debug"
|
||||
if(!air_master)
|
||||
usr << "Cannot find air_system"
|
||||
return
|
||||
|
||||
air_master.process_update_tiles()
|
||||
air_master.process_rebuild_select_groups()
|
||||
|
||||
mark_group_delay()
|
||||
set category = "Debug"
|
||||
if(!air_master)
|
||||
usr << "Cannot find air_system"
|
||||
return
|
||||
|
||||
for(var/datum/air_group/group in air_master.air_groups)
|
||||
group.marker = 0
|
||||
|
||||
for(var/turf/simulated/floor/S in world)
|
||||
S.icon = 'icons/Testing/turf_analysis.dmi'
|
||||
if(S.parent)
|
||||
if(S.parent.group_processing)
|
||||
if (S.parent.check_delay < 2)
|
||||
S.parent.marker=1
|
||||
else if (S.parent.check_delay < 5)
|
||||
S.parent.marker=2
|
||||
else if (S.parent.check_delay < 15)
|
||||
S.parent.marker=3
|
||||
else if (S.parent.check_delay < 30)
|
||||
S.parent.marker=4
|
||||
else
|
||||
S.parent.marker=5
|
||||
if(S.parent.borders && S.parent.borders.Find(S))
|
||||
S.icon_state = "on[S.parent.marker]_border"
|
||||
else
|
||||
S.icon_state = "on[S.parent.marker]"
|
||||
|
||||
else
|
||||
if (S.check_delay < 2)
|
||||
S.icon_state= "on1_border"
|
||||
else if (S.check_delay < 5)
|
||||
S.icon_state= "on2_border"
|
||||
else if (S.check_delay < 15)
|
||||
S.icon_state= "on3_border"
|
||||
else if (S.check_delay < 30)
|
||||
S.icon_state= "on4_border"
|
||||
else
|
||||
S.icon_state = "suspended"
|
||||
else
|
||||
if(S.processing)
|
||||
S.icon_state = "individual_on"
|
||||
else
|
||||
S.icon_state = "individual_off"
|
||||
|
||||
|
||||
mark_groups()
|
||||
set category = "Debug"
|
||||
if(!air_master)
|
||||
usr << "Cannot find air_system"
|
||||
return
|
||||
|
||||
for(var/datum/air_group/group in air_master.air_groups)
|
||||
group.marker = 0
|
||||
|
||||
for(var/turf/simulated/floor/S in world)
|
||||
S.icon = 'icons/Testing/turf_analysis.dmi'
|
||||
if(S.parent)
|
||||
if(S.parent.group_processing)
|
||||
if(S.parent.marker == 0)
|
||||
S.parent.marker = rand(1,5)
|
||||
if(S.parent.borders && S.parent.borders.Find(S))
|
||||
S.icon_state = "on[S.parent.marker]_border"
|
||||
else
|
||||
S.icon_state = "on[S.parent.marker]"
|
||||
|
||||
else
|
||||
S.icon_state = "suspended"
|
||||
else
|
||||
if(S.processing)
|
||||
S.icon_state = "individual_on"
|
||||
else
|
||||
S.icon_state = "individual_off"
|
||||
|
||||
get_broken_icons()
|
||||
set category = "Debug"
|
||||
getbrokeninhands()
|
||||
|
||||
|
||||
/* jump_to_dead_group() Currently in the normal admin commands but fits here
|
||||
set category = "Debug"
|
||||
if(!air_master)
|
||||
usr << "Cannot find air_system"
|
||||
return
|
||||
|
||||
var/datum/air_group/dead_groups = list()
|
||||
for(var/datum/air_group/group in air_master.air_groups)
|
||||
if (!group.group_processing)
|
||||
dead_groups += group
|
||||
var/datum/air_group/dest_group = pick(dead_groups)
|
||||
usr.loc = pick(dest_group.members)*/
|
||||
@@ -1,286 +0,0 @@
|
||||
datum/air_group
|
||||
var/group_processing = 1 //Processing all tiles as one large tile if 1
|
||||
|
||||
var/datum/gas_mixture/air = new
|
||||
|
||||
var/current_cycle = 0 //cycle that oxygen value represents
|
||||
var/archived_cycle = 0 //cycle that oxygen_archived value represents
|
||||
//The use of archived cycle saves processing power by permitting the archiving step of FET
|
||||
// to be rolled into the updating step
|
||||
|
||||
//optimization vars
|
||||
var/next_check = 0 //number of ticks before this group updates
|
||||
var/check_delay = 10 //number of ticks between updates, starts fairly high to get boring groups out of the way
|
||||
|
||||
proc/members()
|
||||
//Returns the members of the group
|
||||
proc/process_group()
|
||||
|
||||
|
||||
var/list/borders //Tiles that connect this group to other groups/individual tiles
|
||||
var/list/members //All tiles in this group
|
||||
|
||||
var/list/space_borders
|
||||
var/length_space_border = 0
|
||||
|
||||
|
||||
proc/suspend_group_processing()
|
||||
group_processing = 0
|
||||
update_tiles_from_group()
|
||||
check_delay=0
|
||||
next_check=0
|
||||
|
||||
|
||||
//Copy group air information to individual tile air
|
||||
//Used right before turning on group processing
|
||||
proc/update_group_from_tiles()
|
||||
var/sample_member = pick(members)
|
||||
var/datum/gas_mixture/sample_air = sample_member:air
|
||||
|
||||
air.copy_from(sample_air)
|
||||
air.group_multiplier = members.len
|
||||
return 1
|
||||
|
||||
|
||||
//Copy group air information to individual tile air
|
||||
//Used right before turning off group processing
|
||||
proc/update_tiles_from_group()
|
||||
for(var/member in members)
|
||||
member:air.copy_from(air)
|
||||
if (istype(member,/turf/simulated))
|
||||
var/turf/simulated/turfmem=member
|
||||
turfmem.reset_delay()
|
||||
|
||||
|
||||
proc/archive()
|
||||
air.archive()
|
||||
archived_cycle = air_master.current_cycle
|
||||
|
||||
|
||||
//If individually processing tiles, checks all member tiles to see if they are close enough that the group may resume group processing
|
||||
//Warning: Do not call, called by air_master.process()
|
||||
proc/check_regroup()
|
||||
//Purpose: Checks to see if group processing should be turned back on
|
||||
//Returns: group_processing
|
||||
if(prevent_airgroup_regroup)
|
||||
return 0
|
||||
|
||||
if(group_processing) return 1
|
||||
|
||||
var/turf/simulated/sample = pick(members)
|
||||
for(var/member in members)
|
||||
if(member:active_hotspot)
|
||||
return 0
|
||||
if(member:air.compare(sample.air)) continue
|
||||
else
|
||||
return 0
|
||||
|
||||
update_group_from_tiles()
|
||||
group_processing = 1
|
||||
return 1
|
||||
|
||||
|
||||
//Look into this
|
||||
turf/process_group()
|
||||
current_cycle = air_master.current_cycle
|
||||
if(!group_processing) //Revert to individual processing then end
|
||||
for(var/T in members)
|
||||
var/turf/simulated/member = T
|
||||
member.process_cell()
|
||||
return
|
||||
|
||||
//check if we're skipping this tick
|
||||
if (next_check > 0)
|
||||
next_check--
|
||||
return 1
|
||||
var/player_count = max(player_list.len, 3) / 3
|
||||
next_check += check_delay + rand(player_count, player_count * 1.5)
|
||||
check_delay++
|
||||
|
||||
var/turf/simulated/list/border_individual = list()
|
||||
var/datum/air_group/list/border_group = list()
|
||||
|
||||
var/turf/simulated/list/enemies = list() //used to send the appropriate border tile of a group to the group proc
|
||||
var/turf/simulated/list/self_group_borders = list()
|
||||
var/turf/simulated/list/self_tile_borders = list()
|
||||
|
||||
if(archived_cycle < air_master.current_cycle)
|
||||
archive()
|
||||
//Archive air data for use in calculations
|
||||
//But only if another group didn't store it for us
|
||||
|
||||
for(var/turf/simulated/border_tile in src.borders)
|
||||
for(var/direction in cardinal) //Go through all border tiles and get bordering groups and individuals
|
||||
if(border_tile.group_border&direction)
|
||||
var/turf/simulated/enemy_tile = get_step(border_tile, direction) //Add found tile to appropriate category
|
||||
if(istype(enemy_tile) && enemy_tile.parent && enemy_tile.parent.group_processing)
|
||||
border_group += enemy_tile.parent
|
||||
enemies += enemy_tile
|
||||
self_group_borders += border_tile
|
||||
else
|
||||
border_individual += enemy_tile
|
||||
self_tile_borders += border_tile
|
||||
|
||||
var/abort_group = 0
|
||||
|
||||
// Process connections to adjacent groups
|
||||
var/border_index = 1
|
||||
for(var/datum/air_group/AG in border_group)
|
||||
if(AG.archived_cycle < archived_cycle) //archive other groups information if it has not been archived yet this cycle
|
||||
AG.archive()
|
||||
if(AG.current_cycle < current_cycle)
|
||||
//This if statement makes sure two groups only process their individual connections once!
|
||||
//Without it, each connection would be processed a second time as the second group is evaluated
|
||||
|
||||
var/connection_difference = 0
|
||||
var/turf/simulated/floor/self_border = self_group_borders[border_index]
|
||||
var/turf/simulated/floor/enemy_border = enemies[border_index]
|
||||
|
||||
var/result = air.check_gas_mixture(AG.air)
|
||||
if(result == 1)
|
||||
connection_difference = air.share(AG.air)
|
||||
else if(result == -1)
|
||||
AG.suspend_group_processing()
|
||||
connection_difference = air.share(enemy_border.air)
|
||||
else
|
||||
abort_group = 1
|
||||
break
|
||||
|
||||
if(connection_difference)
|
||||
if(connection_difference > 0)
|
||||
self_border.consider_pressure_difference(connection_difference, get_dir(self_border,enemy_border))
|
||||
else
|
||||
var/turf/enemy_turf = enemy_border
|
||||
if(!isturf(enemy_turf))
|
||||
enemy_turf = enemy_border.loc
|
||||
enemy_turf.consider_pressure_difference(-connection_difference, get_dir(enemy_turf,self_border))
|
||||
|
||||
border_index++
|
||||
|
||||
// Process connections to adjacent tiles
|
||||
border_index = 1
|
||||
if(!abort_group)
|
||||
for(var/atom/enemy_tile in border_individual)
|
||||
var/connection_difference = 0
|
||||
var/turf/simulated/floor/self_border = self_tile_borders[border_index]
|
||||
|
||||
if(istype(enemy_tile, /turf/simulated))
|
||||
if(enemy_tile:archived_cycle < archived_cycle) //archive tile information if not already done
|
||||
enemy_tile:archive()
|
||||
if(enemy_tile:current_cycle < current_cycle)
|
||||
if(air.check_gas_mixture(enemy_tile:air))
|
||||
connection_difference = air.share(enemy_tile:air)
|
||||
else
|
||||
abort_group = 1
|
||||
break
|
||||
else if(isturf(enemy_tile))
|
||||
if(air.check_turf(enemy_tile))
|
||||
connection_difference = air.mimic(enemy_tile)
|
||||
else
|
||||
abort_group = 1
|
||||
break
|
||||
|
||||
if(connection_difference)
|
||||
if(connection_difference > 0)
|
||||
self_border.consider_pressure_difference(connection_difference, get_dir(self_border,enemy_tile))
|
||||
else
|
||||
var/turf/enemy_turf = enemy_tile
|
||||
if(!isturf(enemy_turf))
|
||||
enemy_turf = enemy_tile.loc
|
||||
enemy_turf.consider_pressure_difference(-connection_difference, get_dir(enemy_tile,enemy_turf))
|
||||
|
||||
// Process connections to space
|
||||
border_index = 1
|
||||
if(!abort_group)
|
||||
if(length_space_border > 0)
|
||||
var/turf/space/sample = locate()
|
||||
var/connection_difference = 0
|
||||
|
||||
if(air.check_turf(sample))
|
||||
connection_difference = air.mimic(sample, length_space_border)
|
||||
else
|
||||
abort_group = 1
|
||||
|
||||
if(connection_difference)
|
||||
for(var/turf/simulated/self_border in space_borders)
|
||||
self_border.consider_pressure_difference_space(connection_difference)
|
||||
|
||||
if(abort_group)
|
||||
suspend_group_processing()
|
||||
else
|
||||
if(air.check_tile_graphic())
|
||||
for(var/T in members)
|
||||
var/turf/simulated/member = T
|
||||
member.update_visuals(air)
|
||||
|
||||
|
||||
if(air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
|
||||
for(var/T in members)
|
||||
var/turf/simulated/member = T
|
||||
member.hotspot_expose(air.temperature, CELL_VOLUME)
|
||||
member.consider_superconductivity(starting=1)
|
||||
|
||||
air.react()
|
||||
return
|
||||
|
||||
|
||||
|
||||
object/process_group()
|
||||
current_cycle = air_master.current_cycle
|
||||
|
||||
if(!group_processing) return //See if processing this group as a group
|
||||
|
||||
var/turf/simulated/list/border_individual = list()
|
||||
var/datum/air_group/list/border_group = list()
|
||||
|
||||
var/turf/simulated/list/enemies = list() //used to send the appropriate border tile of a group to the group proc
|
||||
var/enemy_index = 1
|
||||
|
||||
if(archived_cycle < air_master.current_cycle)
|
||||
archive()
|
||||
//Archive air data for use in calculations
|
||||
//But only if another group didn't store it for us
|
||||
|
||||
enemy_index = 1
|
||||
var/abort_group = 0
|
||||
for(var/datum/air_group/AG in border_group)
|
||||
if(AG.archived_cycle < archived_cycle) //archive other groups information if it has not been archived yet this cycle
|
||||
AG.archive()
|
||||
if(AG.current_cycle < current_cycle)
|
||||
//This if statement makes sure two groups only process their individual connections once!
|
||||
//Without it, each connection would be processed a second time as the second group is evaluated
|
||||
|
||||
var/result = air.check_gas_mixture(AG.air)
|
||||
if(result == 1)
|
||||
air.share(AG.air)
|
||||
else if(result == -1)
|
||||
AG.suspend_group_processing()
|
||||
var/turf/simulated/floor/enemy_border = enemies[enemy_index]
|
||||
air.share(enemy_border.air)
|
||||
else
|
||||
abort_group = 0
|
||||
break
|
||||
enemy_index++
|
||||
|
||||
if(!abort_group)
|
||||
for(var/enemy_tile in border_individual)
|
||||
if(istype(enemy_tile, /turf/simulated))
|
||||
if(enemy_tile:archived_cycle < archived_cycle) //archive tile information if not already done
|
||||
enemy_tile:archive()
|
||||
if(enemy_tile:current_cycle < current_cycle)
|
||||
if(air.check_gas_mixture(enemy_tile:air))
|
||||
air.share(enemy_tile:air)
|
||||
else
|
||||
abort_group = 1
|
||||
break
|
||||
else
|
||||
if(air.check_turf(enemy_tile))
|
||||
air.mimic(enemy_tile)
|
||||
else
|
||||
abort_group = 1
|
||||
break
|
||||
|
||||
if(abort_group)
|
||||
suspend_group_processing()
|
||||
|
||||
return
|
||||
@@ -1,178 +0,0 @@
|
||||
|
||||
/atom/proc/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
return null
|
||||
|
||||
|
||||
|
||||
/turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
|
||||
|
||||
|
||||
|
||||
/turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
|
||||
var/datum/gas_mixture/air_contents = return_air()
|
||||
if(!air_contents)
|
||||
return 0
|
||||
if(active_hotspot)
|
||||
if(soh)
|
||||
if(air_contents.toxins > 0.5 && air_contents.oxygen > 0.5)
|
||||
if(active_hotspot.temperature < exposed_temperature)
|
||||
active_hotspot.temperature = exposed_temperature
|
||||
if(active_hotspot.volume < exposed_volume)
|
||||
active_hotspot.volume = exposed_volume
|
||||
return 1
|
||||
|
||||
var/igniting = 0
|
||||
|
||||
if((exposed_temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) && air_contents.toxins > 0.5)
|
||||
igniting = 1
|
||||
|
||||
if(igniting)
|
||||
if(air_contents.oxygen < 0.5 || air_contents.toxins < 0.5)
|
||||
return 0
|
||||
|
||||
if(parent&&parent.group_processing)
|
||||
parent.suspend_group_processing()
|
||||
|
||||
active_hotspot = new(src)
|
||||
active_hotspot.temperature = exposed_temperature
|
||||
active_hotspot.volume = exposed_volume
|
||||
|
||||
active_hotspot.just_spawned = (current_cycle < air_master.current_cycle)
|
||||
//remove just_spawned protection if no longer processing this cell
|
||||
|
||||
//start processing quickly if we aren't already
|
||||
reset_delay()
|
||||
|
||||
return igniting
|
||||
|
||||
//This is the icon for fire on turfs, also helps for nurturing small fires until they are full tile
|
||||
/obj/effect/hotspot
|
||||
anchored = 1
|
||||
mouse_opacity = 0
|
||||
unacidable = 1//So you can't melt fire with acid.
|
||||
icon = 'icons/effects/fire.dmi'
|
||||
icon_state = "1"
|
||||
layer = TURF_LAYER
|
||||
luminosity = 3
|
||||
|
||||
var/volume = 125
|
||||
var/temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
|
||||
var/just_spawned = 1
|
||||
var/bypassing = 0
|
||||
|
||||
|
||||
/obj/effect/hotspot/proc/perform_exposure()
|
||||
var/turf/simulated/floor/location = loc
|
||||
if(!istype(location)) return 0
|
||||
|
||||
if(volume > CELL_VOLUME*0.95) bypassing = 1
|
||||
else bypassing = 0
|
||||
|
||||
if(bypassing)
|
||||
if(!just_spawned)
|
||||
volume = location.air.fuel_burnt*FIRE_GROWTH_RATE
|
||||
temperature = location.air.temperature
|
||||
else
|
||||
var/datum/gas_mixture/affected = location.air.remove_ratio(volume/location.air.volume)
|
||||
affected.temperature = temperature
|
||||
affected.react()
|
||||
temperature = affected.temperature
|
||||
volume = affected.fuel_burnt*FIRE_GROWTH_RATE
|
||||
location.assume_air(affected)
|
||||
|
||||
for(var/atom/item in loc)
|
||||
if(!bypassing)
|
||||
item.temperature_expose(null, temperature, volume)
|
||||
if(item) // It's possible that the item is deleted in temperature_expose
|
||||
item.fire_act(null, temperature, volume)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
/obj/effect/hotspot/process(turf/simulated/list/possible_spread)
|
||||
if(just_spawned)
|
||||
just_spawned = 0
|
||||
return 0
|
||||
|
||||
var/turf/simulated/floor/location = loc
|
||||
if(!istype(location))
|
||||
Kill()
|
||||
return
|
||||
|
||||
if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1))
|
||||
Kill()
|
||||
return
|
||||
|
||||
if(location.air.toxins < 0.5 || location.air.oxygen < 0.5)
|
||||
Kill()
|
||||
return
|
||||
|
||||
perform_exposure()
|
||||
|
||||
if(location.wet) location.wet = 0
|
||||
|
||||
if(bypassing)
|
||||
icon_state = "3"
|
||||
location.burn_tile()
|
||||
|
||||
//Possible spread due to radiated heat
|
||||
if(location.air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD)
|
||||
var/radiated_temperature = location.air.temperature*FIRE_SPREAD_RADIOSITY_SCALE
|
||||
|
||||
for(var/turf/simulated/possible_target in possible_spread)
|
||||
if(!possible_target.active_hotspot)
|
||||
possible_target.hotspot_expose(radiated_temperature, CELL_VOLUME/4)
|
||||
|
||||
else
|
||||
if(volume > CELL_VOLUME*0.4)
|
||||
icon_state = "2"
|
||||
else
|
||||
icon_state = "1"
|
||||
|
||||
if(temperature > location.max_fire_temperature_sustained)
|
||||
location.max_fire_temperature_sustained = temperature
|
||||
|
||||
if(location.heat_capacity && temperature > location.heat_capacity)
|
||||
location.to_be_destroyed = 1
|
||||
/*if(prob(25))
|
||||
location.ReplaceWithSpace()
|
||||
return 0*/
|
||||
return 1
|
||||
|
||||
// Garbage collect itself by nulling reference to it
|
||||
|
||||
/obj/effect/hotspot/proc/Kill()
|
||||
DestroyTurf()
|
||||
if(istype(loc, /turf/simulated))
|
||||
var/turf/simulated/T = loc
|
||||
if(T.active_hotspot == src)
|
||||
T.active_hotspot = null
|
||||
loc = null
|
||||
|
||||
/obj/effect/hotspot/proc/DestroyTurf()
|
||||
|
||||
if(istype(loc, /turf/simulated))
|
||||
var/turf/simulated/T = loc
|
||||
if(T.to_be_destroyed)
|
||||
var/chance_of_deletion
|
||||
if (T.heat_capacity) //beware of division by zero
|
||||
chance_of_deletion = T.max_fire_temperature_sustained / T.heat_capacity * 8 //there is no problem with prob(23456), min() was redundant --rastaf0
|
||||
else
|
||||
chance_of_deletion = 100
|
||||
if(prob(chance_of_deletion))
|
||||
T.ChangeTurf(/turf/space)
|
||||
else
|
||||
T.to_be_destroyed = 0
|
||||
T.max_fire_temperature_sustained = 0
|
||||
|
||||
/obj/effect/hotspot/New()
|
||||
..()
|
||||
set_dir(pick(cardinal))
|
||||
return
|
||||
|
||||
/*
|
||||
/obj/effect/hotspot/Destroy()
|
||||
if (istype(loc, /turf/simulated))
|
||||
DestroyTurf()
|
||||
..()
|
||||
*/
|
||||
@@ -1,933 +0,0 @@
|
||||
/*
|
||||
What are the archived variables for?
|
||||
Calculations are done using the archived variables with the results merged into the regular variables.
|
||||
This prevents race conditions that arise based on the order of tile processing.
|
||||
*/
|
||||
|
||||
#define SPECIFIC_HEAT_TOXIN 200
|
||||
#define SPECIFIC_HEAT_AIR 20
|
||||
#define SPECIFIC_HEAT_CDO 30
|
||||
#define HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins) \
|
||||
(carbon_dioxide*SPECIFIC_HEAT_CDO + (oxygen+nitrogen)*SPECIFIC_HEAT_AIR + toxins*SPECIFIC_HEAT_TOXIN)
|
||||
|
||||
#define MINIMUM_HEAT_CAPACITY 0.0003
|
||||
#define QUANTIZE(variable) (round(variable,0.0001))
|
||||
|
||||
/datum/gas
|
||||
sleeping_agent
|
||||
specific_heat = 40
|
||||
|
||||
oxygen_agent_b
|
||||
specific_heat = 300
|
||||
|
||||
volatile_fuel
|
||||
specific_heat = 30
|
||||
|
||||
var/moles = 0
|
||||
var/specific_heat = 0
|
||||
|
||||
var/moles_archived = 0
|
||||
|
||||
|
||||
/datum/gas_mixture
|
||||
var/oxygen = 0
|
||||
var/carbon_dioxide = 0
|
||||
var/nitrogen = 0
|
||||
var/toxins = 0
|
||||
|
||||
var/volume = CELL_VOLUME
|
||||
|
||||
var/temperature = 0 //in Kelvin, use calculate_temperature() to modify
|
||||
|
||||
var/group_multiplier = 1
|
||||
//Size of the group this gas_mixture is representing.
|
||||
//=1 for singletons
|
||||
|
||||
var/graphic
|
||||
|
||||
var/list/datum/gas/trace_gases = list()
|
||||
|
||||
|
||||
var/tmp/oxygen_archived
|
||||
var/tmp/carbon_dioxide_archived
|
||||
var/tmp/nitrogen_archived
|
||||
var/tmp/toxins_archived
|
||||
|
||||
var/tmp/temperature_archived
|
||||
|
||||
var/tmp/graphic_archived
|
||||
var/tmp/fuel_burnt = 0
|
||||
|
||||
//PV=nRT - related procedures
|
||||
proc/heat_capacity()
|
||||
var/heat_capacity = HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins)
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
heat_capacity += trace_gas.moles*trace_gas.specific_heat
|
||||
return heat_capacity
|
||||
|
||||
|
||||
proc/heat_capacity_archived()
|
||||
var/heat_capacity_archived = HEAT_CAPACITY_CALCULATION(oxygen_archived,carbon_dioxide_archived,nitrogen_archived,toxins_archived)
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
heat_capacity_archived += trace_gas.moles_archived*trace_gas.specific_heat
|
||||
return heat_capacity_archived
|
||||
|
||||
|
||||
proc/total_moles()
|
||||
var/moles = oxygen + carbon_dioxide + nitrogen + toxins
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
moles += trace_gas.moles
|
||||
return moles
|
||||
|
||||
|
||||
proc/return_pressure()
|
||||
if(volume>0)
|
||||
return total_moles()*R_IDEAL_GAS_EQUATION*temperature/volume
|
||||
return 0
|
||||
|
||||
|
||||
proc/return_temperature()
|
||||
return temperature
|
||||
|
||||
|
||||
proc/return_volume()
|
||||
return max(0, volume)
|
||||
|
||||
|
||||
proc/thermal_energy()
|
||||
return temperature*heat_capacity()
|
||||
|
||||
|
||||
//Procedures used for very specific events
|
||||
proc/check_tile_graphic()
|
||||
//returns 1 if graphic changed
|
||||
graphic = null
|
||||
if(toxins > MOLES_PLASMA_VISIBLE)
|
||||
graphic = "plasma"
|
||||
else
|
||||
var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in trace_gases
|
||||
if(sleeping_agent && (sleeping_agent.moles > 1))
|
||||
graphic = "sleeping_agent"
|
||||
else
|
||||
graphic = null
|
||||
|
||||
return graphic != graphic_archived
|
||||
|
||||
proc/react(atom/dump_location)
|
||||
var/reacting = 0 //set to 1 if a notable reaction occured (used by pipe_network)
|
||||
|
||||
if(trace_gases.len > 0)
|
||||
if(temperature > 900)
|
||||
if(toxins > MINIMUM_HEAT_CAPACITY && carbon_dioxide > MINIMUM_HEAT_CAPACITY)
|
||||
var/datum/gas/oxygen_agent_b/trace_gas = locate(/datum/gas/oxygen_agent_b/) in trace_gases
|
||||
if(trace_gas)
|
||||
var/reaction_rate = min(carbon_dioxide*0.75, toxins*0.25, trace_gas.moles*0.05)
|
||||
|
||||
carbon_dioxide -= reaction_rate
|
||||
oxygen += reaction_rate
|
||||
|
||||
trace_gas.moles -= reaction_rate*0.05
|
||||
|
||||
temperature -= (reaction_rate*20000)/heat_capacity()
|
||||
|
||||
reacting = 1
|
||||
|
||||
fuel_burnt = 0
|
||||
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
|
||||
//world << "pre [temperature], [oxygen], [toxins]"
|
||||
if(fire() > 0)
|
||||
reacting = 1
|
||||
//world << "post [temperature], [oxygen], [toxins]"
|
||||
|
||||
return reacting
|
||||
|
||||
proc/fire()
|
||||
var/energy_released = 0
|
||||
var/old_heat_capacity = heat_capacity()
|
||||
|
||||
var/datum/gas/volatile_fuel/fuel_store = locate(/datum/gas/volatile_fuel/) in trace_gases
|
||||
if(fuel_store) //General volatile gas burn
|
||||
var/burned_fuel = 0
|
||||
|
||||
if(oxygen < fuel_store.moles)
|
||||
burned_fuel = oxygen
|
||||
fuel_store.moles -= burned_fuel
|
||||
oxygen = 0
|
||||
else
|
||||
burned_fuel = fuel_store.moles
|
||||
oxygen -= fuel_store.moles
|
||||
trace_gases -= fuel_store
|
||||
fuel_store = null
|
||||
|
||||
energy_released += FIRE_CARBON_ENERGY_RELEASED * burned_fuel
|
||||
carbon_dioxide += burned_fuel
|
||||
fuel_burnt += burned_fuel
|
||||
|
||||
//Handle plasma burning
|
||||
if(toxins > MINIMUM_HEAT_CAPACITY)
|
||||
var/plasma_burn_rate = 0
|
||||
var/oxygen_burn_rate = 0
|
||||
//more plasma released at higher temperatures
|
||||
var/temperature_scale
|
||||
if(temperature > PLASMA_UPPER_TEMPERATURE)
|
||||
temperature_scale = 1
|
||||
else
|
||||
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
|
||||
if(temperature_scale > 0)
|
||||
oxygen_burn_rate = 1.4 - temperature_scale
|
||||
if(oxygen > toxins*PLASMA_OXYGEN_FULLBURN)
|
||||
plasma_burn_rate = (toxins*temperature_scale)/4
|
||||
else
|
||||
plasma_burn_rate = (temperature_scale*(oxygen/PLASMA_OXYGEN_FULLBURN))/4
|
||||
if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
|
||||
toxins -= plasma_burn_rate
|
||||
oxygen -= plasma_burn_rate*oxygen_burn_rate
|
||||
carbon_dioxide += plasma_burn_rate
|
||||
|
||||
energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
|
||||
|
||||
fuel_burnt += (plasma_burn_rate)*(1+oxygen_burn_rate)
|
||||
|
||||
if(energy_released > 0)
|
||||
var/new_heat_capacity = heat_capacity()
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity
|
||||
|
||||
return fuel_burnt
|
||||
|
||||
proc/archive()
|
||||
//Update archived versions of variables
|
||||
//Returns: 1 in all cases
|
||||
|
||||
proc/merge(datum/gas_mixture/giver)
|
||||
//Merges all air from giver into self. Deletes giver.
|
||||
//Returns: 1 on success (no failure cases yet)
|
||||
|
||||
proc/check_then_merge(datum/gas_mixture/giver)
|
||||
//Similar to merge(...) but first checks to see if the amount of air assumed is small enough
|
||||
// that group processing is still accurate for source (aborts if not)
|
||||
//Returns: 1 on successful merge, 0 if the check failed
|
||||
|
||||
proc/remove(amount)
|
||||
//Proportionally removes amount of gas from the gas_mixture
|
||||
//Returns: gas_mixture with the gases removed
|
||||
|
||||
proc/remove_ratio(ratio)
|
||||
//Proportionally removes amount of gas from the gas_mixture
|
||||
//Returns: gas_mixture with the gases removed
|
||||
|
||||
proc/subtract(datum/gas_mixture/right_side)
|
||||
//Subtracts right_side from air_mixture. Used to help turfs mingle
|
||||
|
||||
proc/check_then_remove(amount)
|
||||
//Similar to remove(...) but first checks to see if the amount of air removed is small enough
|
||||
// that group processing is still accurate for source (aborts if not)
|
||||
//Returns: gas_mixture with the gases removed or null
|
||||
|
||||
proc/copy_from(datum/gas_mixture/sample)
|
||||
//Copies variables from sample
|
||||
|
||||
proc/share(datum/gas_mixture/sharer)
|
||||
//Performs air sharing calculations between two gas_mixtures assuming only 1 boundary length
|
||||
//Return: amount of gas exchanged (+ if sharer received)
|
||||
|
||||
proc/mimic(turf/model)
|
||||
//Similar to share(...), except the model is not modified
|
||||
//Return: amount of gas exchanged
|
||||
|
||||
proc/check_gas_mixture(datum/gas_mixture/sharer)
|
||||
//Returns: 0 if the self-check failed then -1 if sharer-check failed then 1 if both checks pass
|
||||
|
||||
proc/check_turf(turf/model)
|
||||
//Returns: 0 if self-check failed or 1 if check passes
|
||||
|
||||
// check_me_then_share(datum/gas_mixture/sharer)
|
||||
//Similar to share(...) but first checks to see if amount of air moved is small enough
|
||||
// that group processing is still accurate for source (aborts if not)
|
||||
//Returns: 1 on successful share, 0 if the check failed
|
||||
|
||||
// check_me_then_mimic(turf/model)
|
||||
//Similar to mimic(...) but first checks to see if amount of air moved is small enough
|
||||
// that group processing is still accurate (aborts if not)
|
||||
//Returns: 1 on successful mimic, 0 if the check failed
|
||||
|
||||
// check_both_then_share(datum/gas_mixture/sharer)
|
||||
//Similar to check_me_then_share(...) but also checks to see if amount of air moved is small enough
|
||||
// that group processing is still accurate for the sharer (aborts if not)
|
||||
//Returns: 0 if the self-check failed then -1 if sharer-check failed then 1 if successful share
|
||||
|
||||
|
||||
proc/temperature_mimic(turf/model, conduction_coefficient)
|
||||
|
||||
proc/temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
|
||||
|
||||
proc/temperature_turf_share(turf/simulated/sharer, conduction_coefficient)
|
||||
|
||||
|
||||
proc/check_me_then_temperature_mimic(turf/model, conduction_coefficient)
|
||||
|
||||
proc/check_me_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
|
||||
|
||||
proc/check_both_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
|
||||
|
||||
proc/check_me_then_temperature_turf_share(turf/simulated/sharer, conduction_coefficient)
|
||||
|
||||
proc/compare(datum/gas_mixture/sample)
|
||||
//Compares sample to self to see if within acceptable ranges that group processing may be enabled
|
||||
|
||||
archive()
|
||||
oxygen_archived = oxygen
|
||||
carbon_dioxide_archived = carbon_dioxide
|
||||
nitrogen_archived = nitrogen
|
||||
toxins_archived = toxins
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
trace_gas.moles_archived = trace_gas.moles
|
||||
|
||||
temperature_archived = temperature
|
||||
|
||||
graphic_archived = graphic
|
||||
|
||||
return 1
|
||||
|
||||
check_then_merge(datum/gas_mixture/giver)
|
||||
if(!giver)
|
||||
return 0
|
||||
if(((giver.oxygen > MINIMUM_AIR_TO_SUSPEND) && (giver.oxygen >= oxygen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((giver.carbon_dioxide > MINIMUM_AIR_TO_SUSPEND) && (giver.carbon_dioxide >= carbon_dioxide*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((giver.nitrogen > MINIMUM_AIR_TO_SUSPEND) && (giver.nitrogen >= nitrogen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((giver.toxins > MINIMUM_AIR_TO_SUSPEND) && (giver.toxins >= toxins*MINIMUM_AIR_RATIO_TO_SUSPEND)))
|
||||
return 0
|
||||
if(abs(giver.temperature - temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
|
||||
return 0
|
||||
|
||||
if(giver.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in giver.trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if((trace_gas.moles > MINIMUM_AIR_TO_SUSPEND) && (!corresponding || (trace_gas.moles >= corresponding.moles*MINIMUM_AIR_RATIO_TO_SUSPEND)))
|
||||
return 0
|
||||
|
||||
return merge(giver)
|
||||
|
||||
merge(datum/gas_mixture/giver)
|
||||
if(!giver)
|
||||
return 0
|
||||
|
||||
if(abs(temperature-giver.temperature)>MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity()*group_multiplier
|
||||
var/giver_heat_capacity = giver.heat_capacity()*giver.group_multiplier
|
||||
var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity
|
||||
if(combined_heat_capacity != 0)
|
||||
temperature = (giver.temperature*giver_heat_capacity + temperature*self_heat_capacity)/combined_heat_capacity
|
||||
|
||||
if((group_multiplier>1)||(giver.group_multiplier>1))
|
||||
oxygen += giver.oxygen*giver.group_multiplier/group_multiplier
|
||||
carbon_dioxide += giver.carbon_dioxide*giver.group_multiplier/group_multiplier
|
||||
nitrogen += giver.nitrogen*giver.group_multiplier/group_multiplier
|
||||
toxins += giver.toxins*giver.group_multiplier/group_multiplier
|
||||
else
|
||||
oxygen += giver.oxygen
|
||||
carbon_dioxide += giver.carbon_dioxide
|
||||
nitrogen += giver.nitrogen
|
||||
toxins += giver.toxins
|
||||
|
||||
if(giver.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in giver.trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(!corresponding)
|
||||
corresponding = new trace_gas.type()
|
||||
trace_gases += corresponding
|
||||
corresponding.moles += trace_gas.moles*giver.group_multiplier/group_multiplier
|
||||
|
||||
// qdel(giver)
|
||||
return 1
|
||||
|
||||
remove(amount)
|
||||
|
||||
var/sum = total_moles()
|
||||
amount = min(amount,sum) //Can not take more air than tile has!
|
||||
if(amount <= 0)
|
||||
return null
|
||||
|
||||
var/datum/gas_mixture/removed = new
|
||||
|
||||
|
||||
removed.oxygen = QUANTIZE((oxygen/sum)*amount)
|
||||
removed.nitrogen = QUANTIZE((nitrogen/sum)*amount)
|
||||
removed.carbon_dioxide = QUANTIZE((carbon_dioxide/sum)*amount)
|
||||
removed.toxins = QUANTIZE((toxins/sum)*amount)
|
||||
|
||||
oxygen -= removed.oxygen/group_multiplier
|
||||
nitrogen -= removed.nitrogen/group_multiplier
|
||||
carbon_dioxide -= removed.carbon_dioxide/group_multiplier
|
||||
toxins -= removed.toxins/group_multiplier
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
var/datum/gas/corresponding = new trace_gas.type()
|
||||
removed.trace_gases += corresponding
|
||||
|
||||
corresponding.moles = (trace_gas.moles/sum)*amount
|
||||
trace_gas.moles -= corresponding.moles/group_multiplier
|
||||
|
||||
removed.temperature = temperature
|
||||
|
||||
return removed
|
||||
|
||||
remove_ratio(ratio)
|
||||
|
||||
if(ratio <= 0)
|
||||
return null
|
||||
|
||||
ratio = min(ratio, 1)
|
||||
|
||||
var/datum/gas_mixture/removed = new
|
||||
|
||||
removed.oxygen = QUANTIZE(oxygen*ratio)
|
||||
removed.nitrogen = QUANTIZE(nitrogen*ratio)
|
||||
removed.carbon_dioxide = QUANTIZE(carbon_dioxide*ratio)
|
||||
removed.toxins = QUANTIZE(toxins*ratio)
|
||||
|
||||
oxygen -= removed.oxygen/group_multiplier
|
||||
nitrogen -= removed.nitrogen/group_multiplier
|
||||
carbon_dioxide -= removed.carbon_dioxide/group_multiplier
|
||||
toxins -= removed.toxins/group_multiplier
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
var/datum/gas/corresponding = new trace_gas.type()
|
||||
removed.trace_gases += corresponding
|
||||
|
||||
corresponding.moles = trace_gas.moles*ratio
|
||||
trace_gas.moles -= corresponding.moles/group_multiplier
|
||||
|
||||
removed.temperature = temperature
|
||||
|
||||
return removed
|
||||
|
||||
check_then_remove(amount)
|
||||
|
||||
//Since it is all proportional, the check may be done on the gas as a whole
|
||||
var/sum = total_moles()
|
||||
amount = min(amount,sum) //Can not take more air than tile has!
|
||||
|
||||
if((amount > MINIMUM_AIR_RATIO_TO_SUSPEND) && (amount > sum*MINIMUM_AIR_RATIO_TO_SUSPEND))
|
||||
return 0
|
||||
|
||||
return remove(amount)
|
||||
|
||||
copy_from(datum/gas_mixture/sample)
|
||||
oxygen = sample.oxygen
|
||||
carbon_dioxide = sample.carbon_dioxide
|
||||
nitrogen = sample.nitrogen
|
||||
toxins = sample.toxins
|
||||
|
||||
trace_gases.len=null
|
||||
if(sample.trace_gases.len > 0)
|
||||
for(var/datum/gas/trace_gas in sample.trace_gases)
|
||||
var/datum/gas/corresponding = new trace_gas.type()
|
||||
trace_gases += corresponding
|
||||
|
||||
corresponding.moles = trace_gas.moles
|
||||
|
||||
temperature = sample.temperature
|
||||
|
||||
return 1
|
||||
|
||||
subtract(datum/gas_mixture/right_side)
|
||||
oxygen -= right_side.oxygen
|
||||
carbon_dioxide -= right_side.carbon_dioxide
|
||||
nitrogen -= right_side.nitrogen
|
||||
toxins -= right_side.toxins
|
||||
|
||||
if((trace_gases.len > 0)||(right_side.trace_gases.len > 0))
|
||||
for(var/datum/gas/trace_gas in right_side.trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(!corresponding)
|
||||
corresponding = new trace_gas.type()
|
||||
trace_gases += corresponding
|
||||
|
||||
corresponding.moles -= trace_gas.moles
|
||||
|
||||
return 1
|
||||
|
||||
check_gas_mixture(datum/gas_mixture/sharer)
|
||||
if(!sharer) return 0
|
||||
var/delta_oxygen = (oxygen_archived - sharer.oxygen_archived)/5
|
||||
var/delta_carbon_dioxide = (carbon_dioxide_archived - sharer.carbon_dioxide_archived)/5
|
||||
var/delta_nitrogen = (nitrogen_archived - sharer.nitrogen_archived)/5
|
||||
var/delta_toxins = (toxins_archived - sharer.toxins_archived)/5
|
||||
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
|
||||
|
||||
if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)))
|
||||
return 0
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
|
||||
return 0
|
||||
|
||||
if(sharer.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in sharer.trace_gases)
|
||||
if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(corresponding)
|
||||
if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4)
|
||||
return 0
|
||||
else
|
||||
return 0
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
|
||||
if(!locate(trace_gas.type) in sharer.trace_gases)
|
||||
return 0
|
||||
|
||||
if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= sharer.oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= sharer.carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= sharer.nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= sharer.toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)))
|
||||
return -1
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases
|
||||
if(corresponding)
|
||||
if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4)
|
||||
return -1
|
||||
else
|
||||
return -1
|
||||
|
||||
return 1
|
||||
|
||||
check_turf(turf/model)
|
||||
var/delta_oxygen = (oxygen_archived - model.oxygen)/5
|
||||
var/delta_carbon_dioxide = (carbon_dioxide_archived - model.carbon_dioxide)/5
|
||||
var/delta_nitrogen = (nitrogen_archived - model.nitrogen)/5
|
||||
var/delta_toxins = (toxins_archived - model.toxins)/5
|
||||
|
||||
var/delta_temperature = (temperature_archived - model.temperature)
|
||||
|
||||
if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)))
|
||||
return 0
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
|
||||
return 0
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
share(datum/gas_mixture/sharer)
|
||||
if(!sharer) return 0
|
||||
var/delta_oxygen = QUANTIZE(oxygen_archived - sharer.oxygen_archived)/5
|
||||
var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - sharer.carbon_dioxide_archived)/5
|
||||
var/delta_nitrogen = QUANTIZE(nitrogen_archived - sharer.nitrogen_archived)/5
|
||||
var/delta_toxins = QUANTIZE(toxins_archived - sharer.toxins_archived)/5
|
||||
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
|
||||
|
||||
var/old_self_heat_capacity = 0
|
||||
var/old_sharer_heat_capacity = 0
|
||||
|
||||
var/heat_capacity_self_to_sharer = 0
|
||||
var/heat_capacity_sharer_to_self = 0
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
|
||||
var/delta_air = delta_oxygen+delta_nitrogen
|
||||
if(delta_air)
|
||||
var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air
|
||||
if(delta_air > 0)
|
||||
heat_capacity_self_to_sharer += air_heat_capacity
|
||||
else
|
||||
heat_capacity_sharer_to_self -= air_heat_capacity
|
||||
|
||||
if(delta_carbon_dioxide)
|
||||
var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide
|
||||
if(delta_carbon_dioxide > 0)
|
||||
heat_capacity_self_to_sharer += carbon_dioxide_heat_capacity
|
||||
else
|
||||
heat_capacity_sharer_to_self -= carbon_dioxide_heat_capacity
|
||||
|
||||
if(delta_toxins)
|
||||
var/toxins_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_toxins
|
||||
if(delta_toxins > 0)
|
||||
heat_capacity_self_to_sharer += toxins_heat_capacity
|
||||
else
|
||||
heat_capacity_sharer_to_self -= toxins_heat_capacity
|
||||
|
||||
old_self_heat_capacity = heat_capacity()*group_multiplier
|
||||
old_sharer_heat_capacity = sharer.heat_capacity()*sharer.group_multiplier
|
||||
|
||||
oxygen -= delta_oxygen/group_multiplier
|
||||
sharer.oxygen += delta_oxygen/sharer.group_multiplier
|
||||
|
||||
carbon_dioxide -= delta_carbon_dioxide/group_multiplier
|
||||
sharer.carbon_dioxide += delta_carbon_dioxide/sharer.group_multiplier
|
||||
|
||||
nitrogen -= delta_nitrogen/group_multiplier
|
||||
sharer.nitrogen += delta_nitrogen/sharer.group_multiplier
|
||||
|
||||
toxins -= delta_toxins/group_multiplier
|
||||
sharer.toxins += delta_toxins/sharer.group_multiplier
|
||||
|
||||
var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins)
|
||||
|
||||
var/list/trace_types_considered = list()
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases
|
||||
var/delta = 0
|
||||
|
||||
if(corresponding)
|
||||
delta = QUANTIZE(trace_gas.moles_archived - corresponding.moles_archived)/5
|
||||
else
|
||||
corresponding = new trace_gas.type()
|
||||
sharer.trace_gases += corresponding
|
||||
|
||||
delta = trace_gas.moles_archived/5
|
||||
|
||||
trace_gas.moles -= delta/group_multiplier
|
||||
corresponding.moles += delta/sharer.group_multiplier
|
||||
|
||||
if(delta)
|
||||
var/individual_heat_capacity = trace_gas.specific_heat*delta
|
||||
if(delta > 0)
|
||||
heat_capacity_self_to_sharer += individual_heat_capacity
|
||||
else
|
||||
heat_capacity_sharer_to_self -= individual_heat_capacity
|
||||
|
||||
moved_moles += delta
|
||||
|
||||
trace_types_considered += trace_gas.type
|
||||
|
||||
|
||||
if(sharer.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in sharer.trace_gases)
|
||||
if(trace_gas.type in trace_types_considered) continue
|
||||
else
|
||||
var/datum/gas/corresponding
|
||||
var/delta = 0
|
||||
|
||||
corresponding = new trace_gas.type()
|
||||
trace_gases += corresponding
|
||||
|
||||
delta = trace_gas.moles_archived/5
|
||||
|
||||
trace_gas.moles -= delta/sharer.group_multiplier
|
||||
corresponding.moles += delta/group_multiplier
|
||||
|
||||
//Guaranteed transfer from sharer to self
|
||||
var/individual_heat_capacity = trace_gas.specific_heat*delta
|
||||
heat_capacity_sharer_to_self += individual_heat_capacity
|
||||
|
||||
moved_moles += -delta
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/new_self_heat_capacity = old_self_heat_capacity + heat_capacity_sharer_to_self - heat_capacity_self_to_sharer
|
||||
var/new_sharer_heat_capacity = old_sharer_heat_capacity + heat_capacity_self_to_sharer - heat_capacity_sharer_to_self
|
||||
|
||||
if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
temperature = (old_self_heat_capacity*temperature - heat_capacity_self_to_sharer*temperature_archived + heat_capacity_sharer_to_self*sharer.temperature_archived)/new_self_heat_capacity
|
||||
|
||||
if(new_sharer_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
sharer.temperature = (old_sharer_heat_capacity*sharer.temperature-heat_capacity_sharer_to_self*sharer.temperature_archived + heat_capacity_self_to_sharer*temperature_archived)/new_sharer_heat_capacity
|
||||
|
||||
if(abs(old_sharer_heat_capacity) > MINIMUM_HEAT_CAPACITY)
|
||||
if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.10) // <10% change in sharer heat capacity
|
||||
temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT)
|
||||
|
||||
if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - sharer.temperature_archived*(sharer.total_moles() - moved_moles)
|
||||
return delta_pressure*R_IDEAL_GAS_EQUATION/volume
|
||||
|
||||
else
|
||||
return 0
|
||||
|
||||
mimic(turf/model, border_multiplier)
|
||||
var/delta_oxygen = QUANTIZE(oxygen_archived - model.oxygen)/5
|
||||
var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - model.carbon_dioxide)/5
|
||||
var/delta_nitrogen = QUANTIZE(nitrogen_archived - model.nitrogen)/5
|
||||
var/delta_toxins = QUANTIZE(toxins_archived - model.toxins)/5
|
||||
|
||||
var/delta_temperature = (temperature_archived - model.temperature)
|
||||
|
||||
var/heat_transferred = 0
|
||||
var/old_self_heat_capacity = 0
|
||||
var/heat_capacity_transferred = 0
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
|
||||
var/delta_air = delta_oxygen+delta_nitrogen
|
||||
if(delta_air)
|
||||
var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air
|
||||
heat_transferred -= air_heat_capacity*model.temperature
|
||||
heat_capacity_transferred -= air_heat_capacity
|
||||
|
||||
if(delta_carbon_dioxide)
|
||||
var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide
|
||||
heat_transferred -= carbon_dioxide_heat_capacity*model.temperature
|
||||
heat_capacity_transferred -= carbon_dioxide_heat_capacity
|
||||
|
||||
if(delta_toxins)
|
||||
var/toxins_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_toxins
|
||||
heat_transferred -= toxins_heat_capacity*model.temperature
|
||||
heat_capacity_transferred -= toxins_heat_capacity
|
||||
|
||||
old_self_heat_capacity = heat_capacity()*group_multiplier
|
||||
|
||||
if(border_multiplier)
|
||||
oxygen -= delta_oxygen*border_multiplier/group_multiplier
|
||||
carbon_dioxide -= delta_carbon_dioxide*border_multiplier/group_multiplier
|
||||
nitrogen -= delta_nitrogen*border_multiplier/group_multiplier
|
||||
toxins -= delta_toxins*border_multiplier/group_multiplier
|
||||
else
|
||||
oxygen -= delta_oxygen/group_multiplier
|
||||
carbon_dioxide -= delta_carbon_dioxide/group_multiplier
|
||||
nitrogen -= delta_nitrogen/group_multiplier
|
||||
toxins -= delta_toxins/group_multiplier
|
||||
|
||||
var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins)
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
var/delta = 0
|
||||
|
||||
delta = trace_gas.moles_archived/5
|
||||
|
||||
if(border_multiplier)
|
||||
trace_gas.moles -= delta*border_multiplier/group_multiplier
|
||||
else
|
||||
trace_gas.moles -= delta/group_multiplier
|
||||
|
||||
var/heat_cap_transferred = delta*trace_gas.specific_heat
|
||||
heat_transferred += heat_cap_transferred*temperature_archived
|
||||
heat_capacity_transferred += heat_cap_transferred
|
||||
moved_moles += delta
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/new_self_heat_capacity = old_self_heat_capacity - heat_capacity_transferred
|
||||
if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
if(border_multiplier)
|
||||
temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity
|
||||
else
|
||||
temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity
|
||||
|
||||
temperature_mimic(model, model.thermal_conductivity, border_multiplier)
|
||||
|
||||
if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - model.temperature*(model.oxygen+model.carbon_dioxide+model.nitrogen+model.toxins)
|
||||
return delta_pressure*R_IDEAL_GAS_EQUATION/volume
|
||||
else
|
||||
return 0
|
||||
|
||||
check_both_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
|
||||
|
||||
var/self_heat_capacity = heat_capacity_archived()
|
||||
var/sharer_heat_capacity = sharer.heat_capacity_archived()
|
||||
|
||||
var/self_temperature_delta = 0
|
||||
var/sharer_temperature_delta = 0
|
||||
|
||||
if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
|
||||
|
||||
self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
|
||||
sharer_temperature_delta = heat/(sharer_heat_capacity*sharer.group_multiplier)
|
||||
else
|
||||
return 1
|
||||
|
||||
if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
|
||||
&& (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
|
||||
return 0
|
||||
|
||||
if((abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
|
||||
&& (abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*sharer.temperature_archived))
|
||||
return -1
|
||||
|
||||
temperature += self_temperature_delta
|
||||
sharer.temperature += sharer_temperature_delta
|
||||
|
||||
return 1
|
||||
//Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency
|
||||
|
||||
check_me_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
|
||||
|
||||
var/self_heat_capacity = heat_capacity_archived()
|
||||
var/sharer_heat_capacity = sharer.heat_capacity_archived()
|
||||
|
||||
var/self_temperature_delta = 0
|
||||
var/sharer_temperature_delta = 0
|
||||
|
||||
if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
|
||||
|
||||
self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
|
||||
sharer_temperature_delta = heat/(sharer_heat_capacity*sharer.group_multiplier)
|
||||
else
|
||||
return 1
|
||||
|
||||
if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
|
||||
&& (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
|
||||
return 0
|
||||
|
||||
temperature += self_temperature_delta
|
||||
sharer.temperature += sharer_temperature_delta
|
||||
|
||||
return 1
|
||||
//Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency
|
||||
|
||||
check_me_then_temperature_turf_share(turf/simulated/sharer, conduction_coefficient)
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature)
|
||||
|
||||
var/self_temperature_delta = 0
|
||||
var/sharer_temperature_delta = 0
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity_archived()
|
||||
|
||||
if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity))
|
||||
|
||||
self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
|
||||
sharer_temperature_delta = heat/sharer.heat_capacity
|
||||
else
|
||||
return 1
|
||||
|
||||
if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
|
||||
&& (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
|
||||
return 0
|
||||
|
||||
temperature += self_temperature_delta
|
||||
sharer.temperature += sharer_temperature_delta
|
||||
|
||||
return 1
|
||||
//Logic integrated from: temperature_turf_share(sharer, conduction_coefficient) for efficiency
|
||||
|
||||
check_me_then_temperature_mimic(turf/model, conduction_coefficient)
|
||||
var/delta_temperature = (temperature_archived - model.temperature)
|
||||
var/self_temperature_delta = 0
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity_archived()
|
||||
|
||||
if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity))
|
||||
|
||||
self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
|
||||
|
||||
if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
|
||||
&& (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
|
||||
return 0
|
||||
|
||||
temperature += self_temperature_delta
|
||||
|
||||
return 1
|
||||
//Logic integrated from: temperature_mimic(model, conduction_coefficient) for efficiency
|
||||
|
||||
temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
|
||||
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity_archived()
|
||||
var/sharer_heat_capacity = sharer.heat_capacity_archived()
|
||||
|
||||
if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
|
||||
|
||||
temperature -= heat/(self_heat_capacity*group_multiplier)
|
||||
sharer.temperature += heat/(sharer_heat_capacity*sharer.group_multiplier)
|
||||
|
||||
temperature_mimic(turf/model, conduction_coefficient, border_multiplier)
|
||||
var/delta_temperature = (temperature - model.temperature)
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity()//_archived()
|
||||
|
||||
if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity))
|
||||
|
||||
if(border_multiplier)
|
||||
temperature -= heat*border_multiplier/(self_heat_capacity*group_multiplier)
|
||||
else
|
||||
temperature -= heat/(self_heat_capacity*group_multiplier)
|
||||
|
||||
temperature_turf_share(turf/simulated/sharer, conduction_coefficient)
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature)
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity()
|
||||
|
||||
if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity))
|
||||
|
||||
temperature -= heat/(self_heat_capacity*group_multiplier)
|
||||
sharer.temperature += heat/sharer.heat_capacity
|
||||
|
||||
compare(datum/gas_mixture/sample)
|
||||
if((abs(oxygen-sample.oxygen) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((oxygen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen)))
|
||||
return 0
|
||||
if((abs(nitrogen-sample.nitrogen) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((nitrogen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen) || (nitrogen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen)))
|
||||
return 0
|
||||
if((abs(carbon_dioxide-sample.carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide)))
|
||||
return 0
|
||||
if((abs(toxins-sample.toxins) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((toxins < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins) || (toxins > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins)))
|
||||
return 0
|
||||
|
||||
if(total_moles() > MINIMUM_AIR_TO_SUSPEND)
|
||||
if((abs(temperature-sample.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \
|
||||
((temperature < (1-MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature) || (temperature > (1+MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature)))
|
||||
//world << "temp fail [temperature] & [sample.temperature]"
|
||||
return 0
|
||||
|
||||
if(sample.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in sample.trace_gases)
|
||||
if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(corresponding)
|
||||
if((abs(trace_gas.moles - corresponding.moles) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((corresponding.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles) || (corresponding.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles)))
|
||||
return 0
|
||||
else
|
||||
return 0
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
if(trace_gas.moles > MINIMUM_AIR_TO_SUSPEND)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in sample.trace_gases
|
||||
if(corresponding)
|
||||
if((abs(trace_gas.moles - corresponding.moles) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((trace_gas.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*corresponding.moles) || (trace_gas.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*corresponding.moles)))
|
||||
return 0
|
||||
else
|
||||
return 0
|
||||
return 1
|
||||
@@ -1,101 +0,0 @@
|
||||
/turf/simulated/proc/find_group()
|
||||
//Basically, join any nearby valid groups
|
||||
// If more than one, pick one with most members at my borders
|
||||
// If can not find any but there was an ungrouped at border with me, call for group assembly
|
||||
|
||||
var/turf/simulated/floor/north = get_step(src,NORTH)
|
||||
var/turf/simulated/floor/south = get_step(src,SOUTH)
|
||||
var/turf/simulated/floor/east = get_step(src,EAST)
|
||||
var/turf/simulated/floor/west = get_step(src,WEST)
|
||||
|
||||
//Clear those we do not have access to
|
||||
if(!CanPass(null, north, null, 1) || !istype(north))
|
||||
north = null
|
||||
if(!CanPass(null, south, null, 1) || !istype(south))
|
||||
south = null
|
||||
if(!CanPass(null, east, null, 1) || !istype(east))
|
||||
east = null
|
||||
if(!CanPass(null, west, null, 1) || !istype(west))
|
||||
west = null
|
||||
|
||||
var/new_group_possible = 0
|
||||
|
||||
var/north_votes = 0
|
||||
var/south_votes = 0
|
||||
var/east_votes = 0
|
||||
|
||||
if(north)
|
||||
if(north.parent)
|
||||
north_votes = 1
|
||||
|
||||
if(south && (south.parent == north.parent))
|
||||
north_votes++
|
||||
south = null
|
||||
|
||||
if(east && (east.parent == north.parent))
|
||||
north_votes++
|
||||
east = null
|
||||
|
||||
if(west && (west.parent == north.parent))
|
||||
north_votes++
|
||||
west = null
|
||||
else
|
||||
new_group_possible = 1
|
||||
|
||||
if(south)
|
||||
if(south.parent)
|
||||
south_votes = 1
|
||||
|
||||
if(east && (east.parent == south.parent))
|
||||
south_votes++
|
||||
east = null
|
||||
|
||||
if(west && (west.parent == south.parent))
|
||||
south_votes++
|
||||
west = null
|
||||
else
|
||||
new_group_possible = 1
|
||||
|
||||
if(east)
|
||||
if(east.parent)
|
||||
east_votes = 1
|
||||
|
||||
if(west && (west.parent == east.parent))
|
||||
east_votes++
|
||||
west = null
|
||||
else
|
||||
new_group_possible = 1
|
||||
|
||||
// world << "[north_votes], [south_votes], [east_votes]"
|
||||
|
||||
var/datum/air_group/group_joined = null
|
||||
|
||||
if(west)
|
||||
if(west.parent)
|
||||
group_joined = west.parent
|
||||
else
|
||||
new_group_possible = 1
|
||||
|
||||
if(north_votes && (north_votes >= south_votes) && (north_votes >= east_votes))
|
||||
group_joined = north.parent
|
||||
else if(south_votes && (south_votes >= east_votes))
|
||||
group_joined = south.parent
|
||||
else if(east_votes)
|
||||
group_joined = east.parent
|
||||
|
||||
if (istype(group_joined))
|
||||
if (group_joined.group_processing)
|
||||
group_joined.suspend_group_processing()
|
||||
group_joined.members += src
|
||||
parent=group_joined
|
||||
|
||||
air_master.tiles_to_update += group_joined.members
|
||||
return 1
|
||||
|
||||
else if(new_group_possible)
|
||||
air_master.assemble_group_turf(src)
|
||||
return 1
|
||||
|
||||
else
|
||||
air_master.active_singletons += src
|
||||
return 1
|
||||
@@ -1,335 +0,0 @@
|
||||
/*
|
||||
Overview:
|
||||
The air_master global variable is the workhorse for the system.
|
||||
|
||||
Why are you archiving data before modifying it?
|
||||
The general concept with archiving data and having each tile keep track of when they were last updated is to keep everything symmetric
|
||||
and totally independent of the order they are read in an update cycle.
|
||||
This prevents abnormalities like air/fire spreading rapidly in one direction and super slowly in the other.
|
||||
|
||||
Why not just archive everything and then calculate?
|
||||
Efficiency. While a for-loop that goes through all tiles and groups to archive their information before doing any calculations seems simple, it is
|
||||
slightly less efficient than the archive-before-modify/read method.
|
||||
|
||||
Why is there a cycle check for calculating data as well?
|
||||
This ensures that every connection between group-tile, tile-tile, and group-group is only evaluated once per loop.
|
||||
|
||||
|
||||
|
||||
|
||||
Important variables:
|
||||
air_master.groups_to_rebuild (list)
|
||||
A list of air groups that have had their geometry occluded and thus may need to be split in half.
|
||||
A set of adjacent groups put in here will join together if validly connected.
|
||||
This is done before air system calculations for a cycle.
|
||||
air_master.tiles_to_update (list)
|
||||
Turfs that are in this list have their border data updated before the next air calculations for a cycle.
|
||||
Place turfs in this list rather than call the proc directly to prevent race conditions
|
||||
|
||||
turf/simulated.archive() and datum/air_group.archive()
|
||||
This stores all data for.
|
||||
If you modify, make sure to update the archived_cycle to prevent race conditions and maintain symmetry
|
||||
|
||||
atom/CanPass(atom/movable/mover, turf/target, height, air_group)
|
||||
returns 1 for allow pass and 0 for deny pass
|
||||
Turfs automatically call this for all objects/mobs in its turf.
|
||||
This is called both as source.CanPass(target, height, air_group)
|
||||
and target.CanPass(source, height, air_group)
|
||||
|
||||
Cases for the parameters
|
||||
1. This is called with args (mover, location, height>0, air_group=0) for normal objects.
|
||||
2. This is called with args (null, location, height=0, air_group=0) for flowing air.
|
||||
3. This is called with args (null, location, height=?, air_group=1) for determining group boundaries.
|
||||
|
||||
Cases 2 and 3 would be different for doors or other objects open and close fairly often.
|
||||
(Case 3 would return 0 always while Case 2 would return 0 only when the door is open)
|
||||
This prevents the necessity of re-evaluating group geometry every time a door opens/closes.
|
||||
|
||||
|
||||
Important Procedures
|
||||
air_master.process()
|
||||
This first processes the air_master update/rebuild lists then processes all groups and tiles for air calculations
|
||||
|
||||
|
||||
*/
|
||||
|
||||
var/kill_air = 0
|
||||
|
||||
atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
||||
return (!density || !height || air_group)
|
||||
|
||||
turf
|
||||
CanPass(atom/movable/mover, turf/target, height=1.5,air_group=0)
|
||||
if(!target) return 0
|
||||
|
||||
if(istype(mover)) // turf/Enter(...) will perform more advanced checks
|
||||
return !density
|
||||
|
||||
else // Now, doing more detailed checks for air movement and air group formation
|
||||
if(target.blocks_air||blocks_air)
|
||||
return 0
|
||||
|
||||
for(var/obj/obstacle in src)
|
||||
if(!obstacle.CanPass(mover, target, height, air_group))
|
||||
return 0
|
||||
for(var/obj/obstacle in target)
|
||||
if(!obstacle.CanPass(mover, src, height, air_group))
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
var/global/datum/controller/air_system/air_master
|
||||
|
||||
datum
|
||||
controller
|
||||
air_system
|
||||
//Geoemetry lists
|
||||
var/list/datum/air_group/air_groups = list()
|
||||
var/list/turf/simulated/active_singletons = list()
|
||||
|
||||
//Special functions lists
|
||||
var/list/turf/simulated/active_super_conductivity = list()
|
||||
var/list/turf/simulated/high_pressure_delta = list()
|
||||
|
||||
//Geometry updates lists
|
||||
var/list/turf/simulated/tiles_to_update = list()
|
||||
var/list/turf/simulated/groups_to_rebuild = list()
|
||||
|
||||
var/current_cycle = 0
|
||||
|
||||
proc
|
||||
setup()
|
||||
//Call this at the start to setup air groups geometry
|
||||
//Warning: Very processor intensive but only must be done once per round
|
||||
|
||||
assemble_group_turf(turf/simulated/base)
|
||||
//Call this to try to construct a group starting from base and merging with neighboring unparented tiles
|
||||
//Expands the group until all valid borders explored
|
||||
|
||||
// assemble_group_object(obj/movable/floor/base)
|
||||
|
||||
process()
|
||||
//Call this to process air movements for a cycle
|
||||
|
||||
process_groups()
|
||||
//Used by process()
|
||||
//Warning: Do not call this
|
||||
|
||||
process_singletons()
|
||||
//Used by process()
|
||||
//Warning: Do not call this
|
||||
|
||||
process_high_pressure_delta()
|
||||
//Used by process()
|
||||
//Warning: Do not call this
|
||||
|
||||
process_super_conductivity()
|
||||
//Used by process()
|
||||
//Warning: Do not call this
|
||||
|
||||
process_update_tiles()
|
||||
//Used by process()
|
||||
//Warning: Do not call this
|
||||
|
||||
process_rebuild_select_groups()
|
||||
//Used by process()
|
||||
//Warning: Do not call this
|
||||
|
||||
rebuild_group(datum/air_group)
|
||||
//Used by process_rebuild_select_groups()
|
||||
//Warning: Do not call this, add the group to air_master.groups_to_rebuild instead
|
||||
|
||||
add_singleton(turf/simulated/T)
|
||||
if(!active_singletons.Find(T))
|
||||
active_singletons += T
|
||||
|
||||
setup()
|
||||
set background = 1
|
||||
world << "\red \b Processing Geometry..."
|
||||
sleep(1)
|
||||
|
||||
var/start_time = world.timeofday
|
||||
|
||||
for(var/turf/simulated/S in world)
|
||||
if(!S.blocks_air && !S.parent)
|
||||
assemble_group_turf(S)
|
||||
S.update_air_properties()
|
||||
|
||||
world << "\red \b Geometry processed in [(world.timeofday-start_time)/10] seconds!"
|
||||
|
||||
assemble_group_turf(turf/simulated/base)
|
||||
|
||||
var/list/turf/simulated/members = list(base) //Confirmed group members
|
||||
var/list/turf/simulated/possible_members = list(base) //Possible places for group expansion
|
||||
var/list/turf/simulated/possible_borders = list()
|
||||
var/list/turf/simulated/possible_space_borders = list()
|
||||
var/possible_space_length = 0
|
||||
|
||||
while(possible_members.len>0) //Keep expanding, looking for new members
|
||||
for(var/turf/simulated/test in possible_members)
|
||||
test.length_space_border = 0
|
||||
for(var/direction in cardinal)
|
||||
var/turf/T = get_step(test,direction)
|
||||
if(T && !members.Find(T) && test.CanPass(null, T, null,1))
|
||||
if(istype(T,/turf/simulated) && !T:parent)
|
||||
possible_members += T
|
||||
members += T
|
||||
else if(istype(T,/turf/space))
|
||||
possible_space_borders -= test
|
||||
possible_space_borders += test
|
||||
test.length_space_border++
|
||||
else
|
||||
possible_borders -= test
|
||||
possible_borders += test
|
||||
if(test.length_space_border > 0)
|
||||
possible_space_length += test.length_space_border
|
||||
possible_members -= test
|
||||
|
||||
if(members.len > 1)
|
||||
var/datum/air_group/turf/group = new
|
||||
if(possible_borders.len>0)
|
||||
group.borders = possible_borders
|
||||
if(possible_space_borders.len>0)
|
||||
group.space_borders = possible_space_borders
|
||||
group.length_space_border = possible_space_length
|
||||
|
||||
for(var/turf/simulated/test in members)
|
||||
test.parent = group
|
||||
test.processing = 0
|
||||
active_singletons -= test
|
||||
|
||||
group.members = members
|
||||
air_groups += group
|
||||
|
||||
group.update_group_from_tiles() //Initialize air group variables
|
||||
return group
|
||||
else
|
||||
base.processing = 0 //singletons at startup are technically unconnected anyway
|
||||
base.parent = null
|
||||
|
||||
if(base.air.check_tile_graphic())
|
||||
base.update_visuals(base.air)
|
||||
|
||||
return null
|
||||
/*
|
||||
assemble_group_object(obj/movable/floor/base)
|
||||
|
||||
var/list/obj/movable/floor/members = list(base) //Confirmed group members
|
||||
var/list/obj/movable/floor/possible_members = list(base) //Possible places for group expansion
|
||||
var/list/obj/movable/floor/possible_borders = list()
|
||||
|
||||
while(possible_members.len>0) //Keep expanding, looking for new members
|
||||
for(var/obj/movable/floor/test in possible_members)
|
||||
for(var/direction in list(NORTH, SOUTH, EAST, WEST))
|
||||
var/turf/T = get_step(test.loc,direction)
|
||||
if(T && test.loc.CanPass(null, T, null, 1))
|
||||
var/obj/movable/floor/O = locate(/obj/movable/floor) in T
|
||||
if(istype(O) && !O.parent)
|
||||
if(!members.Find(O))
|
||||
possible_members += O
|
||||
members += O
|
||||
else
|
||||
possible_borders -= test
|
||||
possible_borders += test
|
||||
possible_members -= test
|
||||
|
||||
if(members.len > 1)
|
||||
var/datum/air_group/object/group = new
|
||||
if(possible_borders.len>0)
|
||||
group.borders = possible_borders
|
||||
|
||||
for(var/obj/movable/floor/test in members)
|
||||
test.parent = group
|
||||
test.processing = 0
|
||||
active_singletons -= test
|
||||
|
||||
group.members = members
|
||||
air_groups += group
|
||||
|
||||
group.update_group_from_tiles() //Initialize air group variables
|
||||
return group
|
||||
else
|
||||
base.processing = 0 //singletons at startup are technically unconnected anyway
|
||||
base.parent = null
|
||||
|
||||
return null
|
||||
*/
|
||||
process()
|
||||
if(kill_air)
|
||||
return 1
|
||||
current_cycle++
|
||||
if(groups_to_rebuild.len > 0) process_rebuild_select_groups()
|
||||
if(tiles_to_update.len > 0) process_update_tiles()
|
||||
|
||||
process_groups()
|
||||
process_singletons()
|
||||
|
||||
process_super_conductivity()
|
||||
process_high_pressure_delta()
|
||||
|
||||
if(current_cycle%10==5) //Check for groups of tiles to resume group processing every 10 cycles
|
||||
for(var/datum/air_group/AG in air_groups)
|
||||
AG.check_regroup()
|
||||
|
||||
return 1
|
||||
|
||||
process_update_tiles()
|
||||
for(var/turf/simulated/T in tiles_to_update)
|
||||
T.update_air_properties()
|
||||
/*
|
||||
for(var/obj/movable/floor/O in tiles_to_update)
|
||||
O.update_air_properties()
|
||||
*/
|
||||
tiles_to_update.len = 0
|
||||
|
||||
process_rebuild_select_groups()
|
||||
var/turf/list/turfs = list()
|
||||
|
||||
for(var/datum/air_group/turf/turf_AG in groups_to_rebuild) //Deconstruct groups, gathering their old members
|
||||
for(var/turf in turf_AG.members)
|
||||
var/turf/simulated/T = turf
|
||||
T.parent = null
|
||||
turfs += T
|
||||
qdel(turf_AG)
|
||||
|
||||
for(var/turf/simulated/S in turfs) //Have old members try to form new groups
|
||||
if(!S.parent)
|
||||
assemble_group_turf(S)
|
||||
for(var/turf/simulated/S in turfs)
|
||||
S.update_air_properties()
|
||||
|
||||
// var/obj/movable/list/movable_objects = list()
|
||||
|
||||
// for(var/datum/air_group/object/object_AG in groups_to_rebuild) //Deconstruct groups, gathering their old members
|
||||
/*
|
||||
for(var/obj/movable/floor/OM in object_AG.members)
|
||||
OM.parent = null
|
||||
movable_objects += OM
|
||||
qdel(object_AG)
|
||||
|
||||
for(var/obj/movable/floor/OM in movable_objects) //Have old members try to form new groups
|
||||
if(!OM.parent)
|
||||
assemble_group_object(OM)
|
||||
for(var/obj/movable/floor/OM in movable_objects)
|
||||
OM.update_air_properties()
|
||||
*/
|
||||
groups_to_rebuild.len = 0
|
||||
|
||||
process_groups()
|
||||
for(var/datum/air_group/AG in air_groups)
|
||||
AG.process_group()
|
||||
|
||||
process_singletons()
|
||||
for(var/item in active_singletons)
|
||||
item:process_cell()
|
||||
|
||||
process_super_conductivity()
|
||||
for(var/turf/simulated/hot_potato in active_super_conductivity)
|
||||
hot_potato.super_conduct()
|
||||
|
||||
process_high_pressure_delta()
|
||||
for(var/turf/pressurized in high_pressure_delta)
|
||||
pressurized.high_pressure_movements()
|
||||
|
||||
high_pressure_delta.len = 0
|
||||
@@ -1,560 +0,0 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
|
||||
|
||||
atom/movable/var/pressure_resistance = 5
|
||||
atom/movable/var/last_forced_movement = 0
|
||||
|
||||
atom/movable/proc/experience_pressure_difference(pressure_difference, direction)
|
||||
if(last_forced_movement >= air_master.current_cycle)
|
||||
return 0
|
||||
else if(!anchored)
|
||||
if(pressure_difference > pressure_resistance)
|
||||
last_forced_movement = air_master.current_cycle
|
||||
spawn step(src, direction)
|
||||
return 1
|
||||
|
||||
turf
|
||||
assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
|
||||
qdel(giver)
|
||||
return 0
|
||||
|
||||
return_air()
|
||||
//Create gas mixture to hold data for passing
|
||||
var/datum/gas_mixture/GM = new
|
||||
|
||||
GM.oxygen = oxygen
|
||||
GM.carbon_dioxide = carbon_dioxide
|
||||
GM.nitrogen = nitrogen
|
||||
GM.toxins = toxins
|
||||
|
||||
GM.temperature = temperature
|
||||
|
||||
return GM
|
||||
|
||||
remove_air(amount as num)
|
||||
var/datum/gas_mixture/GM = new
|
||||
|
||||
var/sum = oxygen + carbon_dioxide + nitrogen + toxins
|
||||
if(sum>0)
|
||||
GM.oxygen = (oxygen/sum)*amount
|
||||
GM.carbon_dioxide = (carbon_dioxide/sum)*amount
|
||||
GM.nitrogen = (nitrogen/sum)*amount
|
||||
GM.toxins = (toxins/sum)*amount
|
||||
|
||||
GM.temperature = temperature
|
||||
|
||||
return GM
|
||||
|
||||
turf
|
||||
var/pressure_difference = 0
|
||||
var/pressure_direction = 0
|
||||
var/reporting_pressure_difference
|
||||
|
||||
//optimization vars
|
||||
var/next_check = 0 //number of ticks before this tile updates
|
||||
var/check_delay = 0 //number of ticks between updates
|
||||
|
||||
proc/high_pressure_movements()
|
||||
if(reporting_pressure_difference)
|
||||
world << "pressure_difference = [pressure_difference]; pressure_direction = [pressure_direction]"
|
||||
for(var/atom/movable/in_tile in src)
|
||||
in_tile.experience_pressure_difference(pressure_difference, pressure_direction)
|
||||
|
||||
pressure_difference = 0
|
||||
|
||||
proc/consider_pressure_difference(connection_difference, connection_direction)
|
||||
if(connection_difference < 0)
|
||||
connection_difference = -connection_difference
|
||||
connection_direction = turn(connection_direction,180)
|
||||
|
||||
if(connection_difference > pressure_difference)
|
||||
if(!pressure_difference)
|
||||
air_master.high_pressure_delta += src
|
||||
pressure_difference = connection_difference
|
||||
pressure_direction = connection_direction
|
||||
|
||||
turf/simulated/proc/consider_pressure_difference_space(connection_difference)
|
||||
for(var/direction in cardinal)
|
||||
if(direction&group_border)
|
||||
if(istype(get_step(src,direction),/turf/space))
|
||||
if(!pressure_difference)
|
||||
air_master.high_pressure_delta += src
|
||||
pressure_direction = direction
|
||||
pressure_difference = connection_difference
|
||||
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
turf/simulated
|
||||
|
||||
var/current_graphic = null
|
||||
|
||||
var/tmp/datum/gas_mixture/air
|
||||
|
||||
var/tmp/processing = 1
|
||||
var/tmp/datum/air_group/turf/parent
|
||||
var/tmp/group_border = 0
|
||||
var/tmp/length_space_border = 0
|
||||
|
||||
var/tmp/air_check_directions = 0 //Do not modify this, just add turf to air_master.tiles_to_update
|
||||
|
||||
var/tmp/archived_cycle = 0
|
||||
var/tmp/current_cycle = 0
|
||||
|
||||
var/tmp/obj/effect/hotspot/active_hotspot
|
||||
|
||||
var/tmp/temperature_archived //USED ONLY FOR SOLIDS
|
||||
var/tmp/being_superconductive = 0
|
||||
|
||||
proc/update_visuals(datum/gas_mixture/model)
|
||||
overlays.Cut()
|
||||
|
||||
var/siding_icon_state = return_siding_icon_state()
|
||||
if(siding_icon_state)
|
||||
overlays += image('icons/turf/floors.dmi',siding_icon_state)
|
||||
|
||||
switch(model.graphic)
|
||||
if("plasma")
|
||||
overlays.Add(plmaster)
|
||||
if("sleeping_agent")
|
||||
overlays.Add(slmaster)
|
||||
|
||||
|
||||
|
||||
New()
|
||||
..()
|
||||
|
||||
if(!blocks_air)
|
||||
air = new
|
||||
|
||||
air.oxygen = oxygen
|
||||
air.carbon_dioxide = carbon_dioxide
|
||||
air.nitrogen = nitrogen
|
||||
air.toxins = toxins
|
||||
|
||||
air.temperature = temperature
|
||||
|
||||
if(air_master)
|
||||
air_master.tiles_to_update.Add(src)
|
||||
|
||||
find_group()
|
||||
|
||||
// air.parent = src //TODO DEBUG REMOVE
|
||||
|
||||
else
|
||||
if(air_master)
|
||||
for(var/direction in cardinal)
|
||||
var/turf/simulated/floor/target = get_step(src,direction)
|
||||
if(istype(target))
|
||||
air_master.tiles_to_update.Add(target)
|
||||
|
||||
Destroy()
|
||||
if(air_master)
|
||||
if(parent)
|
||||
air_master.groups_to_rebuild.Add(parent)
|
||||
parent.members.Remove(src)
|
||||
else
|
||||
air_master.active_singletons.Remove(src)
|
||||
if(active_hotspot)
|
||||
active_hotspot.Kill()
|
||||
if(blocks_air)
|
||||
for(var/direction in list(NORTH, SOUTH, EAST, WEST))
|
||||
var/turf/simulated/tile = get_step(src,direction)
|
||||
if(istype(tile) && !tile.blocks_air)
|
||||
air_master.tiles_to_update.Add(tile)
|
||||
..()
|
||||
|
||||
assume_air(datum/gas_mixture/giver)
|
||||
if(!giver) return 0
|
||||
var/datum/gas_mixture/receiver = air
|
||||
if(istype(receiver))
|
||||
if(parent&&parent.group_processing)
|
||||
if(!parent.air.check_then_merge(giver))
|
||||
parent.suspend_group_processing()
|
||||
air.merge(giver)
|
||||
else
|
||||
if (giver.total_moles() > MINIMUM_AIR_TO_SUSPEND)
|
||||
reset_delay()
|
||||
|
||||
air.merge(giver)
|
||||
|
||||
if(!processing)
|
||||
if(air.check_tile_graphic())
|
||||
update_visuals(air)
|
||||
|
||||
return 1
|
||||
|
||||
else return ..()
|
||||
|
||||
proc/archive()
|
||||
if(air) //For open space like floors
|
||||
air.archive()
|
||||
|
||||
temperature_archived = temperature
|
||||
archived_cycle = air_master.current_cycle
|
||||
|
||||
proc/share_air_with_tile(turf/simulated/T)
|
||||
return air.share(T.air)
|
||||
|
||||
proc/mimic_air_with_tile(turf/T)
|
||||
return air.mimic(T)
|
||||
|
||||
return_air()
|
||||
if(air)
|
||||
if(parent&&parent.group_processing)
|
||||
return parent.air
|
||||
else return air
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
remove_air(amount as num)
|
||||
if(air)
|
||||
var/datum/gas_mixture/removed = null
|
||||
|
||||
if(parent&&parent.group_processing)
|
||||
removed = parent.air.check_then_remove(amount)
|
||||
if(!removed)
|
||||
parent.suspend_group_processing()
|
||||
removed = air.remove(amount)
|
||||
else
|
||||
removed = air.remove(amount)
|
||||
|
||||
if(!processing)
|
||||
if(air.check_tile_graphic())
|
||||
update_visuals(air)
|
||||
|
||||
return removed
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
proc/update_air_properties()//OPTIMIZE
|
||||
air_check_directions = 0
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(CanPass(null, get_step(src,direction), 0, 0))
|
||||
air_check_directions |= direction
|
||||
|
||||
if(parent)
|
||||
if(parent.borders)
|
||||
parent.borders -= src
|
||||
if(length_space_border > 0)
|
||||
parent.length_space_border -= length_space_border
|
||||
length_space_border = 0
|
||||
|
||||
group_border = 0
|
||||
for(var/direction in cardinal)
|
||||
if(air_check_directions&direction)
|
||||
var/turf/simulated/T = get_step(src,direction)
|
||||
|
||||
//See if actually a border
|
||||
if(!istype(T) || (T.parent!=parent))
|
||||
|
||||
//See what kind of border it is
|
||||
if(istype(T,/turf/space))
|
||||
if(parent.space_borders)
|
||||
parent.space_borders -= src
|
||||
parent.space_borders += src
|
||||
else
|
||||
parent.space_borders = list(src)
|
||||
length_space_border++
|
||||
|
||||
else
|
||||
if(parent.borders)
|
||||
parent.borders -= src
|
||||
parent.borders += src
|
||||
else
|
||||
parent.borders = list(src)
|
||||
|
||||
group_border |= direction
|
||||
|
||||
parent.length_space_border += length_space_border
|
||||
|
||||
if(air_check_directions)
|
||||
processing = 1
|
||||
if(!parent)
|
||||
air_master.add_singleton(src)
|
||||
else
|
||||
processing = 0
|
||||
|
||||
proc/process_cell()
|
||||
//this proc does all the heavy lifting for individual tile processing
|
||||
//it shares with all of its neighbors, spreads fire, calls superconduction
|
||||
//and doesn't afraid of anything
|
||||
//Comment by errorage: In other words, this is the proc that lags the game.
|
||||
|
||||
//check if we're skipping this tick
|
||||
if (next_check > 0)
|
||||
next_check--
|
||||
return 1
|
||||
var/player_count = max(player_list.len, 3) / 3
|
||||
next_check += check_delay + rand(player_count, player_count * 1.5)
|
||||
check_delay++
|
||||
|
||||
var/turf/simulated/list/possible_fire_spreads = list()
|
||||
if(processing)
|
||||
if(archived_cycle < air_master.current_cycle) //archive self if not already done
|
||||
archive()
|
||||
current_cycle = air_master.current_cycle
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(air_check_directions&direction) //Grab all valid bordering tiles
|
||||
var/turf/simulated/enemy_tile = get_step(src, direction)
|
||||
var/connection_difference = 0
|
||||
|
||||
if(istype(enemy_tile)) //enemy_tile == neighbor, btw
|
||||
if(enemy_tile.archived_cycle < archived_cycle) //archive bordering tile information if not already done
|
||||
enemy_tile.archive()
|
||||
|
||||
if (air && enemy_tile.air)
|
||||
var/delay_trigger = air.compare(enemy_tile.air)
|
||||
if (!delay_trigger) //if compare() didn't return 1, air is different enough to trigger processing
|
||||
reset_delay()
|
||||
enemy_tile.reset_delay()
|
||||
|
||||
if(enemy_tile.parent && enemy_tile.parent.group_processing) //apply tile to group sharing
|
||||
if(enemy_tile.parent.current_cycle < current_cycle) //if the group hasn't been archived, it could just be out of date
|
||||
if(enemy_tile.parent.air.check_gas_mixture(air))
|
||||
connection_difference = air.share(enemy_tile.parent.air)
|
||||
else
|
||||
enemy_tile.parent.suspend_group_processing()
|
||||
connection_difference = air.share(enemy_tile.air)
|
||||
//group processing failed so interact with individual tile
|
||||
|
||||
else
|
||||
if(enemy_tile.current_cycle < current_cycle)
|
||||
connection_difference = air.share(enemy_tile.air)
|
||||
|
||||
if(active_hotspot)
|
||||
possible_fire_spreads += enemy_tile
|
||||
else
|
||||
/* var/obj/movable/floor/movable_on_enemy = locate(/obj/movable/floor) in enemy_tile
|
||||
|
||||
if(movable_on_enemy)
|
||||
if(movable_on_enemy.parent && movable_on_enemy.parent.group_processing) //apply tile to group sharing
|
||||
if(movable_on_enemy.parent.current_cycle < current_cycle)
|
||||
if(movable_on_enemy.parent.air.check_gas_mixture(air))
|
||||
connection_difference = air.share(movable_on_enemy.parent.air)
|
||||
|
||||
else
|
||||
movable_on_enemy.parent.suspend_group_processing()
|
||||
|
||||
if(movable_on_enemy.archived_cycle < archived_cycle) //archive bordering tile information if not already done
|
||||
movable_on_enemy.archive()
|
||||
connection_difference = air.share(movable_on_enemy.air)
|
||||
//group processing failed so interact with individual tile
|
||||
else
|
||||
if(movable_on_enemy.archived_cycle < archived_cycle) //archive bordering tile information if not already done
|
||||
movable_on_enemy.archive()
|
||||
|
||||
if(movable_on_enemy.current_cycle < current_cycle)
|
||||
connection_difference = share_air_with_tile(movable_on_enemy)
|
||||
|
||||
else*/
|
||||
connection_difference = mimic_air_with_tile(enemy_tile)
|
||||
//bordering a tile with fixed air properties
|
||||
|
||||
if(connection_difference)
|
||||
if(connection_difference > 0)
|
||||
consider_pressure_difference(connection_difference, direction)
|
||||
else
|
||||
enemy_tile.consider_pressure_difference(connection_difference, direction)
|
||||
else
|
||||
air_master.active_singletons -= src //not active if not processing!
|
||||
|
||||
air.react()
|
||||
|
||||
if(active_hotspot)
|
||||
if (!active_hotspot.process(possible_fire_spreads))
|
||||
return 0
|
||||
|
||||
if(air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION)
|
||||
consider_superconductivity(starting = 1)
|
||||
|
||||
if(air.check_tile_graphic())
|
||||
update_visuals(air)
|
||||
|
||||
if(air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
|
||||
reset_delay() //hotspots always process quickly
|
||||
hotspot_expose(air.temperature, CELL_VOLUME)
|
||||
for(var/atom/movable/item in src)
|
||||
item.temperature_expose(air, air.temperature, CELL_VOLUME)
|
||||
temperature_expose(air, air.temperature, CELL_VOLUME)
|
||||
|
||||
return 1
|
||||
|
||||
proc/super_conduct()
|
||||
var/conductivity_directions = 0
|
||||
if(blocks_air)
|
||||
//Does not participate in air exchange, so will conduct heat across all four borders at this time
|
||||
conductivity_directions = NORTH|SOUTH|EAST|WEST
|
||||
|
||||
if(archived_cycle < air_master.current_cycle)
|
||||
archive()
|
||||
|
||||
else
|
||||
//Does particate in air exchange so only consider directions not considered during process_cell()
|
||||
conductivity_directions = ~air_check_directions & (NORTH|SOUTH|EAST|WEST)
|
||||
|
||||
if(conductivity_directions>0)
|
||||
//Conduct with tiles around me
|
||||
for(var/direction in cardinal)
|
||||
if(conductivity_directions&direction)
|
||||
var/turf/neighbor = get_step(src,direction)
|
||||
|
||||
if(istype(neighbor, /turf/simulated)) //anything under this subtype will share in the exchange
|
||||
var/turf/simulated/modeled_neighbor = neighbor
|
||||
|
||||
if(modeled_neighbor.archived_cycle < air_master.current_cycle)
|
||||
modeled_neighbor.archive()
|
||||
|
||||
if(modeled_neighbor.air)
|
||||
if(air) //Both tiles are open
|
||||
|
||||
if(modeled_neighbor.parent && modeled_neighbor.parent.group_processing)
|
||||
if(parent && parent.group_processing)
|
||||
//both are acting as a group
|
||||
//modified using construct developed in datum/air_group/share_air_with_group(...)
|
||||
|
||||
var/result = parent.air.check_both_then_temperature_share(modeled_neighbor.parent.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
|
||||
if(result==0)
|
||||
//have to deconstruct parent air group
|
||||
|
||||
parent.suspend_group_processing()
|
||||
if(!modeled_neighbor.parent.air.check_me_then_temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT))
|
||||
//may have to deconstruct neighbors air group
|
||||
|
||||
modeled_neighbor.parent.suspend_group_processing()
|
||||
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
|
||||
else if(result==-1)
|
||||
// have to deconstruct neightbors air group but not mine
|
||||
|
||||
modeled_neighbor.parent.suspend_group_processing()
|
||||
parent.air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
|
||||
else
|
||||
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
|
||||
else
|
||||
if(parent && parent.group_processing)
|
||||
if(!parent.air.check_me_then_temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT))
|
||||
//may have to deconstruct neighbors air group
|
||||
|
||||
parent.suspend_group_processing()
|
||||
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
|
||||
|
||||
else
|
||||
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
|
||||
// world << "OPEN, OPEN"
|
||||
|
||||
else //Solid but neighbor is open
|
||||
if(modeled_neighbor.parent && modeled_neighbor.parent.group_processing)
|
||||
if(!modeled_neighbor.parent.air.check_me_then_temperature_turf_share(src, modeled_neighbor.thermal_conductivity))
|
||||
|
||||
modeled_neighbor.parent.suspend_group_processing()
|
||||
modeled_neighbor.air.temperature_turf_share(src, modeled_neighbor.thermal_conductivity)
|
||||
else
|
||||
modeled_neighbor.air.temperature_turf_share(src, modeled_neighbor.thermal_conductivity)
|
||||
// world << "SOLID, OPEN"
|
||||
|
||||
else
|
||||
if(air) //Open but neighbor is solid
|
||||
if(parent && parent.group_processing)
|
||||
if(!parent.air.check_me_then_temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity))
|
||||
parent.suspend_group_processing()
|
||||
air.temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity)
|
||||
else
|
||||
air.temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity)
|
||||
// world << "OPEN, SOLID"
|
||||
|
||||
else //Both tiles are solid
|
||||
share_temperature_mutual_solid(modeled_neighbor, modeled_neighbor.thermal_conductivity)
|
||||
// world << "SOLID, SOLID"
|
||||
|
||||
modeled_neighbor.consider_superconductivity()
|
||||
|
||||
else
|
||||
if(air) //Open
|
||||
if(parent && parent.group_processing)
|
||||
if(!parent.air.check_me_then_temperature_mimic(neighbor, neighbor.thermal_conductivity))
|
||||
parent.suspend_group_processing()
|
||||
air.temperature_mimic(neighbor, neighbor.thermal_conductivity)
|
||||
else
|
||||
air.temperature_mimic(neighbor, neighbor.thermal_conductivity)
|
||||
else
|
||||
mimic_temperature_solid(neighbor, neighbor.thermal_conductivity)
|
||||
|
||||
//Radiate excess tile heat to space
|
||||
if(temperature > T0C)
|
||||
// Is there a pre-defined Space Tile?
|
||||
if(!Space_Tile)
|
||||
Space_Tile = locate(/turf/space) // Define one
|
||||
//Considering 0 degC as te break even point for radiation in and out
|
||||
mimic_temperature_solid(Space_Tile, FLOOR_HEAT_TRANSFER_COEFFICIENT)
|
||||
|
||||
//Conduct with air on my tile if I have it
|
||||
if(air)
|
||||
if(parent && parent.group_processing)
|
||||
if(!parent.air.check_me_then_temperature_turf_share(src, thermal_conductivity))
|
||||
parent.suspend_group_processing()
|
||||
air.temperature_turf_share(src, thermal_conductivity)
|
||||
else
|
||||
air.temperature_turf_share(src, thermal_conductivity)
|
||||
|
||||
|
||||
//Make sure still hot enough to continue conducting heat
|
||||
if(air)
|
||||
if(air.temperature < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
|
||||
being_superconductive = 0
|
||||
air_master.active_super_conductivity -= src
|
||||
return 0
|
||||
|
||||
else
|
||||
if(temperature < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
|
||||
being_superconductive = 0
|
||||
air_master.active_super_conductivity -= src
|
||||
return 0
|
||||
|
||||
proc/mimic_temperature_solid(turf/model, conduction_coefficient)
|
||||
var/delta_temperature = (temperature_archived - model.temperature)
|
||||
if((heat_capacity > 0) && (abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER))
|
||||
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(heat_capacity*model.heat_capacity/(heat_capacity+model.heat_capacity))
|
||||
temperature -= heat/heat_capacity
|
||||
|
||||
proc/share_temperature_mutual_solid(turf/simulated/sharer, conduction_coefficient)
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER && heat_capacity && sharer.heat_capacity)
|
||||
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(heat_capacity*sharer.heat_capacity/(heat_capacity+sharer.heat_capacity))
|
||||
|
||||
temperature -= heat/heat_capacity
|
||||
sharer.temperature += heat/sharer.heat_capacity
|
||||
|
||||
proc/consider_superconductivity(starting)
|
||||
|
||||
if(being_superconductive || !thermal_conductivity)
|
||||
return 0
|
||||
|
||||
if(air)
|
||||
if(air.temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
|
||||
return 0
|
||||
if(air.heat_capacity() < MOLES_CELLSTANDARD*0.1*0.05)
|
||||
return 0
|
||||
else
|
||||
if(temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
|
||||
return 0
|
||||
|
||||
being_superconductive = 1
|
||||
|
||||
air_master.active_super_conductivity += src
|
||||
|
||||
proc/reset_delay()
|
||||
//sets this turf to process quickly again
|
||||
next_check=0
|
||||
check_delay= -5 //negative numbers mean a mandatory quick-update period
|
||||
|
||||
//if this turf has a parent air group, suspend its processing
|
||||
if (parent && parent.group_processing)
|
||||
parent.suspend_group_processing()
|
||||
@@ -1,52 +0,0 @@
|
||||
/obj/item/weapon/tank/jetpack/verb/moveup()
|
||||
set name = "Move Upwards"
|
||||
set category = "Object"
|
||||
if(allow_thrust(0.01, usr))
|
||||
var/turf/controllerlocation = locate(1, 1, usr.z)
|
||||
var/legal = 0
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
legal = controller.up
|
||||
if (controller.up)
|
||||
var/turf/T = locate(usr.x, usr.y, controller.up_target)
|
||||
if(T && (istype(T, /turf/space) || istype(T, /turf/simulated/floor/open)))
|
||||
var/blocked = 0
|
||||
for(var/atom/A in T.contents)
|
||||
if(A.density)
|
||||
blocked = 1
|
||||
usr << "\red You bump into [A.name]."
|
||||
break
|
||||
if(!blocked)
|
||||
usr.Move(T)
|
||||
usr << "You move upwards."
|
||||
else
|
||||
usr << "\red There is something in your way."
|
||||
if (legal == 0)
|
||||
usr << "There is nothing of interest in this direction."
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/tank/jetpack/verb/movedown()
|
||||
set name = "Move Downwards"
|
||||
set category = "Object"
|
||||
if(allow_thrust(0.01, usr))
|
||||
var/turf/controllerlocation = locate(1, 1, usr.z)
|
||||
var/legal = 0
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
legal = controller.down
|
||||
if (controller.down == 1)
|
||||
var/turf/T = locate(usr.x, usr.y, controller.down_target)
|
||||
var/turf/S = locate(usr.x, usr.y, usr.z)
|
||||
if(T && (istype(S, /turf/space) || istype(S, /turf/simulated/floor/open)))
|
||||
var/blocked = 0
|
||||
for(var/atom/A in T.contents)
|
||||
if(A.density)
|
||||
blocked = 1
|
||||
usr << "\red You bump into [A.name]."
|
||||
break
|
||||
if(!blocked)
|
||||
usr.Move(T)
|
||||
usr << "You move downwards."
|
||||
else
|
||||
usr << "\red You cant move through the floor."
|
||||
if (legal == 0)
|
||||
usr << "There is nothing of interest in this direction."
|
||||
return 1
|
||||
@@ -1,274 +0,0 @@
|
||||
///////////////////////////////////////
|
||||
//Contents: Ladders, Hatches, Stairs.//
|
||||
///////////////////////////////////////
|
||||
|
||||
/obj/multiz
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
density = 0
|
||||
opacity = 0
|
||||
anchored = 1
|
||||
|
||||
CanPass(obj/mover, turf/source, height, airflow)
|
||||
return airflow || !density
|
||||
|
||||
/obj/multiz/ladder
|
||||
icon_state = "ladderdown"
|
||||
name = "ladder"
|
||||
desc = "A ladder. You climb up and down it."
|
||||
|
||||
var/d_state = 1
|
||||
var/obj/multiz/target
|
||||
|
||||
New()
|
||||
. = ..()
|
||||
|
||||
proc/connect()
|
||||
if(icon_state == "ladderdown") // the upper will connect to the lower
|
||||
d_state = 1
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.down)
|
||||
var/turf/below = locate(src.x, src.y, controller.down_target)
|
||||
for(var/obj/multiz/ladder/L in below)
|
||||
if(L.icon_state == "ladderup")
|
||||
target = L
|
||||
L.target = src
|
||||
d_state = 0
|
||||
break
|
||||
return
|
||||
|
||||
/* ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
if(icon_state == "ladderup" && prob(10))
|
||||
qdel(src)
|
||||
if(2.0)
|
||||
if(prob(50))
|
||||
qdel(src)
|
||||
if(3.0)
|
||||
qdel(src)
|
||||
return*/
|
||||
|
||||
Destroy()
|
||||
spawn(1)
|
||||
if(target && icon_state == "ladderdown")
|
||||
qdel(target)
|
||||
return ..()
|
||||
|
||||
attackby(obj/item/C as obj, mob/user as mob)
|
||||
(..)
|
||||
|
||||
// construction commented out for balance concerns
|
||||
/* if (!target && istype(C, /obj/item/stack/rods))
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
var/found = 0
|
||||
var/obj/item/stack/rods/S = C
|
||||
if(S.amount < 2)
|
||||
user << "You dont have enough rods to finish the ladder."
|
||||
return
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.down)
|
||||
found = 1
|
||||
var/turf/below = locate(src.x, src.y, controller.down_target)
|
||||
var/blocked = 0
|
||||
for(var/atom/A in below.contents)
|
||||
if(A.density)
|
||||
blocked = 1
|
||||
break
|
||||
if(!blocked && !istype(below, /turf/simulated/wall))
|
||||
var/obj/multiz/ladder/X = new /obj/multiz/ladder(below)
|
||||
S.amount = S.amount - 2
|
||||
if(S.amount == 0) qdel(S)
|
||||
X.icon_state = "ladderup"
|
||||
connect()
|
||||
user << "You finish the ladder."
|
||||
else
|
||||
user << "The area below is blocked."
|
||||
if(!found)
|
||||
user << "You cant build a ladder down there."
|
||||
return
|
||||
|
||||
else if (icon_state == "ladderdown" && d_state == 0 && istype(C, /obj/item/weapon/wrench))
|
||||
user << "<span class='notice'>You start loosening the anchoring bolts which secure the ladder to the frame.</span>"
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
|
||||
|
||||
sleep(30)
|
||||
if(!user || !C) return
|
||||
|
||||
src.d_state = 1
|
||||
if(target)
|
||||
var/obj/item/stack/rods/R = PoolOrNew(/obj/item/stack/rods, target.loc)
|
||||
R.amount = 2
|
||||
qdel(Target)
|
||||
|
||||
user << "<span class='notice'>You remove the bolts anchoring the ladder.</span>"
|
||||
return
|
||||
|
||||
else if (icon_state == "ladderdown" && d_state == 1 && istype(C, /obj/item/weapon/weldingtool) )
|
||||
var/obj/item/weapon/weldingtool/WT = C
|
||||
if( WT.remove_fuel(0,user) )
|
||||
|
||||
user << "<span class='notice'>You begin to remove the ladder.</span>"
|
||||
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
|
||||
|
||||
sleep(60)
|
||||
if(!user || !WT || !WT.isOn()) return
|
||||
|
||||
var/obj/item/stack/material/steel/S = new /obj/item/stack/material/steel( src )
|
||||
S.amount = 2
|
||||
user << "<span class='notice'>You remove the ladder and close the hole.</span>"
|
||||
qdel(src)
|
||||
else
|
||||
user << "<span class='notice'>You need more welding fuel to complete this task.</span>"
|
||||
return
|
||||
|
||||
else
|
||||
src.attack_hand(user)
|
||||
return*/
|
||||
src.attack_hand(user)
|
||||
return
|
||||
|
||||
attack_hand(var/mob/M)
|
||||
if(!target || !istype(target.loc, /turf))
|
||||
M << "The ladder is incomplete and can't be climbed."
|
||||
else
|
||||
var/turf/T = target.loc
|
||||
var/blocked = 0
|
||||
for(var/atom/A in T.contents)
|
||||
if(A.density)
|
||||
blocked = 1
|
||||
break
|
||||
if(blocked || istype(T, /turf/simulated/wall))
|
||||
M << "Something is blocking the ladder."
|
||||
else
|
||||
M.visible_message("\blue \The [M] climbs [src.icon_state == "ladderup" ? "up" : "down"] \the [src]!", "You climb [src.icon_state == "ladderup" ? "up" : "down"] \the [src]!", "You hear some grunting, and clanging of a metal ladder being used.")
|
||||
M.Move(target.loc)
|
||||
|
||||
/* hatch
|
||||
icon_state = "hatchdown"
|
||||
name = "hatch"
|
||||
desc = "A hatch. You climb down it, and it will automatically seal against pressure loss behind you."
|
||||
top_icon_state = "hatchdown"
|
||||
var/top_icon_state_open = "hatchdown-open"
|
||||
var/top_icon_state_close = "hatchdown-close"
|
||||
|
||||
bottom_icon_state = "ladderup"
|
||||
|
||||
var/image/green_overlay
|
||||
var/image/red_overlay
|
||||
|
||||
var/active = 0
|
||||
|
||||
New()
|
||||
. = ..()
|
||||
red_overlay = image(icon, "red-ladderlight")
|
||||
green_overlay = image(icon, "green-ladderlight")
|
||||
|
||||
attack_hand(var/mob/M)
|
||||
|
||||
if(!target || !istype(target.loc, /turf))
|
||||
qdel(src)
|
||||
|
||||
if(active)
|
||||
M << "That [src] is being used."
|
||||
return // It is a tiny airlock, only one at a time.
|
||||
|
||||
active = 1
|
||||
var/obj/multiz/ladder/hatch/top_hatch = target
|
||||
var/obj/multiz/ladder/hatch/bottom_hatch = src
|
||||
if(icon_state == top_icon_state)
|
||||
top_hatch = src
|
||||
bottom_hatch = target
|
||||
|
||||
flick(top_icon_state_open, top_hatch)
|
||||
bottom_hatch.overlays += green_overlay
|
||||
|
||||
spawn(7)
|
||||
if(!target || !istype(target.loc, /turf))
|
||||
qdel(src)
|
||||
if(M.z == z && get_dist(src,M) <= 1)
|
||||
var/list/adjacent_to_me = global_adjacent_z_levels["[z]"]
|
||||
M.visible_message("\blue \The [M] scurries [target.z == adjacent_to_me["up"] ? "up" : "down"] \the [src]!", "You scramble [target.z == adjacent_to_me["up"] ? "up" : "down"] \the [src]!", "You hear some grunting, and a hatch sealing.")
|
||||
M.Move(target.loc)
|
||||
flick(top_icon_state_close,top_hatch)
|
||||
bottom_hatch.overlays -= green_overlay
|
||||
bottom_hatch.overlays += red_overlay
|
||||
|
||||
spawn(7)
|
||||
top_hatch.icon_state = top_icon_state
|
||||
bottom_hatch.overlays -= red_overlay
|
||||
active = 0*/
|
||||
|
||||
/obj/multiz/stairs
|
||||
name = "Stairs"
|
||||
desc = "Stairs. You walk up and down them."
|
||||
icon_state = "rampbottom"
|
||||
var/obj/multiz/stairs/connected
|
||||
var/turf/target
|
||||
var/turf/target2
|
||||
var/suggest_dir // try this dir first when finding stairs; this is the direction to walk *down* the stairs
|
||||
|
||||
New()
|
||||
..()
|
||||
var/turf/cl= locate(1, 1, src.z)
|
||||
for(var/obj/effect/landmark/zcontroller/c in cl)
|
||||
if(c.up)
|
||||
var/turf/O = locate(src.x, src.y, c.up_target)
|
||||
if(istype(O, /turf/space))
|
||||
O.ChangeTurf(/turf/simulated/floor/open)
|
||||
|
||||
spawn(1)
|
||||
var/turf/T
|
||||
if(suggest_dir)
|
||||
T = get_step(src.loc,suggest_dir)
|
||||
find_stair_connection(T, suggest_dir, 1)
|
||||
if(!target)
|
||||
for(var/dir in cardinal)
|
||||
T = get_step(src.loc,dir)
|
||||
find_stair_connection(T, dir)
|
||||
if(target)
|
||||
break
|
||||
|
||||
Bumped(var/atom/movable/M)
|
||||
if(connected && target && istype(src, /obj/multiz/stairs) && locate(/obj/multiz/stairs) in M.loc)
|
||||
var/obj/multiz/stairs/Con = locate(/obj/multiz/stairs) in M.loc
|
||||
if(Con == src.connected) //make sure the atom enters from the approriate lower stairs tile
|
||||
M.Move(target)
|
||||
return
|
||||
|
||||
proc/find_stair_connection(var/turf/T, var/dir, var/suggested=0)
|
||||
for(var/obj/multiz/stairs/S in T)
|
||||
if(S && S.icon_state == "rampbottom" && !S.connected)
|
||||
if(!S.suggest_dir || S.suggest_dir == dir) // it doesn't have a suggested direction, or it's the same direction as we're trying, so we connect to it
|
||||
initialise_stair_connection(src, S, dir)
|
||||
else if(!suggested) // we're trying directions, so it could be a reverse stair (i.e. we're the bottom stair rather than the top)
|
||||
var/inv_dir = 0
|
||||
switch(dir)
|
||||
if(1)
|
||||
inv_dir = 2
|
||||
if(2)
|
||||
inv_dir = 1
|
||||
if(4)
|
||||
inv_dir = 8
|
||||
if(8)
|
||||
inv_dir = 4
|
||||
if(S.suggest_dir == inv_dir)
|
||||
initialise_stair_connection(S, src, inv_dir)
|
||||
|
||||
proc/initialise_stair_connection(var/obj/multiz/stairs/top, var/obj/multiz/stairs/bottom, var/dir)
|
||||
top.set_dir(dir)
|
||||
bottom.set_dir(dir)
|
||||
top.connected = bottom
|
||||
bottom.connected = top
|
||||
top.icon_state = "ramptop"
|
||||
top.density = 1
|
||||
var/turf/controllerlocation = locate(1, 1, top.z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.up)
|
||||
var/turf/above = locate(top.x, top.y, controller.up_target)
|
||||
if(istype(above,/turf/space) || istype(above,/turf/simulated/floor/open))
|
||||
top.target = above
|
||||
var/turf/above2 = locate(bottom.x, bottom.y, controller.up_target)
|
||||
if(istype(above2, /turf/space) || istype(above,/turf/simulated/floor/open))
|
||||
top.target2 = above2
|
||||
return
|
||||
@@ -1,11 +0,0 @@
|
||||
/obj/multiz/stairs/north_up
|
||||
suggest_dir = SOUTH
|
||||
|
||||
/obj/multiz/stairs/south_up
|
||||
suggest_dir = NORTH
|
||||
|
||||
/obj/multiz/stairs/east_up
|
||||
suggest_dir = WEST
|
||||
|
||||
/obj/multiz/stairs/west_up
|
||||
suggest_dir = EAST
|
||||
@@ -1,130 +0,0 @@
|
||||
/turf/simulated/floor/open
|
||||
name = "open space"
|
||||
intact = 0
|
||||
density = 0
|
||||
icon_state = "black"
|
||||
pathweight = 100000 //Seriously, don't try and path over this one numbnuts
|
||||
var/icon/darkoverlays = null
|
||||
var/turf/floorbelow
|
||||
var/list/overlay_references
|
||||
|
||||
New()
|
||||
..()
|
||||
getbelow()
|
||||
return
|
||||
|
||||
Enter(var/atom/movable/AM)
|
||||
if (..()) //TODO make this check if gravity is active (future use) - Sukasa
|
||||
spawn(1)
|
||||
// only fall down in defined areas (read: areas with artificial gravitiy)
|
||||
if(!floorbelow) //make sure that there is actually something below
|
||||
if(!getbelow())
|
||||
return
|
||||
if(AM)
|
||||
var/area/areacheck = get_area(src)
|
||||
var/blocked = 0
|
||||
var/soft = 0
|
||||
for(var/atom/A in floorbelow.contents)
|
||||
if(A.density)
|
||||
if(istype(A, /obj/structure/window))
|
||||
var/obj/structure/window/W = A
|
||||
blocked = W.is_fulltile()
|
||||
if(blocked)
|
||||
break
|
||||
else
|
||||
blocked = 1
|
||||
break
|
||||
if(istype(A, /obj/machinery/atmospherics/pipe/zpipe/up) && istype(AM,/obj/item/pipe))
|
||||
blocked = 1
|
||||
break
|
||||
if(istype(A, /obj/structure/disposalpipe/up) && istype(AM,/obj/item/pipe))
|
||||
blocked = 1
|
||||
break
|
||||
if(istype(A, /obj/multiz/stairs))
|
||||
soft = 1
|
||||
//dont break here, since we still need to be sure that it isnt blocked
|
||||
|
||||
if (soft || (!blocked && !(areacheck.name == "Space")))
|
||||
AM.Move(floorbelow)
|
||||
if (!soft && istype(AM, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = AM
|
||||
var/damage = 5
|
||||
H.apply_damage(min(rand(-damage,damage),0), BRUTE, "head")
|
||||
H.apply_damage(min(rand(-damage,damage),0), BRUTE, "chest")
|
||||
H.apply_damage(min(rand(-damage,damage),0), BRUTE, "l_leg")
|
||||
H.apply_damage(min(rand(-damage,damage),0), BRUTE, "r_leg")
|
||||
H.apply_damage(min(rand(-damage,damage),0), BRUTE, "l_arm")
|
||||
H.apply_damage(min(rand(-damage,damage),0), BRUTE, "r_arm")
|
||||
H:weakened = max(H:weakened,2)
|
||||
H:updatehealth()
|
||||
return ..()
|
||||
|
||||
/turf/proc/hasbelow()
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.down)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/turf/simulated/floor/open/proc/getbelow()
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
// check if there is something to draw below
|
||||
if(!controller.down)
|
||||
src.ChangeTurf(/turf/space)
|
||||
return 0
|
||||
else
|
||||
floorbelow = locate(src.x, src.y, controller.down_target)
|
||||
return 1
|
||||
return 1
|
||||
|
||||
// override to make sure nothing is hidden
|
||||
/turf/simulated/floor/open/levelupdate()
|
||||
for(var/obj/O in src)
|
||||
if(O.level == 1)
|
||||
O.hide(0)
|
||||
|
||||
//overwrite the attackby of space to transform it to openspace if necessary
|
||||
/turf/space/attackby(obj/item/C as obj, mob/user as mob)
|
||||
if (istype(C, /obj/item/stack/cable_coil) && src.hasbelow())
|
||||
var/turf/simulated/floor/open/W = src.ChangeTurf(/turf/simulated/floor/open)
|
||||
W.attackby(C, user)
|
||||
return
|
||||
..()
|
||||
|
||||
/turf/simulated/floor/open/ex_act(severity)
|
||||
// cant destroy empty space with an ordinary bomb
|
||||
return
|
||||
|
||||
/turf/simulated/floor/open/attackby(obj/item/C as obj, mob/user as mob)
|
||||
(..)
|
||||
if (istype(C, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/cable = C
|
||||
cable.turf_place(src, user)
|
||||
return
|
||||
|
||||
if (istype(C, /obj/item/stack/rods))
|
||||
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
|
||||
if(L)
|
||||
return
|
||||
var/obj/item/stack/rods/R = C
|
||||
if (R.use(1))
|
||||
user << "\blue Constructing support lattice ..."
|
||||
playsound(src.loc, 'sound/weapons/Genhit.ogg', 50, 1)
|
||||
ReplaceWithLattice()
|
||||
return
|
||||
|
||||
if (istype(C, /obj/item/stack/tile/steel))
|
||||
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
|
||||
if(L)
|
||||
var/obj/item/stack/tile/steel/S = C
|
||||
if (S.get_amount() < 1)
|
||||
return
|
||||
qdel(L)
|
||||
playsound(src.loc, 'sound/weapons/Genhit.ogg', 50, 1)
|
||||
S.build(src)
|
||||
S.use(1)
|
||||
return
|
||||
else
|
||||
user << "\red The plating is going to need some support."
|
||||
return
|
||||
@@ -1,253 +0,0 @@
|
||||
/obj/effect/landmark/zcontroller
|
||||
name = "Z-Level Controller"
|
||||
var/initialized = 0 // when set to 1, turfs will report to the controller
|
||||
var/up = 0 // 1 allows up movement
|
||||
var/up_target = 0 // the Z-level that is above the current one
|
||||
var/down = 0 // 1 allows down movement
|
||||
var/down_target = 0 // the Z-level that is below the current one
|
||||
|
||||
var/list/slow = list()
|
||||
var/list/normal = list()
|
||||
var/list/fast = list()
|
||||
|
||||
var/slow_time
|
||||
var/normal_time
|
||||
var/fast_time
|
||||
|
||||
/obj/effect/landmark/zcontroller/New()
|
||||
..()
|
||||
for (var/turf/T in world)
|
||||
if (T.z == z)
|
||||
fast += T
|
||||
slow_time = world.time + 3000
|
||||
normal_time = world.time + 600
|
||||
fast_time = world.time + 10
|
||||
|
||||
processing_objects.Add(src)
|
||||
|
||||
initialized = 1
|
||||
return 1
|
||||
|
||||
/obj/effect/landmark/zcontroller/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/landmark/zcontroller/process()
|
||||
if (world.time > fast_time)
|
||||
calc(fast)
|
||||
fast_time = world.time + 10
|
||||
|
||||
if (world.time > normal_time)
|
||||
calc(normal)
|
||||
normal_time = world.time + 600
|
||||
|
||||
/* if (world.time > slow_time)
|
||||
calc(slow)
|
||||
slow_time = world.time + 3000 */
|
||||
return
|
||||
|
||||
/obj/effect/landmark/zcontroller/proc/add(var/list/L, var/I, var/transfer)
|
||||
while (L.len)
|
||||
var/turf/T = pick(L)
|
||||
|
||||
L -= T
|
||||
slow -= T
|
||||
normal -= T
|
||||
fast -= T
|
||||
|
||||
if(!T || !istype(T, /turf))
|
||||
continue
|
||||
|
||||
switch (I)
|
||||
if(1) slow += T
|
||||
if(2) normal += T
|
||||
if(3) fast += T
|
||||
|
||||
if(transfer > 0)
|
||||
if(up)
|
||||
var/turf/controller_up = locate(1, 1, up_target)
|
||||
for(var/obj/effect/landmark/zcontroller/c_up in controller_up)
|
||||
var/list/temp = list()
|
||||
temp += locate(T.x, T.y, up_target)
|
||||
c_up.add(temp, I, transfer-1)
|
||||
|
||||
if(down)
|
||||
var/turf/controller_down = locate(1, 1, down_target)
|
||||
for(var/obj/effect/landmark/zcontroller/c_down in controller_down)
|
||||
var/list/temp = list()
|
||||
temp += locate(T.x, T.y, down_target)
|
||||
c_down.add(temp, I, transfer-1)
|
||||
return
|
||||
|
||||
/turf
|
||||
var/list/z_overlays = list()
|
||||
|
||||
/turf/New()
|
||||
..()
|
||||
|
||||
var/turf/controller = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/c in controller)
|
||||
if(c.initialized)
|
||||
var/list/turf = list()
|
||||
turf += src
|
||||
c.add(turf,3,1)
|
||||
|
||||
atom/movable/Move() //Hackish
|
||||
. = ..()
|
||||
|
||||
var/turf/controllerlocation = locate(1, 1, src.z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.up || controller.down)
|
||||
var/list/temp = list()
|
||||
temp += locate(src.x, src.y, src.z)
|
||||
controller.add(temp,3,1)
|
||||
|
||||
/obj/effect/landmark/zcontroller/proc/calc(var/list/L)
|
||||
var/list/slowholder = list()
|
||||
var/list/normalholder = list()
|
||||
var/list/fastholder = list()
|
||||
var/new_list
|
||||
|
||||
while(L.len)
|
||||
var/turf/T = pick(L)
|
||||
new_list = 0
|
||||
|
||||
if(!T || !istype(T, /turf))
|
||||
L -= T
|
||||
continue
|
||||
|
||||
T.overlays -= T.z_overlays
|
||||
T.z_overlays -= T.z_overlays
|
||||
|
||||
if(down && (istype(T, /turf/space) || istype(T, /turf/simulated/floor/open)))
|
||||
var/turf/below = locate(T.x, T.y, down_target)
|
||||
if(below)
|
||||
if(!(istype(below, /turf/space) || istype(below, /turf/simulated/floor/open)))
|
||||
var/image/t_img = list()
|
||||
new_list = 1
|
||||
|
||||
var/image/temp = image(below, dir=below.dir, layer = TURF_LAYER + 0.04)
|
||||
|
||||
temp.color = rgb(127,127,127)
|
||||
temp.overlays += below.overlays
|
||||
t_img += temp
|
||||
T.overlays += t_img
|
||||
T.z_overlays += t_img
|
||||
|
||||
// get objects
|
||||
var/image/o_img = list()
|
||||
for(var/obj/o in below)
|
||||
// ingore objects that have any form of invisibility
|
||||
if(o.invisibility) continue
|
||||
new_list = 2
|
||||
var/image/temp2 = image(o, dir=o.dir, layer = TURF_LAYER+0.05*o.layer)
|
||||
temp2.color = rgb(127,127,127)
|
||||
temp2.overlays += o.overlays
|
||||
o_img += temp2
|
||||
// you need to add a list to .overlays or it will not display any because space
|
||||
T.overlays += o_img
|
||||
T.z_overlays += o_img
|
||||
|
||||
// get mobs
|
||||
var/image/m_img = list()
|
||||
for(var/mob/m in below)
|
||||
// ingore mobs that have any form of invisibility
|
||||
if(m.invisibility) continue
|
||||
// only add this tile to fastprocessing if there is a living mob, not a dead one
|
||||
if(istype(m, /mob/living)) new_list = 3
|
||||
var/image/temp2 = image(m, dir=m.dir, layer = TURF_LAYER+0.05*m.layer)
|
||||
temp2.color = rgb(127,127,127)
|
||||
temp2.overlays += m.overlays
|
||||
m_img += temp2
|
||||
// you need to add a list to .overlays or it will not display any because space
|
||||
T.overlays += m_img
|
||||
T.z_overlays += m_img
|
||||
|
||||
T.overlays -= below.z_overlays
|
||||
T.z_overlays -= below.z_overlays
|
||||
|
||||
// this is sadly impossible to use right now
|
||||
// the overlay is always opaque to mouseclicks and thus prevents interactions with everything except the turf
|
||||
/*if(up)
|
||||
var/turf/above = locate(T.x, T.y, up_target)
|
||||
if(above)
|
||||
var/eligeable = 0
|
||||
for(var/d in cardinal)
|
||||
var/turf/mT = get_step(above,d)
|
||||
if(istype(mT, /turf/space) || istype(mT, /turf/simulated/floor/open))
|
||||
eligeable = 1
|
||||
/*if(mT.opacity == 0)
|
||||
for(var/f in cardinal)
|
||||
var/turf/nT = get_step(mT,f)
|
||||
if(istype(nT, /turf/space) || istype(nT, /turf/simulated/floor/open))
|
||||
eligeable = 1*/
|
||||
if(istype(above, /turf/space) || istype(above, /turf/simulated/floor/open)) eligeable = 1
|
||||
if(eligeable == 1)
|
||||
if(!(istype(above, /turf/space) || istype(above, /turf/simulated/floor/open)))
|
||||
var/image/t_img = list()
|
||||
if(new_list < 1) new_list = 1
|
||||
|
||||
above.overlays -= above.z_overlays
|
||||
var/image/temp = image(above, dir=above.dir, layer = 5 + 0.04)
|
||||
above.overlays += above.z_overlays
|
||||
|
||||
temp.alpha = 100
|
||||
temp.overlays += above.overlays
|
||||
temp.overlays -= above.z_overlays
|
||||
t_img += temp
|
||||
T.overlays += t_img
|
||||
T.z_overlays += t_img
|
||||
|
||||
// get objects
|
||||
var/image/o_img = list()
|
||||
for(var/obj/o in above)
|
||||
// ingore objects that have any form of invisibility
|
||||
if(o.invisibility) continue
|
||||
if(new_list < 2) new_list = 2
|
||||
var/image/temp2 = image(o, dir=o.dir, layer = 5+0.05*o.layer)
|
||||
temp2.alpha = 100
|
||||
temp2.overlays += o.overlays
|
||||
o_img += temp2
|
||||
// you need to add a list to .overlays or it will not display any because space
|
||||
T.overlays += o_img
|
||||
T.z_overlays += o_img
|
||||
|
||||
// get mobs
|
||||
var/image/m_img = list()
|
||||
for(var/mob/m in above)
|
||||
// ingore mobs that have any form of invisibility
|
||||
if(m.invisibility) continue
|
||||
// only add this tile to fastprocessing if there is a living mob, not a dead one
|
||||
if(istype(m, /mob/living) && new_list < 3) new_list = 3
|
||||
var/image/temp2 = image(m, dir=m.dir, layer = 5+0.05*m.layer)
|
||||
temp2.alpha = 100
|
||||
temp2.overlays += m.overlays
|
||||
m_img += temp2
|
||||
// you need to add a list to .overlays or it will not display any because space
|
||||
T.overlays += m_img
|
||||
T.z_overlays += m_img
|
||||
|
||||
T.overlays -= above.z_overlays
|
||||
T.z_overlays -= above.z_overlays*/
|
||||
|
||||
L -= T
|
||||
|
||||
if(new_list == 1)
|
||||
slowholder += T
|
||||
if(new_list == 2)
|
||||
normalholder += T
|
||||
if(new_list == 3)
|
||||
fastholder += T
|
||||
for(var/d in cardinal)
|
||||
var/turf/mT = get_step(T,d)
|
||||
if(!(mT in fastholder))
|
||||
fastholder += mT
|
||||
for(var/f in cardinal)
|
||||
var/turf/nT = get_step(mT,f)
|
||||
if(!(nT in fastholder))
|
||||
fastholder += nT
|
||||
|
||||
add(slowholder,1, 0)
|
||||
add(normalholder, 2, 0)
|
||||
add(fastholder, 3, 0)
|
||||
return
|
||||
@@ -1,37 +0,0 @@
|
||||
/obj/effect/landmark/zcontroller/level_1_bottom
|
||||
up = 1
|
||||
up_target = 1 //2
|
||||
|
||||
/obj/effect/landmark/zcontroller/level_2_mid
|
||||
up = 1
|
||||
up_target = 6 //3
|
||||
down = 1
|
||||
down_target = 2 //1
|
||||
|
||||
/obj/effect/landmark/zcontroller/level_3_mid
|
||||
up = 1
|
||||
up_target = 2 //4
|
||||
down = 1
|
||||
down_target = 1 //2
|
||||
|
||||
/obj/effect/landmark/zcontroller/level_4_mid
|
||||
up = 1
|
||||
up_target = 5
|
||||
down = 1
|
||||
down_target = 3
|
||||
|
||||
/obj/effect/landmark/zcontroller/level_2_top
|
||||
down = 1
|
||||
down_target = 1
|
||||
|
||||
/obj/effect/landmark/zcontroller/level_3_top
|
||||
down = 1
|
||||
down_target = 2
|
||||
|
||||
/obj/effect/landmark/zcontroller/level_4_top
|
||||
down = 1
|
||||
down_target = 6 //3
|
||||
|
||||
/obj/effect/landmark/zcontroller/level_5_top
|
||||
down = 1
|
||||
down_target = 4
|
||||
@@ -11,6 +11,9 @@ mob/proc/airflow_stun()
|
||||
if(!(status_flags & CANSTUN) && !(status_flags & CANWEAKEN))
|
||||
src << "<span class='notice'>You stay upright as the air rushes past you.</span>"
|
||||
return 0
|
||||
if(buckled)
|
||||
src << "<span class='notice'>Air suddenly rushes past you!</span>"
|
||||
return 0
|
||||
if(!lying)
|
||||
src << "<span class='warning'>The sudden rush of air knocks you over!</span>"
|
||||
Weaken(5)
|
||||
@@ -24,7 +27,7 @@ mob/living/carbon/slime/airflow_stun()
|
||||
|
||||
mob/living/carbon/human/airflow_stun()
|
||||
if(shoes)
|
||||
if(shoes.flags & NOSLIP) return 0
|
||||
if(shoes.item_flags & NOSLIP) return 0
|
||||
..()
|
||||
|
||||
atom/movable/proc/check_airflow_movable(n)
|
||||
@@ -62,6 +65,19 @@ obj/item/check_airflow_movable(n)
|
||||
/atom/movable/var/tmp/airflow_time = 0
|
||||
/atom/movable/var/tmp/last_airflow = 0
|
||||
|
||||
/atom/movable/proc/AirflowCanMove(n)
|
||||
return 1
|
||||
|
||||
/mob/AirflowCanMove(n)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
if(buckled)
|
||||
return 0
|
||||
var/obj/item/shoes = get_equipped_item(slot_shoes)
|
||||
if(istype(shoes) && (shoes.item_flags & NOSLIP))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/atom/movable/proc/GotoAirflowDest(n)
|
||||
if(!airflow_dest) return
|
||||
if(airflow_speed < 0) return
|
||||
@@ -69,18 +85,13 @@ obj/item/check_airflow_movable(n)
|
||||
if(airflow_speed)
|
||||
airflow_speed = n/max(get_dist(src,airflow_dest),1)
|
||||
return
|
||||
last_airflow = world.time
|
||||
if(airflow_dest == loc)
|
||||
step_away(src,loc)
|
||||
if(!src.AirflowCanMove(n))
|
||||
return
|
||||
if(ismob(src))
|
||||
if(src:status_flags & GODMODE)
|
||||
return
|
||||
if(istype(src, /mob/living/carbon/human))
|
||||
if(src:buckled)
|
||||
return
|
||||
if(src:shoes && src:shoes.flags & NOSLIP)
|
||||
return
|
||||
src << "\red You are sucked away by airflow!"
|
||||
src << "<span class='danger'>You are sucked away by airflow!</span>"
|
||||
last_airflow = world.time
|
||||
var/airflow_falloff = 9 - sqrt((x - airflow_dest.x) ** 2 + (y - airflow_dest.y) ** 2)
|
||||
if(airflow_falloff < 1)
|
||||
airflow_dest = null
|
||||
@@ -116,8 +127,9 @@ obj/item/check_airflow_movable(n)
|
||||
if(!istype(loc, /turf))
|
||||
break
|
||||
step_towards(src, src.airflow_dest)
|
||||
if(ismob(src) && src:client)
|
||||
src:client:move_delay = world.time + vsc.airflow_mob_slowdown
|
||||
var/mob/M = src
|
||||
if(istype(M) && M.client)
|
||||
M.setMoveCooldown(vsc.airflow_mob_slowdown)
|
||||
airflow_dest = null
|
||||
airflow_speed = 0
|
||||
airflow_time = 0
|
||||
@@ -134,17 +146,10 @@ obj/item/check_airflow_movable(n)
|
||||
return
|
||||
if(airflow_dest == loc)
|
||||
step_away(src,loc)
|
||||
if(!src.AirflowCanMove(n))
|
||||
return
|
||||
if(ismob(src))
|
||||
if(src:status_flags & GODMODE)
|
||||
return
|
||||
if(istype(src, /mob/living/carbon/human))
|
||||
if(src:buckled)
|
||||
return
|
||||
if(src:shoes)
|
||||
if(istype(src:shoes, /obj/item/clothing/shoes/magboots))
|
||||
if(src:shoes.flags & NOSLIP)
|
||||
return
|
||||
src << "\red You are pushed away by airflow!"
|
||||
src << "<span clas='danger'>You are pushed away by airflow!</span>"
|
||||
last_airflow = world.time
|
||||
var/airflow_falloff = 9 - sqrt((x - airflow_dest.x) ** 2 + (y - airflow_dest.y) ** 2)
|
||||
if(airflow_falloff < 1)
|
||||
@@ -197,7 +202,7 @@ atom/movable/proc/airflow_hit(atom/A)
|
||||
|
||||
mob/airflow_hit(atom/A)
|
||||
for(var/mob/M in hearers(src))
|
||||
M.show_message("\red <B>\The [src] slams into \a [A]!</B>",1,"\red You hear a loud slam!",2)
|
||||
M.show_message("<span class='danger'>\The [src] slams into \a [A]!</span>",1,"<span class='danger'>You hear a loud slam!</span>",2)
|
||||
playsound(src.loc, "smash.ogg", 25, 1, -1)
|
||||
var/weak_amt = istype(A,/obj/item) ? A:w_class : rand(1,5) //Heheheh
|
||||
Weaken(weak_amt)
|
||||
@@ -205,7 +210,7 @@ mob/airflow_hit(atom/A)
|
||||
|
||||
obj/airflow_hit(atom/A)
|
||||
for(var/mob/M in hearers(src))
|
||||
M.show_message("\red <B>\The [src] slams into \a [A]!</B>",1,"\red You hear a loud slam!",2)
|
||||
M.show_message("<span class='danger'>\The [src] slams into \a [A]!</span>",1,"<span class='danger'>You hear a loud slam!</span>",2)
|
||||
playsound(src.loc, "smash.ogg", 25, 1, -1)
|
||||
. = ..()
|
||||
|
||||
@@ -215,7 +220,7 @@ obj/item/airflow_hit(atom/A)
|
||||
|
||||
mob/living/carbon/human/airflow_hit(atom/A)
|
||||
// for(var/mob/M in hearers(src))
|
||||
// M.show_message("\red <B>[src] slams into [A]!</B>",1,"\red You hear a loud slam!",2)
|
||||
// M.show_message("<span class='danger'>[src] slams into [A]!</span>",1,"<span class='danger'>You hear a loud slam!</span>",2)
|
||||
playsound(src.loc, "punch", 25, 1, -1)
|
||||
if (prob(33))
|
||||
loc:add_blood(src)
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
|
||||
|
||||
/atom/var/pressure_resistance = ONE_ATMOSPHERE
|
||||
|
||||
/atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
||||
//Purpose: Determines if the object (or airflow) can pass this atom.
|
||||
//Called by: Movement, airflow.
|
||||
@@ -64,9 +61,9 @@ turf/c_airblock(turf/other)
|
||||
#ifdef ZLEVELS
|
||||
if(other.z != src.z)
|
||||
if(other.z < src.z)
|
||||
if(!istype(src, /turf/simulated/floor/open)) return BLOCKED
|
||||
if(!istype(src, /turf/simulated/open)) return BLOCKED
|
||||
else
|
||||
if(!istype(other, /turf/simulated/floor/open)) return BLOCKED
|
||||
if(!istype(other, /turf/simulated/open)) return BLOCKED
|
||||
#endif
|
||||
|
||||
var/result = 0
|
||||
|
||||
@@ -109,13 +109,13 @@ Class Procs:
|
||||
simulated_turf_count++
|
||||
S.update_air_properties()
|
||||
|
||||
admin_notice({"<span class='danger'>Geometry initialized in [round(0.1*(world.timeofday-start_time),0.1)] seconds.</b></span>
|
||||
admin_notice({"<span class='danger'>Geometry initialized in [round(0.1*(world.timeofday-start_time),0.1)] seconds.</span>
|
||||
<span class='info'>
|
||||
Total Simulated Turfs: [simulated_turf_count]
|
||||
Total Zones: [zones.len]
|
||||
Total Edges: [edges.len]
|
||||
Total Active Edges: [active_edges.len ? "<span class='danger'>[active_edges.len]</span>" : "None"]
|
||||
Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_count]</font>
|
||||
Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_count]
|
||||
</span>"}, R_DEBUG)
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
#ifdef ZASDBG
|
||||
if(updated != updating.len)
|
||||
tick_progress = "[updating.len - updated] tiles left unupdated."
|
||||
world << "\red [tick_progress]"
|
||||
world << "<span class='danger'>[tick_progress]</span>"
|
||||
. = 0
|
||||
#endif
|
||||
|
||||
|
||||
@@ -84,153 +84,6 @@ client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
|
||||
else
|
||||
mob << "both turfs can merge."
|
||||
|
||||
|
||||
/*zone/proc/DebugDisplay(client/client)
|
||||
if(!istype(client))
|
||||
return
|
||||
|
||||
if(!dbg_output)
|
||||
dbg_output = 1 //Don't want to be spammed when someone investigates a zone...
|
||||
|
||||
if(!client.zone_debug_images)
|
||||
client.zone_debug_images = list()
|
||||
|
||||
var/list/current_zone_images = list()
|
||||
|
||||
for(var/turf/T in contents)
|
||||
current_zone_images += image('icons/misc/debug_group.dmi', T, null, TURF_LAYER)
|
||||
|
||||
for(var/turf/space/S in unsimulated_tiles)
|
||||
current_zone_images += image('icons/misc/debug_space.dmi', S, null, TURF_LAYER)
|
||||
|
||||
client << "<u>Zone Air Contents</u>"
|
||||
client << "Oxygen: [air.oxygen]"
|
||||
client << "Nitrogen: [air.nitrogen]"
|
||||
client << "Phoron: [air.phoron]"
|
||||
client << "Carbon Dioxide: [air.carbon_dioxide]"
|
||||
client << "Temperature: [air.temperature] K"
|
||||
client << "Heat Energy: [air.temperature * air.heat_capacity()] J"
|
||||
client << "Pressure: [air.return_pressure()] KPa"
|
||||
client << ""
|
||||
client << "Space Tiles: [length(unsimulated_tiles)]"
|
||||
client << "Movable Objects: [length(movables())]"
|
||||
client << "<u>Connections: [length(connections)]</u>"
|
||||
|
||||
for(var/connection/C in connections)
|
||||
client << "\ref[C] [C.A] --> [C.B] [(C.indirect?"Open":"Closed")]"
|
||||
current_zone_images += image('icons/misc/debug_connect.dmi', C.A, null, TURF_LAYER)
|
||||
current_zone_images += image('icons/misc/debug_connect.dmi', C.B, null, TURF_LAYER)
|
||||
|
||||
client << "Connected Zones:"
|
||||
for(var/zone/zone in connected_zones)
|
||||
client << "\ref[zone] [zone] - [connected_zones[zone]] (Connected)"
|
||||
|
||||
for(var/zone/zone in closed_connection_zones)
|
||||
client << "\ref[zone] [zone] - [closed_connection_zones[zone]] (Unconnected)"
|
||||
|
||||
for(var/C in connections)
|
||||
if(!istype(C,/connection))
|
||||
client << "[C] (Not Connection!)"
|
||||
|
||||
if(!client.zone_debug_images)
|
||||
client.zone_debug_images = list()
|
||||
client.zone_debug_images[src] = current_zone_images
|
||||
|
||||
client.images += client.zone_debug_images[src]
|
||||
|
||||
else
|
||||
dbg_output = 0
|
||||
|
||||
client.images -= client.zone_debug_images[src]
|
||||
client.zone_debug_images.Remove(src)
|
||||
|
||||
if(air_master)
|
||||
for(var/zone/Z in air_master.zones)
|
||||
if(Z.air == air && Z != src)
|
||||
var/turf/zloc = pick(Z.contents)
|
||||
client << "\red Illegal air datum shared by: [zloc.loc.name]"*/
|
||||
|
||||
|
||||
/*client/proc/TestZASRebuild()
|
||||
set category = "Debug"
|
||||
// var/turf/turf = get_turf(mob)
|
||||
var/zone/current_zone = mob.loc:zone
|
||||
if(!current_zone)
|
||||
src << "There is no zone there!"
|
||||
return
|
||||
|
||||
var/list/current_adjacents = list()
|
||||
var/list/overlays = list()
|
||||
var/adjacent_id
|
||||
var/lowest_id
|
||||
|
||||
var/list/identical_ids = list()
|
||||
var/list/turfs = current_zone.contents.Copy()
|
||||
var/current_identifier = 1
|
||||
|
||||
for(var/turf/simulated/current in turfs)
|
||||
lowest_id = null
|
||||
current_adjacents = list()
|
||||
|
||||
for(var/direction in cardinal)
|
||||
var/turf/simulated/adjacent = get_step(current, direction)
|
||||
if(!current.ZCanPass(adjacent))
|
||||
continue
|
||||
if(turfs.Find(adjacent))
|
||||
current_adjacents += adjacent
|
||||
adjacent_id = turfs[adjacent]
|
||||
|
||||
if(adjacent_id && (!lowest_id || adjacent_id < lowest_id))
|
||||
lowest_id = adjacent_id
|
||||
|
||||
if(!lowest_id)
|
||||
lowest_id = current_identifier++
|
||||
identical_ids += lowest_id
|
||||
overlays += image('icons/misc/debug_rebuild.dmi',, "[lowest_id]")
|
||||
|
||||
for(var/turf/simulated/adjacent in current_adjacents)
|
||||
adjacent_id = turfs[adjacent]
|
||||
if(adjacent_id != lowest_id)
|
||||
if(adjacent_id)
|
||||
adjacent.overlays -= overlays[adjacent_id]
|
||||
identical_ids[adjacent_id] = lowest_id
|
||||
|
||||
turfs[adjacent] = lowest_id
|
||||
adjacent.overlays += overlays[lowest_id]
|
||||
|
||||
sleep(5)
|
||||
|
||||
if(turfs[current])
|
||||
current.overlays -= overlays[turfs[current]]
|
||||
turfs[current] = lowest_id
|
||||
current.overlays += overlays[lowest_id]
|
||||
sleep(5)
|
||||
|
||||
var/list/final_arrangement = list()
|
||||
|
||||
for(var/turf/simulated/current in turfs)
|
||||
current_identifier = identical_ids[turfs[current]]
|
||||
current.overlays -= overlays[turfs[current]]
|
||||
current.overlays += overlays[current_identifier]
|
||||
sleep(5)
|
||||
|
||||
if( current_identifier > final_arrangement.len )
|
||||
final_arrangement.len = current_identifier
|
||||
final_arrangement[current_identifier] = list(current)
|
||||
|
||||
else
|
||||
final_arrangement[current_identifier] += current
|
||||
|
||||
//lazy but fast
|
||||
final_arrangement.Remove(null)
|
||||
|
||||
src << "There are [final_arrangement.len] unique segments."
|
||||
|
||||
for(var/turf/current in turfs)
|
||||
current.overlays -= overlays
|
||||
|
||||
return final_arrangement*/
|
||||
|
||||
client/proc/ZASSettings()
|
||||
set category = "Debug"
|
||||
|
||||
|
||||
@@ -7,6 +7,9 @@ If it gains pressure too slowly, it may leak or just rupture instead of explodin
|
||||
*/
|
||||
|
||||
//#define FIREDBG
|
||||
#define FIRE_LIGHT_1 2 //These defines are the power of the light given off by fire at various stages
|
||||
#define FIRE_LIGHT_2 3
|
||||
#define FIRE_LIGHT_3 4
|
||||
|
||||
/turf/var/obj/fire/fire = null
|
||||
|
||||
@@ -134,13 +137,13 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
|
||||
|
||||
if(firelevel > 6)
|
||||
icon_state = "3"
|
||||
set_light(7, 3)
|
||||
set_light(7, FIRE_LIGHT_3)
|
||||
else if(firelevel > 2.5)
|
||||
icon_state = "2"
|
||||
set_light(5, 2)
|
||||
set_light(5, FIRE_LIGHT_2)
|
||||
else
|
||||
icon_state = "1"
|
||||
set_light(3, 1)
|
||||
set_light(3, FIRE_LIGHT_1)
|
||||
|
||||
for(var/mob/living/L in loc)
|
||||
L.FireBurn(firelevel, air_contents.temperature, air_contents.return_pressure()) //Burn the mobs!
|
||||
@@ -432,3 +435,8 @@ datum/gas_mixture/proc/check_recombustability(list/fuel_objs)
|
||||
apply_damage(0.6*mx*legs_exposure, BURN, "r_leg", 0, 0, "Fire")
|
||||
apply_damage(0.4*mx*arms_exposure, BURN, "l_arm", 0, 0, "Fire")
|
||||
apply_damage(0.4*mx*arms_exposure, BURN, "r_arm", 0, 0, "Fire")
|
||||
|
||||
|
||||
#undef FIRE_LIGHT_1
|
||||
#undef FIRE_LIGHT_2
|
||||
#undef FIRE_LIGHT_3
|
||||
@@ -88,7 +88,7 @@ obj/var/contaminated = 0
|
||||
if(vsc.plc.SKIN_BURNS)
|
||||
if(!pl_head_protected() || !pl_suit_protected())
|
||||
burn_skin(0.75)
|
||||
if(prob(20)) src << "\red Your skin burns!"
|
||||
if(prob(20)) src << "<span class='danger'>Your skin burns!</span>"
|
||||
updatehealth()
|
||||
|
||||
//Burn eyes if exposed.
|
||||
@@ -97,36 +97,36 @@ obj/var/contaminated = 0
|
||||
if(!wear_mask)
|
||||
burn_eyes()
|
||||
else
|
||||
if(!(wear_mask.flags & MASKCOVERSEYES))
|
||||
if(!(wear_mask.body_parts_covered & EYES))
|
||||
burn_eyes()
|
||||
else
|
||||
if(!(head.flags & HEADCOVERSEYES))
|
||||
if(!(head.body_parts_covered & EYES))
|
||||
if(!wear_mask)
|
||||
burn_eyes()
|
||||
else
|
||||
if(!(wear_mask.flags & MASKCOVERSEYES))
|
||||
if(!(wear_mask.body_parts_covered & EYES))
|
||||
burn_eyes()
|
||||
|
||||
//Genetic Corruption
|
||||
if(vsc.plc.GENETIC_CORRUPTION)
|
||||
if(rand(1,10000) < vsc.plc.GENETIC_CORRUPTION)
|
||||
randmutb(src)
|
||||
src << "\red High levels of toxins cause you to spontaneously mutate."
|
||||
src << "<span class='danger'>High levels of toxins cause you to spontaneously mutate!</span>"
|
||||
domutcheck(src,null)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/burn_eyes()
|
||||
//The proc that handles eye burning.
|
||||
if(!species.has_organ["eyes"] || get_species() == "Vaurca")
|
||||
if(!species.has_organ["eyes"] || isvaurca(src))
|
||||
return
|
||||
|
||||
var/obj/item/organ/eyes/E = internal_organs_by_name["eyes"]
|
||||
if(E)
|
||||
if(prob(20)) src << "\red Your eyes burn!"
|
||||
if(prob(20)) src << "<span class='danger'>Your eyes burn!</span>"
|
||||
E.damage += 2.5
|
||||
eye_blurry = min(eye_blurry+1.5,50)
|
||||
if (prob(max(0,E.damage - 15) + 1) &&!eye_blind)
|
||||
src << "\red You are blinded!"
|
||||
src << "<span class='danger'>You are blinded!</span>"
|
||||
eye_blind += 20
|
||||
|
||||
/mob/living/carbon/human/proc/pl_head_protected()
|
||||
@@ -135,19 +135,24 @@ obj/var/contaminated = 0
|
||||
if(vsc.plc.PHORONGUARD_ONLY)
|
||||
if(head.flags & PHORONGUARD)
|
||||
return 1
|
||||
else if(head.flags & HEADCOVERSEYES)
|
||||
else if(head.body_parts_covered & EYES)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/proc/pl_suit_protected()
|
||||
//Checks if the suit is adequately sealed.
|
||||
if(wear_suit)
|
||||
if(vsc.plc.PHORONGUARD_ONLY)
|
||||
if(wear_suit.flags & PHORONGUARD) return 1
|
||||
else
|
||||
if(wear_suit.flags_inv & HIDEJUMPSUIT) return 1
|
||||
//should check HIDETAIL as well, but for the moment tails are not a part that can be damaged separately
|
||||
var/coverage = 0
|
||||
for(var/obj/item/protection in list(wear_suit, gloves, shoes))
|
||||
if(!protection)
|
||||
continue
|
||||
if(vsc.plc.PHORONGUARD_ONLY && !(protection.flags & PHORONGUARD))
|
||||
return 0
|
||||
coverage |= protection.body_parts_covered
|
||||
|
||||
if(vsc.plc.PHORONGUARD_ONLY)
|
||||
return 1
|
||||
|
||||
return BIT_TEST_ALL(coverage, UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS)
|
||||
|
||||
/mob/living/carbon/human/proc/suit_contamination()
|
||||
//Runs over the things that can be contaminated and does so.
|
||||
|
||||
@@ -169,7 +169,7 @@ var/global/vs_control/vsc = new
|
||||
vars[ch] = vw
|
||||
if(how == "Toggle")
|
||||
newvar = (newvar?"ON":"OFF")
|
||||
world << "\blue <b>[key_name(user)] changed the setting [display_description] to [newvar].</b>"
|
||||
world << "<span class='notice'><b>[key_name(user)] changed the setting [display_description] to [newvar].</b></span>"
|
||||
if(ch in plc.settings)
|
||||
ChangeSettingsDialog(user,plc.settings)
|
||||
else
|
||||
@@ -322,7 +322,7 @@ var/global/vs_control/vsc = new
|
||||
plc.N2O_HALLUCINATION = initial(plc.N2O_HALLUCINATION)
|
||||
|
||||
|
||||
world << "\blue <b>[key_name(user)] changed the global phoron/ZAS settings to \"[def]\"</b>"
|
||||
world << "<span class='notice'><b>[key_name(user)] changed the global phoron/ZAS settings to \"[def]\"</b></span>"
|
||||
|
||||
/pl_control/var/list/settings = list()
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
// Returns the atom sitting on the turf.
|
||||
// For example, using this on a disk, which is in a bag, on a mob, will return the mob because it's on the turf.
|
||||
/proc/get_atom_on_turf(var/atom/movable/M)
|
||||
var/atom/mloc = M
|
||||
while(mloc && mloc.loc && !istype(mloc.loc, /turf/))
|
||||
mloc = mloc.loc
|
||||
return mloc
|
||||
|
||||
/proc/iswall(turf/T)
|
||||
return (istype(T, /turf/simulated/wall) || istype(T, /turf/unsimulated/wall) || istype(T, /turf/simulated/shuttle/wall))
|
||||
|
||||
/proc/isfloor(turf/T)
|
||||
return (istype(T, /turf/simulated/floor) || istype(T, /turf/unsimulated/floor) || istype(T, /turf/simulated/shuttle/floor))
|
||||
|
||||
/proc/turf_clear(turf/T)
|
||||
for(var/atom/A in T)
|
||||
if(A.simulated)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
// Picks a turf without a mob from the given list of turfs, if one exists.
|
||||
// If no such turf exists, picks any random turf from the given list of turfs.
|
||||
/proc/pick_mobless_turf_if_exists(var/list/start_turfs)
|
||||
if(!start_turfs.len)
|
||||
return null
|
||||
|
||||
var/list/available_turfs = list()
|
||||
for(var/start_turf in start_turfs)
|
||||
var/mob/M = locate() in start_turf
|
||||
if(!M)
|
||||
available_turfs += start_turf
|
||||
if(!available_turfs.len)
|
||||
available_turfs = start_turfs
|
||||
return pick(available_turfs)
|
||||
2
code/__defines/_compile_options.dm
Normal file
2
code/__defines/_compile_options.dm
Normal file
@@ -0,0 +1,2 @@
|
||||
#define BACKGROUND_ENABLED 0 // The default value for all uses of set background. Set background can cause gradual lag and is recommended you only turn this on if necessary.
|
||||
// 1 will enable set background. 0 will disable set background.
|
||||
43
code/__defines/admin.dm
Normal file
43
code/__defines/admin.dm
Normal file
@@ -0,0 +1,43 @@
|
||||
// A set of constants used to determine which type of mute an admin wishes to apply.
|
||||
// Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO, etc. = (MUTE_IC << 1)
|
||||
// Therefore there needs to be a gap between the flags for the automute flags.
|
||||
#define MUTE_IC 0x1
|
||||
#define MUTE_OOC 0x2
|
||||
#define MUTE_PRAY 0x4
|
||||
#define MUTE_ADMINHELP 0x8
|
||||
#define MUTE_DEADCHAT 0x10
|
||||
#define MUTE_AOOC 0x20
|
||||
#define MUTE_ALL 0xFFFF
|
||||
|
||||
// Number of identical messages required to get the spam-prevention auto-mute thing to trigger warnings and automutes.
|
||||
#define SPAM_TRIGGER_WARNING 5
|
||||
#define SPAM_TRIGGER_AUTOMUTE 10
|
||||
|
||||
// Some constants for DB_Ban
|
||||
#define BANTYPE_PERMA 1
|
||||
#define BANTYPE_TEMP 2
|
||||
#define BANTYPE_JOB_PERMA 3
|
||||
#define BANTYPE_JOB_TEMP 4
|
||||
#define BANTYPE_ANY_FULLBAN 5 // Used to locate stuff to unban.
|
||||
|
||||
#define ROUNDSTART_LOGOUT_REPORT_TIME 6000 // Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued.
|
||||
|
||||
// Admin permissions.
|
||||
#define R_BUILDMODE 0x1
|
||||
#define R_ADMIN 0x2
|
||||
#define R_BAN 0x4
|
||||
#define R_FUN 0x8
|
||||
#define R_SERVER 0x10
|
||||
#define R_DEBUG 0x20
|
||||
#define R_POSSESS 0x40
|
||||
#define R_PERMISSIONS 0x80
|
||||
#define R_STEALTH 0x100
|
||||
#define R_REJUVINATE 0x200
|
||||
#define R_VAREDIT 0x400
|
||||
#define R_SOUNDS 0x800
|
||||
#define R_SPAWN 0x1000
|
||||
#define R_MOD 0x2000
|
||||
#define R_DEV 0x4000
|
||||
#define R_CCIAA 0x8000 //higher than this will overflow
|
||||
|
||||
#define R_MAXPERMISSION 0x8000 // This holds the maximum value for a permission. It is used in iteration, so keep it updated.
|
||||
96
code/__defines/atmos.dm
Normal file
96
code/__defines/atmos.dm
Normal file
@@ -0,0 +1,96 @@
|
||||
|
||||
#define CELL_VOLUME 2500 // Liters in a cell.
|
||||
#define MOLES_CELLSTANDARD (ONE_ATMOSPHERE*CELL_VOLUME/(T20C*R_IDEAL_GAS_EQUATION)) // Moles in a 2.5 m^3 cell at 101.325 kPa and 20 C.
|
||||
|
||||
#define O2STANDARD 0.21 // Percentage.
|
||||
#define N2STANDARD 0.79
|
||||
|
||||
#define MOLES_PHORON_VISIBLE 0.7 // Moles in a standard cell after which phoron is visible.
|
||||
#define MOLES_O2STANDARD (MOLES_CELLSTANDARD * O2STANDARD) // O2 standard value (21%)
|
||||
#define MOLES_N2STANDARD (MOLES_CELLSTANDARD * N2STANDARD) // N2 standard value (79%)
|
||||
#define MOLES_O2ATMOS (MOLES_O2STANDARD*50)
|
||||
#define MOLES_N2ATMOS (MOLES_N2STANDARD*50)
|
||||
|
||||
// These are for when a mob breathes poisonous air.
|
||||
#define MIN_TOXIN_DAMAGE 1
|
||||
#define MAX_TOXIN_DAMAGE 10
|
||||
|
||||
#define BREATH_VOLUME 0.5 // Liters in a normal breath.
|
||||
#define BREATH_MOLES (ONE_ATMOSPHERE * BREATH_VOLUME / (T20C * R_IDEAL_GAS_EQUATION)) // Amount of air to take a from a tile
|
||||
#define BREATH_PERCENTAGE (BREATH_VOLUME / CELL_VOLUME) // Amount of air needed before pass out/suffocation commences.
|
||||
#define HUMAN_NEEDED_OXYGEN (MOLES_CELLSTANDARD * BREATH_PERCENTAGE * 0.16)
|
||||
#define HUMAN_HEAT_CAPACITY 280000 //J/K For 80kg person
|
||||
|
||||
#define SOUND_MINIMUM_PRESSURE 10
|
||||
|
||||
#define PRESSURE_DAMAGE_COEFFICIENT 4 // The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE.
|
||||
#define MAX_HIGH_PRESSURE_DAMAGE 4 // This used to be 20... I got this much random rage for some retarded decision by polymorph?! Polymorph now lies in a pool of blood with a katana jammed in his spleen. ~Errorage --PS: The katana did less than 20 damage to him :(
|
||||
#define LOW_PRESSURE_DAMAGE 2 // The amount of damage someone takes when in a low pressure area. (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value).
|
||||
|
||||
#define MINIMUM_AIR_RATIO_TO_SUSPEND 0.05 // Minimum ratio of air that must move to/from a tile to suspend group processing
|
||||
#define MINIMUM_AIR_TO_SUSPEND (MOLES_CELLSTANDARD * MINIMUM_AIR_RATIO_TO_SUSPEND) // Minimum amount of air that has to move before a group processing can be suspended
|
||||
#define MINIMUM_MOLES_DELTA_TO_MOVE (MOLES_CELLSTANDARD * MINIMUM_AIR_RATIO_TO_SUSPEND) // Either this must be active
|
||||
#define MINIMUM_TEMPERATURE_TO_MOVE (T20C + 100) // or this (or both, obviously)
|
||||
|
||||
#define MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND 0.012 // Minimum temperature difference before group processing is suspended.
|
||||
#define MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND 4
|
||||
#define MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER 0.5 // Minimum temperature difference before the gas temperatures are just set to be equal.
|
||||
#define MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION (T20C + 10)
|
||||
#define MINIMUM_TEMPERATURE_START_SUPERCONDUCTION (T20C + 200)
|
||||
|
||||
// Must be between 0 and 1. Values closer to 1 equalize temperature faster. Should not exceed 0.4, else strange heat flow occurs.
|
||||
#define FLOOR_HEAT_TRANSFER_COEFFICIENT 0.4
|
||||
#define WALL_HEAT_TRANSFER_COEFFICIENT 0.0
|
||||
#define DOOR_HEAT_TRANSFER_COEFFICIENT 0.0
|
||||
#define SPACE_HEAT_TRANSFER_COEFFICIENT 0.2 // A hack to partly simulate radiative heat.
|
||||
#define OPEN_HEAT_TRANSFER_COEFFICIENT 0.4
|
||||
#define WINDOW_HEAT_TRANSFER_COEFFICIENT 0.1 // A hack for now.
|
||||
|
||||
// Fire damage.
|
||||
#define CARBON_LIFEFORM_FIRE_RESISTANCE (T0C + 200)
|
||||
#define CARBON_LIFEFORM_FIRE_DAMAGE 4
|
||||
|
||||
// Phoron fire properties.
|
||||
#define PHORON_MINIMUM_BURN_TEMPERATURE (T0C + 126) //400 K - autoignite temperature in tanks and canisters - enclosed environments I guess
|
||||
#define PHORON_FLASHPOINT (T0C + 246) //519 K - autoignite temperature in air if that ever gets implemented.
|
||||
|
||||
//These control the mole ratio of oxidizer and fuel used in the combustion reaction
|
||||
#define FIRE_REACTION_OXIDIZER_AMOUNT 3 //should be greater than the fuel amount if fires are going to spread much
|
||||
#define FIRE_REACTION_FUEL_AMOUNT 2
|
||||
|
||||
//These control the speed at which fire burns
|
||||
#define FIRE_GAS_BURNRATE_MULT 1
|
||||
#define FIRE_LIQUID_BURNRATE_MULT 0.225
|
||||
|
||||
//If the fire is burning slower than this rate then the reaction is going too slow to be self sustaining and the fire burns itself out.
|
||||
//This ensures that fires don't grind to a near-halt while still remaining active forever.
|
||||
#define FIRE_GAS_MIN_BURNRATE 0.01
|
||||
#define FIRE_LIQUD_MIN_BURNRATE 0.0025
|
||||
|
||||
//How many moles of fuel are contained within one solid/liquid fuel volume unit
|
||||
#define LIQUIDFUEL_AMOUNT_TO_MOL 0.45 //mol/volume unit
|
||||
|
||||
// XGM gas flags.
|
||||
#define XGM_GAS_FUEL 1
|
||||
#define XGM_GAS_OXIDIZER 2
|
||||
#define XGM_GAS_CONTAMINANT 4
|
||||
|
||||
#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) // Tank starts leaking.
|
||||
#define TANK_RUPTURE_PRESSURE (40.*ONE_ATMOSPHERE) // Tank spills all contents into atmosphere.
|
||||
#define TANK_FRAGMENT_PRESSURE (50.*ONE_ATMOSPHERE) // Boom 3x3 base explosion.
|
||||
#define TANK_FRAGMENT_SCALE (10.*ONE_ATMOSPHERE) // +1 for each SCALE kPa above threshold. Was 2 atm.
|
||||
|
||||
#define NORMPIPERATE 30 // Pipe-insulation rate divisor.
|
||||
#define HEATPIPERATE 8 // Heat-exchange pipe insulation.
|
||||
#define FLOWFRAC 0.99 // Fraction of gas transfered per process.
|
||||
|
||||
//Flags for zone sleeping
|
||||
#define ZONE_ACTIVE 1
|
||||
#define ZONE_SLEEPING 0
|
||||
|
||||
// Defines how much of certain gas do the Atmospherics tanks start with. Values are in kpa per tile (assuming 20C)
|
||||
#define ATMOSTANK_NITROGEN 90000 // A lot of N2 is needed to produce air mix, that's why we keep 90MPa of it
|
||||
#define ATMOSTANK_OXYGEN 40000 // O2 is also important for airmix, but not as much as N2 as it's only 21% of it.
|
||||
#define ATMOSTANK_CO2 25000 // CO2 and PH are not critically important for station, only for toxins and alternative coolants, no need to store a lot of those.
|
||||
#define ATMOSTANK_PHORON 25000
|
||||
#define ATMOSTANK_NITROUSOXIDE 10000 // N2O doesn't have a real useful use, i guess it's on station just to allow refilling of sec's riot control canisters?
|
||||
40
code/__defines/chemistry.dm
Normal file
40
code/__defines/chemistry.dm
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
|
||||
#define REM 0.2 // Means 'Reagent Effect Multiplier'. This is how many units of reagent are consumed per tick
|
||||
|
||||
#define CHEM_TOUCH 1
|
||||
#define CHEM_INGEST 2
|
||||
#define CHEM_BLOOD 3
|
||||
|
||||
#define MINIMUM_CHEMICAL_VOLUME 0.01
|
||||
|
||||
#define SOLID 1
|
||||
#define LIQUID 2
|
||||
#define GAS 3
|
||||
|
||||
#define REAGENTS_OVERDOSE 30
|
||||
|
||||
#define CHEM_SYNTH_ENERGY 500 // How much energy does it take to synthesize 1 unit of chemical, in Joules.
|
||||
|
||||
// Some on_mob_life() procs check for alien races.
|
||||
#define IS_DIONA 1
|
||||
#define IS_VOX 2
|
||||
#define IS_SKRELL 3
|
||||
#define IS_UNATHI 4
|
||||
#define IS_TAJARA 5
|
||||
#define IS_XENOS 6
|
||||
#define IS_MACHINE 7
|
||||
|
||||
#define CE_STABLE "stable" // Inaprovaline
|
||||
#define CE_ANTIBIOTIC "antibiotic" // Spaceacilin
|
||||
#define CE_BLOODRESTORE "bloodrestore" // Iron/nutriment
|
||||
#define CE_PAINKILLER "painkiller"
|
||||
#define CE_ALCOHOL "alcohol" // Liver filtering
|
||||
#define CE_ALCOHOL_TOXIC "alcotoxic" // Liver damage
|
||||
#define CE_SPEEDBOOST "gofast" // Hyperzine
|
||||
|
||||
// Chemistry lists.
|
||||
var/list/tachycardics = list("coffee", "inaprovaline", "hyperzine", "nitroglycerin", "thirteenloko", "nicotine") // Increase heart rate.
|
||||
var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_drugs", "stoxin") // Decrease heart rate.
|
||||
var/list/heartstopper = list("potassium_chlorophoride", "zombie_powder") // This stops the heart.
|
||||
var/list/cheartstopper = list("potassium_chloride") // This stops the heart when overdose is met. -- c = conditional
|
||||
53
code/__defines/damage_organs.dm
Normal file
53
code/__defines/damage_organs.dm
Normal file
@@ -0,0 +1,53 @@
|
||||
// Damage things. TODO: Merge these down to reduce on defines.
|
||||
// Way to waste perfectly good damage-type names (BRUTE) on this... If you were really worried about case sensitivity, you could have just used lowertext(damagetype) in the proc.
|
||||
#define BRUTE "brute"
|
||||
#define BURN "fire"
|
||||
#define TOX "tox"
|
||||
#define OXY "oxy"
|
||||
#define CLONE "clone"
|
||||
#define HALLOSS "halloss"
|
||||
|
||||
#define CUT "cut"
|
||||
#define BRUISE "bruise"
|
||||
|
||||
#define STUN "stun"
|
||||
#define WEAKEN "weaken"
|
||||
#define PARALYZE "paralize"
|
||||
#define IRRADIATE "irradiate"
|
||||
#define AGONY "agony" // Added in PAIN!
|
||||
#define SLUR "slur"
|
||||
#define STUTTER "stutter"
|
||||
#define EYE_BLUR "eye_blur"
|
||||
#define DROWSY "drowsy"
|
||||
#define INCINERATE "incinerate"
|
||||
|
||||
#define FIRE_DAMAGE_MODIFIER 0.0215 // Higher values result in more external fire damage to the skin. (default 0.0215)
|
||||
#define AIR_DAMAGE_MODIFIER 2.025 // More means less damage from hot air scalding lungs, less = more damage. (default 2.025)
|
||||
|
||||
// Organ defines.
|
||||
#define ORGAN_CUT_AWAY (1<<0)
|
||||
#define ORGAN_BLEEDING (1<<1)
|
||||
#define ORGAN_BROKEN (1<<2)
|
||||
#define ORGAN_DESTROYED (1<<3)
|
||||
#define ORGAN_ROBOT (1<<4)
|
||||
#define ORGAN_SPLINTED (1<<5)
|
||||
#define ORGAN_DEAD (1<<6)
|
||||
#define ORGAN_MUTATED (1<<7)
|
||||
#define ORGAN_ASSISTED (1<<8)
|
||||
#define ORGAN_ADV_ROBOT (1<<9)
|
||||
#define ORGAN_PLANT (1<<10)
|
||||
|
||||
#define DROPLIMB_EDGE 0
|
||||
#define DROPLIMB_BLUNT 1
|
||||
#define DROPLIMB_BURN 2
|
||||
|
||||
// Damage above this value must be repaired with surgery.
|
||||
#define ROBOLIMB_SELF_REPAIR_CAP 30
|
||||
|
||||
//Germs and infections.
|
||||
#define GERM_LEVEL_AMBIENT 110 // Maximum germ level you can reach by standing still.
|
||||
#define GERM_LEVEL_MOVE_CAP 200 // Maximum germ level you can reach by running around.
|
||||
|
||||
#define INFECTION_LEVEL_ONE 100
|
||||
#define INFECTION_LEVEL_TWO 500
|
||||
#define INFECTION_LEVEL_THREE 1000
|
||||
76
code/__defines/dna.dm
Normal file
76
code/__defines/dna.dm
Normal file
@@ -0,0 +1,76 @@
|
||||
// Bitflags for mutations.
|
||||
#define STRUCDNASIZE 27
|
||||
#define UNIDNASIZE 13
|
||||
|
||||
// Generic mutations:
|
||||
#define TK 1
|
||||
#define COLD_RESISTANCE 2
|
||||
#define XRAY 3
|
||||
#define HULK 4
|
||||
#define CLUMSY 5
|
||||
#define FAT 6
|
||||
#define HUSK 7
|
||||
#define NOCLONE 8
|
||||
#define LASER 9 // Harm intent - click anywhere to shoot lasers from eyes.
|
||||
#define HEAL 10 // Healing people with hands.
|
||||
|
||||
#define SKELETON 29
|
||||
#define PLANT 30
|
||||
|
||||
// Other Mutations:
|
||||
#define mNobreath 100 // No need to breathe.
|
||||
#define mRemote 101 // Remote viewing.
|
||||
#define mRegen 102 // Health regeneration.
|
||||
#define mRun 103 // No slowdown.
|
||||
#define mRemotetalk 104 // Remote talking.
|
||||
#define mMorph 105 // Hanging appearance.
|
||||
#define mBlend 106 // Nothing. (seriously nothing)
|
||||
#define mHallucination 107 // Hallucinations.
|
||||
#define mFingerprints 108 // No fingerprints.
|
||||
#define mShock 109 // Insulated hands.
|
||||
#define mSmallsize 110 // Table climbing.
|
||||
|
||||
// disabilities
|
||||
#define NEARSIGHTED 0x1
|
||||
#define EPILEPSY 0x2
|
||||
#define COUGHING 0x4
|
||||
#define TOURETTES 0x8
|
||||
#define NERVOUS 0x10
|
||||
|
||||
// sdisabilities
|
||||
#define BLIND 0x1
|
||||
#define MUTE 0x2
|
||||
#define DEAF 0x4
|
||||
|
||||
// The way blocks are handled badly needs a rewrite, this is horrible.
|
||||
// Too much of a project to handle at the moment, TODO for later.
|
||||
var/BLINDBLOCK = 0
|
||||
var/DEAFBLOCK = 0
|
||||
var/HULKBLOCK = 0
|
||||
var/TELEBLOCK = 0
|
||||
var/FIREBLOCK = 0
|
||||
var/XRAYBLOCK = 0
|
||||
var/CLUMSYBLOCK = 0
|
||||
var/FAKEBLOCK = 0
|
||||
var/COUGHBLOCK = 0
|
||||
var/GLASSESBLOCK = 0
|
||||
var/EPILEPSYBLOCK = 0
|
||||
var/TWITCHBLOCK = 0
|
||||
var/NERVOUSBLOCK = 0
|
||||
var/MONKEYBLOCK = STRUCDNASIZE
|
||||
|
||||
var/BLOCKADD = 0
|
||||
var/DIFFMUT = 0
|
||||
|
||||
var/HEADACHEBLOCK = 0
|
||||
var/NOBREATHBLOCK = 0
|
||||
var/REMOTEVIEWBLOCK = 0
|
||||
var/REGENERATEBLOCK = 0
|
||||
var/INCREASERUNBLOCK = 0
|
||||
var/REMOTETALKBLOCK = 0
|
||||
var/MORPHBLOCK = 0
|
||||
var/BLENDBLOCK = 0
|
||||
var/HALLUCINATIONBLOCK = 0
|
||||
var/NOPRINTSBLOCK = 0
|
||||
var/SHOCKIMMUNITYBLOCK = 0
|
||||
var/SMALLSIZEBLOCK = 0
|
||||
104
code/__defines/gamemode.dm
Normal file
104
code/__defines/gamemode.dm
Normal file
@@ -0,0 +1,104 @@
|
||||
#define GAME_STATE_PREGAME 1
|
||||
#define GAME_STATE_SETTING_UP 2
|
||||
#define GAME_STATE_PLAYING 3
|
||||
#define GAME_STATE_FINISHED 4
|
||||
|
||||
// Security levels.
|
||||
#define SEC_LEVEL_GREEN 0
|
||||
#define SEC_LEVEL_BLUE 1
|
||||
#define SEC_LEVEL_RED 2
|
||||
#define SEC_LEVEL_DELTA 3
|
||||
|
||||
#define BE_PLANT "BE_PLANT"
|
||||
#define BE_SYNTH "BE_SYNTH"
|
||||
#define BE_PAI "BE_PAI"
|
||||
|
||||
// Antagonist datum flags.
|
||||
#define ANTAG_OVERRIDE_JOB 0x1 // Assigned job is set to MODE when spawning.
|
||||
#define ANTAG_OVERRIDE_MOB 0x2 // Mob is recreated from datum mob_type var when spawning.
|
||||
#define ANTAG_CLEAR_EQUIPMENT 0x4 // All preexisting equipment is purged.
|
||||
#define ANTAG_CHOOSE_NAME 0x8 // Antagonists are prompted to enter a name.
|
||||
#define ANTAG_IMPLANT_IMMUNE 0x10 // Cannot be loyalty implanted.
|
||||
#define ANTAG_SUSPICIOUS 0x20 // Shows up on roundstart report.
|
||||
#define ANTAG_HAS_LEADER 0x40 // Generates a leader antagonist.
|
||||
#define ANTAG_HAS_NUKE 0x80 // Will spawn a nuke at supplied location.
|
||||
#define ANTAG_RANDSPAWN 0x100 // Potentially randomly spawns due to events.
|
||||
#define ANTAG_VOTABLE 0x200 // Can be voted as an additional antagonist before roundstart.
|
||||
#define ANTAG_SET_APPEARANCE 0x400 // Causes antagonists to use an appearance modifier on spawn.
|
||||
|
||||
// Mode/antag template macros.
|
||||
#define MODE_BORER "borer"
|
||||
#define MODE_XENOMORPH "xeno"
|
||||
#define MODE_LOYALIST "loyalist"
|
||||
#define MODE_MUTINEER "mutineer"
|
||||
#define MODE_COMMANDO "commando"
|
||||
#define MODE_DEATHSQUAD "deathsquad"
|
||||
#define MODE_ERT "ert"
|
||||
#define MODE_ACTOR "actor"
|
||||
#define MODE_MERCENARY "mercenary"
|
||||
#define MODE_NINJA "ninja"
|
||||
#define MODE_RAIDER "raider"
|
||||
#define MODE_WIZARD "wizard"
|
||||
#define MODE_CHANGELING "changeling"
|
||||
#define MODE_CULTIST "cultist"
|
||||
#define MODE_HIGHLANDER "highlander"
|
||||
#define MODE_MONKEY "monkey"
|
||||
#define MODE_RENEGADE "renegade"
|
||||
#define MODE_REVOLUTIONARY "revolutionary"
|
||||
#define MODE_LOYALIST "loyalist"
|
||||
#define MODE_MALFUNCTION "malf"
|
||||
#define MODE_TRAITOR "traitor"
|
||||
#define MODE_VAMPIRE "vampire"
|
||||
#define MODE_THRALL "thrall"
|
||||
|
||||
|
||||
#define DEFAULT_TELECRYSTAL_AMOUNT 25
|
||||
|
||||
/////////////////
|
||||
////WIZARD //////
|
||||
/////////////////
|
||||
|
||||
/* WIZARD SPELL FLAGS */
|
||||
#define GHOSTCAST 0x1 //can a ghost cast it?
|
||||
#define NEEDSCLOTHES 0x2 //does it need the wizard garb to cast? Nonwizard spells should not have this
|
||||
#define NEEDSHUMAN 0x4 //does it require the caster to be human?
|
||||
#define Z2NOCAST 0x8 //if this is added, the spell can't be cast at centcomm
|
||||
#define STATALLOWED 0x10 //if set, the user doesn't have to be conscious to cast. Required for ghost spells
|
||||
#define IGNOREPREV 0x20 //if set, each new target does not overlap with the previous one
|
||||
//The following flags only affect different types of spell, and therefore overlap
|
||||
//Targeted spells
|
||||
#define INCLUDEUSER 0x40 //does the spell include the caster in its target selection?
|
||||
#define SELECTABLE 0x80 //can you select each target for the spell?
|
||||
//AOE spells
|
||||
#define IGNOREDENSE 0x40 //are dense turfs ignored in selection?
|
||||
#define IGNORESPACE 0x80 //are space turfs ignored in selection?
|
||||
//End split flags
|
||||
#define CONSTRUCT_CHECK 0x100 //used by construct spells - checks for nullrods
|
||||
#define NO_BUTTON 0x200 //spell won't show up in the HUD with this
|
||||
|
||||
//invocation
|
||||
#define SpI_SHOUT "shout"
|
||||
#define SpI_WHISPER "whisper"
|
||||
#define SpI_EMOTE "emote"
|
||||
#define SpI_NONE "none"
|
||||
|
||||
//upgrading
|
||||
#define Sp_SPEED "speed"
|
||||
#define Sp_POWER "power"
|
||||
#define Sp_TOTAL "total"
|
||||
|
||||
//casting costs
|
||||
#define Sp_RECHARGE "recharge"
|
||||
#define Sp_CHARGES "charges"
|
||||
#define Sp_HOLDVAR "holdervar"
|
||||
|
||||
/////////////////
|
||||
//// Vampire ////
|
||||
/////////////////
|
||||
|
||||
#define VAMP_DRAINING 0x1
|
||||
#define VAMP_HEALING 0x2
|
||||
#define VAMP_PRESENCE 0x4
|
||||
#define VAMP_FRENZIED 0x8
|
||||
#define VAMP_ISTHRALL 0x10
|
||||
#define VAMP_FULLPOWER 0x20
|
||||
203
code/__defines/items_clothing.dm
Normal file
203
code/__defines/items_clothing.dm
Normal file
@@ -0,0 +1,203 @@
|
||||
#define HUMAN_STRIP_DELAY 40 // Takes 40ds = 4s to strip someone.
|
||||
|
||||
#define SHOES_SLOWDOWN -1.0 // How much shoes slow you down by default. Negative values speed you up.
|
||||
|
||||
#define CANDLE_LUM 3 // For how bright candles are.
|
||||
|
||||
// Item inventory slot bitmasks.
|
||||
#define SLOT_OCLOTHING 0x1
|
||||
#define SLOT_ICLOTHING 0x2
|
||||
#define SLOT_GLOVES 0x4
|
||||
#define SLOT_EYES 0x8
|
||||
#define SLOT_EARS 0x10
|
||||
#define SLOT_MASK 0x20
|
||||
#define SLOT_HEAD 0x40
|
||||
#define SLOT_FEET 0x80
|
||||
#define SLOT_ID 0x100
|
||||
#define SLOT_BELT 0x200
|
||||
#define SLOT_BACK 0x400
|
||||
#define SLOT_POCKET 0x800 // This is to allow items with a w_class of 3 or 4 to fit in pockets.
|
||||
#define SLOT_DENYPOCKET 0x1000 // This is to deny items with a w_class of 2 or 1 from fitting in pockets.
|
||||
#define SLOT_TWOEARS 0x2000
|
||||
#define SLOT_TIE 0x4000
|
||||
#define SLOT_HOLSTER 0x8000 //16th bit - higher than this will overflow
|
||||
|
||||
// Flags bitmasks.
|
||||
#define NOBLUDGEON 0x1 // When an item has this it produces no "X has been hit by Y with Z" message with the default handler.
|
||||
#define CONDUCT 0x2 // Conducts electricity. (metal etc.)
|
||||
#define ON_BORDER 0x4 // Item has priority to check when entering or leaving.
|
||||
#define NOBLOODY 0x8 // Used for items if they don't want to get a blood overlay.
|
||||
#define OPENCONTAINER 0x10 // Is an open container for chemistry purposes.
|
||||
#define PHORONGUARD 0x20 // Does not get contaminated by phoron.
|
||||
#define NOREACT 0x40 // Reagents don't react inside this container.
|
||||
#define PROXMOVE 0x80 // Does this object require proximity checking in Enter()?
|
||||
|
||||
//Flags for items (equipment)
|
||||
#define THICKMATERIAL 0x1 // Prevents syringes, parapens and hyposprays if equiped to slot_suit or slot_head.
|
||||
#define STOPPRESSUREDAMAGE 0x2 // Counts towards pressure protection. Note that like temperature protection, body_parts_covered is considered here as well.
|
||||
#define AIRTIGHT 0x4 // Functions with internals.
|
||||
#define NOSLIP 0x8 // Prevents from slipping on wet floors, in space, etc.
|
||||
#define BLOCK_GAS_SMOKE_EFFECT 0x10 // Blocks the effect that chemical clouds would have on a mob -- glasses, mask and helmets ONLY! (NOTE: flag shared with ONESIZEFITSALL)
|
||||
#define FLEXIBLEMATERIAL 0x20 // At the moment, masks with this flag will not prevent eating even if they are covering your face.
|
||||
|
||||
// Flags for pass_flags.
|
||||
#define PASSTABLE 0x1
|
||||
#define PASSGLASS 0x2
|
||||
#define PASSGRILLE 0x4
|
||||
#define PASSDOORHATCH 0x8
|
||||
|
||||
// Bitmasks for the flags_inv variable. These determine when a piece of clothing hides another, i.e. a helmet hiding glasses.
|
||||
// WARNING: The following flags apply only to the external suit!
|
||||
#define HIDEGLOVES 0x1
|
||||
#define HIDESUITSTORAGE 0x2
|
||||
#define HIDEJUMPSUIT 0x4
|
||||
#define HIDESHOES 0x8
|
||||
#define HIDETAIL 0x10
|
||||
|
||||
// WARNING: The following flags apply only to the helmets and masks!
|
||||
#define HIDEMASK 0x1
|
||||
#define HIDEEARS 0x2 // Headsets and such.
|
||||
#define HIDEEYES 0x4 // Glasses.
|
||||
#define HIDEFACE 0x8 // Dictates whether we appear as "Unknown".
|
||||
|
||||
#define BLOCKHEADHAIR 0x20 // Hides the user's hair overlay. Leaves facial hair.
|
||||
#define BLOCKHAIR 0x40 // Hides the user's hair, facial and otherwise.
|
||||
|
||||
//This flag applies to gloves, uniforms, shoes, masks, ear items, glasses
|
||||
#define ALWAYSDRAW 0x80//If set, this item is always rendered even if its slot is hidden by other clothing
|
||||
//Note that the item may still not be visible if its sprite is actually covered up.
|
||||
|
||||
// Slots.
|
||||
#define slot_back 1
|
||||
#define slot_wear_mask 2
|
||||
#define slot_handcuffed 3
|
||||
#define slot_l_hand 4
|
||||
#define slot_r_hand 5
|
||||
#define slot_belt 6
|
||||
#define slot_wear_id 7
|
||||
#define slot_l_ear 8
|
||||
#define slot_glasses 9
|
||||
#define slot_gloves 10
|
||||
#define slot_head 11
|
||||
#define slot_shoes 12
|
||||
#define slot_wear_suit 13
|
||||
#define slot_w_uniform 14
|
||||
#define slot_l_store 15
|
||||
#define slot_r_store 16
|
||||
#define slot_s_store 17
|
||||
#define slot_in_backpack 18
|
||||
#define slot_legcuffed 19
|
||||
#define slot_r_ear 20
|
||||
#define slot_legs 21
|
||||
#define slot_tie 22
|
||||
|
||||
// Inventory slot strings.
|
||||
// since numbers cannot be used as associative list keys.
|
||||
//icon_back, icon_l_hand, etc would be much better names for these...
|
||||
#define slot_back_str "slot_back"
|
||||
#define slot_l_hand_str "slot_l_hand"
|
||||
#define slot_r_hand_str "slot_r_hand"
|
||||
#define slot_w_uniform_str "slot_w_uniform"
|
||||
#define slot_head_str "slot_head"
|
||||
#define slot_wear_suit_str "slot_suit"
|
||||
|
||||
//itemstate suffixes. Used for containedsprite worn items
|
||||
#define WORN_LHAND "_lh"
|
||||
#define WORN_RHAND "_rh"
|
||||
#define WORN_LSTORE "_ls"
|
||||
#define WORN_RSTORE "_rs"
|
||||
#define WORN_SSTORE "_ss"
|
||||
#define WORN_LEAR "_le"
|
||||
#define WORN_REAR "_re"
|
||||
#define WORN_HEAD "_he"
|
||||
#define WORN_UNDER "_un"
|
||||
#define WORN_SUIT "_su"
|
||||
#define WORN_GLOVES "_gl"
|
||||
#define WORN_SHOES "_sh"
|
||||
#define WORN_EYES "_ey"
|
||||
#define WORN_BELT "_be"
|
||||
#define WORN_BACK "_ba"
|
||||
#define WORN_ID "_id"
|
||||
#define WORN_MASK "_ma"
|
||||
|
||||
// Bitflags for clothing parts.
|
||||
#define HEAD 0x1
|
||||
#define FACE 0x2
|
||||
#define EYES 0x4
|
||||
#define UPPER_TORSO 0x8
|
||||
#define LOWER_TORSO 0x10
|
||||
#define LEG_LEFT 0x20
|
||||
#define LEG_RIGHT 0x40
|
||||
#define LEGS 0x60 // LEG_LEFT | LEG_RIGHT
|
||||
#define FOOT_LEFT 0x80
|
||||
#define FOOT_RIGHT 0x100
|
||||
#define FEET 0x180 // FOOT_LEFT | FOOT_RIGHT
|
||||
#define ARM_LEFT 0x200
|
||||
#define ARM_RIGHT 0x400
|
||||
#define ARMS 0x600 // ARM_LEFT | ARM_RIGHT
|
||||
#define HAND_LEFT 0x800
|
||||
#define HAND_RIGHT 0x1000
|
||||
#define HANDS 0x1800 // HAND_LEFT | HAND_RIGHT
|
||||
#define FULL_BODY 0xFFFF
|
||||
|
||||
// Bitflags for the percentual amount of protection a piece of clothing which covers the body part offers.
|
||||
// Used with human/proc/get_heat_protection() and human/proc/get_cold_protection().
|
||||
// The values here should add up to 1, e.g., the head has 30% protection.
|
||||
#define THERMAL_PROTECTION_HEAD 0.3
|
||||
#define THERMAL_PROTECTION_UPPER_TORSO 0.15
|
||||
#define THERMAL_PROTECTION_LOWER_TORSO 0.15
|
||||
#define THERMAL_PROTECTION_LEG_LEFT 0.075
|
||||
#define THERMAL_PROTECTION_LEG_RIGHT 0.075
|
||||
#define THERMAL_PROTECTION_FOOT_LEFT 0.025
|
||||
#define THERMAL_PROTECTION_FOOT_RIGHT 0.025
|
||||
#define THERMAL_PROTECTION_ARM_LEFT 0.075
|
||||
#define THERMAL_PROTECTION_ARM_RIGHT 0.075
|
||||
#define THERMAL_PROTECTION_HAND_LEFT 0.025
|
||||
#define THERMAL_PROTECTION_HAND_RIGHT 0.025
|
||||
|
||||
// Pressure limits.
|
||||
#define HAZARD_HIGH_PRESSURE 550 // This determines at what pressure the ultra-high pressure red icon is displayed. (This one is set as a constant)
|
||||
#define WARNING_HIGH_PRESSURE 325 // This determines when the orange pressure icon is displayed (it is 0.7 * HAZARD_HIGH_PRESSURE)
|
||||
#define WARNING_LOW_PRESSURE 50 // This is when the gray low pressure icon is displayed. (it is 2.5 * HAZARD_LOW_PRESSURE)
|
||||
#define HAZARD_LOW_PRESSURE 20 // This is when the black ultra-low pressure icon is displayed. (This one is set as a constant)
|
||||
|
||||
#define TEMPERATURE_DAMAGE_COEFFICIENT 1.5 // This is used in handle_temperature_damage() for humans, and in reagents that affect body temperature. Temperature damage is multiplied by this amount.
|
||||
#define BODYTEMP_AUTORECOVERY_DIVISOR 12 // This is the divisor which handles how much of the temperature difference between the current body temperature and 310.15K (optimal temperature) humans auto-regenerate each tick. The higher the number, the slower the recovery. This is applied each tick, so long as the mob is alive.
|
||||
#define BODYTEMP_AUTORECOVERY_MINIMUM 1 // Minimum amount of kelvin moved toward 310.15K per tick. So long as abs(310.15 - bodytemp) is more than 50.
|
||||
#define BODYTEMP_COLD_DIVISOR 6 // Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is lower than their body temperature. Make it lower to lose bodytemp faster.
|
||||
#define BODYTEMP_HEAT_DIVISOR 6 // Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is higher than their body temperature. Make it lower to gain bodytemp faster.
|
||||
#define BODYTEMP_COOLING_MAX -30 // The maximum number of degrees that your body can cool down in 1 tick, when in a cold area.
|
||||
#define BODYTEMP_HEATING_MAX 30 // The maximum number of degrees that your body can heat up in 1 tick, when in a hot area.
|
||||
|
||||
#define BODYTEMP_HEAT_DAMAGE_LIMIT 360.15 // The limit the human body can take before it starts taking damage from heat.
|
||||
#define BODYTEMP_COLD_DAMAGE_LIMIT 260.15 // The limit the human body can take before it starts taking damage from coldness.
|
||||
|
||||
#define SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE 2.0 // What min_cold_protection_temperature is set to for space-helmet quality headwear. MUST NOT BE 0.
|
||||
#define SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE 2.0 // What min_cold_protection_temperature is set to for space-suit quality jumpsuits or suits. MUST NOT BE 0.
|
||||
#define HELMET_MIN_COLD_PROTECTION_TEMPERATURE 160 // For normal helmets.
|
||||
#define ARMOR_MIN_COLD_PROTECTION_TEMPERATURE 160 // For armor.
|
||||
#define GLOVES_MIN_COLD_PROTECTION_TEMPERATURE 2.0 // For some gloves.
|
||||
#define SHOE_MIN_COLD_PROTECTION_TEMPERATURE 2.0 // For shoes.
|
||||
|
||||
#define SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE 5000 // These need better heat protect, but not as good heat protect as firesuits.
|
||||
#define FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE 30000 // What max_heat_protection_temperature is set to for firesuit quality headwear. MUST NOT BE 0.
|
||||
#define FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE 30000 // For fire-helmet quality items. (Red and white hardhats)
|
||||
#define HELMET_MAX_HEAT_PROTECTION_TEMPERATURE 600 // For normal helmets.
|
||||
#define ARMOR_MAX_HEAT_PROTECTION_TEMPERATURE 600 // For armor.
|
||||
#define GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE 1500 // For some gloves.
|
||||
#define SHOE_MAX_HEAT_PROTECTION_TEMPERATURE 1500 // For shoes.
|
||||
|
||||
// Fire.
|
||||
#define FIRE_MIN_STACKS -20
|
||||
#define FIRE_MAX_STACKS 25
|
||||
#define FIRE_MAX_FIRESUIT_STACKS 20 // If the number of stacks goes above this firesuits won't protect you anymore. If not, you can walk around while on fire like a badass.
|
||||
|
||||
#define THROWFORCE_SPEED_DIVISOR 5 // The throwing speed value at which the throwforce multiplier is exactly 1.
|
||||
#define THROWNOBJ_KNOCKBACK_SPEED 15 // The minumum speed of a w_class 2 thrown object that will cause living mobs it hits to be knocked back. Heavier objects can cause knockback at lower speeds.
|
||||
#define THROWNOBJ_KNOCKBACK_DIVISOR 2 // Affects how much speed the mob is knocked back with.
|
||||
|
||||
// Suit sensor levels
|
||||
#define SUIT_SENSOR_OFF 0
|
||||
#define SUIT_SENSOR_BINARY 1
|
||||
#define SUIT_SENSOR_VITAL 2
|
||||
#define SUIT_SENSOR_TRACKING 3
|
||||
34
code/__defines/lighting.dm
Normal file
34
code/__defines/lighting.dm
Normal file
@@ -0,0 +1,34 @@
|
||||
//DVIEW defines
|
||||
//DVIEW is a hack that uses a mob with darksight in order to find lists of viewable stuff while ignoring darkness
|
||||
|
||||
var/mob/dview/dview_mob = new
|
||||
|
||||
/mob/dview
|
||||
invisibility = 101
|
||||
density = 0
|
||||
|
||||
anchored = 1
|
||||
simulated = 0
|
||||
|
||||
see_in_dark = 1e6
|
||||
|
||||
#define FOR_DVIEW(type, range, center, invis_flags) \
|
||||
dview_mob.loc = center; \
|
||||
dview_mob.see_invisible = invis_flags; \
|
||||
for(type in view(range, dview_mob))
|
||||
|
||||
#define END_FOR_DVIEW dview_mob.loc = null
|
||||
|
||||
#define DVIEW(output, range, center, invis_flags) \
|
||||
dview_mob.loc = center; \
|
||||
dview_mob.see_invisible = invis_flags; \
|
||||
output = view(range, dview_mob); \
|
||||
dview_mob.loc = null ;
|
||||
|
||||
|
||||
|
||||
|
||||
// Night lighting controller times
|
||||
// The time (in ticks based on worldtime2ticks()) that various actions trigger
|
||||
#define MORNING_LIGHT_RESET 252000 // 7am or 07:00 - lighting restores to normal in morning
|
||||
#define NIGHT_LIGHT_ACTIVE 648000 // 6pm or 18:00 - night lighting mode activates
|
||||
98
code/__defines/machinery.dm
Normal file
98
code/__defines/machinery.dm
Normal file
@@ -0,0 +1,98 @@
|
||||
#define KILOWATTS *1000
|
||||
#define MEGAWATTS *1000000
|
||||
#define GIGAWATTS *1000000000
|
||||
|
||||
#define CELLRATE 0.002 // Multiplier for watts per tick <> cell storage (e.g., 0.02 means if there is a load of 1000 watts, 20 units will be taken from a cell per second)
|
||||
// It's a conversion constant. power_used*CELLRATE = charge_provided, or charge_used/CELLRATE = power_provided
|
||||
|
||||
// Doors!
|
||||
#define DOOR_CRUSH_DAMAGE 20
|
||||
#define ALIEN_SELECT_AFK_BUFFER 1 // How many minutes that a person can be AFK before not being allowed to be an alien.
|
||||
|
||||
// Channel numbers for power.
|
||||
#define EQUIP 1
|
||||
#define LIGHT 2
|
||||
#define ENVIRON 3
|
||||
#define TOTAL 4 // For total power used only.
|
||||
|
||||
// Bitflags for machine stat variable.
|
||||
#define BROKEN 0x1
|
||||
#define NOPOWER 0x2
|
||||
#define POWEROFF 0x4 // TBD.
|
||||
#define MAINT 0x8 // Under maintenance.
|
||||
#define EMPED 0x10 // Temporary broken by EMP pulse.
|
||||
|
||||
// Used by firelocks
|
||||
#define FIREDOOR_OPEN 1
|
||||
#define FIREDOOR_CLOSED 2
|
||||
|
||||
#define AI_CAMERA_LUMINOSITY 6
|
||||
|
||||
// Camera networks
|
||||
#define NETWORK_CRESCENT "Crescent"
|
||||
#define NETWORK_CIVILIAN_EAST "Civilian East"
|
||||
#define NETWORK_CIVILIAN_WEST "Civilian West"
|
||||
#define NETWORK_COMMAND "Command"
|
||||
#define NETWORK_ENGINE "Engine"
|
||||
#define NETWORK_ENGINEERING "Engineering"
|
||||
#define NETWORK_ENGINEERING_OUTPOST "Engineering Outpost"
|
||||
#define NETWORK_ERT "ZeEmergencyResponseTeam"
|
||||
#define NETWORK_EXODUS "Exodus"
|
||||
#define NETWORK_MEDICAL "Medical"
|
||||
#define NETWORK_MERCENARY "MercurialNet"
|
||||
#define NETWORK_MINE "MINE"
|
||||
#define NETWORK_RESEARCH "Research"
|
||||
#define NETWORK_RESEARCH_OUTPOST "Research Outpost"
|
||||
#define NETWORK_ROBOTS "Robots"
|
||||
#define NETWORK_PRISON "Prison"
|
||||
#define NETWORK_SECURITY "Security"
|
||||
#define NETWORK_TELECOM "Tcomsat"
|
||||
#define NETWORK_THUNDER "Thunderdome"
|
||||
#define NETWORK_ALARM_ATMOS "Atmosphere Alarms"
|
||||
#define NETWORK_ALARM_POWER "Power Alarms"
|
||||
#define NETWORK_ALARM_FIRE "Fire Alarms"
|
||||
#define NETWORK_SUPPLY "Supply"
|
||||
#define NETWORK_EXPEDITION "Expedition"
|
||||
#define NETWORK_CALYPSO "Calypso"
|
||||
#define NETWORK_POD "General Utility Pod"
|
||||
|
||||
// Those networks can only be accessed by pre-existing terminals. AIs and new terminals can't use them.
|
||||
var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret")
|
||||
|
||||
|
||||
//singularity defines
|
||||
#define STAGE_ONE 1
|
||||
#define STAGE_TWO 3
|
||||
#define STAGE_THREE 5
|
||||
#define STAGE_FOUR 7
|
||||
#define STAGE_FIVE 9
|
||||
#define STAGE_SUPER 11
|
||||
|
||||
// NanoUI flags
|
||||
#define STATUS_INTERACTIVE 2 // GREEN Visability
|
||||
#define STATUS_UPDATE 1 // ORANGE Visability
|
||||
#define STATUS_DISABLED 0 // RED Visability
|
||||
#define STATUS_CLOSE -1 // Close the interface
|
||||
|
||||
/*
|
||||
* Atmospherics Machinery.
|
||||
*/
|
||||
#define MAX_SIPHON_FLOWRATE 2500 // L/s. This can be used to balance how fast a room is siphoned. Anything higher than CELL_VOLUME has no effect.
|
||||
#define MAX_SCRUBBER_FLOWRATE 200 // L/s. Max flow rate when scrubbing from a turf.
|
||||
|
||||
// These balance how easy or hard it is to create huge pressure gradients with pumps and filters.
|
||||
// Lower values means it takes longer to create large pressures differences.
|
||||
// Has no effect on pumping gasses from high pressure to low, only from low to high.
|
||||
#define ATMOS_PUMP_EFFICIENCY 2.5
|
||||
#define ATMOS_FILTER_EFFICIENCY 2.5
|
||||
|
||||
// Will not bother pumping or filtering if the gas source as fewer than this amount of moles, to help with performance.
|
||||
#define MINIMUM_MOLES_TO_PUMP 0.01
|
||||
#define MINIMUM_MOLES_TO_FILTER 0.04
|
||||
|
||||
// The flow rate/effectiveness of various atmos devices is limited by their internal volume,
|
||||
// so for many atmos devices these will control maximum flow rates in L/s.
|
||||
#define ATMOS_DEFAULT_VOLUME_PUMP 200 // Liters.
|
||||
#define ATMOS_DEFAULT_VOLUME_FILTER 200 // L.
|
||||
#define ATMOS_DEFAULT_VOLUME_MIXER 200 // L.
|
||||
#define ATMOS_DEFAULT_VOLUME_PIPE 70 // L.
|
||||
28
code/__defines/math_physics.dm
Normal file
28
code/__defines/math_physics.dm
Normal file
@@ -0,0 +1,28 @@
|
||||
// Math constants.
|
||||
#define M_PI 3.14159265
|
||||
|
||||
#define R_IDEAL_GAS_EQUATION 8.31 // kPa*L/(K*mol).
|
||||
#define ONE_ATMOSPHERE 101.325 // kPa.
|
||||
#define IDEAL_GAS_ENTROPY_CONSTANT 1164 // (mol^3 * s^3) / (kg^3 * L).
|
||||
|
||||
// Radiation constants.
|
||||
#define STEFAN_BOLTZMANN_CONSTANT 5.6704e-8 // W/(m^2*K^4).
|
||||
#define COSMIC_RADIATION_TEMPERATURE 3.15 // K.
|
||||
#define AVERAGE_SOLAR_RADIATION 200 // W/m^2. Kind of arbitrary. Really this should depend on the sun position much like solars.
|
||||
#define RADIATOR_OPTIMUM_PRESSURE 3771 // kPa at 20 C. This should be higher as gases aren't great conductors until they are dense. Used the critical pressure for air.
|
||||
#define GAS_CRITICAL_TEMPERATURE 132.65 // K. The critical point temperature for air.
|
||||
|
||||
#define RADIATOR_EXPOSED_SURFACE_AREA_RATIO 0.04 // (3 cm + 100 cm * sin(3deg))/(2*(3+100 cm)). Unitless ratio.
|
||||
#define HUMAN_EXPOSED_SURFACE_AREA 5.2 //m^2, surface area of 1.7m (H) x 0.46m (D) cylinder
|
||||
|
||||
#define T0C 273.15 // 0.0 degrees celcius
|
||||
#define T20C 293.15 // 20.0 degrees celcius
|
||||
#define TCMB 2.7 // -270.3 degrees celcius
|
||||
|
||||
#define CLAMP01(x) max(0, min(1, x))
|
||||
#define QUANTIZE(variable) (round(variable,0.0001))
|
||||
|
||||
#define INFINITY 1.#INF
|
||||
|
||||
#define TICKS_IN_DAY 24*60*60*10
|
||||
#define TICKS_IN_SECOND 10
|
||||
263
code/__defines/misc.dm
Normal file
263
code/__defines/misc.dm
Normal file
@@ -0,0 +1,263 @@
|
||||
#define DEBUG
|
||||
// Turf-only flags.
|
||||
#define NOJAUNT 1 // This is used in literally one place, turf.dm, to block ethereal jaunt.
|
||||
|
||||
#define TRANSITIONEDGE 7 // Distance from edge to move to another z-level.
|
||||
|
||||
// Invisibility constants.
|
||||
#define INVISIBILITY_LIGHTING 20
|
||||
#define INVISIBILITY_LEVEL_ONE 35
|
||||
#define INVISIBILITY_LEVEL_TWO 45
|
||||
#define INVISIBILITY_OBSERVER 60
|
||||
#define INVISIBILITY_EYE 61
|
||||
|
||||
#define SEE_INVISIBLE_LIVING 25
|
||||
#define SEE_INVISIBLE_NOLIGHTING 15
|
||||
#define SEE_INVISIBLE_LEVEL_ONE 35
|
||||
#define SEE_INVISIBLE_LEVEL_TWO 45
|
||||
#define SEE_INVISIBLE_CULT 60
|
||||
#define SEE_INVISIBLE_OBSERVER 61
|
||||
|
||||
#define SEE_INVISIBLE_MINIMUM 5
|
||||
#define INVISIBILITY_MAXIMUM 100
|
||||
|
||||
// Some arbitrary defines to be used by self-pruning global lists. (see master_controller)
|
||||
#define PROCESS_KILL 26 // Used to trigger removal from a processing list.
|
||||
|
||||
// Age limits on a character.
|
||||
#define AGE_MIN 17
|
||||
#define AGE_MAX 85
|
||||
|
||||
#define MAX_GEAR_COST 5 // Used in chargen for accessory loadout limit.
|
||||
|
||||
// Preference toggles.
|
||||
#define SOUND_ADMINHELP 0x1
|
||||
#define SOUND_MIDI 0x2
|
||||
#define SOUND_AMBIENCE 0x4
|
||||
#define SOUND_LOBBY 0x8
|
||||
#define CHAT_OOC 0x10
|
||||
#define CHAT_DEAD 0x20
|
||||
#define CHAT_GHOSTEARS 0x40
|
||||
#define CHAT_GHOSTSIGHT 0x80
|
||||
#define CHAT_PRAYER 0x100
|
||||
#define CHAT_RADIO 0x200
|
||||
#define CHAT_ATTACKLOGS 0x400
|
||||
#define CHAT_DEBUGLOGS 0x800
|
||||
#define CHAT_LOOC 0x1000
|
||||
#define CHAT_GHOSTRADIO 0x2000
|
||||
#define SHOW_TYPING 0x4000
|
||||
#define CHAT_NOICONS 0x8000
|
||||
|
||||
#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_ATTACKLOGS|CHAT_LOOC)
|
||||
|
||||
//Sound effects toggles
|
||||
#define ASFX_AMBIENCE 1
|
||||
#define ASFX_FOOTSTEPS 2
|
||||
#define ASFX_VOTE 4
|
||||
|
||||
#define ASFX_DEFAULT (ASFX_AMBIENCE|ASFX_FOOTSTEPS|ASFX_VOTE)
|
||||
|
||||
// For secHUDs and medHUDs and variants. The number is the location of the image on the list hud_list of humans.
|
||||
#define HEALTH_HUD 1 // A simple line rounding the mob's number health.
|
||||
#define STATUS_HUD 2 // Alive, dead, diseased, etc.
|
||||
#define ID_HUD 3 // The job asigned to your ID.
|
||||
#define WANTED_HUD 4 // Wanted, released, paroled, security status.
|
||||
#define IMPLOYAL_HUD 5 // Loyality implant.
|
||||
#define IMPCHEM_HUD 6 // Chemical implant.
|
||||
#define IMPTRACK_HUD 7 // Tracking implant.
|
||||
#define SPECIALROLE_HUD 8 // AntagHUD image.
|
||||
#define STATUS_HUD_OOC 9 // STATUS_HUD without virus DB check for someone being ill.
|
||||
#define LIFE_HUD 10 // STATUS_HUD that only reports dead or alive
|
||||
|
||||
//some colors
|
||||
#define COLOR_WHITE "#ffffff"
|
||||
#define COLOR_SILVER "#c0c0c0"
|
||||
#define COLOR_GRAY "#808080"
|
||||
#define COLOR_BLACK "#000000"
|
||||
#define COLOR_RED "#ff0000"
|
||||
#define COLOR_RED_LIGHT "#ff3333"
|
||||
#define COLOR_MAROON "#800000"
|
||||
#define COLOR_YELLOW "#ffff00"
|
||||
#define COLOR_OLIVE "#808000"
|
||||
#define COLOR_LIME "#00ff00"
|
||||
#define COLOR_GREEN "#008000"
|
||||
#define COLOR_CYAN "#00ffff"
|
||||
#define COLOR_TEAL "#008080"
|
||||
#define COLOR_BLUE "#0000ff"
|
||||
#define COLOR_BLUE_LIGHT "#33ccff"
|
||||
#define COLOR_NAVY "#000080"
|
||||
#define COLOR_PINK "#ff00ff"
|
||||
#define COLOR_PURPLE "#800080"
|
||||
#define COLOR_ORANGE "#ff9900"
|
||||
#define COLOR_LUMINOL "#66ffff"
|
||||
#define COLOR_BEIGE "#ceb689"
|
||||
#define COLOR_BLUE_GRAY "#6a97b0"
|
||||
#define COLOR_BROWN "#b19664"
|
||||
#define COLOR_DARK_BROWN "#917448"
|
||||
#define COLOR_DARK_ORANGE "#b95a00"
|
||||
#define COLOR_GREEN_GRAY "#8daf6a"
|
||||
#define COLOR_RED_GRAY "#aa5f61"
|
||||
#define COLOR_PALE_BLUE_GRAY "#8bbbd5"
|
||||
#define COLOR_PALE_GREEN_GRAY "#aed18b"
|
||||
#define COLOR_PALE_RED_GRAY "#cc9090"
|
||||
#define COLOR_PALE_PURPLE_GRAY "#bda2ba"
|
||||
#define COLOR_PURPLE_GRAY "#a2819e"
|
||||
#define COLOR_SUN "#ec8b2f"
|
||||
|
||||
// Shuttles.
|
||||
|
||||
// These define the time taken for the shuttle to get to the space station, and the time before it leaves again.
|
||||
#define SHUTTLE_PREPTIME 300 // 5 minutes = 300 seconds - after this time, the shuttle departs centcom and cannot be recalled.
|
||||
#define SHUTTLE_LEAVETIME 180 // 3 minutes = 180 seconds - the duration for which the shuttle will wait at the station after arriving.
|
||||
#define SHUTTLE_TRANSIT_DURATION 300 // 5 minutes = 300 seconds - how long it takes for the shuttle to get to the station.
|
||||
#define SHUTTLE_TRANSIT_DURATION_RETURN 120 // 2 minutes = 120 seconds - for some reason it takes less time to come back, go figure.
|
||||
|
||||
// Shuttle moving status.
|
||||
#define SHUTTLE_IDLE 0
|
||||
#define SHUTTLE_WARMUP 1
|
||||
#define SHUTTLE_INTRANSIT 2
|
||||
|
||||
// Ferry shuttle processing status.
|
||||
#define IDLE_STATE 0
|
||||
#define WAIT_LAUNCH 1
|
||||
#define FORCE_LAUNCH 2
|
||||
#define WAIT_ARRIVE 3
|
||||
#define WAIT_FINISH 4
|
||||
|
||||
// Setting this much higher than 1024 could allow spammers to DOS the server easily.
|
||||
#define MAX_MESSAGE_LEN 1024
|
||||
#define MAX_PAPER_MESSAGE_LEN 3072
|
||||
#define MAX_BOOK_MESSAGE_LEN 9216
|
||||
#define MAX_LNAME_LEN 64
|
||||
#define MAX_NAME_LEN 26
|
||||
|
||||
// Event defines.
|
||||
#define EVENT_LEVEL_MUNDANE 1
|
||||
#define EVENT_LEVEL_MODERATE 2
|
||||
#define EVENT_LEVEL_MAJOR 3
|
||||
|
||||
//General-purpose life speed define for plants.
|
||||
#define HYDRO_SPEED_MULTIPLIER 1
|
||||
|
||||
#define DEFAULT_JOB_TYPE /datum/job/assistant
|
||||
|
||||
//Area flags, possibly more to come
|
||||
#define RAD_SHIELDED 1 //shielded from radiation, clearly
|
||||
|
||||
// Custom layer definitions, supplementing the default TURF_LAYER, MOB_LAYER, etc.
|
||||
#define DOOR_OPEN_LAYER 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6
|
||||
#define DOOR_CLOSED_LAYER 3.1 //Above most items if closed
|
||||
#define LIGHTING_LAYER 11
|
||||
#define HUD_LAYER 20 //Above lighting, but below obfuscation. For in-game HUD effects (whereas SCREEN_LAYER is for abstract/OOC things like inventory slots)
|
||||
#define OBFUSCATION_LAYER 21 //Where images covering the view for eyes are put
|
||||
#define SCREEN_LAYER 22 //Mob HUD/effects layer
|
||||
#define UNDERDOOR 3.09 //Just barely under a closed door.
|
||||
|
||||
// Convoluted setup so defines can be supplied by Bay12 main server compile script.
|
||||
// Should still work fine for people jamming the icons into their repo.
|
||||
#ifndef CUSTOM_ITEM_OBJ
|
||||
#define CUSTOM_ITEM_OBJ 'icons/obj/custom_items_obj.dmi'
|
||||
#endif
|
||||
#ifndef CUSTOM_ITEM_MOB
|
||||
#define CUSTOM_ITEM_MOB 'icons/mob/custom_items_mob.dmi'
|
||||
#endif
|
||||
#ifndef CUSTOM_ITEM_SYNTH
|
||||
#define CUSTOM_ITEM_SYNTH 'icons/mob/custom_synthetic.dmi'
|
||||
#endif
|
||||
|
||||
#define WALL_CAN_OPEN 1
|
||||
#define WALL_OPENING 2
|
||||
|
||||
#define DEFAULT_TABLE_MATERIAL "plastic"
|
||||
#define DEFAULT_WALL_MATERIAL "steel"
|
||||
|
||||
#define SHARD_SHARD "shard"
|
||||
#define SHARD_SHRAPNEL "shrapnel"
|
||||
#define SHARD_STONE_PIECE "piece"
|
||||
#define SHARD_SPLINTER "splinters"
|
||||
#define SHARD_NONE ""
|
||||
|
||||
#define MATERIAL_UNMELTABLE 0x1
|
||||
#define MATERIAL_BRITTLE 0x2
|
||||
#define MATERIAL_PADDING 0x4
|
||||
|
||||
#define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4 // Amount table damage is multiplied by if it is made of a brittle material (e.g. glass)
|
||||
|
||||
#define BOMBCAP_DVSTN_RADIUS (max_explosion_range/4)
|
||||
#define BOMBCAP_HEAVY_RADIUS (max_explosion_range/2)
|
||||
#define BOMBCAP_LIGHT_RADIUS max_explosion_range
|
||||
#define BOMBCAP_FLASH_RADIUS (max_explosion_range*1.5)
|
||||
// NTNet module-configuration values. Do not change these. If you need to add another use larger number (5..6..7 etc)
|
||||
#define NTNET_SOFTWAREDOWNLOAD 1 // Downloads of software from NTNet
|
||||
#define NTNET_PEERTOPEER 2 // P2P transfers of files between devices
|
||||
#define NTNET_COMMUNICATION 3 // Communication (messaging)
|
||||
#define NTNET_SYSTEMCONTROL 4 // Control of various systems, RCon, air alarm control, etc.
|
||||
|
||||
// NTNet transfer speeds, used when downloading/uploading a file/program.
|
||||
#define NTNETSPEED_LOWSIGNAL 0.05 // GQ/s transfer speed when the device is wirelessly connected and on Low signal
|
||||
#define NTNETSPEED_HIGHSIGNAL 0.25 // GQ/s transfer speed when the device is wirelessly connected and on High signal
|
||||
#define NTNETSPEED_ETHERNET 1 // GQ/s transfer speed when the device is using wired connection
|
||||
#define NTNETSPEED_DOS_AMPLIFICATION 5 // Multiplier for Denial of Service program. Resulting load on NTNet relay is this multiplied by NTNETSPEED of the device
|
||||
|
||||
// Program bitflags
|
||||
#define PROGRAM_ALL 15
|
||||
#define PROGRAM_CONSOLE 1
|
||||
#define PROGRAM_LAPTOP 2
|
||||
#define PROGRAM_TABLET 4
|
||||
#define PROGRAM_TELESCREEN 8
|
||||
|
||||
#define PROGRAM_STATE_KILLED 0
|
||||
#define PROGRAM_STATE_BACKGROUND 1
|
||||
#define PROGRAM_STATE_ACTIVE 2
|
||||
|
||||
// Caps for NTNet logging. Less than 10 would make logging useless anyway, more than 500 may make the log browser too laggy. Defaults to 100 unless user changes it.
|
||||
#define MAX_NTNET_LOGS 500
|
||||
#define MIN_NTNET_LOGS 10
|
||||
|
||||
#define PROGRAM_ACCESS_ONE 1
|
||||
#define PROGRAM_ACCESS_LIST_ONE 2
|
||||
#define PROGRAM_ACCESS_LIST_ALL 3
|
||||
|
||||
// Special return values from bullet_act(). Positive return values are already used to indicate the blocked level of the projectile.
|
||||
#define PROJECTILE_CONTINUE -1 //if the projectile should continue flying after calling bullet_act()
|
||||
#define PROJECTILE_FORCE_MISS -2 //if the projectile should treat the attack as a miss (suppresses attack and admin logs) - only applies to mobs.
|
||||
|
||||
//Camera capture modes
|
||||
#define CAPTURE_MODE_REGULAR 0 //Regular polaroid camera mode
|
||||
#define CAPTURE_MODE_ALL 1 //Admin camera mode
|
||||
#define CAPTURE_MODE_PARTIAL 3 //Simular to regular mode, but does not do dummy check
|
||||
|
||||
//Sound effects toggles
|
||||
#define ASFX_AMBIENCE 1
|
||||
#define ASFX_FOOTSTEPS 2
|
||||
#define ASFX_VOTE 4
|
||||
|
||||
//Cargo random stock vars
|
||||
//These are used in randomstock.dm
|
||||
//And also for generating random loot crates in crates.dm
|
||||
#define TOTAL_STOCK 80//The total number of items we'll spawn in cargo stock
|
||||
|
||||
|
||||
#define STOCK_UNCOMMON_PROB 23
|
||||
//The probability, as a percentage for each item, that we'll choose from the uncommon spawns list
|
||||
|
||||
#define STOCK_RARE_PROB 2.8
|
||||
//The probability, as a percentage for each item, that we'll choose from the rare spawns list
|
||||
|
||||
//If an item is not rare or uncommon, it will be chosen from the common spawns list.
|
||||
//So the probability of a common item is 100 - (uncommon + rare)
|
||||
|
||||
|
||||
#define STOCK_LARGE_PROB 75
|
||||
//Large items are spawned on predetermined locations.
|
||||
//For each large spawn marker, this is the chance that we will spawn there
|
||||
|
||||
|
||||
// Law settings
|
||||
#define PERMABRIG_SENTENCE 90 // Measured in minutes
|
||||
//#define PERMAPRISON_SENTENCE 60 // Measured in IC days
|
||||
#define FELONY_LEVEL 2.0 // What is the minimum law severity that counts as a felony?
|
||||
|
||||
#define LAYER_TABLE 2.8
|
||||
#define LAYER_UNDER_TABLE 2.79
|
||||
#define LAYER_ABOVE_TABLE 2.81
|
||||
182
code/__defines/mobs.dm
Normal file
182
code/__defines/mobs.dm
Normal file
@@ -0,0 +1,182 @@
|
||||
// /mob/var/stat things.
|
||||
#define CONSCIOUS 0
|
||||
#define UNCONSCIOUS 1
|
||||
#define DEAD 2
|
||||
|
||||
// Bitflags defining which status effects could be or are inflicted on a mob.
|
||||
#define CANSTUN 0x1
|
||||
#define CANWEAKEN 0x2
|
||||
#define CANPARALYSE 0x4
|
||||
#define CANPUSH 0x8
|
||||
#define LEAPING 0x10
|
||||
#define PASSEMOTES 0x32 // Mob has a cortical borer or holders inside of it that need to see emotes.
|
||||
#define GODMODE 0x1000
|
||||
#define FAKEDEATH 0x2000 // Replaces stuff like changeling.changeling_fakedeath.
|
||||
#define DISFIGURED 0x4000 // Set but never checked. Remove this sometime and replace occurences with the appropriate organ code
|
||||
#define XENO_HOST 0x8000 // Tracks whether we're gonna be a baby alien's mummy.
|
||||
|
||||
// Grab levels.
|
||||
#define GRAB_PASSIVE 1
|
||||
#define GRAB_AGGRESSIVE 2
|
||||
#define GRAB_NECK 3
|
||||
#define GRAB_UPGRADING 4
|
||||
#define GRAB_KILL 5
|
||||
|
||||
#define BORGMESON 0x1
|
||||
#define BORGTHERM 0x2
|
||||
#define BORGXRAY 0x4
|
||||
#define BORGMATERIAL 8
|
||||
|
||||
#define HOSTILE_STANCE_IDLE 1
|
||||
#define HOSTILE_STANCE_ALERT 2
|
||||
#define HOSTILE_STANCE_ATTACK 3
|
||||
#define HOSTILE_STANCE_ATTACKING 4
|
||||
#define HOSTILE_STANCE_TIRED 5
|
||||
|
||||
#define LEFT 1
|
||||
#define RIGHT 2
|
||||
|
||||
// Pulse levels, very simplified.
|
||||
#define PULSE_NONE 0 // So !M.pulse checks would be possible.
|
||||
#define PULSE_SLOW 1 // <60 bpm
|
||||
#define PULSE_NORM 2 // 60-90 bpm
|
||||
#define PULSE_FAST 3 // 90-120 bpm
|
||||
#define PULSE_2FAST 4 // >120 bpm
|
||||
#define PULSE_THREADY 5 // Occurs during hypovolemic shock
|
||||
#define GETPULSE_HAND 0 // Less accurate. (hand)
|
||||
#define GETPULSE_TOOL 1 // More accurate. (med scanner, sleeper, etc.)
|
||||
|
||||
//intent flags, why wasn't this done the first time?
|
||||
#define I_HELP "help"
|
||||
#define I_DISARM "disarm"
|
||||
#define I_GRAB "grab"
|
||||
#define I_HURT "harm"
|
||||
|
||||
//These are used Bump() code for living mobs, in the mob_bump_flag, mob_swap_flags, and mob_push_flags vars to determine whom can bump/swap with whom.
|
||||
#define HUMAN 1
|
||||
#define MONKEY 2
|
||||
#define ALIEN 4
|
||||
#define ROBOT 8
|
||||
#define SLIME 16
|
||||
#define SIMPLE_ANIMAL 32
|
||||
#define HEAVY 64
|
||||
#define ALLMOBS (HUMAN|MONKEY|ALIEN|ROBOT|SLIME|SIMPLE_ANIMAL|HEAVY)
|
||||
|
||||
//Types of diona, returned by is_diona
|
||||
#define DIONA_NYMPH 1
|
||||
#define DIONA_WORKER 2
|
||||
|
||||
// Robot AI notifications
|
||||
#define ROBOT_NOTIFICATION_NEW_UNIT 1
|
||||
#define ROBOT_NOTIFICATION_NEW_NAME 2
|
||||
#define ROBOT_NOTIFICATION_NEW_MODULE 3
|
||||
#define ROBOT_NOTIFICATION_MODULE_RESET 4
|
||||
|
||||
// Appearance change flags
|
||||
#define APPEARANCE_UPDATE_DNA 0x1
|
||||
#define APPEARANCE_RACE (0x2|APPEARANCE_UPDATE_DNA)
|
||||
#define APPEARANCE_GENDER (0x4|APPEARANCE_UPDATE_DNA)
|
||||
#define APPEARANCE_SKIN 0x8
|
||||
#define APPEARANCE_HAIR 0x10
|
||||
#define APPEARANCE_HAIR_COLOR 0x20
|
||||
#define APPEARANCE_FACIAL_HAIR 0x40
|
||||
#define APPEARANCE_FACIAL_HAIR_COLOR 0x80
|
||||
#define APPEARANCE_EYE_COLOR 0x100
|
||||
#define APPEARANCE_ALL_HAIR (APPEARANCE_HAIR|APPEARANCE_HAIR_COLOR|APPEARANCE_FACIAL_HAIR|APPEARANCE_FACIAL_HAIR_COLOR)
|
||||
#define APPEARANCE_ALL 0xFFFF
|
||||
|
||||
// Click cooldown
|
||||
#define DEFAULT_ATTACK_COOLDOWN 8 //Default timeout for aggressive actions
|
||||
#define DEFAULT_QUICK_COOLDOWN 4
|
||||
|
||||
|
||||
#define MIN_SUPPLIED_LAW_NUMBER 15
|
||||
#define MAX_SUPPLIED_LAW_NUMBER 50
|
||||
|
||||
//default item on-mob icons
|
||||
#define INV_HEAD_DEF_ICON 'icons/mob/head.dmi'
|
||||
#define INV_BACK_DEF_ICON 'icons/mob/back.dmi'
|
||||
#define INV_L_HAND_DEF_ICON 'icons/mob/items/lefthand.dmi'
|
||||
#define INV_R_HAND_DEF_ICON 'icons/mob/items/righthand.dmi'
|
||||
#define INV_W_UNIFORM_DEF_ICON 'icons/mob/uniform.dmi'
|
||||
#define INV_ACCESSORIES_DEF_ICON 'icons/mob/ties.dmi'
|
||||
#define INV_SUIT_DEF_ICON 'icons/mob/ties.dmi'
|
||||
#define INV_SUIT_DEF_ICON 'icons/mob/suit.dmi'
|
||||
#define MAX_SUPPLIED_LAW_NUMBER 50
|
||||
|
||||
// NT's alignment towards the character
|
||||
#define COMPANY_LOYAL "Loyal"
|
||||
#define COMPANY_SUPPORTATIVE "Supportive"
|
||||
#define COMPANY_NEUTRAL "Neutral"
|
||||
#define COMPANY_SKEPTICAL "Skeptical"
|
||||
#define COMPANY_OPPOSED "Opposed"
|
||||
|
||||
#define COMPANY_ALIGNMENTS list(COMPANY_LOYAL,COMPANY_SUPPORTATIVE,COMPANY_NEUTRAL,COMPANY_SKEPTICAL,COMPANY_OPPOSED)
|
||||
|
||||
|
||||
// Defines mob sizes, used by lockers and to determine what is considered a small sized mob, etc.
|
||||
#define MOB_LARGE 16
|
||||
#define MOB_MEDIUM 9
|
||||
#define MOB_SMALL 6
|
||||
#define MOB_TINY 4
|
||||
#define MOB_MINISCULE 1
|
||||
|
||||
// Gluttony levels.
|
||||
#define GLUT_TINY 1 // Eat anything tiny and smaller
|
||||
#define GLUT_SMALLER 2 // Eat anything smaller than we are
|
||||
#define GLUT_ANYTHING 3 // Eat anything, ever
|
||||
|
||||
#define BASE_MAX_NUTRITION 400
|
||||
#define HUNGER_FACTOR 0.05 // Factor of how fast mob nutrition decreases. Moved here from chemistry define
|
||||
|
||||
#define TINT_NONE 0
|
||||
#define TINT_MODERATE 1
|
||||
#define TINT_HEAVY 2
|
||||
#define TINT_BLIND 3
|
||||
|
||||
#define FLASH_PROTECTION_REDUCED -1
|
||||
#define FLASH_PROTECTION_NONE 0
|
||||
#define FLASH_PROTECTION_MODERATE 1
|
||||
#define FLASH_PROTECTION_MAJOR 2
|
||||
#define ANIMAL_SPAWN_DELAY round(config.respawn_delay / 6)
|
||||
#define DRONE_SPAWN_DELAY round(config.respawn_delay / 3)
|
||||
|
||||
#define ANIMAL_SPAWN_DELAY round(config.respawn_delay / 6)
|
||||
#define DRONE_SPAWN_DELAY round(config.respawn_delay / 3)
|
||||
|
||||
// Incapacitation flags, used by the mob/proc/incapacitated() proc
|
||||
#define INCAPACITATION_NONE 0
|
||||
#define INCAPACITATION_RESTRAINED 1
|
||||
#define INCAPACITATION_BUCKLED_PARTIALLY 2
|
||||
#define INCAPACITATION_BUCKLED_FULLY 4
|
||||
#define INCAPACITATION_STUNNED 8
|
||||
#define INCAPACITATION_FORCELYING 16
|
||||
#define INCAPACITATION_KNOCKOUT 32
|
||||
|
||||
#define INCAPACITATION_KNOCKDOWN (INCAPACITATION_KNOCKOUT|INCAPACITATION_FORCELYING)
|
||||
#define INCAPACITATION_DISABLED (INCAPACITATION_KNOCKDOWN|INCAPACITATION_STUNNED)
|
||||
#define INCAPACITATION_DEFAULT (INCAPACITATION_RESTRAINED|INCAPACITATION_BUCKLED_FULLY|INCAPACITATION_DISABLED)
|
||||
#define INCAPACITATION_ALL (~INCAPACITATION_NONE)
|
||||
|
||||
#define MOB_PULL_NONE 0
|
||||
#define MOB_PULL_SMALLER 1
|
||||
#define MOB_PULL_SAME 2
|
||||
#define MOB_PULL_LARGER 3
|
||||
|
||||
//Time of Death constants
|
||||
//Used with a list in preference datums to track times of death
|
||||
#define CREW "crew" //Used for crewmembers, AI, cyborgs, nymphs, antags
|
||||
#define ANIMAL "animal" //Used for mice and any other simple animals
|
||||
#define MINISYNTH "minisynth"//Used for drones and pAIs
|
||||
|
||||
#define RESPAWN_ANIMAL 3000
|
||||
#define RESPAWN_MINISYNTH 6000
|
||||
|
||||
//Flags for the eat_types variable, a bitfield of what can or can't be eaten
|
||||
//Note that any given mob can be more than one type
|
||||
#define TYPE_ORGANIC 1//Almost any creature under /mob/living/carbon and most simple animals
|
||||
#define TYPE_SYNTHETIC 2//Everything under /mob/living/silicon, plus IPCs, viscerators
|
||||
#define TYPE_HUMANOID 4//Humans, skrell, unathi, tajara, vaurca, diona, IPC, vox
|
||||
#define TYPE_WIERD 8//Slimes, constructs, demons, and other creatures of a magical or bluespace nature.
|
||||
|
||||
|
||||
@@ -7,13 +7,12 @@
|
||||
#define PROCESS_STATUS_HUNG 6
|
||||
|
||||
// Process time thresholds
|
||||
#define PROCESS_DEFAULT_HANG_WARNING_TIME 900 // 90 seconds
|
||||
#define PROCESS_DEFAULT_HANG_ALERT_TIME 1800 // 180 seconds
|
||||
#define PROCESS_DEFAULT_HANG_RESTART_TIME 2400 // 240 seconds
|
||||
#define PROCESS_DEFAULT_HANG_WARNING_TIME 300 // 30 seconds
|
||||
#define PROCESS_DEFAULT_HANG_ALERT_TIME 600 // 60 seconds
|
||||
#define PROCESS_DEFAULT_HANG_RESTART_TIME 900 // 90 seconds
|
||||
#define PROCESS_DEFAULT_SCHEDULE_INTERVAL 50 // 50 ticks
|
||||
#define PROCESS_DEFAULT_TICK_ALLOWANCE 20 // 20% of one tick
|
||||
|
||||
// SCHECK macros
|
||||
// This references src directly to work around a weird bug with try/catch
|
||||
#define SCHECK_EVERY(this_many_calls) if(++src.calls_since_last_scheck >= this_many_calls) sleepCheck()
|
||||
#define SCHECK SCHECK_EVERY(50)
|
||||
#define SCHECK sleepCheck()
|
||||
|
||||
@@ -21,12 +21,12 @@ var/global/list/markup_tags = list("/" = list("<i>", "</i>"),
|
||||
"_" = list("<u>", "</u>"))
|
||||
|
||||
/hook/startup/proc/initialize_global_regex()
|
||||
url_find_lazy = new("(https?:\\/\\/\[^\\s\]*)", "g")
|
||||
url_find_lazy = new("((https?|byond):\\/\\/\[^\\s\]*)", "g")
|
||||
|
||||
markup_bold = new("(\\*)(\[^\\*\]*)(\\*)", "g")
|
||||
markup_italics = new("(\\/)(\[^\\/\]*)(\\/)", "g")
|
||||
markup_strike = new("(\\~)(\[^\\~\]*)(\\~)", "g")
|
||||
markup_underline = new("(\\_)(\[^\\_\]*)(\\_)", "g")
|
||||
markup_bold = new("((\\W|^)\\*)(\[^\\*\]*)(\\*(\\W|$))", "g")
|
||||
markup_italics = new("((\\W|^)\\/)(\[^\\/\]*)(\\/(\\W|$))", "g")
|
||||
markup_strike = new("((\\W|^)\\~)(\[^\\~\]*)(\\~(\\W|$))", "g")
|
||||
markup_underline = new("((\\W|^)\\_)(\[^\\_\]*)(\\_(\\W|$))", "g")
|
||||
|
||||
// List needs to be initialized here, due to DM mixing and matching pass-by-value and -reference as it chooses.
|
||||
markup_regex = list("/" = markup_italics,
|
||||
|
||||
18
code/__defines/research.dm
Normal file
18
code/__defines/research.dm
Normal file
@@ -0,0 +1,18 @@
|
||||
#define SHEET_MATERIAL_AMOUNT 2000
|
||||
|
||||
#define TECH_MATERIAL "materials"
|
||||
#define TECH_ENGINEERING "engineering"
|
||||
#define TECH_PHORON "phorontech"
|
||||
#define TECH_POWER "powerstorage"
|
||||
#define TECH_BLUESPACE "bluespace"
|
||||
#define TECH_BIO "biotech"
|
||||
#define TECH_COMBAT "combat"
|
||||
#define TECH_MAGNET "magnets"
|
||||
#define TECH_DATA "programming"
|
||||
#define TECH_ILLEGAL "syndicate"
|
||||
#define TECH_ARCANE "arcane"
|
||||
|
||||
#define IMPRINTER 0x1 //For circuits. Uses glass/chemicals.
|
||||
#define PROTOLATHE 0x2 //New stuff. Uses glass/metal/chemicals
|
||||
#define MECHFAB 0x4 //Mechfab
|
||||
#define CHASSIS 0x8 //For protolathe, but differently
|
||||
76
code/__defines/species_languages.dm
Normal file
76
code/__defines/species_languages.dm
Normal file
@@ -0,0 +1,76 @@
|
||||
// Species flags.
|
||||
#define NO_BLOOD 0x1 // Vessel var is not filled with blood, cannot bleed out.
|
||||
#define NO_BREATHE 0x2 // Cannot suffocate or take oxygen loss.
|
||||
#define NO_SCAN 0x4 // Cannot be scanned in a DNA machine/genome-stolen.
|
||||
#define NO_PAIN 0x8 // Cannot suffer halloss/recieves deceptive health indicator.
|
||||
#define NO_SLIP 0x10 // Cannot fall over.
|
||||
#define NO_POISON 0x20 // Cannot not suffer toxloss.
|
||||
#define IS_PLANT 0x40 // Is a treeperson.
|
||||
#define NO_MINOR_CUT 0x80 // Can step on broken glass with no ill-effects. Either thick skin (diona/vox), cut resistant (slimes) or incorporeal (shadows)
|
||||
// unused: 0x8000 - higher than this will overflow
|
||||
|
||||
// Species spawn flags
|
||||
#define IS_WHITELISTED 0x1 // Must be whitelisted to play.
|
||||
#define CAN_JOIN 0x2 // Species is selectable in chargen.
|
||||
#define IS_RESTRICTED 0x4 // Is not a core/normally playable species. (castes, mutantraces)
|
||||
|
||||
// Species appearance flags
|
||||
#define HAS_SKIN_TONE 0x1 // Skin tone selectable in chargen. (0-255)
|
||||
#define HAS_SKIN_COLOR 0x2 // Skin colour selectable in chargen. (RGB)
|
||||
#define HAS_LIPS 0x4 // Lips are drawn onto the mob icon. (lipstick)
|
||||
#define HAS_UNDERWEAR 0x8 // Underwear is drawn onto the mob icon.
|
||||
#define HAS_EYE_COLOR 0x10 // Eye colour selectable in chargen. (RGB)
|
||||
#define HAS_HAIR_COLOR 0x20 // Hair colour selectable in chargen. (RGB)
|
||||
#define HAS_SOCKS 0x40 // If this species can wear socks
|
||||
#define HAS_FBP 0x80 // If for whatever ungodly reason we decide to ever have non-Shell FBPs.
|
||||
|
||||
// Tau-Ceti basic, language common to all crew.
|
||||
#define LANGUAGE_TCB "Ceti Basic"
|
||||
|
||||
// Species languages
|
||||
#define LANGUAGE_SOL_COMMON "Sol Common"
|
||||
#define LANGUAGE_UNATHI "Sinta'unathi"
|
||||
#define LANGUAGE_SIIK_MAAS "Siik'maas"
|
||||
#define LANGUAGE_SIIK_TAJR "Siik'tajr"
|
||||
#define LANGUAGE_SIGN_TAJARA "Nal'rasan"
|
||||
#define LANGUAGE_SKRELLIAN "Nral'Malic"
|
||||
#define LANGUAGE_RESOMI "Resomi"
|
||||
#define LANGUAGE_ROOTSONG "Rootsong"
|
||||
#define LANGUAGE_TRADEBAND "Tradeband"
|
||||
#define LANGUAGE_GUTTER "Gutter"
|
||||
#define LANGUAGE_VAURCA "Hivenet"
|
||||
#define LANGUAGE_AZAZIBA "Sinta'azaziba"
|
||||
#define LANGUAGE_SIGN "Sign Language"
|
||||
|
||||
// Antag Languages
|
||||
#define LANGUAGE_XENOMORPH "Xenomorph"
|
||||
#define LANGUAGE_HIVEMIND "Hivemind" // xeno hivemind
|
||||
#define LANGUAGE_VOX "Vox-pidgin"
|
||||
#define LANGUAGE_CHANGELING "Changeling"
|
||||
#define LANGUAGE_BORER "Cortical Link"
|
||||
#define LANGUAGE_CULT "Cult" // NOT CULTISTS!
|
||||
#define LANGUAGE_OCCULT "Occult"
|
||||
#define LANGUAGE_TERMINATOR "Hephaestus Darkcomms" // HKs.
|
||||
|
||||
// Lesser-form Languages
|
||||
#define LANGUAGE_CHIMPANZEE "Chimpanzee" // human
|
||||
#define LANGUAGE_NEAERA "Neaera" // skrell
|
||||
#define LANGUAGE_STOK "Stok" // unathi
|
||||
#define LANGUAGE_FARWA "Farwa" // tajara
|
||||
#define LANGUAGE_BUG "V'krexi" // vaurca
|
||||
|
||||
// Synth Languages
|
||||
#define LANGUAGE_ROBOT "Robot Talk"
|
||||
#define LANGUAGE_DRONE "Drone Talk"
|
||||
#define LANGUAGE_EAL "Encoded Audio Language"
|
||||
|
||||
// Language flags.
|
||||
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
|
||||
#define RESTRICTED 2 // Language can only be acquired by spawning or an admin.
|
||||
#define NONVERBAL 4 // Language has a significant non-verbal component. Speech is garbled without line-of-sight.
|
||||
#define SIGNLANG 8 // Language is completely non-verbal. Speech is displayed through emotes for those who can understand.
|
||||
#define HIVEMIND 16 // Broadcast to all mobs with this language.
|
||||
#define NONGLOBAL 32 // Do not add to general languages list.
|
||||
#define INNATE 64 // All mobs can be assumed to speak and understand this language. (audible emotes)
|
||||
#define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message
|
||||
#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems
|
||||
4
code/__defines/targeting.dm
Normal file
4
code/__defines/targeting.dm
Normal file
@@ -0,0 +1,4 @@
|
||||
#define TARGET_CAN_MOVE 1
|
||||
#define TARGET_CAN_RUN 2
|
||||
#define TARGET_CAN_CLICK 4
|
||||
#define TARGET_CAN_RADIO 8
|
||||
10
code/__defines/turfs.dm
Normal file
10
code/__defines/turfs.dm
Normal file
@@ -0,0 +1,10 @@
|
||||
#define TURF_REMOVE_CROWBAR 1
|
||||
#define TURF_REMOVE_SCREWDRIVER 2
|
||||
#define TURF_REMOVE_SHOVEL 4
|
||||
#define TURF_REMOVE_WRENCH 8
|
||||
#define TURF_CAN_BREAK 16
|
||||
#define TURF_CAN_BURN 32
|
||||
#define TURF_HAS_EDGES 64
|
||||
#define TURF_HAS_CORNERS 128
|
||||
#define TURF_IS_FRAGILE 256
|
||||
#define TURF_ACID_IMMUNE 512
|
||||
10
code/__defines/unit_testing.dm
Normal file
10
code/__defines/unit_testing.dm
Normal file
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* This file is used by Travis to indicate that Unit Tests are to be ran.
|
||||
* Do not add anything but the UNIT_TEST definition here as it will be overwritten by Travis when running tests.
|
||||
*
|
||||
*
|
||||
* Should you wish to edit set UNIT_TEST to 1 like so:
|
||||
* #define UNIT_TEST 1
|
||||
*/
|
||||
#define UNIT_TEST 0
|
||||
@@ -1,7 +0,0 @@
|
||||
#define CE_STABLE "stable" // Inaprovaline
|
||||
#define CE_ANTIBIOTIC "antibiotic" // Spaceacilin
|
||||
#define CE_BLOODRESTORE "bloodrestore" // Iron/nutriment
|
||||
#define CE_PAINKILLER "painkiller"
|
||||
#define CE_ALCOHOL "alcohol" // Liver filtering
|
||||
#define CE_ALCOHOL_TOXIC "alcotoxic" // Liver damage
|
||||
#define CE_SPEEDBOOST "gofast" // Hyperzine
|
||||
21
code/_helpers/areas.dm
Normal file
21
code/_helpers/areas.dm
Normal file
@@ -0,0 +1,21 @@
|
||||
//Takes: Area type as text string or as typepath OR an instance of the area.
|
||||
//Returns: A list of all turfs in areas of that type in the world.
|
||||
/proc/get_area_turfs(var/areatype, var/list/predicates)
|
||||
if(!areatype) return null
|
||||
if(istext(areatype)) areatype = text2path(areatype)
|
||||
if(isarea(areatype))
|
||||
var/area/areatemp = areatype
|
||||
areatype = areatemp.type
|
||||
|
||||
var/list/turfs = new/list()
|
||||
for(var/areapath in typesof(areatype))
|
||||
var/area/A = locate(areapath)
|
||||
for(var/turf/T in A.contents)
|
||||
if(!predicates || all_predicates_true(list(T), predicates))
|
||||
turfs += T
|
||||
return turfs
|
||||
|
||||
/proc/pick_area_turf(var/areatype, var/list/predicates)
|
||||
var/list/turfs = get_area_turfs(areatype, predicates)
|
||||
if(turfs && turfs.len)
|
||||
return pick(turfs)
|
||||
47
code/_helpers/atmospherics.dm
Normal file
47
code/_helpers/atmospherics.dm
Normal file
@@ -0,0 +1,47 @@
|
||||
/obj/proc/analyze_gases(var/obj/A, var/mob/user)
|
||||
if(src != A)
|
||||
user.visible_message("<span class='notice'>\The [user] has used \an [src] on \the [A]</span>")
|
||||
|
||||
A.add_fingerprint(user)
|
||||
var/list/result = A.atmosanalyze(user)
|
||||
if(result && result.len)
|
||||
user << "<span class='notice'>Results of the analysis[src == A ? "" : " of \the [A]"]</span>"
|
||||
for(var/line in result)
|
||||
user << "<span class='notice'>[line]</span>"
|
||||
return 1
|
||||
|
||||
user << "<span class='warning'>Your [src] flashes a red light as it fails to analyze \the [A].</span>"
|
||||
return 0
|
||||
|
||||
/proc/atmosanalyzer_scan(var/obj/target, var/datum/gas_mixture/mixture, var/mob/user)
|
||||
var/pressure = mixture.return_pressure()
|
||||
var/total_moles = mixture.total_moles
|
||||
|
||||
var/list/results = list()
|
||||
if (total_moles>0)
|
||||
results += "<span class='notice'>Pressure: [round(pressure,0.1)] kPa</span>"
|
||||
for(var/mix in mixture.gas)
|
||||
results += "<span class='notice'>[gas_data.name[mix]]: [round((mixture.gas[mix] / total_moles) * 100)]%</span>"
|
||||
results += "<span class='notice'>Temperature: [round(mixture.temperature-T0C)]°C</span>"
|
||||
else
|
||||
results += "<span class='notice'>\The [target] is empty!</span>"
|
||||
|
||||
return results
|
||||
|
||||
/obj/proc/atmosanalyze(var/mob/user)
|
||||
return
|
||||
|
||||
/obj/item/weapon/tank/atmosanalyze(var/mob/user)
|
||||
return atmosanalyzer_scan(src, src.air_contents, user)
|
||||
|
||||
/obj/machinery/portable_atmospherics/atmosanalyze(var/mob/user)
|
||||
return atmosanalyzer_scan(src, src.air_contents, user)
|
||||
|
||||
/obj/machinery/atmospherics/pipe/atmosanalyze(var/mob/user)
|
||||
return atmosanalyzer_scan(src, src.parent.air, user)
|
||||
|
||||
/obj/machinery/power/rad_collector/atmosanalyze(var/mob/user)
|
||||
if(P) return atmosanalyzer_scan(src, src.P.air_contents, user)
|
||||
|
||||
/obj/item/weapon/flamethrower/atmosanalyze(var/mob/user)
|
||||
if(ptank) return atmosanalyzer_scan(src, ptank.air_contents, user)
|
||||
@@ -94,17 +94,32 @@ var/global/list/GlobalPool = list()
|
||||
loc = args
|
||||
..()
|
||||
|
||||
/datum/proc/ResetVars(var/list/exlude = list())
|
||||
var/list/excluded = list("animate_movement", "loc", "locs", "parent_type", "vars", "verbs", "type") + exlude
|
||||
var/list/excluded_vars = list("animate_movement", "contents", "loc", "locs", "parent_type", "vars", "verbs", "type")
|
||||
var/list/pooledvariables = list()
|
||||
//thanks to clusterfack @ /vg/station for these two procs
|
||||
/datum/proc/createVariables(var/list/excluded)
|
||||
pooledvariables[type] = new/list()
|
||||
var/list/all_excluded = excluded_vars + excluded
|
||||
|
||||
for(var/V in vars)
|
||||
if(V in excluded)
|
||||
for(var/key in vars)
|
||||
if(key in all_excluded)
|
||||
continue
|
||||
pooledvariables[type][key] = initial(vars[key])
|
||||
|
||||
vars[V] = initial(vars[V])
|
||||
/datum/proc/ResetVars(var/list/excluded = list())
|
||||
if(!pooledvariables[type])
|
||||
createVariables(excluded)
|
||||
|
||||
for(var/key in pooledvariables[type])
|
||||
vars[key] = pooledvariables[type][key]
|
||||
|
||||
/atom/movable/ResetVars()
|
||||
..()
|
||||
vars["loc"] = null
|
||||
loc = null
|
||||
contents = initial(contents) //something is really wrong if this object still has stuff in it by this point
|
||||
|
||||
/image/ResetVars()
|
||||
..()
|
||||
loc = null
|
||||
|
||||
#undef ATOM_POOL_COUNT
|
||||
24
code/_helpers/functional.dm
Normal file
24
code/_helpers/functional.dm
Normal file
@@ -0,0 +1,24 @@
|
||||
/proc/all_predicates_true(var/list/input, var/list/predicates)
|
||||
functional_sanity(input, predicates)
|
||||
|
||||
for(var/i = 1 to predicates.len)
|
||||
if(!call(predicates[i])(arglist(input)))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/proc/any_predicate_true(var/list/input, var/list/predicates)
|
||||
functional_sanity(input, predicates)
|
||||
|
||||
if(!predicates.len)
|
||||
return TRUE
|
||||
|
||||
for(var/i = 1 to predicates.len)
|
||||
if(call(predicates[i])(arglist(input)))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/proc/functional_sanity(var/list/input, var/list/predicates)
|
||||
if(!istype(input))
|
||||
CRASH("Expected list input. Was [input ? "[input.type]" : "null"]")
|
||||
if(!istype(predicates))
|
||||
CRASH("Expected predicate list. Was [predicates ? "[predicates.type]" : "null"]")
|
||||
@@ -156,37 +156,35 @@
|
||||
// It will keep doing this until it checks every content possible. This will fix any problems with mobs, that are inside objects,
|
||||
// being unable to hear people due to being in a box within a bag.
|
||||
|
||||
/proc/recursive_mob_check(var/atom/O, var/list/L = list(), var/recursion_limit = 3, var/client_check = 1, var/sight_check = 1, var/include_radio = 1)
|
||||
/proc/recursive_content_check(var/atom/O, var/list/L = list(), var/recursion_limit = 3, var/client_check = 1, var/sight_check = 1, var/include_mobs = 1, var/include_objects = 1)
|
||||
|
||||
//debug_mob += O.contents.len
|
||||
if(!recursion_limit)
|
||||
return L
|
||||
for(var/atom/A in O.contents)
|
||||
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
if(client_check && !M.client)
|
||||
L |= recursive_mob_check(A, L, recursion_limit - 1, client_check, sight_check, include_radio)
|
||||
continue
|
||||
if(sight_check && !isInSight(A, O))
|
||||
continue
|
||||
for(var/I in O.contents)
|
||||
|
||||
if(ismob(I))
|
||||
if(!sight_check || isInSight(I, O))
|
||||
L |= recursive_content_check(I, L, recursion_limit - 1, client_check, sight_check, include_mobs, include_objects)
|
||||
if(include_mobs)
|
||||
if(client_check)
|
||||
var/mob/M = I
|
||||
if(M.client)
|
||||
L |= M
|
||||
//world.log << "[recursion_limit] = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])"
|
||||
else
|
||||
L |= I
|
||||
|
||||
else if(include_radio && istype(A, /obj/item/device/radio))
|
||||
if(sight_check && !isInSight(A, O))
|
||||
continue
|
||||
L |= A
|
||||
else if(istype(I,/obj/))
|
||||
if(!sight_check || isInSight(I, O))
|
||||
L |= recursive_content_check(I, L, recursion_limit - 1, client_check, sight_check, include_mobs, include_objects)
|
||||
if(include_objects)
|
||||
L |= I
|
||||
|
||||
if(isobj(A) || ismob(A))
|
||||
L |= recursive_mob_check(A, L, recursion_limit - 1, client_check, sight_check, include_radio)
|
||||
return L
|
||||
|
||||
// The old system would loop through lists for a total of 5000 per function call, in an empty server.
|
||||
// This new system will loop at around 1000 in an empty server.
|
||||
// Returns a list of mobs and/or objects in range of R from source. Used in radio and say code.
|
||||
|
||||
/proc/get_mobs_in_view(var/R, var/atom/source)
|
||||
// Returns a list of mobs in range of R from source. Used in radio and say code.
|
||||
/proc/get_mobs_or_objects_in_view(var/R, var/atom/source, var/include_mobs = 1, var/include_objects = 1)
|
||||
|
||||
var/turf/T = get_turf(source)
|
||||
var/list/hear = list()
|
||||
@@ -196,17 +194,17 @@
|
||||
|
||||
var/list/range = hear(R, T)
|
||||
|
||||
for(var/atom/A in range)
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
for(var/I in range)
|
||||
if(ismob(I))
|
||||
hear |= recursive_content_check(I, hear, 3, 1, 0, include_mobs, include_objects)
|
||||
if(include_mobs)
|
||||
var/mob/M = I
|
||||
if(M.client)
|
||||
hear += M
|
||||
//world.log << "Start = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])"
|
||||
else if(istype(A, /obj/item/device/radio))
|
||||
hear += A
|
||||
|
||||
if(isobj(A) || ismob(A))
|
||||
hear |= recursive_mob_check(A, hear, 3, 1, 0, 1)
|
||||
else if(istype(I,/obj/))
|
||||
hear |= recursive_content_check(I, hear, 3, 1, 0, include_mobs, include_objects)
|
||||
if(include_objects)
|
||||
hear += I
|
||||
|
||||
return hear
|
||||
|
||||
@@ -244,7 +242,7 @@
|
||||
if(ear)
|
||||
// Ghostship is magic: Ghosts can hear radio chatter from anywhere
|
||||
if(speaker_coverage[ear] || (istype(M, /mob/dead/observer) && (M.client) && (M.client.prefs.toggles & CHAT_GHOSTRADIO)))
|
||||
. |= M // Since we're already looping through mobs, why bother using |= ? This only slows things down.
|
||||
. += M
|
||||
return .
|
||||
|
||||
#define SIGN(X) ((X<0)?-1:1)
|
||||
@@ -332,12 +330,11 @@ proc/isInSight(var/atom/A, var/atom/B)
|
||||
// Same as above but for alien candidates.
|
||||
|
||||
/proc/get_alien_candidates()
|
||||
|
||||
var/list/candidates = list() //List of candidate KEYS to assume control of the new larva ~Carn
|
||||
var/i = 0
|
||||
while(candidates.len <= 0 && i < 5)
|
||||
for(var/mob/dead/observer/G in player_list)
|
||||
if(G.client.prefs.be_special & BE_ALIEN)
|
||||
if(MODE_XENOMORPH in G.client.prefs.be_special_role)
|
||||
if(((G.client.inactivity/10)/60) <= ALIEN_SELECT_AFK_BUFFER + i) // the most active players are more likely to become an alien
|
||||
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
|
||||
candidates += G.key
|
||||
@@ -362,6 +359,13 @@ proc/isInSight(var/atom/A, var/atom/B)
|
||||
for(var/client/C in group)
|
||||
C.screen -= O
|
||||
|
||||
/proc/flick_overlay(image/I, list/show_to, duration)
|
||||
for(var/client/C in show_to)
|
||||
C.images += I
|
||||
spawn(duration)
|
||||
for(var/client/C in show_to)
|
||||
C.images -= I
|
||||
|
||||
datum/projectile_data
|
||||
var/src_x
|
||||
var/src_y
|
||||
@@ -524,3 +528,6 @@ datum/projectile_data
|
||||
|
||||
/proc/SecondsToTicks(var/seconds)
|
||||
return seconds * 10
|
||||
|
||||
/proc/round_is_spooky(var/spookiness_threshold = config.cult_ghostwriter_req_cultists)
|
||||
return (cult.current_antagonists.len > spookiness_threshold)
|
||||
@@ -11,6 +11,8 @@ var/global/list/human_mob_list = list() //List of all human mobs and sub-type
|
||||
var/global/list/silicon_mob_list = list() //List of all silicon mobs, including clientless
|
||||
var/global/list/living_mob_list = list() //List of all alive mobs, including clientless. Excludes /mob/new_player
|
||||
var/global/list/dead_mob_list = list() //List of all dead mobs, including clientless. Excludes /mob/new_player
|
||||
var/global/list/topic_commands = list() //List of all API commands available
|
||||
var/global/list/topic_commands_names = list() //List of all API commands available
|
||||
|
||||
var/global/list/cable_list = list() //Index for all cables, so that powernets don't have to look through the entire world all the time
|
||||
var/global/list/chemical_reactions_list //list of all /datum/chemical_reaction datums. Used during chemical reactions
|
||||
@@ -50,8 +52,24 @@ var/global/list/underwear_m = list("White" = "m1", "Grey" = "m2", "Green" = "m3"
|
||||
var/global/list/underwear_f = list("Red" = "f1", "White" = "f2", "Yellow" = "f3", "Blue" = "f4", "Black" = "f5", "Thong" = "f6", "Black Sports" = "f7","White Sports" = "f8","None")
|
||||
//undershirt
|
||||
var/global/list/undershirt_t = list("White Tank top" = "u1", "Black Tank top" = "u2", "Black shirt" = "u3", "White shirt" = "u4", "None")
|
||||
|
||||
//socks
|
||||
var/global/list/socks_f = list(
|
||||
"White normal" = "white_norm", "White short" = "white_short", "White knee" = "white_knee",
|
||||
"White thigh" = "white_thigh", "Black normal" = "black_norm", "Black short" = "black_short",
|
||||
"Black knee" = "black_knee", "Black thigh" = "black_thigh", "Striped normal" = "striped_norm",
|
||||
"Striped short" = "striped_short", "Striped knee" = "striped_knee", "Striped thigh" = "striped_thigh",
|
||||
"Rainbow normal" = "rainbow_norm", "Rainbow short" = "rainbow_short", "Rainbow knee" = "rainbow_knee",
|
||||
"Rainbow thigh" = "rainbow_thigh", "Pantyhose" = "pantyhose", "None")
|
||||
|
||||
var/global/list/socks_m = list(
|
||||
"White normal" = "white_norm", "White short" = "white_short", "White knee" = "white_knee",
|
||||
"Black normal" = "black_norm", "Black short" = "black_short", "Black knee" = "black_knee",
|
||||
"Striped normal" = "striped_norm", "Striped short" = "striped_short", "Striped knee" = "striped_knee",
|
||||
"Rainbow normal" = "rainbow_norm", "Rainbow short" = "rainbow_short", "Rainbow knee" = "rainbow_knee", "None")
|
||||
|
||||
//Backpacks
|
||||
var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt")
|
||||
var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt", "Duffel Bag")
|
||||
var/global/list/exclude_jobs = list(/datum/job/ai,/datum/job/cyborg)
|
||||
|
||||
// Visual nets
|
||||
@@ -64,6 +82,12 @@ var/global/list/rune_list = new()
|
||||
var/global/list/escape_list = list()
|
||||
var/global/list/endgame_exits = list()
|
||||
var/global/list/endgame_safespawns = list()
|
||||
|
||||
var/global/list/syndicate_access = list(access_maint_tunnels, access_syndicate, access_external_airlocks)
|
||||
|
||||
//Cloaking devices
|
||||
var/global/list/cloaking_devices = list()
|
||||
|
||||
//////////////////////////
|
||||
/////Initial Building/////
|
||||
//////////////////////////
|
||||
@@ -118,9 +142,7 @@ var/global/list/endgame_safespawns = list()
|
||||
for (var/language_name in all_languages)
|
||||
var/datum/language/L = all_languages[language_name]
|
||||
if(!(L.flags & NONGLOBAL))
|
||||
language_keys[":[lowertext(L.key)]"] = L
|
||||
language_keys[".[lowertext(L.key)]"] = L
|
||||
language_keys["#[lowertext(L.key)]"] = L
|
||||
language_keys[lowertext(L.key)] = L
|
||||
|
||||
var/rkey = 0
|
||||
paths = typesof(/datum/species)-/datum/species
|
||||
@@ -130,9 +152,9 @@ var/global/list/endgame_safespawns = list()
|
||||
S.race_key = rkey //Used in mob icon caching.
|
||||
all_species[S.name] = S
|
||||
|
||||
if(!(S.flags & IS_RESTRICTED))
|
||||
if(!(S.spawn_flags & IS_RESTRICTED))
|
||||
playable_species += S.name
|
||||
if(S.flags & IS_WHITELISTED)
|
||||
if(S.spawn_flags & IS_WHITELISTED)
|
||||
whitelisted_species += S.name
|
||||
|
||||
//Posters
|
||||
@@ -635,7 +635,7 @@ The _flatIcons list is a cache for generated icon files.
|
||||
*/
|
||||
|
||||
proc // Creates a single icon from a given /atom or /image. Only the first argument is required.
|
||||
getFlatIcon(image/A, defdir=2, deficon=null, defstate="", defblend=BLEND_DEFAULT)
|
||||
getFlatIcon(image/A, defdir=2, deficon=null, defstate="", defblend=BLEND_DEFAULT, always_use_defdir = 0)
|
||||
// We start with a blank canvas, otherwise some icon procs crash silently
|
||||
var/icon/flat = icon('icons/effects/effects.dmi', "icon_state"="nothing") // Final flattened icon
|
||||
if(!A)
|
||||
@@ -666,7 +666,7 @@ proc // Creates a single icon from a given /atom or /image. Only the first argu
|
||||
noIcon = TRUE // Do not render this object.
|
||||
|
||||
var/curdir
|
||||
if(A.dir != 2)
|
||||
if(A.dir != 2 && !always_use_defdir)
|
||||
curdir = A.dir
|
||||
else
|
||||
curdir = defdir
|
||||
@@ -760,7 +760,11 @@ proc // Creates a single icon from a given /atom or /image. Only the first argu
|
||||
// Pull the default direction.
|
||||
add = icon(I:icon, I:icon_state)
|
||||
else // 'I' is an appearance object.
|
||||
add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend)
|
||||
if(istype(A,/obj/machinery/atmospherics) && I in A.underlays)
|
||||
var/image/Im = I
|
||||
add = getFlatIcon(new/image(I), Im.dir, curicon, curstate, curblend, 1)
|
||||
else
|
||||
add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend, always_use_defdir)
|
||||
|
||||
// Find the new dimensions of the flat icon to fit the added overlay
|
||||
addX1 = min(flatX1, I:pixel_x+1)
|
||||
@@ -773,9 +777,15 @@ proc // Creates a single icon from a given /atom or /image. Only the first argu
|
||||
flat.Crop(addX1-flatX1+1, addY1-flatY1+1, addX2-flatX1+1, addY2-flatY1+1)
|
||||
flatX1=addX1;flatX2=addX2
|
||||
flatY1=addY1;flatY2=addY2
|
||||
|
||||
var/iconmode
|
||||
if(I in A.overlays)
|
||||
iconmode = ICON_OVERLAY
|
||||
else if(I in A.underlays)
|
||||
iconmode = ICON_UNDERLAY
|
||||
else
|
||||
iconmode = blendMode2iconMode(curblend)
|
||||
// Blend the overlay into the flattened icon
|
||||
flat.Blend(add, blendMode2iconMode(curblend), I:pixel_x + 2 - flatX1, I:pixel_y + 2 - flatY1)
|
||||
flat.Blend(add, iconmode, I:pixel_x + 2 - flatX1, I:pixel_y + 2 - flatY1)
|
||||
|
||||
if(A.color)
|
||||
flat.Blend(A.color, ICON_MULTIPLY)
|
||||
@@ -853,3 +863,66 @@ proc/sort_atoms_by_layer(var/list/atoms)
|
||||
result.Swap(i, gap + i)
|
||||
swapped = 1
|
||||
return result
|
||||
|
||||
/*
|
||||
generate_image function generates image of specified range and location
|
||||
arguments tx, ty, tz are target coordinates (requred), range defines render distance to opposite corner (requred)
|
||||
cap_mode is capturing mode (optional), user is capturing mob (requred only wehen cap_mode = CAPTURE_MODE_REGULAR),
|
||||
lighting determines lighting capturing (optional), suppress_errors suppreses errors and continues to capture (optional).
|
||||
*/
|
||||
proc/generate_image(var/tx as num, var/ty as num, var/tz as num, var/range as num, var/cap_mode = CAPTURE_MODE_PARTIAL, var/mob/living/user, var/lighting = 1, var/suppress_errors = 1)
|
||||
var/list/turfstocapture = list()
|
||||
//Lines below determine what tiles will be rendered
|
||||
for(var/xoff = 0 to range)
|
||||
for(var/yoff = 0 to range)
|
||||
var/turf/T = locate(tx + xoff,ty + yoff,tz)
|
||||
if(T)
|
||||
if(cap_mode == CAPTURE_MODE_REGULAR)
|
||||
if(user.can_capture_turf(T))
|
||||
turfstocapture.Add(T)
|
||||
continue
|
||||
else
|
||||
turfstocapture.Add(T)
|
||||
else
|
||||
//Capture includes non-existan turfs
|
||||
if(!suppress_errors)
|
||||
return
|
||||
//Lines below determine what objects will be rendered
|
||||
var/list/atoms = list()
|
||||
for(var/turf/T in turfstocapture)
|
||||
atoms.Add(T)
|
||||
for(var/atom/A in T)
|
||||
if(istype(A, /atom/movable/lighting_overlay) && lighting) //Special case for lighting
|
||||
atoms.Add(A)
|
||||
continue
|
||||
if(A.invisibility) continue
|
||||
atoms.Add(A)
|
||||
//Lines below actually render all colected data
|
||||
atoms = sort_atoms_by_layer(atoms)
|
||||
var/icon/cap = icon('icons/effects/96x96.dmi', "")
|
||||
cap.Scale(range*32, range*32)
|
||||
cap.Blend("#000", ICON_OVERLAY)
|
||||
for(var/atom/A in atoms)
|
||||
if(A)
|
||||
var/icon/img = getFlatIcon(A)
|
||||
if(istype(img, /icon))
|
||||
if(istype(A, /mob/living) && A:lying)
|
||||
img.BecomeLying()
|
||||
var/xoff = (A.x - tx) * 32
|
||||
var/yoff = (A.y - ty) * 32
|
||||
cap.Blend(img, blendMode2iconMode(A.blend_mode), A.pixel_x + xoff, A.pixel_y + yoff)
|
||||
|
||||
return cap
|
||||
|
||||
proc/percentage_to_colour(var/P)
|
||||
//Takes a value between 0-1
|
||||
//Returns a colour - pure green if 1, pure red if 0
|
||||
//Inbetween values will gradiant through green, yellow, orange, red
|
||||
|
||||
|
||||
var/green = min(1, P*2)*255
|
||||
var/red = 255 - (min(1, (P-0.5)*2)*255)
|
||||
//var/green = (max(0, P-0.5)*2)*255
|
||||
//var/red = 255 - (min(1, P*2)*255)
|
||||
|
||||
return rgb(red,green,0)
|
||||
9
code/_helpers/items.dm
Normal file
9
code/_helpers/items.dm
Normal file
@@ -0,0 +1,9 @@
|
||||
//Prevents robots dropping their modules.
|
||||
/proc/dropsafety(var/atom/movable/A)
|
||||
if (istype(A.loc, /mob/living/silicon))
|
||||
return 0
|
||||
|
||||
else if (istype(A.loc, /obj/item/rig_module))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -71,6 +71,32 @@ proc/isemptylist(list/list)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/is_type_in_oview(var/type, var/dist = 0, var/center = src)
|
||||
if (!ispath(type))
|
||||
CRASH("Not a valid type in 'is_type_in_oview()'")
|
||||
if (!isnum(dist))
|
||||
CRASH("Not a valid dist in 'is_type_in_oview()'")
|
||||
if (!isloc(center))
|
||||
CRASH("Not a valid center in 'is_type_in_oview()'")
|
||||
var/list/atoms = oview(dist, center)
|
||||
for (var/A in atoms)
|
||||
if (istype(A, type))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/is_type_in_view(var/type, var/dist = 0, var/center = src)
|
||||
if (!ispath(type))
|
||||
CRASH("Not a valid type in 'is_type_in_view()'")
|
||||
if (!isnum(dist))
|
||||
CRASH("Not a valid dist in 'is_type_in_view()'")
|
||||
if (!isloc(center))
|
||||
CRASH("Not a valid center in 'is_type_in_view()'")
|
||||
var/list/atoms = view(dist, center)
|
||||
for (var/A in atoms)
|
||||
if (istype(A, type))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/instances_of_type_in_list(var/atom/A, var/list/L)
|
||||
var/instances = 0
|
||||
for(var/type in L)
|
||||
@@ -122,23 +148,29 @@ proc/listclearnulls(list/list)
|
||||
result = first ^ second
|
||||
return result
|
||||
|
||||
//Pretends to pick an element based on its weight but really just seems to pick a random element.
|
||||
|
||||
//Picks a random element by weight from a list. The list must be correctly constructed in this format:
|
||||
//mylist[myelement1] = myweight1
|
||||
//mylist[myelement2] = myweight2
|
||||
//The proc will return the element index, and not the weight.
|
||||
/proc/pickweight(list/L)
|
||||
var/total = 0
|
||||
var/item
|
||||
for (item in L)
|
||||
if (!L[item])
|
||||
if (isnull(L[item]))
|
||||
//Change by nanako, a default weight will no longer overwrite an explicitly set weight of 0
|
||||
//It will only use a default if no weight is defined
|
||||
L[item] = 1
|
||||
total += L[item]
|
||||
|
||||
total = rand(1, total)
|
||||
total = rand() * total//Fix by nanako, allows it to handle noninteger weights
|
||||
for (item in L)
|
||||
total -=L [item]
|
||||
total -= L[item]
|
||||
if (total <= 0)
|
||||
return item
|
||||
|
||||
return null
|
||||
|
||||
|
||||
//Pick a random element from the list and remove it from the list.
|
||||
/proc/pick_n_take(list/listfrom)
|
||||
if (listfrom.len > 0)
|
||||
@@ -598,7 +630,7 @@ proc/dd_sortedTextList(list/incoming)
|
||||
return dd_sortedtextlist(incoming, case_sensitive)
|
||||
|
||||
|
||||
datum/proc/dd_SortValue()
|
||||
/datum/proc/dd_SortValue()
|
||||
return "[src]"
|
||||
|
||||
/obj/machinery/dd_SortValue()
|
||||
@@ -620,3 +652,12 @@ datum/proc/dd_SortValue()
|
||||
for(var/path in subtypesof(prototype))
|
||||
L += new path()
|
||||
return L
|
||||
|
||||
#define listequal(A, B) (A.len == B.len && !length(A^B))
|
||||
|
||||
/proc/Sum(var/list/input)
|
||||
var/total = 0
|
||||
for (var/i=1,i<=input.len,i++)
|
||||
total += input[i]
|
||||
|
||||
return total
|
||||
@@ -82,6 +82,10 @@
|
||||
if (config.log_pda)
|
||||
game_log("PDA", text)
|
||||
|
||||
/proc/log_ntirc(text)
|
||||
if (config.log_pda)
|
||||
game_log("NTIRC", text)
|
||||
|
||||
/proc/log_to_dd(text)
|
||||
world.log << text //this comes before the config check because it can't possibly runtime
|
||||
if(config.log_world_output)
|
||||
@@ -90,6 +94,23 @@
|
||||
/proc/log_misc(text)
|
||||
game_log("MISC", text)
|
||||
|
||||
/proc/log_unit_test(text)
|
||||
world.log << "## UNIT_TEST ##: [text]"
|
||||
|
||||
// Procs for logging into diary_runtime
|
||||
/proc/log_hard_delete(atom/A)
|
||||
if (config.log_runtime)
|
||||
diary_runtime << "hard delete:[log_end]"
|
||||
diary_runtime << "[A.type][log_end]"
|
||||
|
||||
/proc/log_exception(exception/e)
|
||||
if (config.log_runtime)
|
||||
if (config.log_runtime == 2)
|
||||
log_debug("RUNTIME ERROR:\n[e.name]")
|
||||
|
||||
diary_runtime << "runtime error:[e.name][log_end]"
|
||||
diary_runtime << "[e.desc]"
|
||||
|
||||
//pretty print a direction bitflag, can be useful for debugging.
|
||||
/proc/print_dir(var/dir)
|
||||
var/list/comps = list()
|
||||
@@ -122,3 +122,9 @@
|
||||
|
||||
/proc/norm(x, y)
|
||||
return sqrt(squaredNorm(x, y))
|
||||
|
||||
/proc/IsPowerOfTwo(var/val)
|
||||
return (val & (val-1)) == 0
|
||||
|
||||
/proc/RoundUpToPowerOfTwo(var/val)
|
||||
return 2 ** -round(-log(2,val))
|
||||
17
code/_helpers/matrices.dm
Normal file
17
code/_helpers/matrices.dm
Normal file
@@ -0,0 +1,17 @@
|
||||
/matrix/proc/TurnTo(old_angle, new_angle)
|
||||
. = new_angle - old_angle
|
||||
Turn(.) //BYOND handles cases such as -270, 360, 540 etc. DOES NOT HANDLE 180 TURNS WELL, THEY TWEEN AND LOOK LIKE SHIT
|
||||
|
||||
|
||||
/atom/proc/SpinAnimation(speed = 10, loops = -1)
|
||||
var/matrix/m120 = matrix(transform)
|
||||
m120.Turn(120)
|
||||
var/matrix/m240 = matrix(transform)
|
||||
m240.Turn(240)
|
||||
var/matrix/m360 = matrix(transform)
|
||||
speed /= 3 //Gives us 3 equal time segments for our three turns.
|
||||
//Why not one turn? Because byond will see that the start and finish are the same place and do nothing
|
||||
//Why not two turns? Because byond will do a flip instead of a turn
|
||||
animate(src, transform = m120, time = speed, loops)
|
||||
animate(transform = m240, time = speed)
|
||||
animate(transform = m360, time = speed)
|
||||
@@ -1,3 +1,28 @@
|
||||
/atom/movable/proc/get_mob()
|
||||
return
|
||||
|
||||
/obj/machinery/bot/mulebot/get_mob()
|
||||
if(load && istype(load,/mob/living))
|
||||
return load
|
||||
|
||||
/obj/mecha/get_mob()
|
||||
return occupant
|
||||
|
||||
/obj/vehicle/train/get_mob()
|
||||
return buckled_mob
|
||||
|
||||
/mob/get_mob()
|
||||
return src
|
||||
|
||||
/proc/mobs_in_view(var/range, var/source)
|
||||
var/list/mobs = list()
|
||||
for(var/atom/movable/AM in view(range, source))
|
||||
var/M = AM.get_mob()
|
||||
if(M)
|
||||
mobs += M
|
||||
|
||||
return mobs
|
||||
|
||||
proc/random_hair_style(gender, species = "Human")
|
||||
var/h_style = "Bald"
|
||||
|
||||
@@ -37,13 +62,20 @@ proc/random_facial_hair_style(gender, species = "Human")
|
||||
|
||||
return f_style
|
||||
|
||||
proc/sanitize_name(name, species = "Human")
|
||||
var/datum/species/current_species
|
||||
if(species)
|
||||
current_species = all_species[species]
|
||||
|
||||
return current_species ? current_species.sanitize_name(name) : sanitizeName(name)
|
||||
|
||||
proc/random_name(gender, species = "Human")
|
||||
|
||||
var/datum/species/current_species
|
||||
if(species)
|
||||
current_species = all_species[species]
|
||||
|
||||
if(!current_species || current_species.name == "Human")
|
||||
if(!current_species || current_species.name_language == null)
|
||||
if(gender==FEMALE)
|
||||
return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names))
|
||||
else
|
||||
@@ -137,7 +169,44 @@ Proc for attack log creation, because really why not
|
||||
|
||||
/proc/get_exposed_defense_zone(var/atom/movable/target)
|
||||
var/obj/item/weapon/grab/G = locate() in target
|
||||
if (G && G.state >= GRAB_NECK)
|
||||
if(G && G.state >= GRAB_NECK) //works because mobs are currently not allowed to upgrade to NECK if they are grabbing two people.
|
||||
return pick("head", "l_hand", "r_hand", "l_foot", "r_foot", "l_arm", "r_arm", "l_leg", "r_leg")
|
||||
else
|
||||
return pick("chest", "groin")
|
||||
|
||||
|
||||
// Returns true if M was not already in the dead mob list
|
||||
/mob/proc/switch_from_living_to_dead_mob_list()
|
||||
remove_from_living_mob_list()
|
||||
. = add_to_dead_mob_list()
|
||||
|
||||
// Returns true if M was not already in the living mob list
|
||||
/mob/proc/switch_from_dead_to_living_mob_list()
|
||||
remove_from_dead_mob_list()
|
||||
. = add_to_living_mob_list()
|
||||
|
||||
// Returns true if the mob was in neither the dead or living list
|
||||
/mob/proc/add_to_living_mob_list()
|
||||
return FALSE
|
||||
/mob/living/add_to_living_mob_list()
|
||||
if((src in living_mob_list) || (src in dead_mob_list))
|
||||
return FALSE
|
||||
living_mob_list += src
|
||||
return TRUE
|
||||
|
||||
// Returns true if the mob was removed from the living list
|
||||
/mob/proc/remove_from_living_mob_list()
|
||||
return living_mob_list.Remove(src)
|
||||
|
||||
// Returns true if the mob was in neither the dead or living list
|
||||
/mob/proc/add_to_dead_mob_list()
|
||||
return FALSE
|
||||
/mob/living/add_to_dead_mob_list()
|
||||
if((src in living_mob_list) || (src in dead_mob_list))
|
||||
return FALSE
|
||||
dead_mob_list += src
|
||||
return TRUE
|
||||
|
||||
// Returns true if the mob was removed form the dead list
|
||||
/mob/proc/remove_from_dead_mob_list()
|
||||
return dead_mob_list.Remove(src)
|
||||
@@ -20,7 +20,7 @@ var/command_name = null
|
||||
if (command_name)
|
||||
return command_name
|
||||
|
||||
var/name = "Central Command"
|
||||
var/name = "[boss_name]"
|
||||
|
||||
command_name = name
|
||||
return name
|
||||
@@ -44,11 +44,11 @@ var/religion_name = null
|
||||
return capitalize(name)
|
||||
|
||||
/proc/system_name()
|
||||
return "Nyx"
|
||||
return "Tau Ceti"
|
||||
|
||||
/proc/commstation_name()
|
||||
if (commstation_name)
|
||||
return commstation_name
|
||||
if (dock_name)
|
||||
return dock_name
|
||||
|
||||
/proc/station_name()
|
||||
if (station_name)
|
||||
@@ -165,7 +165,7 @@ var/syndicate_code_response//Code response for traitors.
|
||||
Obviously, some people will be better at this than others but in theory, everyone should be able to do it and it only enhances roleplay.
|
||||
Can probably be done through "{ }" but I don't really see the practical benefit.
|
||||
One example of an earlier system is commented below.
|
||||
/N
|
||||
-N
|
||||
*/
|
||||
|
||||
/proc/generate_code_phrase()//Proc is used for phrase and response in master_controller.dm
|
||||
86
code/_helpers/spawn_sync.dm
Normal file
86
code/_helpers/spawn_sync.dm
Normal file
@@ -0,0 +1,86 @@
|
||||
//-------------------------------
|
||||
/*
|
||||
Spawn sync helper
|
||||
|
||||
Helps syncronize spawn()ing multiple processes in loops.
|
||||
|
||||
Example for using this:
|
||||
|
||||
//Create new spawn_sync datum
|
||||
var/datum/spawn_sync/sync = new()
|
||||
|
||||
for(var/obj/O in list)
|
||||
//Call start_worker(), passing it first the object, then a string of the name of the proc you want called, then
|
||||
// any and all arguments you want passed to the proc.
|
||||
sync.start_worker(O, "do_something", arg1, arg2)
|
||||
|
||||
//Finally call wait_until_done()
|
||||
sync.wait_until_done()
|
||||
|
||||
//Once all the workers have completed, or the failsafe has triggered, the code will continue. By default the
|
||||
// failsafe is roughly 10 seconds (100 checks).
|
||||
*/
|
||||
//-------------------------------
|
||||
/datum/spawn_sync
|
||||
var/count = 1
|
||||
var/failsafe = 100 //how many checks before the failsafe triggers and the helper stops waiting
|
||||
|
||||
//Opens a thread counter
|
||||
/datum/spawn_sync/proc/open()
|
||||
count++
|
||||
|
||||
//Closes a thread counter
|
||||
/datum/spawn_sync/proc/close()
|
||||
count--
|
||||
|
||||
//Finalizes the spawn sync by removing the original starting count
|
||||
/datum/spawn_sync/proc/finalize()
|
||||
close()
|
||||
|
||||
//Resets the counter if you want to utilize the same datum multiple times
|
||||
// Optional: pass the number of checks you want for the failsafe
|
||||
/datum/spawn_sync/proc/reset(var/safety = 100)
|
||||
count = 1
|
||||
failsafe = safety
|
||||
|
||||
//Check if all threads have returned
|
||||
// Returns 0 if not all threads have completed
|
||||
// Returns 1 if all threads have completed
|
||||
/datum/spawn_sync/proc/check()
|
||||
safety_check()
|
||||
return count > 0 ? 1 : 0
|
||||
|
||||
//Failsafe in case something breaks horribly
|
||||
/datum/spawn_sync/proc/safety_check()
|
||||
failsafe--
|
||||
if(failsafe < 1)
|
||||
count = 0
|
||||
|
||||
//Set failsafe check count in case you need more time for the workers to return
|
||||
/datum/spawn_sync/proc/set_failsafe(var/safety)
|
||||
failsafe = safety
|
||||
|
||||
/datum/spawn_sync/proc/start_worker()
|
||||
//Extract the thread run proc and it's arguments from the variadic args list.
|
||||
ASSERT(args.len > 0)
|
||||
var/obj = args[1]
|
||||
var/thread_proc = args[2]
|
||||
|
||||
//dispatch a new thread
|
||||
open()
|
||||
spawn()
|
||||
//Utilise try/catch keywords here so the code continues even if an error occurs.
|
||||
try
|
||||
call(obj, thread_proc)(arglist(args.Copy(3)))
|
||||
catch(var/exception/e)
|
||||
error("[e] on [e.file]:[e.line]")
|
||||
close()
|
||||
|
||||
/datum/spawn_sync/proc/wait_until_done()
|
||||
finalize()
|
||||
|
||||
//Create a while loop to check if the sync is complete yet, it will return once all the spawn threads have
|
||||
// completed, or the failsafe has expired.
|
||||
while(check())
|
||||
//Add a sleep call to delay each check.
|
||||
sleep(1)
|
||||
@@ -34,7 +34,8 @@
|
||||
input = replace_characters(input, list("\n"=" ","\t"=" "))
|
||||
|
||||
if(encode)
|
||||
//In addition to processing html, html_encode removes byond formatting codes like "\red", "\i" and other.
|
||||
// The below \ escapes have a space inserted to attempt to enable Travis auto-checking of span class usage. Please do not remove the space.
|
||||
//In addition to processing html, html_encode removes byond formatting codes like "\ red", "\ i" and other.
|
||||
//It is important to avoid double-encode text, it can "break" quotes and some other characters.
|
||||
//Also, keep in mind that escaped characters don't work in the interface (window titles, lower left corner of the main window, etc.)
|
||||
input = html_encode(input)
|
||||
@@ -115,7 +116,7 @@
|
||||
if(last_char_group == 1)
|
||||
output = copytext(output,1,length(output)) //removes the last character (in this case a space)
|
||||
|
||||
for(var/bad_name in list("space","floor","wall","r-wall","monkey","unknown","inactive ai")) //prevents these common metagamey names
|
||||
for(var/bad_name in list("space","floor","wall","r-wall","monkey","unknown","inactive ai","plating")) //prevents these common metagamey names
|
||||
if(cmptext(output,bad_name)) return //(not case sensitive)
|
||||
|
||||
return output
|
||||
@@ -338,7 +339,7 @@ proc/TextPreview(var/string,var/len=40)
|
||||
var/regex/tag_markup
|
||||
for (var/tag in (markup_tags - ignore_tags))
|
||||
tag_markup = markup_regex[tag]
|
||||
message = tag_markup.Replace(message, "[markup_tags[tag][1]]$2[markup_tags[tag][2]]")
|
||||
message = tag_markup.Replace(message, "$2[markup_tags[tag][1]]$3[markup_tags[tag][2]]$5")
|
||||
|
||||
// ---Unload URL cache
|
||||
for (var/ref in urls)
|
||||
@@ -349,3 +350,75 @@ proc/TextPreview(var/string,var/len=40)
|
||||
//Converts New Lines to html <br>
|
||||
/proc/nl2br(var/text)
|
||||
return replacetextEx(text,"\n","<br>")
|
||||
|
||||
/proc/contains_az09(var/input)
|
||||
for(var/i=1, i<=length(input), i++)
|
||||
var/ascii_char = text2ascii(input,i)
|
||||
switch(ascii_char)
|
||||
// A .. Z
|
||||
if(65 to 90) //Uppercase Letters
|
||||
return 1
|
||||
// a .. z
|
||||
if(97 to 122) //Lowercase Letters
|
||||
return 1
|
||||
|
||||
// 0 .. 9
|
||||
if(48 to 57) //Numbers
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/generateRandomString(var/length)
|
||||
. = list()
|
||||
for(var/a in 1 to length)
|
||||
var/letter = rand(33,126)
|
||||
. += ascii2text(letter)
|
||||
. = jointext(.,null)
|
||||
|
||||
#define starts_with(string, substring) (copytext(string,1,1+length(substring)) == substring)
|
||||
|
||||
#define gender2text(gender) capitalize(gender)
|
||||
|
||||
/**
|
||||
* Strip out the special beyond characters for \proper and \improper
|
||||
* from text that will be sent to the browser.
|
||||
*/
|
||||
#define strip_improper(input_text) replacetext(replacetext(input_text, "\proper", ""), "\improper", "")
|
||||
|
||||
|
||||
/proc/pencode2html(t)
|
||||
t = replacetext(t, "\n", "<BR>")
|
||||
t = replacetext(t, "\[center\]", "<center>")
|
||||
t = replacetext(t, "\[/center\]", "</center>")
|
||||
t = replacetext(t, "\[br\]", "<BR>")
|
||||
t = replacetext(t, "\[b\]", "<B>")
|
||||
t = replacetext(t, "\[/b\]", "</B>")
|
||||
t = replacetext(t, "\[i\]", "<I>")
|
||||
t = replacetext(t, "\[/i\]", "</I>")
|
||||
t = replacetext(t, "\[u\]", "<U>")
|
||||
t = replacetext(t, "\[/u\]", "</U>")
|
||||
t = replacetext(t, "\[large\]", "<font size=\"4\">")
|
||||
t = replacetext(t, "\[/large\]", "</font>")
|
||||
t = replacetext(t, "\[field\]", "<span class=\"paper_field\"></span>")
|
||||
t = replacetext(t, "\[h1\]", "<H1>")
|
||||
t = replacetext(t, "\[/h1\]", "</H1>")
|
||||
t = replacetext(t, "\[h2\]", "<H2>")
|
||||
t = replacetext(t, "\[/h2\]", "</H2>")
|
||||
t = replacetext(t, "\[h3\]", "<H3>")
|
||||
t = replacetext(t, "\[/h3\]", "</H3>")
|
||||
t = replacetext(t, "\[*\]", "<li>")
|
||||
t = replacetext(t, "\[hr\]", "<HR>")
|
||||
t = replacetext(t, "\[small\]", "<font size = \"1\">")
|
||||
t = replacetext(t, "\[/small\]", "</font>")
|
||||
t = replacetext(t, "\[list\]", "<ul>")
|
||||
t = replacetext(t, "\[/list\]", "</ul>")
|
||||
t = replacetext(t, "\[table\]", "<table border=1 cellspacing=0 cellpadding=3 style='border: 1px solid black;'>")
|
||||
t = replacetext(t, "\[/table\]", "</td></tr></table>")
|
||||
t = replacetext(t, "\[grid\]", "<table>")
|
||||
t = replacetext(t, "\[/grid\]", "</td></tr></table>")
|
||||
t = replacetext(t, "\[row\]", "</td><tr>")
|
||||
t = replacetext(t, "\[cell\]", "<td>")
|
||||
t = replacetext(t, "\[logo\]", "<img src = ntlogo.png>")
|
||||
t = replacetext(t, "\[time\]", "[worldtime2text()]")
|
||||
t = replacetext(t, "\[date\]", "[worlddate2text()]")
|
||||
t = replacetext(t, "\[editorbr\]", "<BR>")
|
||||
return t
|
||||
@@ -6,9 +6,14 @@
|
||||
|
||||
var/roundstart_hour = 0
|
||||
//Returns the world time in english
|
||||
proc/worldtime2text(time = world.time)
|
||||
if(!roundstart_hour) roundstart_hour = pick(2,7,12,17)
|
||||
return "[(round(time / 36000)+roundstart_hour) % 24]:[(time / 600 % 60) < 10 ? add_zero(time / 600 % 60, 1) : time / 600 % 60]"
|
||||
proc/worldtime2text(time = world.time, timeshift = 1)
|
||||
if(!roundstart_hour) roundstart_hour = rand(0, 23)
|
||||
return timeshift ? time2text(time+(36000*roundstart_hour), "hh:mm") : time2text(time, "hh:mm")
|
||||
|
||||
proc/worldtime2ticks(time = world.time)
|
||||
if(!roundstart_hour)
|
||||
worldtime2text()
|
||||
return ((roundstart_hour * 60 MINUTES) + time) % TICKS_IN_DAY
|
||||
|
||||
proc/worlddate2text()
|
||||
return num2text(game_year) + "-" + time2text(world.timeofday, "MM-DD")
|
||||
74
code/_helpers/turfs.dm
Normal file
74
code/_helpers/turfs.dm
Normal file
@@ -0,0 +1,74 @@
|
||||
// Returns the atom sitting on the turf.
|
||||
// For example, using this on a disk, which is in a bag, on a mob, will return the mob because it's on the turf.
|
||||
/proc/get_atom_on_turf(var/atom/movable/M)
|
||||
var/atom/mloc = M
|
||||
while(mloc && mloc.loc && !istype(mloc.loc, /turf/))
|
||||
mloc = mloc.loc
|
||||
return mloc
|
||||
|
||||
/proc/iswall(turf/T)
|
||||
return (istype(T, /turf/simulated/wall) || istype(T, /turf/unsimulated/wall) || istype(T, /turf/simulated/shuttle/wall))
|
||||
|
||||
/proc/isfloor(turf/T)
|
||||
return (istype(T, /turf/simulated/floor) || istype(T, /turf/unsimulated/floor) || istype(T, /turf/simulated/shuttle/floor))
|
||||
|
||||
|
||||
//Edit by Nanako
|
||||
//This proc is used in only two places, ive changed it to make more sense
|
||||
//The old behaviour returned zero if there were any simulated atoms at all, even pipes and wires
|
||||
//Now it just finds if the tile is blocked by anything solid.
|
||||
/proc/turf_clear(turf/T)
|
||||
if (T.density)
|
||||
return 0
|
||||
for(var/atom/A in T)
|
||||
if(A.density)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
// This proc will check if a neighboring tile in the stated direction "dir" is dense or not
|
||||
// Will return 1 if it is dense and zero if not
|
||||
/proc/check_neighbor_density(turf/T, var/dir)
|
||||
if (!T.loc)
|
||||
CRASH("The Turf has no location!")
|
||||
switch (dir)
|
||||
if (NORTH)
|
||||
return !turf_clear(get_turf(locate(T.x, T.y+1, T.z)))
|
||||
if (NORTHEAST)
|
||||
return !turf_clear(get_turf(locate(T.x+1, T.y+1, T.z)))
|
||||
if (EAST)
|
||||
return !turf_clear(get_turf(locate(T.x+1, T.y, T.z)))
|
||||
if (SOUTHEAST)
|
||||
return !turf_clear(get_turf(locate(T.x+1, T.y-1, T.z)))
|
||||
if (SOUTH)
|
||||
return !turf_clear(get_turf(locate(T.x, T.y-1, T.z)))
|
||||
if (SOUTHWEST)
|
||||
return !turf_clear(get_turf(locate(T.x-1, T.y-1, T.z)))
|
||||
if (WEST)
|
||||
return !turf_clear(get_turf(locate(T.x-1, T.y, T.z)))
|
||||
if (NORTHWEST)
|
||||
return !turf_clear(get_turf(locate(T.x-1, T.y+1, T.z)))
|
||||
else return
|
||||
|
||||
// Picks a turf without a mob from the given list of turfs, if one exists.
|
||||
// If no such turf exists, picks any random turf from the given list of turfs.
|
||||
/proc/pick_mobless_turf_if_exists(var/list/start_turfs)
|
||||
if(!start_turfs.len)
|
||||
return null
|
||||
|
||||
var/list/available_turfs = list()
|
||||
for(var/start_turf in start_turfs)
|
||||
var/mob/M = locate() in start_turf
|
||||
if(!M)
|
||||
available_turfs += start_turf
|
||||
if(!available_turfs.len)
|
||||
available_turfs = start_turfs
|
||||
return pick(available_turfs)
|
||||
|
||||
/proc/turf_contains_dense_objects(var/turf/T)
|
||||
return T.contains_dense_objects()
|
||||
|
||||
/proc/not_turf_contains_dense_objects(var/turf/T)
|
||||
return !turf_contains_dense_objects(T)
|
||||
|
||||
/proc/is_station_turf(var/turf/T)
|
||||
return T && isStationLevel(T.z)
|
||||
@@ -36,35 +36,19 @@
|
||||
return num
|
||||
|
||||
// Returns the hex value of a number given a value assumed to be a base-ten value
|
||||
/proc/num2hex(num, digits)
|
||||
if (digits == null)
|
||||
digits = 2
|
||||
/proc/num2hex(num, padlength)
|
||||
var/global/list/hexdigits = list("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
|
||||
|
||||
if (!isnum(num))
|
||||
return
|
||||
. = ""
|
||||
while(num > 0)
|
||||
var/hexdigit = hexdigits[(num & 0xF) + 1]
|
||||
. = "[hexdigit][.]"
|
||||
num >>= 4 //go to the next half-byte
|
||||
|
||||
// hex is our return value, to which each hex-digit of num is appended to.
|
||||
var/hex = ""
|
||||
var/power = -4
|
||||
var/n = 1
|
||||
|
||||
// Figure out power. (power of 2)
|
||||
while (n <= num)
|
||||
power += 4
|
||||
n *= 16
|
||||
|
||||
// Note that we have to start appending to hex with the most-significant digits.
|
||||
while (power >= 0)
|
||||
var/m = (num >> power) & 15
|
||||
hex += ascii2text(m + (m < 10 ? 48 : 87)) // Provided by the IconProcs library.
|
||||
power -= 4
|
||||
|
||||
// Append zeroes to make sure that hex is atleast digits long.
|
||||
var/left = digits - length(hex)
|
||||
//pad with zeroes
|
||||
var/left = padlength - length(.)
|
||||
while (left-- > 0)
|
||||
hex = text("0[]", hex)
|
||||
|
||||
return hex
|
||||
. = "0[.]"
|
||||
|
||||
// Concatenates a list of strings into a single string. A seperator may optionally be provided.
|
||||
/proc/list2text(list/ls, sep)
|
||||
@@ -292,13 +276,6 @@ proc/tg_list2text(list/list, glue=",")
|
||||
if (rights & R_CCIAA) . += "[seperator]+CCIAA"
|
||||
return .
|
||||
|
||||
/proc/ui_style2icon(ui_style)
|
||||
switch (ui_style)
|
||||
if ("old") return 'icons/mob/screen1_old.dmi'
|
||||
if ("Orange") return 'icons/mob/screen1_Orange.dmi'
|
||||
if ("Midnight") return 'icons/mob/screen1_Midnight.dmi'
|
||||
else return 'icons/mob/screen1_White.dmi'
|
||||
|
||||
// heat2color functions. Adapted from: http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
|
||||
/proc/heat2color(temp)
|
||||
return rgb(heat2color_r(temp), heat2color_g(temp), heat2color_b(temp))
|
||||
@@ -4,6 +4,9 @@
|
||||
* A large number of misc global procs.
|
||||
*/
|
||||
|
||||
//Checks if all high bits in req_mask are set in bitfield
|
||||
#define BIT_TEST_ALL(bitfield, req_mask) ((~(bitfield) & (req_mask)) == 0)
|
||||
|
||||
//Inverts the colour of an HTML string
|
||||
/proc/invertHTML(HTMLstring)
|
||||
|
||||
@@ -223,6 +226,33 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
line+=locate(px,py,M.z)
|
||||
return line
|
||||
|
||||
#define LOCATE_COORDS(X, Y, Z) locate(between(1, X, world.maxx), between(1, Y, world.maxy), Z)
|
||||
/proc/getcircle(turf/center, var/radius) //Uses a fast Bresenham rasterization algorithm to return the turfs in a thin circle.
|
||||
if(!radius) return list(center)
|
||||
|
||||
var/x = 0
|
||||
var/y = radius
|
||||
var/p = 3 - 2 * radius
|
||||
|
||||
. = list()
|
||||
while(y >= x) // only formulate 1/8 of circle
|
||||
|
||||
. += LOCATE_COORDS(center.x - x, center.y - y, center.z) //upper left left
|
||||
. += LOCATE_COORDS(center.x - y, center.y - x, center.z) //upper upper left
|
||||
. += LOCATE_COORDS(center.x + y, center.y - x, center.z) //upper upper right
|
||||
. += LOCATE_COORDS(center.x + x, center.y - y, center.z) //upper right right
|
||||
. += LOCATE_COORDS(center.x - x, center.y + y, center.z) //lower left left
|
||||
. += LOCATE_COORDS(center.x - y, center.y + x, center.z) //lower lower left
|
||||
. += LOCATE_COORDS(center.x + y, center.y + x, center.z) //lower lower right
|
||||
. += LOCATE_COORDS(center.x + x, center.y + y, center.z) //lower right right
|
||||
|
||||
if(p < 0)
|
||||
p += 4*x++ + 6;
|
||||
else
|
||||
p += 4*(x++ - y--) + 10;
|
||||
|
||||
#undef LOCATE_COORDS
|
||||
|
||||
//Returns whether or not a player is a guest using their ckey as an input
|
||||
/proc/IsGuestKey(key)
|
||||
if (findtext(key, "Guest-", 1, 7) != 1) //was findtextEx
|
||||
@@ -240,10 +270,10 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
return 1
|
||||
|
||||
//Ensure the frequency is within bounds of what it should be sending/recieving at
|
||||
/proc/sanitize_frequency(var/f)
|
||||
/proc/sanitize_frequency(var/f, var/low = PUBLIC_LOW_FREQ, var/high = PUBLIC_HIGH_FREQ)
|
||||
f = round(f)
|
||||
f = max(1441, f) // 144.1
|
||||
f = min(1489, f) // 148.9
|
||||
f = max(low, f)
|
||||
f = min(high, f)
|
||||
if ((f % 2) == 0) //Ensure the last digit is an odd number
|
||||
f += 1
|
||||
return f
|
||||
@@ -472,16 +502,6 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
// mob_list.Add(M)
|
||||
return moblist
|
||||
|
||||
//E = MC^2
|
||||
/proc/convert2energy(var/M)
|
||||
var/E = M*(SPEED_OF_LIGHT_SQ)
|
||||
return E
|
||||
|
||||
//M = E/C^2
|
||||
/proc/convert2mass(var/E)
|
||||
var/M = E/(SPEED_OF_LIGHT_SQ)
|
||||
return M
|
||||
|
||||
//Forces a variable to be posative
|
||||
/proc/modulus(var/M)
|
||||
if(M >= 0)
|
||||
@@ -572,11 +592,14 @@ proc/GaussRandRound(var/sigma,var/roundto)
|
||||
return toReturn
|
||||
|
||||
//Step-towards method of determining whether one atom can see another. Similar to viewers()
|
||||
/proc/can_see(var/atom/source, var/atom/target, var/length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate.
|
||||
/proc/can_see(var/atom/source, var/atom/target, var/length=5) // I couldn't be arsed to do actual raycasting :I This is horribly inaccurate.
|
||||
var/turf/current = get_turf(source)
|
||||
var/turf/target_turf = get_turf(target)
|
||||
var/steps = 0
|
||||
|
||||
if(!current || !target_turf)
|
||||
return 0
|
||||
|
||||
while(current != target_turf)
|
||||
if(steps > length) return 0
|
||||
if(current.opacity) return 0
|
||||
@@ -695,21 +718,6 @@ proc/GaussRandRound(var/sigma,var/roundto)
|
||||
if(istype(N, areatype)) areas += N
|
||||
return areas
|
||||
|
||||
//Takes: Area type as text string or as typepath OR an instance of the area.
|
||||
//Returns: A list of all turfs in areas of that type of that type in the world.
|
||||
/proc/get_area_turfs(var/areatype)
|
||||
if(!areatype) return null
|
||||
if(istext(areatype)) areatype = text2path(areatype)
|
||||
if(isarea(areatype))
|
||||
var/area/areatemp = areatype
|
||||
areatype = areatemp.type
|
||||
|
||||
var/list/turfs = new/list()
|
||||
for(var/area/N in world)
|
||||
if(istype(N, areatype))
|
||||
for(var/turf/T in N) turfs += T
|
||||
return turfs
|
||||
|
||||
//Takes: Area type as text string or as typepath OR an instance of the area.
|
||||
//Returns: A list of all atoms (objs, turfs, mobs) in areas of that type of that type in the world.
|
||||
/proc/get_area_all_atoms(var/areatype)
|
||||
@@ -784,11 +792,15 @@ proc/GaussRandRound(var/sigma,var/roundto)
|
||||
var/old_dir1 = T.dir
|
||||
var/old_icon_state1 = T.icon_state
|
||||
var/old_icon1 = T.icon
|
||||
var/old_overlays = T.overlays.Copy()
|
||||
var/old_underlays = T.underlays.Copy()
|
||||
|
||||
var/turf/X = B.ChangeTurf(T.type)
|
||||
X.set_dir(old_dir1)
|
||||
X.icon_state = old_icon_state1
|
||||
X.icon = old_icon1 //Shuttle floors are in shuttle.dmi while the defaults are floors.dmi
|
||||
X.overlays = old_overlays
|
||||
X.underlays = old_underlays
|
||||
|
||||
var/turf/simulated/ST = T
|
||||
if(istype(ST) && ST.zone)
|
||||
@@ -848,7 +860,7 @@ proc/GaussRandRound(var/sigma,var/roundto)
|
||||
if(turftoleave)
|
||||
fromupdate += T.ChangeTurf(turftoleave)
|
||||
else
|
||||
T.ChangeTurf(/turf/space)
|
||||
T.ChangeTurf(get_base_turf_by_area(T))
|
||||
|
||||
refined_src -= T
|
||||
refined_trg -= B
|
||||
@@ -931,9 +943,11 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
|
||||
var/old_dir1 = T.dir
|
||||
var/old_icon_state1 = T.icon_state
|
||||
var/old_icon1 = T.icon
|
||||
var/old_overlays = T.overlays.Copy()
|
||||
var/old_underlays = T.underlays.Copy()
|
||||
|
||||
if(platingRequired)
|
||||
if(istype(B, /turf/space))
|
||||
if(istype(B, get_base_turf_by_area(B)))
|
||||
continue moving
|
||||
|
||||
var/turf/X = B
|
||||
@@ -941,7 +955,8 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
|
||||
X.set_dir(old_dir1)
|
||||
X.icon_state = old_icon_state1
|
||||
X.icon = old_icon1 //Shuttle floors are in shuttle.dmi while the defaults are floors.dmi
|
||||
|
||||
X.overlays = old_overlays
|
||||
X.underlays = old_underlays
|
||||
|
||||
var/list/objs = new/list()
|
||||
var/list/newobjs = new/list()
|
||||
@@ -1050,12 +1065,10 @@ proc/get_mob_with_client_list()
|
||||
|
||||
//gets the turf the atom is located in (or itself, if it is a turf).
|
||||
//returns null if the atom is not in a turf.
|
||||
/proc/get_turf(atom/location)
|
||||
while(location)
|
||||
if(isturf(location))
|
||||
return location
|
||||
location = location.loc
|
||||
return null
|
||||
/proc/get_turf(atom/A)
|
||||
if(!istype(A)) return
|
||||
for(A, A && !isturf(A), A=A.loc);
|
||||
return A
|
||||
|
||||
/proc/get(atom/loc, type)
|
||||
while(loc)
|
||||
@@ -1193,6 +1206,9 @@ proc/is_hot(obj/item/W as obj)
|
||||
istype(W, /obj/item/weapon/bonesetter)
|
||||
)
|
||||
|
||||
/proc/is_borg_item(obj/item/W as obj)
|
||||
return W && W.loc && isrobot(W.loc)
|
||||
|
||||
//check if mob is lying down on something we can operate him on.
|
||||
/proc/can_operate(mob/living/carbon/M)
|
||||
return (M.lying && \
|
||||
@@ -1283,31 +1299,12 @@ var/list/WALLITEMS = list(
|
||||
colour += temp_col
|
||||
return colour
|
||||
|
||||
var/mob/dview/dview_mob = new
|
||||
|
||||
//Version of view() which ignores darkness, because BYOND doesn't have it.
|
||||
/proc/dview(var/range = world.view, var/center, var/invis_flags = 0)
|
||||
if(!center)
|
||||
return
|
||||
|
||||
dview_mob.loc = center
|
||||
|
||||
dview_mob.see_invisible = invis_flags
|
||||
|
||||
. = view(range, dview_mob)
|
||||
dview_mob.loc = null
|
||||
|
||||
/mob/dview
|
||||
invisibility = 101
|
||||
density = 0
|
||||
|
||||
anchored = 1
|
||||
simulated = 0
|
||||
|
||||
see_in_dark = 1e6
|
||||
|
||||
/mob/dview/New()
|
||||
// do nothing. we don't want to be in any mob lists; we're a dummy not a mob.
|
||||
/atom/proc/get_light_and_color(var/atom/origin)
|
||||
if(origin)
|
||||
color = origin.color
|
||||
set_light(origin.light_range, origin.light_power, origin.light_color)
|
||||
|
||||
//This is just so you can stop an orbit.
|
||||
//orbit() can run without it (swap orbiting for A)
|
||||
@@ -1367,6 +1364,35 @@ var/mob/dview/dview_mob = new
|
||||
/atom/movable/proc/stop_orbit()
|
||||
orbiting = null
|
||||
|
||||
/mob/dview/New()
|
||||
..()
|
||||
// We don't want to be in any mob lists; we're a dummy not a mob.
|
||||
mob_list -= src
|
||||
if(stat == DEAD)
|
||||
dead_mob_list -= src
|
||||
else
|
||||
living_mob_list -= src
|
||||
|
||||
// call to generate a stack trace and print to runtime logs
|
||||
/proc/crash_with(msg)
|
||||
CRASH(msg)
|
||||
|
||||
/atom/proc/find_up_hierarchy(var/atom/target)
|
||||
//This function will recurse up the hierarchy containing src, in search of the target
|
||||
//It will stop when it reaches an area, as areas have no loc
|
||||
var/x = 0//As a safety, we'll crawl up a maximum of ten layers
|
||||
var/atom/a = src
|
||||
while (x < 10)
|
||||
x++
|
||||
if (isnull(a))
|
||||
return 0
|
||||
|
||||
if (a == target)//we found it!
|
||||
return 1
|
||||
|
||||
if (istype(a, /area))
|
||||
return 0//Can't recurse any higher than this.
|
||||
|
||||
a = a.loc
|
||||
|
||||
return 0//If we get here, we must be buried many layers deep in nested containers. Shouldn't happen
|
||||
52
code/_macros.dm
Normal file
52
code/_macros.dm
Normal file
@@ -0,0 +1,52 @@
|
||||
#define Clamp(x, y, z) (x <= y ? y : (x >= z ? z : x))
|
||||
#define CLAMP01(x) (Clamp(x, 0, 1))
|
||||
|
||||
#define span(class, text) ("<span class='[class]'>[text]</span>")
|
||||
|
||||
#define isAI(A) istype(A, /mob/living/silicon/ai)
|
||||
#define isDrone(A) istype(A, /mob/living/silicon/robot/drone)
|
||||
|
||||
#define isalien(A) istype(A, /mob/living/carbon/alien)
|
||||
|
||||
#define isanimal(A) istype(A, /mob/living/simple_animal)
|
||||
|
||||
#define isairlock(A) istype(A, /obj/machinery/door/airlock)
|
||||
|
||||
#define isbrain(A) istype(A, /mob/living/carbon/brain)
|
||||
|
||||
#define iscarbon(A) istype(A, /mob/living/carbon)
|
||||
|
||||
#define iscorgi(A) istype(A, /mob/living/simple_animal/corgi)
|
||||
|
||||
#define isEye(A) istype(A, /mob/eye)
|
||||
|
||||
#define ishuman(A) istype(A, /mob/living/carbon/human)
|
||||
|
||||
#define isliving(A) istype(A, /mob/living)
|
||||
|
||||
#define ismouse(A) istype(A, /mob/living/simple_animal/mouse)
|
||||
|
||||
#define isnewplayer(A) istype(A, /mob/new_player)
|
||||
|
||||
#define isobj(A) istype(A, /obj)
|
||||
|
||||
#define isobserver(A) istype(A, /mob/dead/observer)
|
||||
|
||||
#define isorgan(A) istype(A, /obj/item/organ/external)
|
||||
|
||||
#define ispAI(A) istype(A, /mob/living/silicon/pai)
|
||||
|
||||
#define isrobot(A) istype(A, /mob/living/silicon/robot)
|
||||
|
||||
#define issilicon(A) istype(A, /mob/living/silicon)
|
||||
|
||||
#define isslime(A) istype(A, /mob/living/carbon/slime)
|
||||
|
||||
#define to_chat(target, message) target << message
|
||||
#define to_world(message) world << message
|
||||
#define sound_to(target, sound) target << sound
|
||||
#define to_file(file_entry, file_content) file_entry << file_content
|
||||
#define show_browser(target, browser_content, browser_name) target << browse(browser_content, browser_name)
|
||||
#define send_rsc(target, rsc_content, rsc_name) target << browse_rsc(rsc_content, rsc_name)
|
||||
|
||||
#define CanInteract(user, state) (CanUseTopic(user, state) == STATUS_INTERACTIVE)
|
||||
@@ -15,7 +15,6 @@
|
||||
return
|
||||
|
||||
if(control_disabled || stat) return
|
||||
next_move = world.time + 9
|
||||
|
||||
if(ismob(A))
|
||||
ai_actual_track(A)
|
||||
@@ -32,7 +31,7 @@
|
||||
build_click(src, client.buildmode, params, A)
|
||||
return
|
||||
|
||||
if(control_disabled || stat)
|
||||
if(stat)
|
||||
return
|
||||
|
||||
var/list/modifiers = params2list(params)
|
||||
@@ -52,9 +51,15 @@
|
||||
CtrlClickOn(A)
|
||||
return
|
||||
|
||||
if(world.time <= next_move)
|
||||
if(control_disabled || !canClick())
|
||||
return
|
||||
|
||||
if(multitool_mode && isobj(A))
|
||||
var/obj/O = A
|
||||
var/datum/expansion/multitool/MT = O.expansions[/datum/expansion/multitool]
|
||||
if(MT)
|
||||
MT.interact(aiMulti, src)
|
||||
return
|
||||
next_move = world.time + 9
|
||||
|
||||
if(aiCamera.in_camera_mode)
|
||||
aiCamera.camera_mode_off()
|
||||
@@ -91,13 +96,24 @@
|
||||
*/
|
||||
|
||||
/mob/living/silicon/ai/ShiftClickOn(var/atom/A)
|
||||
A.AIShiftClick(src)
|
||||
if(!control_disabled && A.AIShiftClick(src))
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/silicon/ai/CtrlClickOn(var/atom/A)
|
||||
A.AICtrlClick(src)
|
||||
if(!control_disabled && A.AICtrlClick(src))
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/silicon/ai/AltClickOn(var/atom/A)
|
||||
A.AIAltClick(src)
|
||||
if(!control_disabled && A.AIAltClick(src))
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/silicon/ai/MiddleClickOn(var/atom/A)
|
||||
A.AIMiddleClick(src)
|
||||
if(!control_disabled && A.AIMiddleClick(src))
|
||||
return
|
||||
..()
|
||||
|
||||
/*
|
||||
The following criminally helpful code is just the previous code cleaned up;
|
||||
@@ -107,61 +123,64 @@
|
||||
/atom/proc/AICtrlShiftClick()
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/AICtrlShiftClick()
|
||||
if(emagged)
|
||||
return
|
||||
return
|
||||
|
||||
/atom/proc/AIShiftClick()
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/AIShiftClick() // Opens and closes doors!
|
||||
if(density)
|
||||
Topic(src, list("src"= "\ref[src]", "command"="open", "activate" = "1"), 1) // 1 meaning no window (consistency!)
|
||||
Topic(src, list("command"="open", "activate" = "1"))
|
||||
else
|
||||
Topic(src, list("src"= "\ref[src]", "command"="open", "activate" = "0"), 1)
|
||||
return
|
||||
Topic(src, list("command"="open", "activate" = "0"))
|
||||
return 1
|
||||
|
||||
/atom/proc/AICtrlClick()
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/AICtrlClick() // Bolts doors
|
||||
if(locked)
|
||||
Topic(src, list("src"= "\ref[src]", "command"="bolts", "activate" = "0"), 1)// 1 meaning no window (consistency!)
|
||||
Topic(src, list("command"="bolts", "activate" = "0"))
|
||||
else
|
||||
Topic(src, list("src"= "\ref[src]", "command"="bolts", "activate" = "1"), 1)
|
||||
Topic(src, list("command"="bolts", "activate" = "1"))
|
||||
return 1
|
||||
|
||||
/obj/machinery/power/apc/AICtrlClick() // turns off/on APCs.
|
||||
Topic(src, list("src"= "\ref[src]", "breaker"="1"), 1) // 1 meaning no window (consistency!)
|
||||
Topic(src, list("breaker"="1"))
|
||||
return 1
|
||||
|
||||
/obj/machinery/turretid/AICtrlClick() //turns off/on Turrets
|
||||
Topic(src, list("src"= "\ref[src]", "command"="enable", "value"="[!enabled]"), 1) // 1 meaning no window (consistency!)
|
||||
Topic(src, list("command"="enable", "value"="[!enabled]"))
|
||||
return 1
|
||||
|
||||
/atom/proc/AIAltClick(var/atom/A)
|
||||
AltClick(A)
|
||||
return AltClick(A)
|
||||
|
||||
/obj/machinery/door/airlock/AIAltClick() // Electrifies doors.
|
||||
if(!electrified_until)
|
||||
// permanent shock
|
||||
Topic(src, list("src"= "\ref[src]", "command"="electrify_permanently", "activate" = "1"), 1) // 1 meaning no window (consistency!)
|
||||
Topic(src, list("command"="electrify_permanently", "activate" = "1"))
|
||||
else
|
||||
// disable/6 is not in Topic; disable/5 disables both temporary and permanent shock
|
||||
Topic(src, list("src"= "\ref[src]", "command"="electrify_permanently", "activate" = "0"), 1)
|
||||
return
|
||||
Topic(src, list("command"="electrify_permanently", "activate" = "0"))
|
||||
return 1
|
||||
|
||||
/obj/machinery/turretid/AIAltClick() //toggles lethal on turrets
|
||||
Topic(src, list("src"= "\ref[src]", "command"="lethal", "value"="[!lethal]"), 1) // 1 meaning no window (consistency!)
|
||||
Topic(src, list("command"="lethal", "value"="[!lethal]"))
|
||||
return 1
|
||||
|
||||
/atom/proc/AIMiddleClick()
|
||||
return
|
||||
/atom/proc/AIMiddleClick(var/mob/living/silicon/user)
|
||||
return 0
|
||||
|
||||
/obj/machinery/door/airlock/AIMiddleClick() // Toggles door bolt lights.
|
||||
if(!src.lights)
|
||||
Topic(src, list("src"= "\ref[src]", "command"="lights", "activate" = "1"), 1) // 1 meaning no window (consistency!)
|
||||
else
|
||||
Topic(src, list("src"= "\ref[src]", "command"="lights", "activate" = "0"), 1)
|
||||
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(!src.lights)
|
||||
Topic(src, list("command"="lights", "activate" = "1"))
|
||||
else
|
||||
Topic(src, list("command"="lights", "activate" = "0"))
|
||||
return 1
|
||||
|
||||
//
|
||||
// Override AdjacentQuick for AltClicking
|
||||
//
|
||||
|
||||
@@ -15,12 +15,16 @@
|
||||
|
||||
Note that this proc can be overridden, and is in the case of screen objects.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/atom/Click(location,control,params)
|
||||
if(src)
|
||||
usr.ClickOn(src, params)
|
||||
/atom/DblClick(location,control,params)
|
||||
|
||||
/atom/DblClick(var/location, var/control, var/params)
|
||||
if(src)
|
||||
usr.DblClickOn(src,params)
|
||||
usr.DblClickOn(src, params)
|
||||
|
||||
/*
|
||||
Standard mob ClickOn()
|
||||
@@ -35,9 +39,11 @@
|
||||
* item/afterattack(atom,user,adjacent,params) - used both ranged and adjacent
|
||||
* mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed
|
||||
*/
|
||||
/mob/proc/ClickOn( var/atom/A, var/params )
|
||||
if(world.time <= next_click)
|
||||
/mob/proc/ClickOn(var/atom/A, var/params)
|
||||
|
||||
if(world.time <= next_click) // Hard check, before anything else, to avoid crashing
|
||||
return
|
||||
|
||||
next_click = world.time + 1
|
||||
|
||||
if(client.buildmode)
|
||||
@@ -47,117 +53,114 @@
|
||||
var/list/modifiers = params2list(params)
|
||||
if(modifiers["shift"] && modifiers["ctrl"])
|
||||
CtrlShiftClickOn(A)
|
||||
return
|
||||
return 1
|
||||
if(modifiers["middle"])
|
||||
MiddleClickOn(A)
|
||||
return
|
||||
return 1
|
||||
if(modifiers["shift"])
|
||||
ShiftClickOn(A)
|
||||
return
|
||||
return 0
|
||||
if(modifiers["alt"]) // alt and alt-gr (rightalt)
|
||||
if (modifiers["right"])
|
||||
AltRightClickOn(A)
|
||||
else
|
||||
AltClickOn(A)
|
||||
return
|
||||
if(modifiers["ctrl"])
|
||||
CtrlClickOn(A)
|
||||
return
|
||||
return 1
|
||||
|
||||
if(stat || paralysis || stunned || weakened)
|
||||
return
|
||||
|
||||
face_atom(A) // change direction to face what you clicked on
|
||||
|
||||
if(next_move > world.time) // in the year 2000...
|
||||
if(!canClick()) // in the year 2000...
|
||||
return
|
||||
|
||||
if(istype(loc,/obj/mecha))
|
||||
if(!locate(/turf) in list(A,A.loc)) // Prevents inventory from being drilled
|
||||
if(istype(loc, /obj/mecha))
|
||||
if(!locate(/turf) in list(A, A.loc)) // Prevents inventory from being drilled
|
||||
return
|
||||
var/obj/mecha/M = loc
|
||||
return M.click_action(A,src)
|
||||
return M.click_action(A, src)
|
||||
|
||||
if(restrained())
|
||||
setClickCooldown(10)
|
||||
RestrainedClickOn(A)
|
||||
return
|
||||
return 1
|
||||
|
||||
if(in_throw_mode)
|
||||
if(isturf(A) || isturf(A.loc))
|
||||
throw_item(A)
|
||||
return
|
||||
return 1
|
||||
throw_mode_off()
|
||||
|
||||
if(!istype(A,/obj/item/weapon/gun) && !isturf(A) && !istype(A,/obj/screen))
|
||||
last_target_click = world.time
|
||||
|
||||
var/obj/item/W = get_active_hand()
|
||||
|
||||
if(W == A)
|
||||
next_move = world.time + 6
|
||||
if(W.flags&USEDELAY)
|
||||
next_move += 5
|
||||
if(W == A) // Handle attack_self
|
||||
W.attack_self(src)
|
||||
if(hand)
|
||||
update_inv_l_hand(0)
|
||||
else
|
||||
update_inv_r_hand(0)
|
||||
return 1
|
||||
|
||||
return
|
||||
|
||||
// operate two STORAGE levels deep here (item in backpack in src; NOT item in box in backpack in src)
|
||||
//Atoms on your person
|
||||
// A is your location but is not a turf; or is on you (backpack); or is on something on you (box in backpack); sdepth is needed here because contents depth does not equate inventory storage depth.
|
||||
var/sdepth = A.storage_depth(src)
|
||||
if(A == loc || (A in loc) || (sdepth != -1 && sdepth <= 1))
|
||||
|
||||
if((!isturf(A) && A == loc) || (sdepth != -1 && sdepth <= 1))
|
||||
// faster access to objects already on you
|
||||
if(A in contents)
|
||||
next_move = world.time + 6 // on your person
|
||||
else
|
||||
next_move = world.time + 8 // in a box/bag or in your square
|
||||
if(A.loc != src)
|
||||
setMoveCooldown(10) //getting something out of a backpack
|
||||
|
||||
// No adjacency needed
|
||||
if(W)
|
||||
if(W.flags&USEDELAY)
|
||||
next_move += 5
|
||||
|
||||
var/resolved = A.attackby(W,src)
|
||||
var/resolved = W.resolve_attackby(A, src)
|
||||
if(!resolved && A && W)
|
||||
W.afterattack(A,src,1,params) // 1 indicates adjacency
|
||||
W.afterattack(A, src, 1, params) // 1 indicates adjacency
|
||||
else
|
||||
if(ismob(A)) // No instant mob attacking
|
||||
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
UnarmedAttack(A, 1)
|
||||
return
|
||||
return 1
|
||||
|
||||
if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that
|
||||
return
|
||||
|
||||
// Allows you to click on a box's contents, if that box is on the ground, but no deeper than that
|
||||
//Atoms on turfs (not on your person)
|
||||
// A is a turf or is on a turf, or in something on a turf (pen in a box); but not something in something on a turf (pen in a box in a backpack)
|
||||
sdepth = A.storage_depth_turf()
|
||||
if(isturf(A) || isturf(A.loc) || (sdepth != -1 && sdepth <= 1))
|
||||
next_move = world.time + 10
|
||||
|
||||
if(A.Adjacent(src)) // see adjacent.dm
|
||||
if(W)
|
||||
if(W.flags&USEDELAY)
|
||||
next_move += 5
|
||||
setMoveCooldown(5)
|
||||
|
||||
if(W)
|
||||
// Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
|
||||
var/resolved = A.attackby(W,src)
|
||||
var/resolved = W.resolve_attackby(A,src)
|
||||
if(!resolved && A && W)
|
||||
W.afterattack(A,src,1,params) // 1: clicking something Adjacent
|
||||
W.afterattack(A, src, 1, params) // 1: clicking something Adjacent
|
||||
else
|
||||
if(ismob(A)) // No instant mob attacking
|
||||
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
UnarmedAttack(A, 1)
|
||||
return
|
||||
else // non-adjacent click
|
||||
if(W)
|
||||
W.afterattack(A,src,0,params) // 0: not Adjacent
|
||||
W.afterattack(A, src, 0, params) // 0: not Adjacent
|
||||
else
|
||||
RangedAttack(A, params)
|
||||
return 1
|
||||
|
||||
return
|
||||
/mob/proc/setClickCooldown(var/timeout)
|
||||
next_move = max(world.time + timeout, next_move)
|
||||
|
||||
/mob/proc/changeNext_move(num)
|
||||
next_move = world.time + num
|
||||
/mob/proc/canClick()
|
||||
if(config.no_click_cooldown || next_move <= world.time)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
// Default behavior: ignore double clicks, consider them normal clicks instead
|
||||
// Default behavior: ignore double clicks, the second click that makes the doubleclick call already calls for a normal click
|
||||
/mob/proc/DblClickOn(var/atom/A, var/params)
|
||||
ClickOn(A,params)
|
||||
return
|
||||
|
||||
/*
|
||||
Translates into attack_hand, etc.
|
||||
@@ -178,10 +181,6 @@
|
||||
src << "You cannot attack people before the game has started."
|
||||
return 0
|
||||
|
||||
if (istype(get_area(src), /area/start))
|
||||
src << "No attacking people at spawn, you jackass."
|
||||
return 0
|
||||
|
||||
if(stat)
|
||||
return 0
|
||||
|
||||
@@ -201,14 +200,12 @@
|
||||
LaserEyes(A) // moved into a proc below
|
||||
else if(TK in mutations)
|
||||
switch(get_dist(src,A))
|
||||
if(0)
|
||||
;
|
||||
if(1 to 5) // not adjacent may mean blocked by window
|
||||
next_move += 2
|
||||
setMoveCooldown(2)
|
||||
if(5 to 7)
|
||||
next_move += 5
|
||||
setMoveCooldown(5)
|
||||
if(8 to tk_maxrange)
|
||||
next_move += 10
|
||||
setMoveCooldown(10)
|
||||
else
|
||||
return
|
||||
A.attack_tk(src)
|
||||
@@ -226,23 +223,9 @@
|
||||
Only used for swapping hands
|
||||
*/
|
||||
/mob/proc/MiddleClickOn(var/atom/A)
|
||||
return
|
||||
|
||||
/mob/living/carbon/MiddleClickOn(var/atom/A)
|
||||
swap_hand()
|
||||
|
||||
/mob/living/carbon/human/MiddleClickOn(var/atom/A)
|
||||
|
||||
if(back)
|
||||
var/obj/item/weapon/rig/rig = back
|
||||
if(istype(rig) && rig.selected_module)
|
||||
if(world.time <= next_move) return
|
||||
next_move = world.time + 8
|
||||
rig.selected_module.engage(A)
|
||||
return
|
||||
|
||||
swap_hand()
|
||||
|
||||
// In case of use break glass
|
||||
/*
|
||||
/atom/proc/MiddleClick(var/mob/M as mob)
|
||||
@@ -292,7 +275,10 @@
|
||||
else
|
||||
user.listed_turf = T
|
||||
user.client.statpanel = "Turf"
|
||||
return
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
|
||||
/mob/proc/TurfAdjacent(var/turf/T)
|
||||
return T.AdjacentQuick(src)
|
||||
@@ -308,6 +294,31 @@
|
||||
/atom/proc/CtrlShiftClick(var/mob/user)
|
||||
return
|
||||
|
||||
/*
|
||||
Special Rightclick procs!
|
||||
set_context_menu_enabled is called by a macro defined in skin.dmf.
|
||||
It disables the menu when alt is pressed, and re-enables it when alt is released
|
||||
This allows us to do alt+rightclick to achieve something without opening the menu.
|
||||
These could also be duplicated/expanded as desired to suppress the menu with shift/ctrl as well
|
||||
|
||||
*/
|
||||
client/verb/set_context_menu_enabled(Enable as num)
|
||||
set hidden = TRUE, instant = TRUE
|
||||
if(Enable) show_popup_menus = TRUE
|
||||
else show_popup_menus = FALSE
|
||||
|
||||
/mob/proc/AltRightClickOn(var/atom/A)
|
||||
A.AltRightClick(src)
|
||||
return
|
||||
|
||||
/atom/proc/AltRightClick(var/mob/user)
|
||||
user.pointed(src)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Misc helpers
|
||||
|
||||
@@ -318,6 +329,7 @@
|
||||
return
|
||||
|
||||
/mob/living/LaserEyes(atom/A)
|
||||
setClickCooldown(4)
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
var/obj/item/projectile/beam/LE = new (T)
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
if(stat || lockcharge || weakened || stunned || paralysis)
|
||||
return
|
||||
|
||||
if(next_move >= world.time)
|
||||
if(!canClick())
|
||||
return
|
||||
|
||||
face_atom(A) // change direction to face what you clicked on
|
||||
@@ -68,19 +68,22 @@
|
||||
return
|
||||
|
||||
if(W == A)
|
||||
next_move = world.time + 8
|
||||
if(W.flags&USEDELAY)
|
||||
next_move += 5
|
||||
|
||||
W.attack_self(src)
|
||||
return
|
||||
|
||||
|
||||
//Handling using grippers
|
||||
if (istype(W, /obj/item/weapon/gripper))
|
||||
var/obj/item/weapon/gripper/G = W
|
||||
//If the gripper contains something, then we will use its contents to attack
|
||||
if (G.wrapped && (G.wrapped.loc == G))
|
||||
GripperClickOn(A, params, G)
|
||||
return
|
||||
|
||||
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents)
|
||||
if(A == loc || (A in loc) || (A in contents))
|
||||
// No adjacency checks
|
||||
next_move = world.time + 8
|
||||
if(W.flags&USEDELAY)
|
||||
next_move += 5
|
||||
|
||||
var/resolved = A.attackby(W,src)
|
||||
if(!resolved && A && W)
|
||||
@@ -93,20 +96,58 @@
|
||||
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc))
|
||||
if(isturf(A) || isturf(A.loc))
|
||||
if(A.Adjacent(src)) // see adjacent.dm
|
||||
next_move = world.time + 10
|
||||
if(W.flags&USEDELAY)
|
||||
next_move += 5
|
||||
|
||||
var/resolved = A.attackby(W, src)
|
||||
if(!resolved && A && W)
|
||||
W.afterattack(A, src, 1, params)
|
||||
return
|
||||
else
|
||||
next_move = world.time + 10
|
||||
W.afterattack(A, src, 0, params)
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
Gripper Handling
|
||||
This is used when a gripper is used on anything. It does all the handling for it
|
||||
*/
|
||||
/mob/living/silicon/robot/proc/GripperClickOn(var/atom/A, var/params, var/obj/item/weapon/gripper/G)
|
||||
|
||||
var/obj/item/W = G.wrapped
|
||||
if (!grippersafety(G))return
|
||||
|
||||
|
||||
G.force_holder = W.force
|
||||
W.force = 0
|
||||
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents)
|
||||
if(A == loc || (A in loc) || (A in contents))
|
||||
// No adjacency checks
|
||||
|
||||
var/resolved = A.attackby(W,src)
|
||||
if (!grippersafety(G))return
|
||||
if(!resolved && A && W)
|
||||
W.afterattack(A,src,1,params)
|
||||
if (!grippersafety(G))return
|
||||
W.force = G.force_holder
|
||||
return
|
||||
if(!isturf(loc))
|
||||
W.force = G.force_holder
|
||||
return
|
||||
|
||||
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc))
|
||||
if(isturf(A) || isturf(A.loc))
|
||||
if(A.Adjacent(src)) // see adjacent.dm
|
||||
var/resolved = A.attackby(W, src)
|
||||
if (!grippersafety(G))return
|
||||
if(!resolved && A && W)
|
||||
W.afterattack(A, src, 1, params)
|
||||
if (!grippersafety(G))return
|
||||
W.force = G.force_holder
|
||||
return
|
||||
//No non-adjacent clicks. Can't fire guns
|
||||
W.force = G.force_holder
|
||||
return
|
||||
|
||||
//Middle click cycles through selected modules.
|
||||
/mob/living/silicon/robot/MiddleClickOn(var/atom/A)
|
||||
cycle_modules()
|
||||
|
||||
@@ -13,120 +13,115 @@
|
||||
Therefore, the top right corner (except during admin shenanigans) is at "15,15"
|
||||
*/
|
||||
|
||||
//Upper left action buttons, displayed when you pick up an item that has this enabled.
|
||||
#define ui_action_slot1 "1:6,14:26"
|
||||
#define ui_action_slot2 "2:8,14:26"
|
||||
#define ui_action_slot3 "3:10,14:26"
|
||||
#define ui_action_slot4 "4:12,14:26"
|
||||
#define ui_action_slot5 "5:14,14:26"
|
||||
#define ui_entire_screen "WEST,SOUTH to EAST,NORTH"
|
||||
|
||||
//Lower left, persistant menu
|
||||
#define ui_inventory "1:6,1:5"
|
||||
#define ui_inventory "WEST:6,SOUTH:5"
|
||||
|
||||
//Lower center, persistant menu
|
||||
#define ui_sstore1 "3:10,1:5"
|
||||
#define ui_id "4:12,1:5"
|
||||
#define ui_belt "5:14,1:5"
|
||||
#define ui_back "6:14,1:5"
|
||||
#define ui_rhand "7:16,1:5"
|
||||
#define ui_lhand "8:16,1:5"
|
||||
#define ui_equip "7:16,2:5"
|
||||
#define ui_swaphand1 "7:16,2:5"
|
||||
#define ui_swaphand2 "8:16,2:5"
|
||||
#define ui_storage1 "9:18,1:5"
|
||||
#define ui_storage2 "10:20,1:5"
|
||||
#define ui_sstore1 "WEST+2:10,SOUTH:5"
|
||||
#define ui_id "WEST+3:12,SOUTH:5"
|
||||
#define ui_belt "WEST+4:14,SOUTH:5"
|
||||
#define ui_back "CENTER-2:14,SOUTH:5"
|
||||
#define ui_rhand "CENTER-1:16,SOUTH:5"
|
||||
#define ui_lhand "CENTER:16,SOUTH:5"
|
||||
#define ui_equip "CENTER-1:16,SOUTH+1:5"
|
||||
#define ui_swaphand1 "CENTER-1:16,SOUTH+1:5"
|
||||
#define ui_swaphand2 "CENTER:16,SOUTH+1:5"
|
||||
#define ui_storage1 "CENTER+1:16,SOUTH:5"
|
||||
#define ui_storage2 "CENTER+2:16,SOUTH:5"
|
||||
|
||||
#define ui_alien_head "4:12,1:5" //aliens
|
||||
#define ui_alien_oclothing "5:14,1:5" //aliens
|
||||
#define ui_alien_head "CENTER-3:12,SOUTH:5" //aliens
|
||||
#define ui_alien_oclothing "CENTER-2:14,SOUTH:5"//aliens
|
||||
|
||||
#define ui_inv1 "7,1:5" //borgs
|
||||
#define ui_inv2 "8,1:5" //borgs
|
||||
#define ui_inv3 "9,1:5" //borgs
|
||||
#define ui_borg_store "10,1:5" //borgs
|
||||
#define ui_borg_inventory "6,1:5"//borgs
|
||||
#define ui_inv1 "CENTER-1,SOUTH:5" //borgs
|
||||
#define ui_inv2 "CENTER,SOUTH:5" //borgs
|
||||
#define ui_inv3 "CENTER+1,SOUTH:5" //borgs
|
||||
#define ui_borg_store "CENTER+2,SOUTH:5" //borgs
|
||||
#define ui_borg_inventory "CENTER-2,SOUTH:5"//borgs
|
||||
|
||||
#define ui_monkey_mask "5:14,1:5" //monkey
|
||||
#define ui_monkey_back "6:14,1:5" //monkey
|
||||
#define ui_monkey_mask "WEST+4:14,SOUTH:5" //monkey
|
||||
#define ui_monkey_back "WEST+5:14,SOUTH:5" //monkey
|
||||
|
||||
#define ui_construct_health "15:00,7:15" //same height as humans, hugging the right border
|
||||
#define ui_construct_purge "15:00,6:15"
|
||||
#define ui_construct_fire "14:16,8:13" //above health, slightly to the left
|
||||
#define ui_construct_pull "14:28,2:10" //above the zone_sel icon
|
||||
#define ui_construct_health "EAST:00,CENTER:15" //same height as humans, hugging the right border
|
||||
#define ui_construct_purge "EAST:00,CENTER-1:15"
|
||||
#define ui_construct_fire "EAST-1:16,CENTER+1:13" //above health, slightly to the left
|
||||
#define ui_construct_pull "EAST-1:28,SOUTH+1:10" //above the zone_sel icon
|
||||
|
||||
//Lower right, persistant menu
|
||||
#define ui_dropbutton "11:22,1:5"
|
||||
#define ui_drop_throw "14:28,2:7"
|
||||
#define ui_pull_resist "13:26,2:7"
|
||||
#define ui_acti "13:26,1:5"
|
||||
#define ui_movi "12:24,1:5"
|
||||
#define ui_zonesel "14:28,1:5"
|
||||
#define ui_acti_alt "14:28,1:5" //alternative intent switcher for when the interface is hidden (F12)
|
||||
#define ui_dropbutton "EAST-4:22,SOUTH:5"
|
||||
#define ui_drop_throw "EAST-1:28,SOUTH+1:7"
|
||||
#define ui_pull_resist "EAST-2:26,SOUTH+1:7"
|
||||
#define ui_acti "EAST-2:26,SOUTH:5"
|
||||
#define ui_movi "EAST-3:24,SOUTH:5"
|
||||
#define ui_zonesel "EAST-1:28,SOUTH:5"
|
||||
#define ui_acti_alt "EAST-1:28,SOUTH:5" //alternative intent switcher for when the interface is hidden (F12)
|
||||
|
||||
#define ui_borg_pull "12:24,2:7"
|
||||
#define ui_borg_module "13:26,2:7"
|
||||
#define ui_borg_panel "14:28,2:7"
|
||||
#define ui_borg_pull "EAST-3:24,SOUTH+1:7"
|
||||
#define ui_borg_module "EAST-2:26,SOUTH+1:7"
|
||||
#define ui_borg_panel "EAST-1:28,SOUTH+1:7"
|
||||
|
||||
//Gun buttons
|
||||
#define ui_gun1 "13:26,3:7"
|
||||
#define ui_gun2 "14:28, 4:7"
|
||||
#define ui_gun3 "13:26,4:7"
|
||||
#define ui_gun_select "14:28,3:7"
|
||||
#define ui_gun4 "12:24,3:7"
|
||||
#define ui_gun1 "EAST-2:26,SOUTH+2:7"
|
||||
#define ui_gun2 "EAST-1:28, SOUTH+3:7"
|
||||
#define ui_gun3 "EAST-2:26,SOUTH+3:7"
|
||||
#define ui_gun_select "EAST-1:28,SOUTH+2:7"
|
||||
#define ui_gun4 "EAST-3:24,SOUTH+2:7"
|
||||
|
||||
//Upper-middle right (damage indicators)
|
||||
#define ui_toxin "14:28,13:27"
|
||||
#define ui_fire "14:28,12:25"
|
||||
#define ui_oxygen "14:28,11:23"
|
||||
#define ui_pressure "14:28,10:21"
|
||||
#define ui_toxin "EAST-1:28,NORTH-2:27"
|
||||
#define ui_fire "EAST-1:28,NORTH-3:25"
|
||||
#define ui_oxygen "EAST-1:28,NORTH-4:23"
|
||||
#define ui_pressure "EAST-1:28,NORTH-5:21"
|
||||
|
||||
#define ui_alien_toxin "14:28,13:25"
|
||||
#define ui_alien_fire "14:28,12:25"
|
||||
#define ui_alien_oxygen "14:28,11:25"
|
||||
#define ui_alien_toxin "EAST-1:28,NORTH-2:25"
|
||||
#define ui_alien_fire "EAST-1:28,NORTH-3:25"
|
||||
#define ui_alien_oxygen "EAST-1:28,NORTH-4:25"
|
||||
|
||||
//Middle right (status indicators)
|
||||
#define ui_nutrition "14:28,5:11"
|
||||
#define ui_temp "14:28,6:13"
|
||||
#define ui_health "14:28,7:15"
|
||||
#define ui_internal "14:28,8:17"
|
||||
#define ui_nutrition "EAST-1:28,CENTER-2:11"
|
||||
#define ui_temp "EAST-1:28,CENTER-1:13"
|
||||
#define ui_health "EAST-1:28,CENTER:15"
|
||||
#define ui_internal "EAST-1:28,CENTER+1:17"
|
||||
//borgs
|
||||
#define ui_borg_health "14:28,6:13" //borgs have the health display where humans have the pressure damage indicator.
|
||||
#define ui_alien_health "14:28,6:13" //aliens have the health display where humans have the pressure damage indicator.
|
||||
#define ui_borg_health "EAST-1:28,CENTER-1:13" //borgs have the health display where humans have the pressure damage indicator.
|
||||
#define ui_alien_health "EAST-1:28,CENTER-1:13" //aliens have the health display where humans have the pressure damage indicator.
|
||||
|
||||
//Pop-up inventory
|
||||
#define ui_shoes "2:8,1:5"
|
||||
#define ui_shoes "WEST+1:8,SOUTH:5"
|
||||
|
||||
#define ui_iclothing "1:6,2:7"
|
||||
#define ui_oclothing "2:8,2:7"
|
||||
#define ui_gloves "3:10,2:7"
|
||||
#define ui_iclothing "WEST:6,SOUTH+1:7"
|
||||
#define ui_oclothing "WEST+1:8,SOUTH+1:7"
|
||||
#define ui_gloves "WEST+2:10,SOUTH+1:7"
|
||||
|
||||
#define ui_glasses "1:6,3:9"
|
||||
#define ui_mask "2:8,3:9"
|
||||
#define ui_l_ear "3:10,3:9"
|
||||
#define ui_r_ear "3:10,4:11"
|
||||
#define ui_glasses "WEST:6,SOUTH+2:9"
|
||||
#define ui_mask "WEST+1:8,SOUTH+2:9"
|
||||
#define ui_l_ear "WEST+2:10,SOUTH+2:9"
|
||||
#define ui_r_ear "WEST+2:10,SOUTH+3:11"
|
||||
|
||||
#define ui_head "2:8,4:11"
|
||||
#define ui_head "WEST+1:8,SOUTH+3:11"
|
||||
|
||||
//Intent small buttons
|
||||
#define ui_help_small "12:8,1:1"
|
||||
#define ui_disarm_small "12:15,1:18"
|
||||
#define ui_grab_small "12:32,1:18"
|
||||
#define ui_harm_small "12:39,1:1"
|
||||
#define ui_help_small "EAST-3:8,SOUTH:1"
|
||||
#define ui_disarm_small "EAST-3:15,SOUTH:18"
|
||||
#define ui_grab_small "EAST-3:32,SOUTH:18"
|
||||
#define ui_harm_small "EAST-3:39,SOUTH:1"
|
||||
|
||||
//#define ui_swapbutton "6:-16,1:5" //Unused
|
||||
|
||||
//#define ui_headset "SOUTH,8"
|
||||
#define ui_hand "6:14,1:5"
|
||||
#define ui_hstore1 "5,5"
|
||||
#define ui_hand "CENTER-1:14,SOUTH:5"
|
||||
#define ui_hstore1 "CENTER-2,CENTER-2"
|
||||
//#define ui_resist "EAST+1,SOUTH-1"
|
||||
#define ui_sleep "EAST+1, NORTH-13"
|
||||
#define ui_rest "EAST+1, NORTH-14"
|
||||
|
||||
|
||||
#define ui_iarrowleft "SOUTH-1,11"
|
||||
#define ui_iarrowright "SOUTH-1,13"
|
||||
#define ui_iarrowleft "SOUTH-1,EAST-4"
|
||||
#define ui_iarrowright "SOUTH-1,EAST-2"
|
||||
|
||||
#define ui_spell_master "14:16,14:16"
|
||||
#define ui_genetic_master "14:16,12:16"
|
||||
#define ui_spell_master "EAST-1:16,NORTH-1:16"
|
||||
#define ui_genetic_master "EAST-1:16,NORTH-3:16"
|
||||
|
||||
// AI
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user