Merge remote-tracking branch 'ParadiseSS13/master' into pr/SteelSlayer/14333

This commit is contained in:
AffectedArc07
2020-09-16 22:12:32 +01:00
27 changed files with 442 additions and 269 deletions
+108
View File
@@ -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
+32
View File
@@ -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 }}
+7 -42
View File
@@ -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;
@@ -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
+13
View File
@@ -450,6 +450,7 @@
/datum/action/spell_action
check_flags = 0
background_icon_state = "bg_spell"
var/recharge_text_color = "#FFFFFF"
/datum/action/spell_action/New(Target)
..()
@@ -487,6 +488,18 @@
return spell.can_cast(owner)
return 0
/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
+15 -2
View File
@@ -230,12 +230,12 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
/obj/effect/proc_holder/spell/process()
charge_counter += 2
if(action)
action.UpdateButtonIcon()
if(charge_counter < charge_max)
return
STOP_PROCESSING(SSfastprocess, src)
charge_counter = charge_max
if(action)
action.UpdateButtonIcon()
/obj/effect/proc_holder/spell/proc/perform(list/targets, recharge = 1, mob/user = usr, make_attack_logs = TRUE) //if recharge is started is important for the trigger spells
before_cast(targets)
@@ -339,6 +339,19 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
target.vars[type] += amount //I bear no responsibility for the runtimes that'll happen if you try to adjust non-numeric or even non-existant vars
return
/obj/effect/proc_holder/spell/proc/get_availability_percentage()
switch(charge_type)
if("recharge")
if(charge_counter == 0)
return 0
return charge_counter / charge_max
if("charges")
if(charge_counter)
return 1
return 0
if("holdervar")
return 1
/obj/effect/proc_holder/spell/targeted //can mean aoe for mobs (limited/unlimited number) or one target mob
var/max_targets = 1 //leave 0 for unlimited targets in range, 1 for one selectable target in range, more for limited number of casts (can all target one guy, depends on target_ignore_prev) in range
var/target_ignore_prev = 1 //only important if max_targets > 1, affects if the spell can be cast multiple times at one person from one cast
+2 -2
View File
@@ -412,9 +412,9 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/jobspecific/energizedfireaxe
name = "Energized Fire Axe"
desc = "A fire axe with a massive electrical charge built into it. It can release this charge on its first victim and will be rather plain after that."
desc = "A fire axe with a massive energy charge built into it. Upon striking someone while charged it will throw them backwards while stunning them briefly, but will take some time to charge up again. It is also much sharper than a regular axe and can pierce light armor."
reference = "EFA"
item = /obj/item/twohanded/energizedfireaxe
item = /obj/item/twohanded/fireaxe/energized
cost = 10
job = list("Life Support Specialist")
@@ -285,7 +285,7 @@
/obj/item/clothing/gloves/color/yellow/power = 1,
/obj/item/twohanded/chainsaw = 1,
/obj/item/bee_briefcase = 1,
/obj/item/twohanded/energizedfireaxe = 1,
/obj/item/twohanded/fireaxe/energized = 1,
/obj/item/clothing/glasses/thermal = 1,
/obj/item/chameleon = 1,
/obj/item/reagent_containers/hypospray/autoinjector/stimulants = 1,
+48 -35
View File
@@ -37,70 +37,83 @@
overlays.Cut()
/obj/item/aicard/attack_self(mob/user)
ui_interact(user)
tgui_interact(user)
/obj/item/aicard/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = GLOB.inventory_state)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
/obj/item/aicard/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_inventory_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "aicard.tmpl", "[name]", 600, 400, state = state)
ui = new(user, src, ui_key, "AICard", "[name]", 600, 394, master_ui, state)
ui.open()
ui.set_auto_update(1)
/obj/item/aicard/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.inventory_state)
/obj/item/aicard/tgui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.inventory_state)
var/data[0]
var/mob/living/silicon/ai/AI = locate() in src
if(istype(AI))
data["has_ai"] = 1
data["has_ai"] = TRUE
data["name"] = AI.name
data["hardware_integrity"] = ((AI.health + 100) / 2)
data["integrity"] = ((AI.health + 100) / 2)
data["radio"] = !AI.aiRadio.disabledAi
data["wireless"] = !AI.control_disabled
data["operational"] = AI.stat != DEAD
data["flushing"] = flush
var/laws[0]
for(var/datum/ai_law/AL in AI.laws.all_laws())
laws[++laws.len] = list("index" = AL.get_index(), "law" = sanitize(AL.law))
for(var/datum/ai_law/law in AI.laws.all_laws())
if(law in AI.laws.ion_laws) // If we're an ion law, give it an ion index code
laws.Add(ionnum() + ". " + law.law)
else
laws.Add(num2text(law.get_index()) + ". " + law.law)
data["laws"] = laws
data["has_laws"] = laws.len
data["has_laws"] = length(AI.laws.all_laws())
else
data["has_ai"] = FALSE // If this isn't passed to tgui, it won't show there isn't a AI in the card.
return data
/obj/item/aicard/Topic(href, href_list, nowindow, state)
/obj/item/aicard/tgui_act(action, params)
if(..())
return 1
return
var/mob/living/silicon/ai/AI = locate() in src
if(!istype(AI))
return 1
return
var/user = usr
switch(action)
if("wipe")
if(flush) // Don't doublewipe.
to_chat(user, "<span class='warning'>You are already wiping this AI!</span>")
return
var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No")
if(confirm == "Yes" && (tgui_status(user, GLOB.tgui_inventory_state) == STATUS_INTERACTIVE)) // And make doubly sure they want to wipe (three total clicks)
msg_admin_attack("[key_name_admin(user)] wiped [key_name_admin(AI)] with \the [src].", ATKLOG_FEW)
add_attack_logs(user, AI, "Wiped with [src].")
INVOKE_ASYNC(src, .proc/wipe_ai)
if(href_list["wipe"])
var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No")
if(confirm == "Yes" && (CanUseTopic(user, state) == STATUS_INTERACTIVE))
add_attack_logs(user, AI, "Wiped with [src].", ATKLOG_FEW)
flush = 1
AI.suiciding = 1
to_chat(AI, "Your core files are being wiped!")
while(AI && AI.stat != DEAD)
AI.adjustOxyLoss(2)
sleep(10)
flush = 0
if("radio")
AI.aiRadio.disabledAi = !AI.aiRadio.disabledAi
to_chat(AI, "<span class='warning'>Your Subspace Transceiver has been [AI.aiRadio.disabledAi ? "disabled" : "enabled"]!</span>")
to_chat(user, "<span class='notice'>You [AI.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.</span>")
if(href_list["radio"])
AI.aiRadio.disabledAi = text2num(href_list["radio"])
to_chat(AI, "<span class='warning'>Your Subspace Transceiver has been [AI.aiRadio.disabledAi ? "disabled" : "enabled"]!</span>")
to_chat(user, "<span class='notice'>You [AI.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.</span>")
if("wireless")
AI.control_disabled = !AI.control_disabled
to_chat(AI, "<span class='warning'>Your wireless interface has been [AI.control_disabled ? "disabled" : "enabled"]!</span>")
to_chat(user, "<span class='notice'>You [AI.control_disabled ? "disable" : "enable"] the AI's wireless interface.</span>")
update_icon()
if(href_list["wireless"])
AI.control_disabled = text2num(href_list["wireless"])
to_chat(AI, "<span class='warning'>Your wireless interface has been [AI.control_disabled ? "disabled" : "enabled"]!</span>")
to_chat(user, "<span class='notice'>You [AI.control_disabled ? "disable" : "enable"] the AI's wireless interface.</span>")
update_icon()
return TRUE
return 1
/obj/item/aicard/proc/wipe_ai()
var/mob/living/silicon/ai/AI = locate() in src
flush = TRUE
AI.suiciding = TRUE
to_chat(AI, "Your core files are being wiped!")
while(AI && AI.stat != DEAD)
AI.adjustOxyLoss(2)
sleep(10)
flush = FALSE
@@ -1053,7 +1053,7 @@
/obj/item/storage/box/responseteam/New()
..()
new /obj/item/clothing/mask/breath(src)
new /obj/item/tank/emergency_oxygen/engi(src)
new /obj/item/tank/emergency_oxygen/engi/full(src)
new /obj/item/flashlight/flare(src)
new /obj/item/kitchen/knife/combat(src)
new /obj/item/radio/centcom(src)
@@ -167,6 +167,11 @@
icon_state = "emergency_engi"
volume = 6
/obj/item/tank/emergency_oxygen/engi/full/New()
..()
air_contents.oxygen = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
/obj/item/tank/emergency_oxygen/engi/empty/New()
..()
air_contents.oxygen = null
+36 -51
View File
@@ -209,6 +209,42 @@
/obj/item/twohanded/fireaxe/boneaxe/update_icon()
icon_state = "bone_axe[wielded]"
/obj/item/twohanded/fireaxe/energized
desc = "Someone with a love for fire axes decided to turn this one into a high-powered energy weapon. Seems excessive."
force_wielded = 30
armour_penetration = 20
var/charge = 30
var/max_charge = 30
/obj/item/twohanded/fireaxe/energized/update_icon()
if(wielded)
icon_state = "fireaxe2"
else
icon_state = "fireaxe0"
/obj/item/twohanded/fireaxe/energized/New()
..()
START_PROCESSING(SSobj, src)
/obj/item/twohanded/fireaxe/energized/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/twohanded/fireaxe/energized/process()
charge = min(charge + 1, max_charge)
/obj/item/twohanded/fireaxe/energized/attack(mob/M, mob/user)
. = ..()
if(wielded && charge == max_charge)
if(isliving(M))
charge = 0
playsound(loc, 'sound/magic/lightningbolt.ogg', 5, 1)
user.visible_message("<span class='danger'>[user] slams the charged axe into [M.name] with all [user.p_their()] might!</span>")
do_sparks(1, 1, src)
M.Weaken(4)
var/atom/throw_target = get_edge_target_turf(M, get_dir(src, get_step_away(M, src)))
M.throw_at(throw_target, 5, 1)
/*
* Double-Bladed Energy Swords - Cheridan
*/
@@ -755,57 +791,6 @@
charged = 3
playsound(user, 'sound/weapons/marauder.ogg', 50, 1)
// Energized Fire axe
/obj/item/twohanded/energizedfireaxe
name = "energized fire axe"
desc = "Someone with a love for fire axes decided to turn one into a single-charge energy weapon. Seems excessive."
icon_state = "fireaxe0"
force = 5
throwforce = 15
sharp = TRUE
w_class = WEIGHT_CLASS_HUGE
armour_penetration = 20
slot_flags = SLOT_BACK
force_unwielded = 5
force_wielded = 30
attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30)
var/charged = 1
/obj/item/twohanded/energizedfireaxe/update_icon()
if(wielded)
icon_state = "fireaxe2"
else
icon_state = "fireaxe0"
..()
/obj/item/twohanded/energizedfireaxe/afterattack(atom/A, mob/user, proximity)
if(!proximity)
return
if(wielded)
if(isliving(A))
var/mob/living/Z = A
if(charged)
charged--
Z.take_organ_damage(0, 30)
user.visible_message("<span class='danger'>[user] slams the charged axe into [Z.name] with all [user.p_their()] might!</span>")
playsound(loc, 'sound/magic/lightningbolt.ogg', 5, 1)
do_sparks(1, 1, src)
if(A && wielded && (istype(A, /obj/structure/window) || istype(A, /obj/structure/grille)))
if(istype(A, /obj/structure/window))
var/obj/structure/window/W = A
W.deconstruct(FALSE)
if(prob(4))
charged++
user.visible_message("<span class='notice'>The axe starts to emit an electric buzz!</span>")
else
qdel(A)
if(prob(4))
charged++
user.visible_message("<span class='notice'>The axe starts to emit an electric buzz!</span>")
/obj/item/twohanded/pitchfork
icon_state = "pitchfork0"
name = "pitchfork"
+2
View File
@@ -51,6 +51,8 @@
take_damage(AM.throwforce, BRUTE, "melee", 1, get_dir(src, AM))
/obj/ex_act(severity)
if(QDELETED(src))
return
if(resistance_flags & INDESTRUCTIBLE)
return
switch(severity)
+16 -5
View File
@@ -16,15 +16,26 @@
"Vox" = 'icons/mob/species/vox/helmet.dmi'
)
/obj/item/clothing/head/helmet/space/hardsuit/ert/Initialize()
var/mob/living/carbon/human/wearer = loc.loc //loc is the hardsuit, so its loc is the wearer
if(ishuman(wearer))
register_camera(wearer)
..()
/obj/item/clothing/head/helmet/space/hardsuit/ert/attack_self(mob/user)
if(camera || !has_camera)
..(user)
else
camera = new /obj/machinery/camera(src)
camera.network = list("ERT")
GLOB.cameranet.removeCamera(camera)
camera.c_tag = user.name
to_chat(user, "<span class='notice'>User scanned as [camera.c_tag]. Camera activated.</span>")
register_camera(user)
/obj/item/clothing/head/helmet/space/hardsuit/ert/proc/register_camera(mob/wearer)
if(camera || !has_camera)
return
camera = new /obj/machinery/camera(src)
camera.network = list("ERT")
GLOB.cameranet.removeCamera(camera)
camera.c_tag = wearer.name
to_chat(wearer, "<span class='notice'>User scanned as [camera.c_tag]. Camera activated.</span>")
/obj/item/clothing/head/helmet/space/hardsuit/ert/examine(mob/user)
. = ..()
+4
View File
@@ -128,6 +128,10 @@
item_state = "p_suit"
item_color = "purple"
/obj/item/clothing/under/color/purple/sensor //for jani ert
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
/obj/item/clothing/under/color/lightpurple
name = "light purple jumpsuit"
icon_state = "lightpurple"
@@ -48,6 +48,10 @@
item_state = "bl_suit"
item_color = "chapblack"
/obj/item/clothing/under/rank/chaplain/sensor
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
/obj/item/clothing/under/rank/chef
desc = "It's an apron which is given only to the most <b>hardcore</b> chefs in space."
name = "chef's uniform"
@@ -39,6 +39,10 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 60, "acid" = 20)
resistance_flags = NONE
/obj/item/clothing/under/rank/engineer/sensor
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
/obj/item/clothing/under/rank/engineer/skirt
desc = "It's an orange high visibility jumpskirt worn by engineers. It has minor radiation shielding."
@@ -124,6 +124,10 @@
permeability_coefficient = 0.50
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
/obj/item/clothing/under/rank/medical/sensor
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
/obj/item/clothing/under/rank/medical/skirt
name = "medical doctor's jumpskirt"
icon_state = "medicalf"
@@ -34,6 +34,10 @@
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30)
strip_delay = 50
/obj/item/clothing/under/rank/security/sensor
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
/obj/item/clothing/under/rank/security/skirt
name = "security officer's jumpskirt"
desc = "Standard feminine fashion for Security Officers. It's made of sturdier material than the standard jumpskirts."
@@ -88,6 +88,10 @@
item_state = "g_suit"
item_color = "officer"
/obj/item/clothing/under/rank/centcom_officer/sensor
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
/obj/item/clothing/under/rank/centcom_commander
desc = "It's a jumpsuit worn by CentComm's highest-tier Commanders."
name = "\improper CentComm officer's jumpsuit"
+23 -23
View File
@@ -36,7 +36,7 @@
rt_job = "Emergency Response Team Leader"
rt_mob_job = "ERT Commander"
uniform = /obj/item/clothing/under/rank/centcom_officer
uniform = /obj/item/clothing/under/rank/centcom_officer/sensor
back = /obj/item/storage/backpack/ert/commander
id = /obj/item/card/id/ert/commander
@@ -56,12 +56,12 @@
gloves = /obj/item/clothing/gloves/color/black
suit = /obj/item/clothing/suit/armor/vest/ert/command
glasses = /obj/item/clothing/glasses/sunglasses
mask = /obj/item/clothing/mask/gas/sechailer
belt = /obj/item/gun/energy/gun
backpack_contents = list(
/obj/item/clothing/head/helmet/ert/command = 1,
/obj/item/clothing/mask/gas/sechailer = 1,
/obj/item/restraints/handcuffs = 1,
/obj/item/storage/lockbox/mindshield = 1,
/obj/item/flashlight = 1
@@ -73,6 +73,7 @@
gloves = /obj/item/clothing/gloves/combat
suit = /obj/item/clothing/suit/space/hardsuit/ert/commander
glasses = /obj/item/clothing/glasses/sunglasses
mask = /obj/item/clothing/mask/gas/sechailer/swat
cybernetic_implants = list(
/obj/item/organ/internal/cyberimp/eyes/hud/security,
/obj/item/organ/internal/cyberimp/chest/nutriment
@@ -80,7 +81,6 @@
belt = /obj/item/gun/energy/gun/blueshield/pdw9
backpack_contents = list(
/obj/item/clothing/mask/gas/sechailer/swat = 1,
/obj/item/gun/energy/ionrifle/carbine = 1,
/obj/item/restraints/handcuffs = 1,
/obj/item/clothing/shoes/magboots = 1,
@@ -93,11 +93,11 @@
gloves = /obj/item/clothing/gloves/combat
suit = /obj/item/clothing/suit/space/hardsuit/ert/commander/gamma
glasses = /obj/item/clothing/glasses/night
mask = /obj/item/clothing/mask/gas/sechailer/swat
suit_store = /obj/item/gun/energy/gun/blueshield/pdw9
belt = /obj/item/gun/projectile/automatic/pistol/enforcer/lethal
backpack_contents = list(
/obj/item/clothing/mask/gas/sechailer/swat = 1,
/obj/item/restraints/handcuffs = 1,
/obj/item/storage/lockbox/mindshield = 1,
/obj/item/gun/energy/ionrifle/carbine = 1,
@@ -107,7 +107,7 @@
cybernetic_implants = list(
/obj/item/organ/internal/cyberimp/chest/nutriment/plus,
/obj/item/organ/internal/cyberimp/eyes/hud/security,
/obj/item/organ/internal/cyberimp/brain/anti_stun,
/obj/item/organ/internal/cyberimp/brain/anti_stun/hardened,
/obj/item/organ/internal/cyberimp/arm/flash
)
@@ -117,7 +117,7 @@
name = "RT Security"
rt_job = "Emergency Response Team Officer"
rt_mob_job = "ERT Security"
uniform = /obj/item/clothing/under/rank/security
uniform = /obj/item/clothing/under/rank/security/sensor
back = /obj/item/storage/backpack/ert/security
belt = /obj/item/storage/belt/security/response_team
pda = /obj/item/pda/heads/ert/security
@@ -130,12 +130,12 @@
suit = /obj/item/clothing/suit/armor/vest/ert/security
suit_store = /obj/item/gun/energy/gun/advtaser
glasses = /obj/item/clothing/glasses/hud/security/sunglasses
mask = /obj/item/clothing/mask/gas/sechailer
r_hand = /obj/item/gun/energy/laser
backpack_contents = list(
/obj/item/clothing/head/helmet/ert/security = 1,
/obj/item/clothing/mask/gas/sechailer = 1,
/obj/item/storage/box/zipties = 1,
/obj/item/storage/box/teargas = 1,
/obj/item/flashlight/seclite = 1
@@ -149,6 +149,7 @@
suit = /obj/item/clothing/suit/space/hardsuit/ert/security
suit_store = /obj/item/gun/energy/gun/blueshield/pdw9
glasses = /obj/item/clothing/glasses/sunglasses
mask = /obj/item/clothing/mask/gas/sechailer
r_hand = /obj/item/gun/projectile/automatic/lasercarbine
@@ -159,11 +160,9 @@
)
backpack_contents = list(
/obj/item/clothing/mask/gas/sechailer = 1,
/obj/item/clothing/shoes/magboots = 1,
/obj/item/storage/box/handcuffs = 1,
/obj/item/storage/box/teargas = 1,
/obj/item/grenade/flashbang = 1,
/obj/item/grenade/flashbang = 2,
/obj/item/ammo_box/magazine/laser = 2
)
@@ -175,13 +174,13 @@
belt = /obj/item/storage/belt/security/response_team_gamma
suit_store = /obj/item/gun/energy/gun/nuclear
glasses = /obj/item/clothing/glasses/night
mask = /obj/item/clothing/mask/gas/sechailer/swat
l_pocket = /obj/item/restraints/legcuffs/bola/energy
r_pocket = /obj/item/extinguisher/mini
r_hand = /obj/item/gun/energy/immolator/multi
backpack_contents = list(
/obj/item/clothing/mask/gas/sechailer/swat = 1,
/obj/item/storage/box/handcuffs = 1,
/obj/item/storage/box/flashbangs = 1,
/obj/item/whetstone = 1,
@@ -191,9 +190,9 @@
cybernetic_implants = list(
/obj/item/organ/internal/cyberimp/chest/nutriment/plus,
/obj/item/organ/internal/cyberimp/eyes/hud/security,
/obj/item/organ/internal/cyberimp/brain/anti_stun,
/obj/item/organ/internal/cyberimp/brain/anti_stun/hardened,
/obj/item/organ/internal/cyberimp/arm/telebaton,
/obj/item/organ/internal/cyberimp/chest/reviver
/obj/item/organ/internal/cyberimp/chest/reviver/hardened
)
@@ -217,12 +216,12 @@
suit = /obj/item/clothing/suit/space/hardsuit/ert/engineer
suit_store = /obj/item/tank/emergency_oxygen/engi
glasses = /obj/item/clothing/glasses/meson
mask = /obj/item/clothing/mask/gas
l_pocket = /obj/item/gun/energy/gun/mini
r_pocket = /obj/item/melee/classic_baton/telescopic
backpack_contents = list(
/obj/item/clothing/mask/gas = 1,
/obj/item/t_scanner = 1,
/obj/item/stack/sheet/glass/fifty = 1,
/obj/item/stack/sheet/metal/fifty = 1,
@@ -237,6 +236,7 @@
suit = /obj/item/clothing/suit/space/hardsuit/ert/engineer/gamma
suit_store = /obj/item/tank/emergency_oxygen/engi
glasses = /obj/item/clothing/glasses/meson
mask = /obj/item/clothing/mask/gas
cybernetic_implants = list(
/obj/item/organ/internal/cyberimp/eyes/shield,
/obj/item/organ/internal/cyberimp/chest/nutriment
@@ -245,7 +245,6 @@
r_pocket = /obj/item/melee/classic_baton/telescopic
backpack_contents = list(
/obj/item/clothing/mask/gas = 1,
/obj/item/rcd/preloaded = 1,
/obj/item/rcd_ammo = 3,
/obj/item/gun/energy/gun = 1
@@ -259,12 +258,12 @@
suit = /obj/item/clothing/suit/space/hardsuit/ert/engineer/gamma
suit_store = /obj/item/gun/energy/gun/blueshield/pdw9
glasses = /obj/item/clothing/glasses/meson/night
mask = /obj/item/clothing/mask/gas/sechailer/swat
l_pocket = /obj/item/t_scanner/extended_range
r_pocket = /obj/item/melee/classic_baton/telescopic
backpack_contents = list(
/obj/item/clothing/mask/gas/sechailer/swat = 1,
/obj/item/rcd/combat = 1,
/obj/item/rcd_ammo/large = 3
)
@@ -272,7 +271,7 @@
cybernetic_implants = list(
/obj/item/organ/internal/cyberimp/chest/nutriment/plus,
/obj/item/organ/internal/cyberimp/eyes/hud/security,
/obj/item/organ/internal/cyberimp/brain/anti_stun,
/obj/item/organ/internal/cyberimp/brain/anti_stun/hardened,
/obj/item/organ/internal/cyberimp/eyes/shield,
/obj/item/organ/internal/cyberimp/arm/toolset
)
@@ -353,6 +352,7 @@
gloves = /obj/item/clothing/gloves/combat
suit = /obj/item/clothing/suit/space/hardsuit/ert/medical/gamma
glasses = /obj/item/clothing/glasses/night
mask = /obj/item/clothing/mask/gas/sechailer/swat
suit_store = /obj/item/gun/energy/gun/blueshield/pdw9
belt = /obj/item/defibrillator/compact/loaded
@@ -361,7 +361,6 @@
r_pocket = /obj/item/reagent_containers/hypospray/autoinjector
backpack_contents = list(
/obj/item/clothing/mask/gas/sechailer/swat = 1,
/obj/item/bodyanalyzer/advanced = 1,
/obj/item/extinguisher/mini = 1,
/obj/item/roller = 1,
@@ -375,7 +374,7 @@
/obj/item/organ/internal/cyberimp/arm/medibeam,
/obj/item/organ/internal/cyberimp/chest/nutriment/plus,
/obj/item/organ/internal/cyberimp/eyes/hud/medical,
/obj/item/organ/internal/cyberimp/brain/anti_stun
/obj/item/organ/internal/cyberimp/brain/anti_stun/hardened
)
//////////////////// PARANORMAL ///////////////////
@@ -390,11 +389,11 @@
shoes = /obj/item/clothing/shoes/combat
l_ear = /obj/item/radio/headset/ert/alt
glasses = /obj/item/clothing/glasses/hud/security/sunglasses
mask = /obj/item/clothing/mask/gas/sechailer/swat
belt = /obj/item/storage/belt/security/response_team
id = /obj/item/card/id/centcom
pda = /obj/item/pda/centcom
backpack_contents = list(
/obj/item/clothing/mask/gas/sechailer/swat = 1,
/obj/item/storage/box/zipties = 1,
/obj/item/flashlight/seclite = 1
)
@@ -435,7 +434,7 @@
cybernetic_implants = list(
/obj/item/organ/internal/cyberimp/chest/nutriment/plus,
/obj/item/organ/internal/cyberimp/eyes/hud/security,
/obj/item/organ/internal/cyberimp/brain/anti_stun
/obj/item/organ/internal/cyberimp/brain/anti_stun/hardened
)
//////////////////// JANITORIAL ///////////////////
@@ -444,7 +443,7 @@
name = "RT Janitor"
rt_job = "Emergency Response Team Janitor"
rt_mob_job = "ERT Janitor"
uniform = /obj/item/clothing/under/color/purple
uniform = /obj/item/clothing/under/color/purple/sensor
back = /obj/item/storage/backpack/ert/janitor
belt = /obj/item/storage/belt/janitor/full
gloves = /obj/item/clothing/gloves/color/yellow
@@ -500,5 +499,6 @@
)
cybernetic_implants = list(
/obj/item/organ/internal/cyberimp/arm/advmop
/obj/item/organ/internal/cyberimp/arm/advmop,
/obj/item/organ/internal/cyberimp/brain/anti_stun/hardened
)
@@ -1,5 +1,3 @@
#define STUN_SET_AMOUNT 2
/obj/item/organ/internal/cyberimp
name = "cybernetic implant"
desc = "a state-of-the-art implant that improves a baseline's functionality"
@@ -128,15 +126,16 @@
implant_color = "#FFFF00"
slot = "brain_antistun"
origin_tech = "materials=5;programming=4;biotech=5"
var/stun_max_amount = 2
/obj/item/organ/internal/cyberimp/brain/anti_stun/on_life()
..()
if(crit_fail)
return
if(owner.stunned > STUN_SET_AMOUNT)
owner.SetStunned(STUN_SET_AMOUNT)
if(owner.weakened > STUN_SET_AMOUNT)
owner.SetWeakened(STUN_SET_AMOUNT)
if(owner.stunned > stun_max_amount)
owner.SetStunned(stun_max_amount)
if(owner.weakened > stun_max_amount)
owner.SetWeakened(stun_max_amount)
/obj/item/organ/internal/cyberimp/brain/anti_stun/emp_act(severity)
if(crit_fail || emp_proof)
@@ -147,6 +146,12 @@
/obj/item/organ/internal/cyberimp/brain/anti_stun/proc/reboot()
crit_fail = FALSE
/obj/item/organ/internal/cyberimp/brain/anti_stun/hardened
name = "Hardened CNS Rebooter implant"
desc = "A military-grade version of the standard implant, for NT's more elite forces."
origin_tech = "materials=6;programming=5;biotech=5"
emp_proof = TRUE
/obj/item/organ/internal/cyberimp/brain/clown_voice
name = "Comical implant"
desc = "<span class='sans'>Uh oh.</span>"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 114 KiB

-98
View File
@@ -1,98 +0,0 @@
<!--
Title: inteliCard interface
Used In File(s): \code\game\objects\items\devices\aicard.dm
-->
<style type="text/css">
table.borders {
width:95%;
margin-left:2.4%;
margin-right:2.4%;
}
table.borders, table.borders tr {
border: 1px solid White;
}
td.law_index {
width: 50px;
}
td.state {
width: 63px;
text-align:center;
}
td.add {
width: 36px;
}
td.edit {
width: 36px;
text-align:center;
}
td.delete {
width: 53px;
text-align:center;
}
td.law_type {
width: 65px;
}
td.position {
width: 37px;
}
</style>
{{if data.has_ai}}
<div class="item">
<div class="itemLabel">
Hardware Integrity:
</div>
<div class="itemContent">
{{:data.hardware_integrity}}%
</div>
</div>
{{if data.has_laws}}
<table class='borders'>
<tr><td class='law_index'>Index</td><td>Law</td></tr>
<div class="itemLabelNarrow">
Laws:
</div>
{{for data.laws}}
<tr><td valign="top">{{:value.index}}.</td><td>{{:value.law}}</td></tr>
{{/for}}
</table>
{{else}}
<span class='notice'>No laws found.</span>
{{/if}}
{{if data.operational}}
<table>
<tr>
<td><span class='itemLabelWidest'>Radio Subspace Transceiver</span></td>
<td>{{:helper.link("Enabled", null, {'radio' : 0}, data.radio ? 'selected' : null)}}</td>
<td>{{:helper.link("Disabled", null, {'radio' : 1}, data.radio ? null : 'redButton' )}}</td>
</tr>
<tr><td><span class='itemLabelWidest'>Wireless Interface</span></td>
<td>{{:helper.link("Enabled", null, {'wireless' : 0}, data.wireless ? 'selected' : null)}}</td>
<td>{{:helper.link("Disabled", null, {'wireless' : 1}, data.wireless ? null : 'redButton' )}}</td>
</tr>
{{if data.flushing}}
<tr><td><span class='notice'>AI wipe in progress...</span></td></tr>
{{else}}
<tr>
<td><span class='itemLabelWidest'>Wipe AI</span></td>
<td>{{:helper.link("Wipe", 'exclamation-circle', {'wipe' : 1}, null, 'redButton')}}</td>
</tr>
{{/if}}
</table>
{{/if}}
{{else}}
Stored AI: <span class='notice'>No AI detected.</span>
{{/if}}
+94
View File
@@ -0,0 +1,94 @@
import { useBackend } from "../backend";
import { Button, ProgressBar, LabeledList, Box, Section } from "../components";
import { Window } from "../layouts";
export const AICard = (props, context) => {
const { act, data } = useBackend(context);
if (data.has_ai === 0) {
return (
<Window>
<Window.Content>
<Section title="Stored AI">
<Box>
<h3>No AI detected.</h3>
</Box>
</Section>
</Window.Content>
</Window>
);
} else {
let integrityColor = null; // Handles changing color of the integrity bar
if (data.integrity >= 75) { integrityColor = 'green'; }
else if (data.integrity >= 25) { integrityColor = 'yellow'; }
else { integrityColor = 'red'; }
return (
<Window scrollable>
<Window.Content>
<Section title="Stored AI">
<Box bold display="inline-block">
<h3>{data.name}</h3>
</Box>
<Box>
<LabeledList>
<LabeledList.Item label="Integrity">
<ProgressBar
color={integrityColor}
value={data.integrity/100} />
</LabeledList.Item>
</LabeledList>
</Box>
<Box color="red">
<h2>{data.flushing === 1 ? "Wipe of AI in progress..." : ""}</h2>
</Box>
</Section>
<Section title="Laws">
{!!data.has_laws && (
<Box>
{data.laws.map((value, key) => (
<Box key={key} display="inline-block">
{value}
</Box>
))}
</Box>
) || ( // Else, no laws.
<Box color="red">
<h3>No laws detected.</h3>
</Box>
)}
</Section>
<Section title="Actions">
<LabeledList>
<LabeledList.Item label="Wireless Activity">
<Button
icon={data.wireless ? "check" : "times"}
content={data.wireless ? "Enabled" : "Disabled"}
color={data.wireless ? "green" : "red"}
onClick={() => act("wireless")} />
</LabeledList.Item>
<LabeledList.Item label="Subspace Transceiver">
<Button
icon={data.radio ? "check" : "times"}
content={data.radio ? "Enabled" : "Disabled"}
color={data.radio ? "green" : "red"}
onClick={() => act("radio")} />
</LabeledList.Item>
<LabeledList.Item label="Wipe">
<Button.Confirm
icon="trash-alt"
confirmIcon="trash-alt"
disabled={data.flushing || data.integrity === 0}
confirmColor="red"
content="Wipe AI"
onClick={() => act("wipe")} />
</LabeledList.Item>
</LabeledList>
</Section>
</Window.Content>
</Window>
);
}
};
File diff suppressed because one or more lines are too long
+1
View File
@@ -4,3 +4,4 @@ This folder contains all the script and tools required for GitHub actions. If yo
- `nanomap-renderer` - A linux application to render NanoMap images of the ingame maps automatically. Based off of SpacemanDMM (Modified source [here](https://github.com/AffectedArc07/ParaSpacemanDMM), original source [here](https://github.com/Spacemaniac/SpacemanDMM))
- `nanomap-renderer-invoker.sh` - A script which invokes the render tool and clones the maps to the correct directory
- `doc-generator` - A linux application to generate documentation of game code automatically. Based off of SpacemanDMM (Modified source [here](https://github.com/AffectedArc07/ParaSpacemanDMM), original source [here](https://github.com/Spacemaniac/SpacemanDMM))
Binary file not shown.