Conflict Fix

This commit is contained in:
Artur
2020-02-19 13:11:33 +02:00
514 changed files with 6176 additions and 2858 deletions
@@ -735,7 +735,7 @@
/obj/machinery/atmospherics/components/unary/outlet_injector{
dir = 1
},
/turf/open/space/basic,
/turf/open/floor/plating/airless,
/area/engine/engineering)
"Si" = (
/obj/structure/cable/yellow{
@@ -240,7 +240,7 @@
/obj/machinery/atmospherics/components/unary/outlet_injector{
dir = 1
},
/turf/open/space/basic,
/turf/open/floor/plating/airless,
/area/engine/engineering)
"nR" = (
/obj/structure/cable{
@@ -905,14 +905,6 @@
},
/turf/open/space/basic,
/area/space/nearstation)
"VR" = (
/obj/structure/lattice/catwalk,
/obj/machinery/camera/emp_proof{
c_tag = "Tesla Engine Northeast";
network = list("ss13","engine")
},
/turf/open/space/basic,
/area/space/nearstation)
"Wf" = (
/obj/effect/turf_decal/stripes/line{
dir = 9
@@ -1728,7 +1720,7 @@ dz
dz
FP
FP
VR
FP
dz
dz
Yl
+7 -3
View File
@@ -21911,7 +21911,7 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/obj/machinery/computer/arcade/minesweeper,
/obj/machinery/vending/wardrobe/cap_wardrobe,
/turf/open/floor/wood,
/area/crew_quarters/heads/captain)
"bdj" = (
@@ -55854,6 +55854,10 @@
},
/turf/open/floor/plasteel,
/area/crew_quarters/dorms)
"nZL" = (
/obj/machinery/computer/arcade/minesweeper,
/turf/open/floor/wood,
/area/crew_quarters/heads/captain)
"oax" = (
/obj/structure/table/wood/fancy,
/obj/machinery/light,
@@ -57068,7 +57072,7 @@
/turf/open/floor/plating,
/area/space)
"sRH" = (
/obj/machinery/autolathe{
/obj/machinery/autolathe/secure{
name = "public autolathe"
},
/turf/open/floor/plasteel,
@@ -90865,7 +90869,7 @@ aVv
aXg
aYF
aZV
bbw
nZL
bcn
tgH
ben
+10 -3
View File
@@ -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,
@@ -62353,7 +62353,7 @@
/turf/open/floor/wood,
/area/crew_quarters/heads/captain/private)
"cbd" = (
/obj/effect/landmark/event_spawn,
/obj/machinery/vending/wardrobe/cap_wardrobe,
/turf/open/floor/wood,
/area/crew_quarters/heads/captain/private)
"cbe" = (
@@ -127169,6 +127169,13 @@
dir = 9
},
/area/science/circuit)
"rjr" = (
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
dir = 1
},
/obj/effect/landmark/event_spawn,
/turf/open/floor/wood,
/area/crew_quarters/heads/captain/private)
"rqh" = (
/obj/structure/lattice,
/turf/open/space/basic,
@@ -169426,7 +169433,7 @@ bUO
bXf
bUQ
cbe
ccP
rjr
ceH
cgu
cij
+16 -2
View File
@@ -28355,6 +28355,7 @@
/obj/structure/disposalpipe/segment{
dir = 6
},
/obj/machinery/vending/wardrobe/cap_wardrobe,
/turf/open/floor/carpet,
/area/crew_quarters/heads/captain/private)
"bdL" = (
@@ -31855,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,
@@ -81645,6 +81646,19 @@
/obj/machinery/door/firedoor,
/turf/open/floor/plating,
/area/crew_quarters/cryopod)
"eQf" = (
/obj/machinery/computer/shuttle/mining/common{
dir = 1
},
/obj/structure/window/reinforced,
/obj/structure/window/reinforced{
dir = 8
},
/obj/structure/window/reinforced{
dir = 4
},
/turf/open/floor/plating,
/area/hallway/primary/port)
"eZe" = (
/obj/structure/cable/yellow{
icon_state = "1-2"
@@ -98511,7 +98525,7 @@ bgA
biz
bkb
blZ
bnM
eQf
bqf
bqf
bqf
File diff suppressed because it is too large Load Diff
+6 -13
View File
@@ -9830,6 +9830,7 @@
/obj/structure/cable{
icon_state = "0-2"
},
/obj/item/twohanded/required/kirbyplants/random,
/turf/open/floor/carpet,
/area/crew_quarters/heads/captain)
"axT" = (
@@ -11162,10 +11163,7 @@
/obj/structure/extinguisher_cabinet{
pixel_x = -24
},
/obj/item/twohanded/required/kirbyplants{
icon_state = "plant-20";
pixel_y = 3
},
/obj/machinery/vending/wardrobe/cap_wardrobe,
/turf/open/floor/plasteel/dark,
/area/crew_quarters/heads/captain)
"aBl" = (
@@ -28097,11 +28095,6 @@
},
/turf/open/floor/plasteel/dark,
/area/science/robotics/lab)
"boY" = (
/obj/effect/turf_decal/bot,
/obj/effect/landmark/start/cyborg,
/turf/open/floor/plasteel,
/area/science/robotics/lab)
"boZ" = (
/obj/structure/table,
/obj/machinery/cell_charger,
@@ -98811,8 +98804,8 @@ beI
bkt
blH
bmO
boY
boY
bnQ
bnQ
bqi
bry
bsZ
@@ -99068,8 +99061,8 @@ bju
bkt
blI
bmO
boY
boY
bnQ
bnQ
bqi
brz
bta
+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
+1 -1
View File
@@ -20,7 +20,7 @@
#define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;}
#define START_PROCESSING(Processor, Datum) if (!(Datum.datum_flags & DF_ISPROCESSING)) {Datum.datum_flags |= DF_ISPROCESSING;Processor.processing += Datum}
#define STOP_PROCESSING(Processor, Datum) Datum.datum_flags &= ~DF_ISPROCESSING;Processor.processing -= Datum
#define STOP_PROCESSING(Processor, Datum) Datum.datum_flags &= ~DF_ISPROCESSING;Processor.processing -= Datum;Processor.currentrun -= Datum
//SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier)
+1
View File
@@ -34,6 +34,7 @@
#define CAN_MASTURBATE_WITH (1<<5)
#define MASTURBATE_LINKED_ORGAN (1<<6) //used to pass our mission to the linked organ
#define CAN_CLIMAX_WITH (1<<7)
#define GENITAL_CAN_AROUSE (1<<8)
#define COCK_SIZE_MIN 1
#define COCK_SIZE_MAX 20
-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)
+3 -1
View File
@@ -199,4 +199,6 @@
#define LORENTZ_CUMULATIVE_DISTRIBUTION(x, y, s) ( (1/PI)*TORADIANS(arctan((x-y)/s)) + 1/2 )
#define RULE_OF_THREE(a, b, x) ((a*x)/b)
// )
// )
#define MANHATTAN_DISTANCE(a, b) (abs(a.x - b.x) + abs(a.y - b.y))
+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
+11 -11
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
+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
+2 -2
View File
@@ -1,5 +1,5 @@
#define PROFILE_START ;PROFILE_STORE = list();PROFILE_SET;
#define PROFILE_STOP ;PROFILE_STORE = null;
#define LINE_PROFILE_START ;PROFILE_STORE = list();PROFILE_SET;
#define LINE_PROFILE_STOP ;PROFILE_STORE = null;
#define PROFILE_SET ;PROFILE_TIME = TICK_USAGE_REAL; PROFILE_LINE = __LINE__; PROFILE_FILE = __FILE__; PROFILE_SLEEPCHECK = world.time;
+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
+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
+1
View File
@@ -47,6 +47,7 @@
// Subsystems shutdown in the reverse of the order they initialize in
// The numbers just define the ordering, they are meaningless otherwise.
#define INIT_ORDER_PROFILER 101
#define INIT_ORDER_FAIL2TOPIC 22
#define INIT_ORDER_TITLE 20
#define INIT_ORDER_GARBAGE 19
+1
View File
@@ -1,4 +1,5 @@
#define TGS_EXTERNAL_CONFIGURATION
#define TGS_V3_API
#define TGS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name)
#define TGS_READ_GLOBAL(Name) GLOB.##Name
#define TGS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value
+21 -5
View File
@@ -107,6 +107,22 @@
var/commit //full sha of compiled commit
var/origin_commit //full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch
//represents a version of tgstation-server
/datum/tgs_version
var/suite //The suite version, can be >=3
//this group of variables can be null to represent a wild card
var/major //The major version
var/minor //The minor version
var/patch //The patch version
var/raw_parameter //The unparsed parameter
var/deprefixed_parameter //The version only bit of raw_parameter
//if the tgs_version is a wildcard version
/datum/tgs_version/proc/Wildcard()
return
//represents a merge of a GitHub pull request
/datum/tgs_revision_information/test_merge
var/number //pull request number
@@ -155,22 +171,22 @@
//FUNCTIONS
//Returns the respective string version of the API
//Returns the respective supported /datum/tgs_version of the API
/world/proc/TgsMaximumAPIVersion()
return
/world/proc/TgsMinimumAPIVersion()
return
//Gets the current version of the server tools running the server
/world/proc/TgsVersion()
return
//Returns TRUE if the world was launched under the server tools and the API matches, FALSE otherwise
//No function below this succeeds if it returns FALSE
/world/proc/TgsAvailable()
return
//Gets the current /datum/tgs_version of the server tools running the server
/world/proc/TgsVersion()
return
/world/proc/TgsInstanceName()
return
+17 -10
View File
@@ -57,14 +57,11 @@ GLOBAL_LIST_EMPTY(ipc_antennas_list)
//Genitals and Arousal Lists
GLOBAL_LIST_EMPTY(genitals_list)
GLOBAL_LIST_EMPTY(cock_shapes_list)//global_lists.dm for the list initializations //Now also _DATASTRUCTURES globals.dm
GLOBAL_LIST_EMPTY(cock_shapes_icons) //Associated list for names->icon_states for cockshapes.
GLOBAL_LIST_EMPTY(cock_shapes_list)
GLOBAL_LIST_EMPTY(gentlemans_organ_names)
GLOBAL_LIST_EMPTY(balls_shapes_list)
GLOBAL_LIST_EMPTY(balls_shapes_icons)
GLOBAL_LIST_EMPTY(breasts_size_list)
GLOBAL_LIST_EMPTY(breasts_shapes_list)
GLOBAL_LIST_EMPTY(breasts_shapes_icons)
GLOBAL_LIST_EMPTY(vagina_shapes_list)
GLOBAL_LIST_INIT(cum_into_containers_list, list(/obj/item/reagent_containers/food/snacks/pie)) //Yer fuggin snowflake name list jfc
GLOBAL_LIST_INIT(dick_nouns, list("dick","cock","member","shaft"))
@@ -111,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 -12
View File
@@ -51,26 +51,15 @@
init_sprite_accessory_subtypes(/datum/sprite_accessory/antenna, GLOB.ipc_antennas_list, roundstart = TRUE)
//genitals
init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list)
for(var/K in GLOB.cock_shapes_list)
var/datum/sprite_accessory/penis/value = GLOB.cock_shapes_list[K]
GLOB.cock_shapes_icons[K] = value.icon_state
init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/testicles, GLOB.balls_shapes_list)
GLOB.breasts_size_list = list ("a", "b", "c", "d", "e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing.
GLOB.gentlemans_organ_names = list("phallus", "willy", "dick", "prick", "member", "tool", "gentleman's organ",
"cock", "wang", "knob", "dong", "joystick", "pecker", "johnson", "weenie", "tadger", "schlong", "thirsty ferret",
"baloney pony", "schlanger", "Mutton dagger", "old blind bob","Hanging Johnny", "fishing rod", "Tally whacker", "polly rocket",
"One eyed trouser trout", "Ding dong", "ankle spanker", "Pork sword", "engine cranker", "Harry hot dog", "Davy Crockett",
"Kidney cracker", "Heat seeking moisture missile", "Giggle stick", "love whistle", "Tube steak", "Uncle Dick", "Purple helmet warrior")
for(var/K in GLOB.breasts_shapes_list)
var/datum/sprite_accessory/breasts/value = GLOB.breasts_shapes_list[K]
GLOB.breasts_shapes_icons[K] = value.icon_state
init_sprite_accessory_subtypes(/datum/sprite_accessory/testicles, GLOB.balls_shapes_list)
for(var/K in GLOB.balls_shapes_list)
var/datum/sprite_accessory/testicles/value = GLOB.balls_shapes_list[K]
GLOB.balls_shapes_icons[K] = value.icon_state
for(var/gpath in subtypesof(/obj/item/organ/genital))
var/obj/item/organ/genital/G = gpath
+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
+22
View File
@@ -1543,3 +1543,25 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
for(var/each_item in items_list)
for(var/i in 1 to items_list[each_item])
new each_item(where_to)
//sends a message to chat
//config_setting should be one of the following
//null - noop
//empty string - use TgsTargetBroadcast with admin_only = FALSE
//other string - use TgsChatBroadcast with the tag that matches config_setting, only works with TGS4, if using TGS3 the above method is used
/proc/send2chat(message, config_setting)
if(config_setting == null || !world.TgsAvailable())
return
var/datum/tgs_version/version = world.TgsVersion()
if(config_setting == "" || version.suite == 3)
world.TgsTargetedChatBroadcast(message, FALSE)
return
var/list/channels_to_use = list()
for(var/I in world.TgsChatChannelInfo())
var/datum/tgs_chat_channel/channel = I
if(channel.tag == config_setting)
channels_to_use += channel
if(channels_to_use.len)
world.TgsChatBroadcast()
+57
View File
@@ -0,0 +1,57 @@
// Basic geometry things.
/datum/vector/
var/x = 0
var/y = 0
/datum/vector/New(var/x, var/y)
src.x = x
src.y = y
/datum/vector/proc/duplicate()
return new /datum/vector(x, y)
/datum/vector/proc/euclidian_norm()
return sqrt(x*x + y*y)
/datum/vector/proc/squared_norm()
return x*x + y*y
/datum/vector/proc/normalize()
var/norm = euclidian_norm()
x = x/norm
y = y/norm
return src
/datum/vector/proc/chebyshev_norm()
return max(abs(x), abs(y))
/datum/vector/proc/chebyshev_normalize()
var/norm = chebyshev_norm()
x = x/norm
y = y/norm
return src
/datum/vector/proc/is_integer()
return ISINTEGER(x) && ISINTEGER(y)
/atom/movable/proc/vector_translate(var/datum/vector/V, var/delay)
var/turf/T = get_turf(src)
var/turf/destination = locate(T.x + V.x, T.y + V.y, z)
var/datum/vector/V_norm = V.duplicate()
V_norm.chebyshev_normalize()
if (!V_norm.is_integer())
return
var/turf/destination_temp
while (destination_temp != destination)
destination_temp = locate(T.x + V_norm.x, T.y + V_norm.y, z)
forceMove(destination_temp)
T = get_turf(src)
sleep(delay + world.tick_lag) // Shortest possible time to sleep
/atom/proc/get_translated_turf(var/datum/vector/V)
var/turf/T = get_turf(src)
return locate(T.x + V.x, T.y + V.y, z)
/proc/atoms2vector(var/atom/A, var/atom/B)
return new /datum/vector((B.x - A.x), (B.y - A.y)) // Vector from A -> B
+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
..()
..()
+27 -18
View File
@@ -1,19 +1,28 @@
/**
*This is the proc that handles the order of an item_attack.
*The order of procs called is:
*tool_act on the target. If it returns TRUE, the chain will be stopped.
*pre_attack() on src. If this returns TRUE, the chain will be stopped.
*attackby on the target. If it returns TRUE, the chain will be stopped.
*and lastly
*afterattack. The return value does not matter.
*/
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params)
if(!tool_attack_chain(user, target) && pre_attack(target, user, params))
// Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
var/resolved = target.attackby(src, user, params)
if(!resolved && target && !QDELETED(src))
afterattack(target, user, 1, params) // 1: clicking something Adjacent
//Checks if the item can work as a tool, calling the appropriate tool behavior on the target
/obj/item/proc/tool_attack_chain(mob/user, atom/target)
if(!tool_behaviour)
return FALSE
return target.tool_act(user, src, tool_behaviour)
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))
return
if(target.attackby(src,user, params))
return
if(QDELETED(src) || QDELETED(target))
return
afterattack(target, user, TRUE, params)
// Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown.
/obj/item/proc/attack_self(mob/user)
@@ -23,8 +32,8 @@
/obj/item/proc/pre_attack(atom/A, mob/living/user, params) //do stuff before attackby!
if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_NO_ATTACK)
return FALSE
return TRUE //return FALSE to avoid calling attackby after this proc does stuff
return TRUE
return FALSE //return TRUE to avoid calling attackby after this proc does stuff
// No comment
/atom/proc/attackby(obj/item/W, mob/user, params)
@@ -112,7 +121,7 @@
send_item_attack_message(I, user)
if(I.force)
apply_damage(totitemdamage, I.damtype) //CIT CHANGE - replaces I.force with totitemdamage
if(I.damtype == BRUTE && !HAS_TRAIT(src, TRAIT_NOMARROW))
if(I.damtype == BRUTE && !HAS_TRAIT(src, TRAIT_NOMARROW))
if(prob(33))
I.add_mob_blood(src)
var/turf/location = get_turf(src)
@@ -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()
. = ..()
@@ -1,3 +1,5 @@
/datum/config_entry/flag/auto_profile // Automatically start profiler on server start
/datum/config_entry/flag/autoadmin // if autoadmin is enabled
protection = CONFIG_ENTRY_LOCKED
@@ -392,6 +394,13 @@
config_entry_value = 50
/datum/config_entry/flag/irc_announce_new_game
deprecated_by = /datum/config_entry/string/chat_announce_new_game
/datum/config_entry/flag/irc_announce_new_game/DeprecationUpdate(value)
return "" //default broadcast
/datum/config_entry/string/chat_announce_new_game
config_entry_value = null
/datum/config_entry/flag/debug_admin_hrefs
+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
@@ -4,25 +4,16 @@
#define END_STAGE 4
//Used for all kinds of weather, ex. lavaland ash storms.
SUBSYSTEM_DEF(weather)
PROCESSING_SUBSYSTEM_DEF(weather)
name = "Weather"
flags = SS_BACKGROUND
wait = 10
runlevels = RUNLEVEL_GAME
var/list/processing = list()
var/list/eligible_zlevels = list()
var/list/next_hit_by_zlevel = list() //Used by barometers to know when the next storm is coming
/datum/controller/subsystem/weather/fire()
// process active weather
for(var/V in processing)
var/datum/weather/W = V
if(W.aesthetic || W.stage != MAIN_STAGE)
continue
for(var/i in GLOB.mob_living_list)
var/mob/living/L = i
if(W.can_weather_act(L))
W.weather_act(L)
/datum/controller/subsystem/processing/weather/fire()
. = ..() //Active weather is handled by . = ..() processing subsystem base fire().
// start random weather on relevant levels
for(var/z in eligible_zlevels)
@@ -34,7 +25,7 @@ SUBSYSTEM_DEF(weather)
addtimer(CALLBACK(src, .proc/make_eligible, z, possible_weather), randTime + initial(W.weather_duration_upper), TIMER_UNIQUE) //Around 5-10 minutes between weathers
next_hit_by_zlevel["[z]"] = world.time + randTime + initial(W.telegraph_duration)
/datum/controller/subsystem/weather/Initialize(start_timeofday)
/datum/controller/subsystem/processing/weather/Initialize(start_timeofday)
for(var/V in subtypesof(/datum/weather))
var/datum/weather/W = V
var/probability = initial(W.probability)
@@ -47,7 +38,7 @@ SUBSYSTEM_DEF(weather)
eligible_zlevels["[z]"][W] = probability
return ..()
/datum/controller/subsystem/weather/proc/run_weather(datum/weather/weather_datum_type, z_levels)
/datum/controller/subsystem/processing/weather/proc/run_weather(datum/weather/weather_datum_type, z_levels)
if (istext(weather_datum_type))
for (var/V in subtypesof(/datum/weather))
var/datum/weather/W = V
@@ -69,11 +60,11 @@ SUBSYSTEM_DEF(weather)
var/datum/weather/W = new weather_datum_type(z_levels)
W.telegraph()
/datum/controller/subsystem/weather/proc/make_eligible(z, possible_weather)
/datum/controller/subsystem/processing/weather/proc/make_eligible(z, possible_weather)
eligible_zlevels[z] = possible_weather
next_hit_by_zlevel["[z]"] = null
/datum/controller/subsystem/weather/proc/get_weather(z, area/active_area)
/datum/controller/subsystem/processing/weather/proc/get_weather(z, area/active_area)
var/datum/weather/A
for(var/V in processing)
var/datum/weather/W = V
+63
View File
@@ -0,0 +1,63 @@
#define PROFILER_FILENAME "profiler.json"
SUBSYSTEM_DEF(profiler)
name = "Profiler"
init_order = INIT_ORDER_PROFILER
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
wait = 3000
flags = SS_NO_TICK_CHECK
var/fetch_cost = 0
var/write_cost = 0
/datum/controller/subsystem/profiler/stat_entry(msg)
msg += "F:[round(fetch_cost,1)]ms"
msg += "|W:[round(write_cost,1)]ms"
..(msg)
/datum/controller/subsystem/profiler/Initialize()
if(CONFIG_GET(flag/auto_profile))
StartProfiling()
else
StopProfiling() //Stop the early start from world/New
return ..()
/datum/controller/subsystem/profiler/fire()
if(CONFIG_GET(flag/auto_profile))
DumpFile()
/datum/controller/subsystem/profiler/Shutdown()
if(CONFIG_GET(flag/auto_profile))
DumpFile()
return ..()
/datum/controller/subsystem/profiler/proc/StartProfiling()
#if DM_BUILD < 1506 || DM_VERSION < 513
stack_trace("Auto profiling unsupported on this byond version")
CONFIG_SET(flag/auto_profile, FALSE)
#else
world.Profile(PROFILE_START)
#endif
/datum/controller/subsystem/profiler/proc/StopProfiling()
#if DM_BUILD >= 1506 && DM_VERSION >= 513
world.Profile(PROFILE_STOP)
#endif
/datum/controller/subsystem/profiler/proc/DumpFile()
#if DM_BUILD < 1506 || DM_VERSION < 513
stack_trace("Auto profiling unsupported on this byond version")
CONFIG_SET(flag/auto_profile, FALSE)
#else
var/timer = TICK_USAGE_REAL
var/current_profile_data = world.Profile(PROFILE_REFRESH,format="json")
fetch_cost = MC_AVERAGE(fetch_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
CHECK_TICK
if(!length(current_profile_data)) //Would be nice to have explicit proc to check this
stack_trace("Warning, profiling stopped manually before dump.")
var/json_file = file("[GLOB.log_directory]/[PROFILER_FILENAME]")
if(fexists(json_file))
fdel(json_file)
timer = TICK_USAGE_REAL
WRITE_FILE(json_file, current_profile_data)
write_cost = MC_AVERAGE(write_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
#endif
+2 -2
View File
@@ -81,8 +81,8 @@ SUBSYSTEM_DEF(server_maint)
co.ehjax_send(data = "roundrestart")
if(server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
C << link("byond://[server]")
var/tgsversion = world.TgsVersion()
var/datum/tgs_version/tgsversion = world.TgsVersion()
if(tgsversion)
SSblackbox.record_feedback("text", "server_tools", 1, tgsversion)
SSblackbox.record_feedback("text", "server_tools", 1, tgsversion.raw_parameter)
#undef PING_BUFFER_TIME
+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 -3
View File
@@ -158,8 +158,7 @@ SUBSYSTEM_DEF(ticker)
for(var/client/C in GLOB.clients)
window_flash(C, ignorepref = TRUE) //let them know lobby has opened up.
to_chat(world, "<span class='boldnotice'>Welcome to [station_name()]!</span>")
if(CONFIG_GET(flag/irc_announce_new_game))
world.TgsTargetedChatBroadcast("New round starting on [SSmapping.config.map_name]!", FALSE)
send2chat("New round starting on [SSmapping.config.map_name]!", CONFIG_GET(string/chat_announce_new_game))
current_state = GAME_STATE_PREGAME
//Everyone who wants to be an observer is now spawned
create_observers()
@@ -488,7 +487,7 @@ SUBSYSTEM_DEF(ticker)
if("SCORE")
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = MAJORITY_JUDGEMENT_VOTING)
// fallback
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = MAJORITY_JUDGEMENT_VOTING)
SSvote.initiate_vote("map","server",hideresults=TRUE)
/datum/controller/subsystem/ticker/proc/HasRoundStarted()
return current_state >= GAME_STATE_PLAYING
+3 -3
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)
@@ -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)
+8
View File
@@ -820,3 +820,11 @@
target.layer = old_layer
target.plane = old_plane
current_button.appearance_cache = target.appearance
/proc/get_action_of_type(mob/M, var/action_type)
if(!M.actions || !ispath(action_type, /datum/action))
return
for(var/datum/action/A in M.actions)
if(istype(A, action_type))
return A
return
+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
@@ -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
+2 -2
View File
@@ -25,7 +25,7 @@
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
host_mob.hud_set_nanite_indicator()
@@ -212,7 +212,7 @@
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)
+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)
+24 -15
View File
@@ -25,6 +25,7 @@ GLOBAL_LIST_EMPTY(uplinks)
var/unlock_code
var/failsafe_code
var/datum/ui_state/checkstate
var/compact_mode = FALSE
var/debug = FALSE
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20, datum/ui_state/_checkstate)
@@ -122,7 +123,7 @@ GLOBAL_LIST_EMPTY(uplinks)
active = TRUE
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "uplink", name, 450, 750, master_ui, state)
ui = new(user, src, ui_key, "uplink", name, 620, 580, master_ui, state)
ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input.
ui.set_style("syndicate")
ui.open()
@@ -139,29 +140,35 @@ GLOBAL_LIST_EMPTY(uplinks)
var/list/data = list()
data["telecrystals"] = telecrystals
data["lockable"] = lockable
data["compact_mode"] = compact_mode
return data
/datum/component/uplink/ui_static_data(mob/user)
var/list/data = list()
data["categories"] = list()
for(var/category in uplink_items)
var/list/cat = list(
"name" = category,
"items" = (category == selected_cat ? list() : null))
if(category == selected_cat)
for(var/item in uplink_items[category])
var/datum/uplink_item/I = uplink_items[category][item]
if(I.limited_stock == 0)
for(var/item in uplink_items[category])
var/datum/uplink_item/I = uplink_items[category][item]
if(I.limited_stock == 0)
continue
if(I.restricted_roles.len)
var/is_inaccessible = TRUE
for(var/R in I.restricted_roles)
if(R == user.mind.assigned_role || debug)
is_inaccessible = FALSE
if(is_inaccessible)
continue
if(I.restricted_roles.len)
var/is_inaccessible = 1
for(var/R in I.restricted_roles)
if(R == user.mind.assigned_role || debug)
is_inaccessible = 0
if(is_inaccessible)
continue
cat["items"] += list(list(
"name" = I.name,
"cost" = I.cost,
"desc" = I.desc,
))
cat["items"] += list(list(
"name" = I.name,
"cost" = I.cost,
"desc" = I.desc,
))
data["categories"] += list(cat)
return data
@@ -189,6 +196,8 @@ GLOBAL_LIST_EMPTY(uplinks)
SStgui.close_uis(src)
if("select")
selected_cat = params["category"]
if("compact_toggle")
compact_mode = !compact_mode
return TRUE
/datum/component/uplink/proc/MakePurchase(mob/user, datum/uplink_item/U)
+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
@@ -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
+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>")
+8 -6
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)
@@ -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
@@ -128,7 +130,7 @@
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 +160,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 +172,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 +183,4 @@
location = location.loc
if(ismob(location))
return location.loc.remove_air(amount)
return loc.remove_air(amount)
return location.remove_air(amount)
+4 -2
View File
@@ -27,7 +27,8 @@
for(var/line in testmerge)
var/datum/tgs_revision_information/test_merge/tm = line
msg += "Test merge active of PR #[tm.number] commit [tm.commit]"
msg += "Test merge active of PR #[tm.number] commit [tm.pull_request_commit]"
SSblackbox.record_feedback("associative", "testmerged_prs", 1, list("number" = "[tm.number]", "commit" = "[tm.pull_request_commit]", "title" = "[tm.title]", "author" = "[tm.author]"))
if(commit && commit != originmastercommit)
msg += "HEAD: [commit]"
@@ -75,7 +76,8 @@
else if(!pc)
msg += "No commit information"
if(world.TgsAvailable())
msg += "Server tools version: [world.TgsVersion()]"
var/datum/tgs_version/version = world.TgsVersion()
msg += "Server tools version: [version.raw_parameter]"
// Game mode odds
msg += "<br><b>Current Informational Settings:</b>"
-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 -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"
+9 -1
View File
@@ -61,7 +61,7 @@
if(A.z in impacted_z_levels)
impacted_areas |= A
weather_duration = rand(weather_duration_lower, weather_duration_upper)
START_PROCESSING(SSweather, src)
START_PROCESSING(SSweather, src) //The reason this doesn't start and stop at main stage is because processing list is also used to see active running weathers (for example, you wouldn't want two ash storms starting at once.)
update_areas()
for(var/M in GLOB.player_list)
var/turf/mob_turf = get_turf(M)
@@ -107,6 +107,14 @@
STOP_PROCESSING(SSweather, src)
update_areas()
/datum/weather/process()
if(aesthetic || (stage != MAIN_STAGE))
return
for(var/i in GLOB.mob_living_list)
var/mob/living/L = i
if(can_weather_act(L))
weather_act(L)
/datum/weather/proc/can_weather_act(mob/living/L) //Can this weather impact a mob?
var/turf/mob_turf = get_turf(L)
if(mob_turf && !(mob_turf.z in impacted_z_levels))
-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?
+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)
@@ -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)
@@ -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
+44 -54
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
@@ -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)
+9 -15
View File
@@ -2,13 +2,11 @@
#define FONT_SIZE "5pt"
#define FONT_COLOR "#09f"
#define FONT_STYLE "Arial Black"
#define MAX_TIMER 9000
#define PRESET_SHORT 1200
#define PRESET_MEDIUM 1800
#define PRESET_LONG 3000
#define MAX_TIMER 15 MINUTES
#define PRESET_SHORT 2 MINUTES
#define PRESET_MEDIUM 3 MINUTES
#define PRESET_LONG 5 MINUTES
///////////////////////////////////////////////////////////////////////////////////////////////
// Brig Door control displays.
@@ -25,7 +23,7 @@
desc = "A remote control for a door."
req_access = list(ACCESS_SECURITY)
density = FALSE
var/id = null // id of linked machinery/lockers
var/id // id of linked machinery/lockers
var/activation_time = 0
var/timer_duration = 0
@@ -43,8 +41,6 @@
Radio = new/obj/item/radio(src)
Radio.listening = 0
/obj/machinery/door_timer/Initialize()
. = ..()
if(id != null)
for(var/obj/machinery/door/window/brigdoor/M in urange(20, src))
if (M.id == id)
@@ -71,7 +67,7 @@
return
if(timing)
if(world.realtime - activation_time >= timer_duration)
if(REALTIMEOFDAY - activation_time >= timer_duration)
timer_end() // open doors, reset timer, clear status screen
update_icon()
@@ -80,14 +76,13 @@
..()
update_icon()
// open/closedoor checks if door_timer has power, if so it checks if the
// linked door is open/closed (by density) then opens it/closes it.
/obj/machinery/door_timer/proc/timer_start()
if(stat & (NOPOWER|BROKEN))
return 0
activation_time = world.realtime
activation_time = REALTIMEOFDAY
timing = TRUE
for(var/obj/machinery/door/window/brigdoor/door in targets)
@@ -104,7 +99,6 @@
C.update_icon()
return 1
/obj/machinery/door_timer/proc/timer_end(forced = FALSE)
if(stat & (NOPOWER|BROKEN))
@@ -136,7 +130,7 @@
/obj/machinery/door_timer/proc/time_left(seconds = FALSE)
. = max(0,timer_duration - (activation_time ? world.realtime - activation_time : 0))
. = max(0,timer_duration - (activation_time ? REALTIMEOFDAY - activation_time : 0))
if(seconds)
. /= 10
@@ -240,7 +234,7 @@
preset_time = PRESET_LONG
. = set_timer(preset_time)
if(timing)
activation_time = world.realtime
activation_time = REALTIMEOFDAY
else
. = FALSE
+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
@@ -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)
+1 -1
View File
@@ -345,7 +345,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
A = get_turf(A)
var/can_make_pipe = (isturf(A) || is_type_in_typecache(A, make_pipe_whitelist))
. = FALSE
. = TRUE
if((mode & DESTROY_MODE) && istype(A, /obj/item/pipe) || istype(A, /obj/structure/disposalconstruct) || istype(A, /obj/structure/c_transit_tube) || istype(A, /obj/structure/c_transit_tube_pod) || istype(A, /obj/item/pipe_meter))
to_chat(user, "<span class='notice'>You start destroying a pipe...</span>")
+1 -1
View File
@@ -67,7 +67,7 @@
L.Remove()
// make some colorful reagent, and apply it to the lungs
L.create_reagents(10)
L.create_reagents(10, NONE, NO_REAGENTS_VALUE)
L.reagents.add_reagent(/datum/reagent/colorful_reagent, 10)
L.reagents.reaction(L, TOUCH, 1)
+1 -1
View File
@@ -23,7 +23,7 @@
if(!boomingandboxing)
var/list/tracklist = list()
for(var/datum/track/S in SSjukeboxes.songs)
if(istype(S) && S.song_associated_id in availabletrackids)
if(istype(S) && (S.song_associated_id in availabletrackids))
tracklist[S.song_name] = S
var/selected = input(user, "Play song", "Track:") as null|anything in tracklist
if(QDELETED(src) || !selected || !istype(tracklist[selected], /datum/track))

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