mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-27 22:17:32 +01:00
Merge branch 'master' into client-hud-consistency
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
# dmdoc
|
||||
[DOCUMENTATION]: https://codedocs.paradisestation.org/
|
||||
|
||||
[BYOND]: https://secure.byond.com/
|
||||
|
||||
[DMDOC]: https://github.com/AffectedArc07/ParaSpacemanDMM/tree/master/src/dmdoc
|
||||
|
||||
[DMDOC] is a documentation generator for DreamMaker, the scripting language
|
||||
of the [BYOND] game engine. It produces simple static HTML files based on
|
||||
documented files, macros, types, procs, and vars.
|
||||
|
||||
We use **dmdoc** to generate [DOCUMENTATION] for our code, and that documentation
|
||||
is automatically generated and built on every new commit to the master branch
|
||||
|
||||
This gives new developers a clickable reference [DOCUMENTATION] they can browse to better help
|
||||
gain understanding of the Paradise codebase structure and api reference.
|
||||
|
||||
## Documenting code on Paradise
|
||||
We use block comments to document procs and classes, and we use `///` line comments
|
||||
when documenting individual variables.
|
||||
|
||||
Documentation is not required at Paradise, but it is highly recommended that all new code be covered with DMdoc code, according to the [Specifications](#Specification)
|
||||
|
||||
We also recommend that when you touch older code, you document the functions that you
|
||||
have touched in the process of updating that code
|
||||
|
||||
### Specification
|
||||
A class *should* always be autodocumented, and all public functions *should* be documented
|
||||
|
||||
All class level defined variables *should* be documented
|
||||
|
||||
Internal functions *can* be documented, but may not be
|
||||
|
||||
A public function is any function that a developer might reasonably call while using
|
||||
or interacting with your object. Internal functions are helper functions that your
|
||||
public functions rely on to implement logic
|
||||
|
||||
|
||||
### Documenting a proc
|
||||
When documenting a proc, we give a short one line description (as this is shown
|
||||
next to the proc definition in the list of all procs for a type or global
|
||||
namespace), then a longer paragraph which will be shown when the user clicks on
|
||||
the proc to jump to it's definition
|
||||
```
|
||||
/**
|
||||
* Short description of the proc
|
||||
*
|
||||
* Longer detailed paragraph about the proc
|
||||
* including any relevant detail
|
||||
* Arguments:
|
||||
* * arg1 - Relevance of this argument
|
||||
* * arg2 - Relevance of this argument
|
||||
*/
|
||||
```
|
||||
|
||||
### Documenting a class
|
||||
We first give the name of the class as a header, this can be omitted if the name is
|
||||
just going to be the typepath of the class, as dmdoc uses that by default
|
||||
|
||||
Then we give a short oneline description of the class
|
||||
|
||||
Finally we give a longer multi paragraph description of the class and it's details
|
||||
```
|
||||
/**
|
||||
* # Classname (Can be omitted if it's just going to be the typepath)
|
||||
*
|
||||
* The short overview
|
||||
*
|
||||
* A longer
|
||||
* paragraph of functionality about the class
|
||||
* including any assumptions/special cases
|
||||
*
|
||||
*/
|
||||
```
|
||||
|
||||
### Documenting a variable/define
|
||||
Give a short explanation of what the variable, in the context of the class, or define is.
|
||||
```
|
||||
/// Type path of item to go in suit slot
|
||||
var/suit = null
|
||||
```
|
||||
|
||||
## Module level description of code
|
||||
Modules are the best way to describe the structure/intent of a package of code
|
||||
where you don't want to be tied to the formal layout of the class structure.
|
||||
|
||||
On Paradise we do this by adding markdown files inside the `code` directory
|
||||
that will also be rendered and added to the modules tree. The structure for
|
||||
these is deliberately not defined, so you can be as freeform and as wheeling as
|
||||
you would like.
|
||||
|
||||
[Here is a representative example of what you might write](https://codedocs.paradisestation.org/code/modules/keybindings/readme.html)
|
||||
|
||||
## Special variables
|
||||
You can use certain special template variables in DM DOC comments and they will be expanded
|
||||
```
|
||||
[DEFINE_NAME] - Expands to a link to the define definition if documented
|
||||
[/mob] - Expands to a link to the docs for the /mob class
|
||||
[/mob/proc/Dizzy] - Expands to a link that will take you to the /mob class and anchor you to the dizzy proc docs
|
||||
[/mob/var/stat] - Expands to a link that will take you to the /mob class and anchor you to the stat var docs
|
||||
```
|
||||
|
||||
You can customise the link name by using `[link name][link shorthand].`
|
||||
|
||||
eg. `[see more about dizzy here] [/mob/proc/Dizzy]`
|
||||
|
||||
This is very useful to quickly link to other parts of the autodoc code to expand
|
||||
upon a comment made, or reasoning about code
|
||||
+42
-41
@@ -36,13 +36,13 @@ actual development.
|
||||
Due to limitations of the engine, this may not always be possible; but do try your best.
|
||||
|
||||
* Document and explain your pull requests thoroughly. Failure to do so will delay a PR as
|
||||
we question why changes were made. This is especially important if you're porting a PR
|
||||
we question why changes were made. This is especially important if you're porting a PR
|
||||
from another codebase (i.e. TG) and divert from the original. Explaining with single
|
||||
comment on why you've made changes will help us review the PR faster and understand your
|
||||
decision making process.
|
||||
|
||||
* Any pull request must have a changelog, this is to allow us to know when a PR is deployed
|
||||
on the live server. Inline changelogs are supported through the format described
|
||||
* Any pull request must have a changelog, this is to allow us to know when a PR is deployed
|
||||
on the live server. Inline changelogs are supported through the format described
|
||||
[here](https://github.com/ParadiseSS13/Paradise/pull/3291#issuecomment-172950466)
|
||||
and should be used rather than manually edited .yml file changelogs.
|
||||
|
||||
@@ -51,14 +51,14 @@ actual development.
|
||||
commits. Use `git rebase` or `git reset` to update your branches, not `git pull`.
|
||||
|
||||
* Please explain why you are submitting the pull request, and how you think your change will be beneficial to the game. Failure to do so will be grounds for rejecting the PR.
|
||||
|
||||
|
||||
* If your pull request is not finished make sure it is at least testable in a live environment. Pull requests that do not at least meet this requirement may be closed at maintainer discretion. You may request a maintainer reopen the pull request when you're ready, or make a new one.
|
||||
|
||||
* While we have no issue helping contributors (and especially new contributors) bring reasonably sized contributions up to standards via the pull request review process, larger contributions are expected to pass a higher bar of completeness and code quality *before* you open a pull request. Maintainers may close such pull requests that are deemed to be substantially flawed. You should take some time to discuss with maintainers or other contributors on how to improve the changes.
|
||||
* While we have no issue helping contributors (and especially new contributors) bring reasonably sized contributions up to standards via the pull request review process, larger contributions are expected to pass a higher bar of completeness and code quality *before* you open a pull request. Maintainers may close such pull requests that are deemed to be substantially flawed. You should take some time to discuss with maintainers or other contributors on how to improve the changes.
|
||||
|
||||
#### Using Changelog
|
||||
* Tags used in changelog include add/rscadd, del/rscdel, fix/fixes, typo/spellcheck.
|
||||
* Without specifying a name it will default to using your GitHub name.
|
||||
* Tags used in changelog include add/rscadd, del/rscdel, fix/fixes, typo/spellcheck.
|
||||
* Without specifying a name it will default to using your GitHub name.
|
||||
Some examples
|
||||
```
|
||||
:cl:
|
||||
@@ -76,11 +76,11 @@ typo: Fixes some misspelled words under Using Changelog
|
||||
|
||||
## Specifications
|
||||
|
||||
As mentioned before, you are expected to follow these specifications in order to make everyone's lives easier. It'll save both your time and ours, by making
|
||||
As mentioned before, you are expected to follow these specifications in order to make everyone's lives easier. It'll save both your time and ours, by making
|
||||
sure you don't have to make any changes and we don't have to ask you to. Thank you for reading this section!
|
||||
|
||||
### Object Oriented Code
|
||||
As BYOND's Dream Maker (henceforth "DM") is an object-oriented language, code must be object-oriented when possible in order to be more flexible when adding
|
||||
As BYOND's Dream Maker (henceforth "DM") is an object-oriented language, code must be object-oriented when possible in order to be more flexible when adding
|
||||
content to it. If you don't know what "object-oriented" means, we highly recommend you do some light research to grasp the basics.
|
||||
|
||||
### All BYOND paths must contain the full path
|
||||
@@ -113,7 +113,7 @@ datum
|
||||
code
|
||||
```
|
||||
|
||||
The use of this is not allowed in this project *unless the majority of the file is already relatively pathed* as it makes finding definitions via full text
|
||||
The use of this is not allowed in this project *unless the majority of the file is already relatively pathed* as it makes finding definitions via full text
|
||||
searching next to impossible. The only exception is the variables of an object may be nested to the object, but must not nest further.
|
||||
|
||||
The previous code made compliant:
|
||||
@@ -167,7 +167,7 @@ ever forming.
|
||||
|
||||
```DM
|
||||
//Good
|
||||
var/atom/A
|
||||
var/atom/A
|
||||
"[A]"
|
||||
|
||||
//Bad
|
||||
@@ -177,7 +177,7 @@ var/atom/A
|
||||
### Use the pronoun library instead of `\his` macros.
|
||||
We have a system in code/\_\_HELPERS/pronouns.dm for addressing all forms of pronouns. This is useful in a number of ways;
|
||||
* BYOND's \his macro can be unpredictable on what object it references.
|
||||
Take this example: `"[user] waves \his [user.weapon] around, hitting \his opponents!"`.
|
||||
Take this example: `"[user] waves \his [user.weapon] around, hitting \his opponents!"`.
|
||||
This will end up referencing the user's gender in the first occurence, but what about the second?
|
||||
It'll actually print the gender set on the weapon he's carrying, which is unintended - and there's no way around this.
|
||||
* It always prints the real `gender` variable of the atom it's referencing. This can lead to exposing a mob's gender even when their face is covered,
|
||||
@@ -217,7 +217,7 @@ You must use tabs to indent your code, NOT SPACES.
|
||||
Hacky code, such as adding specific checks (ex: `istype(src, /obj/whatever)`), is highly discouraged and only allowed when there is ***no*** other option. (
|
||||
Protip: 'I couldn't immediately think of a proper way so thus there must be no other option' is not gonna cut it here! If you can't think of anything else, say that outright and admit that you need help with it. Maintainers exist for exactly that reason.)
|
||||
|
||||
You can avoid hacky code by using object-oriented methodologies, such as overriding a function (called "procs" in DM) or sectioning code into functions and
|
||||
You can avoid hacky code by using object-oriented methodologies, such as overriding a function (called "procs" in DM) or sectioning code into functions and
|
||||
then overriding them as required.
|
||||
|
||||
The same also applies to bugfix - If an invalid value is being passed into a proc from something that shouldn't have that value, don't fix it on the proc itself, fix it at its origin! (Where feasible)
|
||||
@@ -239,15 +239,15 @@ There are two key points here:
|
||||
Remember: although this tradeoff makes sense in many cases, it doesn't cover them all. Think carefully about your addition before deciding if you need to use it.
|
||||
|
||||
### Prefer `Initialize()` over `New()` for atoms
|
||||
Our game controller is pretty good at handling long operations and lag, but it can't control what happens when the map is loaded, which calls `New` for all atoms on the map. If you're creating a new atom, use the `Initialize` proc to do what you would normally do in `New`. This cuts down on the number of proc calls needed when the world is loaded.
|
||||
Our game controller is pretty good at handling long operations and lag, but it can't control what happens when the map is loaded, which calls `New` for all atoms on the map. If you're creating a new atom, use the `Initialize` proc to do what you would normally do in `New`. This cuts down on the number of proc calls needed when the world is loaded.
|
||||
|
||||
While we normally encourage (and in some cases, even require) bringing out of date code up to date when you make unrelated changes near the out of date code, that is not the case for `New` -> `Initialize` conversions. These systems are generally more dependant on parent and children procs so unrelated random conversions of existing things can cause bugs that take months to figure out.
|
||||
|
||||
### No implicit var/
|
||||
When you declare a parameter in a proc, the var/ is implicit. Do not include any implicit var/ when declaring a variable.
|
||||
|
||||
I.e.
|
||||
Bad:
|
||||
I.e.
|
||||
Bad:
|
||||
````
|
||||
obj/item/proc1(var/input1, var/input2)
|
||||
````
|
||||
@@ -258,7 +258,7 @@ obj/item/proc1(input1, input2)
|
||||
````
|
||||
|
||||
### No magic numbers or strings
|
||||
This means stuff like having a "mode" variable for an object set to "1" or "2" with no clear indicator of what that means. Make these #defines with a name that
|
||||
This means stuff like having a "mode" variable for an object set to "1" or "2" with no clear indicator of what that means. Make these #defines with a name that
|
||||
more clearly states what it's for. For instance:
|
||||
````DM
|
||||
/datum/proc/do_the_thing(thing_to_do)
|
||||
@@ -285,10 +285,10 @@ This is clearer and enhances readability of your code! Get used to doing it!
|
||||
(if, while, for, etc)
|
||||
|
||||
* All control statements must not contain code on the same line as the statement (`if(condition) return`)
|
||||
* All control statements comparing a variable to a number should use the formula of `thing` `operator` `number`, not the reverse
|
||||
* All control statements comparing a variable to a number should use the formula of `thing` `operator` `number`, not the reverse
|
||||
(eg: `if(count <= 10)` not `if(10 >= count)`)
|
||||
* All control statements must be spaced as `if()`, with the brackets touching the keyword.
|
||||
* Do not use one-line control statements.
|
||||
* All control statements must be spaced as `if()`, with the brackets touching the keyword.
|
||||
* Do not use one-line control statements.
|
||||
Instead of doing
|
||||
```
|
||||
if(x) return
|
||||
@@ -305,7 +305,7 @@ you must use `to_chat(mob/client/world, "message")`. Failure to do so will lead
|
||||
|
||||
### Use early return
|
||||
Do not enclose a proc in an if-block when returning on a condition is more feasible.
|
||||
|
||||
|
||||
This is bad:
|
||||
````DM
|
||||
/datum/datum1/proc/proc1()
|
||||
@@ -329,11 +329,11 @@ This prevents nesting levels from getting deeper then they need to be.
|
||||
|
||||
### Uses addtimer() instead of sleep() or spawn()
|
||||
If you need to call a proc after a set amount of time, use addtimer() instead of spawn() / sleep() where feasible.
|
||||
Although it is more complex, it is more performant and unlike spawn() or sleep(), it can be cancelled.
|
||||
Although it is more complex, it is more performant and unlike spawn() or sleep(), it can be cancelled.
|
||||
For more details, see https://github.com/tgstation/tgstation/pull/22933.
|
||||
|
||||
Look for code example on how to properly use it.
|
||||
|
||||
|
||||
This is bad:
|
||||
````DM
|
||||
/datum/datum1/proc/proc1()
|
||||
@@ -369,13 +369,13 @@ This prevents nesting levels from getting deeper then they need to be.
|
||||
|
||||
#### Bitflags
|
||||
* We prefer using bitshift operators instead of directly typing out the value. I.E.
|
||||
```
|
||||
```
|
||||
#define MACRO_ONE (1<<0)
|
||||
#define MACRO_TWO (1<<1)
|
||||
#define MACRO_THREE (1<<2)
|
||||
```
|
||||
Is preferable to
|
||||
```
|
||||
```
|
||||
#define MACRO_ONE 1
|
||||
#define MACRO_TWO 2
|
||||
#define MACRO_THREE 4
|
||||
@@ -455,7 +455,7 @@ SS13 has a lot of legacy code that's never been updated. Here are some examples
|
||||
|
||||
* All changes to the database's layout(schema) must be specified in the database changelog in SQL, as well as reflected in the schema files
|
||||
|
||||
* Any time the schema is changed the `DB_MAJOR_VERSION` defines must be incremented, as well as the example config, with an appropriate conversion kit placed
|
||||
* Any time the schema is changed the `DB_MAJOR_VERSION` defines must be incremented, as well as the example config, with an appropriate conversion kit placed
|
||||
in the SQL/updates folder.
|
||||
|
||||
* Queries must never specify the database, be it in code, or in text files in the repo.
|
||||
@@ -463,7 +463,7 @@ in the SQL/updates folder.
|
||||
### Mapping Standards
|
||||
* Map Merge
|
||||
* You MUST run Map Merge prior to opening your PR when updating existing maps to minimize the change differences (even when using third party mapping programs such as FastDMM.)
|
||||
* Failure to run Map Merge on a map after using third party mapping programs (such as FastDMM) greatly increases the risk of the map's key dictionary
|
||||
* Failure to run Map Merge on a map after using third party mapping programs (such as FastDMM) greatly increases the risk of the map's key dictionary
|
||||
becoming corrupted by future edits after running map merge. Resolving the corruption issue involves rebuilding the map's key dictionary;
|
||||
|
||||
* Variable Editing (Var-edits)
|
||||
@@ -487,12 +487,12 @@ in the SQL/updates folder.
|
||||
Like all languages, Dream Maker has its quirks, some of them are beneficial to us, like these
|
||||
|
||||
#### In-To for-loops
|
||||
```for(var/i = 1, i <= some_value, i++)``` is a fairly standard way to write an incremental for loop in most languages (especially those in the C family), but
|
||||
```for(var/i = 1, i <= some_value, i++)``` is a fairly standard way to write an incremental for loop in most languages (especially those in the C family), but
|
||||
DM's ```for(var/i in 1 to some_value)``` syntax is oddly faster than its implementation of the former syntax; where possible, it's advised to use DM's syntax. (
|
||||
Note, the ```to``` keyword is inclusive, so it automatically defaults to replacing ```<=```; if you want ```<``` then you should write it as ```1 to
|
||||
Note, the ```to``` keyword is inclusive, so it automatically defaults to replacing ```<=```; if you want ```<``` then you should write it as ```1 to
|
||||
some_value-1```).
|
||||
|
||||
HOWEVER, if either ```some_value``` or ```i``` changes within the body of the for (underneath the ```for(...)``` header) or if you are looping over a list AND
|
||||
HOWEVER, if either ```some_value``` or ```i``` changes within the body of the for (underneath the ```for(...)``` header) or if you are looping over a list AND
|
||||
changing the length of the list then you can NOT use this type of for-loop!
|
||||
|
||||
### for(var/A in list) VS for(var/i in 1 to list.len)
|
||||
@@ -510,9 +510,9 @@ for(var/obj/item/sword/S in bag_of_items)
|
||||
if(!best_sword || S.damage > best_sword.damage)
|
||||
best_sword = S
|
||||
```
|
||||
The above is a simple proc for checking all swords in a container and returning the one with the highest damage, and it uses DM's standard syntax for a
|
||||
for-loop by specifying a type in the variable of the for's header that DM interprets as a type to filter by. It performs this filter using ```istype()``` (or
|
||||
some internal-magic similar to ```istype()``` - this is BYOND, after all). This is fine in its current state for ```bag_of_items```, but if ```bag_of_items```
|
||||
The above is a simple proc for checking all swords in a container and returning the one with the highest damage, and it uses DM's standard syntax for a
|
||||
for-loop by specifying a type in the variable of the for's header that DM interprets as a type to filter by. It performs this filter using ```istype()``` (or
|
||||
some internal-magic similar to ```istype()``` - this is BYOND, after all). This is fine in its current state for ```bag_of_items```, but if ```bag_of_items```
|
||||
contained ONLY swords, or only SUBTYPES of swords, then the above is inefficient. For example:
|
||||
```DM
|
||||
var/list/bag_of_swords = list(sword, sword, sword, sword)
|
||||
@@ -521,10 +521,10 @@ for(var/obj/item/sword/S in bag_of_swords)
|
||||
if(!best_sword || S.damage > best_sword.damage)
|
||||
best_sword = S
|
||||
```
|
||||
specifies a type for DM to filter by.
|
||||
specifies a type for DM to filter by.
|
||||
|
||||
With the previous example that's perfectly fine, we only want swords, but here the bag only contains swords? Is DM still going to try to filter because we gave
|
||||
it a type to filter by? YES, and here comes the inefficiency. Wherever a list (or other container, such as an atom (in which case you're technically accessing
|
||||
With the previous example that's perfectly fine, we only want swords, but here the bag only contains swords? Is DM still going to try to filter because we gave
|
||||
it a type to filter by? YES, and here comes the inefficiency. Wherever a list (or other container, such as an atom (in which case you're technically accessing
|
||||
their special contents list, but that's irrelevant)) contains datums of the same datatype or subtypes of the datatype you require for your loop's body,
|
||||
you can circumvent DM's filtering and automatic ```istype()``` checks by writing the loop as such:
|
||||
```DM
|
||||
@@ -535,7 +535,7 @@ for(var/s in bag_of_swords)
|
||||
if(!best_sword || S.damage > best_sword.damage)
|
||||
best_sword = S
|
||||
```
|
||||
Of course, if the list contains data of a mixed type then the above optimisation is DANGEROUS, as it will blindly typecast all data in the list as the
|
||||
Of course, if the list contains data of a mixed type then the above optimisation is DANGEROUS, as it will blindly typecast all data in the list as the
|
||||
specified type, even if it isn't really that type, causing runtime errors (AKA your shit won't work if this happens).
|
||||
|
||||
#### Dot variable
|
||||
@@ -559,7 +559,7 @@ DM has a var keyword, called global. This var keyword is for vars inside of type
|
||||
```
|
||||
This does NOT mean that you can access it everywhere like a global var. Instead, it means that that var will only exist once for all instances of its type, in this case that var will only exist once for all mobs - it's shared across everything in its type. (Much more like the keyword `static` in other languages like PHP/C++/C#/Java)
|
||||
|
||||
Isn't that confusing?
|
||||
Isn't that confusing?
|
||||
|
||||
There is also an undocumented keyword called `static` that has the same behaviour as global but more correctly describes BYOND's behaviour. Therefore, we always use static instead of global where we need it, as it reduces suprise when reading BYOND code.
|
||||
|
||||
@@ -576,7 +576,7 @@ To access it:
|
||||
GLOB.my_global_here = X
|
||||
```
|
||||
|
||||
There are a few other defines that do other things. `GLOBAL_REAL` shouldn't be used unless you know exactly what you're doing.
|
||||
There are a few other defines that do other things. `GLOBAL_REAL` shouldn't be used unless you know exactly what you're doing.
|
||||
`GLOBAL_VAR_INIT` allows you to set an initial value on the var, like `GLOBAL_VAR_INIT(number_one, 1)`.
|
||||
`GLOBAL_LIST_INIT` allows you to define a list global var with an initial value. Etc.
|
||||
|
||||
@@ -589,6 +589,7 @@ pull requests/issues, and merging/closing pull requests.
|
||||
* [Fox P McCloud](https://github.com/Fox-McCloud)
|
||||
* [Crazy Lemon](https://github.com/Crazylemon64)
|
||||
* [Ansari](https://github.com/variableundefined)
|
||||
* [AffectedArc07](https://github.com/AffectedArc07)
|
||||
|
||||
### Maintainer instructions
|
||||
* Do not `self-merge`; this refers to the practice of opening a pull request, then
|
||||
@@ -604,6 +605,6 @@ pull requests/issues, and merging/closing pull requests.
|
||||
hours, to allow other coders and the community time to discuss the proposed changes.
|
||||
* If the discussion is active, or the change is controversial, the pull request is to be
|
||||
put on hold until a consensus is reached.
|
||||
* To keep commit history easy to navigate for future contributors (e.g. Git Blame), squash merge
|
||||
is to be preferred to normal merge where suitable. Ensure that the squashed commit name is easy
|
||||
* To keep commit history easy to navigate for future contributors (e.g. Git Blame), squash merge
|
||||
is to be preferred to normal merge where suitable. Ensure that the squashed commit name is easy
|
||||
to understand and read. Modify it if needed.
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
name: Generate Documentation
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *" # Every day at the very start of the day
|
||||
|
||||
jobs:
|
||||
generate_docs:
|
||||
name: 'Generate Documentation'
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- name: 'Update Branch'
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
ref: master
|
||||
|
||||
- name: 'Generate Documentation'
|
||||
run: |
|
||||
./tools/github-actions/doc-generator
|
||||
touch dmdoc/.nojekyll
|
||||
# Nojekyll is important to disable jeykll syntax, which can mess with files that start with underscores
|
||||
|
||||
- name: 'Deploy Documentation'
|
||||
uses: crazy-max/ghaction-github-pages@v2
|
||||
with:
|
||||
keep_history: false
|
||||
build_dir: dmdoc
|
||||
jekyll: false
|
||||
fqdn: codedocs.paradisestation.org
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
+2
-2
@@ -52,8 +52,6 @@ jobs:
|
||||
- libstdc++6:i386
|
||||
- libssl-dev:i386
|
||||
- gcc-multilib
|
||||
- g++-7
|
||||
- g++-7-multilib
|
||||
- pkg-config:i386
|
||||
- zlib1g-dev:i386
|
||||
cache:
|
||||
@@ -61,6 +59,8 @@ jobs:
|
||||
- $HOME/.cargo
|
||||
- $HOME/.rustup
|
||||
- $HOME/BYOND
|
||||
before_install:
|
||||
- 'sudo apt-get -qq update'
|
||||
install:
|
||||
- tools/travis/install_byond.sh
|
||||
- source $HOME/BYOND/byond/bin/byondsetup
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
[langserver]
|
||||
dreamchecker = true
|
||||
|
||||
[code_standards]
|
||||
disallow_relative_type_definitions = true
|
||||
disallow_relative_proc_definitions = true
|
||||
|
||||
[dmdoc]
|
||||
use_typepath_names = true
|
||||
@@ -28449,7 +28449,7 @@
|
||||
/obj/machinery/light{
|
||||
dir = 1
|
||||
},
|
||||
/obj/machinery/computer/ordercomp,
|
||||
/obj/machinery/computer/supplycomp/public,
|
||||
/obj/effect/decal/warning_stripes/yellow/hollow,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 5;
|
||||
@@ -29206,7 +29206,7 @@
|
||||
},
|
||||
/area/hallway/primary/fore)
|
||||
"bed" = (
|
||||
/obj/machinery/computer/ordercomp,
|
||||
/obj/machinery/computer/supplycomp/public,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 8;
|
||||
icon_state = "purple"
|
||||
@@ -40663,40 +40663,16 @@
|
||||
/turf/simulated/wall/r_wall,
|
||||
/area/engine/break_room)
|
||||
"byz" = (
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/modular_computer/console/preset/engineering,
|
||||
/obj/machinery/status_display{
|
||||
pixel_x = -32
|
||||
},
|
||||
/obj/machinery/computer/security/engineering,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 8;
|
||||
icon_state = "caution"
|
||||
},
|
||||
/area/atmos)
|
||||
"byA" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8";
|
||||
tag = ""
|
||||
},
|
||||
/obj/structure/chair/office/dark{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 8;
|
||||
icon_state = "neutralfull"
|
||||
},
|
||||
/area/atmos)
|
||||
"byB" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 1;
|
||||
d2 = 8;
|
||||
icon_state = "1-8"
|
||||
},
|
||||
/obj/structure/cable{
|
||||
d1 = 1;
|
||||
d2 = 4;
|
||||
@@ -41937,12 +41913,7 @@
|
||||
icon_state = "1-2";
|
||||
tag = ""
|
||||
},
|
||||
/obj/machinery/modular_computer/console/preset/command,
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-2";
|
||||
pixel_y = 1;
|
||||
d2 = 2
|
||||
},
|
||||
/obj/machinery/computer/shuttle/mining,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 1;
|
||||
icon_state = "darkpurple"
|
||||
@@ -47144,7 +47115,7 @@
|
||||
pixel_y = 3
|
||||
},
|
||||
/obj/item/circuitboard/powermonitor,
|
||||
/obj/item/circuitboard/stationalert_all{
|
||||
/obj/item/circuitboard/stationalert{
|
||||
pixel_x = 3;
|
||||
pixel_y = -3
|
||||
},
|
||||
@@ -51367,18 +51338,6 @@
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/engine/break_room)
|
||||
"bQf" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8";
|
||||
pixel_x = 0
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "neutral";
|
||||
dir = 4
|
||||
},
|
||||
/area/crew_quarters/chief)
|
||||
"bQg" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 1;
|
||||
@@ -51405,11 +51364,6 @@
|
||||
},
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/item/clipboard,
|
||||
/obj/structure/cable{
|
||||
d1 = 1;
|
||||
d2 = 8;
|
||||
icon_state = "1-8"
|
||||
},
|
||||
/obj/item/toy/figure/ce,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 8;
|
||||
@@ -54089,12 +54043,6 @@
|
||||
/area/crew_quarters/chief)
|
||||
"bUq" = (
|
||||
/obj/machinery/hologram/holopad,
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8";
|
||||
pixel_x = 0
|
||||
},
|
||||
/obj/effect/decal/warning_stripes/yellow/hollow,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 8;
|
||||
@@ -55398,11 +55346,6 @@
|
||||
},
|
||||
/area/crew_quarters/chief)
|
||||
"bWl" = (
|
||||
/obj/machinery/modular_computer/console/preset/engineering,
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/keycard_auth{
|
||||
pixel_x = -24
|
||||
},
|
||||
@@ -55420,6 +55363,7 @@
|
||||
pixel_y = -8;
|
||||
req_access_txt = "11"
|
||||
},
|
||||
/obj/machinery/computer/security/engineering,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
@@ -58725,9 +58669,6 @@
|
||||
/area/blueshield)
|
||||
"cce" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/machinery/computer/skills{
|
||||
req_one_access = null
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 2;
|
||||
icon_state = "bcarpet05"
|
||||
@@ -59666,9 +59607,6 @@
|
||||
/area/ntrep)
|
||||
"cdK" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/machinery/computer/skills{
|
||||
req_access_txt = "57"
|
||||
},
|
||||
/turf/simulated/floor/carpet,
|
||||
/area/ntrep)
|
||||
"cdL" = (
|
||||
@@ -60483,6 +60421,9 @@
|
||||
icon_state = "4-8";
|
||||
tag = ""
|
||||
},
|
||||
/obj/machinery/computer/monitor{
|
||||
name = "Grid Power Monitoring Computer"
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 5;
|
||||
icon_state = "dark";
|
||||
@@ -61209,10 +61150,6 @@
|
||||
/obj/machinery/tcomms/core/station,
|
||||
/turf/simulated/floor/bluegrid,
|
||||
/area/tcommsat/chamber)
|
||||
"cgA" = (
|
||||
/obj/machinery/ntnet_relay,
|
||||
/turf/simulated/floor/bluegrid,
|
||||
/area/tcommsat/chamber)
|
||||
"cgB" = (
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Singularity NorthEast";
|
||||
@@ -62517,7 +62454,6 @@
|
||||
dir = 1;
|
||||
network = list("Engineering","SS13")
|
||||
},
|
||||
/obj/machinery/modular_computer/console/preset/engineering,
|
||||
/obj/machinery/firealarm{
|
||||
dir = 8;
|
||||
pixel_x = -26;
|
||||
@@ -62527,6 +62463,9 @@
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/computer/monitor{
|
||||
name = "Grid Power Monitoring Computer"
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 5;
|
||||
icon_state = "dark";
|
||||
@@ -88635,7 +88574,7 @@
|
||||
/area/maintenance/starboard)
|
||||
"dey" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/modular_computer/tablet/preset/cheap,
|
||||
/obj/effect/spawner/lootdrop/maintenance,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "wood"
|
||||
},
|
||||
@@ -97243,7 +97182,6 @@
|
||||
},
|
||||
/area/crew_quarters/hor)
|
||||
"dtZ" = (
|
||||
/obj/structure/cable,
|
||||
/obj/structure/cable{
|
||||
d1 = 1;
|
||||
d2 = 4;
|
||||
@@ -97253,7 +97191,6 @@
|
||||
pixel_x = 0;
|
||||
pixel_y = -30
|
||||
},
|
||||
/obj/machinery/modular_computer/console/preset/research,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 2;
|
||||
icon_state = "whitepurplecorner"
|
||||
@@ -114782,6 +114719,9 @@
|
||||
"qrT" = (
|
||||
/turf/simulated/wall/r_wall,
|
||||
/area/tcommsat/chamber)
|
||||
"rSI" = (
|
||||
/turf/simulated/floor/bluegrid,
|
||||
/area/tcommsat/chamber)
|
||||
"udT" = (
|
||||
/obj/structure/chair/comfy/shuttle{
|
||||
dir = 8
|
||||
@@ -123168,9 +123108,9 @@ bVO
|
||||
bPI
|
||||
bNM
|
||||
qrT
|
||||
eaH
|
||||
rSI
|
||||
ceL
|
||||
cgu
|
||||
eaH
|
||||
qrT
|
||||
qrT
|
||||
bkt
|
||||
@@ -123940,7 +123880,7 @@ bXJ
|
||||
bZh
|
||||
caX
|
||||
ccW
|
||||
ccW
|
||||
cgu
|
||||
ccW
|
||||
chW
|
||||
qrT
|
||||
@@ -124710,9 +124650,9 @@ bVT
|
||||
bXL
|
||||
bNM
|
||||
qrT
|
||||
hng
|
||||
rSI
|
||||
vzz
|
||||
cgA
|
||||
hng
|
||||
qrT
|
||||
qrT
|
||||
bkt
|
||||
@@ -138067,7 +138007,7 @@ bIr
|
||||
bKe
|
||||
bMh
|
||||
bOa
|
||||
bQf
|
||||
bOa
|
||||
bOa
|
||||
bUh
|
||||
bWk
|
||||
@@ -142426,7 +142366,7 @@ btt
|
||||
buD
|
||||
bvO
|
||||
ban
|
||||
byA
|
||||
bzY
|
||||
bzY
|
||||
bBK
|
||||
aOg
|
||||
|
||||
@@ -31415,7 +31415,7 @@
|
||||
pixel_x = -2;
|
||||
pixel_y = 2
|
||||
},
|
||||
/obj/item/circuitboard/stationalert_all{
|
||||
/obj/item/circuitboard/stationalert{
|
||||
pixel_x = 1;
|
||||
pixel_y = -1
|
||||
},
|
||||
@@ -35305,7 +35305,7 @@
|
||||
},
|
||||
/area/engine/chiefs_office)
|
||||
"bjJ" = (
|
||||
/obj/machinery/computer/ordercomp,
|
||||
/obj/machinery/computer/supplycomp/public,
|
||||
/obj/effect/decal/warning_stripes/yellow,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 9;
|
||||
@@ -38185,7 +38185,7 @@
|
||||
d2 = 2;
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/modular_computer/console/preset/command,
|
||||
/obj/machinery/computer/card,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
@@ -41916,7 +41916,7 @@
|
||||
d2 = 8;
|
||||
icon_state = "1-8"
|
||||
},
|
||||
/obj/machinery/computer/ordercomp,
|
||||
/obj/machinery/computer/supplycomp/public,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
@@ -44531,7 +44531,7 @@
|
||||
layer = 4;
|
||||
pixel_y = 32
|
||||
},
|
||||
/obj/machinery/computer/ordercomp,
|
||||
/obj/machinery/computer/supplycomp/public,
|
||||
/turf/simulated/floor/wood,
|
||||
/area/crew_quarters/heads)
|
||||
"byv" = (
|
||||
@@ -57433,9 +57433,6 @@
|
||||
})
|
||||
"bVc" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/machinery/computer/skills{
|
||||
req_access_txt = "57"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
|
||||
/turf/simulated/floor/carpet,
|
||||
/area/ntrep)
|
||||
@@ -58264,9 +58261,6 @@
|
||||
/area/blueshield)
|
||||
"bWI" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/machinery/computer/skills{
|
||||
req_one_access = null
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "bcarpet05"
|
||||
},
|
||||
@@ -96414,10 +96408,7 @@
|
||||
d2 = 2;
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/simulated/floor/plasteel/dark,
|
||||
/area/tcommsat/server)
|
||||
"gIG" = (
|
||||
/obj/machinery/ntnet_relay,
|
||||
/obj/machinery/tcomms/core/station,
|
||||
/turf/simulated/floor/bluegrid,
|
||||
/area/tcommsat/server)
|
||||
"gRw" = (
|
||||
@@ -96649,10 +96640,6 @@
|
||||
},
|
||||
/turf/space,
|
||||
/area/solar/starboard)
|
||||
"rUQ" = (
|
||||
/obj/machinery/tcomms/core/station,
|
||||
/turf/simulated/floor/bluegrid,
|
||||
/area/tcommsat/server)
|
||||
"sjF" = (
|
||||
/obj/structure/window/reinforced{
|
||||
dir = 1
|
||||
@@ -151152,7 +151139,7 @@ bDf
|
||||
bFi
|
||||
bIz
|
||||
bKl
|
||||
gIG
|
||||
bOa
|
||||
bOb
|
||||
odO
|
||||
bKl
|
||||
@@ -152180,7 +152167,7 @@ bDj
|
||||
bFm
|
||||
bRo
|
||||
bKl
|
||||
rUQ
|
||||
bOa
|
||||
dRN
|
||||
kwJ
|
||||
bKl
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
/turf/simulated/floor/wood,
|
||||
/area/ruin/powered/snow_cabin)
|
||||
"aL" = (
|
||||
/obj/structure/displaycase/captain,
|
||||
/obj/mecha/working/ripley/mining,
|
||||
/turf/simulated/floor/wood,
|
||||
/area/ruin/powered/snow_cabin)
|
||||
"aM" = (
|
||||
@@ -392,12 +392,6 @@
|
||||
/obj/structure/filingcabinet,
|
||||
/turf/simulated/floor/pod/dark,
|
||||
/area/ruin/powered/snow_biodome)
|
||||
"UM" = (
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/pod/dark,
|
||||
/area/ruin/powered/snow_biodome)
|
||||
"Wg" = (
|
||||
/turf/simulated/wall/r_wall,
|
||||
/area/ruin/powered/snow_biodome)
|
||||
@@ -484,7 +478,7 @@ HP
|
||||
tl
|
||||
PK
|
||||
gz
|
||||
UM
|
||||
HP
|
||||
Wg
|
||||
ak
|
||||
ak
|
||||
|
||||
@@ -0,0 +1,614 @@
|
||||
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
|
||||
"a" = (
|
||||
/turf/template_noop,
|
||||
/area/template_noop)
|
||||
"b" = (
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"c" = (
|
||||
/obj/structure/lattice,
|
||||
/obj/structure/disposalpipe/broken{
|
||||
dir = 1
|
||||
},
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"d" = (
|
||||
/obj/structure/lattice,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"e" = (
|
||||
/obj/structure/grille/broken,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"g" = (
|
||||
/obj/structure/disposalpipe/broken{
|
||||
dir = 4
|
||||
},
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"h" = (
|
||||
/obj/structure/disposalpipe/broken{
|
||||
dir = 8
|
||||
},
|
||||
/obj/item/stack/cable_coil/cut,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"l" = (
|
||||
/obj/item/stack/cable_coil/cut,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"m" = (
|
||||
/obj/effect/spawner/random_spawners/grille_often,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"n" = (
|
||||
/obj/effect/spawner/random_spawners/grille_maybe,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"o" = (
|
||||
/obj/random/tool,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"p" = (
|
||||
/obj/structure/girder/displaced,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"r" = (
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"t" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 2;
|
||||
d2 = 8;
|
||||
icon_state = "2-8"
|
||||
},
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"u" = (
|
||||
/obj/structure/door_assembly/door_assembly_sec,
|
||||
/obj/item/airlock_electronics,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"v" = (
|
||||
/obj/structure/lattice,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"x" = (
|
||||
/obj/structure/disposalpipe/junction,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"y" = (
|
||||
/turf/simulated/floor/plating/burnt,
|
||||
/area/space)
|
||||
"z" = (
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/space)
|
||||
"B" = (
|
||||
/obj/structure/lattice,
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"C" = (
|
||||
/obj/structure/disposalpipe/broken{
|
||||
dir = 1
|
||||
},
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"D" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8";
|
||||
pixel_y = 0;
|
||||
tag = ""
|
||||
},
|
||||
/turf/simulated/floor/plating/burnt,
|
||||
/area/space)
|
||||
"E" = (
|
||||
/obj/item/stack/rods,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"F" = (
|
||||
/turf/simulated/floor/plating,
|
||||
/area/space)
|
||||
"G" = (
|
||||
/obj/random/toolbox,
|
||||
/turf/simulated/floor/plating/burnt,
|
||||
/area/space)
|
||||
"I" = (
|
||||
/obj/structure/grille/broken,
|
||||
/obj/structure/lattice,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"J" = (
|
||||
/obj/structure/disposalpipe/broken,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"K" = (
|
||||
/obj/item/shard,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"N" = (
|
||||
/obj/structure/lattice,
|
||||
/obj/structure/lattice,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"O" = (
|
||||
/obj/machinery/power/apc/worn_out{
|
||||
pixel_y = -24
|
||||
},
|
||||
/obj/structure/cable,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/space)
|
||||
"Q" = (
|
||||
/obj/effect/decal/cleanable/shreds{
|
||||
pixel_x = 4;
|
||||
pixel_y = 3
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/space)
|
||||
"T" = (
|
||||
/obj/structure/girder,
|
||||
/turf/simulated/floor/plating/burnt,
|
||||
/area/space)
|
||||
"U" = (
|
||||
/obj/effect/spawner/random_barrier/wall_probably,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"V" = (
|
||||
/turf/simulated/wall,
|
||||
/area/space)
|
||||
"X" = (
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"Y" = (
|
||||
/obj/item/shard,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/space)
|
||||
"Z" = (
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
|
||||
(1,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
(2,1,1) = {"
|
||||
a
|
||||
a
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
d
|
||||
d
|
||||
d
|
||||
r
|
||||
r
|
||||
d
|
||||
r
|
||||
a
|
||||
a
|
||||
"}
|
||||
(3,1,1) = {"
|
||||
a
|
||||
d
|
||||
v
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(4,1,1) = {"
|
||||
a
|
||||
d
|
||||
X
|
||||
m
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
v
|
||||
Z
|
||||
X
|
||||
X
|
||||
d
|
||||
a
|
||||
"}
|
||||
(5,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
g
|
||||
F
|
||||
X
|
||||
E
|
||||
I
|
||||
X
|
||||
X
|
||||
v
|
||||
X
|
||||
F
|
||||
v
|
||||
v
|
||||
X
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(6,1,1) = {"
|
||||
a
|
||||
r
|
||||
J
|
||||
x
|
||||
C
|
||||
E
|
||||
v
|
||||
F
|
||||
X
|
||||
E
|
||||
X
|
||||
v
|
||||
g
|
||||
Z
|
||||
X
|
||||
X
|
||||
F
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(7,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
y
|
||||
E
|
||||
X
|
||||
E
|
||||
Y
|
||||
X
|
||||
n
|
||||
X
|
||||
h
|
||||
E
|
||||
F
|
||||
X
|
||||
v
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(8,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
X
|
||||
B
|
||||
l
|
||||
p
|
||||
X
|
||||
X
|
||||
y
|
||||
p
|
||||
X
|
||||
X
|
||||
X
|
||||
E
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(9,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
v
|
||||
X
|
||||
o
|
||||
X
|
||||
X
|
||||
Z
|
||||
l
|
||||
X
|
||||
E
|
||||
a
|
||||
X
|
||||
X
|
||||
V
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(10,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
Z
|
||||
Q
|
||||
v
|
||||
X
|
||||
y
|
||||
v
|
||||
D
|
||||
y
|
||||
U
|
||||
X
|
||||
X
|
||||
E
|
||||
X
|
||||
X
|
||||
n
|
||||
r
|
||||
a
|
||||
"}
|
||||
(11,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
I
|
||||
v
|
||||
v
|
||||
X
|
||||
v
|
||||
t
|
||||
O
|
||||
V
|
||||
X
|
||||
X
|
||||
F
|
||||
E
|
||||
Z
|
||||
X
|
||||
d
|
||||
a
|
||||
"}
|
||||
(12,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
J
|
||||
b
|
||||
c
|
||||
v
|
||||
G
|
||||
V
|
||||
X
|
||||
E
|
||||
e
|
||||
X
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(13,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
X
|
||||
V
|
||||
X
|
||||
Z
|
||||
X
|
||||
X
|
||||
X
|
||||
u
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
e
|
||||
Z
|
||||
r
|
||||
a
|
||||
"}
|
||||
(14,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
v
|
||||
X
|
||||
v
|
||||
N
|
||||
E
|
||||
E
|
||||
K
|
||||
X
|
||||
v
|
||||
o
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(15,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
E
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
E
|
||||
J
|
||||
C
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
d
|
||||
a
|
||||
"}
|
||||
(16,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
E
|
||||
X
|
||||
T
|
||||
X
|
||||
Z
|
||||
X
|
||||
n
|
||||
v
|
||||
X
|
||||
z
|
||||
n
|
||||
X
|
||||
Z
|
||||
X
|
||||
d
|
||||
a
|
||||
"}
|
||||
(17,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
F
|
||||
X
|
||||
X
|
||||
X
|
||||
p
|
||||
X
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(18,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
v
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(19,1,1) = {"
|
||||
a
|
||||
a
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
d
|
||||
r
|
||||
d
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
a
|
||||
a
|
||||
"}
|
||||
(20,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
@@ -0,0 +1,631 @@
|
||||
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
|
||||
"a" = (
|
||||
/turf/template_noop,
|
||||
/area/template_noop)
|
||||
"b" = (
|
||||
/turf/simulated/floor/plating/airless,
|
||||
/area/space)
|
||||
"c" = (
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/space)
|
||||
"d" = (
|
||||
/turf/simulated/wall/r_wall,
|
||||
/area/space)
|
||||
"e" = (
|
||||
/obj/item/stack/cable_coil/cut,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"h" = (
|
||||
/obj/structure/girder,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"j" = (
|
||||
/obj/structure/grille/broken,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"l" = (
|
||||
/obj/structure/girder,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/space)
|
||||
"m" = (
|
||||
/obj/structure/grille/broken,
|
||||
/turf/template_noop,
|
||||
/area/space)
|
||||
"n" = (
|
||||
/obj/item/stack/cable_coil/cut,
|
||||
/turf/template_noop,
|
||||
/area/space)
|
||||
"o" = (
|
||||
/obj/machinery/door/airlock/command{
|
||||
max_integrity = 40
|
||||
},
|
||||
/turf/simulated/floor/plating/burnt,
|
||||
/area/space)
|
||||
"p" = (
|
||||
/mob/living/simple_animal/hostile/carp,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"q" = (
|
||||
/obj/structure/lattice,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"s" = (
|
||||
/obj/item/stack/rods,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"t" = (
|
||||
/obj/structure/door_assembly/door_assembly_com,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"u" = (
|
||||
/obj/item/clothing/head/bio_hood/virology,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"w" = (
|
||||
/obj/structure/lattice,
|
||||
/turf/template_noop,
|
||||
/area/space)
|
||||
"x" = (
|
||||
/turf/template_noop,
|
||||
/area/space)
|
||||
"y" = (
|
||||
/obj/structure/lattice,
|
||||
/obj/structure/door_assembly/door_assembly_vault{
|
||||
anchored = 1
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/space)
|
||||
"z" = (
|
||||
/obj/item/stack/rods,
|
||||
/turf/template_noop,
|
||||
/area/space)
|
||||
"A" = (
|
||||
/obj/structure/closet/crate,
|
||||
/obj/item/reagent_containers/glass/beaker/bluespace,
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/space)
|
||||
"B" = (
|
||||
/obj/item/shard{
|
||||
icon_state = "small"
|
||||
},
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"C" = (
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"D" = (
|
||||
/obj/effect/landmark/burnturf,
|
||||
/turf/simulated/floor/plating/airless,
|
||||
/area/space)
|
||||
"E" = (
|
||||
/obj/item/reagent_containers/glass/beaker/large,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"F" = (
|
||||
/obj/effect/landmark/burnturf,
|
||||
/turf/simulated/floor,
|
||||
/area/space)
|
||||
"G" = (
|
||||
/obj/structure/safe,
|
||||
/obj/item/stack/sheet/mineral/bananium{
|
||||
amount = 5
|
||||
},
|
||||
/obj/item/stack/ore/bluespace_crystal/refined{
|
||||
amount = 3
|
||||
},
|
||||
/obj/item/dnainjector/comic,
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/space)
|
||||
"H" = (
|
||||
/obj/structure/table,
|
||||
/obj/item/shard{
|
||||
icon_state = "medium"
|
||||
},
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/space)
|
||||
"I" = (
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"J" = (
|
||||
/mob/living/simple_animal/hostile/carp,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"L" = (
|
||||
/obj/item/shard,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"M" = (
|
||||
/turf/simulated/floor,
|
||||
/area/space)
|
||||
"N" = (
|
||||
/obj/item/clothing/suit/bio_suit/virology,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"O" = (
|
||||
/obj/item/shard{
|
||||
icon_state = "small"
|
||||
},
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"P" = (
|
||||
/obj/item/reagent_containers/spray/cleaner,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"R" = (
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/template_noop,
|
||||
/area/space)
|
||||
"S" = (
|
||||
/obj/item/reagent_containers/spray/cleaner,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"T" = (
|
||||
/turf/simulated/wall,
|
||||
/area/space)
|
||||
"U" = (
|
||||
/obj/effect/landmark/burnturf,
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/space)
|
||||
"V" = (
|
||||
/obj/structure/lattice,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"W" = (
|
||||
/obj/effect/landmark/burnturf,
|
||||
/turf/simulated/floor/plating/burnt,
|
||||
/area/space)
|
||||
"X" = (
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"Y" = (
|
||||
/obj/structure/girder/reinforced,
|
||||
/turf/simulated/floor/plating/damaged,
|
||||
/area/space)
|
||||
"Z" = (
|
||||
/obj/machinery/computer/pandemic{
|
||||
circuit = /obj/effect/decal/cleanable/shreds
|
||||
},
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/space)
|
||||
|
||||
(1,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
(2,1,1) = {"
|
||||
a
|
||||
d
|
||||
d
|
||||
d
|
||||
d
|
||||
d
|
||||
Y
|
||||
x
|
||||
S
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
C
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(3,1,1) = {"
|
||||
a
|
||||
d
|
||||
G
|
||||
A
|
||||
U
|
||||
F
|
||||
d
|
||||
z
|
||||
T
|
||||
T
|
||||
T
|
||||
T
|
||||
o
|
||||
T
|
||||
I
|
||||
p
|
||||
O
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(4,1,1) = {"
|
||||
a
|
||||
Y
|
||||
c
|
||||
U
|
||||
c
|
||||
U
|
||||
d
|
||||
X
|
||||
w
|
||||
M
|
||||
c
|
||||
U
|
||||
M
|
||||
T
|
||||
V
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(5,1,1) = {"
|
||||
a
|
||||
Y
|
||||
M
|
||||
F
|
||||
F
|
||||
q
|
||||
d
|
||||
z
|
||||
m
|
||||
F
|
||||
M
|
||||
F
|
||||
M
|
||||
T
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(6,1,1) = {"
|
||||
a
|
||||
d
|
||||
d
|
||||
y
|
||||
d
|
||||
d
|
||||
Y
|
||||
X
|
||||
w
|
||||
X
|
||||
n
|
||||
X
|
||||
w
|
||||
T
|
||||
I
|
||||
I
|
||||
I
|
||||
C
|
||||
I
|
||||
a
|
||||
"}
|
||||
(7,1,1) = {"
|
||||
a
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
P
|
||||
J
|
||||
X
|
||||
T
|
||||
T
|
||||
T
|
||||
x
|
||||
T
|
||||
I
|
||||
I
|
||||
V
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(8,1,1) = {"
|
||||
a
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
R
|
||||
X
|
||||
w
|
||||
X
|
||||
b
|
||||
x
|
||||
x
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(9,1,1) = {"
|
||||
a
|
||||
p
|
||||
s
|
||||
T
|
||||
m
|
||||
w
|
||||
T
|
||||
R
|
||||
X
|
||||
B
|
||||
X
|
||||
w
|
||||
X
|
||||
x
|
||||
z
|
||||
I
|
||||
s
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(10,1,1) = {"
|
||||
a
|
||||
s
|
||||
I
|
||||
T
|
||||
M
|
||||
F
|
||||
T
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
x
|
||||
x
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(11,1,1) = {"
|
||||
a
|
||||
I
|
||||
I
|
||||
T
|
||||
c
|
||||
F
|
||||
T
|
||||
X
|
||||
X
|
||||
c
|
||||
F
|
||||
b
|
||||
j
|
||||
D
|
||||
T
|
||||
I
|
||||
I
|
||||
I
|
||||
t
|
||||
a
|
||||
"}
|
||||
(12,1,1) = {"
|
||||
a
|
||||
C
|
||||
I
|
||||
T
|
||||
X
|
||||
M
|
||||
N
|
||||
s
|
||||
I
|
||||
I
|
||||
L
|
||||
q
|
||||
q
|
||||
b
|
||||
T
|
||||
I
|
||||
s
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(13,1,1) = {"
|
||||
a
|
||||
I
|
||||
I
|
||||
l
|
||||
T
|
||||
T
|
||||
T
|
||||
I
|
||||
I
|
||||
u
|
||||
j
|
||||
W
|
||||
c
|
||||
U
|
||||
T
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(14,1,1) = {"
|
||||
a
|
||||
I
|
||||
s
|
||||
p
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
p
|
||||
I
|
||||
I
|
||||
c
|
||||
H
|
||||
Z
|
||||
T
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(15,1,1) = {"
|
||||
a
|
||||
V
|
||||
I
|
||||
I
|
||||
s
|
||||
V
|
||||
C
|
||||
I
|
||||
I
|
||||
s
|
||||
h
|
||||
T
|
||||
T
|
||||
T
|
||||
T
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(16,1,1) = {"
|
||||
a
|
||||
I
|
||||
I
|
||||
E
|
||||
I
|
||||
I
|
||||
V
|
||||
I
|
||||
O
|
||||
I
|
||||
V
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
C
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(17,1,1) = {"
|
||||
a
|
||||
I
|
||||
I
|
||||
C
|
||||
I
|
||||
e
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
e
|
||||
I
|
||||
V
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(18,1,1) = {"
|
||||
a
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
h
|
||||
I
|
||||
I
|
||||
C
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(19,1,1) = {"
|
||||
a
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
C
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(20,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
@@ -0,0 +1,824 @@
|
||||
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
|
||||
"a" = (
|
||||
/turf/template_noop,
|
||||
/area/template_noop)
|
||||
"b" = (
|
||||
/obj/item/stack/rods,
|
||||
/turf/simulated/floor/plating/damaged,
|
||||
/area/template_noop)
|
||||
"c" = (
|
||||
/obj/item/trash/popcorn,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"d" = (
|
||||
/obj/effect/spawner/random_spawners/wall_rusted_maybe,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"e" = (
|
||||
/obj/item/poster/random_contraband,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"f" = (
|
||||
/obj/structure/lattice,
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"g" = (
|
||||
/obj/item/paperplane,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"h" = (
|
||||
/obj/item/trash/can,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"i" = (
|
||||
/obj/item/stack/rods,
|
||||
/turf/template_noop,
|
||||
/area/template_noop)
|
||||
"k" = (
|
||||
/obj/item/shard,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"l" = (
|
||||
/obj/item/stack/cable_coil{
|
||||
amount = 10
|
||||
},
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"m" = (
|
||||
/turf/simulated/wall,
|
||||
/area/template_noop)
|
||||
"n" = (
|
||||
/obj/item/stack/sheet/glass,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"p" = (
|
||||
/obj/random/plushie,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"q" = (
|
||||
/obj/item/stack/rods,
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"t" = (
|
||||
/obj/machinery/computer/arcade/battle,
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/template_noop)
|
||||
"u" = (
|
||||
/obj/random/tool,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"v" = (
|
||||
/obj/item/trash/syndi_cakes,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"w" = (
|
||||
/obj/item/stack/tickets,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"x" = (
|
||||
/obj/structure/bookcase/random/fiction,
|
||||
/turf/simulated/floor/plating/damaged,
|
||||
/area/template_noop)
|
||||
"y" = (
|
||||
/obj/item/storage/pill_bottle/random_meds/labelled,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"z" = (
|
||||
/turf/simulated/floor/plating/damaged,
|
||||
/area/template_noop)
|
||||
"A" = (
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"B" = (
|
||||
/obj/item/stack/rods,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"D" = (
|
||||
/obj/item/paper,
|
||||
/obj/item/paper,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"F" = (
|
||||
/obj/random/tool,
|
||||
/turf/simulated/floor/plating/damaged,
|
||||
/area/template_noop)
|
||||
"G" = (
|
||||
/obj/item/poster/random_official,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"H" = (
|
||||
/obj/item/stack/sheet/wood,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"I" = (
|
||||
/obj/item/stack/rods,
|
||||
/obj/item/stack/rods,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"J" = (
|
||||
/obj/item/trash/pistachios,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"K" = (
|
||||
/obj/structure/lattice,
|
||||
/obj/structure/girder,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"L" = (
|
||||
/obj/structure/girder,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"M" = (
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"O" = (
|
||||
/obj/structure/girder/displaced,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"S" = (
|
||||
/obj/structure/lattice,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"U" = (
|
||||
/obj/item/stack/sheet/wood,
|
||||
/obj/item/stack/sheet/wood,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"V" = (
|
||||
/obj/item/circuitboard/arcade,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"W" = (
|
||||
/obj/item/stack/tickets,
|
||||
/obj/item/stack/tickets,
|
||||
/obj/item/stack/tickets,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"Z" = (
|
||||
/obj/item/paper,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
|
||||
(1,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
i
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
(2,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
i
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
i
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
(3,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(4,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
B
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
B
|
||||
B
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(5,1,1) = {"
|
||||
i
|
||||
a
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
w
|
||||
A
|
||||
M
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
i
|
||||
"}
|
||||
(6,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
I
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
B
|
||||
B
|
||||
M
|
||||
A
|
||||
A
|
||||
M
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(7,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
k
|
||||
A
|
||||
A
|
||||
O
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
m
|
||||
A
|
||||
w
|
||||
A
|
||||
M
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(8,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
B
|
||||
A
|
||||
M
|
||||
A
|
||||
A
|
||||
H
|
||||
A
|
||||
G
|
||||
n
|
||||
m
|
||||
A
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(9,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
m
|
||||
A
|
||||
w
|
||||
A
|
||||
M
|
||||
S
|
||||
A
|
||||
A
|
||||
d
|
||||
B
|
||||
M
|
||||
A
|
||||
O
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(10,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
w
|
||||
A
|
||||
A
|
||||
Z
|
||||
A
|
||||
W
|
||||
B
|
||||
S
|
||||
h
|
||||
M
|
||||
L
|
||||
A
|
||||
c
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(11,1,1) = {"
|
||||
a
|
||||
i
|
||||
B
|
||||
w
|
||||
A
|
||||
S
|
||||
A
|
||||
F
|
||||
A
|
||||
A
|
||||
S
|
||||
A
|
||||
Z
|
||||
A
|
||||
A
|
||||
A
|
||||
M
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(12,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
H
|
||||
L
|
||||
S
|
||||
m
|
||||
m
|
||||
b
|
||||
A
|
||||
A
|
||||
Z
|
||||
w
|
||||
B
|
||||
A
|
||||
i
|
||||
a
|
||||
"}
|
||||
(13,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
B
|
||||
O
|
||||
A
|
||||
B
|
||||
A
|
||||
M
|
||||
A
|
||||
D
|
||||
K
|
||||
z
|
||||
S
|
||||
H
|
||||
B
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(14,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
n
|
||||
A
|
||||
y
|
||||
f
|
||||
B
|
||||
A
|
||||
z
|
||||
B
|
||||
A
|
||||
m
|
||||
t
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(15,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
z
|
||||
H
|
||||
A
|
||||
A
|
||||
A
|
||||
S
|
||||
A
|
||||
q
|
||||
z
|
||||
z
|
||||
A
|
||||
A
|
||||
O
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(16,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
S
|
||||
A
|
||||
S
|
||||
U
|
||||
B
|
||||
B
|
||||
A
|
||||
A
|
||||
S
|
||||
A
|
||||
M
|
||||
B
|
||||
u
|
||||
A
|
||||
a
|
||||
i
|
||||
"}
|
||||
(17,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
M
|
||||
H
|
||||
w
|
||||
Z
|
||||
B
|
||||
x
|
||||
S
|
||||
B
|
||||
S
|
||||
A
|
||||
k
|
||||
J
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(18,1,1) = {"
|
||||
a
|
||||
a
|
||||
B
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
w
|
||||
B
|
||||
z
|
||||
A
|
||||
O
|
||||
A
|
||||
M
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(19,1,1) = {"
|
||||
i
|
||||
a
|
||||
A
|
||||
A
|
||||
M
|
||||
z
|
||||
S
|
||||
w
|
||||
S
|
||||
M
|
||||
A
|
||||
m
|
||||
p
|
||||
A
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(20,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
B
|
||||
A
|
||||
O
|
||||
H
|
||||
v
|
||||
A
|
||||
V
|
||||
H
|
||||
A
|
||||
B
|
||||
L
|
||||
A
|
||||
M
|
||||
A
|
||||
w
|
||||
a
|
||||
a
|
||||
"}
|
||||
(21,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
e
|
||||
M
|
||||
A
|
||||
w
|
||||
Z
|
||||
w
|
||||
B
|
||||
A
|
||||
w
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(22,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
M
|
||||
O
|
||||
m
|
||||
m
|
||||
L
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
q
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(23,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
B
|
||||
k
|
||||
A
|
||||
B
|
||||
A
|
||||
B
|
||||
g
|
||||
n
|
||||
A
|
||||
O
|
||||
A
|
||||
A
|
||||
B
|
||||
B
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(24,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
M
|
||||
A
|
||||
A
|
||||
l
|
||||
A
|
||||
w
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(25,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
w
|
||||
B
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
A
|
||||
w
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(26,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
B
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
B
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(27,1,1) = {"
|
||||
a
|
||||
a
|
||||
B
|
||||
A
|
||||
w
|
||||
A
|
||||
B
|
||||
A
|
||||
w
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
w
|
||||
a
|
||||
a
|
||||
"}
|
||||
(28,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
w
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
i
|
||||
"}
|
||||
(29,1,1) = {"
|
||||
i
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
i
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
(30,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
i
|
||||
a
|
||||
a
|
||||
"}
|
||||
@@ -99,6 +99,12 @@
|
||||
/obj/item/tank/air,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/ruin/powered)
|
||||
"u" = (
|
||||
/obj/machinery/tcomms/relay/ruskie{
|
||||
network_id = "LISTENINGOUTPOST-RELAY"
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/ruin/powered)
|
||||
"w" = (
|
||||
/obj/machinery/light/small,
|
||||
/turf/simulated/floor/plasteel,
|
||||
@@ -922,7 +928,7 @@ b
|
||||
f
|
||||
f
|
||||
f
|
||||
c
|
||||
f
|
||||
f
|
||||
D
|
||||
m
|
||||
@@ -964,7 +970,7 @@ f
|
||||
f
|
||||
p
|
||||
Y
|
||||
f
|
||||
u
|
||||
f
|
||||
j
|
||||
i
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -68,7 +68,6 @@
|
||||
"an" = (
|
||||
/obj/machinery/navbeacon/invisible{
|
||||
codes_txt = "patrol;next_patrol=SDNW";
|
||||
invisibility = 100;
|
||||
location = "SDNE"
|
||||
},
|
||||
/turf/simulated/floor/plating/asteroid/airless,
|
||||
@@ -292,15 +291,13 @@
|
||||
"aU" = (
|
||||
/obj/machinery/navbeacon/invisible{
|
||||
codes_txt = "patrol;next_patrol=SDSW";
|
||||
invisibility = 100;
|
||||
location = "SDNW"
|
||||
},
|
||||
/turf/simulated/floor/plating/asteroid/airless,
|
||||
/area/syndicate_depot/outer)
|
||||
"aV" = (
|
||||
/obj/machinery/light{
|
||||
dir = 4;
|
||||
icon_state = "tube1"
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/plating/asteroid/airless,
|
||||
/area/syndicate_depot/outer)
|
||||
@@ -429,8 +426,7 @@
|
||||
/area/syndicate_depot/core)
|
||||
"bo" = (
|
||||
/obj/machinery/light{
|
||||
dir = 4;
|
||||
icon_state = "tube1"
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/spawner/random_spawners/syndicate/loot,
|
||||
/turf/simulated/floor/plasteel{
|
||||
@@ -512,7 +508,6 @@
|
||||
id = "syndi_depot_rear";
|
||||
idle_power_usage = 0;
|
||||
name = "mysterious button";
|
||||
normaldoorcontrol = 0;
|
||||
pixel_x = 24;
|
||||
use_power = 0
|
||||
},
|
||||
@@ -663,8 +658,8 @@
|
||||
/obj/machinery/turretid/syndicate{
|
||||
name = "external turret controls";
|
||||
pixel_x = -32;
|
||||
pixel_y = 0;
|
||||
req_access = list(150)
|
||||
req_access = null;
|
||||
req_access_txt = "150"
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
@@ -745,9 +740,8 @@
|
||||
/area/syndicate_depot/core)
|
||||
"ce" = (
|
||||
/obj/machinery/light/small{
|
||||
tag = "icon-bulb1 (EAST)";
|
||||
icon_state = "bulb1";
|
||||
dir = 4
|
||||
dir = 4;
|
||||
tag = "icon-bulb1 (EAST)"
|
||||
},
|
||||
/turf/simulated/floor/mineral/silver,
|
||||
/area/syndicate_depot/core)
|
||||
@@ -757,7 +751,6 @@
|
||||
id = "syndi_depot_rear";
|
||||
idle_power_usage = 0;
|
||||
name = "mysterious button";
|
||||
normaldoorcontrol = 0;
|
||||
use_power = 0
|
||||
},
|
||||
/obj/structure/sign/poster/contraband/syndicate_recruitment,
|
||||
@@ -774,8 +767,8 @@
|
||||
/area/syndicate_depot/core)
|
||||
"ci" = (
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-2";
|
||||
d2 = 2
|
||||
d2 = 2;
|
||||
icon_state = "0-2"
|
||||
},
|
||||
/obj/machinery/power/smes/upgraded{
|
||||
charge = 5e+006;
|
||||
@@ -845,7 +838,6 @@
|
||||
"cr" = (
|
||||
/obj/structure/sink{
|
||||
dir = 4;
|
||||
icon_state = "sink";
|
||||
pixel_x = 12
|
||||
},
|
||||
/turf/simulated/floor/mineral/silver,
|
||||
@@ -1154,7 +1146,6 @@
|
||||
"dc" = (
|
||||
/obj/machinery/navbeacon/invisible{
|
||||
codes_txt = "patrol;next_patrol=SDSE";
|
||||
invisibility = 100;
|
||||
location = "SDSW"
|
||||
},
|
||||
/turf/simulated/floor/plating/asteroid/airless,
|
||||
@@ -1179,7 +1170,6 @@
|
||||
"df" = (
|
||||
/obj/machinery/navbeacon/invisible{
|
||||
codes_txt = "patrol;next_patrol=SDNE";
|
||||
invisibility = 100;
|
||||
location = "SDSE"
|
||||
},
|
||||
/turf/simulated/floor/plating/asteroid/airless,
|
||||
|
||||
@@ -26723,10 +26723,6 @@
|
||||
dir = 4
|
||||
},
|
||||
/area/security/nuke_storage)
|
||||
"aXS" = (
|
||||
/obj/machinery/vending/modularpc,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/storage/primary)
|
||||
"aXU" = (
|
||||
/obj/item/flag/mime,
|
||||
/obj/machinery/power/apc{
|
||||
@@ -26847,23 +26843,13 @@
|
||||
},
|
||||
/area/crew_quarters/bar)
|
||||
"aYf" = (
|
||||
/obj/machinery/modular_computer/console/preset/command,
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-2";
|
||||
pixel_y = 1;
|
||||
d2 = 2
|
||||
},
|
||||
/obj/machinery/computer/card,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 10;
|
||||
icon_state = "green"
|
||||
},
|
||||
/area/bridge)
|
||||
"aYg" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 1;
|
||||
d2 = 2;
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 1;
|
||||
icon_state = "greencorner"
|
||||
@@ -27432,7 +27418,6 @@
|
||||
/area/storage/primary)
|
||||
"aZf" = (
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/machinery/computer/skills,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "red"
|
||||
},
|
||||
@@ -35244,7 +35229,7 @@
|
||||
},
|
||||
/area/bridge)
|
||||
"bnW" = (
|
||||
/obj/machinery/computer/station_alert/all,
|
||||
/obj/machinery/computer/station_alert,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 0;
|
||||
icon_state = "yellow"
|
||||
@@ -38278,11 +38263,6 @@
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/bridge)
|
||||
"bup" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 1;
|
||||
d2 = 2;
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/atmospherics/unary/vent_pump/on,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/bridge)
|
||||
@@ -38895,11 +38875,6 @@
|
||||
icon_state = "4-8";
|
||||
tag = ""
|
||||
},
|
||||
/obj/structure/cable{
|
||||
d1 = 1;
|
||||
d2 = 4;
|
||||
icon_state = "1-4"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/bridge)
|
||||
@@ -48824,7 +48799,7 @@
|
||||
},
|
||||
/area/engine/gravitygenerator)
|
||||
"bOt" = (
|
||||
/obj/machinery/computer/ordercomp,
|
||||
/obj/machinery/computer/supplycomp/public,
|
||||
/obj/item/radio/intercom{
|
||||
broadcasting = 0;
|
||||
name = "station intercom (General)";
|
||||
@@ -51723,9 +51698,6 @@
|
||||
pixel_x = 0;
|
||||
pixel_y = 32
|
||||
},
|
||||
/obj/machinery/computer/skills{
|
||||
req_access_txt = "57"
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/crew_quarters/heads)
|
||||
"bTd" = (
|
||||
@@ -61633,9 +61605,6 @@
|
||||
/area/ntrep)
|
||||
"cjf" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/machinery/computer/skills{
|
||||
req_access_txt = "57"
|
||||
},
|
||||
/turf/simulated/floor/carpet,
|
||||
/area/ntrep)
|
||||
"cjg" = (
|
||||
@@ -66311,9 +66280,6 @@
|
||||
/area/blueshield)
|
||||
"cqJ" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/machinery/computer/skills{
|
||||
req_one_access = null
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "bcarpet05"
|
||||
},
|
||||
@@ -72578,7 +72544,7 @@
|
||||
pixel_x = -2;
|
||||
pixel_y = 2
|
||||
},
|
||||
/obj/item/circuitboard/stationalert_all{
|
||||
/obj/item/circuitboard/stationalert{
|
||||
pixel_x = 1;
|
||||
pixel_y = -1
|
||||
},
|
||||
@@ -75846,7 +75812,7 @@
|
||||
pixel_x = 32;
|
||||
pixel_y = 0
|
||||
},
|
||||
/obj/machinery/computer/station_alert/all,
|
||||
/obj/machinery/computer/station_alert,
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
@@ -77210,6 +77176,10 @@
|
||||
pixel_x = -22
|
||||
},
|
||||
/obj/item/stack/tape_roll,
|
||||
/obj/machinery/camera/motion{
|
||||
c_tag = "EVA Motion Sensor";
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
@@ -95350,6 +95320,11 @@
|
||||
icon_state = "vault"
|
||||
},
|
||||
/area/shuttle/escape)
|
||||
"kIR" = (
|
||||
/obj/structure/lattice/catwalk,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/yellow,
|
||||
/turf/space,
|
||||
/area/space/nearstation)
|
||||
"kLF" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 9
|
||||
@@ -95983,11 +95958,6 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
|
||||
/turf/simulated/wall,
|
||||
/area/crew_quarters/dorms)
|
||||
"rOX" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/yellow,
|
||||
/obj/machinery/ntnet_relay,
|
||||
/turf/simulated/floor/plasteel/dark,
|
||||
/area/tcommsat/chamber)
|
||||
"rSv" = (
|
||||
/obj/structure/shuttle/engine/propulsion{
|
||||
dir = 8;
|
||||
@@ -96034,10 +96004,6 @@
|
||||
icon_state = "floor4"
|
||||
},
|
||||
/area/shuttle/administration)
|
||||
"sag" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
/turf/simulated/floor/plasteel/dark,
|
||||
/area/tcommsat/chamber)
|
||||
"sbp" = (
|
||||
/turf/simulated/shuttle/wall{
|
||||
icon_state = "wall3"
|
||||
@@ -115862,7 +115828,7 @@ aKb
|
||||
aNx
|
||||
aVi
|
||||
aWt
|
||||
aXS
|
||||
aXQ
|
||||
aZr
|
||||
bbp
|
||||
bdk
|
||||
@@ -131635,7 +131601,7 @@ dmW
|
||||
aaa
|
||||
aab
|
||||
aaa
|
||||
iUc
|
||||
aaa
|
||||
iUc
|
||||
iUc
|
||||
iUc
|
||||
@@ -131892,10 +131858,10 @@ ddC
|
||||
doE
|
||||
ddM
|
||||
ddO
|
||||
kIR
|
||||
oOZ
|
||||
dQC
|
||||
fAw
|
||||
rOX
|
||||
mkE
|
||||
dpe
|
||||
dpl
|
||||
@@ -132150,8 +132116,8 @@ dmB
|
||||
bfu
|
||||
dnT
|
||||
dpf
|
||||
iUc
|
||||
rTy
|
||||
sag
|
||||
wbr
|
||||
hyv
|
||||
dpd
|
||||
|
||||
@@ -4296,55 +4296,20 @@
|
||||
dir = 2
|
||||
},
|
||||
/area/centcom/control)
|
||||
"mE" = (
|
||||
/obj/structure/flora/ausbushes/lavendergrass,
|
||||
/turf/unsimulated/floor{
|
||||
icon_state = "grass1";
|
||||
name = "grass"
|
||||
},
|
||||
/area/centcom/specops)
|
||||
"mF" = (
|
||||
/obj/structure/flora/ausbushes/stalkybush,
|
||||
/turf/unsimulated/floor{
|
||||
icon_state = "grass1";
|
||||
name = "grass"
|
||||
},
|
||||
/area/centcom/specops)
|
||||
"mG" = (
|
||||
/obj/structure/flora/ausbushes/pointybush,
|
||||
/turf/unsimulated/floor{
|
||||
icon_state = "grass1";
|
||||
name = "grass"
|
||||
},
|
||||
/area/centcom/specops)
|
||||
"mH" = (
|
||||
/obj/structure/flora/ausbushes/ywflowers,
|
||||
/turf/unsimulated/floor{
|
||||
icon_state = "grass1";
|
||||
name = "grass"
|
||||
},
|
||||
/area/centcom/specops)
|
||||
"mI" = (
|
||||
/obj/structure/flora/ausbushes/brflowers,
|
||||
/turf/unsimulated/floor{
|
||||
icon_state = "grass1";
|
||||
name = "grass"
|
||||
},
|
||||
/area/centcom/specops)
|
||||
"mJ" = (
|
||||
/obj/structure/flora/ausbushes/sparsegrass,
|
||||
/turf/unsimulated/floor{
|
||||
icon_state = "grass1";
|
||||
name = "grass"
|
||||
},
|
||||
/area/centcom/specops)
|
||||
/area/centcom/control)
|
||||
"mK" = (
|
||||
/obj/structure/flora/ausbushes/reedbush,
|
||||
/turf/unsimulated/floor{
|
||||
icon_state = "grass1";
|
||||
name = "grass"
|
||||
},
|
||||
/area/centcom/specops)
|
||||
/area/centcom/control)
|
||||
"mL" = (
|
||||
/turf/unsimulated/floor{
|
||||
dir = 1;
|
||||
@@ -9891,7 +9856,7 @@
|
||||
},
|
||||
/area/admin)
|
||||
"xV" = (
|
||||
/obj/machinery/computer/ordercomp,
|
||||
/obj/machinery/computer/supplycomp/public,
|
||||
/turf/unsimulated/floor{
|
||||
tag = "icon-floor";
|
||||
icon_state = "floor"
|
||||
@@ -36255,7 +36220,7 @@ lH
|
||||
lH
|
||||
mu
|
||||
su
|
||||
mF
|
||||
mZ
|
||||
mY
|
||||
su
|
||||
nD
|
||||
@@ -36512,7 +36477,7 @@ mc
|
||||
lH
|
||||
lH
|
||||
su
|
||||
mE
|
||||
nd
|
||||
mX
|
||||
su
|
||||
nD
|
||||
@@ -36769,7 +36734,7 @@ mc
|
||||
lH
|
||||
lH
|
||||
su
|
||||
mH
|
||||
mY
|
||||
na
|
||||
su
|
||||
nD
|
||||
@@ -37026,7 +36991,7 @@ lH
|
||||
lH
|
||||
lH
|
||||
su
|
||||
mG
|
||||
WW
|
||||
mZ
|
||||
su
|
||||
nD
|
||||
@@ -37283,7 +37248,7 @@ lH
|
||||
mk
|
||||
mw
|
||||
su
|
||||
mJ
|
||||
na
|
||||
ne
|
||||
su
|
||||
nD
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -173,6 +173,7 @@ GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new())
|
||||
add_fingerprint(user)
|
||||
|
||||
var/unsafe_wrenching = FALSE
|
||||
var/safefromgusts = FALSE
|
||||
var/I = int_air ? int_air.return_pressure() : 0
|
||||
var/E = env_air ? env_air.return_pressure() : 0
|
||||
var/internal_pressure = I - E
|
||||
@@ -190,9 +191,16 @@ GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new())
|
||||
"<span class='italics'>You hear ratchet.</span>")
|
||||
investigate_log("was <span class='warning'>REMOVED</span> by [key_name(usr)]", "atmos")
|
||||
|
||||
for(var/obj/item/clothing/shoes/magboots/usermagboots in user.get_equipped_items())
|
||||
if(usermagboots.gustprotection && usermagboots.magpulse)
|
||||
safefromgusts = TRUE
|
||||
|
||||
//You unwrenched a pipe full of pressure? let's splat you into the wall silly.
|
||||
if(unsafe_wrenching)
|
||||
unsafe_pressure_release(user,internal_pressure)
|
||||
if(safefromgusts)
|
||||
to_chat(user, "<span class='italics'>Your magboots cling to the floor as a great burst of wind bellows against you.</span>")
|
||||
else
|
||||
unsafe_pressure_release(user,internal_pressure)
|
||||
deconstruct(TRUE)
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -137,51 +137,56 @@
|
||||
return
|
||||
|
||||
add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
|
||||
/obj/machinery/atmospherics/binary/passive_gate/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
user.set_machine(src)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 385, 115, state = state)
|
||||
ui = new(user, src, ui_key, "AtmosPump", name, 310, 110, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["on"] = on
|
||||
data["pressure"] = round(target_pressure)
|
||||
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
|
||||
/obj/machinery/atmospherics/binary/passive_gate/tgui_data(mob/user)
|
||||
var/list/data = list(
|
||||
"on" = on,
|
||||
"rate" = round(target_pressure),
|
||||
"max_rate" = MAX_OUTPUT_PRESSURE,
|
||||
"gas_unit" = "kPa",
|
||||
"step" = 10 // This is for the TGUI <NumberInput> step. It's here since multiple pumps share the same UI, but need different values.
|
||||
)
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/Topic(href,href_list)
|
||||
/obj/machinery/atmospherics/binary/passive_gate/tgui_act(action, list/params)
|
||||
if(..())
|
||||
return 1
|
||||
return
|
||||
|
||||
if(href_list["power"])
|
||||
switch(action)
|
||||
if("power")
|
||||
toggle()
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
return TRUE
|
||||
|
||||
if("max_rate")
|
||||
target_pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
|
||||
if("min_rate")
|
||||
target_pressure = 0
|
||||
. = TRUE
|
||||
|
||||
if("custom_rate")
|
||||
target_pressure = clamp(text2num(params["rate"]), 0 , MAX_OUTPUT_PRESSURE)
|
||||
. = TRUE
|
||||
if(.)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/proc/toggle()
|
||||
if(powered())
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if(href_list["pressure"])
|
||||
var/pressure = href_list["pressure"]
|
||||
if(pressure == "max")
|
||||
pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "input")
|
||||
pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
|
||||
if(!isnull(pressure))
|
||||
. = TRUE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/attackby(obj/item/W, mob/user, params)
|
||||
if(!istype(W, /obj/item/wrench))
|
||||
|
||||
@@ -192,51 +192,51 @@ Thus, the two variables affect pump operation are set in New():
|
||||
return
|
||||
|
||||
add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
|
||||
/obj/machinery/atmospherics/binary/pump/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
user.set_machine(src)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 385, 115, state = state)
|
||||
ui = new(user, src, ui_key, "AtmosPump", name, 310, 110, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["on"] = on
|
||||
data["pressure"] = round(target_pressure)
|
||||
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
|
||||
/obj/machinery/atmospherics/binary/pump/tgui_data(mob/user)
|
||||
var/list/data = list(
|
||||
"on" = on,
|
||||
"rate" = round(target_pressure),
|
||||
"max_rate" = MAX_OUTPUT_PRESSURE,
|
||||
"gas_unit" = "kPa",
|
||||
"step" = 10 // This is for the TGUI <NumberInput> step. It's here since multiple pumps share the same UI, but need different values.
|
||||
)
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/Topic(href,href_list)
|
||||
/obj/machinery/atmospherics/binary/pump/tgui_act(action, list/params)
|
||||
if(..())
|
||||
return 1
|
||||
return
|
||||
|
||||
if(href_list["power"])
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if(href_list["pressure"])
|
||||
var/pressure = href_list["pressure"]
|
||||
if(pressure == "max")
|
||||
pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "input")
|
||||
pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
|
||||
if(!isnull(pressure))
|
||||
. = TRUE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
switch(action)
|
||||
if("power")
|
||||
toggle()
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
return TRUE
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
if("max_rate")
|
||||
target_pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
|
||||
if("min_rate")
|
||||
target_pressure = 0
|
||||
. = TRUE
|
||||
|
||||
if("custom_rate")
|
||||
target_pressure = clamp(text2num(params["rate"]), 0 , MAX_OUTPUT_PRESSURE)
|
||||
. = TRUE
|
||||
if(.)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/power_change()
|
||||
var/old_stat = stat
|
||||
|
||||
@@ -188,51 +188,51 @@ Thus, the two variables affect pump operation are set in New():
|
||||
return
|
||||
|
||||
add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/binary/volume_pump/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/binary/volume_pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
|
||||
/obj/machinery/atmospherics/binary/volume_pump/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
user.set_machine(src)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 310, 115, state = state)
|
||||
ui = new(user, src, ui_key, "AtmosPump", name, 310, 110, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/binary/volume_pump/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["on"] = on
|
||||
data["rate"] = round(transfer_rate)
|
||||
data["max_rate"] = round(MAX_TRANSFER_RATE)
|
||||
/obj/machinery/atmospherics/binary/volume_pump/tgui_data(mob/user)
|
||||
var/list/data = list(
|
||||
"on" = on,
|
||||
"rate" = round(transfer_rate),
|
||||
"max_rate" = round(MAX_TRANSFER_RATE),
|
||||
"gas_unit" = "L/s",
|
||||
"step" = 1 // This is for the TGUI <NumberInput> step. It's here since multiple pumps share the same UI, but need different values.
|
||||
)
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/binary/volume_pump/Topic(href,href_list)
|
||||
/obj/machinery/atmospherics/binary/volume_pump/tgui_act(action, list/params)
|
||||
if(..())
|
||||
return 1
|
||||
return
|
||||
|
||||
if(href_list["power"])
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if(href_list["rate"])
|
||||
var/rate = href_list["rate"]
|
||||
if(rate == "max")
|
||||
rate = MAX_TRANSFER_RATE
|
||||
. = TRUE
|
||||
else if(rate == "input")
|
||||
rate = input("New transfer rate (0-[MAX_TRANSFER_RATE] L/s):", name, transfer_rate) as num|null
|
||||
if(!isnull(rate))
|
||||
. = TRUE
|
||||
else if(text2num(rate) != null)
|
||||
rate = text2num(rate)
|
||||
. = TRUE
|
||||
if(.)
|
||||
transfer_rate = clamp(rate, 0, MAX_TRANSFER_RATE)
|
||||
investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", "atmos")
|
||||
switch(action)
|
||||
if("power")
|
||||
toggle()
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
return TRUE
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
if("max_rate")
|
||||
transfer_rate = MAX_TRANSFER_RATE
|
||||
. = TRUE
|
||||
|
||||
if("min_rate")
|
||||
transfer_rate = 0
|
||||
. = TRUE
|
||||
|
||||
if("custom_rate")
|
||||
transfer_rate = clamp(text2num(params["rate"]), 0 , MAX_TRANSFER_RATE)
|
||||
. = TRUE
|
||||
if(.)
|
||||
investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", "atmos")
|
||||
|
||||
/obj/machinery/atmospherics/binary/volume_pump/power_change()
|
||||
var/old_stat = stat
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
//--------------------------------------------
|
||||
// Omni device port types
|
||||
//--------------------------------------------
|
||||
#define ATM_NONE 0
|
||||
#define ATM_INPUT 1
|
||||
#define ATM_OUTPUT 2
|
||||
|
||||
#define ATM_O2 3
|
||||
#define ATM_N2 4
|
||||
#define ATM_CO2 5
|
||||
#define ATM_P 6 //Plasma
|
||||
#define ATM_N2O 7
|
||||
|
||||
//--------------------------------------------
|
||||
// Omni port datum
|
||||
//
|
||||
// Used by omni devices to manage connections
|
||||
// to other atmospheric objects.
|
||||
//--------------------------------------------
|
||||
/datum/omni_port
|
||||
var/obj/machinery/atmospherics/omni/master
|
||||
var/dir
|
||||
var/update = 1
|
||||
var/mode = 0
|
||||
var/concentration = 0
|
||||
var/con_lock = 0
|
||||
var/transfer_moles = 0
|
||||
var/datum/gas_mixture/air
|
||||
var/obj/machinery/atmospherics/node
|
||||
var/datum/pipeline/parent
|
||||
|
||||
/datum/omni_port/New(var/obj/machinery/atmospherics/omni/M, var/direction = NORTH)
|
||||
..()
|
||||
dir = direction
|
||||
if(istype(M))
|
||||
master = M
|
||||
air = new
|
||||
air.volume = 200
|
||||
|
||||
/datum/omni_port/proc/connect()
|
||||
if(node)
|
||||
return
|
||||
master.atmos_init()
|
||||
if(node)
|
||||
node.atmos_init()
|
||||
node.addMember(master)
|
||||
master.build_network()
|
||||
|
||||
/datum/omni_port/proc/disconnect()
|
||||
if(node)
|
||||
node.disconnect(master)
|
||||
node = null
|
||||
master.nullifyPipenet(parent)
|
||||
|
||||
//--------------------------------------------
|
||||
// Need to find somewhere else for these
|
||||
//--------------------------------------------
|
||||
|
||||
//returns a text string based on the direction flag input
|
||||
// if capitalize is true, it will return the string capitalized
|
||||
// otherwise it will return the direction string in lower case
|
||||
/proc/dir_name(var/dir, var/capitalize = 0)
|
||||
var/string = null
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
string = "North"
|
||||
if(SOUTH)
|
||||
string = "South"
|
||||
if(EAST)
|
||||
string = "East"
|
||||
if(WEST)
|
||||
string = "West"
|
||||
|
||||
if(!capitalize && string)
|
||||
string = lowertext(string)
|
||||
|
||||
return string
|
||||
|
||||
//returns a direction flag based on the string passed to it
|
||||
// case insensitive
|
||||
/proc/dir_flag(var/dir)
|
||||
dir = lowertext(dir)
|
||||
switch(dir)
|
||||
if("north")
|
||||
return NORTH
|
||||
if("south")
|
||||
return SOUTH
|
||||
if("east")
|
||||
return EAST
|
||||
if("west")
|
||||
return WEST
|
||||
else
|
||||
return 0
|
||||
|
||||
@@ -1,273 +0,0 @@
|
||||
//--------------------------------------------
|
||||
// Gas filter - omni variant
|
||||
//--------------------------------------------
|
||||
/obj/machinery/atmospherics/omni/filter
|
||||
name = "omni gas filter"
|
||||
icon_state = "map_filter"
|
||||
|
||||
var/list/o_filters = new()
|
||||
var/datum/omni_port/input
|
||||
var/datum/omni_port/output
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/Destroy()
|
||||
input = null
|
||||
output = null
|
||||
o_filters.Cut()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/sort_ports()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.update)
|
||||
if(output == P)
|
||||
output = null
|
||||
if(input == P)
|
||||
input = null
|
||||
if(o_filters.Find(P))
|
||||
o_filters -= P
|
||||
|
||||
P.air.volume = 200
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
input = P
|
||||
if(ATM_OUTPUT)
|
||||
output = P
|
||||
if(ATM_O2 to ATM_N2O)
|
||||
o_filters += P
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/error_check()
|
||||
if(!input || !output || !o_filters)
|
||||
return 1
|
||||
if(o_filters.len < 1 || o_filters.len > 2) //requires 1 or 2 o_filters ~otherwise why are you using a filter?
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/process_atmos()
|
||||
..()
|
||||
if(!on)
|
||||
return 0
|
||||
|
||||
if(!input || !output)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/output_air = output.air //BYOND doesn't like referencing "output.air.return_pressure()" so we need to make a direct reference
|
||||
var/datum/gas_mixture/input_air = input.air // it's completely happy with them if they're in a loop though i.e. "P.air.return_pressure()"... *shrug*
|
||||
|
||||
var/output_pressure = output_air.return_pressure()
|
||||
|
||||
if(output_pressure >= target_pressure)
|
||||
return 1
|
||||
for(var/datum/omni_port/P in o_filters)
|
||||
if(P.air.return_pressure() >= target_pressure)
|
||||
return 1
|
||||
|
||||
var/pressure_delta = target_pressure - output_pressure
|
||||
|
||||
if(input_air.return_temperature() > 0)
|
||||
input.transfer_moles = pressure_delta * output_air.volume / (input_air.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
if(input.transfer_moles > 0)
|
||||
var/datum/gas_mixture/removed = input_air.remove(input.transfer_moles)
|
||||
|
||||
if(!removed)
|
||||
return 1
|
||||
|
||||
for(var/datum/omni_port/P in o_filters)
|
||||
var/datum/gas_mixture/filtered_out = new
|
||||
filtered_out.temperature = removed.return_temperature()
|
||||
|
||||
switch(P.mode)
|
||||
if(ATM_O2)
|
||||
filtered_out.oxygen = removed.oxygen
|
||||
removed.oxygen = 0
|
||||
if(ATM_N2)
|
||||
filtered_out.nitrogen = removed.nitrogen
|
||||
removed.nitrogen = 0
|
||||
if(ATM_CO2)
|
||||
filtered_out.carbon_dioxide = removed.carbon_dioxide
|
||||
removed.carbon_dioxide = 0
|
||||
if(ATM_P)
|
||||
filtered_out.toxins = removed.toxins
|
||||
removed.toxins = 0
|
||||
|
||||
filtered_out.agent_b = removed.agent_b
|
||||
removed.agent_b = 0
|
||||
if(ATM_N2O)
|
||||
filtered_out.sleeping_agent = removed.sleeping_agent
|
||||
removed.sleeping_agent = 0
|
||||
else
|
||||
filtered_out = null
|
||||
|
||||
P.air.merge(filtered_out)
|
||||
P.parent.update = 1
|
||||
|
||||
output_air.merge(removed)
|
||||
output.parent.update = 1
|
||||
|
||||
input.transfer_moles = 0
|
||||
input.parent.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0)
|
||||
usr.set_machine(src)
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "omni_filter.tmpl", "Omni Filter Control", 330, 330)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/ui_data(mob/user, datum/topic_state/state)
|
||||
var/data[0]
|
||||
|
||||
data["power"] = on
|
||||
data["config"] = configuring
|
||||
|
||||
var/portData[0]
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(!configuring && P.mode == 0)
|
||||
continue
|
||||
|
||||
var/input = 0
|
||||
var/output = 0
|
||||
var/filter = 1
|
||||
var/f_type = null
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
input = 1
|
||||
filter = 0
|
||||
if(ATM_OUTPUT)
|
||||
output = 1
|
||||
filter = 0
|
||||
if(ATM_O2 to ATM_N2O)
|
||||
f_type = mode_send_switch(P.mode)
|
||||
|
||||
portData[++portData.len] = list("dir" = dir_name(P.dir, capitalize = 1), \
|
||||
"input" = input, \
|
||||
"output" = output, \
|
||||
"filter" = filter, \
|
||||
"f_type" = f_type)
|
||||
|
||||
if(portData.len)
|
||||
data["ports"] = portData
|
||||
if(output)
|
||||
data["pressure"] = target_pressure
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/mode_send_switch(var/mode = ATM_NONE)
|
||||
switch(mode)
|
||||
if(ATM_O2)
|
||||
return "Oxygen"
|
||||
if(ATM_N2)
|
||||
return "Nitrogen"
|
||||
if(ATM_CO2)
|
||||
return "Carbon Dioxide"
|
||||
if(ATM_P)
|
||||
return "Plasma" //*cough* Plasma *cough*
|
||||
if(ATM_N2O)
|
||||
return "Nitrous Oxide"
|
||||
else
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
switch(href_list["command"])
|
||||
if("power")
|
||||
if(!configuring)
|
||||
on = !on
|
||||
else
|
||||
on = 0
|
||||
if("configure")
|
||||
configuring = !configuring
|
||||
if(configuring)
|
||||
on = 0
|
||||
|
||||
//only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on
|
||||
if(configuring && !on)
|
||||
switch(href_list["command"])
|
||||
if("set_pressure")
|
||||
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",target_pressure) as num
|
||||
target_pressure = between(0, new_pressure, 4500)
|
||||
if("switch_mode")
|
||||
switch_mode(dir_flag(href_list["dir"]), mode_return_switch(href_list["mode"]))
|
||||
if("switch_filter")
|
||||
var/new_filter = input(usr,"Select filter mode:","Change filter",href_list["mode"]) in list("None", "Oxygen", "Nitrogen", "Carbon Dioxide", "Plasma", "Nitrous Oxide")
|
||||
switch_filter(dir_flag(href_list["dir"]), mode_return_switch(new_filter))
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/mode_return_switch(var/mode)
|
||||
switch(mode)
|
||||
if("Oxygen")
|
||||
return ATM_O2
|
||||
if("Nitrogen")
|
||||
return ATM_N2
|
||||
if("Carbon Dioxide")
|
||||
return ATM_CO2
|
||||
if("Plasma")
|
||||
return ATM_P
|
||||
if("Nitrous Oxide")
|
||||
return ATM_N2O
|
||||
if("in")
|
||||
return ATM_INPUT
|
||||
if("out")
|
||||
return ATM_OUTPUT
|
||||
if("None")
|
||||
return ATM_NONE
|
||||
else
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/switch_filter(var/dir, var/mode)
|
||||
//check they aren't trying to disable the input or output ~this can only happen if they hack the cached tmpl file
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.dir == dir)
|
||||
if(P.mode == ATM_INPUT || P.mode == ATM_OUTPUT)
|
||||
return
|
||||
|
||||
switch_mode(dir, mode)
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/switch_mode(var/port, var/mode)
|
||||
if(mode == null || !port)
|
||||
return
|
||||
var/datum/omni_port/target_port = null
|
||||
var/list/other_ports = new()
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.dir == port)
|
||||
target_port = P
|
||||
else
|
||||
other_ports += P
|
||||
|
||||
var/previous_mode = null
|
||||
if(target_port)
|
||||
previous_mode = target_port.mode
|
||||
target_port.mode = mode
|
||||
if(target_port.mode != previous_mode)
|
||||
handle_port_change(target_port)
|
||||
else
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
for(var/datum/omni_port/P in other_ports)
|
||||
if(P.mode == mode)
|
||||
var/old_mode = P.mode
|
||||
P.mode = previous_mode
|
||||
if(P.mode != old_mode)
|
||||
handle_port_change(P)
|
||||
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/handle_port_change(var/datum/omni_port/P)
|
||||
switch(P.mode)
|
||||
if(ATM_NONE)
|
||||
initialize_directions &= ~P.dir
|
||||
P.disconnect()
|
||||
else
|
||||
initialize_directions |= P.dir
|
||||
P.connect()
|
||||
P.update = 1
|
||||
@@ -1,291 +0,0 @@
|
||||
//--------------------------------------------
|
||||
// Gas mixer - omni variant
|
||||
//--------------------------------------------
|
||||
/obj/machinery/atmospherics/omni/mixer
|
||||
name = "omni gas mixer"
|
||||
icon_state = "map_mixer"
|
||||
|
||||
var/list/inputs = new()
|
||||
var/datum/omni_port/output
|
||||
|
||||
//setup tags for initial concentration values (must be decimal)
|
||||
var/tag_north_con
|
||||
var/tag_south_con
|
||||
var/tag_east_con
|
||||
var/tag_west_con
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/New()
|
||||
..()
|
||||
if(mapper_set())
|
||||
var/con = 0
|
||||
for(var/datum/omni_port/P in ports)
|
||||
switch(P.dir)
|
||||
if(NORTH)
|
||||
if(tag_north_con && tag_north == 1)
|
||||
P.concentration = tag_north_con
|
||||
con += max(0, tag_north_con)
|
||||
if(SOUTH)
|
||||
if(tag_south_con && tag_south == 1)
|
||||
P.concentration = tag_south_con
|
||||
con += max(0, tag_south_con)
|
||||
if(EAST)
|
||||
if(tag_east_con && tag_east == 1)
|
||||
P.concentration = tag_east_con
|
||||
con += max(0, tag_east_con)
|
||||
if(WEST)
|
||||
if(tag_west_con && tag_west == 1)
|
||||
P.concentration = tag_west_con
|
||||
con += max(0, tag_west_con)
|
||||
|
||||
//mappers who are bad at maths will be punished (total concentration must be 100%)
|
||||
if(con != 1)
|
||||
tag_north_con = null
|
||||
tag_south_con = null
|
||||
tag_east_con = null
|
||||
tag_west_con = null
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/Destroy()
|
||||
inputs.Cut()
|
||||
output = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/sort_ports()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.update)
|
||||
if(output == P)
|
||||
output = null
|
||||
if(inputs.Find(P))
|
||||
inputs -= P
|
||||
|
||||
P.air.volume = 200
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
inputs += P
|
||||
if(ATM_OUTPUT)
|
||||
output = P
|
||||
|
||||
if(!mapper_set())
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
P.concentration = 1 / max(1, inputs.len)
|
||||
|
||||
if(output)
|
||||
output.air.volume *= 0.75 * inputs.len
|
||||
output.concentration = 1
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/mapper_set()
|
||||
return (tag_north_con || tag_south_con || tag_east_con || tag_west_con)
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/error_check()
|
||||
if(!output || !inputs)
|
||||
return 1
|
||||
if(inputs.len < 2 || inputs.len > 3) //requires 2 or 3 inputs ~otherwise why are you using a mixer?
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/process_atmos()
|
||||
..()
|
||||
if(!on)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/output_air = output.air
|
||||
var/output_pressure = output_air.return_pressure()
|
||||
|
||||
|
||||
if(output_pressure >= target_pressure * 0.999)
|
||||
//No need to mix if target is already full! - 0.1% margin of error so we minimize processing minor gas volumes
|
||||
return 1
|
||||
|
||||
//Calculate necessary moles to transfer using PV=nRT
|
||||
|
||||
var/pressure_delta = target_pressure - output_pressure
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.air.return_temperature() > 0)
|
||||
P.transfer_moles = (P.concentration * pressure_delta) * output_air.return_volume() / (P.air.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/ratio_check = null
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(!P.transfer_moles)
|
||||
return 1
|
||||
if(P.air.total_moles() < P.transfer_moles)
|
||||
ratio_check = 1
|
||||
continue
|
||||
|
||||
if(ratio_check)
|
||||
var/list/ratio_list = new()
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
ratio_list.Add(P.air.total_moles() / P.transfer_moles)
|
||||
|
||||
var/ratio = min(ratio_list)
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
P.transfer_moles *= ratio
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.transfer_moles > 0)
|
||||
output_air.merge(P.air.remove(P.transfer_moles))
|
||||
P.parent.update = 1
|
||||
P.transfer_moles = 0
|
||||
|
||||
output.parent.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0)
|
||||
usr.set_machine(src)
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "omni_mixer.tmpl", "Omni Mixer Control", 360, 330)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/ui_data(mob/user, datum/topic_state/state)
|
||||
var/data[0]
|
||||
|
||||
data["power"] = on
|
||||
data["config"] = configuring
|
||||
|
||||
var/portData[0]
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(!configuring && P.mode == 0)
|
||||
continue
|
||||
|
||||
var/input = 0
|
||||
var/output = 0
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
input = 1
|
||||
if(ATM_OUTPUT)
|
||||
output = 1
|
||||
|
||||
portData[++portData.len] = list("dir" = dir_name(P.dir, capitalize = 1), \
|
||||
"concentration" = P.concentration, \
|
||||
"input" = input, \
|
||||
"output" = output, \
|
||||
"con_lock" = P.con_lock)
|
||||
|
||||
if(portData.len)
|
||||
data["ports"] = portData
|
||||
if(output)
|
||||
data["pressure"] = target_pressure
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
switch(href_list["command"])
|
||||
if("power")
|
||||
if(!configuring)
|
||||
on = !on
|
||||
else
|
||||
on = 0
|
||||
if("configure")
|
||||
configuring = !configuring
|
||||
if(configuring)
|
||||
on = 0
|
||||
|
||||
//only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on
|
||||
if(configuring && !on)
|
||||
switch(href_list["command"])
|
||||
if("set_pressure")
|
||||
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",target_pressure) as num
|
||||
target_pressure = between(0, new_pressure, 4500)
|
||||
if("switch_mode")
|
||||
switch_mode(dir_flag(href_list["dir"]), href_list["mode"])
|
||||
if("switch_con")
|
||||
change_concentration(dir_flag(href_list["dir"]))
|
||||
if("switch_conlock")
|
||||
con_lock(dir_flag(href_list["dir"]))
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/switch_mode(var/port = NORTH, var/mode = ATM_NONE)
|
||||
if(mode != ATM_INPUT && mode != ATM_OUTPUT)
|
||||
switch(mode)
|
||||
if("in")
|
||||
mode = ATM_INPUT
|
||||
if("out")
|
||||
mode = ATM_OUTPUT
|
||||
else
|
||||
mode = ATM_NONE
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
var/old_mode = P.mode
|
||||
if(P.dir == port)
|
||||
switch(mode)
|
||||
if(ATM_INPUT)
|
||||
if(P.mode == ATM_OUTPUT)
|
||||
return
|
||||
P.mode = mode
|
||||
if(ATM_OUTPUT)
|
||||
P.mode = mode
|
||||
if(ATM_NONE)
|
||||
if(P.mode == ATM_OUTPUT)
|
||||
return
|
||||
if(P.mode == ATM_INPUT && inputs.len > 2)
|
||||
P.mode = mode
|
||||
else if(P.mode == ATM_OUTPUT && mode == ATM_OUTPUT)
|
||||
P.mode = ATM_INPUT
|
||||
if(P.mode != old_mode)
|
||||
switch(P.mode)
|
||||
if(ATM_NONE)
|
||||
initialize_directions &= ~P.dir
|
||||
P.disconnect()
|
||||
else
|
||||
initialize_directions |= P.dir
|
||||
P.connect()
|
||||
P.update = 1
|
||||
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/change_concentration(var/port = NORTH)
|
||||
tag_north_con = null
|
||||
tag_south_con = null
|
||||
tag_east_con = null
|
||||
tag_west_con = null
|
||||
|
||||
var/old_con = 0
|
||||
var/non_locked = 0
|
||||
var/remain_con = 1
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.dir == port)
|
||||
old_con = P.concentration
|
||||
else if(!P.con_lock)
|
||||
non_locked++
|
||||
else
|
||||
remain_con -= P.concentration
|
||||
|
||||
//return if no adjustable ports
|
||||
if(non_locked < 1)
|
||||
return
|
||||
|
||||
var/new_con = (input(usr,"Enter a new concentration (0-[round(remain_con * 100, 0.5)])%","Concentration control", min(remain_con, old_con)*100) as num) / 100
|
||||
|
||||
//cap it between 0 and the max remaining concentration
|
||||
new_con = between(0, new_con, remain_con)
|
||||
|
||||
//new_con = min(remain_con, new_con)
|
||||
|
||||
//clamp remaining concentration so we don't go into negatives
|
||||
remain_con = max(0, remain_con - new_con)
|
||||
|
||||
//distribute remaining concentration between unlocked ports evenly
|
||||
remain_con /= max(1, non_locked)
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.dir == port)
|
||||
P.concentration = new_con
|
||||
else if(!P.con_lock)
|
||||
P.concentration = remain_con
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/con_lock(var/port = NORTH)
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.dir == port)
|
||||
P.con_lock = !P.con_lock
|
||||
@@ -1,302 +0,0 @@
|
||||
//--------------------------------------------
|
||||
// Base omni device
|
||||
//--------------------------------------------
|
||||
/obj/machinery/atmospherics/omni
|
||||
name = "omni device"
|
||||
icon = 'icons/atmos/omni_devices.dmi'
|
||||
icon_state = "base"
|
||||
use_power = IDLE_POWER_USE
|
||||
initialize_directions = 0
|
||||
|
||||
can_unwrench = 1
|
||||
|
||||
var/on = 0
|
||||
var/configuring = 0
|
||||
var/target_pressure = ONE_ATMOSPHERE
|
||||
|
||||
var/tag_north = ATM_NONE
|
||||
var/tag_south = ATM_NONE
|
||||
var/tag_east = ATM_NONE
|
||||
var/tag_west = ATM_NONE
|
||||
|
||||
var/overlays_on[5]
|
||||
var/overlays_off[5]
|
||||
var/overlays_error[2]
|
||||
var/underlays_current[4]
|
||||
|
||||
var/list/ports = new()
|
||||
|
||||
/obj/machinery/atmospherics/omni/New()
|
||||
..()
|
||||
icon_state = "base"
|
||||
|
||||
ports = new()
|
||||
for(var/d in GLOB.cardinal)
|
||||
var/datum/omni_port/new_port = new(src, d)
|
||||
switch(d)
|
||||
if(NORTH)
|
||||
new_port.mode = tag_north
|
||||
if(SOUTH)
|
||||
new_port.mode = tag_south
|
||||
if(EAST)
|
||||
new_port.mode = tag_east
|
||||
if(WEST)
|
||||
new_port.mode = tag_west
|
||||
if(new_port.mode > 0)
|
||||
initialize_directions |= d
|
||||
ports += new_port
|
||||
|
||||
build_icons()
|
||||
|
||||
/obj/machinery/atmospherics/omni/Destroy()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.node)
|
||||
P.node.disconnect(src)
|
||||
P.node = null
|
||||
nullifyPipenet(P.parent)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/atmos_init()
|
||||
..()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.node || P.mode == 0)
|
||||
continue
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src, P.dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
P.node = target
|
||||
break
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
P.update = 1
|
||||
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/update_icon()
|
||||
..()
|
||||
|
||||
if(stat & NOPOWER)
|
||||
overlays = overlays_off
|
||||
on = 0
|
||||
else if(error_check())
|
||||
overlays = overlays_error
|
||||
on = 0
|
||||
else
|
||||
overlays = on ? (overlays_on) : (overlays_off)
|
||||
|
||||
underlays = underlays_current
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/error_check()
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/omni/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/omni/attackby(var/obj/item/W as obj, var/mob/user as mob, params)
|
||||
if(!istype(W, /obj/item/wrench))
|
||||
return ..()
|
||||
|
||||
if(can_unwrench)
|
||||
var/int_pressure = 0
|
||||
for(var/datum/omni_port/P in ports)
|
||||
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)
|
||||
to_chat(user, "<span class='danger'>You cannot unwrench [src], it is too exerted due to internal pressure.</span>")
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
if(do_after(user, 40 * W.toolspeed, target = src))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
|
||||
add_fingerprint(usr)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/omni/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/build_icons()
|
||||
if(!check_icon_cache())
|
||||
return
|
||||
|
||||
var/core_icon = null
|
||||
if(istype(src, /obj/machinery/atmospherics/omni/mixer))
|
||||
core_icon = "mixer"
|
||||
else if(istype(src, /obj/machinery/atmospherics/omni/filter))
|
||||
core_icon = "filter"
|
||||
else
|
||||
return
|
||||
|
||||
//directional icons are layers 1-4, with the core icon on layer 5
|
||||
if(core_icon)
|
||||
overlays_off[5] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon)
|
||||
overlays_on[5] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon + "_glow")
|
||||
|
||||
overlays_error[1] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon)
|
||||
overlays_error[2] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , "error")
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/update_port_icons()
|
||||
if(!check_icon_cache())
|
||||
return
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.update)
|
||||
var/ref_layer = 0
|
||||
switch(P.dir)
|
||||
if(NORTH)
|
||||
ref_layer = 1
|
||||
if(SOUTH)
|
||||
ref_layer = 2
|
||||
if(EAST)
|
||||
ref_layer = 3
|
||||
if(WEST)
|
||||
ref_layer = 4
|
||||
|
||||
if(!ref_layer)
|
||||
continue
|
||||
|
||||
var/list/port_icons = select_port_icons(P)
|
||||
if(port_icons)
|
||||
if(P.node)
|
||||
underlays_current[ref_layer] = port_icons["pipe_icon"]
|
||||
else
|
||||
underlays_current[ref_layer] = null
|
||||
overlays_off[ref_layer] = port_icons["off_icon"]
|
||||
overlays_on[ref_layer] = port_icons["on_icon"]
|
||||
else
|
||||
underlays_current[ref_layer] = null
|
||||
overlays_off[ref_layer] = null
|
||||
overlays_on[ref_layer] = null
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/select_port_icons(var/datum/omni_port/P)
|
||||
if(!istype(P))
|
||||
return
|
||||
|
||||
if(P.mode > 0)
|
||||
var/ic_dir = dir_name(P.dir)
|
||||
var/ic_on = ic_dir
|
||||
var/ic_off = ic_dir
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
ic_on += "_in_glow"
|
||||
ic_off += "_in"
|
||||
if(ATM_OUTPUT)
|
||||
ic_on += "_out_glow"
|
||||
ic_off += "_out"
|
||||
if(ATM_O2 to ATM_N2O)
|
||||
ic_on += "_filter"
|
||||
ic_off += "_out"
|
||||
|
||||
ic_on = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , ic_on)
|
||||
ic_off = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , ic_off)
|
||||
|
||||
var/pipe_state
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(T.intact && istype(P.node, /obj/machinery/atmospherics/pipe) && P.node.level == 1 )
|
||||
//pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay_down", P.dir, color_cache_name(P.node))
|
||||
pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "down")
|
||||
else
|
||||
//pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay_intact", P.dir, color_cache_name(P.node))
|
||||
pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "intact")
|
||||
|
||||
return list("on_icon" = ic_on, "off_icon" = ic_off, "pipe_icon" = pipe_state)
|
||||
|
||||
/obj/machinery/atmospherics/omni/update_underlays()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
P.update = 1
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/hide(var/i)
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/update_ports()
|
||||
sort_ports()
|
||||
update_port_icons()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
P.update = 0
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/sort_ports()
|
||||
return
|
||||
|
||||
// Pipenet procs
|
||||
/obj/machinery/atmospherics/omni/build_network(remove_deferral = FALSE)
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(!P.parent)
|
||||
P.parent = new /datum/pipeline()
|
||||
P.parent.build_pipeline(src)
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/disconnect(obj/machinery/atmospherics/reference)
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(reference == P.node)
|
||||
if(istype(P.node, /obj/machinery/atmospherics/pipe))
|
||||
qdel(P.parent)
|
||||
P.node = null
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/nullifyPipenet(datum/pipeline/P)
|
||||
..()
|
||||
if(!P)
|
||||
return
|
||||
for(var/datum/omni_port/PO in ports)
|
||||
if(P == PO.parent)
|
||||
PO.parent.other_airs -= PO.air
|
||||
PO.parent = null
|
||||
|
||||
/obj/machinery/atmospherics/omni/returnPipenetAir(datum/pipeline/P)
|
||||
for(var/datum/omni_port/PO in ports)
|
||||
if(P == PO.parent)
|
||||
return PO.air
|
||||
|
||||
/obj/machinery/atmospherics/omni/pipeline_expansion(datum/pipeline/P)
|
||||
if(P)
|
||||
for(var/datum/omni_port/PO in ports)
|
||||
if(PO.parent == P)
|
||||
return list(PO.node)
|
||||
else
|
||||
var/list/nodes = list()
|
||||
for(var/datum/omni_port/PO in ports)
|
||||
nodes += PO.node
|
||||
|
||||
return nodes
|
||||
|
||||
/obj/machinery/atmospherics/omni/setPipenet(datum/pipeline/P, obj/machinery/atmospherics/A)
|
||||
for(var/datum/omni_port/PO in ports)
|
||||
if(A == PO.node)
|
||||
PO.parent = P
|
||||
|
||||
/obj/machinery/atmospherics/omni/returnPipenet(obj/machinery/atmospherics/A)
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(A == P.node)
|
||||
return P.parent
|
||||
|
||||
/obj/machinery/atmospherics/omni/replacePipenet(datum/pipeline/Old, datum/pipeline/New)
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(Old == P.parent)
|
||||
P.parent = New
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/omni/process_atmos()
|
||||
..()
|
||||
for(var/datum/omni_port/port in ports)
|
||||
if(!port.parent)
|
||||
return 0
|
||||
return 1
|
||||
@@ -1,26 +1,39 @@
|
||||
|
||||
/// Nothing will be filtered.
|
||||
#define FILTER_NOTHING -1
|
||||
/// Plasma, and Oxygen Agent B.
|
||||
#define FILTER_TOXINS 0
|
||||
/// Oxygen only.
|
||||
#define FILTER_OXYGEN 1
|
||||
/// Nitrogen only.
|
||||
#define FILTER_NITROGEN 2
|
||||
/// Carbon dioxide only.
|
||||
#define FILTER_CO2 3
|
||||
/// Nitrous oxide only.
|
||||
#define FILTER_N2O 4
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter
|
||||
name = "gas filter"
|
||||
icon = 'icons/atmos/filter.dmi'
|
||||
icon_state = "map"
|
||||
|
||||
can_unwrench = 1
|
||||
|
||||
name = "gas filter"
|
||||
|
||||
can_unwrench = TRUE
|
||||
/// The amount of pressure the filter wants to operate at.
|
||||
var/target_pressure = ONE_ATMOSPHERE
|
||||
|
||||
var/filter_type = 0
|
||||
/*
|
||||
Filter types:
|
||||
-1: Nothing
|
||||
0: Toxins: Toxins, Oxygen Agent B
|
||||
1: Oxygen: Oxygen ONLY
|
||||
2: Nitrogen: Nitrogen ONLY
|
||||
3: Carbon Dioxide: Carbon Dioxide ONLY
|
||||
4: Sleeping Agent (N2O)
|
||||
*/
|
||||
|
||||
var/frequency = 0
|
||||
/// The type of gas we want to filter. Valid values that go here are from the `FILTER` defines at the top of the file.
|
||||
var/filter_type = FILTER_NOTHING
|
||||
/// The frequency of the filter. Used with `radio_connection`.
|
||||
var/frequency = NONE
|
||||
/// A reference to the filter's `datum/radio_frequency`.
|
||||
var/datum/radio_frequency/radio_connection
|
||||
/// A list of available filter options. Used with `tgui_data`.
|
||||
var/list/filter_list = list(
|
||||
"Nothing" = FILTER_NOTHING,
|
||||
"Plasma" = FILTER_TOXINS,
|
||||
"O2" = FILTER_OXYGEN,
|
||||
"N2" = FILTER_NITROGEN,
|
||||
"CO2" = FILTER_CO2,
|
||||
"N2O" = FILTER_N2O
|
||||
)
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/CtrlClick(mob/living/user)
|
||||
if(!istype(user) || user.incapacitated())
|
||||
@@ -146,26 +159,26 @@ Filter types:
|
||||
filtered_out.temperature = removed.temperature
|
||||
|
||||
switch(filter_type)
|
||||
if(0) //removing hydrocarbons
|
||||
if(FILTER_TOXINS)
|
||||
filtered_out.toxins = removed.toxins
|
||||
removed.toxins = 0
|
||||
|
||||
filtered_out.agent_b = removed.agent_b
|
||||
removed.agent_b = 0
|
||||
|
||||
if(1) //removing O2
|
||||
if(FILTER_OXYGEN)
|
||||
filtered_out.oxygen = removed.oxygen
|
||||
removed.oxygen = 0
|
||||
|
||||
if(2) //removing N2
|
||||
if(FILTER_NITROGEN)
|
||||
filtered_out.nitrogen = removed.nitrogen
|
||||
removed.nitrogen = 0
|
||||
|
||||
if(3) //removing CO2
|
||||
if(FILTER_CO2)
|
||||
filtered_out.carbon_dioxide = removed.carbon_dioxide
|
||||
removed.carbon_dioxide = 0
|
||||
|
||||
if(4)//removing N2O
|
||||
if(FILTER_N2O)
|
||||
filtered_out.sleeping_agent = removed.sleeping_agent
|
||||
removed.sleeping_agent = 0
|
||||
else
|
||||
@@ -188,7 +201,7 @@ Filter types:
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/attack_hand(mob/user)
|
||||
if(..())
|
||||
@@ -199,53 +212,56 @@ Filter types:
|
||||
return
|
||||
|
||||
add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
|
||||
/obj/machinery/atmospherics/trinary/filter/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
user.set_machine(src)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_filter.tmpl", name, 475, 155, state = state)
|
||||
ui = new(user, src, ui_key, "AtmosFilter", name, 380, 140, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["on"] = on
|
||||
data["pressure"] = round(target_pressure)
|
||||
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
|
||||
data["filter_type"] = filter_type
|
||||
/obj/machinery/atmospherics/trinary/filter/tgui_data(mob/user)
|
||||
var/list/data = list(
|
||||
"on" = on,
|
||||
"pressure" = round(target_pressure),
|
||||
"max_pressure" = round(MAX_OUTPUT_PRESSURE),
|
||||
"filter_type" = filter_type
|
||||
)
|
||||
data["filter_type_list"] = list()
|
||||
for(var/label in filter_list)
|
||||
data["filter_type_list"] += list(list("label" = label, "gas_type" = filter_list[label]))
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/Topic(href, href_list) // -- TLE
|
||||
/obj/machinery/atmospherics/trinary/filter/tgui_act(action, list/params)
|
||||
if(..())
|
||||
return 1
|
||||
return
|
||||
|
||||
if(href_list["power"])
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if(href_list["pressure"])
|
||||
var/pressure = href_list["pressure"]
|
||||
if(pressure == "max")
|
||||
pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "input")
|
||||
pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
|
||||
if(!isnull(pressure) && !..())
|
||||
. = TRUE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
if(href_list["filter"])
|
||||
filter_type = text2num(href_list["filter"])
|
||||
investigate_log("was set to filter [filter_type] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("power")
|
||||
toggle()
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
return TRUE
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
if("set_filter")
|
||||
filter_type = text2num(params["filter"])
|
||||
investigate_log("was set to filter [filter_type] by [key_name(usr)]", "atmos")
|
||||
return TRUE
|
||||
|
||||
if("max_pressure")
|
||||
target_pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
|
||||
if("min_pressure")
|
||||
target_pressure = 0
|
||||
. = TRUE
|
||||
|
||||
if("custom_pressure")
|
||||
target_pressure = clamp(text2num(params["pressure"]), 0, MAX_OUTPUT_PRESSURE)
|
||||
. = TRUE
|
||||
if(.)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/pen))
|
||||
@@ -258,3 +274,10 @@ Filter types:
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
#undef FILTER_NOTHING
|
||||
#undef FILTER_TOXINS
|
||||
#undef FILTER_OXYGEN
|
||||
#undef FILTER_NITROGEN
|
||||
#undef FILTER_CO2
|
||||
#undef FILTER_N2O
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/trinary/mixer/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/trinary/mixer/attack_hand(mob/user)
|
||||
if(..())
|
||||
@@ -163,62 +163,62 @@
|
||||
return
|
||||
|
||||
add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/trinary/mixer/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
|
||||
/obj/machinery/atmospherics/trinary/mixer/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
user.set_machine(src)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_mixer.tmpl", name, 370, 165, state = state)
|
||||
ui = new(user, src, ui_key, "AtmosMixer", name, 330, 165, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/trinary/mixer/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["on"] = on
|
||||
data["pressure"] = round(target_pressure)
|
||||
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
|
||||
data["node1_concentration"] = round(node1_concentration*100)
|
||||
data["node2_concentration"] = round(node2_concentration*100)
|
||||
/obj/machinery/atmospherics/trinary/mixer/tgui_data(mob/user)
|
||||
var/list/data = list(
|
||||
"on" = on,
|
||||
"pressure" = round(target_pressure, 0.01),
|
||||
"max_pressure" = MAX_OUTPUT_PRESSURE,
|
||||
"node1_concentration" = round(node1_concentration * 100),
|
||||
"node2_concentration" = round(node2_concentration * 100)
|
||||
)
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/trinary/mixer/Topic(href,href_list)
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/trinary/mixer/tgui_act(action, list/params)
|
||||
if(..())
|
||||
return 1
|
||||
return
|
||||
|
||||
if(href_list["power"])
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if(href_list["pressure"])
|
||||
var/pressure = href_list["pressure"]
|
||||
if(pressure == "max")
|
||||
pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "input")
|
||||
pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
|
||||
if(!isnull(pressure) && !..())
|
||||
. = TRUE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
if(href_list["node1"])
|
||||
var/value = text2num(href_list["node1"])
|
||||
node1_concentration = max(0, min(1, node1_concentration + value))
|
||||
node2_concentration = max(0, min(1, node2_concentration - value))
|
||||
investigate_log("was set to [node1_concentration] % on node 1 by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if(href_list["node2"])
|
||||
var/value = text2num(href_list["node2"])
|
||||
node2_concentration = max(0, min(1, node2_concentration + value))
|
||||
node1_concentration = max(0, min(1, node1_concentration - value))
|
||||
investigate_log("was set to [node2_concentration] % on node 2 by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("power")
|
||||
toggle()
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
return TRUE
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
if("set_node")
|
||||
if(params["node_name"] == "Node 1")
|
||||
node1_concentration = clamp(round(text2num(params["concentration"]), 0.01), 0, 1)
|
||||
node2_concentration = round(1 - node1_concentration, 0.01)
|
||||
investigate_log("was set to [node1_concentration] % on node 1 by [key_name(usr)]", "atmos")
|
||||
return TRUE
|
||||
else
|
||||
node2_concentration = clamp(round(text2num(params["concentration"]), 0.01), 0, 1)
|
||||
node1_concentration = round(1 - node2_concentration, 0.01)
|
||||
investigate_log("was set to [node2_concentration] % on node 2 by [key_name(usr)]", "atmos")
|
||||
return TRUE
|
||||
|
||||
if("max_pressure")
|
||||
target_pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
|
||||
if("min_pressure")
|
||||
target_pressure = 0
|
||||
. = TRUE
|
||||
|
||||
if("custom_pressure")
|
||||
target_pressure = clamp(text2num(params["pressure"]), 0, MAX_OUTPUT_PRESSURE)
|
||||
. = TRUE
|
||||
if(.)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
|
||||
/obj/machinery/atmospherics/trinary/mixer/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/pen))
|
||||
|
||||
@@ -128,66 +128,56 @@
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/process_atmos()
|
||||
..()
|
||||
if((stat & (NOPOWER|BROKEN)))
|
||||
return 0
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return FALSE
|
||||
if(!node)
|
||||
on = 0
|
||||
on = FALSE
|
||||
//broadcast_status() // from now air alarm/control computer should request update purposely --rastaf0
|
||||
if(!on)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(welded)
|
||||
if(air_contents.return_pressure() >= weld_burst_pressure && prob(5)) //the weld is on but the cover is welded shut, can it withstand the internal pressure?
|
||||
visible_message("<span class='danger'>The welded cover of [src] bursts open!</span>")
|
||||
for(var/mob/M in range(1, src))
|
||||
for(var/mob/living/M in range(1))
|
||||
unsafe_pressure_release(M, air_contents.return_pressure()) //let's send everyone flying
|
||||
welded = FALSE
|
||||
update_icon()
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
var/environment_pressure = environment.return_pressure()
|
||||
|
||||
if(pump_direction) //internal -> external
|
||||
var/pressure_delta = 10000
|
||||
|
||||
if(pressure_checks&1)
|
||||
if(pressure_checks & 1)
|
||||
pressure_delta = min(pressure_delta, (external_pressure_bound - environment_pressure))
|
||||
if(pressure_checks&2)
|
||||
if(pressure_checks & 2)
|
||||
pressure_delta = min(pressure_delta, (air_contents.return_pressure() - internal_pressure_bound))
|
||||
|
||||
if(pressure_delta > 0.5)
|
||||
if(air_contents.temperature > 0)
|
||||
var/transfer_moles = pressure_delta*environment.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
||||
|
||||
loc.assume_air(removed)
|
||||
air_update_turf()
|
||||
|
||||
parent.update = 1
|
||||
if(pressure_delta > 0.5 && air_contents.temperature > 0)
|
||||
var/transfer_moles = pressure_delta * environment.volume / (air_contents.temperature * R_IDEAL_GAS_EQUATION)
|
||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
||||
loc.assume_air(removed)
|
||||
air_update_turf()
|
||||
parent.update = TRUE
|
||||
|
||||
else //external -> internal
|
||||
var/pressure_delta = 10000
|
||||
if(pressure_checks&1)
|
||||
if(pressure_checks & 1)
|
||||
pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_bound))
|
||||
if(pressure_checks&2)
|
||||
if(pressure_checks & 2)
|
||||
pressure_delta = min(pressure_delta, (internal_pressure_bound - air_contents.return_pressure()))
|
||||
|
||||
if(pressure_delta > 0.5)
|
||||
if(environment.temperature > 0)
|
||||
var/transfer_moles = pressure_delta*air_contents.volume/(environment.temperature * R_IDEAL_GAS_EQUATION)
|
||||
if(pressure_delta > 0.5 && environment.temperature > 0)
|
||||
var/transfer_moles = pressure_delta * air_contents.volume / (environment.temperature * R_IDEAL_GAS_EQUATION)
|
||||
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
|
||||
if(isnull(removed)) //in space
|
||||
return
|
||||
air_contents.merge(removed)
|
||||
air_update_turf()
|
||||
parent.update = TRUE
|
||||
|
||||
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
|
||||
if(isnull(removed)) //in space
|
||||
return
|
||||
|
||||
air_contents.merge(removed)
|
||||
air_update_turf()
|
||||
|
||||
parent.update = 1
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//Radio remote control
|
||||
|
||||
@@ -386,11 +376,11 @@
|
||||
if(I.use_tool(src, user, 20, volume = I.tool_volume))
|
||||
if(!welded)
|
||||
welded = TRUE
|
||||
visible_message("<span class='notice'>[user] welds [src] shut!</span>",\
|
||||
user.visible_message("<span class='notice'>[user] welds [src] shut!</span>",\
|
||||
"<span class='notice'>You weld [src] shut!</span>")
|
||||
else
|
||||
welded = FALSE
|
||||
visible_message("<span class='notice'>[user] unwelds [src]!</span>",\
|
||||
user.visible_message("<span class='notice'>[user] unwelds [src]!</span>",\
|
||||
"<span class='notice'>You unweld [src]!</span>")
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -404,10 +404,10 @@
|
||||
if(I.use_tool(src, user, 20, volume = I.tool_volume))
|
||||
if(!welded)
|
||||
welded = TRUE
|
||||
visible_message("<span class='notice'>[user] welds [src] shut!</span>",\
|
||||
user.visible_message("<span class='notice'>[user] welds [src] shut!</span>",\
|
||||
"<span class='notice'>You weld [src] shut!</span>")
|
||||
else
|
||||
welded = FALSE
|
||||
visible_message("<span class='notice'>[user] unwelds [src]!</span>",\
|
||||
user.visible_message("<span class='notice'>[user] unwelds [src]!</span>",\
|
||||
"<span class='notice'>You unweld [src]!</span>")
|
||||
update_icon()
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
//var/list/underlays_intact[]
|
||||
//var/list/pipe_underlays_exposed[]
|
||||
//var/list/pipe_underlays_intact[]
|
||||
var/list/omni_icons[]
|
||||
|
||||
/datum/pipe_icon_manager/New()
|
||||
check_icons()
|
||||
@@ -53,8 +52,6 @@
|
||||
return manifold_icons[state + color]
|
||||
if("device")
|
||||
return device_icons[state]
|
||||
if("omni")
|
||||
return omni_icons[state]
|
||||
if("underlay")
|
||||
return underlays[state + dir + color]
|
||||
//if("underlay_intact")
|
||||
@@ -75,8 +72,6 @@
|
||||
gen_manifold_icons()
|
||||
if(!device_icons)
|
||||
gen_device_icons()
|
||||
if(!omni_icons)
|
||||
gen_omni_icons()
|
||||
//if(!underlays_intact || !underlays_down || !underlays_exposed || !pipe_underlays_exposed || !pipe_underlays_intact)
|
||||
if(!underlays)
|
||||
gen_underlay_icons()
|
||||
@@ -150,18 +145,6 @@
|
||||
continue
|
||||
device_icons["scrubber" + state] = image('icons/atmos/vent_scrubber.dmi', icon_state = state)
|
||||
|
||||
/datum/pipe_icon_manager/proc/gen_omni_icons()
|
||||
if(!omni_icons)
|
||||
omni_icons = new()
|
||||
|
||||
var/icon/omni = new('icons/atmos/omni_devices.dmi')
|
||||
|
||||
for(var/state in omni.IconStates())
|
||||
if(!state || findtext(state, "map"))
|
||||
continue
|
||||
omni_icons[state] = image('icons/atmos/omni_devices.dmi', icon_state = state)
|
||||
|
||||
|
||||
/datum/pipe_icon_manager/proc/gen_underlay_icons()
|
||||
|
||||
if(!underlays)
|
||||
|
||||
@@ -32,13 +32,13 @@
|
||||
if(!R)
|
||||
return 1
|
||||
|
||||
atom/movable/proc/CanAtmosPass()
|
||||
/atom/movable/proc/CanAtmosPass()
|
||||
return 1
|
||||
|
||||
atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5)
|
||||
/atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5)
|
||||
return (!density || !height)
|
||||
|
||||
turf/CanPass(atom/movable/mover, turf/target, height=1.5)
|
||||
/turf/CanPass(atom/movable/mover, turf/target, height=1.5)
|
||||
if(!target) return 0
|
||||
|
||||
if(istype(mover)) // turf/Enter(...) will perform more advanced checks
|
||||
|
||||
@@ -473,7 +473,7 @@
|
||||
SSair.active_super_conductivity -= src
|
||||
return 0
|
||||
|
||||
turf/simulated/proc/consider_superconductivity(starting)
|
||||
/turf/simulated/proc/consider_superconductivity(starting)
|
||||
if(!thermal_conductivity)
|
||||
return 0
|
||||
|
||||
@@ -489,7 +489,7 @@ turf/simulated/proc/consider_superconductivity(starting)
|
||||
SSair.active_super_conductivity |= src
|
||||
return 1
|
||||
|
||||
turf/simulated/proc/radiate_to_spess() //Radiate excess tile heat to space
|
||||
/turf/simulated/proc/radiate_to_spess() //Radiate excess tile heat to space
|
||||
if(temperature > T0C) //Considering 0 degC as te break even point for radiation in and out
|
||||
var/delta_temperature = (temperature_archived - TCMB) //hardcoded space temperature
|
||||
if((heat_capacity > 0) && (abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER))
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
#define AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS 1
|
||||
#define AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER 2
|
||||
|
||||
//used by airlocks and airlock wires.
|
||||
#define AICONTROLDISABLED_OFF 0 // Silicons can control the airlock normally.
|
||||
#define AICONTROLDISABLED_ON 1 // Silicons cannot control the airlock, but can hack the airlock.
|
||||
#define AICONTROLDISABLED_BYPASS 2 // Silicons can control the airlock because they succeeded on the hack
|
||||
#define AICONTROLDISABLED_PERMA 3 // Wire cutting an airlock on AICONTROLDISABLED_BYPASS toggles it between AICONTROLDISABLED_BYPASS and this.
|
||||
|
||||
//plastic flaps construction states
|
||||
#define PLASTIC_FLAPS_NORMAL 0
|
||||
#define PLASTIC_FLAPS_DETACHED 1
|
||||
|
||||
@@ -726,3 +726,7 @@
|
||||
#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt"
|
||||
///from monkey CtrlClickOn(): (/mob)
|
||||
#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl"
|
||||
|
||||
///SSalarm signals
|
||||
#define COMSIG_TRIGGERED_ALARM "ssalarm_triggered"
|
||||
#define COMSIG_CANCELLED_ALARM "ssalarm_cancelled"
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#define INSTRUMENT_MIN_OCTAVE 1
|
||||
#define INSTRUMENT_MAX_OCTAVE 9
|
||||
#define INSTRUMENT_MIN_KEY 0
|
||||
#define INSTRUMENT_MAX_KEY 127
|
||||
|
||||
/// Max number of playing notes per instrument.
|
||||
#define CHANNELS_PER_INSTRUMENT 128
|
||||
|
||||
/// Distance multiplier that makes us not be impacted by 3d sound as much. This is a multiplier so lower it is the closer we will pretend to be to people.
|
||||
#define INSTRUMENT_DISTANCE_FALLOFF_BUFF 0.2
|
||||
/// How many tiles instruments have no falloff for
|
||||
#define INSTRUMENT_DISTANCE_NO_FALLOFF 3
|
||||
|
||||
/// Maximum length a note should ever go for
|
||||
#define INSTRUMENT_MAX_TOTAL_SUSTAIN (5 SECONDS)
|
||||
|
||||
/// These are per decisecond.
|
||||
#define INSTRUMENT_EXP_FALLOFF_MIN 1.025 //100/(1.025^50) calculated for [INSTRUMENT_MIN_SUSTAIN_DROPOFF] to be 30.
|
||||
#define INSTRUMENT_EXP_FALLOFF_MAX 10
|
||||
|
||||
/// Minimum volume for when the sound is considered dead.
|
||||
#define INSTRUMENT_MIN_SUSTAIN_DROPOFF 0.1
|
||||
|
||||
#define SUSTAIN_LINEAR 1
|
||||
#define SUSTAIN_EXPONENTIAL 2
|
||||
|
||||
// /datum/instrument instrument_flags
|
||||
#define INSTRUMENT_LEGACY (1<<0) //Legacy instrument. Implies INSTRUMENT_DO_NOT_AUTOSAMPLE
|
||||
#define INSTRUMENT_DO_NOT_AUTOSAMPLE (1<<1) //Do not automatically sample
|
||||
@@ -36,7 +36,7 @@ Be sure to include required js functions in your page, or it'll raise an excepti
|
||||
|
||||
And yes I know this is a proc in a defines file, but its highly relevant so it can be here
|
||||
*/
|
||||
proc/send_byjax(receiver, control_id, target_element, new_content=null, callback=null, list/callback_args=null)
|
||||
/proc/send_byjax(receiver, control_id, target_element, new_content=null, callback=null, list/callback_args=null)
|
||||
if(receiver && target_element && control_id) // && winexists(receiver, control_id))
|
||||
var/list/argums = list(target_element, new_content)
|
||||
if(callback)
|
||||
|
||||
@@ -92,3 +92,9 @@
|
||||
// Firelock states
|
||||
#define FD_OPEN 1
|
||||
#define FD_CLOSED 2
|
||||
|
||||
// Computer login types
|
||||
#define LOGIN_TYPE_NORMAL 1
|
||||
#define LOGIN_TYPE_AI 2
|
||||
#define LOGIN_TYPE_ROBOT 3
|
||||
#define LOGIN_TYPE_ADMIN 4
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#define MARTIAL_COMBO_FAIL 0 // If the combo failed
|
||||
#define MARTIAL_COMBO_CONTINUE 1 // If the combo should continue
|
||||
#define MARTIAL_COMBO_DONE 2 // If the combo is successful and done
|
||||
#define MARTIAL_COMBO_DONE_NO_CLEAR 3 // If the combo is successful and done but the others should have a chance to finish
|
||||
#define MARTIAL_COMBO_DONE_BASIC_HIT 4 // If the combo should do a basic hit after it's done
|
||||
#define MARTIAL_COMBO_DONE_CLEAR_COMBOS 5 // If the combo should do a basic hit after it's done
|
||||
|
||||
#define MARTIAL_ARTS_CANNOT_USE -1
|
||||
|
||||
#define MARTIAL_COMBO_STEP_HARM "Harm"
|
||||
#define MARTIAL_COMBO_STEP_DISARM "Disarm"
|
||||
#define MARTIAL_COMBO_STEP_GRAB "Grab"
|
||||
#define MARTIAL_COMBO_STEP_HELP "Help"
|
||||
|
||||
// A check used for all act types. Such as disarm_act
|
||||
#define MARTIAL_ARTS_ACT_CHECK if((. = ..()) != FALSE) return .
|
||||
+60
-16
@@ -69,9 +69,6 @@
|
||||
#define ZONE_ACTIVE 1
|
||||
#define ZONE_SLEEPING 0
|
||||
|
||||
#define shuttle_time_in_station 1800 // 3 minutes in the station
|
||||
#define shuttle_time_to_arrive 6000 // 10 minutes to arrive
|
||||
|
||||
#define EVENT_LEVEL_MUNDANE 1
|
||||
#define EVENT_LEVEL_MODERATE 2
|
||||
#define EVENT_LEVEL_MAJOR 3
|
||||
@@ -245,28 +242,75 @@
|
||||
0.4,0.6,0.0,\
|
||||
0.2,0.2,0.6)
|
||||
|
||||
#define LIST_REPLACE_RENAME list("rebeccapurple" = "dark purple", "darkslategrey" = "dark grey", "darkolivegreen" = "dark green", "darkslateblue" = "dark blue",\
|
||||
"darkkhaki" = "khaki", "darkseagreen" = "light green", "midnightblue" = "blue", "lightgrey" = "light grey", "darkgrey" = "dark grey",\
|
||||
"steelblue" = "blue", "goldenrod" = "gold")
|
||||
/*
|
||||
Used for wire name appearances. Replaces the color name on the left with the one on the right.
|
||||
The color on the left is the one used as the actual color of the wire, but it doesn't look good when written.
|
||||
So, we need to replace the name to something that looks better.
|
||||
*/
|
||||
#define LIST_COLOR_RENAME \
|
||||
list( \
|
||||
"rebeccapurple" = "dark purple",\
|
||||
"darkslategrey" = "dark grey", \
|
||||
"darkolivegreen"= "dark green", \
|
||||
"darkslateblue" = "dark blue", \
|
||||
"darkkhaki" = "khaki", \
|
||||
"darkseagreen" = "light green",\
|
||||
"midnightblue" = "blue", \
|
||||
"lightgrey" = "light grey", \
|
||||
"darkgrey" = "dark grey", \
|
||||
"steelblue" = "blue", \
|
||||
"goldenrod" = "gold" \
|
||||
)
|
||||
|
||||
#define LIST_GREYSCALE_REPLACE list("red" = "lightgrey", "blue" = "grey", "green" = "grey", "orange" = "lightgrey", "brown" = "grey",\
|
||||
"gold" = "lightgrey", "cyan" = "lightgrey", "navy" = "grey", "purple" = "grey", "pink"= "lightgrey")
|
||||
/// Pure Black and white colorblindness. Every species except Vulpkanins and Tajarans will have this.
|
||||
#define GREYSCALE_COLOR_REPLACE \
|
||||
list( \
|
||||
"red" = "grey", \
|
||||
"blue" = "grey", \
|
||||
"green" = "grey", \
|
||||
"orange" = "light grey", \
|
||||
"brown" = "grey", \
|
||||
"gold" = "light grey", \
|
||||
"cyan" = "silver", \
|
||||
"magenta" = "grey", \
|
||||
"purple" = "grey", \
|
||||
"pink" = "light grey" \
|
||||
)
|
||||
|
||||
#define LIST_VULP_REPLACE list("pink" = "beige", "orange" = "goldenrod", "gold" = "goldenrod", "red" = "darkolivegreen", "brown" = "darkolivegreen",\
|
||||
"green" = "darkslategrey", "cyan" = "steelblue", "purple" = "darkslategrey", "navy" = "midnightblue")
|
||||
|
||||
#define LIST_TAJ_REPLACE list("red" = "rebeccapurple", "brown" = "rebeccapurple", "purple" = "darkslateblue", "blue" = "darkslateblue",\
|
||||
"green" = "darkolivegreen", "orange" = "darkkhaki", "gold" = "darkkhaki", "cyan" = "darkseagreen", \
|
||||
"navy" = "midnightblue", "pink" = "lightgrey")
|
||||
/// Red colorblindness. Vulpkanins/Wolpins have this.
|
||||
#define PROTANOPIA_COLOR_REPLACE \
|
||||
list( \
|
||||
"red" = "darkolivegreen", \
|
||||
"green" = "darkslategrey", \
|
||||
"orange" = "goldenrod", \
|
||||
"gold" = "goldenrod", \
|
||||
"brown" = "darkolivegreen", \
|
||||
"cyan" = "steelblue", \
|
||||
"magenta" = "blue", \
|
||||
"purple" = "darkslategrey", \
|
||||
"pink" = "beige" \
|
||||
)
|
||||
|
||||
/// Yellow-Blue colorblindness. Tajarans/Farwas have this.
|
||||
#define TRITANOPIA_COLOR_REPLACE \
|
||||
list( \
|
||||
"red" = "rebeccapurple", \
|
||||
"blue" = "darkslateblue", \
|
||||
"green" = "darkolivegreen", \
|
||||
"orange" = "darkkhaki", \
|
||||
"gold" = "darkkhaki", \
|
||||
"brown" = "rebeccapurple", \
|
||||
"cyan" = "darkseagreen", \
|
||||
"magenta" = "darkslateblue", \
|
||||
"purple" = "darkslateblue", \
|
||||
"pink" = "lightgrey" \
|
||||
)
|
||||
|
||||
//Gun trigger guards
|
||||
#define TRIGGER_GUARD_ALLOW_ALL -1
|
||||
#define TRIGGER_GUARD_NONE 0
|
||||
#define TRIGGER_GUARD_NORMAL 1
|
||||
|
||||
#define CLIENT_FROM_VAR(I) (ismob(I) ? I:client : (istype(I, /client) ? I : (istype(I, /datum/mind) ? I:current?:client : null)))
|
||||
|
||||
// Macro to get the current elapsed round time, rather than total world runtime
|
||||
#define ROUND_TIME (SSticker.round_start_time ? (world.time - SSticker.round_start_time) : 0)
|
||||
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
#define isguardian(A) (istype((A), /mob/living/simple_animal/hostile/guardian))
|
||||
#define isnymph(A) (istype((A), /mob/living/simple_animal/diona))
|
||||
#define ishostile(A) (istype(A, /mob/living/simple_animal/hostile))
|
||||
#define isterrorspider(A) (istype((A), /mob/living/simple_animal/hostile/poison/terror_spider))
|
||||
|
||||
#define issilicon(A) (istype((A), /mob/living/silicon))
|
||||
#define isAI(A) (istype((A), /mob/living/silicon/ai))
|
||||
@@ -240,3 +241,12 @@
|
||||
#define is_admin(user) (check_rights(R_ADMIN, 0, (user)) != 0)
|
||||
|
||||
#define SLEEP_CHECK_DEATH(X) sleep(X); if(QDELETED(src) || stat == DEAD) return;
|
||||
|
||||
// Locations
|
||||
#define is_ventcrawling(A) (istype(A.loc, /obj/machinery/atmospherics))
|
||||
|
||||
// Hearing protection
|
||||
#define HEARING_PROTECTION_NONE 0
|
||||
#define HEARING_PROTECTION_MINOR 1
|
||||
#define HEARING_PROTECTION_MAJOR 2
|
||||
#define HEARING_PROTECTION_TOTAL 3
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#define MUZZLE_FLASH_STRENGTH_WEAK 1
|
||||
#define MUZZLE_FLASH_STRENGTH_NORMAL 2
|
||||
#define MUZZLE_FLASH_STRENGTH_STRONG 3
|
||||
|
||||
#define MUZZLE_FLASH_RANGE_WEAK 1
|
||||
#define MUZZLE_FLASH_RANGE_NORMAL 2
|
||||
#define MUZZLE_FLASH_RANGE_STRONG 3
|
||||
@@ -21,8 +21,6 @@
|
||||
#define PIPE_TVALVE 18
|
||||
#define PIPE_MANIFOLD4W 19
|
||||
#define PIPE_CAP 20
|
||||
#define PIPE_OMNI_MIXER 21
|
||||
#define PIPE_OMNI_FILTER 22
|
||||
#define PIPE_UNIVERSAL 23
|
||||
#define PIPE_SUPPLY_STRAIGHT 24
|
||||
#define PIPE_SUPPLY_BENT 25
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#define CHANNEL_HIGHEST_AVAILABLE 1017
|
||||
|
||||
#define MAX_INSTRUMENT_CHANNELS (128 * 6)
|
||||
|
||||
#define SOUND_MINIMUM_PRESSURE 10
|
||||
#define FALLOFF_SOUNDS 0.5
|
||||
|
||||
+3
-10
@@ -22,16 +22,9 @@
|
||||
|
||||
// these define the time taken for the shuttle to get to SS13
|
||||
// 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.
|
||||
|
||||
//Ferry shuttle processing status
|
||||
#define IDLE_STATE 0
|
||||
#define WAIT_LAUNCH 1
|
||||
#define WAIT_ARRIVE 2
|
||||
#define WAIT_FINISH 3
|
||||
#define SHUTTLE_CALLTIME 6000 //10 minutes = 6000 deciseconds - time taken for emergency shuttle to reach the station when called (in deciseconds)
|
||||
#define SHUTTLE_DOCKTIME 1800 //3 minutes = 1800 deciseconds - time taken for emergency shuttle to leave again once it has docked (in deciseconds)
|
||||
#define SHUTTLE_ESCAPETIME 1200 //2 minutes = 1200 deciseconds - time taken for emergency shuttle to reach a safe distance after leaving station (in deciseconds)
|
||||
|
||||
//shuttle mode defines
|
||||
#define SHUTTLE_IGNITING 0
|
||||
|
||||
@@ -45,11 +45,13 @@
|
||||
// Subsystems shutdown in the reverse of the order they initialize in
|
||||
// The numbers just define the ordering, they are meaningless otherwise.
|
||||
#define INIT_ORDER_TITLE 100 // This **MUST** load first or people will se blank lobby screens
|
||||
#define INIT_ORDER_GARBAGE 19
|
||||
#define INIT_ORDER_DBCORE 18
|
||||
#define INIT_ORDER_BLACKBOX 17
|
||||
#define INIT_ORDER_SERVER_MAINT 16
|
||||
#define INIT_ORDER_INPUT 15
|
||||
#define INIT_ORDER_GARBAGE 21
|
||||
#define INIT_ORDER_DBCORE 20
|
||||
#define INIT_ORDER_BLACKBOX 19
|
||||
#define INIT_ORDER_CLEANUP 18
|
||||
#define INIT_ORDER_INPUT 17
|
||||
#define INIT_ORDER_SOUNDS 16
|
||||
#define INIT_ORDER_INSTRUMENTS 15
|
||||
#define INIT_ORDER_RESEARCH 14
|
||||
#define INIT_ORDER_EVENTS 13
|
||||
#define INIT_ORDER_JOBS 12
|
||||
@@ -80,8 +82,7 @@
|
||||
#define INIT_ORDER_NANOMOB -23
|
||||
#define INIT_ORDER_SQUEAK -40
|
||||
#define INIT_ORDER_PATH -50
|
||||
#define INIT_ORDER_PERSISTENCE -95
|
||||
#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
|
||||
#define INIT_ORDER_PERSISTENCE -95
|
||||
|
||||
// Subsystem fire priority, from lowest to highest priority
|
||||
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
|
||||
@@ -89,7 +90,7 @@
|
||||
#define FIRE_PRIORITY_NANOMOB 10
|
||||
#define FIRE_PRIORITY_NIGHTSHIFT 10
|
||||
#define FIRE_PRIORITY_IDLE_NPC 10
|
||||
#define FIRE_PRIORITY_SERVER_MAINT 10
|
||||
#define FIRE_PRIORITY_CLEANUP 10
|
||||
#define FIRE_PRIORITY_TICKETS 10
|
||||
#define FIRE_PRIORITY_RESEARCH 10
|
||||
#define FIRE_PRIORITY_GARBAGE 15
|
||||
@@ -113,7 +114,6 @@
|
||||
#define FIRE_PRIORITY_MOBS 100
|
||||
#define FIRE_PRIORITY_NANOUI 110
|
||||
#define FIRE_PRIORITY_TICKER 200
|
||||
#define FIRE_PRIORITY_CHAT 400
|
||||
#define FIRE_PRIORITY_OVERLAYS 500
|
||||
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// TGUI defines
|
||||
#define TGUI_MODAL_INPUT_MAX_LENGTH 1024
|
||||
#define TGUI_MODAL_INPUT_MAX_LENGTH_NAME 64 // Names for generally anything don't go past 32, let alone 64.
|
||||
|
||||
#define TGUI_MODAL_OPEN 1
|
||||
#define TGUI_MODAL_DELEGATE 2
|
||||
#define TGUI_MODAL_ANSWER 3
|
||||
#define TGUI_MODAL_CLOSE 4
|
||||
@@ -0,0 +1,77 @@
|
||||
// Wire defines for all machines/items.
|
||||
|
||||
// Miscellaneous
|
||||
#define WIRE_DUD_PREFIX "__dud"
|
||||
|
||||
// General
|
||||
#define WIRE_IDSCAN "ID Scan"
|
||||
#define WIRE_MAIN_POWER1 "Primary Power"
|
||||
#define WIRE_MAIN_POWER2 "Secondary Power"
|
||||
#define WIRE_AI_CONTROL "AI Control"
|
||||
#define WIRE_ELECTRIFY "Electrification"
|
||||
#define WIRE_SAFETY "Safety"
|
||||
|
||||
// Vendors and smartfridges
|
||||
#define WIRE_THROW_ITEM "Item Throw"
|
||||
#define WIRE_CONTRABAND "Contraband"
|
||||
|
||||
// Airlock
|
||||
#define WIRE_DOOR_BOLTS "Door Bolts"
|
||||
#define WIRE_BACKUP_POWER1 "Primary Backup Power"
|
||||
#define WIRE_OPEN_DOOR "Door State"
|
||||
#define WIRE_SPEED "Door Timing"
|
||||
#define WIRE_BOLT_LIGHT "Bolt Lights"
|
||||
|
||||
// Air alarm
|
||||
#define WIRE_SYPHON "Siphon"
|
||||
#define WIRE_AALARM "Atmospherics Alarm"
|
||||
|
||||
// Camera
|
||||
#define WIRE_FOCUS "Focus"
|
||||
|
||||
// Mulebot
|
||||
#define WIRE_MOB_AVOIDANCE "Mob Avoidance"
|
||||
#define WIRE_LOADCHECK "Load Checking"
|
||||
#define WIRE_MOTOR1 "Primary Motor"
|
||||
#define WIRE_MOTOR2 "Secondary Motor"
|
||||
#define WIRE_REMOTE_RX "Signal Receiver"
|
||||
#define WIRE_REMOTE_TX "Signal Sender"
|
||||
#define WIRE_BEACON_RX "Beacon Receiver"
|
||||
|
||||
// Explosives, bombs
|
||||
#define WIRE_EXPLODE "Explode" // Explodes if pulsed or cut while active, defuses a bomb that isn't active on cut.
|
||||
#define WIRE_BOMB_UNBOLT "Unbolt" // Unbolts the bomb if cut, hint on pulsed.
|
||||
#define WIRE_BOMB_DELAY "Delay" // Raises the timer on pulse, does nothing on cut.
|
||||
#define WIRE_BOMB_PROCEED "Proceed" // Lowers the timer, explodes if cut while the bomb is active.
|
||||
#define WIRE_BOMB_ACTIVATE "Activate" // Will start a bombs timer if pulsed, will hint if pulsed while already active, will stop a timer a bomb on cut.
|
||||
|
||||
// Nuclear bomb
|
||||
#define WIRE_BOMB_LIGHT "Bomb Light"
|
||||
#define WIRE_BOMB_TIMING "Bomb Timing"
|
||||
#define WIRE_BOMB_SAFETY "Bomb Safety"
|
||||
|
||||
// Particle accelerator
|
||||
#define WIRE_PARTICLE_POWER "Power Toggle" // Toggles whether the PA is on or not.
|
||||
#define WIRE_PARTICLE_STRENGTH "Strength" // Determines the strength of the PA.
|
||||
#define WIRE_PARTICLE_INTERFACE "Interface" // Determines the interface showing up.
|
||||
#define WIRE_PARTICLE_POWER_LIMIT "Maximum Power" // Determines how strong the PA can be.
|
||||
|
||||
// Autolathe
|
||||
#define WIRE_AUTOLATHE_HACK "Hack"
|
||||
#define WIRE_AUTOLATHE_DISABLE "Disable"
|
||||
|
||||
// Radio
|
||||
#define WIRE_RADIO_SIGNAL "Signal"
|
||||
#define WIRE_RADIO_RECEIVER "Receiver"
|
||||
#define WIRE_RADIO_TRANSMIT "Transmitter"
|
||||
|
||||
// Cyborg
|
||||
#define WIRE_BORG_LOCKED "Lockdown"
|
||||
#define WIRE_BORG_CAMERA "Camera"
|
||||
#define WIRE_BORG_LAWCHECK "Law Check"
|
||||
|
||||
// Suit storage unit
|
||||
#define WIRE_SSU_UV "UV wire"
|
||||
|
||||
// Tesla coil
|
||||
#define WIRE_TESLACOIL_ZAP "Zap"
|
||||
+46
-7
@@ -5,11 +5,11 @@
|
||||
var/turf/T = get_turf(A)
|
||||
return T ? T.loc : null
|
||||
|
||||
/proc/get_area_name(N) //get area by its name
|
||||
for(var/area/A in world)
|
||||
if(A.name == N)
|
||||
return A
|
||||
return 0
|
||||
/proc/get_area_name(atom/X, format_text = FALSE)
|
||||
var/area/A = isarea(X) ? X : get_area(X)
|
||||
if(!A)
|
||||
return null
|
||||
return format_text ? format_text(A.name) : A.name
|
||||
|
||||
/proc/get_location_name(atom/X, format_text = FALSE)
|
||||
var/area/A = isarea(X) ? X : get_area(X)
|
||||
@@ -31,6 +31,24 @@
|
||||
areas |= T.loc
|
||||
return areas
|
||||
|
||||
/proc/get_open_turf_in_dir(atom/center, dir)
|
||||
var/turf/T = get_ranged_target_turf(center, dir, 1)
|
||||
if(T && !T.density)
|
||||
return T
|
||||
|
||||
/proc/get_adjacent_open_turfs(atom/center)
|
||||
. = list(get_open_turf_in_dir(center, NORTH),
|
||||
get_open_turf_in_dir(center, SOUTH),
|
||||
get_open_turf_in_dir(center, EAST),
|
||||
get_open_turf_in_dir(center, WEST))
|
||||
listclearnulls(.)
|
||||
|
||||
/proc/get_adjacent_open_areas(atom/center)
|
||||
. = list()
|
||||
var/list/adjacent_turfs = get_adjacent_open_turfs(center)
|
||||
for(var/I in adjacent_turfs)
|
||||
. |= get_area(I)
|
||||
|
||||
// Like view but bypasses luminosity check
|
||||
|
||||
/proc/hear(var/range, var/atom/source)
|
||||
@@ -425,8 +443,8 @@
|
||||
if(pressure <= LAVALAND_EQUIPMENT_EFFECT_PRESSURE)
|
||||
. = TRUE
|
||||
|
||||
/proc/pollCandidatesWithVeto(adminclient, adminusr, max_slots, Question, be_special_type, antag_age_check = FALSE, poll_time = 300, ignore_respawnability = FALSE, min_hours = FALSE, flashwindow = TRUE, check_antaghud = TRUE, source)
|
||||
var/list/willing_ghosts = SSghost_spawns.poll_candidates(Question, be_special_type, antag_age_check, poll_time, ignore_respawnability, min_hours, flashwindow, check_antaghud, source)
|
||||
/proc/pollCandidatesWithVeto(adminclient, adminusr, max_slots, Question, be_special_type, antag_age_check = FALSE, poll_time = 300, ignore_respawnability = FALSE, min_hours = FALSE, flashwindow = TRUE, check_antaghud = TRUE, source, role_cleanname)
|
||||
var/list/willing_ghosts = SSghost_spawns.poll_candidates(Question, be_special_type, antag_age_check, poll_time, ignore_respawnability, min_hours, flashwindow, check_antaghud, source, role_cleanname)
|
||||
var/list/selected_ghosts = list()
|
||||
if(!willing_ghosts.len)
|
||||
return selected_ghosts
|
||||
@@ -454,3 +472,24 @@
|
||||
if(!C || !C.prefs.windowflashing)
|
||||
return
|
||||
winset(C, "mainwindow", "flash=5")
|
||||
|
||||
/**
|
||||
* Get a bounding box of a list of atoms.
|
||||
*
|
||||
* Arguments:
|
||||
* - atoms - List of atoms. Can accept output of view() and range() procs.
|
||||
*
|
||||
* Returns: list(x1, y1, x2, y2)
|
||||
*/
|
||||
/proc/get_bbox_of_atoms(list/atoms)
|
||||
var/list/list_x = list()
|
||||
var/list/list_y = list()
|
||||
for(var/_a in atoms)
|
||||
var/atom/a = _a
|
||||
list_x += a.x
|
||||
list_y += a.y
|
||||
return list(
|
||||
min(list_x),
|
||||
min(list_y),
|
||||
max(list_x),
|
||||
max(list_y))
|
||||
|
||||
@@ -672,9 +672,6 @@ proc/dd_sortedObjectList(list/incoming)
|
||||
/obj/machinery/camera/dd_SortValue()
|
||||
return "[c_tag]"
|
||||
|
||||
/datum/alarm/dd_SortValue()
|
||||
return "[sanitize(last_name)]"
|
||||
|
||||
//Picks from the list, with some safeties, and returns the "default" arg if it fails
|
||||
#define DEFAULTPICK(L, default) ((istype(L, /list) && L:len) ? pick(L) : default)
|
||||
|
||||
|
||||
+27
-26
@@ -1,4 +1,4 @@
|
||||
proc/GetOppositeDir(var/dir)
|
||||
/proc/GetOppositeDir(var/dir)
|
||||
switch(dir)
|
||||
if(NORTH) return SOUTH
|
||||
if(SOUTH) return NORTH
|
||||
@@ -10,7 +10,7 @@ proc/GetOppositeDir(var/dir)
|
||||
if(SOUTHEAST) return NORTHWEST
|
||||
return 0
|
||||
|
||||
proc/random_underwear(gender, species = "Human")
|
||||
/proc/random_underwear(gender, species = "Human")
|
||||
var/list/pick_list = list()
|
||||
switch(gender)
|
||||
if(MALE) pick_list = GLOB.underwear_m
|
||||
@@ -18,7 +18,7 @@ proc/random_underwear(gender, species = "Human")
|
||||
else pick_list = GLOB.underwear_list
|
||||
return pick_species_allowed_underwear(pick_list, species)
|
||||
|
||||
proc/random_undershirt(gender, species = "Human")
|
||||
/proc/random_undershirt(gender, species = "Human")
|
||||
var/list/pick_list = list()
|
||||
switch(gender)
|
||||
if(MALE) pick_list = GLOB.undershirt_m
|
||||
@@ -26,7 +26,7 @@ proc/random_undershirt(gender, species = "Human")
|
||||
else pick_list = GLOB.undershirt_list
|
||||
return pick_species_allowed_underwear(pick_list, species)
|
||||
|
||||
proc/random_socks(gender, species = "Human")
|
||||
/proc/random_socks(gender, species = "Human")
|
||||
var/list/pick_list = list()
|
||||
switch(gender)
|
||||
if(MALE) pick_list = GLOB.socks_m
|
||||
@@ -34,7 +34,7 @@ proc/random_socks(gender, species = "Human")
|
||||
else pick_list = GLOB.socks_list
|
||||
return pick_species_allowed_underwear(pick_list, species)
|
||||
|
||||
proc/pick_species_allowed_underwear(list/all_picks, species)
|
||||
/proc/pick_species_allowed_underwear(list/all_picks, species)
|
||||
var/list/valid_picks = list()
|
||||
for(var/test in all_picks)
|
||||
var/datum/sprite_accessory/S = all_picks[test]
|
||||
@@ -46,7 +46,7 @@ proc/pick_species_allowed_underwear(list/all_picks, species)
|
||||
|
||||
return pick(valid_picks)
|
||||
|
||||
proc/random_hair_style(var/gender, species = "Human", var/datum/robolimb/robohead)
|
||||
/proc/random_hair_style(var/gender, species = "Human", var/datum/robolimb/robohead)
|
||||
var/h_style = "Bald"
|
||||
var/list/valid_hairstyles = list()
|
||||
for(var/hairstyle in GLOB.hair_styles_public_list)
|
||||
@@ -75,7 +75,7 @@ proc/random_hair_style(var/gender, species = "Human", var/datum/robolimb/robohea
|
||||
|
||||
return h_style
|
||||
|
||||
proc/random_facial_hair_style(var/gender, species = "Human", var/datum/robolimb/robohead)
|
||||
/proc/random_facial_hair_style(var/gender, species = "Human", var/datum/robolimb/robohead)
|
||||
var/f_style = "Shaved"
|
||||
var/list/valid_facial_hairstyles = list()
|
||||
for(var/facialhairstyle in GLOB.facial_hair_styles_list)
|
||||
@@ -104,7 +104,7 @@ proc/random_facial_hair_style(var/gender, species = "Human", var/datum/robolimb/
|
||||
|
||||
return f_style
|
||||
|
||||
proc/random_head_accessory(species = "Human")
|
||||
/proc/random_head_accessory(species = "Human")
|
||||
var/ha_style = "None"
|
||||
var/list/valid_head_accessories = list()
|
||||
for(var/head_accessory in GLOB.head_accessory_styles_list)
|
||||
@@ -119,7 +119,7 @@ proc/random_head_accessory(species = "Human")
|
||||
|
||||
return ha_style
|
||||
|
||||
proc/random_marking_style(var/location = "body", species = "Human", var/datum/robolimb/robohead, var/body_accessory, var/alt_head)
|
||||
/proc/random_marking_style(var/location = "body", species = "Human", var/datum/robolimb/robohead, var/body_accessory, var/alt_head)
|
||||
var/m_style = "None"
|
||||
var/list/valid_markings = list()
|
||||
for(var/marking in GLOB.marking_styles_list)
|
||||
@@ -158,7 +158,7 @@ proc/random_marking_style(var/location = "body", species = "Human", var/datum/ro
|
||||
|
||||
return m_style
|
||||
|
||||
proc/random_body_accessory(species = "Vulpkanin")
|
||||
/proc/random_body_accessory(species = "Vulpkanin")
|
||||
var/body_accessory = null
|
||||
var/list/valid_body_accessories = list()
|
||||
for(var/B in GLOB.body_accessory_by_name)
|
||||
@@ -174,7 +174,7 @@ proc/random_body_accessory(species = "Vulpkanin")
|
||||
|
||||
return body_accessory
|
||||
|
||||
proc/random_name(gender, species = "Human")
|
||||
/proc/random_name(gender, species = "Human")
|
||||
|
||||
var/datum/species/current_species
|
||||
if(species)
|
||||
@@ -188,7 +188,7 @@ proc/random_name(gender, species = "Human")
|
||||
else
|
||||
return current_species.get_random_name(gender)
|
||||
|
||||
proc/random_skin_tone(species = "Human")
|
||||
/proc/random_skin_tone(species = "Human")
|
||||
if(species == "Human" || species == "Drask")
|
||||
switch(pick(60;"caucasian", 15;"afroamerican", 10;"african", 10;"latino", 5;"albino"))
|
||||
if("caucasian") . = -10
|
||||
@@ -202,7 +202,7 @@ proc/random_skin_tone(species = "Human")
|
||||
. = rand(1, 6)
|
||||
return .
|
||||
|
||||
proc/skintone2racedescription(tone, species = "Human")
|
||||
/proc/skintone2racedescription(tone, species = "Human")
|
||||
if(species == "Human")
|
||||
switch(tone)
|
||||
if(30 to INFINITY) return "albino"
|
||||
@@ -225,7 +225,7 @@ proc/skintone2racedescription(tone, species = "Human")
|
||||
else
|
||||
return "unknown"
|
||||
|
||||
proc/age2agedescription(age)
|
||||
/proc/age2agedescription(age)
|
||||
switch(age)
|
||||
if(0 to 1) return "infant"
|
||||
if(1 to 3) return "toddler"
|
||||
@@ -238,36 +238,37 @@ proc/age2agedescription(age)
|
||||
if(70 to INFINITY) return "elderly"
|
||||
else return "unknown"
|
||||
|
||||
/proc/set_criminal_status(mob/living/user, datum/data/record/target_records , criminal_status, comment, user_rank, list/authcard_access = list())
|
||||
/proc/set_criminal_status(mob/living/user, datum/data/record/target_records , criminal_status, comment, user_rank, list/authcard_access = list(), user_name)
|
||||
var/status = criminal_status
|
||||
var/their_name = target_records.fields["name"]
|
||||
var/their_rank = target_records.fields["rank"]
|
||||
switch(criminal_status)
|
||||
if("arrest")
|
||||
if("arrest", SEC_RECORD_STATUS_ARREST)
|
||||
status = SEC_RECORD_STATUS_ARREST
|
||||
if("none")
|
||||
if("none", SEC_RECORD_STATUS_NONE)
|
||||
status = SEC_RECORD_STATUS_NONE
|
||||
if("execute")
|
||||
if("execute", SEC_RECORD_STATUS_EXECUTE)
|
||||
if((ACCESS_MAGISTRATE in authcard_access) || (ACCESS_ARMORY in authcard_access))
|
||||
status = SEC_RECORD_STATUS_EXECUTE
|
||||
message_admins("[ADMIN_FULLMONTY(usr)] authorized <span class='warning'>EXECUTION</span> for [their_rank] [their_name], with comment: [comment]")
|
||||
else
|
||||
return 0
|
||||
if("search")
|
||||
if("search", SEC_RECORD_STATUS_SEARCH)
|
||||
status = SEC_RECORD_STATUS_SEARCH
|
||||
if("monitor")
|
||||
if("monitor", SEC_RECORD_STATUS_MONITOR)
|
||||
status = SEC_RECORD_STATUS_MONITOR
|
||||
if ("demote")
|
||||
if("demote", SEC_RECORD_STATUS_DEMOTE)
|
||||
message_admins("[ADMIN_FULLMONTY(usr)] set criminal status to <span class='warning'>DEMOTE</span> for [their_rank] [their_name], with comment: [comment]")
|
||||
status = SEC_RECORD_STATUS_DEMOTE
|
||||
if("incarcerated")
|
||||
if("incarcerated", SEC_RECORD_STATUS_INCARCERATED)
|
||||
status = SEC_RECORD_STATUS_INCARCERATED
|
||||
if("parolled")
|
||||
if("parolled", SEC_RECORD_STATUS_PAROLLED)
|
||||
status = SEC_RECORD_STATUS_PAROLLED
|
||||
if("released")
|
||||
if("released", SEC_RECORD_STATUS_RELEASED)
|
||||
status = SEC_RECORD_STATUS_RELEASED
|
||||
target_records.fields["criminal"] = status
|
||||
log_admin("[key_name_admin(user)] set secstatus of [their_rank] [their_name] to [status], comment: [comment]")
|
||||
target_records.fields["comments"] += "Set to [status] by [user.name] ([user_rank]) on [GLOB.current_date_string] [station_time_timestamp()], comment: [comment]"
|
||||
target_records.fields["comments"] += "Set to [status] by [user_name || user.name] ([user_rank]) on [GLOB.current_date_string] [station_time_timestamp()], comment: [comment]"
|
||||
update_all_mob_security_hud()
|
||||
return 1
|
||||
|
||||
@@ -541,7 +542,7 @@ GLOBAL_LIST_INIT(do_after_once_tracker, list())
|
||||
to_chat(user, "Name = <b>[M.name]</b>; Real_name = [M.real_name]; Mind_name = [M.mind?"[M.mind.name]":""]; Key = <b>[M.key]</b>;")
|
||||
to_chat(user, "Location = [location_description];")
|
||||
to_chat(user, "[special_role_description]")
|
||||
to_chat(user, "(<a href='?src=[usr.UID()];priv_msg=[M.client ? M.client.UID(): null]'>PM</a>) ([ADMIN_PP(M,"PP")]) ([ADMIN_VV(M,"VV")]) ([ADMIN_TP(M,"TP")]) ([ADMIN_SM(M,"SM")]) ([ADMIN_FLW(M,"FLW")])")
|
||||
to_chat(user, "(<a href='?src=[usr.UID()];priv_msg=[M.client?.ckey]'>PM</a>) ([ADMIN_PP(M,"PP")]) ([ADMIN_VV(M,"VV")]) ([ADMIN_TP(M,"TP")]) ([ADMIN_SM(M,"SM")]) ([ADMIN_FLW(M,"FLW")])")
|
||||
|
||||
// Gets the first mob contained in an atom, and warns the user if there's not exactly one
|
||||
/proc/get_mob_in_atom_with_warning(atom/A, mob/user = usr)
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
//checks text for html tags
|
||||
//if tag is not in whitelist (var/list/paper_tag_whitelist in global.dm)
|
||||
//relpaces < with <
|
||||
proc/checkhtml(var/t)
|
||||
/proc/checkhtml(var/t)
|
||||
t = sanitize_simple(t, list("&#"="."))
|
||||
var/p = findtext(t,"<",1)
|
||||
while(p) //going through all the tags
|
||||
@@ -615,5 +615,3 @@ proc/checkhtml(var/t)
|
||||
text = replacetext(text, "<td>", "\[cell\]")
|
||||
text = replacetext(text, "<img src = ntlogo.png>", "\[logo\]")
|
||||
return text
|
||||
|
||||
#define string2charlist(string) (splittext(string, regex("(\\x0A|.)")) - splittext(string, ""))
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
return time2text(station_time(time, TRUE), format)
|
||||
|
||||
/* Returns 1 if it is the selected month and day */
|
||||
proc/isDay(var/month, var/day)
|
||||
/proc/isDay(var/month, var/day)
|
||||
if(isnum(month) && isnum(day))
|
||||
var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month
|
||||
var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day
|
||||
@@ -95,7 +95,7 @@ proc/isDay(var/month, var/day)
|
||||
/proc/seconds_to_time(var/seconds as num)
|
||||
var/numSeconds = seconds % 60
|
||||
var/numMinutes = (seconds - numSeconds) / 60
|
||||
return "[numMinutes] [numMinutes > 1 ? "minutes" : "minute"] and [numSeconds] seconds."
|
||||
return "[numMinutes] [numMinutes > 1 ? "minutes" : "minute"] and [numSeconds] seconds"
|
||||
|
||||
//Take a value in seconds and makes it display like a clock
|
||||
/proc/seconds_to_clock(var/seconds as num)
|
||||
|
||||
@@ -14,16 +14,33 @@
|
||||
// var/myUID = mydatum.UID()
|
||||
// var/datum/D = locateUID(myUID)
|
||||
|
||||
/// The next UID to be used (Increments by 1 for each UID)
|
||||
GLOBAL_VAR_INIT(next_unique_datum_id, 1)
|
||||
/// Log of all UIDs created in the round. Assoc list with type as key and amount as value
|
||||
GLOBAL_LIST_EMPTY(uid_log)
|
||||
|
||||
/**
|
||||
* Gets or creates the UID of a datum
|
||||
*
|
||||
* BYOND refs are recycled, so this system prevents that. If a datum does not have a UID when this proc is ran, one will be created
|
||||
* Returns the UID of the datum
|
||||
*/
|
||||
/datum/proc/UID()
|
||||
if(!unique_datum_id)
|
||||
var/tag_backup = tag
|
||||
tag = null // Grab the raw ref, not the tag
|
||||
unique_datum_id = "\ref[src]_[GLOB.next_unique_datum_id++]"
|
||||
// num2text can output 8 significant figures max. If we go above 10 million UIDs in a round, shit breaks
|
||||
unique_datum_id = "\ref[src]_[num2text(GLOB.next_unique_datum_id++, 8)]"
|
||||
tag = tag_backup
|
||||
GLOB.uid_log[type]++
|
||||
return unique_datum_id
|
||||
|
||||
/**
|
||||
* Locates a datum based off of the UID
|
||||
*
|
||||
* Replacement for locate() which takes a UID instead of a ref
|
||||
* Returns the datum, if found
|
||||
*/
|
||||
/proc/locateUID(uid)
|
||||
if(!istext(uid))
|
||||
return null
|
||||
@@ -38,3 +55,24 @@ GLOBAL_VAR_INIT(next_unique_datum_id, 1)
|
||||
if(D && D.unique_datum_id == uid)
|
||||
return D
|
||||
return null
|
||||
|
||||
/**
|
||||
* Opens a lof of UIDs
|
||||
*
|
||||
* In-round ability to view what has created a UID, and how many times a UID for that path has been declared
|
||||
*/
|
||||
/client/proc/uid_log()
|
||||
set name = "View UID Log"
|
||||
set category = "Debug"
|
||||
set desc = "Shows the log of created UIDs this round"
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/list/sorted = sortTim(GLOB.uid_log, cmp=/proc/cmp_numeric_dsc, associative = TRUE)
|
||||
var/list/text = list("<h1>UID Log</h1>", "<p>Current UID: [GLOB.next_unique_datum_id]</p>", "<ul>")
|
||||
for(var/key in sorted)
|
||||
text += "<li>[key] - [sorted[key]]</li>"
|
||||
|
||||
text += "</ul>"
|
||||
usr << browse(text.Join(), "window=uidlog")
|
||||
|
||||
+44
-36
@@ -20,31 +20,6 @@
|
||||
|
||||
return 0
|
||||
|
||||
//Inverts the colour of an HTML string
|
||||
/proc/invertHTML(HTMLstring)
|
||||
|
||||
if(!( istext(HTMLstring) ))
|
||||
CRASH("Given non-text argument!")
|
||||
else
|
||||
if(length(HTMLstring) != 7)
|
||||
CRASH("Given non-HTML argument!")
|
||||
var/textr = copytext(HTMLstring, 2, 4)
|
||||
var/textg = copytext(HTMLstring, 4, 6)
|
||||
var/textb = copytext(HTMLstring, 6, 8)
|
||||
var/r = hex2num(textr)
|
||||
var/g = hex2num(textg)
|
||||
var/b = hex2num(textb)
|
||||
textr = num2hex(255 - r)
|
||||
textg = num2hex(255 - g)
|
||||
textb = num2hex(255 - b)
|
||||
if(length(textr) < 2)
|
||||
textr = text("0[]", textr)
|
||||
if(length(textg) < 2)
|
||||
textr = text("0[]", textg)
|
||||
if(length(textb) < 2)
|
||||
textr = text("0[]", textb)
|
||||
return text("#[][][]", textr, textg, textb)
|
||||
|
||||
//Returns the middle-most value
|
||||
/proc/dd_range(var/low, var/high, var/num)
|
||||
return max(low,min(high,num))
|
||||
@@ -449,6 +424,18 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
if(M.ckey == key)
|
||||
return M
|
||||
|
||||
/proc/get_client_by_ckey(ckey)
|
||||
if(cmptext(copytext(ckey, 1, 2),"@"))
|
||||
ckey = findStealthKey(ckey)
|
||||
return GLOB.directory[ckey]
|
||||
|
||||
|
||||
/proc/findStealthKey(txt)
|
||||
if(txt)
|
||||
for(var/P in GLOB.stealthminID)
|
||||
if(GLOB.stealthminID[P] == txt)
|
||||
return P
|
||||
|
||||
// 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)
|
||||
@@ -529,7 +516,7 @@ Returns 1 if the chain up to the area contains the given typepath
|
||||
return max(min(middle, high), low)
|
||||
|
||||
//returns random gauss number
|
||||
proc/GaussRand(var/sigma)
|
||||
/proc/GaussRand(var/sigma)
|
||||
var/x,y,rsq
|
||||
do
|
||||
x=2*rand()-1
|
||||
@@ -539,7 +526,7 @@ proc/GaussRand(var/sigma)
|
||||
return sigma*y*sqrt(-2*log(rsq)/rsq)
|
||||
|
||||
//returns random gauss number, rounded to 'roundto'
|
||||
proc/GaussRandRound(var/sigma,var/roundto)
|
||||
/proc/GaussRandRound(var/sigma,var/roundto)
|
||||
return round(GaussRand(sigma),roundto)
|
||||
|
||||
//Will return the contents of an atom recursivly to a depth of 'searchDepth'
|
||||
@@ -583,7 +570,7 @@ proc/GaussRandRound(var/sigma,var/roundto)
|
||||
|
||||
return 1
|
||||
|
||||
proc/is_blocked_turf(turf/T, exclude_mobs)
|
||||
/proc/is_blocked_turf(turf/T, exclude_mobs)
|
||||
if(T.density)
|
||||
return 1
|
||||
for(var/i in T)
|
||||
@@ -984,16 +971,16 @@ proc/is_blocked_turf(turf/T, exclude_mobs)
|
||||
|
||||
|
||||
|
||||
proc/get_cardinal_dir(atom/A, atom/B)
|
||||
/proc/get_cardinal_dir(atom/A, atom/B)
|
||||
var/dx = abs(B.x - A.x)
|
||||
var/dy = abs(B.y - A.y)
|
||||
return get_dir(A, B) & (rand() * (dx+dy) < dy ? 3 : 12)
|
||||
|
||||
//chances are 1:value. anyprob(1) will always return true
|
||||
proc/anyprob(value)
|
||||
/proc/anyprob(value)
|
||||
return (rand(1,value)==value)
|
||||
|
||||
proc/view_or_range(distance = world.view , center = usr , type)
|
||||
/proc/view_or_range(distance = world.view , center = usr , type)
|
||||
switch(type)
|
||||
if("view")
|
||||
. = view(distance,center)
|
||||
@@ -1001,7 +988,7 @@ proc/view_or_range(distance = world.view , center = usr , type)
|
||||
. = range(distance,center)
|
||||
return
|
||||
|
||||
proc/oview_or_orange(distance = world.view , center = usr , type)
|
||||
/proc/oview_or_orange(distance = world.view , center = usr , type)
|
||||
switch(type)
|
||||
if("view")
|
||||
. = oview(distance,center)
|
||||
@@ -1009,7 +996,7 @@ proc/oview_or_orange(distance = world.view , center = usr , type)
|
||||
. = orange(distance,center)
|
||||
return
|
||||
|
||||
proc/get_mob_with_client_list()
|
||||
/proc/get_mob_with_client_list()
|
||||
var/list/mobs = list()
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
if(M.client)
|
||||
@@ -1233,10 +1220,10 @@ GLOBAL_LIST_INIT(wall_items, typecacheof(list(/obj/machinery/power/apc, /obj/mac
|
||||
return 0
|
||||
|
||||
|
||||
proc/get_angle(atom/a, atom/b)
|
||||
/proc/get_angle(atom/a, atom/b)
|
||||
return atan2(b.y - a.y, b.x - a.x)
|
||||
|
||||
proc/atan2(x, y)
|
||||
/proc/atan2(x, y)
|
||||
if(!x && !y) return 0
|
||||
return y >= 0 ? arccos(x / sqrt(x * x + y * y)) : -arccos(x / sqrt(x * x + y * y))
|
||||
|
||||
@@ -1329,7 +1316,7 @@ Standard way to write links -Sayu
|
||||
return FACING_INIT_FACING_TARGET_TARGET_FACING_PERPENDICULAR
|
||||
|
||||
|
||||
atom/proc/GetTypeInAllContents(typepath)
|
||||
/atom/proc/GetTypeInAllContents(typepath)
|
||||
var/list/processing_list = list(src)
|
||||
var/list/processed = list()
|
||||
|
||||
@@ -2022,5 +2009,26 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Proc which gets all adjacent turfs to `src`, including the turf that `src` is on.
|
||||
*
|
||||
* This is similar to doing `for(var/turf/T in range(1, src))`. However it is slightly more performant.
|
||||
* Additionally, the above proc becomes more costly the more atoms there are nearby. This proc does not care about that.
|
||||
*/
|
||||
/atom/proc/get_all_adjacent_turfs()
|
||||
var/turf/src_turf = get_turf(src)
|
||||
var/list/_list = list(
|
||||
src_turf,
|
||||
get_step(src_turf, NORTH),
|
||||
get_step(src_turf, NORTHEAST),
|
||||
get_step(src_turf, NORTHWEST),
|
||||
get_step(src_turf, SOUTH),
|
||||
get_step(src_turf, SOUTHEAST),
|
||||
get_step(src_turf, SOUTHWEST),
|
||||
get_step(src_turf, EAST),
|
||||
get_step(src_turf, WEST)
|
||||
)
|
||||
return _list
|
||||
|
||||
/// Waits at a line of code until X is true
|
||||
#define UNTIL(X) while(!(X)) stoplag()
|
||||
|
||||
@@ -40,6 +40,7 @@ GLOBAL_LIST_INIT(round_end_sounds, list(
|
||||
'sound/AI/newroundsexy.ogg' = 2.3 SECONDS,
|
||||
'sound/misc/apcdestroyed.ogg' = 3 SECONDS,
|
||||
'sound/misc/bangindonk.ogg' = 1.6 SECONDS,
|
||||
'sound/misc/berightback.ogg' = 2.9 SECONDS,
|
||||
'sound/goonstation/misc/newround1.ogg' = 6.9 SECONDS,
|
||||
'sound/goonstation/misc/newround2.ogg' = 14.8 SECONDS
|
||||
)) // Maps available round end sounds to their duration
|
||||
|
||||
@@ -47,7 +47,10 @@ GLOBAL_LIST_EMPTY(ladders)
|
||||
GLOBAL_LIST_INIT(active_diseases, list()) //List of Active disease in all mobs; purely for quick referencing.
|
||||
|
||||
GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects
|
||||
|
||||
GLOBAL_LIST_EMPTY(alert_consoles) // Station alert consoles, /obj/machinery/computer/station_alert
|
||||
GLOBAL_LIST_EMPTY(explosive_walls)
|
||||
|
||||
GLOBAL_LIST_EMPTY(engine_beacon_list)
|
||||
|
||||
/// List of wire colors for each object type of that round. One for airlocks, one for vendors, etc.
|
||||
GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the `holder_type` as the key, and a list of colors as the value.
|
||||
|
||||
@@ -10,12 +10,12 @@ GLOBAL_DATUM_INIT(command_announcer, /obj/item/radio/intercom/command, create_co
|
||||
|
||||
// Load order issues means this can't be new'd until other code runs
|
||||
// This is probably not the way I should be doing this, but I don't know how to do it right!
|
||||
proc/create_global_announcer()
|
||||
/proc/create_global_announcer()
|
||||
spawn(0)
|
||||
GLOB.global_announcer = new(null)
|
||||
return
|
||||
|
||||
proc/create_command_announcer()
|
||||
/proc/create_command_announcer()
|
||||
spawn(0)
|
||||
GLOB.command_announcer = new(null)
|
||||
return
|
||||
@@ -92,6 +92,7 @@ GLOBAL_VAR(map_name) // Self explanatory
|
||||
GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) // Station datacore, manifest, etc
|
||||
|
||||
GLOBAL_VAR_INIT(panic_bunker_enabled, FALSE) // Is the panic bunker enabled
|
||||
GLOBAL_VAR_INIT(pending_server_update, FALSE)
|
||||
|
||||
//Database connections
|
||||
//A connection is established on world creation. Ideally, the connection dies when the server restarts (After feedback logging.).
|
||||
|
||||
+68
-66
@@ -9,7 +9,7 @@
|
||||
|
||||
Note that AI have no need for the adjacency proc, and so this proc is a lot cleaner.
|
||||
*/
|
||||
/mob/living/silicon/ai/DblClickOn(var/atom/A, params)
|
||||
/mob/living/silicon/ai/DblClickOn(atom/A, params)
|
||||
if(client.click_intercept)
|
||||
// Not doing a click intercept here, because otherwise we double-tap with the `ClickOn` proc.
|
||||
// But we return here since we don't want to do regular dblclick handling
|
||||
@@ -23,7 +23,7 @@
|
||||
A.move_camera_by_click()
|
||||
|
||||
|
||||
/mob/living/silicon/ai/ClickOn(var/atom/A, params)
|
||||
/mob/living/silicon/ai/ClickOn(atom/A, params)
|
||||
if(client.click_intercept)
|
||||
client.click_intercept.InterceptClickOn(src, params, A)
|
||||
return
|
||||
@@ -123,7 +123,7 @@
|
||||
/mob/living/silicon/ai/RangedAttack(atom/A, params)
|
||||
A.attack_ai(src)
|
||||
|
||||
/atom/proc/attack_ai(mob/user as mob)
|
||||
/atom/proc/attack_ai(mob/user)
|
||||
return
|
||||
|
||||
/*
|
||||
@@ -132,25 +132,23 @@
|
||||
for AI shift, ctrl, and alt clicking.
|
||||
*/
|
||||
|
||||
/mob/living/silicon/ai/CtrlShiftClickOn(var/atom/A)
|
||||
/mob/living/silicon/ai/CtrlShiftClickOn(atom/A)
|
||||
A.AICtrlShiftClick(src)
|
||||
/mob/living/silicon/ai/AltShiftClickOn(var/atom/A)
|
||||
/mob/living/silicon/ai/AltShiftClickOn(atom/A)
|
||||
A.AIAltShiftClick(src)
|
||||
/mob/living/silicon/ai/ShiftClickOn(var/atom/A)
|
||||
/mob/living/silicon/ai/ShiftClickOn(atom/A)
|
||||
A.AIShiftClick(src)
|
||||
/mob/living/silicon/ai/CtrlClickOn(var/atom/A)
|
||||
/mob/living/silicon/ai/CtrlClickOn(atom/A)
|
||||
A.AICtrlClick(src)
|
||||
/mob/living/silicon/ai/AltClickOn(var/atom/A)
|
||||
/mob/living/silicon/ai/AltClickOn(atom/A)
|
||||
A.AIAltClick(src)
|
||||
/mob/living/silicon/ai/MiddleClickOn(var/atom/A)
|
||||
/mob/living/silicon/ai/MiddleClickOn(atom/A)
|
||||
A.AIMiddleClick(src)
|
||||
|
||||
/*
|
||||
The following criminally helpful code is just the previous code cleaned up;
|
||||
I have no idea why it was in atoms.dm instead of respective files.
|
||||
*/
|
||||
|
||||
/atom/proc/AICtrlShiftClick(var/mob/user) // Examines
|
||||
// DEFAULT PROCS TO OVERRIDE
|
||||
|
||||
/atom/proc/AICtrlShiftClick(mob/user) // Examines
|
||||
if(user.client)
|
||||
user.examinate(src)
|
||||
return
|
||||
@@ -158,74 +156,78 @@
|
||||
/atom/proc/AIAltShiftClick()
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/AIAltShiftClick() // Sets/Unsets Emergency Access Override
|
||||
if(density)
|
||||
Topic(src, list("src" = UID(), "command"="emergency", "activate" = "1"), 1) // 1 meaning no window (consistency!)
|
||||
else
|
||||
Topic(src, list("src" = UID(), "command"="emergency", "activate" = "0"), 1)
|
||||
return
|
||||
|
||||
/atom/proc/AIShiftClick(var/mob/user)
|
||||
/atom/proc/AIShiftClick(mob/living/user) // borgs use this too
|
||||
if(user.client)
|
||||
user.examinate(src)
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/AIShiftClick() // Opens and closes doors!
|
||||
if(density)
|
||||
Topic(src, list("src" = UID(), "command"="open", "activate" = "1"), 1) // 1 meaning no window (consistency!)
|
||||
else
|
||||
Topic(src, list("src" = UID(), "command"="open", "activate" = "0"), 1)
|
||||
/atom/proc/AICtrlClick(mob/living/silicon/user)
|
||||
return
|
||||
|
||||
/atom/proc/AICtrlClick(var/mob/living/silicon/ai/user)
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/AICtrlClick() // Bolts doors
|
||||
if(locked)
|
||||
Topic(src, list("src" = UID(), "command"="bolts", "activate" = "0"), 1)// 1 meaning no window (consistency!)
|
||||
else
|
||||
Topic(src, list("src" = UID(), "command"="bolts", "activate" = "1"), 1)
|
||||
|
||||
/obj/machinery/power/apc/AICtrlClick() // turns off/on APCs.
|
||||
Topic("breaker=1", list("breaker"="1"), 0) // 0 meaning no window (consistency! wait...)
|
||||
|
||||
/obj/machinery/turretid/AICtrlClick() //turns off/on Turrets
|
||||
Topic(src, list("src" = UID(), "command"="enable", "value"="[!enabled]"), 1) // 1 meaning no window (consistency!)
|
||||
|
||||
/atom/proc/AIAltClick(var/atom/A)
|
||||
/atom/proc/AIAltClick(atom/A)
|
||||
AltClick(A)
|
||||
|
||||
/obj/machinery/door/airlock/AIAltClick() // Electrifies doors.
|
||||
if(!electrified_until)
|
||||
// permanent shock
|
||||
Topic(src, list("src" = UID(), "command"="electrify_permanently", "activate" = "1"), 1) // 1 meaning no window (consistency!)
|
||||
else
|
||||
// disable/6 is not in Topic; disable/5 disables both temporary and permanent shock
|
||||
Topic(src, list("src" = UID(), "command"="electrify_permanently", "activate" = "0"), 1)
|
||||
/atom/proc/AIMiddleClick(mob/living/user)
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/TurfAdjacent(turf/T)
|
||||
return (GLOB.cameranet && GLOB.cameranet.checkTurfVis(T))
|
||||
|
||||
|
||||
// APC
|
||||
|
||||
/obj/machinery/power/apc/AICtrlClick(mob/living/user) // turns off/on APCs.
|
||||
toggle_breaker(user)
|
||||
|
||||
|
||||
// TURRETCONTROL
|
||||
|
||||
/obj/machinery/turretid/AICtrlClick(mob/living/silicon/user) //turns off/on Turrets
|
||||
enabled = !enabled
|
||||
updateTurrets()
|
||||
|
||||
/obj/machinery/turretid/AIAltClick() //toggles lethal on turrets
|
||||
Topic(src, list("src" = UID(), "command"="lethal", "value"="[!lethal]"), 1) // 1 meaning no window (consistency!)
|
||||
if(lethal_is_configurable)
|
||||
lethal = !lethal
|
||||
updateTurrets()
|
||||
|
||||
/atom/proc/AIMiddleClick()
|
||||
return
|
||||
// AIRLOCKS
|
||||
|
||||
/obj/machinery/door/airlock/AIMiddleClick() // Toggles door bolt lights.
|
||||
if(!src.lights)
|
||||
Topic(src, list("src" = UID(), "command"="lights", "activate" = "1"), 1) // 1 meaning no window (consistency!)
|
||||
/obj/machinery/door/airlock/AIAltShiftClick(mob/user) // Sets/Unsets Emergency Access Override
|
||||
if(!ai_control_check(user))
|
||||
return
|
||||
toggle_emergency_status(user)
|
||||
|
||||
/obj/machinery/door/airlock/AIShiftClick(mob/user) // Opens and closes doors!
|
||||
if(!ai_control_check(user))
|
||||
return
|
||||
open_close(user)
|
||||
|
||||
/obj/machinery/door/airlock/AICtrlClick(mob/living/silicon/user) // Bolts doors
|
||||
if(!ai_control_check(user))
|
||||
return
|
||||
toggle_bolt(user)
|
||||
|
||||
/obj/machinery/door/airlock/AIAltClick(mob/living/silicon/user) // Electrifies doors.
|
||||
if(!ai_control_check(user))
|
||||
return
|
||||
if(wires.is_cut(WIRE_ELECTRIFY))
|
||||
to_chat(user, "<span class='warning'>The electrification wire is cut - Cannot electrify the door.</span>")
|
||||
if(isElectrified())
|
||||
electrify(0, user, TRUE) // un-shock
|
||||
else
|
||||
Topic(src, list("src" = UID(), "command"="lights", "activate" = "0"), 1)
|
||||
return
|
||||
electrify(-1, user, TRUE) // permanent shock
|
||||
|
||||
/obj/machinery/ai_slipper/AICtrlClick() //Turns liquid dispenser on or off
|
||||
|
||||
/obj/machinery/door/airlock/AIMiddleClick(mob/living/user) // Toggles door bolt lights.
|
||||
if(!ai_control_check(user))
|
||||
return
|
||||
toggle_light(user)
|
||||
|
||||
// AI-CONTROLLED SLIP GENERATOR IN AI CORE
|
||||
|
||||
/obj/machinery/ai_slipper/AICtrlClick(mob/living/silicon/ai/user) //Turns liquid dispenser on or off
|
||||
ToggleOn()
|
||||
|
||||
/obj/machinery/ai_slipper/AIAltClick() //Dispenses liquid if on
|
||||
Activate()
|
||||
|
||||
//
|
||||
// Override AdjacentQuick for AltClicking
|
||||
//
|
||||
|
||||
/mob/living/silicon/ai/TurfAdjacent(var/turf/T)
|
||||
return (GLOB.cameranet && GLOB.cameranet.checkTurfVis(T))
|
||||
|
||||
+52
-37
@@ -6,7 +6,7 @@
|
||||
adjacency code.
|
||||
*/
|
||||
|
||||
/mob/living/silicon/robot/ClickOn(var/atom/A, var/params)
|
||||
/mob/living/silicon/robot/ClickOn(atom/A, params)
|
||||
if(client.click_intercept)
|
||||
client.click_intercept.InterceptClickOn(src, params, A)
|
||||
return
|
||||
@@ -15,6 +15,8 @@
|
||||
return
|
||||
changeNext_click(1)
|
||||
|
||||
if(is_ventcrawling(src)) // To stop drones interacting with anything while ventcrawling
|
||||
return
|
||||
|
||||
var/list/modifiers = params2list(params)
|
||||
if(modifiers["shift"] && modifiers["ctrl"])
|
||||
@@ -98,12 +100,12 @@
|
||||
return
|
||||
|
||||
//Ctrl+Middle click cycles through modules
|
||||
/mob/living/silicon/robot/proc/CtrlMiddleClickOn(var/atom/A)
|
||||
/mob/living/silicon/robot/proc/CtrlMiddleClickOn(atom/A)
|
||||
cycle_modules()
|
||||
return
|
||||
|
||||
//Middle click points
|
||||
/mob/living/silicon/robot/MiddleClickOn(var/atom/A)
|
||||
/mob/living/silicon/robot/MiddleClickOn(atom/A)
|
||||
if(istype(src, /mob/living/silicon/robot/drone))
|
||||
// Drones cannot point.
|
||||
return
|
||||
@@ -112,18 +114,31 @@
|
||||
|
||||
//Give cyborgs hotkey clicks without breaking existing uses of hotkey clicks
|
||||
// for non-doors/apcs
|
||||
/mob/living/silicon/robot/CtrlShiftClickOn(var/atom/A)
|
||||
A.BorgCtrlShiftClick(src)
|
||||
/mob/living/silicon/robot/AltShiftClickOn(var/atom/A)
|
||||
A.BorgAltShiftClick(src)
|
||||
/mob/living/silicon/robot/ShiftClickOn(var/atom/A)
|
||||
/mob/living/silicon/robot/ShiftClickOn(atom/A)
|
||||
A.BorgShiftClick(src)
|
||||
/mob/living/silicon/robot/CtrlClickOn(var/atom/A)
|
||||
/mob/living/silicon/robot/CtrlClickOn(atom/A)
|
||||
A.BorgCtrlClick(src)
|
||||
/mob/living/silicon/robot/AltClickOn(var/atom/A)
|
||||
/mob/living/silicon/robot/AltClickOn(atom/A)
|
||||
A.BorgAltClick(src)
|
||||
/mob/living/silicon/robot/CtrlShiftClickOn(atom/A)
|
||||
A.BorgCtrlShiftClick(src)
|
||||
/mob/living/silicon/robot/AltShiftClickOn(atom/A)
|
||||
A.BorgAltShiftClick(src)
|
||||
|
||||
/atom/proc/BorgCtrlShiftClick(var/mob/user) // Examines
|
||||
|
||||
/atom/proc/BorgShiftClick(mob/user)
|
||||
if(user.client && user.client.eye == user)
|
||||
user.examinate(src)
|
||||
return
|
||||
|
||||
/atom/proc/BorgCtrlClick(mob/living/silicon/robot/user) //forward to human click if not overriden
|
||||
CtrlClick(user)
|
||||
|
||||
/atom/proc/BorgAltClick(mob/living/silicon/robot/user)
|
||||
AltClick(user)
|
||||
return
|
||||
|
||||
/atom/proc/BorgCtrlShiftClick(mob/user) // Examines
|
||||
if(user.client && user.client.eye == user)
|
||||
user.examinate(src)
|
||||
return
|
||||
@@ -131,45 +146,45 @@
|
||||
/atom/proc/BorgAltShiftClick()
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/BorgAltShiftClick() // Enables emergency override on doors! Forwards to AI code.
|
||||
AIAltShiftClick()
|
||||
|
||||
/atom/proc/BorgShiftClick(var/mob/user)
|
||||
if(user.client && user.client.eye == user)
|
||||
user.examinate(src)
|
||||
return
|
||||
// AIRLOCKS
|
||||
|
||||
/obj/machinery/door/airlock/BorgShiftClick() // Opens and closes doors! Forwards to AI code.
|
||||
AIShiftClick()
|
||||
/obj/machinery/door/airlock/BorgShiftClick(mob/living/silicon/robot/user) // Opens and closes doors! Forwards to AI code.
|
||||
AIShiftClick(user)
|
||||
|
||||
/atom/proc/BorgCtrlClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden
|
||||
CtrlClick(user)
|
||||
/obj/machinery/door/airlock/BorgCtrlClick(mob/living/silicon/robot/user) // Bolts doors. Forwards to AI code.
|
||||
AICtrlClick(user)
|
||||
|
||||
/obj/machinery/door/airlock/BorgCtrlClick() // Bolts doors. Forwards to AI code.
|
||||
AICtrlClick()
|
||||
/obj/machinery/door/airlock/BorgAltClick(mob/living/silicon/robot/user) // Eletrifies doors. Forwards to AI code.
|
||||
AIAltClick(user)
|
||||
|
||||
/obj/machinery/power/apc/BorgCtrlClick() // turns off/on APCs. Forwards to AI code.
|
||||
AICtrlClick()
|
||||
/obj/machinery/door/airlock/BorgAltShiftClick(mob/living/silicon/robot/user) // Enables emergency override on doors! Forwards to AI code.
|
||||
AIAltShiftClick(user)
|
||||
|
||||
/obj/machinery/turretid/BorgCtrlClick() //turret control on/off. Forwards to AI code.
|
||||
AICtrlClick()
|
||||
|
||||
/atom/proc/BorgAltClick(var/mob/living/silicon/robot/user)
|
||||
AltClick(user)
|
||||
return
|
||||
// APC
|
||||
|
||||
/obj/machinery/door/airlock/BorgAltClick() // Eletrifies doors. Forwards to AI code.
|
||||
AIAltClick()
|
||||
/obj/machinery/power/apc/BorgCtrlClick(mob/living/silicon/robot/user) // turns off/on APCs. Forwards to AI code.
|
||||
AICtrlClick(user)
|
||||
|
||||
/obj/machinery/turretid/BorgAltClick() //turret lethal on/off. Forwards to AI code.
|
||||
AIAltClick()
|
||||
|
||||
/obj/machinery/ai_slipper/BorgCtrlClick() //Turns liquid dispenser on or off
|
||||
// AI SLIPPER
|
||||
|
||||
/obj/machinery/ai_slipper/BorgCtrlClick(mob/living/silicon/robot/user) //Turns liquid dispenser on or off
|
||||
ToggleOn()
|
||||
|
||||
/obj/machinery/ai_slipper/BorgAltClick() //Dispenses liquid if on
|
||||
/obj/machinery/ai_slipper/BorgAltClick(mob/living/silicon/robot/user) //Dispenses liquid if on
|
||||
Activate()
|
||||
|
||||
|
||||
// TURRETCONTROL
|
||||
|
||||
/obj/machinery/turretid/BorgCtrlClick(mob/living/silicon/robot/user) //turret control on/off. Forwards to AI code.
|
||||
AICtrlClick(user)
|
||||
|
||||
/obj/machinery/turretid/BorgAltClick(mob/living/silicon/robot/user) //turret lethal on/off. Forwards to AI code.
|
||||
AIAltClick(user)
|
||||
|
||||
/*
|
||||
As with AI, these are not used in click code,
|
||||
because the code for robots is specific, not generic.
|
||||
@@ -184,6 +199,6 @@
|
||||
/mob/living/silicon/robot/RangedAttack(atom/A, params)
|
||||
A.attack_robot(src)
|
||||
|
||||
/atom/proc/attack_robot(mob/user as mob)
|
||||
/atom/proc/attack_robot(mob/user)
|
||||
attack_ai(user)
|
||||
return
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
/obj/screen/ai/alerts/Click()
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.subsystem_alarm_monitor()
|
||||
AI.ai_alerts()
|
||||
|
||||
/obj/screen/ai/announcement
|
||||
name = "Make Announcement"
|
||||
|
||||
@@ -569,6 +569,10 @@ so as to remain in compliance with the most up-to-date laws."
|
||||
if(NOTIFY_FOLLOW)
|
||||
G.ManualFollow(target)
|
||||
|
||||
/obj/screen/alert/notify_action/Topic(href, href_list)
|
||||
if(href_list["signup"] && poll?.sign_up(usr))
|
||||
display_signed_up()
|
||||
|
||||
/obj/screen/alert/notify_action/proc/display_signed_up()
|
||||
var/image/I = image('icons/mob/screen_gen.dmi', icon_state = "selector")
|
||||
I.layer = FLOAT_LAYER
|
||||
|
||||
@@ -81,6 +81,9 @@
|
||||
|
||||
/obj/screen/ghost/respawn_pai/Click()
|
||||
var/mob/dead/observer/G = usr
|
||||
if(!GLOB.paiController.check_recruit(G))
|
||||
to_chat(G, "<span class='warning'>You are not eligible to become a pAI.</span>")
|
||||
return
|
||||
GLOB.paiController.recruitWindow(G)
|
||||
|
||||
/datum/hud/ghost
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
using.icon_state = mymob.a_intent
|
||||
static_inventory += using
|
||||
action_intent = using
|
||||
|
||||
|
||||
using = new /obj/screen/guardian/Manifest()
|
||||
using.screen_loc = ui_rhand
|
||||
static_inventory += using
|
||||
@@ -49,8 +49,8 @@
|
||||
/obj/screen/guardian/Manifest/Click()
|
||||
if(isguardian(usr))
|
||||
var/mob/living/simple_animal/hostile/guardian/G = usr
|
||||
G.Manifest()
|
||||
|
||||
if(G.loc == G.summoner)
|
||||
G.Manifest()
|
||||
|
||||
/obj/screen/guardian/Recall
|
||||
icon_state = "recall"
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
/client
|
||||
/**
|
||||
* Assoc list with all the active maps - when a screen obj is added to
|
||||
* a map, it's put in here as well.
|
||||
*
|
||||
* Format: list(<mapname> = list(/obj/screen))
|
||||
*/
|
||||
var/list/screen_maps = list()
|
||||
|
||||
/obj/screen
|
||||
/**
|
||||
* Map name assigned to this object.
|
||||
* Automatically set by /client/proc/add_obj_to_map.
|
||||
*/
|
||||
var/assigned_map
|
||||
/**
|
||||
* Mark this object as garbage-collectible after you clean the map
|
||||
* it was registered on.
|
||||
*
|
||||
* This could probably be changed to be a proc, for conditional removal.
|
||||
* But for now, this works.
|
||||
*/
|
||||
var/del_on_map_removal = TRUE
|
||||
|
||||
/**
|
||||
* A screen object, which acts as a container for turfs and other things
|
||||
* you want to show on the map, which you usually attach to "vis_contents".
|
||||
*/
|
||||
/obj/screen/map_view
|
||||
// Map view has to be on the lowest plane to enable proper lighting
|
||||
layer = GAME_PLANE
|
||||
plane = GAME_PLANE
|
||||
|
||||
/**
|
||||
* A generic background object.
|
||||
* It is also implicitly used to allocate a rectangle on the map, which will
|
||||
* be used for auto-scaling the map.
|
||||
*/
|
||||
/obj/screen/background
|
||||
name = "background"
|
||||
icon = 'icons/mob/map_backgrounds.dmi'
|
||||
icon_state = "clear"
|
||||
layer = GAME_PLANE
|
||||
plane = GAME_PLANE
|
||||
|
||||
/**
|
||||
* Sets screen_loc of this screen object, in form of point coordinates,
|
||||
* with optional pixel offset (px, py).
|
||||
*
|
||||
* If applicable, "assigned_map" has to be assigned before this proc call.
|
||||
*/
|
||||
/obj/screen/proc/set_position(x, y, px = 0, py = 0)
|
||||
if(assigned_map)
|
||||
screen_loc = "[assigned_map]:[x]:[px],[y]:[py]"
|
||||
else
|
||||
screen_loc = "[x]:[px],[y]:[py]"
|
||||
|
||||
/**
|
||||
* Sets screen_loc to fill a rectangular area of the map.
|
||||
*
|
||||
* If applicable, "assigned_map" has to be assigned before this proc call.
|
||||
*/
|
||||
/obj/screen/proc/fill_rect(x1, y1, x2, y2)
|
||||
if(assigned_map)
|
||||
screen_loc = "[assigned_map]:[x1],[y1] to [x2],[y2]"
|
||||
else
|
||||
screen_loc = "[x1],[y1] to [x2],[y2]"
|
||||
|
||||
/**
|
||||
* Registers screen obj with the client, which makes it visible on the
|
||||
* assigned map, and becomes a part of the assigned map's lifecycle.
|
||||
*/
|
||||
/client/proc/register_map_obj(obj/screen/screen_obj)
|
||||
if(!screen_obj.assigned_map)
|
||||
CRASH("Can't register [screen_obj] without 'assigned_map' property.")
|
||||
if(!screen_maps[screen_obj.assigned_map])
|
||||
screen_maps[screen_obj.assigned_map] = list()
|
||||
// NOTE: Possibly an expensive operation
|
||||
var/list/screen_map = screen_maps[screen_obj.assigned_map]
|
||||
if(!screen_map.Find(screen_obj))
|
||||
screen_map += screen_obj
|
||||
if(!screen.Find(screen_obj))
|
||||
screen += screen_obj
|
||||
|
||||
/**
|
||||
* Clears the map of registered screen objects.
|
||||
*
|
||||
* Not really needed most of the time, as the client's screen list gets reset
|
||||
* on relog. any of the buttons are going to get caught by garbage collection
|
||||
* anyway. they're effectively qdel'd.
|
||||
*/
|
||||
/client/proc/clear_map(map_name)
|
||||
if(!map_name || !(map_name in screen_maps))
|
||||
return FALSE
|
||||
for(var/obj/screen/screen_obj in screen_maps[map_name])
|
||||
screen_maps[map_name] -= screen_obj
|
||||
if(screen_obj.del_on_map_removal)
|
||||
qdel(screen_obj)
|
||||
screen_maps -= map_name
|
||||
|
||||
/**
|
||||
* Clears all the maps of registered screen objects.
|
||||
*/
|
||||
/client/proc/clear_all_maps()
|
||||
for(var/map_name in screen_maps)
|
||||
clear_map(map_name)
|
||||
|
||||
/**
|
||||
* Creates a popup window with a basic map element in it, without any
|
||||
* further initialization.
|
||||
*
|
||||
* Ratio is how many pixels by how many pixels (keep it simple).
|
||||
*
|
||||
* Returns a map name.
|
||||
*/
|
||||
/client/proc/create_popup(name, ratiox = 100, ratioy = 100)
|
||||
winclone(src, "popupwindow", name)
|
||||
var/list/winparams = list()
|
||||
winparams["size"] = "[ratiox]x[ratioy]"
|
||||
winparams["on-close"] = "handle-popup-close [name]"
|
||||
winset(src, "[name]", list2params(winparams))
|
||||
winshow(src, "[name]", 1)
|
||||
|
||||
var/list/params = list()
|
||||
params["parent"] = "[name]"
|
||||
params["type"] = "map"
|
||||
params["size"] = "[ratiox]x[ratioy]"
|
||||
params["anchor1"] = "0,0"
|
||||
params["anchor2"] = "[ratiox],[ratioy]"
|
||||
winset(src, "[name]_map", list2params(params))
|
||||
|
||||
return "[name]_map"
|
||||
|
||||
/**
|
||||
* Create the popup, and get it ready for generic use by giving
|
||||
* it a background.
|
||||
*
|
||||
* Width and height are multiplied by 64 by default.
|
||||
*/
|
||||
/client/proc/setup_popup(popup_name, width = 9, height = 9, \
|
||||
tilesize = 2, bg_icon)
|
||||
if(!popup_name)
|
||||
return
|
||||
clear_map("[popup_name]_map")
|
||||
var/x_value = world.icon_size * tilesize * width
|
||||
var/y_value = world.icon_size * tilesize * height
|
||||
var/map_name = create_popup(popup_name, x_value, y_value)
|
||||
|
||||
var/obj/screen/background/background = new
|
||||
background.assigned_map = map_name
|
||||
background.fill_rect(1, 1, width, height)
|
||||
if(bg_icon)
|
||||
background.icon_state = bg_icon
|
||||
register_map_obj(background)
|
||||
|
||||
return map_name
|
||||
|
||||
/**
|
||||
* Closes a popup.
|
||||
*/
|
||||
/client/proc/close_popup(popup)
|
||||
winshow(src, popup, 0)
|
||||
handle_popup_close(popup)
|
||||
|
||||
/**
|
||||
* When the popup closes in any way (player or proc call) it calls this.
|
||||
*/
|
||||
/client/verb/handle_popup_close(window_id as text)
|
||||
set hidden = TRUE
|
||||
clear_map("[window_id]_map")
|
||||
@@ -488,7 +488,7 @@
|
||||
var/list/cached_healthdoll_overlays = list() // List of icon states (strings) for overlays
|
||||
|
||||
/obj/screen/healthdoll/Click()
|
||||
if(ishuman(usr))
|
||||
if(ishuman(usr) && !usr.is_dead())
|
||||
var/mob/living/carbon/H = usr
|
||||
H.check_self_for_injuries()
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
if(A.attack_hulk(src))
|
||||
return
|
||||
|
||||
if(buckled && isstructure(buckled))
|
||||
var/obj/structure/S = buckled
|
||||
if(S.prevents_buckled_mobs_attacking())
|
||||
return
|
||||
|
||||
A.attack_hand(src)
|
||||
|
||||
/atom/proc/attack_hand(mob/user as mob)
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
SUBSYSTEM_DEF(alarms)
|
||||
name = "Alarms"
|
||||
init_order = INIT_ORDER_ALARMS // 2
|
||||
offline_implications = "Alarms (Power, camera, fire, etc) will no longer be checked. No immediate action is needed."
|
||||
var/datum/alarm_handler/atmosphere/atmosphere_alarm = new()
|
||||
var/datum/alarm_handler/burglar/burglar_alarm = new()
|
||||
var/datum/alarm_handler/camera/camera_alarm = new()
|
||||
var/datum/alarm_handler/fire/fire_alarm = new()
|
||||
var/datum/alarm_handler/motion/motion_alarm = new()
|
||||
var/datum/alarm_handler/power/power_alarm = new()
|
||||
var/list/datum/alarm/all_handlers
|
||||
SUBSYSTEM_DEF(alarm)
|
||||
name = "Alarm"
|
||||
flags = SS_NO_INIT | SS_NO_FIRE
|
||||
var/list/alarms = list("Motion" = list(), "Fire" = list(), "Atmosphere" = list(), "Power" = list(), "Camera" = list(), "Burglar" = list())
|
||||
|
||||
/datum/controller/subsystem/alarms/Initialize(start_timeofday)
|
||||
all_handlers = list(SSalarms.atmosphere_alarm, SSalarms.burglar_alarm, SSalarms.camera_alarm, SSalarms.fire_alarm, SSalarms.motion_alarm, SSalarms.power_alarm)
|
||||
return ..()
|
||||
/datum/controller/subsystem/alarm/proc/triggerAlarm(class, area/A, list/O, obj/alarmsource)
|
||||
var/list/L = alarms[class]
|
||||
for(var/I in L)
|
||||
if(I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/sources = alarm[3]
|
||||
if(!(alarmsource.UID() in sources))
|
||||
sources += alarmsource.UID()
|
||||
return TRUE
|
||||
L[A.name] = list(get_area_name(A, TRUE), O, list(alarmsource.UID()))
|
||||
SEND_SIGNAL(SSalarm, COMSIG_TRIGGERED_ALARM, class, A, O, alarmsource)
|
||||
return TRUE
|
||||
|
||||
/datum/controller/subsystem/alarms/fire()
|
||||
for(var/datum/alarm_handler/AH in all_handlers)
|
||||
AH.process()
|
||||
/datum/controller/subsystem/alarm/proc/cancelAlarm(class, area/A, obj/origin)
|
||||
var/list/L = alarms[class]
|
||||
var/cleared = FALSE
|
||||
for(var/I in L)
|
||||
if(I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/srcs = alarm[3]
|
||||
srcs -= origin.UID()
|
||||
if(!length(srcs))
|
||||
cleared = TRUE
|
||||
L -= I
|
||||
|
||||
/datum/controller/subsystem/alarms/proc/active_alarms()
|
||||
var/list/all_alarms = new ()
|
||||
for(var/datum/alarm_handler/AH in all_handlers)
|
||||
var/list/alarms = AH.alarms
|
||||
all_alarms += alarms
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/controller/subsystem/alarms/proc/number_of_active_alarms()
|
||||
var/list/alarms = active_alarms()
|
||||
return alarms.len
|
||||
SEND_SIGNAL(SSalarm, COMSIG_CANCELLED_ALARM, class, A, origin, cleared)
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
SUBSYSTEM_DEF(chat)
|
||||
name = "Chat"
|
||||
flags = SS_TICKER|SS_NO_INIT
|
||||
wait = 1
|
||||
priority = FIRE_PRIORITY_CHAT
|
||||
init_order = INIT_ORDER_CHAT
|
||||
offline_implications = "Chat messages will no longer be cleanly queued. No immediate action is needed."
|
||||
|
||||
var/list/payload = list()
|
||||
|
||||
|
||||
/datum/controller/subsystem/chat/fire()
|
||||
for(var/i in payload)
|
||||
var/client/C = i
|
||||
if(C)
|
||||
C << output(payload[C], "browseroutput:output")
|
||||
payload -= C
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
|
||||
/datum/controller/subsystem/chat/proc/queue(target, message, flag)
|
||||
if(!target || !message)
|
||||
return
|
||||
|
||||
if(!istext(message))
|
||||
stack_trace("to_chat called with invalid input type")
|
||||
return
|
||||
|
||||
if(target == world)
|
||||
target = GLOB.clients
|
||||
|
||||
//Some macros remain in the string even after parsing and fuck up the eventual output
|
||||
message = replacetext(message, "\improper", "")
|
||||
message = replacetext(message, "\proper", "")
|
||||
message += "<br>"
|
||||
|
||||
|
||||
//url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript.
|
||||
//Do the double-encoding here to save nanoseconds
|
||||
var/twiceEncoded = url_encode(url_encode(message))
|
||||
|
||||
if(islist(target))
|
||||
for(var/I in target)
|
||||
var/client/C = CLIENT_FROM_VAR(I) //Grab us a client if possible
|
||||
|
||||
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
|
||||
continue
|
||||
|
||||
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
|
||||
C.chatOutput.messageQueue += message
|
||||
continue
|
||||
|
||||
payload[C] += twiceEncoded
|
||||
|
||||
else
|
||||
var/client/C = CLIENT_FROM_VAR(target) //Grab us a client if possible
|
||||
|
||||
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
|
||||
return
|
||||
|
||||
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
|
||||
C.chatOutput.messageQueue += message
|
||||
return
|
||||
|
||||
payload[C] += twiceEncoded
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* # Cleanup Subsystem
|
||||
*
|
||||
* For now, all it does is periodically clean the supplied global lists of any null values they may contain.
|
||||
*
|
||||
* Why is this important?
|
||||
*
|
||||
* Sometimes, these lists can gain nulls due to errors.
|
||||
* For example, when a dead player trasitions from the `dead_mob_list` to the `alive_mob_list`, a null value may get stuck in the dead mob list.
|
||||
* This can cause issues when other code tries to do things with the values in the list, but are instead met with null values.
|
||||
* These problems are incredibly hard to track down and fix, so this subsystem is a solution to that.
|
||||
*/
|
||||
SUBSYSTEM_DEF(cleanup)
|
||||
name = "Null cleanup"
|
||||
wait = 30 SECONDS
|
||||
flags = SS_POST_FIRE_TIMING
|
||||
priority = FIRE_PRIORITY_CLEANUP
|
||||
init_order = INIT_ORDER_CLEANUP
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
offline_implications = "Certain global lists will no longer be cleared of nulls, which may result in runtimes. No immediate action is needed."
|
||||
/// A list of global lists we want the subsystem to clean.
|
||||
var/list/lists_to_clean
|
||||
|
||||
/datum/controller/subsystem/cleanup/Initialize(start_timeofday)
|
||||
// If you want this subsystem to clean out nulls from a specific list, add it here.
|
||||
lists_to_clean = list(
|
||||
GLOB.clients = "clients",
|
||||
GLOB.player_list = "player_list",
|
||||
GLOB.mob_list = "mob_list",
|
||||
GLOB.alive_mob_list = "alive_mob_list",
|
||||
GLOB.dead_mob_list = "dead_mob_list",
|
||||
GLOB.human_list = "human_list",
|
||||
GLOB.carbon_list = "carbon_list"
|
||||
)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/cleanup/fire(resumed)
|
||||
for(var/L in lists_to_clean)
|
||||
var/list/_list = L
|
||||
var/prev_length = length(_list)
|
||||
listclearnulls(_list)
|
||||
|
||||
if(length(_list) < prev_length)
|
||||
stack_trace("Found a null value in GLOB.[lists_to_clean[_list]]!")
|
||||
@@ -40,7 +40,7 @@ SUBSYSTEM_DEF(events)
|
||||
var/datum/event_container/EC = event_containers[i]
|
||||
EC.process()
|
||||
|
||||
/datum/controller/subsystem/events/proc/event_complete(var/datum/event/E)
|
||||
/datum/controller/subsystem/events/proc/event_complete(datum/event/E)
|
||||
if(!E.event_meta) // datum/event is used here and there for random reasons, maintaining "backwards compatibility"
|
||||
log_debug("Event of '[E.type]' with missing meta-data has completed.")
|
||||
return
|
||||
@@ -65,11 +65,11 @@ SUBSYSTEM_DEF(events)
|
||||
|
||||
log_debug("Event '[EM.name]' has completed at [station_time_timestamp()].")
|
||||
|
||||
/datum/controller/subsystem/events/proc/delay_events(var/severity, var/delay)
|
||||
/datum/controller/subsystem/events/proc/delay_events(severity, delay)
|
||||
var/datum/event_container/EC = event_containers[severity]
|
||||
EC.next_event_time += delay
|
||||
|
||||
/datum/controller/subsystem/events/proc/Interact(var/mob/living/user)
|
||||
/datum/controller/subsystem/events/proc/Interact(mob/living/user)
|
||||
|
||||
var/html = GetInteractWindow()
|
||||
|
||||
@@ -113,7 +113,7 @@ SUBSYSTEM_DEF(events)
|
||||
html += "<td>[EM.name]</td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];set_weight=\ref[EM]'>[EM.weight]</A></td>"
|
||||
html += "<td>[EM.min_weight]</td>"
|
||||
html += "<td>[EM.max_weight]</td>"
|
||||
html += "<td>[EM.max_weight == INFINITY ? "No max" : EM.max_weight]</td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];toggle_oneshot=\ref[EM]'>[EM.one_shot]</A></td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];toggle_enabled=\ref[EM]'>[EM.enabled]</A></td>"
|
||||
html += "<td><span class='alert'>[EM.get_weight(number_active_with_role())]</span></td>"
|
||||
|
||||
@@ -41,9 +41,10 @@ SUBSYSTEM_DEF(ghost_spawns)
|
||||
* * flash_window - Whether the poll should flash a potential candidate's game window
|
||||
* * check_antaghud - Whether to filter out potential candidates who enabled AntagHUD
|
||||
* * source - The atom, atom prototype, icon or mutable appearance to display as an icon in the alert
|
||||
* * role_cleanname - The name override to display to clients
|
||||
*/
|
||||
/datum/controller/subsystem/ghost_spawns/proc/poll_candidates(question = "Would you like to play a special role?", role, antag_age_check = FALSE, poll_time = 30 SECONDS, ignore_respawnability = FALSE, min_hours = 0, flash_window = TRUE, check_antaghud = TRUE, source)
|
||||
log_debug("Polling candidates [role ? "for [get_roletext(role)]" : "\"[question]\""] for [poll_time / 10] seconds")
|
||||
/datum/controller/subsystem/ghost_spawns/proc/poll_candidates(question = "Would you like to play a special role?", role, antag_age_check = FALSE, poll_time = 30 SECONDS, ignore_respawnability = FALSE, min_hours = 0, flash_window = TRUE, check_antaghud = TRUE, source, role_cleanname)
|
||||
log_debug("Polling candidates [role ? "for [role_cleanname || get_roletext(role)]" : "\"[question]\""] for [poll_time / 10] seconds")
|
||||
|
||||
// Start firing
|
||||
polls_active = TRUE
|
||||
@@ -59,7 +60,7 @@ SUBSYSTEM_DEF(ghost_spawns)
|
||||
var/category = "[P.hash]_notify_action"
|
||||
|
||||
for(var/mob/dead/observer/M in (ignore_respawnability ? GLOB.player_list : GLOB.respawnable_list))
|
||||
if(!is_eligible(M))
|
||||
if(!is_eligible(M, role, antag_age_check, role, min_hours, check_antaghud))
|
||||
continue
|
||||
|
||||
SEND_SOUND(M, 'sound/misc/notice2.ogg')
|
||||
@@ -125,6 +126,13 @@ SUBSYSTEM_DEF(ghost_spawns)
|
||||
I.plane = FLOAT_PLANE
|
||||
A.overlays += I
|
||||
|
||||
// Chat message
|
||||
var/act_jump = ""
|
||||
if(isatom(source))
|
||||
act_jump = "<a href='?src=[M.UID()];jump=\ref[source]'>\[Teleport]</a>"
|
||||
var/act_signup = "<a href='?src=[A.UID()];signup=1'>\[Sign Up]</a>"
|
||||
to_chat(M, "<big><span class='boldnotice'>Now looking for candidates [role ? "to play as \an [role_cleanname || get_roletext(role)]" : "\"[question]\""]. [act_jump] [act_signup]</span></big>")
|
||||
|
||||
// Start processing it so it updates visually the timer
|
||||
START_PROCESSING(SSprocessing, A)
|
||||
A.process()
|
||||
|
||||
@@ -620,20 +620,32 @@ SUBSYSTEM_DEF(jobs)
|
||||
var/mob/M = tgtcard.getPlayer()
|
||||
for(var/datum/job/job in occupations)
|
||||
if(tgtcard.assignment && tgtcard.assignment == job.title)
|
||||
jobs_to_formats[job.title] = "disabled" // the job they already have is pre-selected
|
||||
jobs_to_formats[job.title] = "green" // the job they already have is pre-selected
|
||||
else if(tgtcard.assignment == "Demoted" || tgtcard.assignment == "Terminated")
|
||||
jobs_to_formats[job.title] = "grey"
|
||||
else if(!job.would_accept_job_transfer_from_player(M))
|
||||
jobs_to_formats[job.title] = "linkDiscourage" // jobs which are karma-locked and not unlocked for this player are discouraged
|
||||
jobs_to_formats[job.title] = "grey" // jobs which are karma-locked and not unlocked for this player are discouraged
|
||||
else if((job.title in GLOB.command_positions) && istype(M) && M.client && job.available_in_playtime(M.client))
|
||||
jobs_to_formats[job.title] = "linkDiscourage" // command jobs which are playtime-locked and not unlocked for this player are discouraged
|
||||
jobs_to_formats[job.title] = "grey" // command jobs which are playtime-locked and not unlocked for this player are discouraged
|
||||
else if(job.total_positions && !job.current_positions && job.title != "Civilian")
|
||||
jobs_to_formats[job.title] = "linkEncourage" // jobs with nobody doing them at all are encouraged
|
||||
jobs_to_formats[job.title] = "teal" // jobs with nobody doing them at all are encouraged
|
||||
else if(job.total_positions >= 0 && job.current_positions >= job.total_positions)
|
||||
jobs_to_formats[job.title] = "linkDiscourage" // jobs that are full (no free positions) are discouraged
|
||||
jobs_to_formats[job.title] = "grey" // jobs that are full (no free positions) are discouraged
|
||||
if(tgtcard.assignment == "Demoted" || tgtcard.assignment == "Terminated")
|
||||
jobs_to_formats["Custom"] = "grey"
|
||||
return jobs_to_formats
|
||||
|
||||
|
||||
/datum/controller/subsystem/jobs/proc/log_job_transfer(transferee, oldvalue, newvalue, whodidit)
|
||||
id_change_records["[id_change_counter]"] = list("transferee" = transferee, "oldvalue" = oldvalue, "newvalue" = newvalue, "whodidit" = whodidit, "timestamp" = station_time_timestamp())
|
||||
|
||||
/datum/controller/subsystem/jobs/proc/log_job_transfer(transferee, oldvalue, newvalue, whodidit, reason)
|
||||
id_change_records["[id_change_counter]"] = list(
|
||||
"transferee" = transferee,
|
||||
"oldvalue" = oldvalue,
|
||||
"newvalue" = newvalue,
|
||||
"whodidit" = whodidit,
|
||||
"timestamp" = station_time_timestamp(),
|
||||
"reason" = reason
|
||||
)
|
||||
id_change_counter++
|
||||
|
||||
/datum/controller/subsystem/jobs/proc/slot_job_transfer(oldtitle, newtitle)
|
||||
@@ -663,45 +675,35 @@ SUBSYSTEM_DEF(jobs)
|
||||
return
|
||||
var/datum/data/pda/app/messenger/PM = target_pda.find_program(/datum/data/pda/app/messenger)
|
||||
if(PM && PM.can_receive())
|
||||
PM.notify("<b>Automated Notification: </b>\"[antext]\" (Unable to Reply)")
|
||||
PM.notify("<b>Automated Notification: </b>\"[antext]\" (Unable to Reply)", 0) // the 0 means don't make the PDA flash
|
||||
|
||||
/datum/controller/subsystem/jobs/proc/notify_by_name(target_name, antext)
|
||||
// Used to notify a specific crew member based on their real_name
|
||||
if(!target_name || !antext)
|
||||
return
|
||||
var/obj/item/pda/target_pda
|
||||
for(var/obj/item/pda/check_pda in GLOB.PDAs)
|
||||
if(check_pda.owner == target_name)
|
||||
target_pda = check_pda
|
||||
break
|
||||
if(!target_pda)
|
||||
return
|
||||
var/datum/data/pda/app/messenger/PM = target_pda.find_program(/datum/data/pda/app/messenger)
|
||||
if(PM && PM.can_receive())
|
||||
PM.notify("<b>Automated Notification: </b>\"[antext]\" (Unable to Reply)", 0) // the 0 means don't make the PDA flash
|
||||
|
||||
/datum/controller/subsystem/jobs/proc/fetch_transfer_record_html(var/centcom)
|
||||
var/record_html = "<TABLE border=\"1\">"
|
||||
|
||||
var/table_headers = list("Crewman", "Old Rank", "New Rank", "Authorized By", "Time")
|
||||
var/hidden_fields = list("deletedby")
|
||||
if(centcom)
|
||||
table_headers += "<span class='bad'>Deleted By</span>"
|
||||
record_html += "<TR>"
|
||||
for(var/thisheader in table_headers)
|
||||
record_html += "<TD><B>[thisheader]</B></TD>"
|
||||
record_html += "</TR>"
|
||||
|
||||
var/visible_record_count = 0
|
||||
/datum/controller/subsystem/jobs/proc/format_job_change_records(centcom)
|
||||
var/list/formatted = list()
|
||||
for(var/thisid in id_change_records)
|
||||
var/thisrecord = id_change_records[thisid]
|
||||
|
||||
if(thisrecord["deletedby"] && !centcom)
|
||||
continue
|
||||
|
||||
record_html += "<TR>"
|
||||
var/list/newlist = list()
|
||||
for(var/lkey in thisrecord)
|
||||
if(lkey in hidden_fields)
|
||||
if(centcom)
|
||||
record_html += "<TD><span class='bad'>[thisrecord[lkey]]<span></TD>"
|
||||
else
|
||||
continue
|
||||
else
|
||||
record_html += "<TD>[thisrecord[lkey]]</TD>"
|
||||
record_html += "</TR>"
|
||||
visible_record_count++
|
||||
newlist[lkey] = thisrecord[lkey]
|
||||
formatted.Add(list(newlist))
|
||||
return formatted
|
||||
|
||||
record_html += "</TABLE>"
|
||||
|
||||
if(!visible_record_count)
|
||||
return "No records on file yet."
|
||||
return record_html
|
||||
|
||||
/datum/controller/subsystem/jobs/proc/delete_log_records(sourceuser, delete_all)
|
||||
. = 0
|
||||
|
||||
@@ -34,7 +34,7 @@ SUBSYSTEM_DEF(parallax)
|
||||
for (A; isloc(A.loc) && !isturf(A.loc); A = A.loc);
|
||||
|
||||
if(A != C.movingmob)
|
||||
if(C.movingmob != null)
|
||||
if(C.movingmob != null && C.movingmob.client_mobs_in_contents)
|
||||
C.movingmob.client_mobs_in_contents -= C.mob
|
||||
UNSETEMPTY(C.movingmob.client_mobs_in_contents)
|
||||
LAZYINITLIST(A.client_mobs_in_contents)
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(instruments)
|
||||
name = "Instruments"
|
||||
init_order = INIT_ORDER_INSTRUMENTS
|
||||
wait = 1
|
||||
flags = SS_TICKER|SS_BACKGROUND|SS_KEEP_TIMING
|
||||
offline_implications = "Instruments will no longer play. No immediate action is needed."
|
||||
|
||||
/// List of all instrument data, associative id = datum
|
||||
var/list/datum/instrument/instrument_data
|
||||
/// List of all song datums.
|
||||
var/list/datum/song/songs
|
||||
/// Max lines in songs
|
||||
var/musician_maxlines = 600
|
||||
/// Max characters per line in songs
|
||||
var/musician_maxlinechars = 300
|
||||
/// Deciseconds between hearchecks. Too high and instruments seem to lag when people are moving around in terms of who can hear it. Too low and the server lags from this.
|
||||
var/musician_hearcheck_mindelay = 5
|
||||
/// Maximum instrument channels total instruments are allowed to use. This is so you don't have instruments deadlocking all sound channels.
|
||||
var/max_instrument_channels = MAX_INSTRUMENT_CHANNELS
|
||||
/// Current number of channels allocated for instruments
|
||||
var/current_instrument_channels = 0
|
||||
/// Single cached list for synthesizer instrument ids, so you don't have to have a new list with every synthesizer.
|
||||
var/list/synthesizer_instrument_ids
|
||||
|
||||
/datum/controller/subsystem/processing/instruments/Initialize()
|
||||
initialize_instrument_data()
|
||||
synthesizer_instrument_ids = get_allowed_instrument_ids()
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Initializes all instrument datums
|
||||
*/
|
||||
/datum/controller/subsystem/processing/instruments/proc/initialize_instrument_data()
|
||||
instrument_data = list()
|
||||
for(var/path in subtypesof(/datum/instrument))
|
||||
var/datum/instrument/I = path
|
||||
if(initial(I.abstract_type) == path)
|
||||
continue
|
||||
I = new path
|
||||
I.Initialize()
|
||||
if(!I.id)
|
||||
qdel(I)
|
||||
continue
|
||||
else
|
||||
instrument_data[I.id] = I
|
||||
CHECK_TICK
|
||||
|
||||
/**
|
||||
* Reserves a sound channel for a given instrument datum
|
||||
*
|
||||
* Arguments:
|
||||
* * I - The instrument datum
|
||||
*/
|
||||
/datum/controller/subsystem/processing/instruments/proc/reserve_instrument_channel(datum/instrument/I)
|
||||
if(current_instrument_channels > max_instrument_channels)
|
||||
return
|
||||
. = SSsounds.reserve_sound_channel(I)
|
||||
if(!isnull(.))
|
||||
current_instrument_channels++
|
||||
|
||||
/**
|
||||
* Called when a datum/song is created
|
||||
*
|
||||
* Arguments:
|
||||
* * S - The created datum/song
|
||||
*/
|
||||
/datum/controller/subsystem/processing/instruments/proc/on_song_new(datum/song/S)
|
||||
LAZYADD(songs, S)
|
||||
|
||||
/**
|
||||
* Called when a datum/song is deleted
|
||||
*
|
||||
* Arguments:
|
||||
* * S - The deleted datum/song
|
||||
*/
|
||||
/datum/controller/subsystem/processing/instruments/proc/on_song_del(datum/song/S)
|
||||
LAZYREMOVE(songs, S)
|
||||
|
||||
/**
|
||||
* Returns the instrument datum at the given ID or path
|
||||
*
|
||||
* Arguments:
|
||||
* * id_or_path - The ID or path of the instrument
|
||||
*/
|
||||
/datum/controller/subsystem/processing/instruments/proc/get_instrument(id_or_path)
|
||||
return instrument_data["[id_or_path]"]
|
||||
@@ -14,9 +14,9 @@ SUBSYSTEM_DEF(shuttle)
|
||||
//emergency shuttle stuff
|
||||
var/obj/docking_port/mobile/emergency/emergency
|
||||
var/obj/docking_port/mobile/emergency/backup/backup_shuttle
|
||||
var/emergencyCallTime = 6000 //time taken for emergency shuttle to reach the station when called (in deciseconds)
|
||||
var/emergencyDockTime = 1800 //time taken for emergency shuttle to leave again once it has docked (in deciseconds)
|
||||
var/emergencyEscapeTime = 1200 //time taken for emergency shuttle to reach a safe distance after leaving station (in deciseconds)
|
||||
var/emergencyCallTime = SHUTTLE_CALLTIME //time taken for emergency shuttle to reach the station when called (in deciseconds)
|
||||
var/emergencyDockTime = SHUTTLE_DOCKTIME //time taken for emergency shuttle to leave again once it has docked (in deciseconds)
|
||||
var/emergencyEscapeTime = SHUTTLE_ESCAPETIME //time taken for emergency shuttle to reach a safe distance after leaving station (in deciseconds)
|
||||
var/emergency_sec_level_time = 0 // time sec level was last raised to red or higher
|
||||
var/area/emergencyLastCallLoc
|
||||
var/emergencyNoEscape
|
||||
@@ -31,7 +31,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
var/points_per_intel = 250 //points gained per intel returned
|
||||
var/points_per_plasma = 5 //points gained per plasma returned
|
||||
var/points_per_design = 25 //points gained per research design returned
|
||||
var/centcom_message = "" //Remarks from Centcom on how well you checked the last order.
|
||||
var/centcom_message = null //Remarks from Centcom on how well you checked the last order.
|
||||
var/list/discoveredPlants = list() //Typepaths for unusual plants we've already sent CentComm, associated with their potencies
|
||||
var/list/techLevels = list()
|
||||
var/list/researchDesigns = list()
|
||||
@@ -61,6 +61,8 @@ SUBSYSTEM_DEF(shuttle)
|
||||
supply_packs["[P.type]"] = P
|
||||
initial_move()
|
||||
|
||||
centcom_message = "<center>---[station_time_timestamp()]---</center><br>Remember to stamp and send back the supply manifests.<hr>"
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/shuttle/stat_entry(msg)
|
||||
@@ -93,6 +95,11 @@ SUBSYSTEM_DEF(shuttle)
|
||||
return S
|
||||
WARNING("couldn't find dock with id: [id]")
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/secondsToRefuel()
|
||||
var/elapsed = world.time - SSticker.round_start_time
|
||||
var/remaining = round((config.shuttle_refuel_delay - elapsed) / 10)
|
||||
return remaining > 0 ? remaining : 0
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/requestEvac(mob/user, call_reason)
|
||||
if(!emergency)
|
||||
WARNING("requestEvac(): There is no emergency shuttle, but the shuttle was called. Using the backup shuttle instead.")
|
||||
@@ -107,7 +114,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
return
|
||||
emergency = backup_shuttle
|
||||
|
||||
if(world.time - SSticker.round_start_time < config.shuttle_refuel_delay)
|
||||
if(secondsToRefuel())
|
||||
to_chat(user, "The emergency shuttle is refueling. Please wait another [abs(round(((world.time - SSticker.round_start_time) - config.shuttle_refuel_delay)/600))] minutes before trying again.")
|
||||
return
|
||||
|
||||
@@ -131,7 +138,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
call_reason = trim(html_encode(call_reason))
|
||||
|
||||
if(length(call_reason) < CALL_SHUTTLE_REASON_LENGTH)
|
||||
to_chat(user, "You must provide a reason.")
|
||||
to_chat(user, "Reason is too short. [CALL_SHUTTLE_REASON_LENGTH] character minimum.")
|
||||
return
|
||||
|
||||
var/area/signal_origin = get_area(user)
|
||||
@@ -192,7 +199,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
var/obj/machinery/computer/communications/C = thing
|
||||
if(C.stat & BROKEN)
|
||||
continue
|
||||
else if(istype(thing, /datum/computer_file/program/comm) || istype(thing, /obj/item/circuitboard/communications))
|
||||
else if(istype(thing, /obj/item/circuitboard/communications))
|
||||
continue
|
||||
|
||||
var/turf/T = get_turf(thing)
|
||||
@@ -247,7 +254,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
/datum/controller/subsystem/shuttle/proc/generateSupplyOrder(packId, _orderedby, _orderedbyRank, _comment, _crates)
|
||||
if(!packId)
|
||||
return
|
||||
var/datum/supply_packs/P = supply_packs["[packId]"]
|
||||
var/datum/supply_packs/P = locateUID(packId)
|
||||
if(!P)
|
||||
return
|
||||
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
#define DATUMLESS "NO_DATUM"
|
||||
|
||||
SUBSYSTEM_DEF(sounds)
|
||||
name = "Sounds"
|
||||
init_order = INIT_ORDER_SOUNDS
|
||||
flags = SS_NO_FIRE
|
||||
offline_implications = "Sounds may not play correctly. Shuttle call recommended."
|
||||
|
||||
var/using_channels_max = CHANNEL_HIGHEST_AVAILABLE // BYOND max channels
|
||||
/// Amount of channels to reserve for random usage rather than reservations being allowed to reserve all channels. Also a nice safeguard for when someone screws up.
|
||||
var/random_channels_min = 50
|
||||
// Hey uh these two needs to be initialized fast because the whole "things get deleted before init" thing.
|
||||
/// Assoc list, "[channel]" = either the datum using it or TRUE for an unsafe-reserved (datumless reservation) channel
|
||||
var/list/using_channels
|
||||
/// Assoc list datum = list(channel1, channel2, ...) for what channels something reserved.
|
||||
var/list/using_channels_by_datum
|
||||
// Special datastructure for fast channel management
|
||||
/// List of all channels as numbers
|
||||
var/list/channel_list
|
||||
/// Associative list of all reserved channels associated to their position. "[channel_number]" = index as number
|
||||
var/list/reserved_channels
|
||||
/// lower iteration position - Incremented and looped to get "random" sound channels for normal sounds. The channel at this index is returned when asking for a random channel.
|
||||
var/channel_random_low
|
||||
/// higher reserve position - decremented and incremented to reserve sound channels, anything above this is reserved. The channel at this index is the highest unreserved channel.
|
||||
var/channel_reserve_high
|
||||
|
||||
/datum/controller/subsystem/sounds/Initialize()
|
||||
setup_available_channels()
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Sets up all available sound channels
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/setup_available_channels()
|
||||
channel_list = list()
|
||||
reserved_channels = list()
|
||||
using_channels = list()
|
||||
using_channels_by_datum = list()
|
||||
for(var/i in 1 to using_channels_max)
|
||||
channel_list += i
|
||||
channel_random_low = 1
|
||||
channel_reserve_high = length(channel_list)
|
||||
|
||||
/**
|
||||
* Removes a channel from using list
|
||||
*
|
||||
* Arguments:
|
||||
* * channel - The channel number
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/free_sound_channel(channel)
|
||||
var/text_channel = num2text(channel)
|
||||
var/using = using_channels[text_channel]
|
||||
using_channels -= text_channel
|
||||
if(!using) // datum channel
|
||||
using_channels_by_datum[using] -= channel
|
||||
if(!length(using_channels_by_datum[using]))
|
||||
using_channels_by_datum -= using
|
||||
free_channel(channel)
|
||||
|
||||
/**
|
||||
* Frees all the channels a datum is using
|
||||
*
|
||||
* Arguments:
|
||||
* * D - The datum
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/free_datum_channels(datum/D)
|
||||
var/list/L = using_channels_by_datum[D]
|
||||
if(!L)
|
||||
return
|
||||
for(var/channel in L)
|
||||
using_channels -= num2text(channel)
|
||||
free_channel(channel)
|
||||
using_channels_by_datum -= D
|
||||
|
||||
/**
|
||||
* Frees all datumless channels
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/free_datumless_channels()
|
||||
free_datum_channels(DATUMLESS)
|
||||
|
||||
/**
|
||||
* NO AUTOMATIC CLEANUP - If you use this, you better manually free it later!
|
||||
*
|
||||
* Returns an integer for channel
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/reserve_sound_channel_datumless()
|
||||
. = reserve_channel()
|
||||
if(!.) // oh no..
|
||||
return FALSE
|
||||
var/text_channel = num2text(.)
|
||||
using_channels[text_channel] = DATUMLESS
|
||||
LAZYADD(using_channels_by_datum[DATUMLESS], .)
|
||||
|
||||
/**
|
||||
* Reserves a channel for a datum. Automatic cleanup only when the datum is deleted.
|
||||
*
|
||||
* Returns an integer for channel
|
||||
* Arguments:
|
||||
* * D - The datum
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/reserve_sound_channel(datum/D)
|
||||
if(!D) // i don't like typechecks but someone will fuck it up
|
||||
CRASH("Attempted to reserve sound channel without datum using the managed proc.")
|
||||
. = reserve_channel()
|
||||
if(!.)
|
||||
return FALSE
|
||||
var/text_channel = num2text(.)
|
||||
using_channels[text_channel] = D
|
||||
LAZYADD(using_channels_by_datum[D], .)
|
||||
|
||||
/**
|
||||
* Reserves a channel and updates the datastructure. Private proc.
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/reserve_channel()
|
||||
PRIVATE_PROC(TRUE)
|
||||
if(channel_reserve_high <= random_channels_min) // out of channels
|
||||
return
|
||||
var/channel = channel_list[channel_reserve_high]
|
||||
reserved_channels[num2text(channel)] = channel_reserve_high--
|
||||
return channel
|
||||
|
||||
/**
|
||||
* Frees a channel and updates the datastructure. Private proc.
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/free_channel(number)
|
||||
PRIVATE_PROC(TRUE)
|
||||
var/text_channel = num2text(number)
|
||||
var/index = reserved_channels[text_channel]
|
||||
if(!index)
|
||||
CRASH("Attempted to (internally) free a channel that wasn't reserved.")
|
||||
reserved_channels -= text_channel
|
||||
// push reserve index up, which makes it now on a channel that is reserved
|
||||
channel_reserve_high++
|
||||
// swap the reserved channel with the unreserved channel so the reserve index is now on an unoccupied channel and the freed channel is next to be used.
|
||||
channel_list.Swap(channel_reserve_high, index)
|
||||
// now, an existing reserved channel will likely (exception: unreserving last reserved channel) be at index
|
||||
// get it, and update position.
|
||||
var/text_reserved = num2text(channel_list[index])
|
||||
if(!reserved_channels[text_reserved]) // if it isn't already reserved make sure we don't accidently mistakenly put it on reserved list!
|
||||
return
|
||||
reserved_channels[text_reserved] = index
|
||||
|
||||
/**
|
||||
* Random available channel, returns text
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/random_available_channel_text()
|
||||
if(channel_random_low > channel_reserve_high)
|
||||
channel_random_low = 1
|
||||
. = "[channel_list[channel_random_low++]]"
|
||||
|
||||
/**
|
||||
* Random available channel, returns number
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/random_available_channel()
|
||||
if(channel_random_low > channel_reserve_high)
|
||||
channel_random_low = 1
|
||||
. = channel_list[channel_random_low++]
|
||||
|
||||
/**
|
||||
* How many channels we have left
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/available_channels_left()
|
||||
return length(channel_list) - random_channels_min
|
||||
|
||||
#undef DATUMLESS
|
||||
@@ -126,6 +126,8 @@ SUBSYSTEM_DEF(tgui)
|
||||
* return int The number of UIs closed.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/close_uis(datum/src_object)
|
||||
if(!src_object.unique_datum_id) // First check if the datum has an UID set
|
||||
return 0
|
||||
var/src_object_key = "[src_object.UID()]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return 0 // Couldn't find any UIs for this object.
|
||||
|
||||
@@ -65,6 +65,8 @@ SUBSYSTEM_DEF(ticker)
|
||||
to_chat(world, "Please, setup your character and select ready. Game will start in [config.pregame_timestart] seconds")
|
||||
current_state = GAME_STATE_PREGAME
|
||||
fire() // TG says this is a good idea
|
||||
for(var/mob/new_player/N in GLOB.player_list)
|
||||
N.new_player_panel_proc() // to enable the observe option
|
||||
if(GAME_STATE_PREGAME)
|
||||
if(!SSticker.ticker_going) // This has to be referenced like this, and I dont know why. If you dont put SSticker. it will break
|
||||
return
|
||||
|
||||
@@ -25,4 +25,4 @@ GLOBAL_REAL(SSmentor_tickets, /datum/controller/subsystem/tickets/mentor_tickets
|
||||
message_mentorTicket(msg)
|
||||
|
||||
/datum/controller/subsystem/tickets/mentor_tickets/create_other_system_ticket(datum/ticket/T)
|
||||
SStickets.newTicket(T.clientName, T.content, T.title)
|
||||
SStickets.newTicket(get_client_by_ckey(T.client_ckey), T.content, T.title)
|
||||
|
||||
@@ -93,7 +93,7 @@ SUBSYSTEM_DEF(tickets)
|
||||
|
||||
var/datum/ticket/T = new(title, passedContent, getTicketCounterAndInc())
|
||||
allTickets += T
|
||||
T.clientName = C
|
||||
T.client_ckey = C.ckey
|
||||
T.locationSent = C.mob.loc.name
|
||||
T.mobControlled = C.mob
|
||||
|
||||
@@ -139,14 +139,16 @@ SUBSYSTEM_DEF(tickets)
|
||||
/datum/controller/subsystem/tickets/proc/convert_ticket(datum/ticket/T)
|
||||
T.ticketState = TICKET_CLOSED
|
||||
var/client/C = usr.client
|
||||
to_chat_safe(T.clientName, list("<span class='[span_class]'>[key_name_hidden(C)] has converted your ticket to a [other_ticket_name] ticket.</span>",\
|
||||
var/client/owner = get_client_by_ckey(T.client_ckey)
|
||||
to_chat_safe(owner, list("<span class='[span_class]'>[key_name_hidden(C)] has converted your ticket to a [other_ticket_name] ticket.</span>",\
|
||||
"<span class='[span_class]'>Be sure to use the correct type of help next time!</span>"))
|
||||
message_staff("<span class='[span_class]'>[C] has converted ticket number [T.ticketNum] to a [other_ticket_name] ticket.</span>")
|
||||
log_game("[C] has converted ticket number [T.ticketNum] to a [other_ticket_name] ticket.")
|
||||
create_other_system_ticket(T)
|
||||
|
||||
/datum/controller/subsystem/tickets/proc/create_other_system_ticket(datum/ticket/T)
|
||||
SSmentor_tickets.newTicket(T.clientName, T.content, T.title)
|
||||
var/client/C = get_client_by_ckey(T.client_ckey)
|
||||
SSmentor_tickets.newTicket(C, T.content, T.title)
|
||||
|
||||
/datum/controller/subsystem/tickets/proc/autoRespond(N)
|
||||
if(!check_rights(rights_needed))
|
||||
@@ -177,7 +179,7 @@ SUBSYSTEM_DEF(tickets)
|
||||
sorted_responses += key
|
||||
|
||||
var/message_key = input("Select an autoresponse. This will mark the ticket as resolved.", "Autoresponse") as null|anything in sortTim(sorted_responses, /proc/cmp_text_asc) //use sortTim and cmp_text_asc to sort alphabetically
|
||||
|
||||
var/client/ticket_owner = get_client_by_ckey(T.client_ckey)
|
||||
switch(message_key)
|
||||
if(null) //they cancelled
|
||||
T.staffAssigned = initial(T.staffAssigned) //if they cancel we dont need to hold this ticket anymore
|
||||
@@ -189,18 +191,18 @@ SUBSYSTEM_DEF(tickets)
|
||||
C.man_up(returnClient(N))
|
||||
T.lastStaffResponse = "Autoresponse: [message_key]"
|
||||
resolveTicket(N)
|
||||
message_staff("[C] has auto responded to [T.clientName]\'s adminhelp with:<span class='adminticketalt'> [message_key] </span>")
|
||||
log_game("[C] has auto responded to [T.clientName]\'s adminhelp with: [response_phrases[message_key]]")
|
||||
message_staff("[C] has auto responded to [ticket_owner]\'s adminhelp with:<span class='adminticketalt'> [message_key] </span>")
|
||||
log_game("[C] has auto responded to [ticket_owner]\'s adminhelp with: [response_phrases[message_key]]")
|
||||
if("Mentorhelp")
|
||||
convert_ticket(T)
|
||||
else
|
||||
var/msg_sound = sound('sound/effects/adminhelp.ogg')
|
||||
SEND_SOUND(returnClient(N), msg_sound)
|
||||
to_chat_safe(returnClient(N), "<span class='[span_class]'>[key_name_hidden(C)] is autoresponding with: <span/> <span class='adminticketalt'>[response_phrases[message_key]]</span>")//for this we want the full value of whatever key this is to tell the player so we do response_phrases[message_key]
|
||||
message_staff("[C] has auto responded to [T.clientName]\'s adminhelp with:<span class='adminticketalt'> [message_key] </span>") //we want to use the short named keys for this instead of the full sentence which is why we just do message_key
|
||||
message_staff("[C] has auto responded to [ticket_owner]\'s adminhelp with:<span class='adminticketalt'> [message_key] </span>") //we want to use the short named keys for this instead of the full sentence which is why we just do message_key
|
||||
T.lastStaffResponse = "Autoresponse: [message_key]"
|
||||
resolveTicket(N)
|
||||
log_game("[C] has auto responded to [T.clientName]\'s adminhelp with: [response_phrases[message_key]]")
|
||||
log_game("[C] has auto responded to [ticket_owner]\'s adminhelp with: [response_phrases[message_key]]")
|
||||
|
||||
//Set ticket state with key N to closed
|
||||
/datum/controller/subsystem/tickets/proc/closeTicket(N)
|
||||
@@ -214,7 +216,7 @@ SUBSYSTEM_DEF(tickets)
|
||||
//Check if the user already has a ticket open and within the cooldown period.
|
||||
/datum/controller/subsystem/tickets/proc/checkForOpenTicket(client/C)
|
||||
for(var/datum/ticket/T in allTickets)
|
||||
if(T.clientName == C && T.ticketState == TICKET_OPEN && (T.ticketCooldown > world.time))
|
||||
if(T.client_ckey == C.ckey && T.ticketState == TICKET_OPEN && (T.ticketCooldown > world.time))
|
||||
return T
|
||||
return FALSE
|
||||
|
||||
@@ -222,7 +224,7 @@ SUBSYSTEM_DEF(tickets)
|
||||
/datum/controller/subsystem/tickets/proc/checkForTicket(client/C)
|
||||
var/list/tickets = list()
|
||||
for(var/datum/ticket/T in allTickets)
|
||||
if(T.clientName == C && (T.ticketState == TICKET_OPEN || T.ticketState == TICKET_STALE))
|
||||
if(T.client_ckey == C.ckey && (T.ticketState == TICKET_OPEN || T.ticketState == TICKET_STALE))
|
||||
tickets += T
|
||||
if(tickets.len)
|
||||
return tickets
|
||||
@@ -231,7 +233,7 @@ SUBSYSTEM_DEF(tickets)
|
||||
//return the client of a ticket number
|
||||
/datum/controller/subsystem/tickets/proc/returnClient(N)
|
||||
var/datum/ticket/T = allTickets[N]
|
||||
return T.clientName
|
||||
return get_client_by_ckey(T.client_ckey)
|
||||
|
||||
/datum/controller/subsystem/tickets/proc/assignStaffToTicket(client/C, N)
|
||||
var/datum/ticket/T = allTickets[N]
|
||||
@@ -244,7 +246,8 @@ SUBSYSTEM_DEF(tickets)
|
||||
|
||||
/datum/ticket
|
||||
var/ticketNum // Ticket number
|
||||
var/clientName // Client which opened the ticket
|
||||
/// ckey of the client who opened the ticket
|
||||
var/client_ckey
|
||||
var/timeOpened // Time the ticket was opened
|
||||
var/title //The initial message with links
|
||||
var/list/content // content of the staff help
|
||||
@@ -379,7 +382,7 @@ UI STUFF
|
||||
|
||||
dat += "<h2>Ticket #[T.ticketNum]</h2>"
|
||||
|
||||
dat += "<h3>[T.clientName] / [T.mobControlled] opened this [ticket_name] at [T.timeOpened] at location [T.locationSent]</h3>"
|
||||
dat += "<h3>[T.client_ckey] / [T.mobControlled] opened this [ticket_name] at [T.timeOpened] at location [T.locationSent]</h3>"
|
||||
dat += "<h4>Ticket Status: <font color='red'>[status]</font>"
|
||||
dat += "<table style='width:950px; border: 3px solid;'>"
|
||||
dat += "<tr><td>[T.title]</td></tr>"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.")
|
||||
|
||||
/client/proc/debug_controller(controller in list("failsafe", "Master", "Ticker", "Air", "Jobs", "Sun", "Radio", "Configuration", "pAI",
|
||||
"Cameras", "Garbage", "Event", "Alarm", "Nano", "Vote", "Fires",
|
||||
"Cameras", "Garbage", "Event", "Nano", "Vote", "Fires",
|
||||
"Mob", "NPC Pool", "Shuttle", "Timer", "Weather", "Space", "Mob Hunt Server","Input"))
|
||||
set category = "Debug"
|
||||
set name = "Debug Controller"
|
||||
@@ -65,9 +65,6 @@
|
||||
if("Event")
|
||||
debug_variables(SSevents)
|
||||
feedback_add_details("admin_verb","DEvent")
|
||||
if("Alarm")
|
||||
debug_variables(SSalarms)
|
||||
feedback_add_details("admin_verb", "DAlarm")
|
||||
if("Nano")
|
||||
debug_variables(SSnanoui)
|
||||
feedback_add_details("admin_verb","DNano")
|
||||
|
||||
+24
-16
@@ -174,6 +174,14 @@
|
||||
/datum/action/item_action/print_report
|
||||
name = "Print Report"
|
||||
|
||||
/datum/action/item_action/print_forensic_report
|
||||
name = "Print Report"
|
||||
button_icon_state = "scanner_print"
|
||||
use_itemicon = FALSE
|
||||
|
||||
/datum/action/item_action/clear_records
|
||||
name = "Clear Scanner Records"
|
||||
|
||||
/datum/action/item_action/toggle_gunlight
|
||||
name = "Toggle Gunlight"
|
||||
|
||||
@@ -202,9 +210,6 @@
|
||||
/datum/action/item_action/toggle_mister
|
||||
name = "Toggle Mister"
|
||||
|
||||
/datum/action/item_action/toggle_headphones
|
||||
name = "Toggle Headphones"
|
||||
|
||||
/datum/action/item_action/toggle_helmet_light
|
||||
name = "Toggle Helmet Light"
|
||||
|
||||
@@ -244,19 +249,6 @@
|
||||
button.name = name
|
||||
..()
|
||||
|
||||
/datum/action/item_action/synthswitch
|
||||
name = "Change Synthesizer Instrument"
|
||||
desc = "Change the type of instrument your synthesizer is playing as."
|
||||
|
||||
/datum/action/item_action/synthswitch/Trigger()
|
||||
if(istype(target, /obj/item/instrument/piano_synth))
|
||||
var/obj/item/instrument/piano_synth/synth = target
|
||||
var/chosen = input("Choose the type of instrument you want to use", "Instrument Selection", "piano") as null|anything in synth.insTypes
|
||||
if(!synth.insTypes[chosen])
|
||||
return
|
||||
return synth.changeInstrument(chosen)
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/vortex_recall
|
||||
name = "Vortex Recall"
|
||||
desc = "Recall yourself, and anyone nearby, to an attuned hierophant beacon at any time.<br>If the beacon is still attached, will detach it."
|
||||
@@ -269,6 +261,9 @@
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/change_headphones_song
|
||||
name = "Change Headphones Song"
|
||||
|
||||
/datum/action/item_action/toggle
|
||||
|
||||
/datum/action/item_action/toggle/New(Target)
|
||||
@@ -475,6 +470,7 @@
|
||||
/datum/action/spell_action
|
||||
check_flags = 0
|
||||
background_icon_state = "bg_spell"
|
||||
var/recharge_text_color = "#FFFFFF"
|
||||
|
||||
/datum/action/spell_action/New(Target)
|
||||
..()
|
||||
@@ -512,6 +508,18 @@
|
||||
return spell.can_cast(owner)
|
||||
return FALSE
|
||||
|
||||
/datum/action/spell_action/UpdateButtonIcon()
|
||||
if(button && !(. = ..()))
|
||||
var/obj/effect/proc_holder/spell/S = target
|
||||
if(!istype(S))
|
||||
return
|
||||
var/progress = S.get_availability_percentage()
|
||||
var/col_val_high = 72 * progress + 128
|
||||
var/col_val_low = 200 * progress
|
||||
button.maptext = "<div style=\"font-size:6pt;color:[recharge_text_color];font:'Small Fonts';text-align:center;\" valign=\"bottom\">[round_down(progress * 100)]%</div>"
|
||||
button.color = rgb(col_val_high, col_val_low, col_val_low, col_val_high)
|
||||
else
|
||||
button.maptext = null
|
||||
/*
|
||||
/datum/action/spell_action/alien
|
||||
|
||||
|
||||
Vendored
+5
-1
@@ -1,3 +1,5 @@
|
||||
#define AIR_ALARM_DATA_CACHE_DURATION 10 SECONDS
|
||||
|
||||
GLOBAL_DATUM_INIT(air_alarm_repository, /datum/repository/air_alarm, new())
|
||||
|
||||
/datum/repository/air_alarm/proc/air_alarm_data(var/list/monitored_alarms, var/refresh = 0, var/obj/machinery/alarm/passed_alarm)
|
||||
@@ -8,7 +10,7 @@ GLOBAL_DATUM_INIT(air_alarm_repository, /datum/repository/air_alarm, new())
|
||||
cache_entry = new/datum/cache_entry
|
||||
cache_data = cache_entry
|
||||
|
||||
if(!refresh)
|
||||
if(!refresh && cache_entry.timestamp + AIR_ALARM_DATA_CACHE_DURATION > world.time)
|
||||
return cache_entry.data
|
||||
|
||||
if(SSticker && SSticker.current_state < GAME_STATE_PLAYING && istype(passed_alarm)) // Generating the list for the first time as the game hasn't started - no need to run through the machines list everything every time
|
||||
@@ -29,3 +31,5 @@ GLOBAL_DATUM_INIT(air_alarm_repository, /datum/repository/air_alarm, new())
|
||||
|
||||
/datum/repository/air_alarm/proc/update_cache(var/obj/machinery/alarm/alarm)
|
||||
return air_alarm_data(refresh = 1, passed_alarm = alarm)
|
||||
|
||||
#undef AIR_ALARM_DATA_CACHE_DURATION
|
||||
|
||||
Vendored
+13
-1
@@ -1,5 +1,8 @@
|
||||
GLOBAL_DATUM_INIT(crew_repository, /datum/repository/crew, new())
|
||||
|
||||
/datum/repository/crew
|
||||
var/static/list/bold_jobs
|
||||
|
||||
/datum/repository/crew/New()
|
||||
cache_data = list()
|
||||
..()
|
||||
@@ -18,6 +21,13 @@ GLOBAL_DATUM_INIT(crew_repository, /datum/repository/crew, new())
|
||||
if(world.time < cache_entry.timestamp)
|
||||
return cache_entry.data
|
||||
|
||||
// Initialize the jobs here because in New(), GLOB.command_positions may not be inited yet
|
||||
if(!bold_jobs)
|
||||
bold_jobs = list()
|
||||
bold_jobs += GLOB.command_positions
|
||||
bold_jobs += get_all_centcom_jobs()
|
||||
bold_jobs += list("Nanotrasen Representative", "Blueshield", "Magistrate")
|
||||
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
var/obj/item/clothing/under/C = H.w_uniform
|
||||
@@ -32,11 +42,13 @@ GLOBAL_DATUM_INIT(crew_repository, /datum/repository/crew, new())
|
||||
crewmemberData["name"] = H.get_authentification_name(if_no_id="Unknown")
|
||||
crewmemberData["rank"] = H.get_authentification_rank(if_no_id="Unknown", if_no_job="No Job")
|
||||
crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job")
|
||||
crewmemberData["is_command"] = (crewmemberData["assignment"] in bold_jobs)
|
||||
|
||||
if(C.sensor_mode >= SUIT_SENSOR_BINARY)
|
||||
crewmemberData["dead"] = H.stat > UNCONSCIOUS
|
||||
crewmemberData["dead"] = H.stat == DEAD
|
||||
|
||||
if(C.sensor_mode >= SUIT_SENSOR_VITAL)
|
||||
crewmemberData["stat"] = H.stat
|
||||
crewmemberData["oxy"] = round(H.getOxyLoss(), 1)
|
||||
crewmemberData["tox"] = round(H.getToxLoss(), 1)
|
||||
crewmemberData["fire"] = round(H.getFireLoss(), 1)
|
||||
|
||||
Vendored
+1
-1
@@ -13,7 +13,7 @@ GLOBAL_DATUM_INIT(powermonitor_repository, /datum/repository/powermonitor, new()
|
||||
|
||||
for(var/obj/machinery/computer/monitor/pMon in GLOB.power_monitors)
|
||||
if( !(pMon.stat & (NOPOWER|BROKEN)) && !pMon.is_secret_monitor )
|
||||
pMonData[++pMonData.len] = list ("Name" = pMon.name, "ref" = "\ref[pMon]")
|
||||
pMonData[++pMonData.len] = list ("Name" = pMon.name, "uid" = "[pMon.UID()]")
|
||||
|
||||
cache_entry.timestamp = world.time //+ 30 SECONDS
|
||||
cache_entry.data = pMonData
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
if(!(flags & CALTROP_BYPASS_SHOES) && (H.shoes || feetCover))
|
||||
return
|
||||
|
||||
if((H.flying) || H.buckled)
|
||||
if(H.flying || H.floating || H.buckled)
|
||||
return
|
||||
|
||||
var/damage = rand(min_damage, max_damage)
|
||||
|
||||
@@ -47,23 +47,30 @@
|
||||
return
|
||||
if(!isturf(target))
|
||||
return
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
var/turf/source_turf = get_turf(I)
|
||||
var/turf/target_turf = target
|
||||
var/list/clickparams = params2list(params)
|
||||
var/x_offset = text2num(clickparams["icon-x"]) - 16
|
||||
var/y_offset = text2num(clickparams["icon-y"]) - 16
|
||||
var/x_offset
|
||||
var/y_offset
|
||||
if(target_turf != get_turf(I)) //Trying to stick it on a wall, don't move it to the actual wall or you can move the item through it. Instead set the pixels as appropriate
|
||||
var/target_direction = get_dir(source_turf, target_turf)//The direction we clicked
|
||||
// Snowflake diagonal handling
|
||||
if(target_direction in GLOB.diagonals)
|
||||
to_chat(user, "<span class='warning'>You cant reach [target_turf].</span>")
|
||||
return
|
||||
if(target_direction & EAST)
|
||||
x_offset += 32
|
||||
x_offset = 16
|
||||
y_offset = rand(-12, 12)
|
||||
else if(target_direction & WEST)
|
||||
x_offset -= 32
|
||||
if(target_direction & NORTH)
|
||||
y_offset += 32
|
||||
x_offset = -16
|
||||
y_offset = rand(-12, 12)
|
||||
else if(target_direction & NORTH)
|
||||
x_offset = rand(-12, 12)
|
||||
y_offset = 16
|
||||
else if(target_direction & SOUTH)
|
||||
y_offset -= 32
|
||||
x_offset = rand(-12, 12)
|
||||
y_offset = -16
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You stick [I] to [target_turf].</span>")
|
||||
I.pixel_x = x_offset
|
||||
I.pixel_y = y_offset
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* # Proximity monitor component
|
||||
*
|
||||
* Attaching this component to an atom means that the atom will be able to detect mobs/objs moving within a 1 tile of it.
|
||||
*
|
||||
* The component creates several `obj/effect/abstract/proximity_checker` objects, which follow the parent atom around, always making sure it's at the center.
|
||||
* When something crosses one of these `proximiy_checker`s, the parent has the `HasProximity()` proc called on it, with the crossing mob/obj as the argument.
|
||||
*/
|
||||
/datum/component/proximity_monitor
|
||||
var/atom/owner
|
||||
/// A list of currently created `/obj/effect/abstract/proximity_checker`s in use with this component.
|
||||
var/list/proximity_checkers
|
||||
|
||||
/datum/component/proximity_monitor/Initialize()
|
||||
. = ..()
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
owner = parent
|
||||
create_prox_checkers()
|
||||
|
||||
/datum/component/proximity_monitor/Destroy(force, silent)
|
||||
QDEL_LIST(proximity_checkers)
|
||||
owner = null
|
||||
return ..()
|
||||
|
||||
/datum/component/proximity_monitor/RegisterWithParent()
|
||||
. = ..()
|
||||
if(ismovable(parent))
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/HandleMove)
|
||||
|
||||
/datum/component/proximity_monitor/UnregisterFromParent()
|
||||
. = ..()
|
||||
if(ismovable(parent))
|
||||
UnregisterSignal(parent, COMSIG_MOVABLE_MOVED)
|
||||
|
||||
/**
|
||||
* Called when the `parent` receives the `COMSIG_MOVABLE_MOVED` signal, which occurs when it `Move()`s
|
||||
*
|
||||
* Code is only ran when there is no `Dir`, which occurs when the parent is teleported, gets placed into a storage item, dropped, or picked up.
|
||||
* Normal movement, for example moving 1 tile to the west, is handled by the `proximity_checker` objects.
|
||||
*
|
||||
* Arguments:
|
||||
* * source - this will be the `parent`
|
||||
* * OldLoc - the location the parent just moved from
|
||||
* * Dir - the direction the parent just moved in
|
||||
* * forced - if we were forced to move
|
||||
*/
|
||||
/datum/component/proximity_monitor/proc/HandleMove(datum/source, atom/OldLoc, Dir, forced)
|
||||
if(!Dir) // No dir means the parent teleported, or moved in a non-standard way like getting placed into disposals, onto a table, dropped, picked up, etc.
|
||||
recenter_prox_checkers()
|
||||
|
||||
/**
|
||||
* Called in Initialize(). Generates a set of `/obj/effect/abstract/proximity_checker` objects around the parent, and registers signals to them.
|
||||
*/
|
||||
/datum/component/proximity_monitor/proc/create_prox_checkers()
|
||||
proximity_checkers = list()
|
||||
for(var/turf/T in range(1, get_turf(parent)))
|
||||
var/obj/effect/abstract/proximity_checker/P = new(T, parent)
|
||||
proximity_checkers += P
|
||||
// Basic movement for the proximity_checker objects. The objects will move 1 tile in the direction the parent just moved.
|
||||
P.RegisterSignal(parent, COMSIG_MOVABLE_MOVED, /obj/effect/abstract/proximity_checker/.proc/HandleMove)
|
||||
|
||||
/**
|
||||
* Re-centers all of the parent's `proximity_checker`s around its current location.
|
||||
*/
|
||||
/datum/component/proximity_monitor/proc/recenter_prox_checkers()
|
||||
var/list/prox_checkers = owner.get_all_adjacent_turfs()
|
||||
for(var/checker in proximity_checkers)
|
||||
var/obj/effect/abstract/proximity_checker/P = checker
|
||||
P.loc = pick_n_take(prox_checkers)
|
||||
|
||||
/**
|
||||
* # Proximity checker abstract object
|
||||
*
|
||||
* Inteded for use with the proximity checker component (/datum/component/proximity_monitor).
|
||||
* Whenever a movable atom crosses this object, it calls `HasProximity()` on the object which is listening for proximity (`hasprox_receiver`).
|
||||
*/
|
||||
/obj/effect/abstract/proximity_checker
|
||||
name = "Proximity checker"
|
||||
/// Whether or not the proximity checker is listening for things crossing it.
|
||||
var/active
|
||||
/// The linked atom which has the proximity_monitor component, and will recieve the `HasProximity()` calls.
|
||||
var/atom/hasprox_receiver
|
||||
|
||||
// If this object is initialized without a `_hasprox_receiver` arg, it is qdel'd.
|
||||
/obj/effect/abstract/proximity_checker/Initialize(mapload, atom/_hasprox_receiver)
|
||||
if(_hasprox_receiver)
|
||||
hasprox_receiver = _hasprox_receiver
|
||||
RegisterSignal(hasprox_receiver, COMSIG_PARENT_QDELETING, .proc/OnParentDeletion)
|
||||
if(isturf(hasprox_receiver.loc)) // if the reciever is inside a locker/crate/etc, they don't detect proximity
|
||||
active = TRUE
|
||||
else
|
||||
stack_trace("/obj/effect/abstract/proximity_checker created without a receiver")
|
||||
return INITIALIZE_HINT_QDEL
|
||||
return ..()
|
||||
|
||||
/obj/effect/abstract/proximity_checker/Destroy()
|
||||
hasprox_receiver = null
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Called when the `hasprox_receiver` receives the `COMSIG_PARENT_QDELETING` signal. When the receiver is deleted, so is this object.
|
||||
*
|
||||
* Arugments:
|
||||
* * source - this will be the `hasprox_receiver`
|
||||
* * force - the force flag taken from the qdel proc currently running on `hasprox_receiver`
|
||||
*/
|
||||
/obj/effect/abstract/proximity_checker/proc/OnParentDeletion(datum/source, force = FALSE)
|
||||
qdel(src)
|
||||
|
||||
/**
|
||||
* Something crossed over the proximity_checker. Notify the `hasprox_receiver` it has proximity with something. Only fires if the checker is `active`.
|
||||
*/
|
||||
/obj/effect/abstract/proximity_checker/Crossed(atom/movable/AM, oldloc)
|
||||
set waitfor = FALSE
|
||||
if(active)
|
||||
hasprox_receiver.HasProximity(AM)
|
||||
|
||||
/**
|
||||
* Moves the proximity_checker 1 tile in the `Dir` direction.
|
||||
*
|
||||
* If `Dir` is null it will be recentered around the receiver via the `recenter_prox_checkers()` proc.
|
||||
* If the new location of the receiver is NOT a turf, set `active` to FALSE, so that it does not receive proximity calls.
|
||||
* If the new location of the receiver IS a turf, set `active` to TRUE, so that it can receive proximity calls again.
|
||||
*
|
||||
* Arguments:
|
||||
* * source - this will be the `hasprox_receiver`
|
||||
* * OldLoc - the location the `hasprox_receiver` just moved from
|
||||
* * Dir - the direction the `hasprox_receiver` just moved in
|
||||
* * forced - if we were forced to move
|
||||
*/
|
||||
/obj/effect/abstract/proximity_checker/proc/HandleMove(datum/source, atom/OldLoc, Dir, forced)
|
||||
if(Dir)
|
||||
loc = get_step(src, Dir) // Basic movement 1 tile in some direction.
|
||||
return
|
||||
if(!isturf(hasprox_receiver.loc))
|
||||
active = FALSE // Receiver shouldn't detect proximity while picked up, in a backpack, closet, etc.
|
||||
else
|
||||
active = TRUE // Receiver can detect proximity again because it's on a turf.
|
||||
@@ -51,6 +51,6 @@
|
||||
Additionally calls the parent's `after_slip()` proc on the `victim`.
|
||||
*/
|
||||
/datum/component/slippery/proc/Slip(datum/source, mob/living/carbon/human/victim)
|
||||
if(istype(victim) && prob(slip_chance) && victim.slip(description, stun, weaken, slip_tiles, walking_is_safe, slip_always, slip_verb))
|
||||
if(istype(victim) && !victim.flying && prob(slip_chance) && victim.slip(description, stun, weaken, slip_tiles, walking_is_safe, slip_always, slip_verb))
|
||||
var/atom/movable/owner = parent
|
||||
owner.after_slip(victim)
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/datum/component/spooky
|
||||
var/too_spooky = TRUE //will it spawn a new instrument?
|
||||
|
||||
/datum/component/spooky/Initialize()
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/spectral_attack)
|
||||
|
||||
/datum/component/spooky/proc/spectral_attack(datum/source, mob/living/carbon/C, mob/user)
|
||||
if(ishuman(user)) //this weapon wasn't meant for mortals.
|
||||
var/mob/living/carbon/human/U = user
|
||||
if(!istype(U.dna.species, /datum/species/skeleton))
|
||||
U.adjustStaminaLoss(35) //Extra Damage
|
||||
U.Jitter(35)
|
||||
U.stuttering = 20
|
||||
if(U.getStaminaLoss() > 95)
|
||||
to_chat(U, "<font color='red' size='4'><b>Your ears weren't meant for this spectral sound.</b></font>")
|
||||
spectral_change(U)
|
||||
return
|
||||
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(istype(H.dna.species, /datum/species/skeleton))
|
||||
return //undeads are unaffected by the spook-pocalypse.
|
||||
C.Jitter(35)
|
||||
C.stuttering = 20
|
||||
if(!istype(H.dna.species, /datum/species/diona) && !istype(H.dna.species, /datum/species/machine) && !istype(H.dna.species, /datum/species/slime) && !istype(H.dna.species, /datum/species/golem) && !istype(H.dna.species, /datum/species/plasmaman))
|
||||
C.adjustStaminaLoss(25) //boneless humanoids don't lose the will to live
|
||||
to_chat(C, "<font color='red' size='4'><B>DOOT</B></font>")
|
||||
spectral_change(H)
|
||||
|
||||
else //the sound will spook monkeys.
|
||||
C.Jitter(15)
|
||||
C.stuttering = 20
|
||||
|
||||
/datum/component/spooky/proc/spectral_change(mob/living/carbon/human/H, mob/user)
|
||||
if((H.getStaminaLoss() > 95) && (!istype(H.dna.species, /datum/species/diona) && !istype(H.dna.species, /datum/species/machine) && !istype(H.dna.species, /datum/species/slime) && !istype(H.dna.species, /datum/species/golem) && !istype(H.dna.species, /datum/species/plasmaman) && !istype(H.dna.species, /datum/species/skeleton)))
|
||||
H.Stun(20)
|
||||
H.set_species(/datum/species/skeleton)
|
||||
H.visible_message("<span class='warning'>[H] has given up on life as a mortal.</span>")
|
||||
var/T = get_turf(H)
|
||||
if(too_spooky)
|
||||
if(prob(30))
|
||||
new/obj/item/instrument/saxophone/spectral(T)
|
||||
else if(prob(30))
|
||||
new/obj/item/instrument/trumpet/spectral(T)
|
||||
else if(prob(30))
|
||||
new/obj/item/instrument/trombone/spectral(T)
|
||||
else
|
||||
to_chat(H, "<span class='boldwarning'>The spooky gods forgot to ship your instrument. Better luck next unlife.</span>")
|
||||
to_chat(H, "<span class='boldnotice'>You are the spooky skeleton!</span>")
|
||||
to_chat(H, "<span class='boldnotice'>A new life and identity has begun. Help your fellow skeletons into bringing out the spooky-pocalypse. You haven't forgotten your past life, and are still beholden to past loyalties.</span>")
|
||||
change_name(H) //time for a new name!
|
||||
|
||||
/datum/component/spooky/proc/change_name(mob/living/carbon/human/H)
|
||||
var/t = stripped_input(H, "Enter your new skeleton name", H.real_name, null, MAX_NAME_LEN)
|
||||
if(!t)
|
||||
t = "spooky skeleton"
|
||||
H.real_name = t
|
||||
H.name = t
|
||||
@@ -67,6 +67,14 @@
|
||||
var/obj/item/projectile/P = AM
|
||||
if(P.original != parent)
|
||||
return
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(M.flying)
|
||||
return
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = M
|
||||
if(L.floating)
|
||||
return
|
||||
var/atom/current_parent = parent
|
||||
if(isturf(current_parent.loc))
|
||||
play_squeak()
|
||||
|
||||
@@ -278,8 +278,8 @@ GLOBAL_VAR_INIT(record_id_num, 1001)
|
||||
G.fields["sex"] = capitalize(H.gender)
|
||||
G.fields["species"] = H.dna.species.name
|
||||
G.fields["photo"] = get_id_photo(H)
|
||||
G.fields["photo-south"] = "'data:image/png;base64,[icon2base64(icon(G.fields["photo"], dir = SOUTH))]'"
|
||||
G.fields["photo-west"] = "'data:image/png;base64,[icon2base64(icon(G.fields["photo"], dir = WEST))]'"
|
||||
G.fields["photo-south"] = "data:image/png;base64,[icon2base64(icon(G.fields["photo"], dir = SOUTH))]"
|
||||
G.fields["photo-west"] = "data:image/png;base64,[icon2base64(icon(G.fields["photo"], dir = WEST))]"
|
||||
if(H.gen_record && !jobban_isbanned(H, "Records"))
|
||||
G.fields["notes"] = H.gen_record
|
||||
else
|
||||
@@ -319,7 +319,7 @@ GLOBAL_VAR_INIT(record_id_num, 1001)
|
||||
if(H.sec_record && !jobban_isbanned(H, "Records"))
|
||||
S.fields["notes"] = H.sec_record
|
||||
else
|
||||
S.fields["notes"] = "No notes."
|
||||
S.fields["notes"] = "No notes found."
|
||||
LAZYINITLIST(S.fields["comments"])
|
||||
security += S
|
||||
|
||||
@@ -518,8 +518,8 @@ GLOBAL_VAR_INIT(record_id_num, 1001)
|
||||
clothes_s = new /icon('icons/mob/uniform.dmi', "cargotech_s")
|
||||
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
|
||||
if("Shaft Miner")
|
||||
clothes_s = new /icon('icons/mob/uniform.dmi', "miner_s")
|
||||
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
|
||||
clothes_s = new /icon('icons/mob/uniform.dmi', "explorer_s")
|
||||
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "explorer"), ICON_UNDERLAY)
|
||||
if("Lawyer")
|
||||
clothes_s = new /icon('icons/mob/uniform.dmi', "internalaffairs_s")
|
||||
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY)
|
||||
|
||||
@@ -191,6 +191,10 @@
|
||||
..()
|
||||
desc = "That's Definitely Not [M.real_name]."
|
||||
|
||||
/datum/dog_fashion/head/cone
|
||||
name = "REAL_NAME"
|
||||
desc = "Omnicone's Chosen Champion"
|
||||
|
||||
/datum/dog_fashion/back/hardsuit
|
||||
name = "Space Explorer REAL_NAME"
|
||||
desc = "That's one small step for a corgi. One giant yap for corgikind."
|
||||
@@ -200,3 +204,7 @@
|
||||
D.mutations.Add(BREATHLESS)
|
||||
D.atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
D.minbodytemp = 0
|
||||
|
||||
/datum/dog_fashion/head/fried_vox_empty
|
||||
name = "Colonel REAL_NAME"
|
||||
desc = "Keep away from live vox."
|
||||
|
||||
@@ -152,13 +152,11 @@
|
||||
return doTeleport()
|
||||
return 0
|
||||
|
||||
/datum/teleport/instant //teleports when datum is created
|
||||
|
||||
start(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null)
|
||||
if(..())
|
||||
if(teleport())
|
||||
return 1
|
||||
return 0
|
||||
/datum/teleport/instant/start(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null)
|
||||
if(..())
|
||||
if(teleport())
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/datum/teleport/instant/science
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
var/raw_time // When did this happen?
|
||||
var/what // What happened
|
||||
var/who // Who did it
|
||||
var/target // Who/what was targeted (can be a string)
|
||||
var/turf/where // Where did it happen
|
||||
var/target // Who/what was targeted
|
||||
var/where // Where did it happen
|
||||
|
||||
/datum/log_record/New(_log_type, _who, _what, _target, _where, _raw_time)
|
||||
log_type = _log_type
|
||||
@@ -12,9 +12,13 @@
|
||||
who = get_subject_text(_who, _log_type)
|
||||
what = _what
|
||||
target = get_subject_text(_target, _log_type)
|
||||
if(!_where)
|
||||
if(!istext(_where) && !isturf(_where))
|
||||
_where = get_turf(_who)
|
||||
where = _where
|
||||
if(isturf(_where))
|
||||
var/turf/T = _where
|
||||
where = ADMIN_COORDJMP(T)
|
||||
else
|
||||
where = _where
|
||||
if(!_raw_time)
|
||||
_raw_time = world.time
|
||||
raw_time = _raw_time
|
||||
|
||||
@@ -4,6 +4,9 @@ if(!result || result.ckey != __ckey){\
|
||||
selected_ckeys_mobs[__ckey] = result;\
|
||||
}
|
||||
|
||||
#define RECORD_WARN_LIMIT 1000
|
||||
#define RECORD_HARD_LIMIT 2500
|
||||
|
||||
/datum/log_viewer
|
||||
var/time_from = 0
|
||||
var/time_to = 4 HOURS // 4 Hours should be enough. INFINITY would screw the UI up
|
||||
@@ -23,7 +26,7 @@ if(!result || result.ckey != __ckey){\
|
||||
log_records.Cut()
|
||||
return
|
||||
|
||||
/datum/log_viewer/proc/search()
|
||||
/datum/log_viewer/proc/search(user)
|
||||
log_records.Cut() // Empty the old results
|
||||
var/list/invalid_mobs = list()
|
||||
var/list/ckeys = selected_ckeys.Copy()
|
||||
@@ -47,8 +50,8 @@ if(!result || result.ckey != __ckey){\
|
||||
continue
|
||||
log_records.Add(logs.Copy(start_index, end_index + 1))
|
||||
|
||||
if(invalid_mobs.len)
|
||||
to_chat(usr, "<span class='warning'>The search criteria contained invalid mobs. They have been removed from the criteria.</span>")
|
||||
if(length(invalid_mobs))
|
||||
to_chat(user, "<span class='warning'>The search criteria contained invalid mobs. They have been removed from the criteria.</span>")
|
||||
for(var/i in invalid_mobs)
|
||||
selected_mobs -= i // Cleanup
|
||||
|
||||
@@ -103,13 +106,13 @@ if(!result || result.ckey != __ckey){\
|
||||
return 0
|
||||
|
||||
/datum/log_viewer/proc/add_mobs(list/mob/mobs)
|
||||
if(!mobs?.len)
|
||||
if(!length(mobs))
|
||||
return
|
||||
for(var/i in mobs)
|
||||
add_mob(usr, i, FALSE)
|
||||
|
||||
/datum/log_viewer/proc/add_ckey(mob/user, ckey)
|
||||
if(!user || !user)
|
||||
if(!user || !ckey)
|
||||
return
|
||||
selected_ckeys |= ckey
|
||||
UPDATE_CKEY_MOB(ckey)
|
||||
@@ -127,7 +130,7 @@ if(!result || result.ckey != __ckey){\
|
||||
var/all_log_types = ALL_LOGS
|
||||
var/trStyleTop = "border-top:2px solid; border-bottom:2px solid; padding-top: 5px; padding-bottom: 5px;"
|
||||
var/trStyle = "border-top:1px solid; border-bottom:1px solid; padding-top: 5px; padding-bottom: 5px;"
|
||||
var/dat
|
||||
var/list/dat = list()
|
||||
dat += "<head><meta http-equiv='X-UA-Compatible' content='IE=edge'><style>.adminticket{border:2px solid} td{border:1px solid grey;} th{border:1px solid grey;} span{float:left;width:150px;}</style></head>"
|
||||
dat += "<div style='min-height:100px'>"
|
||||
dat += "<span>Time Search Range:</span> <a href='?src=[UID()];start_time=1'>[gameTimestamp(wtime = time_from)]</a>"
|
||||
@@ -184,13 +187,12 @@ if(!result || result.ckey != __ckey){\
|
||||
|
||||
dat +="<tr style='[trStyle]'><td style='[tdStyleTime]'>[time]</td><td style='[tdStyleType]background: [get_logtype_color(L.log_type)]'>[L.log_type]</td>\
|
||||
<td style='[tdStyleWho]'>[L.who]</td><td style='background: [get_logtype_color(L.log_type)];'>[L.what]</td>\
|
||||
<td style='[tdStyleWho]'>[L.target]</td><td style='[tdStyleWhere]'>[ADMIN_COORDJMP(L.where)]</td></tr>"
|
||||
|
||||
<td style='[tdStyleWho]'>[L.target]</td><td style='[tdStyleWhere]'>[L.where]</td></tr>"
|
||||
dat += "</table>"
|
||||
dat += "</div>"
|
||||
|
||||
var/datum/browser/popup = new(user, "Log Viewer", "Log Viewer", 1500, 600)
|
||||
popup.set_content(dat)
|
||||
popup.set_content(dat.Join())
|
||||
popup.open()
|
||||
|
||||
/datum/log_viewer/Topic(href, href_list)
|
||||
@@ -219,6 +221,19 @@ if(!result || result.ckey != __ckey){\
|
||||
return
|
||||
if(href_list["search"])
|
||||
search(usr)
|
||||
var/records_len = length(log_records)
|
||||
if(records_len > RECORD_WARN_LIMIT)
|
||||
var/datum/log_record/last_record = log_records[RECORD_WARN_LIMIT]
|
||||
var/last_time = gameTimestamp(wtime = last_record.raw_time - 9.99)
|
||||
var/answer = alert(usr, "More than [RECORD_WARN_LIMIT] records were found. continuing will take a long time. This won't cause much lag for the server. Time at the [RECORD_WARN_LIMIT]th record '[last_time]'", "Warning", "Continue", "Limit to [RECORD_WARN_LIMIT]", "Cancel")
|
||||
if(answer == "Limit to [RECORD_WARN_LIMIT]")
|
||||
log_records.Cut(RECORD_WARN_LIMIT)
|
||||
else if(answer == "Cancel")
|
||||
log_records.Cut()
|
||||
else
|
||||
if(records_len > RECORD_HARD_LIMIT)
|
||||
to_chat(usr, "<span class='warning'>Record limit reached. Limiting to [RECORD_HARD_LIMIT].</span>")
|
||||
log_records.Cut(RECORD_HARD_LIMIT)
|
||||
show_ui(usr)
|
||||
return
|
||||
if(href_list["clear_all"])
|
||||
@@ -300,3 +315,5 @@ if(!result || result.ckey != __ckey){\
|
||||
return get_display_name(M)
|
||||
|
||||
#undef UPDATE_CKEY_MOB
|
||||
#undef RECORD_WARN_LIMIT
|
||||
#undef RECORD_HARD_LIMIT
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
var/list/atoms_cache = output_atoms
|
||||
var/sound/S = sound(soundfile)
|
||||
if(direct)
|
||||
S.channel = open_sound_channel()
|
||||
S.channel = SSsounds.random_available_channel()
|
||||
S.volume = volume
|
||||
for(var/i in 1 to atoms_cache.len)
|
||||
var/atom/thing = atoms_cache[i]
|
||||
|
||||
+11
-4
@@ -35,6 +35,7 @@
|
||||
var/list/restricted_roles = list()
|
||||
|
||||
var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button.
|
||||
var/datum/martial_art/martial_art
|
||||
|
||||
var/role_alt_title
|
||||
|
||||
@@ -101,6 +102,7 @@
|
||||
leave_all_huds() //leave all the huds in the old body, so it won't get huds if somebody else enters it
|
||||
|
||||
SSnanoui.user_transferred(current, new_character)
|
||||
SStgui.on_transfer(current, new_character)
|
||||
|
||||
if(new_character.mind) //remove any mind currently in our new body's mind variable
|
||||
new_character.mind.current = null
|
||||
@@ -111,6 +113,11 @@
|
||||
A.on_body_transfer(old_current, current)
|
||||
transfer_antag_huds(hud_to_transfer) //inherit the antag HUD
|
||||
transfer_actions(new_character)
|
||||
if(martial_art)
|
||||
if(martial_art.temporary)
|
||||
martial_art.remove(current)
|
||||
else
|
||||
martial_art.teach(current)
|
||||
|
||||
if(active)
|
||||
new_character.key = key //now transfer the key to link the client to our new body
|
||||
@@ -914,7 +921,7 @@
|
||||
log_admin("[key_name(usr)] has equipped [key_name(current)] as a wizard")
|
||||
message_admins("[key_name_admin(usr)] has equipped [key_name_admin(current)] as a wizard")
|
||||
if("name")
|
||||
SSticker.mode.name_wizard(current)
|
||||
INVOKE_ASYNC(SSticker.mode, /datum/game_mode/wizard.proc/name_wizard, current)
|
||||
log_admin("[key_name(usr)] has allowed wizard [key_name(current)] to name themselves")
|
||||
message_admins("[key_name_admin(usr)] has allowed wizard [key_name_admin(current)] to name themselves")
|
||||
if("autoobjectives")
|
||||
@@ -1102,8 +1109,8 @@
|
||||
special_role = null
|
||||
to_chat(current,"<span class='userdanger'>Your infernal link has been severed! You are no longer a devil!</span>")
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/infernal_jaunt)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/fireball/hellish)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/summon_contract)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/click/fireball/hellish)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/click/summon_contract)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork/greater)
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork/ascended)
|
||||
@@ -1501,7 +1508,7 @@
|
||||
SSticker.mode.equip_wizard(current)
|
||||
for(var/obj/item/spellbook/S in current.contents)
|
||||
S.op = 0
|
||||
SSticker.mode.name_wizard(current)
|
||||
INVOKE_ASYNC(SSticker.mode, /datum/game_mode/wizard.proc/name_wizard, current)
|
||||
SSticker.mode.forge_wizard_objectives(src)
|
||||
SSticker.mode.greet_wizard(src)
|
||||
SSticker.mode.update_wiz_icons_added(src)
|
||||
|
||||
@@ -222,10 +222,10 @@
|
||||
name = "NT Undercover Operative"
|
||||
// Disguised NT special forces, sent to quietly eliminate or keep tabs on people in high positions (e.g: captain)
|
||||
|
||||
uniform = /obj/item/clothing/under/color/black
|
||||
uniform = /obj/item/clothing/under/color/random
|
||||
back = /obj/item/storage/backpack
|
||||
belt = /obj/item/storage/belt/utility/full/multitool
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
gloves = /obj/item/clothing/gloves/color/yellow
|
||||
shoes = /obj/item/clothing/shoes/chameleon/noslip
|
||||
l_ear = /obj/item/radio/headset/centcom
|
||||
id = /obj/item/card/id
|
||||
@@ -242,7 +242,7 @@
|
||||
/obj/item/organ/internal/cyberimp/eyes/shield,
|
||||
/obj/item/organ/internal/cyberimp/eyes/hud/security,
|
||||
/obj/item/organ/internal/cyberimp/eyes/xray,
|
||||
/obj/item/organ/internal/cyberimp/brain/anti_stun,
|
||||
/obj/item/organ/internal/cyberimp/brain/anti_stun/hardened,
|
||||
/obj/item/organ/internal/cyberimp/chest/nutriment/plus,
|
||||
/obj/item/organ/internal/cyberimp/arm/combat/centcom
|
||||
)
|
||||
|
||||
@@ -351,16 +351,6 @@ GLOBAL_LIST_EMPTY(rpd_pipe_list) //Some pipes we don't want to be dispensable
|
||||
pipe_id = PIPE_CIRCULATOR
|
||||
pipe_icon = "circ"
|
||||
|
||||
/datum/pipes/atmospheric/omni_filter
|
||||
pipe_name = "omni filter"
|
||||
pipe_id = PIPE_OMNI_FILTER
|
||||
pipe_icon = "omni_filter"
|
||||
|
||||
/datum/pipes/atmospheric/omni_mixer
|
||||
pipe_name = "omni mixer"
|
||||
pipe_id = PIPE_OMNI_MIXER
|
||||
pipe_icon = "omni_mixer"
|
||||
|
||||
/datum/pipes/atmospheric/insulated
|
||||
pipe_name = "insulated pipe"
|
||||
pipe_id = PIPE_INSULATED_STRAIGHT
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user