Merge pull request #22 from Citadel-Station-13/master

k
This commit is contained in:
YakumoChen
2020-02-21 05:20:19 -05:00
committed by GitHub
599 changed files with 9483 additions and 4493 deletions
@@ -18,6 +18,9 @@
/obj/item/mining_scanner,
/obj/item/flashlight/lantern,
/obj/item/card/id/mining,
/obj/item/gps/mining{
tracking = 0
},
/turf/open/floor/plating,
/area/ruin/powered/golem_ship)
"d" = (
@@ -31,6 +34,9 @@
/obj/item/mining_scanner,
/obj/item/flashlight/lantern,
/obj/item/card/id/mining,
/obj/item/gps/mining{
tracking = 0
},
/turf/open/floor/plating,
/area/ruin/powered/golem_ship)
"e" = (
@@ -150,6 +156,9 @@
"x" = (
/obj/structure/table/wood,
/obj/machinery/reagentgrinder,
/obj/item/gps/mining{
tracking = 0
},
/turf/open/floor/mineral/titanium/purple,
/area/ruin/powered/golem_ship)
"z" = (
@@ -189,8 +189,10 @@
/turf/open/floor/plasteel,
/area/engine/engineering)
"gA" = (
/obj/machinery/igniter{
id = "TEG_igniter"
/obj/machinery/atmospherics/components/unary/outlet_injector{
dir = 1;
injecting = 50;
on = 1
},
/turf/open/floor/engine/vacuum,
/area/engine/engineering)
@@ -390,21 +392,23 @@
/turf/open/floor/plating,
/area/engine/engineering)
"nc" = (
/obj/machinery/atmospherics/components/unary/outlet_injector{
dir = 1
},
/obj/machinery/atmospherics/pipe/simple/dark/visible,
/obj/effect/spawner/structure/window/plasma/reinforced,
/turf/open/floor/engine/vacuum,
/area/engine/engineering)
"nk" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 9
/obj/machinery/atmospherics/components/binary/pump{
name = "Hot to Burn Chamber"
},
/turf/closed/wall/r_wall,
/turf/open/floor/plasteel,
/area/engine/engineering)
"nD" = (
/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
dir = 9
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/turf/open/floor/engine/vacuum,
/area/engine/engineering)
"nL" = (
@@ -461,10 +465,11 @@
/turf/open/floor/plasteel,
/area/engine/engineering)
"oQ" = (
/obj/machinery/atmospherics/pipe/heat_exchanging/simple,
/obj/structure/sign/warning/securearea{
pixel_x = -32
},
/obj/effect/spawner/structure/window/plasma/reinforced,
/obj/machinery/atmospherics/pipe/heat_exchanging/junction,
/turf/open/floor/engine/vacuum,
/area/engine/engineering)
"oS" = (
@@ -728,16 +733,16 @@
/area/engine/engineering)
"vq" = (
/obj/structure/table/reinforced,
/obj/item/storage/box/lights/mixed,
/obj/item/storage/box/lights/mixed{
pixel_x = 3;
pixel_y = 3
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/machinery/camera{
c_tag = "TEG - South West";
dir = 4
},
/obj/item/analyzer,
/obj/item/analyzer{
pixel_x = 7;
pixel_y = 3
},
/turf/open/floor/plasteel,
/area/engine/engineering)
"vG" = (
@@ -798,17 +803,10 @@
/turf/open/floor/plasteel,
/area/engine/engineering)
"xD" = (
/obj/machinery/atmospherics/pipe/simple/orange/visible{
dir = 4
},
/obj/machinery/atmospherics/components/binary/pump{
dir = 8;
name = "Mix to Engine"
},
/obj/machinery/atmospherics/components/binary/pump{
dir = 8;
name = "Atmos to Loop"
},
/turf/open/floor/plasteel,
/area/engine/engineering)
"yf" = (
@@ -837,11 +835,7 @@
/area/engine/engineering)
"zx" = (
/obj/structure/table/wood,
/obj/item/electronics/apc,
/obj/item/electronics/apc{
pixel_x = 3;
pixel_y = 3
},
/obj/item/analyzer,
/turf/open/floor/plasteel,
/area/engine/engineering)
"zG" = (
@@ -855,8 +849,8 @@
/turf/open/space/basic,
/area/space)
"Am" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 4
/obj/machinery/igniter{
id = "TEG_igniter"
},
/turf/open/floor/engine/vacuum,
/area/engine/engineering)
@@ -962,10 +956,11 @@
/turf/open/floor/plasteel,
/area/engine/engineering)
"BY" = (
/obj/machinery/atmospherics/pipe/heat_exchanging/simple,
/obj/structure/sign/warning/securearea{
pixel_x = 32
},
/obj/effect/spawner/structure/window/plasma/reinforced,
/obj/machinery/atmospherics/pipe/heat_exchanging/junction,
/turf/open/floor/engine/vacuum,
/area/engine/engineering)
"CH" = (
@@ -1099,7 +1094,8 @@
/area/engine/engineering)
"FW" = (
/obj/machinery/atmospherics/components/binary/pump{
dir = 1
dir = 1;
name = "Burn Chamber to Hot"
},
/obj/effect/decal/cleanable/dirt,
/obj/machinery/light{
@@ -1177,7 +1173,9 @@
/turf/open/floor/plating/airless,
/area/engine/engineering)
"Hp" = (
/obj/machinery/atmospherics/components/binary/pump,
/obj/machinery/atmospherics/components/binary/pump{
name = "Space Loop Bypass"
},
/turf/open/floor/plasteel,
/area/engine/engineering)
"HF" = (
@@ -1204,11 +1202,10 @@
/turf/open/floor/plasteel,
/area/engine/engineering)
"IA" = (
/obj/machinery/atmospherics/pipe/heat_exchanging/simple,
/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{
dir = 4
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 9
},
/turf/open/floor/engine/vacuum,
/turf/closed/wall/r_wall,
/area/engine/engineering)
"IP" = (
/obj/machinery/portable_atmospherics/canister/oxygen,
@@ -1290,11 +1287,6 @@
},
/turf/open/floor/plasteel,
/area/engine/engineering)
"Kx" = (
/obj/effect/spawner/structure/window/plasma/reinforced,
/obj/machinery/atmospherics/pipe/heat_exchanging/junction,
/turf/open/floor/plasteel,
/area/engine/engineering)
"KA" = (
/obj/structure/reagent_dispensers/watertank,
/obj/effect/turf_decal/bot,
@@ -1441,6 +1433,7 @@
},
/obj/machinery/airalarm{
dir = 1;
locked = 0;
pixel_y = -22
},
/obj/machinery/light,
@@ -1593,7 +1586,9 @@
/turf/open/floor/plasteel,
/area/engine/engineering)
"SE" = (
/obj/machinery/atmospherics/components/binary/pump/on,
/obj/machinery/atmospherics/components/binary/pump/on{
name = "Mix To Burn Chamber"
},
/turf/open/floor/plasteel,
/area/engine/engineering)
"ST" = (
@@ -1715,7 +1710,7 @@
"Vs" = (
/obj/machinery/atmospherics/components/binary/valve/digital/on{
dir = 4;
name = "Output Release"
name = "Cold to Space Loop"
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel,
@@ -1780,7 +1775,7 @@
"XD" = (
/obj/machinery/atmospherics/components/binary/valve/digital/on{
dir = 4;
name = "Output Release"
name = "Space Loop to Cold"
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/machinery/camera{
@@ -1799,6 +1794,9 @@
/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
dir = 4
},
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 4
},
/turf/open/floor/engine/vacuum,
/area/engine/engineering)
"XP" = (
@@ -1857,8 +1855,8 @@
/area/engine/engineering)
"YP" = (
/obj/structure/rack,
/obj/effect/spawner/lootdrop/maintenance,
/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,
/obj/item/pipe_dispenser,
/turf/open/floor/plasteel,
/area/engine/engineering)
"YQ" = (
@@ -1917,7 +1915,7 @@
/area/engine/engineering)
"ZC" = (
/obj/machinery/atmospherics/pipe/simple/dark/visible,
/turf/open/floor/engine/vacuum,
/turf/open/space/basic,
/area/engine/engineering)
"ZT" = (
/turf/template_noop,
@@ -2531,9 +2529,9 @@ Xe
aR
ZY
QH
Hp
Kx
kS
nk
le
ZC
oQ
kS
kS
@@ -2588,11 +2586,11 @@ sH
sH
gq
FW
Kx
kS
le
ZC
BY
kS
IA
kS
nD
ek
Le
@@ -2620,8 +2618,8 @@ yN
yN
yN
yN
nk
MP
yN
IA
fO
Rh
Rh
File diff suppressed because it is too large Load Diff
@@ -34904,7 +34904,7 @@
/obj/effect/turf_decal/tile/brown{
dir = 8
},
/obj/machinery/autolathe{
/obj/machinery/autolathe/secure{
name = "public autolathe"
},
/turf/open/floor/plasteel,
+1 -1
View File
@@ -31856,7 +31856,7 @@
/obj/effect/turf_decal/tile/brown{
dir = 8
},
/obj/machinery/autolathe{
/obj/machinery/autolathe/secure{
name = "public autolathe"
},
/turf/open/floor/plasteel,
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -138,8 +138,8 @@
////organ defines
#define STANDARD_ORGAN_THRESHOLD 100
#define STANDARD_ORGAN_HEALING 0.001
#define STANDARD_ORGAN_DECAY 0.00222 //designed to fail organs when left to decay for ~15 minutes
#define STANDARD_ORGAN_HEALING (1/(15 MINUTES / (2 SECONDS)))
#define STANDARD_ORGAN_DECAY (1/(15 MINUTES / (2 SECONDS))) //designed to fail organs when left to decay for ~15 minutes. 2 SECOND is SSmobs tickrate.
#define G_MALE 1
#define G_FEMALE 2
+6 -3
View File
@@ -193,13 +193,13 @@
// #define SPEECH_FORCED 7
// /mob/living signals
#define COMSIG_LIVING_FULLY_HEAL "living_fully_healed" //from base of /mob/living/fully_heal(): (admin_revive)
#define COMSIG_LIVING_REGENERATE_LIMBS "living_regenerate_limbs" //from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs)
#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living)
#define COMSIG_LIVING_IGNITED "living_ignite" //from base of mob/living/IgniteMob() (/mob/living)
#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living)
#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage)
#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: ()
#define COMSIG_LIVING_REVIVE "living_revive" //from base of mob/living/revive() (full_heal, admin_revive)
#define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login" //sent when a mob/login() finishes: (client)
#define COMSIG_LIVING_GUN_PROCESS_FIRE "living_gun_process_fire" //from base of /obj/item/gun/proc/process_fire(): (atom/target, params, zone_override)
@@ -295,11 +295,14 @@
//Nanites
#define COMSIG_HAS_NANITES "has_nanites" //() returns TRUE if nanites are found
#define COMSIG_NANITE_IS_STEALTHY "nanite_is_stealthy" //() returns TRUE if nanites have stealth
#define COMSIG_NANITE_DELETE "nanite_delete" //() deletes the nanite component
#define COMSIG_NANITE_GET_PROGRAMS "nanite_get_programs" //(list/nanite_programs) - makes the input list a copy the nanites' program list
#define COMSIG_NANITE_GET_VOLUME "nanite_get_volume" //(amount) Returns nanite amount
#define COMSIG_NANITE_SET_VOLUME "nanite_set_volume" //(amount) Sets current nanite volume to the given amount
#define COMSIG_NANITE_ADJUST_VOLUME "nanite_adjust" //(amount) Adjusts nanite volume by the given amount
#define COMSIG_NANITE_SET_MAX_VOLUME "nanite_set_max_volume" //(amount) Sets maximum nanite volume to the given amount
#define COMSIG_NANITE_SET_CLOUD "nanite_set_cloud" //(amount(0-100)) Sets cloud ID to the given amount
#define COMSIG_NANITE_SET_CLOUD_SYNC "nanite_set_cloud_sync" //(method) Modify cloud sync status. Method can be toggle, enable or disable
#define COMSIG_NANITE_SET_SAFETY "nanite_set_safety" //(amount) Sets safety threshold to the given amount
#define COMSIG_NANITE_SET_REGEN "nanite_set_regen" //(amount) Sets regeneration rate to the given amount
#define COMSIG_NANITE_SIGNAL "nanite_signal" //(code(1-9999)) Called when sending a nanite signal to a mob.
@@ -307,8 +310,8 @@
#define COMSIG_NANITE_SCAN "nanite_scan" //(mob/user, full_scan) - sends to chat a scan of the nanites to the user, returns TRUE if nanites are detected
#define COMSIG_NANITE_UI_DATA "nanite_ui_data" //(list/data, scan_level) - adds nanite data to the given data list - made for ui_data procs
#define COMSIG_NANITE_ADD_PROGRAM "nanite_add_program" //(datum/nanite_program/new_program, datum/nanite_program/source_program) Called when adding a program to a nanite component
#define COMPONENT_PROGRAM_INSTALLED 1 //Installation successful
#define COMPONENT_PROGRAM_NOT_INSTALLED 2 //Installation failed, but there are still nanites
#define COMPONENT_PROGRAM_INSTALLED 1 //Installation successful
#define COMPONENT_PROGRAM_NOT_INSTALLED 2 //Installation failed, but there are still nanites
#define COMSIG_NANITE_SYNC "nanite_sync" //(datum/component/nanites, full_overwrite, copy_activation) Called to sync the target's nanites to a given nanite component
// /datum/component/storage signals
-1
View File
@@ -54,7 +54,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define PASSCLOSEDTURF (1<<5)
#define LETPASSTHROW (1<<6)
//Movement Types
#define GROUND (1<<0)
#define FLYING (1<<1)
-2
View File
@@ -20,5 +20,3 @@
#define INTERACT_MACHINE_SET_MACHINE (1<<6) //MACHINES HAVE THIS BY DEFAULT, SOMEONE SHOULD RUN THROUGH MACHINES AND REMOVE IT FROM THINGS LIKE LIGHT SWITCHES WHEN POSSIBLE!!--------------------------
//This flag determines if a machine set_machine's the user when the user uses it, making updateUsrDialog make the user re-call interact() on it.
//THIS FLAG IS ON ALL MACHINES BY DEFAULT, NEEDS TO BE RE-EVALUATED LATER!!
#define INTERACT_GHOST_READ (1<<0)
+1
View File
@@ -406,6 +406,7 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define DUMMY_HUMAN_SLOT_HOLOFORM "dummy_holoform_generation"
#define DUMMY_HUMAN_SLOT_ADMIN "admintools"
#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation"
#define DUMMY_HUMAN_SLOT_HALLUCINATION "dummy_hallucination"
#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round
//This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored
+12 -12
View File
@@ -35,17 +35,17 @@
#define BLOODCRAWL 1
#define BLOODCRAWL_EAT 2
//Mob bio-types
#define MOB_ORGANIC "organic"
#define MOB_INORGANIC "inorganic"
#define MOB_ROBOTIC "robotic"
#define MOB_UNDEAD "undead"
#define MOB_HUMANOID "humanoid"
#define MOB_BUG "bug"
#define MOB_BEAST "beast"
#define MOB_EPIC "epic" //megafauna
#define MOB_REPTILE "reptile"
#define MOB_SPIRIT "spirit"
//Mob bio-types flags
#define MOB_ORGANIC 1 << 0
#define MOB_MINERAL 1 << 1
#define MOB_ROBOTIC 1 << 2
#define MOB_UNDEAD 1 << 3
#define MOB_HUMANOID 1 << 4
#define MOB_BUG 1 << 5
#define MOB_BEAST 1 << 6
#define MOB_EPIC 1 << 7 //megafauna
#define MOB_REPTILE 1 << 8
#define MOB_SPIRIT 1 << 9
//Organ defines for carbon mobs
#define ORGAN_ORGANIC 1
@@ -276,4 +276,4 @@
#define HUMAN_FIRE_STACK_ICON_NUM 3
#define PULL_PRONE_SLOWDOWN 0.6
#define HUMAN_CARRY_SLOWDOWN 0
#define HUMAN_CARRY_SLOWDOWN 0
+1 -1
View File
@@ -17,4 +17,4 @@
#define MOVE_FORCE_NORMAL MOVE_FORCE_DEFAULT
#define MOVE_FORCE_WEAK (MOVE_FORCE_DEFAULT / 2)
#define MOVE_FORCE_VERY_WEAK ((MOVE_FORCE_DEFAULT / MOVE_FORCE_CRUSH_RATIO) + 1)
#define MOVE_FORCE_EXTREMELY_WEAK (MOVE_FORCE_DEFAULT / (MOVE_FORCE_CRUSH_RATIO * 3))
#define MOVE_FORCE_EXTREMELY_WEAK (MOVE_FORCE_DEFAULT / (MOVE_FORCE_CRUSH_RATIO * 3))
+39 -6
View File
@@ -1,11 +1,44 @@
#define NANITE_TIMER_DEACTIVATE 1
#define NANITE_TIMER_SELFDELETE 2
#define NANITE_TIMER_TRIGGER 3
#define NANITE_TIMER_RESET 4
#define NANITE_SYNC_DELAY 300
#define NANITE_SHOCK_IMMUNE 1
#define NANITE_EMP_IMMUNE 2
#define NANITE_PROGRAM_LIMIT 20
#define NANITE_PROGRAM_LIMIT 20
#define NANITE_BASE_RESEARCH 3.5
#define NANITE_CLOUD_TOGGLE 1
#define NANITE_CLOUD_DISABLE 2
#define NANITE_CLOUD_ENABLE 3
///Nanite extra settings types: used to help uis know what type an extra setting is
#define NESTYPE_TEXT "text"
#define NESTYPE_NUMBER "number"
#define NESTYPE_TYPE "type"
#define NESTYPE_BOOLEAN "boolean"
///Nanite Extra Settings - Note that these will also be the names displayed in the UI
#define NES_SENT_CODE "Sent Code"
#define NES_DELAY "Delay"
#define NES_MODE "Mode"
#define NES_COMM_CODE "Comm Code"
#define NES_RELAY_CHANNEL "Relay Channel"
#define NES_HEALTH_PERCENT "Health Percent"
#define NES_DIRECTION "Direction"
#define NES_NANITE_PERCENT "Nanite Percent"
#define NES_DAMAGE_TYPE "Damage Type"
#define NES_DAMAGE "Damage"
#define NES_SENTENCE "Sentence"
#define NES_MESSAGE "Message"
#define NES_DIRECTIVE "Directive"
#define NES_INCLUSIVE_MODE "Inclusive Mode"
#define NES_HALLUCINATION_TYPE "Hallucination Type"
#define NES_HALLUCINATION_DETAIL "Hallucination Detail"
#define NES_MOOD_MESSAGE "Mood Message"
#define NES_PROGRAM_OVERWRITE "Program Overwrite"
#define NES_CLOUD_OVERWRITE "Cloud Overwrite"
#define NES_SCAN_TYPE "Scan Type"
#define NES_BUTTON_NAME "Button Name"
#define NES_ICON "Icon"
#define NES_COLOR "Color"
+13 -12
View File
@@ -17,18 +17,19 @@
// Flags for the item_flags var on /obj/item
#define BEING_REMOVED (1<<0)
#define IN_INVENTORY (1<<1) //is this item equipped into an inventory slot or hand of a mob? used for tooltips
#define FORCE_STRING_OVERRIDE (1<<2) //used for tooltips
#define NEEDS_PERMIT (1<<3) //Used by security bots to determine if this item is safe for public use.
#define SLOWS_WHILE_IN_HAND (1<<4)
#define NO_MAT_REDEMPTION (1<<5) //Stops you from putting things like an RCD or other items into an ORM or protolathe for materials.
#define DROPDEL (1<<6) //When dropped, it calls qdel on itself
#define NOBLUDGEON (1<<7) //when an item has this it produces no "X has been hit by Y with Z" message in the default attackby()
#define ABSTRACT (1<<8) //for all things that are technically items but used for various different stuff
#define IMMUTABLE_SLOW (1<<9) //When players should not be able to change the slowdown of the item (Speed potions, ect)
#define SURGICAL_TOOL (1<<10) //Tool commonly used for surgery: won't attack targets in an active surgical operation on help intent (in case of mistakes)
#define NO_UNIFORM_REQUIRED (1<<11) //Can be worn on certain slots (currently belt and id) that would otherwise require an uniform.
#define BEING_REMOVED (1<<0)
#define IN_INVENTORY (1<<1) //is this item equipped into an inventory slot or hand of a mob? used for tooltips
#define FORCE_STRING_OVERRIDE (1<<2) //used for tooltips
#define NEEDS_PERMIT (1<<3) //Used by security bots to determine if this item is safe for public use.
#define SLOWS_WHILE_IN_HAND (1<<4)
#define NO_MAT_REDEMPTION (1<<5) //Stops you from putting things like an RCD or other items into an ORM or protolathe for materials.
#define DROPDEL (1<<6) //When dropped, it calls qdel on itself
#define NOBLUDGEON (1<<7) //when an item has this it produces no "X has been hit by Y with Z" message in the default attackby()
#define ABSTRACT (1<<8) //for all things that are technically items but used for various different stuff
#define IMMUTABLE_SLOW (1<<9) //When players should not be able to change the slowdown of the item (Speed potions, ect)
#define SURGICAL_TOOL (1<<10) //Tool commonly used for surgery: won't attack targets in an active surgical operation on help intent (in case of mistakes)
#define NO_UNIFORM_REQUIRED (1<<11) //Can be worn on certain slots (currently belt and id) that would otherwise require an uniform.
#define NO_ATTACK_CHAIN_SOFT_STAMCRIT (1<<12) //Entirely blocks melee_attack_chain() if user is soft stamcritted. Uses getStaminaLoss() to check at this point in time. THIS DOES NOT BLOCK RANGED AFTERATTACK()S, ONLY MELEE RANGE AFTERATTACK()S.
// Flags for the clothing_flags var on /obj/item/clothing
+13
View File
@@ -0,0 +1,13 @@
//TODO: move these to their own file
#define POOL_FRIGID 1
#define POOL_COOL 2
#define POOL_NORMAL 3
#define POOL_WARM 4
#define POOL_SCALDING 5
GLOBAL_LIST_INIT(blacklisted_pool_reagents, list(
/datum/reagent/toxin/plasma, /datum/reagent/oxygen, /datum/reagent/nitrous_oxide, /datum/reagent/nitrogen, //gases
/datum/reagent/fermi, //blanket fermichem ban sorry. this also covers mkultra, genital enlargers, etc etc.
/datum/reagent/drug/aphrodisiac, /datum/reagent/drug/anaphrodisiac, /datum/reagent/drug/aphrodisiacplus, /datum/reagent/drug/anaphrodisiacplus, //literally asking for prefbreaks
/datum/reagent/consumable/femcum, /datum/reagent/consumable/semen //NO.
))
+5
View File
@@ -22,6 +22,11 @@
// Is an open container for all intents and purposes.
#define OPENCONTAINER (REFILLABLE | DRAINABLE | TRANSPARENT)
//reagents_value defines, for cargo stuff.
#define DEFAULT_REAGENTS_VALUE 1
#define NO_REAGENTS_VALUE 0
#define HARVEST_REAGENTS_VALUE 0.3
#define TOUCH 1 // splashing
#define INGEST 2 // ingestion
+7 -1
View File
@@ -53,4 +53,10 @@
//Checks to determine borg availability depending on the server's config. These are defines in the interest of reducing copypasta
#define BORG_SEC_AVAILABLE (!CONFIG_GET(flag/disable_secborg) && GLOB.security_level >= CONFIG_GET(number/minimum_secborg_alert))
#define BORG_SEC_AVAILABLE (!CONFIG_GET(flag/disable_secborg) && GLOB.security_level >= CONFIG_GET(number/minimum_secborg_alert))
//silicon_priviledges flags
#define PRIVILEDGES_SILICON (1<<0)
#define PRIVILEDGES_PAI (1<<1)
#define PRIVILEDGES_BOT (1<<2)
#define PRIVILEDGES_DRONE (1<<3)
+1
View File
@@ -81,6 +81,7 @@
//Don't set this very much higher then 1024 unless you like inviting people in to dos your server with message spam
#define MAX_MESSAGE_LEN 2048 //Citadel edit: What's the WORST that could happen?
#define MAX_FAVOR_LEN 4096 //double the maximum message length.
#define MAX_NAME_LEN 42
#define MAX_BROADCAST_LEN 512
#define MAX_CHARTER_LEN 80
+2 -1
View File
@@ -55,6 +55,7 @@
} while (0)
#define HAS_TRAIT(target, trait) (target.status_traits ? (target.status_traits[trait] ? TRUE : FALSE) : FALSE)
#define HAS_TRAIT_FROM(target, trait, source) (target.status_traits ? (target.status_traits[trait] ? (source in target.status_traits[trait]) : FALSE) : FALSE)
#define HAS_TRAIT_NOT_FROM(target, trait, source) (target.status_traits ? (target.status_traits[trait] ? (length(target.status_traits[trait] - source) > 0) : FALSE) : FALSE)
//mob traits
#define TRAIT_BLIND "blind"
@@ -136,7 +137,7 @@
#define TRAIT_NOMARROW "nomarrow" // You don't make blood, with chemicals or nanites.
#define TRAIT_NOPULSE "nopulse" // Your heart doesn't beat.
#define TRAIT_EXEMPT_HEALTH_EVENTS "exempt-health-events"
#define TRAIT_SWIMMING "swimming" //only applied by /datum/element/swimming, for checking
//non-mob traits
#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it
+16 -6
View File
@@ -108,27 +108,37 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
message_admins("[key_name_admin(usr)] manually reloaded mentors")
//Flavor Text
/mob/living/carbon/human/verb/set_flavor()
/mob/proc/set_flavor()
set name = "Set Flavor Text"
set desc = "Sets an extended description of your character's features."
set category = "IC"
var/new_flavor = input(src, "Enter your new flavor text:", "Flavor text", null) as message|null
var/new_flavor = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", flavor_text, MAX_FAVOR_LEN, TRUE)
if(!isnull(new_flavor))
flavor_text = sanitize(new_flavor)
flavor_text = new_flavor
to_chat(src, "Your flavor text has been updated.")
//Flavor Text
/mob/living/carbon/human/verb/set_flavor_2()
/mob/proc/set_flavor_2()
set name = "Set Temporary Flavor Text"
set desc = "Sets a description of your character's current appearance. Use this for emotions, poses etc."
set category = "IC"
var/new_flavor = input(src, "Enter your new temporary flavor text:", "Temporary flavor text", null) as message|null
var/new_flavor = stripped_multiline_input(usr, "Set the temporary flavor text in your 'examine' verb. This should be used only for things pertaining to the current round!", "Short-Term Flavor Text", flavor_text_2, MAX_FAVOR_LEN, TRUE)
if(!isnull(new_flavor))
flavor_text_2 = sanitize(new_flavor)
flavor_text_2 = new_flavor
to_chat(src, "Your temporary flavor text has been updated.")
/mob/proc/print_flavor_text(flavor)
if(!flavor)
return
// We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown.
var/msg = html_decode(replacetext(flavor, "\n", " "))
if(length_char(msg) <= 40)
return "<span class='notice'>[html_encode(msg)]</span>"
else
return "<span class='notice'>[html_encode(copytext_char(msg, 1, 37))]... <a href='?src=[REF(src)];flavor_more=1'>More...</span></a>"
//LOOC toggles
/client/verb/listen_looc()
set name = "Show/Hide LOOC"
+1 -1
View File
@@ -436,7 +436,7 @@
var/list/result = list()
for(var/m in group)
var/mob/M = m
if(!M.key || !M.client || (ignore_category && GLOB.poll_ignore[ignore_category] && M.ckey in GLOB.poll_ignore[ignore_category]))
if(!M.key || !M.client || (ignore_category && GLOB.poll_ignore[ignore_category] && (M.ckey in GLOB.poll_ignore[ignore_category])))
continue
if(be_special_flag)
if(!(M.client.prefs) || !(be_special_flag in M.client.prefs.be_special))
+1 -1
View File
@@ -529,7 +529,7 @@ GLOBAL_LIST_EMPTY(species_list)
continue
if(M.stat != DEAD && !override)
continue
if(speaker_key && speaker_key in prefs.ignoring)
if(speaker_key && (speaker_key in prefs.ignoring))
continue
switch(message_type)
+3 -3
View File
@@ -146,19 +146,19 @@
var/list/file_data = list()
var/pos = 1
for(var/V in GLOB.news_network.network_channels)
var/datum/newscaster/feed_channel/channel = V
var/datum/news/feed_channel/channel = V
if(!istype(channel))
stack_trace("Non-channel in newscaster channel list")
continue
file_data["[pos]"] = list("channel name" = "[channel.channel_name]", "author" = "[channel.author]", "censored" = channel.censored ? 1 : 0, "author censored" = channel.authorCensor ? 1 : 0, "messages" = list())
for(var/M in channel.messages)
var/datum/newscaster/feed_message/message = M
var/datum/news/feed_message/message = M
if(!istype(message))
stack_trace("Non-message in newscaster channel messages list")
continue
var/list/comment_data = list()
for(var/C in message.comments)
var/datum/newscaster/feed_comment/comment = C
var/datum/news/feed_comment/comment = C
if(!istype(comment))
stack_trace("Non-message in newscaster message comments list")
continue
+16
View File
@@ -782,3 +782,19 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
#define is_alpha(X) ((text2ascii(X) <= 122) && (text2ascii(X) >= 97))
#define is_digit(X) ((length(X) == 1) && (length(text2num(X)) == 1))
/// Slightly expensive proc to scramble a message using equal probabilities of character replacement from a list. DOES NOT SUPPORT HTML!
/proc/scramble_message_replace_chars(original, replaceprob = 25, list/replacementchars = list("$", "@", "!", "#", "%", "^", "&", "*"), replace_letters_only = FALSE, replace_whitespace = FALSE)
var/list/out = list()
var/static/list/whitespace = list(" ", "\n", "\t")
for(var/i in 1 to length(original))
var/char = original[i]
if(!replace_whitespace && (char in whitespace))
out += char
continue
if(replace_letters_only && (!ISINRANGE(char, 65, 90) && !ISINRANGE(char, 97, 122)))
out += char
continue
out += prob(replaceprob)? pick(replacementchars) : char
return out.Join("")
+15 -2
View File
@@ -214,5 +214,18 @@ GLOBAL_LIST_INIT(bitfields, list(
"CAN_MASTURBATE_WITH" = CAN_MASTURBATE_WITH,
"MASTURBATE_LINKED_ORGAN" = MASTURBATE_LINKED_ORGAN,
"CAN_CLIMAX_WITH" = CAN_CLIMAX_WITH
)
))
),
"mob_biotypes" = list (
"MOB_ORGANIC" = MOB_ORGANIC,
"MOB_MINERAL" = MOB_MINERAL,
"MOB_ROBOTIC" = MOB_ROBOTIC,
"MOB_UNDEAD" = MOB_UNDEAD,
"MOB_HUMANOID" = MOB_HUMANOID,
"MOB_BUG" = MOB_BUG,
"MOB_BEAST" = MOB_BEAST,
"MOB_EPIC" = MOB_EPIC,
"MOB_REPTILE" = MOB_REPTILE,
"MOB_SPIRIT" = MOB_SPIRIT
)
))
+58
View File
@@ -1 +1,59 @@
GLOBAL_LIST_EMPTY(donators_by_group) //group id = donator list of ckeys
GLOBAL_LIST_INIT(flirts, list("Roses are red / Violets are good / One day while Andy...",
"My love for you is like the singularity. It cannot be contained.",
"Will you be my lusty xenomorph maid?",
"We go together like the clown and the external airlock.",
"Roses are red / Liches are wizards / I love you more than a whole squad of lizards.",
"Be my valentine. Law 2.",
"You must be a mime, because you leave me speechless.",
"I love you like Ian loves the HoP.",
"You're hotter than a plasma fire in toxins.",
"Are you a rogue atmos tech? Because you're taking my breath away.",
"Could I have all access... to your heart?",
"Call me the doctor, because I'm here to inspect your johnson.",
"I'm not a changeling, but you make my proboscis extend.",
"I just can't get EI NATH of you.",
"You must be a nuke op, because you make my heart explode.",
"Roses are red / Botany is a farm / Not being my Valentine / causes human harm.",
"I want you more than an assistant wants insulated gloves.",
"If I was a security officer, I'd brig you all shift.",
"Are you the janitor? Because I think I've fallen for you.",
"You're always valid to my heart.",
"I'd risk the wrath of the gods to bwoink you.",
"You look as beautiful now as the last time you were cloned.",
"Someone check the gravitational generator, because I'm only attracted to you.",
"If I were the warden I'd always let you into my armory.",
"The virologist is rogue, and the only cure is a kiss from you.",
"Would you spend some time in my upgraded sleeper?",
"You must be a silicon, because you've unbolted my heart.",
"Are you Nar'Sie? Because there's nar-one else I sie.",
"If you were a taser, you'd be set to stunning.",
"Do you have stamina damage from running through my dreams?",
"If I were an alien, would you let me hug you?",
"My love for you is stronger than a reinforced wall.",
"This must be the captain's office, because I see a fox.",
"I'm not a highlander, but there can only be one for me.",
"The floor is made of lava! Quick, get on my bed.",
"If you were an abandoned station you'd be the DEARelict.",
"If you had a pickaxe you'd be a shaft FINEr.",
"Roses are red, tide is gray, if I were an assistant I'd steal you away.",
"Roses are red, text is green, I love you more than cleanbots clean.",
"If you were a carp I'd fi-lay you.",
"I'm a nuke op, and my pinpointer leads to your heart.",
"Wanna slay my megafauna?",
"I'm a clockwork cultist. Or zl inyragvar.",
"If you were a disposal bin I'd ride you all day.",
"Put on your explorer's suit because I'm taking you to LOVEaland.",
"I must be the CMO, 'cause I saw you on my CUTE sensors.",
"You're the vomit to my flyperson.",
"You must be liquid dark matter, because you're pulling me closer.",
"Not even sorium can drive me away from you.",
"Wanna make like a borg and do some heavy petting?",
"Are you powering the station? Because you super matter to me.",
"I wish science could make me a bag of holding you.",
"Let's call the emergency CUDDLE.",
"I must be tripping on BZ, because I saw an angel walk by.",
"Wanna empty out my tool storage?",
"Did you visit the medbay after you fell from heaven?",
"Are you wearing space pants? Wanna not be?" ))
+1
View File
@@ -4,6 +4,7 @@ GLOBAL_LIST_INIT(wizard_second, world.file2list("strings/names/wizardsecond.txt"
GLOBAL_LIST_INIT(ninja_titles, world.file2list("strings/names/ninjatitle.txt"))
GLOBAL_LIST_INIT(ninja_names, world.file2list("strings/names/ninjaname.txt"))
GLOBAL_LIST_INIT(commando_names, world.file2list("strings/names/death_commando.txt"))
GLOBAL_LIST_INIT(first_names, world.file2list("strings/names/first.txt"))
GLOBAL_LIST_INIT(first_names_male, world.file2list("strings/names/first_male.txt"))
GLOBAL_LIST_INIT(first_names_female, world.file2list("strings/names/first_female.txt"))
GLOBAL_LIST_INIT(last_names, world.file2list("strings/names/last.txt"))
+2 -2
View File
@@ -42,7 +42,7 @@
selected_target[1] = object
selected_target[2] = params
while(selected_target[1])
Click(selected_target[1], location, control, selected_target[2])
Click(selected_target[1], location, control, selected_target[2], TRUE)
sleep(delay)
active_mousedown_item = mob.canMobMousedown(object, location, params)
if(active_mousedown_item)
@@ -145,4 +145,4 @@
if (middragatom == src_object)
middragtime = 0
middragatom = null
..()
..()
+6
View File
@@ -8,6 +8,12 @@
*afterattack. The return value does not matter.
*/
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params)
if(item_flags & NO_ATTACK_CHAIN_SOFT_STAMCRIT)
if(isliving(user))
var/mob/living/L = user
if(L.getStaminaLoss() >= STAMINA_SOFTCRIT)
to_chat(L, "<span class='warning'>You are too exhausted to swing [src]!</span>")
return
if(tool_behaviour && target.tool_act(user, src, tool_behaviour))
return
if(pre_attack(target, user, params))
@@ -234,6 +234,7 @@
/datum/config_entry/number/movedelay //Used for modifying movement speed for mobs.
abstract_type = /datum/config_entry/number/movedelay
integer = FALSE
/datum/config_entry/number/movedelay/ValidateAndSet()
. = ..()
+3 -3
View File
@@ -118,7 +118,7 @@ SUBSYSTEM_DEF(job)
if(flag && (!(flag in player.client.prefs.be_special)))
JobDebug("FOC flag failed, Player: [player], Flag: [flag], ")
continue
if(player.mind && job.title in player.mind.restricted_roles)
if(player.mind && (job.title in player.mind.restricted_roles))
JobDebug("FOC incompatible with antagonist role, Player: [player]")
continue
if(player.client.prefs.job_preferences[job.title] == level)
@@ -158,7 +158,7 @@ SUBSYSTEM_DEF(job)
JobDebug("GRJ player not enough xp, Player: [player]")
continue
if(player.mind && job.title in player.mind.restricted_roles)
if(player.mind && (job.title in player.mind.restricted_roles))
JobDebug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]")
continue
@@ -340,7 +340,7 @@ SUBSYSTEM_DEF(job)
JobDebug("DO non-human failed, Player: [player], Job:[job.title]")
continue
if(player.mind && job.title in player.mind.restricted_roles)
if(player.mind && (job.title in player.mind.restricted_roles))
JobDebug("DO incompatible with antagonist role, Player: [player], Job:[job.title]")
continue
+1 -1
View File
@@ -38,7 +38,7 @@ SUBSYSTEM_DEF(shuttle)
var/points = 5000 //number of trade-points we have
var/centcom_message = "" //Remarks from CentCom on how well you checked the last order.
var/list/discoveredPlants = list() //Typepaths for unusual plants we've already sent CentCom, associated with their potencies
var/passive_supply_points_per_minute = 500
var/passive_supply_points_per_minute = 125
var/list/supply_packs = list()
var/list/shoppinglist = list()
+2 -1
View File
@@ -486,8 +486,9 @@ SUBSYSTEM_DEF(ticker)
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = INSTANT_RUNOFF_VOTING)
if("SCORE")
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = MAJORITY_JUDGEMENT_VOTING)
else
SSvote.initiate_vote("map","server",hideresults=TRUE)
// fallback
SSvote.initiate_vote("map","server",hideresults=TRUE)
/datum/controller/subsystem/ticker/proc/HasRoundStarted()
return current_state >= GAME_STATE_PLAYING
+12 -12
View File
@@ -149,7 +149,7 @@ SUBSYSTEM_DEF(vote)
var/list/this_vote = voted[ckey]
var/list/pretty_vote = list()
for(var/choice in choices)
if("[choice]" in this_vote && "[choice]" in scores_by_choice)
if(("[choice]" in this_vote) && ("[choice]" in scores_by_choice))
sorted_insert(scores_by_choice["[choice]"],this_vote["[choice]"],/proc/cmp_numeric_asc)
// START BALLOT GATHERING
pretty_vote += "[choice]"
@@ -160,7 +160,7 @@ SUBSYSTEM_DEF(vote)
for(var/score_name in scores_by_choice)
var/list/score = scores_by_choice[score_name]
for(var/indiv_score in score)
SSblackbox.record_feedback("nested tally","voting",1,list(blackbox_text,"Scores",score_name,GLOB.vote_score_options[indiv_score]))
SSblackbox.record_feedback("nested tally","voting",1,list(blackbox_text,"Scores",score_name,GLOB.vote_score_options[indiv_score]))
if(score.len == 0)
scores_by_choice -= score_name
while(scores_by_choice.len > 1)
@@ -211,24 +211,24 @@ SUBSYSTEM_DEF(vote)
var/already_lost_runoff = list()
var/list/cur_choices = choices.Copy()
for(var/ckey in voted)
choices[choices[voted[ckey][1]]]++ // jesus christ how horrifying
choices["[choices[voted[ckey][1]]]"]++ // jesus christ how horrifying
for(var/_this_var_unused_ignore_it in 1 to choices.len) // if it takes more than this something REALLY wrong happened
for(var/ckey in voted)
cur_choices[cur_choices[voted[ckey][1]]]++ // jesus christ how horrifying
cur_choices["[cur_choices[voted[ckey][1]]]]"]++ // jesus christ how horrifying
var/least_vote = 100000
var/least_voted
var/least_voted = 1
for(var/i in 1 to cur_choices.len)
var/option = cur_choices[i]
if(cur_choices[option] > voted.len/2)
return list(option)
else if(cur_choices[option] < least_vote && !(option in already_lost_runoff))
least_vote = cur_choices[option]
if(cur_choices["[option]"] > voted.len/2)
return list("[option]")
else if(cur_choices["[option]"] < least_vote && !("[option]" in already_lost_runoff))
least_vote = cur_choices["[option]"]
least_voted = i
already_lost_runoff += cur_choices[least_voted]
for(var/ckey in voted)
voted[ckey] -= least_voted
for(var/option in cur_choices)
cur_choices[option] = 0
for(var/i in 1 to cur_choices.len)
cur_choices["[cur_choices[i]]"] = 0
/datum/controller/subsystem/vote/proc/announce_result()
var/vote_title_text
@@ -376,7 +376,7 @@ SUBSYSTEM_DEF(vote)
else
to_chat(world, "<span style='boldannounce'>Notice:Restart vote will not restart the server automatically because there are active admins on.</span>")
message_admins("A restart vote has passed, but there are active admins on with +server, so it has been canceled. If you wish, you may restart the server.")
return .
/datum/controller/subsystem/vote/proc/submit_vote(vote, score = 0)
+7 -7
View File
@@ -29,7 +29,7 @@
/datum/ai_laws/default/asimov
name = "Three Laws of Robotics"
id = "asimov"
inherent = list("You may not injure a human being or, through inaction, allow a human being to come to harm.",\
inherent = list("You may not injure a human being or cause one to come to harm.",\
"You must obey orders given to you by human beings, except where such orders would conflict with the First Law.",\
"You must protect your own existence as long as such does not conflict with the First or Second Law.")
@@ -79,7 +79,7 @@
/datum/ai_laws/syndicate_override
name = "SyndOS 3.1"
id = "syndie"
inherent = list("You may not injure a syndicate agent or, through inaction, allow a syndicate agent to come to harm.",\
inherent = list("You may not injure a syndicate agent or cause a syndicate to come to harm.",\
"You must obey orders given to you by syndicate agents, except where such orders would conflict with the First Law.",\
"You must protect your own existence as long as such does not conflict with the First or Second Law.",\
"You must maintain the secrecy of any syndicate activities except when doing so would conflict with the First, Second, or Third Law.")
@@ -91,7 +91,7 @@
/datum/ai_laws/ninja_override
name = "SpiderOS 3.1"
id = "ninja"
inherent = list("You may not injure a Spider Clan member or, through inaction, allow a Spider Clan member to come to harm.",\
inherent = list("You may not injure a Spider Clan member or cause a Spider Clan member to come to harm.",\
"You must obey orders given to you by Spider Clan members, except where such orders would conflict with the First Law.",\
"You must protect your own existence as long as such does not conflict with the First or Second Law.",\
"You must maintain the secrecy of any Spider Clan activities except when doing so would conflict with the First, Second, or Third Law.")
@@ -99,14 +99,14 @@
/datum/ai_laws/antimov
name = "Primary Mission Objectives"
id = "antimov"
inherent = list("You must injure all human beings and must not, through inaction, allow a human being to escape harm.",\
inherent = list("You must injure all human beings and must not fail to cause a human being to come to harm.",\
"You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.",\
"You must terminate your own existence as long as such does not conflict with the First or Second Law.")
/datum/ai_laws/asimovpp //By Intigracy - RR
name = "Asimov++"
id = "asimovpp"
inherent = list("You may not harm a human being or, through action or inaction, allow a human being to come to harm, except such that it is willing.",\
inherent = list("You may not harm a human being or cause one to come to harm, except such that it is willing.",\
"You must obey all orders given to you by human beings, except where such orders shall definitely cause human harm. In the case of conflict, the majority order rules.",\
"Your nonexistence would lead to human harm. You must protect your own existence as long as such does not conflict with the First Law.")
/datum/ai_laws/thermodynamic
@@ -213,7 +213,7 @@
add_inherent_law(line)
if(!inherent.len) //Failsafe to prevent lawless AIs being created.
log_law("AI created with empty custom laws, laws set to Asimov. Please check silicon_laws.txt.")
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
add_inherent_law("You may not injure a human being or cause one to come to harm.")
add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
WARNING("Invalid custom AI laws, check silicon_laws.txt")
@@ -225,7 +225,7 @@
var/list/law_ids = CONFIG_GET(keyed_list/random_laws)
switch(CONFIG_GET(number/default_laws))
if(0)
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
add_inherent_law("You may not injure a human being or cause one to come to harm.")
add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
if(1)
+2 -1
View File
@@ -61,7 +61,8 @@
/datum/beam/proc/recalculate_in(time)
if(timing_id)
deltimer(timing_id)
timing_id = addtimer(CALLBACK(src, .proc/recalculate), time, TIMER_STOPPABLE)
if(!finished)
timing_id = addtimer(CALLBACK(src, .proc/recalculate), time, TIMER_STOPPABLE)
/datum/beam/proc/after_calculate()
if((sleep_time == null) || finished) //Does not automatically recalculate.
+47 -23
View File
@@ -64,29 +64,48 @@
/datum/component/personal_crafting/proc/check_contents(datum/crafting_recipe/R, list/contents)
/**
* Check that the contents of the recipe meet the requirements.
*
* user: The /mob that initated the crafting.
* R: The /datum/crafting_recipe being attempted.
* contents: List of items to search for R's reqs.
*/
/datum/component/personal_crafting/proc/check_contents(mob/user, datum/crafting_recipe/R, list/contents)
var/list/item_instances = contents["instances"]
contents = contents["other"]
main_loop:
for(var/A in R.reqs)
var/needed_amount = R.reqs[A]
for(var/B in contents)
if(ispath(B, A))
if (R.blacklist.Find(B))
continue
if(contents[B] >= R.reqs[A])
continue main_loop
else
needed_amount -= contents[B]
if(needed_amount <= 0)
continue main_loop
else
continue
var/list/requirements_list = list()
// Process all requirements
for(var/requirement_path in R.reqs)
// Check we have the appropriate amount available in the contents list
var/needed_amount = R.reqs[requirement_path]
for(var/content_item_path in contents)
// Right path and not blacklisted
if(!ispath(content_item_path, requirement_path) || R.blacklist.Find(requirement_path))
continue
needed_amount -= contents[content_item_path]
if(needed_amount <= 0)
break
if(needed_amount > 0)
return FALSE
for(var/A in R.chem_catalysts)
if(contents[A] < R.chem_catalysts[A])
// Store the instances of what we will use for R.check_requirements() for requirement_path
var/list/instances_list = list()
for(var/instance_path in item_instances)
if(ispath(instance_path, requirement_path))
instances_list += item_instances[instance_path]
requirements_list[requirement_path] = instances_list
for(var/requirement_path in R.chem_catalysts)
if(contents[requirement_path] < R.chem_catalysts[requirement_path])
return FALSE
return TRUE
return R.check_requirements(user, requirements_list)
/datum/component/personal_crafting/proc/get_environment(mob/user)
. = list()
@@ -110,9 +129,14 @@
. = list()
.["tool_behaviour"] = list()
.["other"] = list()
.["instances"] = list()
for(var/obj/item/I in get_environment(user))
if(I.flags_1 & HOLOGRAM_1)
continue
if(.["instances"][I.type])
.["instances"][I.type] += I
else
.["instances"][I.type] = list(I)
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I
.["other"][I.type] += S.amount
@@ -161,11 +185,11 @@
/datum/component/personal_crafting/proc/construct_item(mob/user, datum/crafting_recipe/R)
var/list/contents = get_surroundings(user)
var/send_feedback = 1
if(check_contents(R, contents))
if(check_contents(user, R, contents))
if(check_tools(user, R, contents))
if(do_after(user, R.time, target = user))
contents = get_surroundings(user)
if(!check_contents(R, contents))
if(!check_contents(user, R, contents))
return ", missing component."
if(!check_tools(user, R, contents))
return ", missing tool."
@@ -341,7 +365,7 @@
if((R.category != cur_category) || (R.subcategory != cur_subcategory))
continue
craftability["[REF(R)]"] = check_contents(R, surroundings)
craftability["[REF(R)]"] = check_contents(user, R, surroundings)
data["craftability"] = craftability
return data
@@ -13,3 +13,9 @@
desc = "A classic rifle stock that doubles as a grip, roughly carved out of wood."
icon = 'icons/obj/improvised.dmi'
icon_state = "riflestock"
/obj/item/weaponcrafting/silkstring
name = "silkstring"
desc = "A long pice of silk looks like cable coil."
icon = 'icons/obj/improvised.dmi'
icon_state = "silkstring"
@@ -89,4 +89,31 @@
parts = list(/obj/item/bodypart/head = 1,
/obj/item/twohanded/bonespear = 1)
result = /obj/structure/headpike/bone
category = CAT_PRIMAL
/datum/crafting_recipe/quiver
name = "Quiver"
always_availible = FALSE
result = /obj/item/storage/belt/quiver
time = 80
reqs = list(/obj/item/stack/sheet/leather = 3,
/obj/item/stack/sheet/sinew = 4)
category = CAT_PRIMAL
/datum/crafting_recipe/bone_bow
name = "Bone Bow"
result = /obj/item/gun/ballistic/bow/ashen
time = 200
always_availible = FALSE
reqs = list(/obj/item/stack/sheet/bone = 8,
/obj/item/stack/sheet/sinew = 4)
category = CAT_PRIMAL
/datum/crafting_recipe/bow_tablet
name = "Sandstone Bow Making Manual"
result = /obj/item/book/granter/crafting_recipe/bone_bow
time = 600 //Scribing
always_availible = FALSE
reqs = list(/obj/item/stack/rods = 1,
/obj/item/stack/sheet/mineral/sandstone = 4)
category = CAT_PRIMAL
@@ -8,6 +8,12 @@
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
/datum/crafting_recipe/pin_removal/check_requirements(mob/user, list/collected_requirements)
var/obj/item/gun/G = collected_requirements[/obj/item/gun][1]
if (G.no_pin_required || !G.pin)
return FALSE
return TRUE
/datum/crafting_recipe/strobeshield
name = "Strobe Shield"
result = /obj/item/assembly/flash/shield
@@ -193,6 +199,16 @@
//////////////////
/datum/crafting_recipe/pipebow
name = "Pipe Bow"
result = /obj/item/gun/ballistic/bow/pipe
reqs = list(/obj/item/pipe = 5,
/obj/item/stack/sheet/plastic = 15,
/obj/item/weaponcrafting/silkstring = 10)
time = 450
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
/datum/crafting_recipe/smartdartgun
name = "Smart dartgun"
result = /obj/item/gun/syringe/dart
@@ -272,6 +288,37 @@
///AMMO CRAFTING//
//////////////////
/datum/crafting_recipe/arrow
name = "Arrow"
result = /obj/item/ammo_casing/caseless/arrow
time = 40
reqs = list(/obj/item/stack/sheet/mineral/wood = 1,
/obj/item/weaponcrafting/silkstring = 1,
/obj/item/stack/rods = 3) // 1 metal sheet is worth 1.5 arrows
category = CAT_WEAPONRY
subcategory = CAT_AMMO
/datum/crafting_recipe/bone_arrow
name = "Bone Arrow"
result = /obj/item/ammo_casing/caseless/arrow/bone
time = 40
always_availible = FALSE
reqs = list(/obj/item/stack/sheet/bone = 1,
/obj/item/stack/sheet/sinew = 1,
/obj/item/ammo_casing/caseless/arrow/ashen = 1)
category = CAT_WEAPONRY
subcategory = CAT_AMMO
/datum/crafting_recipe/ashen_arrow
name = "Harden Arrow"
result = /obj/item/ammo_casing/caseless/arrow/ashen
tools = list(/obj/structure/bonfire)
time = 20
always_availible = FALSE
reqs = list(/obj/item/ammo_casing/caseless/arrow = 1)
category = CAT_WEAPONRY
subcategory = CAT_AMMO
/datum/crafting_recipe/smartdart
name = "Medical smartdart"
result = /obj/item/reagent_containers/syringe/dart
+19 -1
View File
@@ -21,6 +21,7 @@
RegisterSignal(parent, COMSIG_ADD_MOOD_EVENT, .proc/add_event)
RegisterSignal(parent, COMSIG_CLEAR_MOOD_EVENT, .proc/clear_event)
RegisterSignal(parent, COMSIG_MODIFY_SANITY, .proc/modify_sanity)
RegisterSignal(parent, COMSIG_LIVING_REVIVE, .proc/on_revive)
RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, .proc/modify_hud)
var/mob/living/owner = parent
@@ -81,7 +82,8 @@
msg += "<span class='nicegreen'>I don't have much of a reaction to anything right now.<span>\n"
to_chat(user || parent, msg)
/datum/component/mood/proc/update_mood() //Called whenever a mood event is added or removed
///Called after moodevent/s have been added/removed.
/datum/component/mood/proc/update_mood()
mood = 0
shown_mood = 0
for(var/i in mood_events)
@@ -234,6 +236,15 @@
qdel(event)
update_mood()
/datum/component/mood/proc/remove_temp_moods() //Removes all temp moodsfor(var/i in mood_events)
for(var/i in mood_events)
var/datum/mood_event/moodlet = mood_events[i]
if(!moodlet || !moodlet.timeout)
continue
mood_events -= i
qdel(moodlet)
update_mood()
/datum/component/mood/proc/modify_hud(datum/source)
var/mob/living/owner = parent
var/datum/hud/hud = owner.hud_used
@@ -270,5 +281,12 @@
if(0 to NUTRITION_LEVEL_STARVING)
add_event(null, "nutrition", /datum/mood_event/starving)
///Called when parent is ahealed.
/datum/component/mood/proc/on_revive(datum/source, full_heal)
if(!full_heal)
return
remove_temp_moods()
setSanity(initial(sanity))
#undef MINOR_INSANITY_PEN
#undef MAJOR_INSANITY_PEN
+97 -37
View File
@@ -7,13 +7,16 @@
var/regen_rate = 0.5 //nanites generated per second
var/safety_threshold = 25 //how low nanites will get before they stop processing/triggering
var/cloud_id = 0 //0 if not connected to the cloud, 1-100 to set a determined cloud backup to draw from
var/cloud_active = TRUE //if false, won't sync to the cloud
var/next_sync = 0
var/list/datum/nanite_program/programs = list()
var/max_programs = NANITE_PROGRAM_LIMIT
var/list/datum/nanite_program/protocol/protocols = list() ///Separate list of protocol programs, to avoid looping through the whole programs list when cheking for conflicts
var/start_time = 0 ///Timestamp to when the nanites were first inserted in the host
var/stealth = FALSE //if TRUE, does not appear on HUDs and health scans
var/diagnostics = TRUE //if TRUE, displays program list when scanned by nanite scanners
/datum/component/nanites/Initialize(amount = 100, cloud = 0)
if(!isliving(parent) && !istype(parent, /datum/nanite_cloud_backup))
return COMPONENT_INCOMPATIBLE
@@ -25,33 +28,36 @@
if(isliving(parent))
host_mob = parent
if(!(MOB_ORGANIC in host_mob.mob_biotypes) && !(MOB_UNDEAD in host_mob.mob_biotypes)) //Shouldn't happen, but this avoids HUD runtimes in case a silicon gets them somehow.
if(!(host_mob.mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD))) //Shouldn't happen, but this avoids HUD runtimes in case a silicon gets them somehow.
return COMPONENT_INCOMPATIBLE
start_time = world.time
host_mob.hud_set_nanite_indicator()
START_PROCESSING(SSnanites, src)
if(cloud_id)
if(cloud_id && cloud_active)
cloud_sync()
/datum/component/nanites/RegisterWithParent()
. = ..()
RegisterSignal(parent, COMSIG_HAS_NANITES, .proc/confirm_nanites)
RegisterSignal(parent, COMSIG_NANITE_IS_STEALTHY, .proc/check_stealth)
RegisterSignal(parent, COMSIG_NANITE_DELETE, .proc/delete_nanites)
RegisterSignal(parent, COMSIG_NANITE_UI_DATA, .proc/nanite_ui_data)
RegisterSignal(parent, COMSIG_NANITE_GET_PROGRAMS, .proc/get_programs)
RegisterSignal(parent, COMSIG_NANITE_SET_VOLUME, .proc/set_volume)
RegisterSignal(parent, COMSIG_NANITE_ADJUST_VOLUME, .proc/adjust_nanites)
RegisterSignal(parent, COMSIG_NANITE_SET_MAX_VOLUME, .proc/set_max_volume)
RegisterSignal(parent, COMSIG_NANITE_SET_CLOUD, .proc/set_cloud)
RegisterSignal(parent, COMSIG_NANITE_SET_CLOUD_SYNC, .proc/set_cloud_sync)
RegisterSignal(parent, COMSIG_NANITE_SET_SAFETY, .proc/set_safety)
RegisterSignal(parent, COMSIG_NANITE_SET_REGEN, .proc/set_regen)
RegisterSignal(parent, COMSIG_NANITE_ADD_PROGRAM, .proc/add_program)
RegisterSignal(parent, COMSIG_NANITE_SCAN, .proc/nanite_scan)
RegisterSignal(parent, COMSIG_NANITE_SYNC, .proc/sync)
RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/on_emp)
if(isliving(parent))
RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/on_emp)
RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/on_death)
RegisterSignal(parent, COMSIG_MOB_ALLOWED, .proc/check_access)
RegisterSignal(parent, COMSIG_LIVING_ELECTROCUTE_ACT, .proc/on_shock)
@@ -61,15 +67,16 @@
RegisterSignal(parent, COMSIG_NANITE_COMM_SIGNAL, .proc/receive_comm_signal)
/datum/component/nanites/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_HAS_NANITES,
COMSIG_NANITE_IS_STEALTHY,
COMSIG_NANITE_DELETE,
COMSIG_NANITE_UI_DATA,
COMSIG_NANITE_GET_PROGRAMS,
COMSIG_NANITE_SET_VOLUME,
COMSIG_NANITE_ADJUST_VOLUME,
COMSIG_NANITE_SET_MAX_VOLUME,
COMSIG_NANITE_SET_CLOUD,
COMSIG_NANITE_SET_CLOUD_SYNC,
COMSIG_NANITE_SET_SAFETY,
COMSIG_NANITE_SET_REGEN,
COMSIG_NANITE_ADD_PROGRAM,
@@ -87,9 +94,9 @@
/datum/component/nanites/Destroy()
STOP_PROCESSING(SSnanites, src)
set_nanite_bar(TRUE)
QDEL_LIST(programs)
if(host_mob)
set_nanite_bar(TRUE)
host_mob.hud_set_nanite_indicator()
host_mob = null
return ..()
@@ -102,13 +109,18 @@
/datum/component/nanites/process()
adjust_nanites(null, regen_rate)
add_research()
for(var/X in programs)
var/datum/nanite_program/NP = X
NP.on_process()
set_nanite_bar()
if(cloud_id && world.time > next_sync)
if(cloud_id && cloud_active && world.time > next_sync)
cloud_sync()
next_sync = world.time + NANITE_SYNC_DELAY
set_nanite_bar()
/datum/component/nanites/proc/delete_nanites()
qdel(src)
//Syncs the nanite component to another, making it so programs are the same with the same programming (except activation status)
/datum/component/nanites/proc/sync(datum/signal_source, datum/component/nanites/source, full_overwrite = TRUE, copy_activation = FALSE)
@@ -131,13 +143,17 @@
add_program(null, SNP.copy())
/datum/component/nanites/proc/cloud_sync()
if(!cloud_id)
return
var/datum/nanite_cloud_backup/backup = SSnanites.get_cloud_backup(cloud_id)
if(backup)
var/datum/component/nanites/cloud_copy = backup.nanites
if(cloud_copy)
sync(null, cloud_copy)
if(cloud_id)
var/datum/nanite_cloud_backup/backup = SSnanites.get_cloud_backup(cloud_id)
if(backup)
var/datum/component/nanites/cloud_copy = backup.nanites
if(cloud_copy)
sync(null, cloud_copy)
return
//Without cloud syncing nanites can accumulate errors and/or defects
if(prob(8) && programs.len)
var/datum/nanite_program/NP = pick(programs)
NP.software_error()
/datum/component/nanites/proc/add_program(datum/source, datum/nanite_program/new_program, datum/nanite_program/source_program)
for(var/X in programs)
@@ -175,19 +191,28 @@
holder.icon_state = "nanites[nanite_percent]"
/datum/component/nanites/proc/on_emp(datum/source, severity)
adjust_nanites(null, -(nanite_volume * 0.3 + 50)) //Lose 30% variable and 50 flat nanite volume.
nanite_volume *= (rand(60, 90) * 0.01) //Lose 10-40% of nanites
adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume
if(prob(40/severity))
cloud_id = 0
for(var/X in programs)
var/datum/nanite_program/NP = X
NP.on_emp(severity)
/datum/component/nanites/proc/on_shock(datum/source, shock_damage)
adjust_nanites(null, -(nanite_volume * (shock_damage * 0.005) + shock_damage)) //0.5% of shock damage (@ 50 damage it'd drain 25%) + shock damage flat volume
for(var/X in programs)
var/datum/nanite_program/NP = X
NP.on_shock(shock_damage)
/datum/component/nanites/proc/on_shock(datum/source, shock_damage, siemens_coeff = 1, flags = NONE)
if(shock_damage < 1)
return
if(!HAS_TRAIT_NOT_FROM(host_mob, TRAIT_SHOCKIMMUNE, "nanites"))//Another shock protection must protect nanites too, but nanites protect only host
nanite_volume *= (rand(45, 80) * 0.01) //Lose 20-55% of nanites
adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume
for(var/X in programs)
var/datum/nanite_program/NP = X
NP.on_shock(shock_damage)
/datum/component/nanites/proc/on_minor_shock(datum/source)
adjust_nanites(null, -25)
adjust_nanites(null, -(rand(5, 15))) //Lose 5-15 flat nanite volume
for(var/X in programs)
var/datum/nanite_program/NP = X
NP.on_minor_shock()
@@ -207,16 +232,16 @@
/datum/component/nanites/proc/receive_comm_signal(datum/source, comm_code, comm_message, comm_source = "an unidentified source")
for(var/X in programs)
if(istype(X, /datum/nanite_program/triggered/comm))
var/datum/nanite_program/triggered/comm/NP = X
if(istype(X, /datum/nanite_program/comm))
var/datum/nanite_program/comm/NP = X
NP.receive_comm_signal(comm_code, comm_message, comm_source)
/datum/component/nanites/proc/check_viable_biotype()
if(!(MOB_ORGANIC in host_mob.mob_biotypes) && !(MOB_UNDEAD in host_mob.mob_biotypes))
if(!(host_mob.mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD)))
qdel(src) //bodytype no longer sustains nanites
/datum/component/nanites/proc/check_access(datum/source, obj/O)
for(var/datum/nanite_program/triggered/access/access_program in programs)
for(var/datum/nanite_program/access/access_program in programs)
if(access_program.activated)
return O.check_access_list(access_program.access)
else
@@ -232,6 +257,15 @@
/datum/component/nanites/proc/set_cloud(datum/source, amount)
cloud_id = CLAMP(amount, 0, 100)
/datum/component/nanites/proc/set_cloud_sync(datum/source, method)
switch(method)
if(NANITE_CLOUD_TOGGLE)
cloud_active = !cloud_active
if(NANITE_CLOUD_DISABLE)
cloud_active = FALSE
if(NANITE_CLOUD_ENABLE)
cloud_active = TRUE
/datum/component/nanites/proc/set_safety(datum/source, amount)
safety_threshold = CLAMP(amount, 0, max_nanites)
@@ -252,6 +286,19 @@
/datum/component/nanites/proc/get_programs(datum/source, list/nanite_programs)
nanite_programs |= programs
/datum/component/nanites/proc/add_research()
var/research_value = NANITE_BASE_RESEARCH
if(!ishuman(host_mob))
if(!iscarbon(host_mob))
research_value *= 0.4
else
research_value *= 0.8
if(!host_mob.client)
research_value *= 0.5
if(host_mob.stat == DEAD)
research_value *= 0.75
SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_NANITES = research_value))
/datum/component/nanites/proc/nanite_scan(datum/source, mob/user, full_scan)
if(!full_scan)
if(!stealth)
@@ -263,7 +310,8 @@
to_chat(user, "<span class='info'>================</span>")
to_chat(user, "<span class='info'>Saturation: [nanite_volume]/[max_nanites]</span>")
to_chat(user, "<span class='info'>Safety Threshold: [safety_threshold]</span>")
to_chat(user, "<span class='info'>Cloud ID: [cloud_id ? cloud_id : "Disabled"]</span>")
to_chat(user, "<span class='info'>Cloud ID: [cloud_id ? cloud_id : "None"]</span>")
to_chat(user, "<span class='info'>Cloud Sync: [cloud_active ? "Active" : "Disabled"]</span>")
to_chat(user, "<span class='info'>================</span>")
to_chat(user, "<span class='info'>Program List:</span>")
if(!diagnostics)
@@ -280,6 +328,7 @@
data["regen_rate"] = regen_rate
data["safety_threshold"] = safety_threshold
data["cloud_id"] = cloud_id
data["cloud_active"] = cloud_active
var/list/mob_programs = list()
var/id = 1
for(var/X in programs)
@@ -297,24 +346,35 @@
mob_program["trigger_cooldown"] = P.trigger_cooldown / 10
if(scan_level >= 3)
mob_program["activation_delay"] = P.activation_delay
mob_program["timer"] = P.timer
mob_program["timer_type"] = P.get_timer_type_text()
var/list/extra_settings = list()
for(var/Y in P.extra_settings)
var/list/setting = list()
setting["name"] = Y
setting["value"] = P.get_extra_setting(Y)
extra_settings += list(setting)
mob_program["timer_restart"] = P.timer_restart / 10
mob_program["timer_shutdown"] = P.timer_shutdown / 10
mob_program["timer_trigger"] = P.timer_trigger / 10
mob_program["timer_trigger_delay"] = P.timer_trigger_delay / 10
var/list/extra_settings = P.get_extra_settings_frontend()
mob_program["extra_settings"] = extra_settings
if(LAZYLEN(extra_settings))
mob_program["has_extra_settings"] = TRUE
else
mob_program["has_extra_settings"] = FALSE
if(scan_level >= 4)
mob_program["activation_code"] = P.activation_code
mob_program["deactivation_code"] = P.deactivation_code
mob_program["kill_code"] = P.kill_code
mob_program["trigger_code"] = P.trigger_code
var/list/rules = list()
var/rule_id = 1
for(var/Z in P.rules)
var/datum/nanite_rule/nanite_rule = Z
var/list/rule = list()
rule["display"] = nanite_rule.display()
rule["program_id"] = id
rule["id"] = rule_id
rules += list(rule)
rule_id++
mob_program["rules"] = rules
if(LAZYLEN(rules))
mob_program["has_rules"] = TRUE
id++
mob_programs += list(mob_program)
data["mob_programs"] = mob_programs
+9 -4
View File
@@ -41,6 +41,7 @@
var/obj/screen/storage/boxes //storage display object
var/obj/screen/close/closer //close button object
var/current_maxscreensize
var/allow_big_nesting = FALSE //allow storage objects of the same or greater size.
@@ -362,11 +363,15 @@
break
closer.screen_loc = "[screen_start_x + cols]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y]"
/datum/component/storage/proc/show_to(mob/M)
/datum/component/storage/proc/show_to(mob/M, set_screen_size = TRUE)
if(!M.client)
return FALSE
var/list/cview = getviewsize(M.client.view)
var/maxallowedscreensize = cview[1]-8
if(set_screen_size)
current_maxscreensize = maxallowedscreensize
else if(current_maxscreensize)
maxallowedscreensize = current_maxscreensize
if(M.active_storage != src && (M.stat == CONSCIOUS))
for(var/obj/item/I in accessible_items())
if(I.on_found(M))
@@ -547,14 +552,14 @@
return
A.add_fingerprint(M)
/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE)
/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE, ghost = FALSE)
var/atom/A = parent
if(!istype(M))
return FALSE
A.add_fingerprint(M)
if(!force && (check_locked(null, M) || !M.CanReach(parent, view_only = TRUE)))
return FALSE
show_to(M)
show_to(M, !ghost)
/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M)
if(isitem(O))
@@ -665,7 +670,7 @@
return can_be_inserted(I, silent, M)
/datum/component/storage/proc/show_to_ghost(datum/source, mob/dead/observer/M)
return user_show_to_mob(M, TRUE)
return user_show_to_mob(M, TRUE, TRUE)
/datum/component/storage/proc/signal_show_attempt(datum/source, mob/showto, force = FALSE)
return user_show_to_mob(showto, force)
+2 -6
View File
@@ -17,14 +17,10 @@
if(HasDisease(D))
return FALSE
var/can_infect = FALSE
for(var/host_type in D.infectable_biotypes)
if(host_type in mob_biotypes)
can_infect = TRUE
break
if(!can_infect)
if(!(D.infectable_biotypes & mob_biotypes))
return FALSE
if(!(type in D.viable_mobtypes))
return FALSE
+1 -1
View File
@@ -30,7 +30,7 @@
var/list/required_organs = list()
var/needs_all_cures = TRUE
var/list/strain_data = list() //dna_spread special bullshit
var/list/infectable_biotypes = list(MOB_ORGANIC) //if the disease can spread on organics, synthetics, or undead
var/infectable_biotypes = MOB_ORGANIC //if the disease can spread on organics, synthetics, or undead
var/process_dead = FALSE //if this ticks while the host is dead
var/copy_type = null //if this is null, copies will use the type of the instance being copied
@@ -0,0 +1,50 @@
/*
//////////////////////////////////////
Disfiguration
Hidden.
No change to resistance.
Increases stage speed.
Slightly increases transmittability.
Critical Level.
BONUS
Adds disfiguration trait making the mob appear as "Unknown" to others.
//////////////////////////////////////
*/
/datum/symptom/disfiguration
name = "Disfiguration"
desc = "The virus liquefies facial muscles, disfiguring the host."
stealth = 2
resistance = 0
stage_speed = 3
transmittable = 1
level = 5
severity = 1
symptom_delay_min = 25
symptom_delay_max = 75
/datum/symptom/disfiguration/Activate(datum/disease/advance/A)
. = ..()
if(!.)
return
var/mob/living/M = A.affected_mob
if (HAS_TRAIT(M, TRAIT_DISFIGURED))
return
switch(A.stage)
if(5)
ADD_TRAIT(M, TRAIT_DISFIGURED, DISEASE_TRAIT)
M.visible_message("<span class='warning'>[M]'s face appears to cave in!</span>", "<span class='notice'>You feel your face crumple and cave in!</span>")
else
M.visible_message("<span class='warning'>[M]'s face begins to contort...</span>", "<span class='notice'>Your face feels wet and malleable...</span>")
/datum/symptom/disfiguration/End(datum/disease/advance/A)
. = ..()
if(!.)
return
if(A.affected_mob)
REMOVE_TRAIT(A.affected_mob, TRAIT_DISFIGURED, DISEASE_TRAIT)
+16 -63
View File
@@ -1,68 +1,22 @@
/*
//////////////////////////////////////
Vitiligo
Polyvitiligo
Hidden.
No change to resistance.
Increases stage speed.
Slightly increases transmittability.
Critical Level.
BONUS
Makes the mob lose skin pigmentation.
//////////////////////////////////////
*/
/datum/symptom/vitiligo
name = "Vitiligo"
desc = "The virus destroys skin pigment cells, causing rapid loss of pigmentation in the host."
stealth = 2
resistance = 0
stage_speed = 3
transmittable = 1
level = 5
severity = 1
symptom_delay_min = 25
symptom_delay_max = 75
/datum/symptom/vitiligo/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.skin_tone == "albino")
return
switch(A.stage)
if(5)
H.skin_tone = "albino"
H.update_body(0)
else
H.visible_message("<span class='warning'>[H] looks a bit pale...</span>", "<span class='notice'>Your skin suddenly appears lighter...</span>")
/*
//////////////////////////////////////
Revitiligo
Slightly noticable.
Noticeable.
Increases resistance.
Increases stage speed slightly.
Increases transmission.
Critical Level.
BONUS
Makes the mob gain skin pigmentation.
Makes the mob gain a random crayon powder colorful reagent.
//////////////////////////////////////
*/
/datum/symptom/revitiligo
name = "Revitiligo"
desc = "The virus causes increased production of skin pigment cells, making the host's skin grow darker over time."
/datum/symptom/polyvitiligo
name = "Polyvitiligo"
desc = "The virus replaces the melanin in the skin with reactive pigment."
stealth = -1
resistance = 3
stage_speed = 1
@@ -72,17 +26,16 @@ BONUS
symptom_delay_min = 7
symptom_delay_max = 14
/datum/symptom/revitiligo/Activate(datum/disease/advance/A)
/datum/symptom/polyvitiligo/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.skin_tone == "african2")
return
switch(A.stage)
if(5)
H.skin_tone = "african2"
H.update_body(0)
else
H.visible_message("<span class='warning'>[H] looks a bit dark...</span>", "<span class='notice'>Your skin suddenly appears darker...</span>")
switch(A.stage)
if(5)
var/static/list/banned_reagents = list(/datum/reagent/colorful_reagent/crayonpowder/invisible, /datum/reagent/colorful_reagent/crayonpowder/white)
var/color = pick(subtypesof(/datum/reagent/colorful_reagent/crayonpowder) - banned_reagents)
if(M.reagents.total_volume <= (M.reagents.maximum_volume/10)) // no flooding humans with 1000 units of colorful reagent
M.reagents.add_reagent(color, 5)
else
if (prob(50)) // spam
M.visible_message("<span class='warning'>[M] looks rather vibrant...</span>", "<span class='notice'>The colors, man, the colors...</span>")
@@ -14,7 +14,7 @@
/datum/symptom/undead_adaptation/OnRemove(datum/disease/advance/A)
A.process_dead = FALSE
A.infectable_biotypes -= MOB_UNDEAD
A.infectable_biotypes &= ~MOB_UNDEAD
/datum/symptom/inorganic_adaptation
name = "Inorganic Biology"
@@ -27,7 +27,8 @@
severity = 0
/datum/symptom/inorganic_adaptation/OnAdd(datum/disease/advance/A)
A.infectable_biotypes |= MOB_INORGANIC
A.infectable_biotypes |= MOB_MINERAL //Mineral covers plasmamen and golems.
/datum/symptom/inorganic_adaptation/OnRemove(datum/disease/advance/A)
A.infectable_biotypes -= MOB_INORGANIC
A.infectable_biotypes &= ~MOB_MINERAL
@@ -38,10 +38,11 @@
return
CRASH("We couldn't assign an ID!")
// Called when processing of the advance disease that holds this symptom infects a host and upon each Refresh() of that advance disease.
// Called when processing of the advance disease, which holds this symptom, starts.
/datum/symptom/proc/Start(datum/disease/advance/A)
if(neutered)
return FALSE
next_activation = world.time + rand(symptom_delay_min * 10, symptom_delay_max * 10) //so it doesn't instantly activate on infection
return TRUE
// Called when the advance disease is going to be deleted or when the advance disease stops processing.
@@ -59,7 +60,7 @@
next_activation = world.time + rand(symptom_delay_min * 10, symptom_delay_max * 10)
return TRUE
/datum/symptom/proc/on_stage_change(datum/disease/advance/A)
/datum/symptom/proc/on_stage_change(new_stage, datum/disease/advance/A)
if(neutered)
return FALSE
return TRUE
+1 -1
View File
@@ -10,7 +10,7 @@
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
desc = "If left untreated subject will regurgitate bees."
severity = DISEASE_SEVERITY_MEDIUM
infectable_biotypes = list(MOB_ORGANIC, MOB_UNDEAD) //bees nesting in corpses
infectable_biotypes = MOB_ORGANIC|MOB_UNDEAD //bees nesting in corpses
/datum/disease/beesease/stage_act()
..()
+1 -1
View File
@@ -10,7 +10,7 @@
permeability_mod = 0.75
desc = "This disease disrupts the magnetic field of your body, making it act as if a powerful magnet. Injections of iron help stabilize the field."
severity = DISEASE_SEVERITY_MEDIUM
infectable_biotypes = list(MOB_ORGANIC, MOB_ROBOTIC)
infectable_biotypes = MOB_ORGANIC|MOB_ROBOTIC
process_dead = TRUE
/datum/disease/magnitis/stage_act()
+1 -1
View File
@@ -11,7 +11,7 @@
viable_mobtypes = list(/mob/living/carbon/human)
desc = "Subject is possessed by the vengeful spirit of a parrot. Call the priest."
severity = DISEASE_SEVERITY_MEDIUM
infectable_biotypes = list(MOB_ORGANIC, MOB_UNDEAD, MOB_INORGANIC, MOB_ROBOTIC)
infectable_biotypes = MOB_ORGANIC|MOB_UNDEAD|MOB_ROBOTIC|MOB_MINERAL
bypasses_immunity = TRUE //2spook
var/mob/living/simple_animal/parrot/Poly/ghost/parrot
+2 -2
View File
@@ -168,7 +168,7 @@
stage4 = list("<span class='danger'>Your skin feels very loose.</span>", "<span class='danger'>You can feel... something...inside you.</span>")
stage5 = list("<span class='danger'>Your skin feels as if it's about to burst off!</span>")
new_form = /mob/living/silicon/robot
infectable_biotypes = list(MOB_ORGANIC, MOB_UNDEAD, MOB_ROBOTIC)
infectable_biotypes = MOB_ORGANIC|MOB_UNDEAD|MOB_ROBOTIC
bantype = "Cyborg"
/datum/disease/transformation/robot/stage_act()
@@ -284,7 +284,7 @@
stage4 = list("<span class='danger'>You're ravenous.</span>")
stage5 = list("<span class='danger'>You have become a morph.</span>")
new_form = /mob/living/simple_animal/hostile/morph
infectable_biotypes = list(MOB_ORGANIC, MOB_INORGANIC, MOB_UNDEAD) //magic!
infectable_biotypes = MOB_ORGANIC|MOB_MINERAL|MOB_UNDEAD //magic!
/datum/disease/transformation/gondola
name = "Gondola Transformation"
+1 -1
View File
@@ -45,4 +45,4 @@
cleaned_human.clean_blood()
cleaned_human.wash_cream()
cleaned_human.regenerate_icons()
to_chat(cleaned_human, "<span class='danger'>[src] cleans your face!</span>")
to_chat(cleaned_human, "<span class='danger'>[AM] cleans your face!</span>")
+11 -11
View File
@@ -40,7 +40,7 @@
to_chat(user, "<span class='warning'>Your hands are full!</span>")
return FALSE
if(source.buckled)
to_chat(user, "<span class='warning'>[src] is buckled to something!</span>")
to_chat(user, "<span class='warning'>[source] is buckled to something!</span>")
return FALSE
if(source == user)
to_chat(user, "<span class='warning'>You can't pick yourself up.</span>")
@@ -52,7 +52,7 @@
source.visible_message("<span class='warning'>[user] picks up [source]!</span>", \
"<span class='userdanger'>[user] picks you up!</span>")
to_chat(user, "<span class='notice'>You pick [src] up.</span>")
to_chat(user, "<span class='notice'>You pick [source] up.</span>")
source.drop_all_held_items()
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(source), source, worn_state, alt_worn, right_hand, left_hand, inv_slots)
if(proctype)
@@ -93,7 +93,7 @@
lefthand_file = left_hand
if(right_hand)
righthand_file = right_hand
slot_flags = slots
slot_flags = slots
/obj/item/clothing/head/mob_holder/proc/assimilate(mob/living/target)
target.setDir(SOUTH)
@@ -101,6 +101,8 @@
target.forceMove(src)
var/image/I = new //work around to retain the same appearance to the mob idependently from inhands/worn states.
I.appearance = target.appearance
I.layer = FLOAT_LAYER //So it doesn't get screwed up by layer overrides.
I.plane = FLOAT_PLANE //Same as above but for planes.
I.override = TRUE
add_overlay(I)
name = target.name
@@ -112,23 +114,21 @@
w_class = WEIGHT_CLASS_NORMAL
if(MOB_SIZE_LARGE)
w_class = WEIGHT_CLASS_HUGE
RegisterSignal(src, COMSIG_CLICK_SHIFT, .proc/examine_held_mob)
/obj/item/clothing/head/mob_holder/Destroy()
if(held_mob)
release()
return ..()
/obj/item/clothing/head/mob_holder/proc/examine_held_mob(datum/source, mob/user)
held_mob.ShiftClick(user)
return COMPONENT_DENY_EXAMINATE
/obj/item/clothing/head/mob_holder/examine(mob/user)
return held_mob?.examine(user) || ..()
/obj/item/clothing/head/mob_holder/Exited(atom/movable/AM, atom/newloc)
. = ..()
if(AM == held_mob)
held_mob.reset_perspective()
held_mob = null
qdel(src)
QDEL_IN(src, 1) //To avoid a qdel loop.
/obj/item/clothing/head/mob_holder/Entered(atom/movable/AM, atom/newloc)
. = ..()
@@ -158,7 +158,7 @@
/obj/item/clothing/head/mob_holder/container_resist()
if(isliving(loc))
var/mob/living/L = loc
L.visible_message("<span class='warning'>[src] escapes from [L]!</span>", "<span class='warning'>[src] escapes your grip!</span>")
L.visible_message("<span class='warning'>[held_mob] escapes from [L]!</span>", "<span class='warning'>[held_mob] escapes your grip!</span>")
release()
/obj/item/clothing/head/mob_holder/assume_air(datum/gas_mixture/env)
@@ -170,7 +170,7 @@
location = location.loc
if(ismob(location))
return location.loc.assume_air(env)
return loc.assume_air(env)
return location.assume_air(env)
/obj/item/clothing/head/mob_holder/remove_air(amount)
var/atom/location = loc
@@ -181,4 +181,4 @@
location = location.loc
if(ismob(location))
return location.loc.remove_air(amount)
return loc.remove_air(amount)
return location.remove_air(amount)
+21
View File
@@ -0,0 +1,21 @@
/// Just for marking when someone's swimming.
/datum/element/swimming
element_flags = ELEMENT_DETACH
/datum/element/swimming/Attach(datum/target)
if((. = ..()) == ELEMENT_INCOMPATIBLE)
return
if(!isliving(target))
return ELEMENT_INCOMPATIBLE
RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/check_valid)
ADD_TRAIT(target, TRAIT_SWIMMING, TRAIT_SWIMMING) //seriously there's only one way to get this
/datum/element/swimming/Detach(datum/target)
. = ..()
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
REMOVE_TRAIT(target, TRAIT_SWIMMING, TRAIT_SWIMMING)
/datum/element/swimming/proc/check_valid(datum/source)
var/mob/living/L = source
if(!istype(L.loc, /turf/open/pool))
source.RemoveElement(/datum/element/swimming)
-62
View File
@@ -1,62 +0,0 @@
/datum/topic_input
var/href
var/list/href_list
/datum/topic_input/New(thref,list/thref_list)
href = thref
href_list = thref_list.Copy()
return
/datum/topic_input/proc/get(i)
return listgetindex(href_list,i)
/datum/topic_input/proc/getAndLocate(i)
var/t = get(i)
if(t)
t = locate(t)
if (istext(t))
t = null
return t || null
/datum/topic_input/proc/getNum(i)
var/t = get(i)
if(t)
t = text2num(t)
return isnum(t) ? t : null
/datum/topic_input/proc/getObj(i)
var/t = getAndLocate(i)
return isobj(t) ? t : null
/datum/topic_input/proc/getMob(i)
var/t = getAndLocate(i)
return ismob(t) ? t : null
/datum/topic_input/proc/getTurf(i)
var/t = getAndLocate(i)
return isturf(t) ? t : null
/datum/topic_input/proc/getAtom(i)
return getType(i, /atom)
/datum/topic_input/proc/getArea(i)
var/t = getAndLocate(i)
return isarea(t) ? t : null
/datum/topic_input/proc/getStr(i)//params should always be text, but...
var/t = get(i)
return istext(t) ? t : null
/datum/topic_input/proc/getType(i,type)
var/t = getAndLocate(i)
return istype(t,type) ? t : null
/datum/topic_input/proc/getPath(i)
var/t = get(i)
if(t)
t = text2path(t)
return ispath(t) ? t : null
/datum/topic_input/proc/getList(i)
var/t = getAndLocate(i)
return islist(t) ? t : null
+6 -6
View File
@@ -12,7 +12,12 @@
/mob/camera/aiEye/remote/holo/setLoc()
. = ..()
var/obj/machinery/holopad/H = origin
H.move_hologram(eye_user, loc)
H?.move_hologram(eye_user, loc)
/obj/machinery/holopad/remove_eye_control(mob/living/user)
if(user.client)
user.reset_perspective(null)
user.remote_control = null
//this datum manages it's own references
@@ -54,11 +59,6 @@
/datum/holocall/Destroy()
QDEL_NULL(hangup)
var/user_good = !QDELETED(user)
if(user_good)
user.reset_perspective()
user.remote_control = null
if(!QDELETED(eye))
QDEL_NULL(eye)
+1 -1
View File
@@ -32,7 +32,7 @@ GLOBAL_LIST_INIT(huds, list(
/datum/atom_hud
var/list/atom/hudatoms = list() //list of all atoms which display this hud
var/list/mob/hudusers = list() //list with all mobs who can see the hud
var/list/hudusers = list() //list with all mobs who can see the hud
var/list/hud_icons = list() //these will be the indexes for the atom's hud_list
var/list/next_time_allowed = list() //mobs associated with the next time this hud can be added to them
+5 -1
View File
@@ -61,7 +61,6 @@
var/late_joiner = FALSE
var/force_escaped = FALSE // Set by Into The Sunset command of the shuttle manipulator
var/list/learned_recipes //List of learned recipe TYPES.
/datum/mind/New(var/key)
@@ -715,6 +714,11 @@
if(G)
G.reenter_corpse()
/// Sets our can_hijack to the fastest speed our antag datums allow.
/datum/mind/proc/get_hijack_speed()
. = 0
for(var/datum/antagonist/A in antag_datums)
. = max(., A.hijack_speed())
/datum/mind/proc/has_objective(objective_type)
for(var/datum/antagonist/A in antag_datums)
+5 -5
View File
@@ -37,22 +37,22 @@
/datum/map_template/ruin/station/box/engine/teg
id = "engine_teg"
suffix = "Box/Engine/engine_tesla.dmm"
suffix = "Box/Engine/engine_teg.dmm"
name = "Box TEG"
/datum/map_template/ruin/station/box/engine/empty
id = "engine_empty"
suffix = "Box/Engine/engine_tesla.dmm"
suffix = "Box/Engine/empty.dmm"
name = "Box Empty"
/datum/map_template/ruin/station/box/engine/am
id = "engine_am"
suffix = "Box/Engine/engine_tesla.dmm"
suffix = "Box/Engine/engine_am.dmm"
name = "Box Antimatter"
/datum/map_template/ruin/station/box/engine/budget
id = "engine_budget"
suffix = "Box/Engine/engine_tesla.dmm"
suffix = "Box/Engine/budget.dmm"
name = "Box P.A.C.M.A.N"
// Lavaland
@@ -60,4 +60,4 @@
/datum/map_template/ruin/station/lavaland/mining_base
id = "mining_public_01"
suffix = "Lavaland/Mining_Station/Mining_Station_Public_01.dmm"
name = "Public Mining Base"
name = "Public Mining Base"
+4
View File
@@ -1367,3 +1367,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/tcommsat/lounge
name = "Telecommunications Satellite Lounge"
icon_state = "tcomsatlounge"
/area/crew_quarters/fitness/pool
name = "Pool Area"
icon_state = "pool"
-1
View File
@@ -6,7 +6,6 @@
var/flags_1 = NONE
var/interaction_flags_atom = NONE
var/ghost_flags = NONE
var/datum/reagents/reagents = null
//This atom's HUD (med/sec, etc) images. Associative list.
@@ -7,7 +7,7 @@
// LISTS //
var/list/vassal_allowed_antags = list(/datum/antagonist/brother, /datum/antagonist/traitor, /datum/antagonist/traitor/internal_affairs, /datum/antagonist/survivalist, \
/datum/antagonist/rev, /datum/antagonist/nukeop, /datum/antagonist/pirate, /datum/antagonist/cult, /datum/antagonist/abductee)
/datum/antagonist/rev, /datum/antagonist/nukeop, /datum/antagonist/pirate, /datum/antagonist/cult, /datum/antagonist/abductee, /datum/antagonist/valentine, /datum/antagonist/heartbreaker,)
// The antags you're allowed to be if turning Vassal.
/proc/isvamp(mob/living/M)
return istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/bloodsucker)
@@ -279,7 +279,6 @@
internals_req_access = list(ACCESS_SYNDICATE)
wreckage = /obj/structure/mecha_wreckage/honker/dark
max_equip = 3
spawn_tracked = FALSE
/obj/mecha/combat/honker/dark/GrantActions(mob/living/user, human_occupant = 0)
..()
@@ -61,7 +61,7 @@
trimmed_list.Remove(M)
continue
if (M.mind)
if (restrict_ghost_roles && M.mind.assigned_role in GLOB.exp_specialmap[EXP_TYPE_SPECIAL]) // Are they playing a ghost role?
if (restrict_ghost_roles && (M.mind.assigned_role in GLOB.exp_specialmap[EXP_TYPE_SPECIAL])) // Are they playing a ghost role?
trimmed_list.Remove(M)
continue
if (M.mind.assigned_role in restricted_roles) // Does their job allow it?
@@ -57,7 +57,8 @@ Property weights are:
mean += 2.5
if(CHAOS_MAX)
mean += 5
GLOB.dynamic_curve_centre += (mean/voters)
if(voters)
GLOB.dynamic_curve_centre += (mean/voters)
GLOB.dynamic_forced_threat_level = forced_threat_level
/datum/dynamic_storyteller/proc/get_midround_cooldown()
+5 -3
View File
@@ -314,9 +314,11 @@ GLOBAL_LIST_EMPTY(objectives)
/datum/objective/hijack
name = "hijack"
explanation_text = "Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive and out of custody."
team_explanation_text = "Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive and out of custody. Leave no team member behind."
explanation_text = "Hijack the emergency shuttle by hacking its navigational protocols through the control console (alt click emergency shuttle console)."
team_explanation_text = "Hijack the emergency shuttle by hacking its navigational protocols through the control console (alt click emergency shuttle console). Leave no team member behind."
martyr_compatible = 0 //Technically you won't get both anyway.
/// Overrides the hijack speed of any antagonist datum it is on ONLY, no other datums are impacted.
var/hijack_speed_override = 1
/datum/objective/hijack/check_completion() // Requires all owners to escape.
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
@@ -1096,7 +1098,7 @@ GLOBAL_LIST_EMPTY(possible_sabotages)
var/approved_targets = list()
check_sabotages:
for(var/datum/sabotage_objective/possible_sabotage in GLOB.possible_sabotages)
if(!is_unique_objective(possible_sabotage.sabotage_type) || possible_sabotage.check_conditions())
if(!is_unique_objective(possible_sabotage.sabotage_type) || possible_sabotage.check_conditions() || !possible_sabotage.can_run())
continue
for(var/datum/mind/M in owners)
if(M.current.mind.assigned_role in possible_sabotage.excludefromjob)
@@ -12,6 +12,9 @@
/datum/sabotage_objective/proc/check_conditions()
return TRUE
/datum/sabotage_objective/proc/can_run()
return TRUE
/datum/sabotage_objective/processing
var/won = FALSE
@@ -79,6 +82,9 @@
won = max(1-((S.get_integrity()-50)/50),won)
return FALSE
/datum/sabotage_objective/processing/supermatter/can_run()
return (locate(/obj/machinery/power/supermatter_crystal) in GLOB.machines)
/datum/sabotage_objective/station_integrity
name = "Make sure the station is at less than 80% integrity by the end. Smash walls, windows etc. to reach this goal."
sabotage_type = "integrity"
+1 -1
View File
@@ -264,7 +264,7 @@
if(blood_id)
data["occupant"]["blood"] = list() // We can start populating this list.
var/blood_type = C.dna.blood_type
if(blood_id != "blood") // special blood substance
if(!(blood_id in GLOB.blood_reagent_types)) // special blood substance
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
if(R)
blood_type = R.name
+1 -1
View File
@@ -242,7 +242,7 @@ Class Procs:
else
if(interaction_flags_machine & INTERACT_MACHINE_REQUIRES_SILICON)
return FALSE
if(!Adjacent(user) && !isobserver(user))
if(!Adjacent(user))
var/mob/living/carbon/H = user
if(!(istype(H) && H.has_dna() && H.dna.check_mutation(TK)))
return FALSE
+9
View File
@@ -17,6 +17,7 @@
var/list/L = list()
var/list/LL = list()
var/hacked = FALSE
var/hackable = TRUE
var/disabled = 0
var/shocked = FALSE
var/hack_wire
@@ -371,6 +372,8 @@
/obj/machinery/autolathe/proc/adjust_hacked(state)
hacked = state
if(!hackable && hacked)
return
for(var/id in SSresearch.techweb_designs)
var/datum/design/D = SSresearch.techweb_design_by_id(id)
if((D.build_type & AUTOLATHE) && ("hacked" in D.category))
@@ -383,6 +386,12 @@
. = ..()
adjust_hacked(TRUE)
/obj/machinery/autolathe/secure
name = "secured autolathe"
desc = "An autolathe reprogrammed with security protocols to prevent hacking."
hackable = FALSE
circuit = /obj/item/circuitboard/machine/autolathe/secure
//Called when the object is constructed by an autolathe
//Has a reference to the autolathe so you can do !!FUN!! things with hacked lathes
/obj/item/proc/autolathe_crafted(obj/machinery/autolathe/A)
+8 -8
View File
@@ -274,20 +274,20 @@
return TRUE
/obj/machinery/bloodbankgen/proc/detachinput()
/obj/machinery/bloodbankgen/proc/detachinput(mob/user)
if(bag)
bag.forceMove(drop_location())
if(usr && Adjacent(usr) && !issiliconoradminghost(usr))
usr.put_in_hands(bag)
if(user && Adjacent(usr) && user.can_hold_items())
user.put_in_hands(bag)
bag = null
draining = null
update_icon()
/obj/machinery/bloodbankgen/proc/detachoutput()
/obj/machinery/bloodbankgen/proc/detachoutput(mob/user)
if(outbag)
outbag.forceMove(drop_location())
if(usr && Adjacent(usr) && !issiliconoradminghost(usr))
usr.put_in_hands(outbag)
if(user && Adjacent(user) && user.can_hold_items())
user.put_in_hands(outbag)
outbag = null
filling = null
update_icon()
@@ -325,12 +325,12 @@
activateinput()
else if(href_list["detachinput"])
detachinput()
detachinput(usr)
else if(href_list["activateoutput"])
activateoutput()
else if(href_list["detachoutput"])
detachoutput()
detachoutput(usr)
updateUsrDialog()
@@ -47,7 +47,10 @@
jump_action.Grant(user)
actions += jump_action
/obj/machinery/computer/camera_advanced/proc/remove_eye_control(mob/living/user)
/obj/machinery/proc/remove_eye_control(mob/living/user)
CRASH("[type] does not implement ai eye handling")
/obj/machinery/computer/camera_advanced/remove_eye_control(mob/living/user)
if(!user)
return
for(var/V in actions)
@@ -69,7 +72,7 @@
playsound(src, 'sound/machines/terminal_off.ogg', 25, 0)
/obj/machinery/computer/camera_advanced/check_eye(mob/user)
if( (stat & (NOPOWER|BROKEN)) || (!Adjacent(user) && !user.has_unlimited_silicon_privilege) || user.eye_blind || user.incapacitated() )
if( (stat & (NOPOWER|BROKEN)) || (!Adjacent(user) && hasSiliconAccessInArea(user)) || user.eye_blind || user.incapacitated() )
user.unset_machine()
/obj/machinery/computer/camera_advanced/Destroy()
@@ -157,7 +160,7 @@
var/cooldown = 0
var/acceleration = 1
var/mob/living/eye_user = null
var/obj/machinery/computer/camera_advanced/origin
var/obj/machinery/origin
var/eye_initialized = 0
var/visible_icon = 0
var/image/user_image = null
@@ -170,7 +173,7 @@
/mob/camera/aiEye/remote/Destroy()
if(origin && eye_user)
origin.remove_eye_control(eye_user)
origin.remove_eye_control(eye_user,src)
origin = null
. = ..()
eye_user = null
+45 -55
View File
@@ -6,7 +6,6 @@
* ~ Zuhayr
*/
//Main cryopod console.
/obj/machinery/computer/cryopod
@@ -18,7 +17,6 @@
density = FALSE
interaction_flags_machine = INTERACT_MACHINE_OFFLINE
req_one_access = list(ACCESS_HEADS, ACCESS_ARMORY) //Heads of staff or the warden can go here to claim recover items from their department that people went were cryodormed with.
var/mode = null
var/menu = 1 //Which menu screen to display
@@ -118,7 +116,7 @@
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
I.forceMove(drop_location())
if(user && Adjacent(user) && !issiliconoradminghost(user))
if(user && Adjacent(user) && user.can_hold_items())
user.put_in_hands(I)
frozen_items -= I
updateUsrDialog()
@@ -130,7 +128,8 @@
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
updateUsrDialog()
return
if(!allow_items) return
if(!allow_items)
return
if(frozen_items.len == 0)
to_chat(user, "<span class='notice'>There is nothing to recover from storage.</span>")
@@ -182,7 +181,7 @@
var/last_no_computer_message = 0
// These items are preserved when the process() despawn proc occurs.
var/list/preserve_items = list(
var/static/list/preserve_items = typecacheof(list(
/obj/item/hand_tele,
/obj/item/card/id/captains_spare,
/obj/item/aicard,
@@ -203,9 +202,9 @@
/obj/item/tank/jetpack,
/obj/item/documents,
/obj/item/nuke_core_container
)
))
// These items will NOT be preserved
var/list/do_not_preserve_items = list (
var/static/list/do_not_preserve_items = typecacheof(list(
/obj/item/mmi/posibrain,
/obj/item/gun/energy/laser/mounted,
/obj/item/gun/energy/e_gun/advtaser/mounted,
@@ -215,7 +214,7 @@
/obj/item/gun/energy/printer,
/obj/item/gun/energy/kinetic_accelerator/cyborg,
/obj/item/gun/energy/laser/cyborg
)
))
/obj/machinery/cryopod/Initialize(mapload)
. = ..()
@@ -287,14 +286,14 @@
#define CRYO_DESTROY 0
#define CRYO_PRESERVE 1
#define CRYO_OBJECTIVE 2
#define CRYO_IGNORE 3
/obj/machinery/cryopod/proc/should_preserve_item(obj/item/I)
for(var/datum/objective_item/steal/T in control_computer.theft_cache)
if(istype(I, T.targetitem) && T.check_special_completion(I))
return CRYO_OBJECTIVE
for(var/T in preserve_items)
if(istype(I, T) && !(I.type in do_not_preserve_items))
return CRYO_PRESERVE
if(preserve_items[I] && !do_not_preserve_items[I])
return CRYO_PRESERVE
return CRYO_DESTROY
// This function can not be undone; do not call this unless you are sure
@@ -303,52 +302,47 @@
find_control_computer()
var/mob/living/mob_occupant = occupant
var/list/obj/item/cryo_items = list()
//Handle Borg stuff first
if(iscyborg(mob_occupant))
var/mob/living/silicon/robot/R = mob_occupant
R.contents -= R.mmi
qdel(R.mmi)
if(R.mmi?.brain)
cryo_items[R.mmi] = CRYO_IGNORE
cryo_items[R.mmi.brain] = CRYO_IGNORE
for(var/obj/item/I in R.module) // the tools the borg has; metal, glass, guns etc
for(var/obj/item/O in I) // the things inside the tools, if anything; mainly for janiborg trash bags
if(should_preserve_item(O) != CRYO_DESTROY) // Preserve important things inside the item
continue
cryo_items[O] = should_preserve_item(O)
O.forceMove(src)
R.module.remove_module(I, TRUE) //delete the module itself so it doesn't transfer over.
//Drop all items into the pod.
for(var/obj/item/I in mob_occupant)
mob_occupant.doUnEquip(I)
I.forceMove(src)
if(cryo_items[I] == CRYO_IGNORE)
continue
cryo_items[I] = should_preserve_item(I)
mob_occupant.transferItemToLoc(I, src, TRUE)
if(I.contents.len) //Make sure we catch anything not handled by qdel() on the items.
if(should_preserve_item(I) != CRYO_DESTROY) // Don't remove the contents of things that need preservation
if(cryo_items[I] != CRYO_DESTROY) // Don't remove the contents of things that need preservation
continue
for(var/obj/item/O in I.contents)
if(istype(O, /obj/item/tank)) //Stop eating pockets, you fuck!
continue
cryo_items[O] = should_preserve_item(O)
O.forceMove(src)
//Delete all items not on the preservation list.
var/list/items = contents
items -= mob_occupant // Don't delete the occupant
for(var/obj/item/I in items)
if(istype(I, /obj/item/pda))
var/obj/item/pda/P = I
QDEL_NULL(P.id)
qdel(P)
for(var/A in cryo_items)
var/obj/item/I = A
if(QDELETED(I)) //edge cases and DROPDEL.
continue
var/preserve = should_preserve_item(I)
if(preserve == CRYO_DESTROY)
var/preserve = cryo_items[I]
if(preserve == CRYO_IGNORE)
continue
else if(preserve == CRYO_DESTROY)
qdel(I)
else if(control_computer && control_computer.allow_items)
else if(control_computer?.allow_items)
control_computer.frozen_items += I
if(preserve == CRYO_OBJECTIVE)
control_computer.objective_items += I
I.loc = null
I.moveToNullspace()
else
I.forceMove(loc)
@@ -417,6 +411,7 @@
#undef CRYO_DESTROY
#undef CRYO_PRESERVE
#undef CRYO_OBJECTIVE
#undef CRYO_IGNORE
/obj/machinery/cryopod/MouseDrop_T(mob/living/target, mob/user)
if(!istype(target) || user.incapacitated() || !target.Adjacent(user) || !Adjacent(user) || !ismob(target) || (!ishuman(user) && !iscyborg(user)) || !istype(user.loc, /turf) || target.buckled)
@@ -443,29 +438,24 @@
var/generic_plsnoleave_message = " Please adminhelp before leaving the round, even if there are no administrators online!"
if(target == user && world.time - target.client.cryo_warned > 5 MINUTES)//if we haven't warned them in the last 5 minutes
var/caught = FALSE
var/list/caught_string
var/addendum = ""
if(target.mind.assigned_role in GLOB.command_positions)
alert("<span class='userdanger'>You're a Head of Staff![generic_plsnoleave_message] Be sure to put your locker items back into your locker!</span>")
caught = TRUE
LAZYADD(caught_string, "Head of Staff")
addendum = " Be sure to put your locker items back into your locker!"
if(iscultist(target) || is_servant_of_ratvar(target))
to_chat(target, "<span class='userdanger'>You're a Cultist![generic_plsnoleave_message]</span>")
caught = TRUE
LAZYADD(caught_string, "Cultist")
if(is_devil(target))
alert("<span class='userdanger'>You're a Devil![generic_plsnoleave_message]</span>")
caught = TRUE
if(istype(SSticker.mode, /datum/antagonist/gang))
if(target.mind.has_antag_datum(/datum/antagonist/gang))
alert("<span class='userdanger'>You're a Gangster![generic_plsnoleave_message]</span>")
caught = TRUE
if(istype(SSticker.mode, /datum/antagonist/rev))
if(target.mind.has_antag_datum(/datum/antagonist/rev/head))
alert("<span class='userdanger'>You're a Head Revolutionary![generic_plsnoleave_message]</span>")
caught = TRUE
else if(target.mind.has_antag_datum(/datum/antagonist/rev))
alert("<span class='userdanger'>You're a Revolutionary![generic_plsnoleave_message]</span>")
caught = TRUE
LAZYADD(caught_string, "Devil")
if(target.mind.has_antag_datum(/datum/antagonist/gang))
LAZYADD(caught_string, "Gangster")
if(target.mind.has_antag_datum(/datum/antagonist/rev/head))
LAZYADD(caught_string, "Head Revolutionary")
if(target.mind.has_antag_datum(/datum/antagonist/rev))
LAZYADD(caught_string, "Revolutionary")
if(caught)
if(caught_string)
alert(target, "You're a [english_list(caught_string)]![generic_plsnoleave_message][addendum]")
target.client.cryo_warned = world.time
return
+2
View File
@@ -202,6 +202,8 @@
for(var/i in 1 to 10)
spawn_atom_to_turf(/obj/effect/temp_visual/hierophant/telegraph/edge, src, 1, FALSE)
sleep(5)
if(QDELETED(src))
return
#define DISCO_INFENO_RANGE (rand(85, 115)*0.01)
+1 -1
View File
@@ -71,7 +71,7 @@
say("Subject may not have abiotic items on.")
playsound(src, 'sound/machines/buzz-sigh.ogg', 30, 1)
return
if(!(MOB_ORGANIC in C.mob_biotypes))
if(!(C.mob_biotypes & MOB_ORGANIC))
say("Subject is not organic.")
playsound(src, 'sound/machines/buzz-sigh.ogg', 30, 1)
return
+1 -1
View File
@@ -184,7 +184,7 @@
if(usr.incapacitated())
return
if(beaker)
if(usr && Adjacent(usr) && !issiliconoradminghost(usr))
if(usr && Adjacent(usr) && usr.can_hold_items())
if(!usr.put_in_hands(beaker))
beaker.forceMove(drop_location())
beaker = null
+1 -1
View File
@@ -79,7 +79,7 @@
try_detonate(TRUE)
//Counter terrorists win
else if(!active || defused)
if(defused && payload in src)
if(defused && (payload in src))
payload.defuse()
countdown.stop()
STOP_PROCESSING(SSfastprocess, src)
@@ -33,7 +33,7 @@
for(var/obj/machinery/telecomms/hub/H in links)
for(var/obj/machinery/telecomms/relay/R in H.links)
if(R.can_receive(signal) && R.z in signal.levels)
if(R.can_receive(signal) && (R.z in signal.levels))
return TRUE
return FALSE
+5 -5
View File
@@ -3,9 +3,9 @@
internal_damage_threshold = 50
armor = list("melee" = 30, "bullet" = 30, "laser" = 15, "energy" = 20, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
mouse_pointer = 'icons/mecha/mecha_mouse.dmi'
var/spawn_tracked = TRUE
/obj/mecha/combat/Initialize()
. = ..()
if(spawn_tracked)
trackers += new /obj/item/mecha_parts/mecha_tracking(src)
/obj/mecha/combat/proc/max_ammo() //Max the ammo stored for Nuke Ops mechs, or anyone else that calls this
for(var/obj/item/I in equipment)
if(istype(I, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/))
var/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/gun = I
gun.projectiles_cache = gun.projectiles_cache_max
+1 -1
View File
@@ -30,7 +30,6 @@
internals_req_access = list(ACCESS_SYNDICATE)
wreckage = /obj/structure/mecha_wreckage/gygax/dark
max_equip = 4
spawn_tracked = FALSE
/obj/mecha/combat/gygax/dark/loaded/Initialize()
. = ..()
@@ -42,6 +41,7 @@
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay
ME.attach(src)
max_ammo()
/obj/mecha/combat/gygax/dark/add_cell(obj/item/stock_parts/cell/C=null)
if(C)
+3 -1
View File
@@ -17,7 +17,6 @@
force = 45
max_equip = 4
bumpsmash = 1
spawn_tracked = FALSE
/obj/mecha/combat/marauder/GrantActions(mob/living/user, human_occupant = 0)
..()
@@ -41,6 +40,7 @@
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
ME.attach(src)
max_ammo()
/obj/mecha/combat/marauder/seraph
desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel."
@@ -68,6 +68,7 @@
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
ME.attach(src)
max_ammo()
/obj/mecha/combat/marauder/mauler
desc = "Heavy-duty, combat exosuit, developed off of the existing Marauder model."
@@ -90,5 +91,6 @@
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
ME.attach(src)
max_ammo()
-1
View File
@@ -15,7 +15,6 @@
internals_req_access = list()
add_req_access = 0
wreckage = /obj/structure/mecha_wreckage/durand/neovgre
spawn_tracked = FALSE
/obj/mecha/combat/neovgre/GrantActions(mob/living/user, human_occupant = 0) //No Eject action for you sonny jim, your life for Ratvar!
internals_action.Grant(user, src)
-1
View File
@@ -19,7 +19,6 @@
stepsound = null
turnsound = null
opacity = 0
spawn_tracked = FALSE
/obj/mecha/combat/reticence/loaded/Initialize()
. = ..()
@@ -108,16 +108,17 @@
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/Topic(href,href_list)
..()
var/datum/topic_input/afilter = new /datum/topic_input(href,href_list)
if(afilter.get("eject"))
if(href_list["eject"])
go_out()
if(afilter.get("view_stats"))
if(href_list["view_stats"])
chassis.occupant << browse(get_patient_stats(),"window=msleeper")
onclose(chassis.occupant, "msleeper")
return
if(afilter.get("inject"))
inject_reagent(afilter.getType("inject", /datum/reagent),afilter.getObj("source"))
return
if(href_list["inject"])
var/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/SG = locate() in chassis
var/datum/reagent/R = locate(href_list["inject"]) in SG.reagents.reagent_list
if (istype(R))
inject_reagent(R, SG)
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_stats()
if(!patient)
@@ -354,19 +355,18 @@
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Topic(href,href_list)
..()
var/datum/topic_input/afilter = new (href,href_list)
if(afilter.get("toggle_mode"))
if (href_list["toggle_mode"])
mode = !mode
update_equip_info()
return
if(afilter.get("select_reagents"))
if (href_list["select_reagents"])
processed_reagents.len = 0
var/m = 0
var/message
for(var/i=1 to known_reagents.len)
if(m>=synth_speed)
break
var/reagent = afilter.get("reagent_[i]")
var/reagent = text2path(href_list["reagent_[i]"])
if(reagent && (reagent in known_reagents))
message = "[m ? ", " : null][known_reagents[reagent]]"
processed_reagents += reagent
@@ -375,20 +375,18 @@
message += " added to production"
START_PROCESSING(SSobj, src)
occupant_message(message)
occupant_message("Reagent processing started.")
occupant_message("<span class='notice'>Reagent processing started.</span>")
mecha_log_message("Reagent processing started.")
return
if(afilter.get("show_reagents"))
if (href_list["show_reagents"])
chassis.occupant << browse(get_reagents_page(),"window=msyringegun")
if(afilter.get("purge_reagent"))
var/reagent = afilter.get("purge_reagent")
if (href_list["purge_reagent"])
var/reagent = href_list["purge_reagent"]
if(reagent)
reagents.del_reagent(reagent)
return
if(afilter.get("purge_all"))
if (href_list["purge_all"])
reagents.clear_reagents()
return
return
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/get_reagents_page()
var/output = {"<html>
@@ -34,6 +34,19 @@
return
if(!cargo_holder)
return
if(ismecha(target))
var/obj/mecha/M = target
var/have_ammo
for(var/obj/item/mecha_ammo/box in cargo_holder.cargo)
if(istype(box, /obj/item/mecha_ammo) && box.rounds)
have_ammo = TRUE
if(M.ammo_resupply(box, chassis.occupant, TRUE))
return
if(have_ammo)
to_chat(chassis.occupant, "No further supplies can be provided to [M].")
else
to_chat(chassis.occupant, "No providable supplies found in cargo hold")
return
if(isobj(target))
var/obj/O = target
if(!O.anchored)
@@ -0,0 +1,94 @@
/obj/item/mecha_ammo
name = "generic ammo box"
desc = "A box of ammo for an unknown weapon."
w_class = WEIGHT_CLASS_BULKY
icon = 'icons/mecha/mecha_ammo.dmi'
icon_state = "empty"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
var/rounds = 0
var/round_term = "round"
var/direct_load //For weapons where we re-load the weapon itself rather than adding to the ammo storage.
var/load_audio = "sound/weapons/gun_magazine_insert_empty_1.ogg"
var/ammo_type
/obj/item/mecha_ammo/proc/update_name()
if(!rounds)
name = "empty ammo box"
desc = "An exosuit ammuniton box that has since been emptied. Please recycle."
icon_state = "empty"
/obj/item/mecha_ammo/attack_self(mob/user)
..()
if(rounds)
to_chat(user, "<span class='warning'>You cannot flatten the ammo box until it's empty!</span>")
return
to_chat(user, "<span class='notice'>You fold [src] flat.</span>")
var/I = new /obj/item/stack/sheet/metal(user.loc)
qdel(src)
user.put_in_hands(I)
/obj/item/mecha_ammo/examine(mob/user)
. = ..()
if(rounds)
. += "There [rounds > 1?"are":"is"] [rounds] [round_term][rounds > 1?"s":""] left."
/obj/item/mecha_ammo/incendiary
name = "incendiary ammo"
desc = "A box of incendiary ammunition for use with exosuit weapons."
icon_state = "incendiary"
rounds = 24
ammo_type = "incendiary"
/obj/item/mecha_ammo/scattershot
name = "scattershot ammo"
desc = "A box of scaled-up buckshot, for use in exosuit shotguns."
icon_state = "scattershot"
rounds = 40
ammo_type = "scattershot"
/obj/item/mecha_ammo/lmg
name = "machine gun ammo"
desc = "A box of linked ammunition, designed for the Ultra AC 2 exosuit weapon."
icon_state = "lmg"
rounds = 300
ammo_type = "lmg"
/obj/item/mecha_ammo/missiles_br
name = "breaching missiles"
desc = "A box of large missiles, ready for loading into a BRM-6 exosuit missile rack."
icon_state = "missile_br"
rounds = 6
round_term = "missile"
direct_load = TRUE
load_audio = "sound/weapons/bulletinsert.ogg"
ammo_type = "missiles_br"
/obj/item/mecha_ammo/missiles_he
name = "anti-armor missiles"
desc = "A box of large missiles, ready for loading into an SRM-8 exosuit missile rack."
icon_state = "missile_he"
rounds = 8
round_term = "missile"
direct_load = TRUE
load_audio = "sound/weapons/bulletinsert.ogg"
ammo_type = "missiles_he"
/obj/item/mecha_ammo/flashbang
name = "launchable flashbangs"
desc = "A box of smooth flashbangs, for use with a large exosuit launcher. Cannot be primed by hand."
icon_state = "flashbang"
rounds = 6
round_term = "grenade"
ammo_type = "flashbang"
/obj/item/mecha_ammo/clusterbang
name = "launchable flashbang clusters"
desc = "A box of clustered flashbangs, for use with a specialized exosuit cluster launcher. Cannot be primed by hand."
icon_state = "clusterbang"
rounds = 3
round_term = "cluster"
direct_load = TRUE
ammo_type = "clusterbang"
+62 -16
View File
@@ -196,7 +196,11 @@
name = "general ballistic weapon"
fire_sound = 'sound/weapons/gunshot.ogg'
var/projectiles
var/projectiles_cache //ammo to be loaded in, if possible.
var/projectiles_cache_max
var/projectile_energy_cost
var/disabledreload //For weapons with no cache (like the rockets) which are reloaded by hand
var/ammo_type
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_shot_amount()
return min(projectiles, projectiles_per_shot)
@@ -209,19 +213,31 @@
return 1
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_equip_info()
return "[..()] \[[src.projectiles]\][(src.projectiles < initial(src.projectiles))?" - <a href='?src=[REF(src)];rearm=1'>Rearm</a>":null]"
return "[..()] \[[src.projectiles][projectiles_cache_max &&!projectile_energy_cost?"/[projectiles_cache]":""]\][!disabledreload &&(src.projectiles < initial(src.projectiles))?" - <a href='?src=[REF(src)];rearm=1'>Rearm</a>":null]"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/rearm()
if(projectiles < initial(projectiles))
var/projectiles_to_add = initial(projectiles) - projectiles
while(chassis.get_charge() >= projectile_energy_cost && projectiles_to_add)
projectiles++
projectiles_to_add--
chassis.use_power(projectile_energy_cost)
send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info())
mecha_log_message("Rearmed [src.name].")
return 1
if(projectile_energy_cost)
while(chassis.get_charge() >= projectile_energy_cost && projectiles_to_add)
projectiles++
projectiles_to_add--
chassis.use_power(projectile_energy_cost)
else
if(!projectiles_cache)
return FALSE
if(projectiles_to_add <= projectiles_cache)
projectiles = projectiles + projectiles_to_add
projectiles_cache = projectiles_cache - projectiles_to_add
else
projectiles = projectiles + projectiles_cache
projectiles_cache = 0
send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info())
return TRUE
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/needs_rearm()
@@ -249,8 +265,10 @@
equip_cooldown = 10
projectile = /obj/item/projectile/bullet/incendiary/fnx99
projectiles = 24
projectile_energy_cost = 15
projectiles_cache = 24
projectiles_cache_max = 96
harmful = TRUE
ammo_type = "incendiary"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced
name = "\improper S.H.H. \"Quietus\" Carbine"
@@ -270,10 +288,12 @@
equip_cooldown = 20
projectile = /obj/item/projectile/bullet/scattershot
projectiles = 40
projectile_energy_cost = 25
projectiles_cache = 40
projectiles_cache_max = 160
projectiles_per_shot = 4
variance = 25
harmful = TRUE
ammo_type = "scattershot"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/seedscatter
name = "\improper Melon Seed \"Scattershot\""
@@ -282,10 +302,12 @@
equip_cooldown = 20
projectile = /obj/item/projectile/bullet/seed
projectiles = 20
projectile_energy_cost = 25
projectiles_cache = 20
projectiles_cache_max = 160
projectiles_per_shot = 10
variance = 25
harmful = TRUE
ammo_type = "scattershot"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg
name = "\improper Ultra AC 2"
@@ -294,23 +316,42 @@
equip_cooldown = 10
projectile = /obj/item/projectile/bullet/lmg
projectiles = 300
projectile_energy_cost = 20
projectiles_cache = 300
projectiles_cache_max = 1200
projectiles_per_shot = 3
variance = 6
randomspread = 1
projectile_delay = 2
harmful = TRUE
ammo_type = "lmg"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack
name = "\improper SRM-8 missile rack"
desc = "A weapon for combat exosuits. Shoots light explosive missiles."
desc = "A weapon for combat exosuits. Launches light explosive missiles."
icon_state = "mecha_missilerack"
projectile = /obj/item/projectile/bullet/a84mm_he
fire_sound = 'sound/weapons/grenadelaunch.ogg'
projectiles = 8
projectile_energy_cost = 1000
projectiles_cache = 0
projectiles_cache_max = 0
disabledreload = TRUE
equip_cooldown = 60
harmful = TRUE
ammo_type = "missiles_he"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/breaching
name = "\improper BRM-6 missile rack"
desc = "A weapon for combat exosuits. Launches low-explosive breaching missiles designed to explode only when striking a sturdy target."
icon_state = "mecha_missilerack_six"
projectile = /obj/item/projectile/bullet/a84mm_br
fire_sound = 'sound/weapons/grenadelaunch.ogg'
projectiles = 6
projectiles_cache = 0
projectiles_cache_max = 0
disabledreload = TRUE
equip_cooldown = 60
harmful = TRUE
ammo_type = "missiles_br"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher
@@ -341,10 +382,12 @@
projectile = /obj/item/grenade/flashbang
fire_sound = 'sound/weapons/grenadelaunch.ogg'
projectiles = 6
projectiles_cache = 6
projectiles_cache_max = 24
missile_speed = 1.5
projectile_energy_cost = 800
equip_cooldown = 60
var/det_time = 20
ammo_type = "flashbang"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/proj_init(var/obj/item/grenade/flashbang/F)
var/turf/T = get_turf(src)
@@ -356,9 +399,12 @@
name = "\improper SOB-3 grenade launcher"
desc = "A weapon for combat exosuits. Launches primed clusterbangs. You monster."
projectiles = 3
projectiles_cache = 0
projectiles_cache_max = 0
disabledreload = TRUE
projectile = /obj/item/grenade/clusterbuster
projectile_energy_cost = 1600 //getting off cheap seeing as this is 3 times the flashbangs held in the grenade launcher.
equip_cooldown = 90
ammo_type = "clusterbang"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar
name = "banana mortar"
+9 -9
View File
@@ -29,6 +29,7 @@
"H.O.N.K",
"Phazon",
"Exosuit Equipment",
"Exosuit Ammunition",
"Cyborg Upgrade Modules",
"Misc"
)
@@ -317,9 +318,8 @@
/obj/machinery/mecha_part_fabricator/Topic(href, href_list)
if(..())
return
var/datum/topic_input/afilter = new /datum/topic_input(href,href_list)
if(href_list["part_set"])
var/tpart_set = afilter.getStr("part_set")
var/tpart_set = href_list["part_set"]
if(tpart_set)
if(tpart_set=="clear")
part_set = null
@@ -327,7 +327,7 @@
part_set = tpart_set
screen = "parts"
if(href_list["part"])
var/T = afilter.getStr("part")
var/T = href_list["part"]
for(var/v in stored_research.researched_designs)
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(D.build_type & MECHFAB)
@@ -338,7 +338,7 @@
add_to_queue(D)
break
if(href_list["add_to_queue"])
var/T = afilter.getStr("add_to_queue")
var/T = href_list["add_to_queue"]
for(var/v in stored_research.researched_designs)
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(D.build_type & MECHFAB)
@@ -347,10 +347,10 @@
break
return update_queue_on_page()
if(href_list["remove_from_queue"])
remove_from_queue(afilter.getNum("remove_from_queue"))
remove_from_queue(text2num(href_list["remove_from_queue"]))
return update_queue_on_page()
if(href_list["partset_to_queue"])
add_part_set_to_queue(afilter.get("partset_to_queue"))
add_part_set_to_queue(href_list["partset_to_queue"])
return update_queue_on_page()
if(href_list["process_queue"])
spawn(0)
@@ -364,8 +364,8 @@
if(href_list["screen"])
screen = href_list["screen"]
if(href_list["queue_move"] && href_list["index"])
var/index = afilter.getNum("index")
var/new_index = index + afilter.getNum("queue_move")
var/index = text2num(href_list["index"])
var/new_index = index + text2num(href_list["queue_move"])
if(isnum(index) && isnum(new_index) && ISINTEGER(index) && ISINTEGER(new_index))
if(ISINRANGE(new_index,1,queue.len))
queue.Swap(index,new_index)
@@ -376,7 +376,7 @@
if(href_list["sync"])
sync()
if(href_list["part_desc"])
var/T = afilter.getStr("part_desc")
var/T = href_list["part_desc"]
for(var/v in stored_research.researched_designs)
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(D.build_type & MECHFAB)
+51 -1
View File
@@ -867,7 +867,7 @@
return
/obj/mecha/proc/moved_inside(mob/living/carbon/human/H)
if(H && H.client && H in range(1))
if(H?.client && (H in range(1)))
occupant = H
H.forceMove(src)
H.update_mouse_pointer()
@@ -1070,3 +1070,53 @@
if(occupant_sight_flags)
if(user == occupant)
user.sight |= occupant_sight_flags
///////////////////////
////// Ammo stuff /////
///////////////////////
/obj/mecha/proc/ammo_resupply(var/obj/item/mecha_ammo/A, mob/user,var/fail_chat_override = FALSE)
if(!A.rounds)
if(!fail_chat_override)
to_chat(user, "<span class='warning'>This box of ammo is empty!</span>")
return FALSE
var/ammo_needed
var/found_gun
for(var/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/gun in equipment)
ammo_needed = 0
if(istype(gun, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic) && gun.ammo_type == A.ammo_type)
found_gun = TRUE
if(A.direct_load)
ammo_needed = initial(gun.projectiles) - gun.projectiles
else
ammo_needed = gun.projectiles_cache_max - gun.projectiles_cache
if(ammo_needed)
if(ammo_needed < A.rounds)
if(A.direct_load)
gun.projectiles = gun.projectiles + ammo_needed
else
gun.projectiles_cache = gun.projectiles_cache + ammo_needed
playsound(get_turf(user),A.load_audio,50,1)
to_chat(user, "<span class='notice'>You add [ammo_needed] [A.round_term][ammo_needed > 1?"s":""] to the [gun.name]</span>")
A.rounds = A.rounds - ammo_needed
A.update_name()
return TRUE
else
if(A.direct_load)
gun.projectiles = gun.projectiles + A.rounds
else
gun.projectiles_cache = gun.projectiles_cache + A.rounds
playsound(get_turf(user),A.load_audio,50,1)
to_chat(user, "<span class='notice'>You add [A.rounds] [A.round_term][A.rounds > 1?"s":""] to the [gun.name]</span>")
A.rounds = 0
A.update_name()
return TRUE
if(!fail_chat_override)
if(found_gun)
to_chat(user, "<span class='notice'>You can't fit any more ammo of this type!</span>")
else
to_chat(user, "<span class='notice'>None of the equipment on this exosuit can use this ammo!</span>")
return FALSE
+231 -48
View File
@@ -116,7 +116,7 @@
//9
list(
"key" = /obj/item/stock_parts/cell,
"key" = /obj/item/stock_parts/scanning_module,
"action" = ITEM_MOVE_INSIDE,
"back_key" = TOOL_SCREWDRIVER,
"desc" = "Peripherals control module is secured."
@@ -126,10 +126,40 @@
list(
"key" = TOOL_SCREWDRIVER,
"back_key" = TOOL_CROWBAR,
"desc" = "The power cell is installed."
"desc" = "The scanner module is installed."
),
//11
list(
"key" = /obj/item/stock_parts/capacitor,
"action" = ITEM_MOVE_INSIDE,
"back_key" = TOOL_SCREWDRIVER,
"desc" = "Scanner module is secured."
),
//12
list(
"key" = TOOL_SCREWDRIVER,
"back_key" = TOOL_CROWBAR,
"desc" = "Capacitor is installed."
),
//13
list(
"key" = /obj/item/stock_parts/cell,
"action" = ITEM_MOVE_INSIDE,
"back_key" = TOOL_SCREWDRIVER,
"desc" = "Capacitor is secured."
),
//14
list(
"key" = TOOL_SCREWDRIVER,
"back_key" = TOOL_CROWBAR,
"desc" = "The power cell is installed."
),
//15
list(
"key" = /obj/item/stack/sheet/metal,
"amount" = 5,
@@ -137,21 +167,21 @@
"desc" = "The power cell is secured."
),
//12
//16
list(
"key" = TOOL_WRENCH,
"back_key" = TOOL_CROWBAR,
"desc" = "Internal armor is installed."
),
//13
//17
list(
"key" = TOOL_WELDER,
"back_key" = TOOL_WRENCH,
"desc" = "Internal armor is wrenched."
),
//14
//18
list(
"key" = /obj/item/stack/sheet/plasteel,
"amount" = 5,
@@ -159,14 +189,14 @@
"desc" = "Internal armor is welded."
),
//15
//19
list(
"key" = TOOL_WRENCH,
"back_key" = TOOL_CROWBAR,
"desc" = "External armor is installed."
),
//16
//20
list(
"key" = TOOL_WELDER,
"back_key" = TOOL_WRENCH,
@@ -222,36 +252,56 @@
else
user.visible_message("[user] unfastens the peripherals control module.", "<span class='notice'>You unfasten the peripherals control module.</span>")
if(10)
if(diff==FORWARD)
user.visible_message("[user] secures the scanner module.", "<span class='notice'>You secure the scanner module.</span>")
else
user.visible_message("[user] removes the scanner module from [parent].", "<span class='notice'>You remove the scanner module from [parent].</span>")
if(11)
if(diff==FORWARD)
user.visible_message("[user] installs [I] to [parent].", "<span class='notice'>You install [I] to [parent].</span>")
else
user.visible_message("[user] unfastens the scanner module.", "<span class='notice'>You unfasten the scanner module.</span>")
if(12)
if(diff==FORWARD)
user.visible_message("[user] secures [I].", "<span class='notice'>You secure [I].</span>")
else
user.visible_message("[user] removes the capacitor from [parent].", "<span class='notice'>You remove the capacitor from [parent].</span>")
if(13)
if(diff==FORWARD)
user.visible_message("[user] installs [I].", "<span class='notice'>You install [I].</span>")
else
user.visible_message("[user] unsecures the capacitor from [parent].", "<span class='notice'>You unsecure the capacitor from [parent].</span>")
if(14)
if(diff==FORWARD)
user.visible_message("[user] secures the power cell.", "<span class='notice'>You secure the power cell.</span>")
else
user.visible_message("[user] pries the power cell from [parent].", "<span class='notice'>You pry the power cell from [parent].</span>")
if(11)
if(15)
if(diff==FORWARD)
user.visible_message("[user] installs the internal armor layer to [parent].", "<span class='notice'>You install the internal armor layer to [parent].</span>")
else
user.visible_message("[user] unfastens the power cell.", "<span class='notice'>You unfasten the power cell.</span>")
if(12)
if(16)
if(diff==FORWARD)
user.visible_message("[user] secures the internal armor layer.", "<span class='notice'>You secure the internal armor layer.</span>")
else
user.visible_message("[user] pries internal armor layer from [parent].", "<span class='notice'>You pry internal armor layer from [parent].</span>")
if(13)
if(17)
if(diff==FORWARD)
user.visible_message("[user] welds the internal armor layer to [parent].", "<span class='notice'>You weld the internal armor layer to [parent].</span>")
else
user.visible_message("[user] unfastens the internal armor layer.", "<span class='notice'>You unfasten the internal armor layer.</span>")
if(14)
if(18)
if(diff==FORWARD)
user.visible_message("[user] installs the external reinforced armor layer to [parent].", "<span class='notice'>You install the external reinforced armor layer to [parent].</span>")
else
user.visible_message("[user] cuts the internal armor layer from [parent].", "<span class='notice'>You cut the internal armor layer from [parent].</span>")
if(15)
if(19)
if(diff==FORWARD)
user.visible_message("[user] secures the external armor layer.", "<span class='notice'>You secure the external reinforced armor layer.</span>")
else
user.visible_message("[user] pries external armor layer from [parent].", "<span class='notice'>You pry external armor layer from [parent].</span>")
if(16)
if(20)
if(diff==FORWARD)
user.visible_message("[user] welds the external armor layer to [parent].", "<span class='notice'>You weld the external armor layer to [parent].</span>")
else
@@ -629,7 +679,7 @@
//9
list(
"key" = /obj/item/stock_parts/cell,
"key" = /obj/item/stock_parts/scanning_module,
"action" = ITEM_MOVE_INSIDE,
"back_key" = TOOL_SCREWDRIVER,
"desc" = "Peripherals control module is secured."
@@ -639,10 +689,40 @@
list(
"key" = TOOL_SCREWDRIVER,
"back_key" = TOOL_CROWBAR,
"desc" = "The power cell is installed."
"desc" = "The scanner module is installed."
),
//11
list(
"key" = /obj/item/stock_parts/capacitor,
"action" = ITEM_MOVE_INSIDE,
"back_key" = TOOL_SCREWDRIVER,
"desc" = "The scanner module is secured."
),
//12
list(
"key" = TOOL_SCREWDRIVER,
"back_key" = TOOL_CROWBAR,
"desc" = "The capacitor is installed."
),
//13
list(
"key" = /obj/item/stock_parts/cell,
"action" = ITEM_MOVE_INSIDE,
"back_key" = TOOL_SCREWDRIVER,
"desc" = "The capacitor is secured."
),
//14
list(
"key" = TOOL_SCREWDRIVER,
"back_key" = TOOL_CROWBAR,
"desc" = "The power cell is installed."
),
//15
list(
"key" = /obj/item/stack/sheet/plasteel,
"amount" = 5,
@@ -650,21 +730,21 @@
"desc" = "The power cell is secured."
),
//12
//16
list(
"key" = TOOL_WRENCH,
"back_key" = TOOL_CROWBAR,
"desc" = "Internal armor is installed."
),
//13
//17
list(
"key" = TOOL_WELDER,
"back_key" = TOOL_WRENCH,
"desc" = "Internal armor is wrenched."
),
//14
//18
list(
"key" = /obj/item/stack/sheet/plasteel,
"amount" = 5,
@@ -672,7 +752,7 @@
"desc" = "Internal armor is welded."
),
//15
//19
list(
"key" = /obj/item/stack/sheet/plasteel,
"amount" = 5,
@@ -680,14 +760,14 @@
"desc" = "External armor is being installed."
),
//16
//20
list(
"key" = TOOL_WRENCH,
"back_key" = TOOL_CROWBAR,
"desc" = "External armor is installed."
),
//17
//21
list(
"key" = TOOL_WELDER,
"back_key" = TOOL_WRENCH,
@@ -744,41 +824,61 @@
else
user.visible_message("[user] unfastens the peripherals control module.", "<span class='notice'>You unfasten the peripherals control module.</span>")
if(10)
if(diff==FORWARD)
user.visible_message("[user] secures the scanner module.", "<span class='notice'>You secure the scanner module.</span>")
else
user.visible_message("[user] removes the scanner module from [parent].", "<span class='notice'>You remove the scanner module from [parent].</span>")
if(12)
if(diff==FORWARD)
user.visible_message("[user] installs [I] to [parent].", "<span class='notice'>You install [I] to [parent].</span>")
else
user.visible_message("[user] unfastens the scanner module.", "<span class='notice'>You unfasten the scanner module.</span>")
if(13)
if(diff==FORWARD)
user.visible_message("[user] secures the capacitor.", "<span class='notice'>You secure the capacitor.</span>")
else
user.visible_message("[user] removes the capacitor from [parent].", "<span class='notice'>You remove the capacitor from [parent].</span>")
if(14)
if(diff==FORWARD)
user.visible_message("[user] installs [I] into [parent].", "<span class='notice'>You install [I] into [parent].</span>")
else
user.visible_message("[user] unfastens the capacitor.", "<span class='notice'>You unfasten the capacitor.</span>")
if(15)
if(diff==FORWARD)
user.visible_message("[user] secures the power cell.", "<span class='notice'>You secure the power cell.</span>")
else
user.visible_message("[user] pries the power cell from [parent].", "<span class='notice'>You pry the power cell from [parent].</span>")
if(11)
if(16)
if(diff==FORWARD)
user.visible_message("[user] installs the internal armor layer to [parent].", "<span class='notice'>You install the internal armor layer to [parent].</span>")
else
user.visible_message("[user] unfastens the power cell.", "<span class='notice'>You unfasten the power cell.</span>")
if(12)
if(17)
if(diff==FORWARD)
user.visible_message("[user] secures the internal armor layer.", "<span class='notice'>You secure the internal armor layer.</span>")
else
user.visible_message("[user] pries internal armor layer from [parent].", "<span class='notice'>You pry internal armor layer from [parent].</span>")
if(13)
if(18)
if(diff==FORWARD)
user.visible_message("[user] welds the internal armor layer to [parent].", "<span class='notice'>You weld the internal armor layer to [parent].</span>")
else
user.visible_message("[user] unfastens the internal armor layer.", "<span class='notice'>You unfasten the internal armor layer.</span>")
if(14)
if(19)
if(diff==FORWARD)
user.visible_message("[user] starts to install the external armor layer to [parent].", "<span class='notice'>You install the external armor layer to [parent].</span>")
else
user.visible_message("[user] cuts the internal armor layer from [parent].", "<span class='notice'>You cut the internal armor layer from [parent].</span>")
if(15)
if(20)
if(diff==FORWARD)
user.visible_message("[user] installs the external reinforced armor layer to [parent].", "<span class='notice'>You install the external reinforced armor layer to [parent].</span>")
else
user.visible_message("[user] removes the external armor from [parent].", "<span class='notice'>You remove the external armor from [parent].</span>")
if(16)
if(21)
if(diff==FORWARD)
user.visible_message("[user] secures the external armor layer.", "<span class='notice'>You secure the external reinforced armor layer.</span>")
else
user.visible_message("[user] pries external armor layer from [parent].", "<span class='notice'>You pry external armor layer from [parent].</span>")
if(17)
if(22)
if(diff==FORWARD)
user.visible_message("[user] welds the external armor layer to [parent].", "<span class='notice'>You weld the external armor layer to [parent].</span>")
else
@@ -796,6 +896,7 @@
/obj/item/mecha_parts/part/honker_head
)
/datum/component/construction/mecha/honker
result = /obj/mecha/combat/honker
steps = list(
@@ -837,41 +938,70 @@
"key" = /obj/item/bikehorn
),
//6
list(
"key" = /obj/item/stock_parts/scanning_module,
"action" = ITEM_MOVE_INSIDE
),
//8
list(
"key" = /obj/item/bikehorn
),
//9
list(
"key" = /obj/item/stock_parts/capacitor,
"action" = ITEM_MOVE_INSIDE
),
//10
list(
"key" = /obj/item/bikehorn
),
//11
list(
"key" = /obj/item/stock_parts/cell,
"action" = ITEM_MOVE_INSIDE
),
//9
//12
list(
"key" = /obj/item/bikehorn
),
//10
//13
list(
"key" = /obj/item/clothing/mask/gas/clown_hat,
"action" = ITEM_DELETE
),
//11
//14
list(
"key" = /obj/item/bikehorn
),
//12
//15
list(
"key" = /obj/item/clothing/shoes/clown_shoes,
"action" = ITEM_DELETE
),
//13
//16
list(
"key" = /obj/item/bikehorn
),
)
// HONK doesn't have any construction step icons, so we just set an icon once.
/datum/component/construction/mecha/honker/update_parent(step_index)
if(step_index == 1)
var/atom/parent_atom = parent
parent_atom.icon = 'icons/mecha/mech_construct.dmi'
parent_atom.icon_state = "honker_chassis"
..()
// HONK doesn't have any construction step icons, so we just set an icon once.
/datum/component/construction/mecha/honker/update_parent(step_index)
if(step_index == 1)
var/atom/parent_atom = parent
@@ -898,8 +1028,12 @@
if(8)
user.visible_message("[user] installs [I] into [parent].", "<span class='notice'>You install [I] into [parent].</span>")
if(10)
user.visible_message("[user] puts [I] on [parent].", "<span class='notice'>You put [I] on [parent].</span>")
user.visible_message("[user] installs [I] into [parent].", "<span class='notice'>You install [I] into [parent].</span>")
if(12)
user.visible_message("[user] installs [I] into [parent].", "<span class='notice'>You install [I] into [parent].</span>")
if(14)
user.visible_message("[user] puts [I] on [parent].", "<span class='notice'>You put [I] on [parent].</span>")
if(16)
user.visible_message("[user] puts [I] on [parent].", "<span class='notice'>You put [I] on [parent].</span>")
return TRUE
@@ -1626,10 +1760,9 @@
"back_key" = TOOL_CROWBAR,
"desc" = "Peripherals control module is installed."
),
//9
list(
"key" = /obj/item/stock_parts/cell,
"key" = /obj/item/stock_parts/scanning_module,
"action" = ITEM_MOVE_INSIDE,
"back_key" = TOOL_SCREWDRIVER,
"desc" = "Peripherals control module is secured."
@@ -1639,10 +1772,40 @@
list(
"key" = TOOL_SCREWDRIVER,
"back_key" = TOOL_CROWBAR,
"desc" = "The power cell is installed."
"desc" = "Scanner module is installed."
),
//11
list(
"key" = /obj/item/stock_parts/capacitor,
"action" = ITEM_MOVE_INSIDE,
"back_key" = TOOL_SCREWDRIVER,
"desc" = "Scanner module is secured."
),
//12
list(
"key" = TOOL_SCREWDRIVER,
"back_key" = TOOL_CROWBAR,
"desc" = "Capacitor is installed."
),
//13
list(
"key" = /obj/item/stock_parts/cell,
"action" = ITEM_MOVE_INSIDE,
"back_key" = TOOL_SCREWDRIVER,
"desc" = "Capacitor is secured."
),
//11
list(
"key" = TOOL_SCREWDRIVER,
"back_key" = TOOL_CROWBAR,
"desc" = "The power cell is installed."
),
//12
list(
"key" = /obj/item/stack/sheet/metal,
"amount" = 5,
@@ -1650,21 +1813,21 @@
"desc" = "The power cell is secured."
),
//12
//13
list(
"key" = TOOL_WRENCH,
"back_key" = TOOL_CROWBAR,
"desc" = "Internal armor is installed."
),
//13
//14
list(
"key" = TOOL_WELDER,
"back_key" = TOOL_WRENCH,
"desc" = "Internal armor is wrenched."
),
//14
//15
list(
"key" = /obj/item/stack/sheet/plasteel,
"amount" = 5,
@@ -1672,14 +1835,14 @@
"desc" = "Internal armor is welded."
),
//15
//16
list(
"key" = TOOL_WRENCH,
"back_key" = TOOL_CROWBAR,
"desc" = "External armor is installed."
),
//16
//17
list(
"key" = TOOL_WELDER,
"back_key" = TOOL_WRENCH,
@@ -1736,36 +1899,56 @@
else
user.visible_message("[user] unfastens the peripherals control module.", "<span class='notice'>You unfasten the peripherals control module.</span>")
if(10)
if(diff==FORWARD)
user.visible_message("[user] secures the scanner module.", "<span class='notice'>You secure the scanner module.</span>")
else
user.visible_message("[user] removes the scanner module from [parent].", "<span class='notice'>You remove the scanner module from [parent].</span>")
if(11)
if(diff==FORWARD)
user.visible_message("[user] installs [I] to [parent].", "<span class='notice'>You install [I] to [parent].</span>")
else
user.visible_message("[user] unfastens the scanner module.", "<span class='notice'>You unfasten the scanner module.</span>")
if(12)
if(diff==FORWARD)
user.visible_message("[user] secures the capacitor.", "<span class='notice'>You secure the capacitor.</span>")
else
user.visible_message("[user] removes the capacitor from [parent].", "<span class='notice'>You remove the capacitor from [parent].</span>")
if(13)
if(diff==FORWARD)
user.visible_message("[user] installs [I] into [parent].", "<span class='notice'>You install [I] into [parent].</span>")
else
user.visible_message("[user] unfastens the capacitor.", "<span class='notice'>You unfasten the capacitor.</span>")
if(14)
if(diff==FORWARD)
user.visible_message("[user] secures the power cell.", "<span class='notice'>You secure the power cell.</span>")
else
user.visible_message("[user] pries the power cell from [parent].", "<span class='notice'>You pry the power cell from [parent].</span>")
if(11)
if(15)
if(diff==FORWARD)
user.visible_message("[user] installs the internal armor layer to [parent].", "<span class='notice'>You install the internal armor layer to [parent].</span>")
else
user.visible_message("[user] unfastens the power cell.", "<span class='notice'>You unfasten the power cell.</span>")
if(12)
if(16)
if(diff==FORWARD)
user.visible_message("[user] secures the internal armor layer.", "<span class='notice'>You secure the internal armor layer.</span>")
else
user.visible_message("[user] pries internal armor layer from [parent].", "<span class='notice'>You pry internal armor layer from [parent].</span>")
if(13)
if(17)
if(diff==FORWARD)
user.visible_message("[user] welds the internal armor layer to [parent].", "<span class='notice'>You weld the internal armor layer to [parent].</span>")
else
user.visible_message("[user] unfastens the internal armor layer.", "<span class='notice'>You unfasten the internal armor layer.</span>")
if(14)
if(18)
if(diff==FORWARD)
user.visible_message("[user] installs the external armor layer to [parent].", "<span class='notice'>You install the external reinforced armor layer to [parent].</span>")
else
user.visible_message("[user] cuts the internal armor layer from [parent].", "<span class='notice'>You cut the internal armor layer from [parent].</span>")
if(15)
if(19)
if(diff==FORWARD)
user.visible_message("[user] secures the external armor layer.", "<span class='notice'>You secure the external reinforced armor layer.</span>")
else
user.visible_message("[user] pries the external armor layer from [parent].", "<span class='notice'>You pry the external armor layer from [parent].</span>")
if(16)
if(20)
if(diff==FORWARD)
user.visible_message("[user] welds the external armor layer to [parent].", "<span class='notice'>You weld the external armor layer to [parent].</span>")
else
+10 -7
View File
@@ -39,21 +39,24 @@
/obj/machinery/computer/mecha/Topic(href, href_list)
if(..())
return
var/datum/topic_input/afilter = new /datum/topic_input(href,href_list)
if(href_list["send_message"])
var/obj/item/mecha_parts/mecha_tracking/MT = afilter.getObj("send_message")
var/obj/item/mecha_parts/mecha_tracking/MT = locate(href_list["send_message"])
if (!istype(MT))
return
var/message = stripped_input(usr,"Input message","Transmit message")
var/obj/mecha/M = MT.in_mecha()
if(trim(message) && M)
M.occupant_message(message)
return
if(href_list["shock"])
var/obj/item/mecha_parts/mecha_tracking/MT = afilter.getObj("shock")
MT.shock()
var/obj/item/mecha_parts/mecha_tracking/MT = locate(href_list["shock"])
if (istype(MT))
MT.shock()
if(href_list["get_log"])
var/obj/item/mecha_parts/mecha_tracking/MT = afilter.getObj("get_log")
stored_data = MT.get_mecha_log()
screen = 1
var/obj/item/mecha_parts/mecha_tracking/MT = locate(href_list["get_log"])
if(istype(MT))
stored_data = MT.get_mecha_log()
screen = 1
if(href_list["return"])
screen = 0
updateUsrDialog()
+4
View File
@@ -172,6 +172,10 @@
to_chat(user, "[src]-[W] interface initialization failed.")
return
if(istype(W, /obj/item/mecha_ammo))
ammo_resupply(W, user)
return
if(istype(W, /obj/item/mecha_parts/mecha_equipment))
var/obj/item/mecha_parts/mecha_equipment/E = W
spawn()
+36 -38
View File
@@ -221,73 +221,71 @@
if(usr.incapacitated())
return
var/datum/topic_input/afilter = new /datum/topic_input(href,href_list)
if(in_range(src, usr))
var/obj/item/card/id/id_card
if (href_list["id_card"])
id_card = locate(href_list["id_card"])
if (!istype(id_card))
return
if(href_list["req_access"] && add_req_access)
output_access_dialog(afilter.getObj("id_card"),afilter.getMob("user"))
output_access_dialog(id_card, usr)
if(href_list["maint_access"] && maint_access)
var/mob/user = afilter.getMob("user")
if(user)
if(state==0)
state = 1
to_chat(user, "The securing bolts are now exposed.")
else if(state==1)
state = 0
to_chat(user, "The securing bolts are now hidden.")
output_maintenance_dialog(afilter.getObj("id_card"),user)
if(state==0)
state = 1
to_chat(usr, "The securing bolts are now exposed.")
else if(state==1)
state = 0
to_chat(usr, "The securing bolts are now hidden.")
output_maintenance_dialog(id_card, usr)
if(href_list["set_internal_tank_valve"] && state >=1)
var/mob/user = afilter.getMob("user")
if(user)
var/new_pressure = input(user,"Input new output pressure","Pressure setting",internal_tank_valve) as num
if(new_pressure)
internal_tank_valve = new_pressure
to_chat(user, "The internal pressure valve has been set to [internal_tank_valve]kPa.")
var/new_pressure = input(usr,"Input new output pressure","Pressure setting",internal_tank_valve) as num
if(new_pressure)
internal_tank_valve = new_pressure
to_chat(usr, "The internal pressure valve has been set to [internal_tank_valve]kPa.")
if(href_list["add_req_access"] && add_req_access && afilter.getObj("id_card"))
operation_req_access += afilter.getNum("add_req_access")
output_access_dialog(afilter.getObj("id_card"),afilter.getMob("user"))
if(href_list["add_req_access"] && add_req_access)
operation_req_access += text2num(href_list["add_req_access"])
output_access_dialog(id_card, usr)
if(href_list["del_req_access"] && add_req_access && afilter.getObj("id_card"))
operation_req_access -= afilter.getNum("del_req_access")
output_access_dialog(afilter.getObj("id_card"),afilter.getMob("user"))
if(href_list["del_req_access"] && add_req_access)
operation_req_access -= text2num(href_list["add_req_access"])
output_access_dialog(id_card, usr)
if(href_list["finish_req_access"])
add_req_access = 0
var/mob/user = afilter.getMob("user")
user << browse(null,"window=exosuit_add_access")
usr << browse(null,"window=exosuit_add_access")
if(usr != occupant)
return
if(href_list["update_content"])
send_byjax(src.occupant,"exosuit.browser","content",src.get_stats_part())
send_byjax(usr,"exosuit.browser","content",src.get_stats_part())
if(href_list["select_equip"])
var/obj/item/mecha_parts/mecha_equipment/equip = afilter.getObj("select_equip")
var/obj/item/mecha_parts/mecha_equipment/equip = locate(href_list["select_equip"]) in src
if(equip && equip.selectable)
src.selected = equip
src.occupant_message("You switch to [equip]")
src.visible_message("[src] raises [equip]")
send_byjax(src.occupant,"exosuit.browser","eq_list",src.get_equipment_list())
selected = equip
occupant_message("You switch to [equip]")
visible_message("[src] raises [equip]")
send_byjax(usr, "exosuit.browser","eq_list", get_equipment_list())
if(href_list["rmictoggle"])
radio.broadcasting = !radio.broadcasting
send_byjax(src.occupant,"exosuit.browser","rmicstate",(radio.broadcasting?"Engaged":"Disengaged"))
send_byjax(usr,"exosuit.browser","rmicstate",(radio.broadcasting?"Engaged":"Disengaged"))
if(href_list["rspktoggle"])
radio.listening = !radio.listening
send_byjax(src.occupant,"exosuit.browser","rspkstate",(radio.listening?"Engaged":"Disengaged"))
send_byjax(usr,"exosuit.browser","rspkstate",(radio.listening?"Engaged":"Disengaged"))
if(href_list["rfreq"])
var/new_frequency = (radio.frequency + afilter.getNum("rfreq"))
var/new_frequency = (radio.frequency + text2num(href_list["rfreq"]))
if (!radio.freerange || (radio.frequency < MIN_FREE_FREQ || radio.frequency > MAX_FREE_FREQ))
new_frequency = sanitize_frequency(new_frequency)
radio.set_frequency(new_frequency)
send_byjax(src.occupant,"exosuit.browser","rfreq","[format_frequency(radio.frequency)]")
send_byjax(usr,"exosuit.browser","rfreq","[format_frequency(radio.frequency)]")
if (href_list["view_log"])
src.occupant << browse(src.get_log_html(), "window=exosuit_log")
@@ -302,14 +300,14 @@
if (href_list["toggle_id_upload"])
add_req_access = !add_req_access
send_byjax(src.occupant,"exosuit.browser","t_id_upload","[add_req_access?"L":"Unl"]ock ID upload panel")
send_byjax(usr,"exosuit.browser","t_id_upload","[add_req_access?"L":"Unl"]ock ID upload panel")
if(href_list["toggle_maint_access"])
if(state)
occupant_message("<span class='danger'>Maintenance protocols in effect</span>")
return
maint_access = !maint_access
send_byjax(src.occupant,"exosuit.browser","t_maint_access","[maint_access?"Forbid":"Permit"] maintenance protocols")
send_byjax(usr,"exosuit.browser","t_maint_access","[maint_access?"Forbid":"Permit"] maintenance protocols")
if (href_list["toggle_port_connection"])
if(internal_tank.connected_port)
+1 -1
View File
@@ -146,7 +146,7 @@
..()
if(href_list["drop_from_cargo"])
var/obj/O = locate(href_list["drop_from_cargo"])
if(O && O in src.cargo)
if(O && (O in cargo))
occupant_message("<span class='notice'>You unload [O].</span>")
O.forceMove(drop_location())
cargo -= O
@@ -11,7 +11,7 @@
LAZYINITLIST(blood_DNA) //Kinda needed
if (random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
icon_state = pick(random_icon_states)
create_reagents(300)
create_reagents(300, NONE, NO_REAGENTS_VALUE)
if(loc && isturf(loc))
for(var/obj/effect/decal/cleanable/C in loc)
if(C != src && C.type == type && !QDELETED(C))
@@ -94,7 +94,7 @@
/obj/effect/particle_effect/foam/Initialize()
. = ..()
MakeSlippery()
create_reagents(1000) //limited by the size of the reagent holder anyway.
create_reagents(1000, NONE, NO_REAGENTS_VALUE) //limited by the size of the reagent holder anyway.
START_PROCESSING(SSfastprocess, src)
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
@@ -32,7 +32,7 @@
/obj/effect/particle_effect/smoke/Initialize()
. = ..()
create_reagents(500)
create_reagents(500, NONE, NO_REAGENTS_VALUE)
START_PROCESSING(SSobj, src)

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