From cb346a3847f26a9e6e5d80a01136210c6006b009 Mon Sep 17 00:00:00 2001 From: Letter N <24603524+LetterN@users.noreply.github.com> Date: Fri, 5 Mar 2021 14:29:36 +0800 Subject: [PATCH] a --- .github/workflows/ci_suite.yml | 4 +- code/__HELPERS/unsorted.dm | 44 +++-- code/_onclick/hud/plane_master.dm | 3 - code/datums/callback.dm | 176 +++++++++--------- code/datums/components/material_container.dm | 95 ++++++++-- code/datums/materials/_material.dm | 111 ++++++++--- code/game/atoms.dm | 6 +- code/game/objects/items/stacks/cash.dm | 2 +- .../game/objects/items/stacks/sheets/glass.dm | 14 +- .../objects/items/stacks/sheets/sheets.dm | 2 +- code/game/objects/items/stacks/stack.dm | 84 +++++---- code/modules/admin/callproc/callproc.dm | 59 +++--- .../machinery/portable/canister.dm | 2 - code/modules/power/cable.dm | 11 +- tools/build/build.js | 1 + tools/ci/check_grep.sh | 2 +- tools/ci/run_server.sh | 5 + 17 files changed, 386 insertions(+), 235 deletions(-) diff --git a/.github/workflows/ci_suite.yml b/.github/workflows/ci_suite.yml index 168807e742..a6b91bd559 100644 --- a/.github/workflows/ci_suite.yml +++ b/.github/workflows/ci_suite.yml @@ -98,8 +98,8 @@ jobs: bash tools/ci/install_byond.sh source $HOME/BYOND/byond/bin/byondsetup tgui/bin/tgui --build - # bash tools/ci/dm.sh -DCIBUILDING tgstation.dme - # bash tools/ci/run_server.sh + bash tools/ci/dm.sh -DCIBUILDING tgstation.dme + # bash tools/ci/run_server.sh test_windows: if: "!contains(github.event.head_commit.message, '[ci skip]')" diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index d0bb17efd2..ee4b09d42c 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1247,28 +1247,40 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) #define FOR_DVIEW_END GLOB.dview_mob.loc = null -//can a window be here, or is there a window blocking it? -/proc/valid_window_location(turf/T, dir_to_check) - if(!T) +/** + * Checks whether the target turf is in a valid state to accept a directional window + * or other directional pseudo-dense object such as railings. + * + * Returns FALSE if the target turf cannot accept a directional window or railing. + * Returns TRUE otherwise. + * + * Arguments: + * * dest_turf - The destination turf to check for existing windows and railings + * * test_dir - The prospective dir of some atom you'd like to put on this turf. + * * is_fulltile - Whether the thing you're attempting to move to this turf takes up the entire tile or whether it supports multiple movable atoms on its tile. + */ +/proc/valid_window_location(turf/dest_turf, test_dir, is_fulltile = FALSE) + if(!dest_turf) return FALSE - for(var/obj/O in T) - if(istype(O, /obj/machinery/door/window) && (O.dir == dir_to_check || dir_to_check == FULLTILE_WINDOW_DIR)) - return FALSE - if(istype(O, /obj/structure/windoor_assembly)) - var/obj/structure/windoor_assembly/W = O - if(W.ini_dir == dir_to_check || dir_to_check == FULLTILE_WINDOW_DIR) + for(var/obj/turf_content in dest_turf) + if(istype(turf_content, /obj/machinery/door/window)) + if((turf_content.dir == test_dir) || is_fulltile) return FALSE - if(istype(O, /obj/structure/window)) - var/obj/structure/window/W = O - if(W.ini_dir == dir_to_check || W.ini_dir == FULLTILE_WINDOW_DIR || dir_to_check == FULLTILE_WINDOW_DIR) + if(istype(turf_content, /obj/structure/windoor_assembly)) + var/obj/structure/windoor_assembly/windoor_assembly = turf_content + if(windoor_assembly.dir == test_dir || is_fulltile) return FALSE - if(istype(O, /obj/structure/railing)) - var/obj/structure/railing/rail = O - if(rail.ini_dir == dir_to_check || rail.ini_dir == FULLTILE_WINDOW_DIR || dir_to_check == FULLTILE_WINDOW_DIR) + if(istype(turf_content, /obj/structure/window)) + var/obj/structure/window/window_structure = turf_content + if(window_structure.dir == test_dir || window_structure.fulltile || is_fulltile) + return FALSE + if(istype(turf_content, /obj/structure/railing)) + var/obj/structure/railing/rail = turf_content + if(rail.dir == test_dir || is_fulltile) return FALSE return TRUE -/proc/pass() +/proc/pass(...) return /proc/get_mob_or_brainmob(occupant) diff --git a/code/_onclick/hud/plane_master.dm b/code/_onclick/hud/plane_master.dm index f5b8991e20..4c736c9a2b 100644 --- a/code/_onclick/hud/plane_master.dm +++ b/code/_onclick/hud/plane_master.dm @@ -38,9 +38,6 @@ /obj/screen/plane_master/proc/shadow(_size, _offset = 0, _x = 0, _y = 0, _color = "#04080FAA") filters += filter(type = "drop_shadow", x = _x, y = _y, color = _color, size = _size, offset = _offset) -/obj/screen/plane_master/proc/clear_filters() - filters = list() - ///Contains just the floor /obj/screen/plane_master/floor name = "floor plane master" diff --git a/code/datums/callback.dm b/code/datums/callback.dm index 62e10922f3..b5baea28f1 100644 --- a/code/datums/callback.dm +++ b/code/datums/callback.dm @@ -1,53 +1,53 @@ /** - *# Callback Datums - *A datum that holds a proc to be called on another object, used to track proccalls to other objects - * - * ## USAGE - * - * ``` - * var/datum/callback/C = new(object|null, /proc/type/path|"procstring", arg1, arg2, ... argn) - * var/timerid = addtimer(C, time, timertype) - * you can also use the compiler define shorthand - * var/timerid = addtimer(CALLBACK(object|null, /proc/type/path|procstring, arg1, arg2, ... argn), time, timertype) - * ``` - * - * Note: proc strings can only be given for datum proc calls, global procs must be proc paths - * - * Also proc strings are strongly advised against because they don't compile error if the proc stops existing - * - * In some cases you can provide a shortform of the procname, see the proc typepath shortcuts documentation below - * - * ## INVOKING THE CALLBACK - *`var/result = C.Invoke(args, to, add)` additional args are added after the ones given when the callback was created - * - * `var/result = C.InvokeAsync(args, to, add)` Asyncronous - returns . on the first sleep then continues on in the background - * after the sleep/block ends, otherwise operates normally. - * - * ## PROC TYPEPATH SHORTCUTS - * (these operate on paths, not types, so to these shortcuts, datum is NOT a parent of atom, etc...) - * - * ### global proc while in another global proc: - * .procname - * - * `CALLBACK(GLOBAL_PROC, .some_proc_here)` - * - * ### proc defined on current(src) object (when in a /proc/ and not an override) OR overridden at src or any of it's parents: - * .procname - * - * `CALLBACK(src, .some_proc_here)` - * - * ### when the above doesn't apply: - *.proc/procname - * - * `CALLBACK(src, .proc/some_proc_here)` - * - * - * proc defined on a parent of a some type - * - * `/some/type/.proc/some_proc_here` - * - * Otherwise you must always provide the full typepath of the proc (/type/of/thing/proc/procname) - */ + *# Callback Datums + *A datum that holds a proc to be called on another object, used to track proccalls to other objects + * + * ## USAGE + * + * ``` + * var/datum/callback/C = new(object|null, /proc/type/path|"procstring", arg1, arg2, ... argn) + * var/timerid = addtimer(C, time, timertype) + * you can also use the compiler define shorthand + * var/timerid = addtimer(CALLBACK(object|null, /proc/type/path|procstring, arg1, arg2, ... argn), time, timertype) + * ``` + * + * Note: proc strings can only be given for datum proc calls, global procs must be proc paths + * + * Also proc strings are strongly advised against because they don't compile error if the proc stops existing + * + * In some cases you can provide a shortform of the procname, see the proc typepath shortcuts documentation below + * + * ## INVOKING THE CALLBACK + *`var/result = C.Invoke(args, to, add)` additional args are added after the ones given when the callback was created + * + * `var/result = C.InvokeAsync(args, to, add)` Asyncronous - returns . on the first sleep then continues on in the background + * after the sleep/block ends, otherwise operates normally. + * + * ## PROC TYPEPATH SHORTCUTS + * (these operate on paths, not types, so to these shortcuts, datum is NOT a parent of atom, etc...) + * + * ### global proc while in another global proc: + * .procname + * + * `CALLBACK(GLOBAL_PROC, .some_proc_here)` + * + * ### proc defined on current(src) object (when in a /proc/ and not an override) OR overridden at src or any of it's parents: + * .procname + * + * `CALLBACK(src, .some_proc_here)` + * + * ### when the above doesn't apply: + *.proc/procname + * + * `CALLBACK(src, .proc/some_proc_here)` + * + * + * proc defined on a parent of a some type + * + * `/some/type/.proc/some_proc_here` + * + * Otherwise you must always provide the full typepath of the proc (/type/of/thing/proc/procname) + */ /datum/callback ///The object we will be calling the proc on @@ -60,13 +60,13 @@ var/datum/weakref/user /** - * Create a new callback datum - * - * Arguments - * * thingtocall the object to call the proc on - * * proctocall the proc to call on the target object - * * ... an optional list of extra arguments to pass to the proc - */ + * Create a new callback datum + * + * Arguments + * * thingtocall the object to call the proc on + * * proctocall the proc to call on the target object + * * ... an optional list of extra arguments to pass to the proc + */ /datum/callback/New(thingtocall, proctocall, ...) if (thingtocall) object = thingtocall @@ -76,13 +76,13 @@ if(usr) user = WEAKREF(usr) /** - * Immediately Invoke proctocall on thingtocall, with waitfor set to false - * - * Arguments: - * * thingtocall Object to call on - * * proctocall Proc to call on that object - * * ... optional list of arguments to pass as arguments to the proc being called - */ + * Immediately Invoke proctocall on thingtocall, with waitfor set to false + * + * Arguments: + * * thingtocall Object to call on + * * proctocall Proc to call on that object + * * ... optional list of arguments to pass as arguments to the proc being called + */ /world/proc/ImmediateInvokeAsync(thingtocall, proctocall, ...) set waitfor = FALSE @@ -97,13 +97,13 @@ call(thingtocall, proctocall)(arglist(calling_arguments)) /** - * Invoke this callback - * - * Calls the registered proc on the registered object, if the user ref - * can be resolved it also inclues that as an arg - * - * If the datum being called on is varedited, the call is wrapped via WrapAdminProcCall - */ + * Invoke this callback + * + * Calls the registered proc on the registered object, if the user ref + * can be resolved it also inclues that as an arg + * + * If the datum being called on is varedited, the call is wrapped via [WrapAdminProcCall][/proc/WrapAdminProcCall] + */ /datum/callback/proc/Invoke(...) if(!usr) var/datum/weakref/W = user @@ -130,13 +130,13 @@ return call(object, delegate)(arglist(calling_arguments)) /** - * Invoke this callback async (waitfor=false) - * - * Calls the registered proc on the registered object, if the user ref - * can be resolved it also inclues that as an arg - * - * If the datum being called on is varedited, the call is wrapped via WrapAdminProcCall - */ + * Invoke this callback async (waitfor=false) + * + * Calls the registered proc on the registered object, if the user ref + * can be resolved it also inclues that as an arg + * + * If the datum being called on is varedited, the call is wrapped via WrapAdminProcCall + */ /datum/callback/proc/InvokeAsync(...) set waitfor = FALSE @@ -166,7 +166,7 @@ /** Helper datum for the select callbacks proc - */ + */ /datum/callback_select var/list/finished var/pendingcount @@ -192,16 +192,16 @@ finished[index] = rtn /** - * Runs a list of callbacks asyncronously, returning only when all have finished - * - * Callbacks can be repeated, to call it multiple times - * - * Arguments: - * * list/callbacks the list of callbacks to be called - * * list/callback_args the list of lists of arguments to pass into each callback - * * savereturns Optionally save and return the list of returned values from each of the callbacks - * * resolution The number of byond ticks between each time you check if all callbacks are complete - */ + * Runs a list of callbacks asyncronously, returning only when all have finished + * + * Callbacks can be repeated, to call it multiple times + * + * Arguments: + * * list/callbacks the list of callbacks to be called + * * list/callback_args the list of lists of arguments to pass into each callback + * * savereturns Optionally save and return the list of returned values from each of the callbacks + * * resolution The number of byond ticks between each time you check if all callbacks are complete + */ /proc/callback_select(list/callbacks, list/callback_args, savereturns = TRUE, resolution = 1) if (!callbacks) return diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm index 7adc634621..24f043db36 100644 --- a/code/datums/components/material_container.dm +++ b/code/datums/components/material_container.dm @@ -10,25 +10,37 @@ */ /datum/component/material_container + /// The total amount of materials this material container contains var/total_amount = 0 + /// The maximum amount of materials this material container can contain var/max_amount - var/sheet_type + /// Map of material ref -> amount var/list/materials //Map of key = material ref | Value = amount + /// The list of materials that this material container can accept + var/list/allowed_materials var/show_on_examine var/disable_attackby var/list/allowed_typecache + /// The last main material that was inserted into this container var/last_inserted_id + /// Whether or not this material container allows specific amounts from sheets to be inserted var/precise_insertion = FALSE + /// A callback invoked before materials are inserted into this container var/datum/callback/precondition + /// A callback invoked after materials are inserted into this container var/datum/callback/after_insert /// Sets up the proper signals and fills the list of materials with the appropriate references. /datum/component/material_container/Initialize(list/mat_list, max_amt = 0, _show_on_examine = FALSE, list/allowed_types, datum/callback/_precondition, datum/callback/_after_insert, _disable_attackby) + if(!isatom(parent)) + return COMPONENT_INCOMPATIBLE + materials = list() max_amount = max(0, max_amt) show_on_examine = _show_on_examine disable_attackby = _disable_attackby + allowed_materials = mat_list || list() if(allowed_types) if(ispath(allowed_types) && allowed_types == /obj/item/stack) allowed_typecache = GLOB.typecache_stack @@ -38,14 +50,32 @@ precondition = _precondition after_insert = _after_insert - RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy) - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/OnExamine) + RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/on_attackby) + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine) - for(var/mat in mat_list) //Make the assoc list ref | amount - var/datum/material/M = SSmaterials.GetMaterialRef(mat) - materials[M] = 0 + for(var/mat in mat_list) //Make the assoc list material reference -> amount + var/mat_ref = SSmaterials.GetMaterialRef(mat) + if(isnull(mat_ref)) + continue + var/mat_amt = mat_list[mat] + if(isnull(mat_amt)) + mat_amt = 0 + materials[mat_ref] += mat_amt + +/datum/component/material_container/Destroy(force, silent) + materials = null + allowed_typecache = null + // if(insertion_check) + // QDEL_NULL(insertion_check) + if(precondition) + QDEL_NULL(precondition) + if(after_insert) + QDEL_NULL(after_insert) + return ..() + +/datum/component/material_container/proc/on_examine(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER -/datum/component/material_container/proc/OnExamine(datum/source, mob/user, list/examine_list) if(show_on_examine) for(var/I in materials) var/datum/material/M = I @@ -54,7 +84,9 @@ examine_list += "It has [amt] units of [lowertext(M.name)] stored." /// Proc that allows players to fill the parent with mats -/datum/component/material_container/proc/OnAttackBy(datum/source, obj/item/I, mob/living/user) +/datum/component/material_container/proc/on_attackby(datum/source, obj/item/I, mob/living/user) + SIGNAL_HANDLER + var/list/tc = allowed_typecache if(disable_attackby) return @@ -63,20 +95,21 @@ if(I.item_flags & ABSTRACT) return if((I.flags_1 & HOLOGRAM_1) || (I.item_flags & NO_MAT_REDEMPTION) || (tc && !is_type_in_typecache(I, tc))) + // if(!(mat_container_flags & MATCONTAINER_SILENT)) to_chat(user, "[parent] won't accept [I]!") return . = COMPONENT_NO_AFTERATTACK var/datum/callback/pc = precondition if(pc && !pc.Invoke(user)) return - var/material_amount = get_item_material_amount(I) + var/material_amount = get_item_material_amount(I) //, mat_container_flags) if(!material_amount) to_chat(user, "[I] does not contain sufficient materials to be accepted by [parent].") return if((!precise_insertion || !GLOB.typecache_stack[I.type]) && !has_space(material_amount)) - to_chat(user, "[parent] has not enough space. Please remove materials from [parent] in order to insert more.") + to_chat(user, "[parent] is full. Please remove materials from [parent] in order to insert more.") return - user_insert(I, user) + user_insert(I, user) //, mat_container_flags) /// Proc used for when player inserts materials /datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user) @@ -94,7 +127,7 @@ if(!user.temporarilyRemoveItemFromInventory(I)) to_chat(user, "[I] is stuck to you and cannot be placed into [parent].") return - var/inserted = insert_item(I, stack_amt = requested_amount) + var/inserted = insert_item(I, stack_amt = requested_amount)//, breakdown_flags= mat_container_flags) if(inserted) to_chat(user, "You insert a material total of [inserted] into [parent].") qdel(I) @@ -117,16 +150,46 @@ last_inserted_id = insert_item_materials(I, multiplier) return material_amount +/** + * Inserts the relevant materials from an item into this material container. + * + * Arguments: + * - [source][/obj/item]: The source of the materials we are inserting. + * - multiplier: The multiplier for the materials being inserted. + * - breakdown_flags: The breakdown bitflags that will be used to retrieve the materials from the source + */ /datum/component/material_container/proc/insert_item_materials(obj/item/I, multiplier = 1) var/primary_mat var/max_mat_value = 0 - for(var/MAT in materials) - materials[MAT] += I.custom_materials[MAT] * multiplier - total_amount += I.custom_materials[MAT] * multiplier - if(I.custom_materials[MAT] > max_mat_value) + var/list/item_materials = I.custom_materials + for(var/MAT in item_materials) + if(!can_hold_material(MAT)) + continue + materials[MAT] += item_materials[MAT] * multiplier + total_amount += item_materials[MAT] * multiplier + if(item_materials[MAT] > max_mat_value) + max_mat_value = item_materials[MAT] primary_mat = MAT + return primary_mat +/** + * The default check for whether we can add materials to this material container. + * + * Arguments: + * - [mat][/atom/material]: The material we are checking for insertability. + */ +/datum/component/material_container/proc/can_hold_material(datum/material/mat) + if(mat in allowed_typecache) + return TRUE + if(istype(mat) && (((mat.id in allowed_typecache) ||mat.type in allowed_materials))) + allowed_materials += mat // This could get messy with passing lists by ref... but if you're doing that the list expansion is probably being taken care of elsewhere anyway... + return TRUE + // if(insertion_check?.Invoke(mat)) + // allowed_materials += mat + // return TRUE + return FALSE + /// For inserting an amount of material /datum/component/material_container/proc/insert_amount_mat(amt, var/datum/material/mat) if(!istype(mat)) diff --git a/code/datums/materials/_material.dm b/code/datums/materials/_material.dm index 5148aab4ac..ec8037cfa6 100644 --- a/code/datums/materials/_material.dm +++ b/code/datums/materials/_material.dm @@ -1,15 +1,24 @@ /*! Material datum + Simple datum which is instanced once per type and is used for every object of said material. It has a variety of variables that define behavior. Subtyping from this makes it easier to create your own materials. + */ /datum/material + /// What the material is referred to as IC. var/name = "material" + /// A short description of the material. Not used anywhere, yet... var/desc = "its..stuff." + /// What the material is indexed by in the SSmaterials.materials list. Defaults to the type of the material. + var/id + ///Base color of the material, is used for greyscale. Item isn't changed in color if this is null. var/color ///Base alpha of the material, is used for greyscale icons. var/alpha + ///Bitflags that influence how SSmaterials handles this material. + // var/init_flags = MATERIAL_INIT_MAPLOAD ///Materials "Traits". its a map of key = category | Value = Bool. Used to define what it can be used for var/list/categories = list() ///The type of sheet this material creates. This should be replaced as soon as possible by greyscale sheets @@ -22,7 +31,7 @@ Simple datum which is instanced once per type and is used for every object of sa var/value_per_unit = 0 ///Armor modifiers, multiplies an items normal armor vars by these amounts. var/armor_modifiers = list("melee" = 1, "bullet" = 1, "laser" = 1, "energy" = 1, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 1, "acid" = 1) - ///How beautiful is this material per unit? + ///How beautiful is this material per unit. var/beauty_modifier = 0 ///Can be used to override the sound items make, lets add some SLOSHing. var/item_sound_override @@ -30,14 +39,31 @@ Simple datum which is instanced once per type and is used for every object of sa var/turf_sound_override ///what texture icon state to overlay var/texture_layer_icon_state - ///a cached filter for the texture icon + ///a cached icon for the texture filter var/cached_texture_filter + ///What type of shard the material will shatter to + var/obj/item/shard_type + + +/** Handles initializing the material. + * + * Arugments: + * - _id: The ID the material should use. Overrides the existing ID. + */ +/datum/material/proc/Initialize(_id, ...) + if(_id) + id = _id + else if(isnull(id)) + id = type + + if(texture_layer_icon_state) + cached_texture_filter = icon('icons/materials/composite.dmi', texture_layer_icon_state) + + return TRUE /datum/material/New() . = ..() - if(texture_layer_icon_state) - var/texture_icon = icon('icons/materials/composite.dmi', texture_layer_icon_state) - cached_texture_filter = filter(type="layer", icon=texture_icon, blend_mode = BLEND_INSET_OVERLAY) + Initialize() ///This proc is called when the material is added to an object. /datum/material/proc/on_applied(atom/source, amount, material_flags) @@ -48,8 +74,10 @@ Simple datum which is instanced once per type and is used for every object of sa source.alpha = alpha if(texture_layer_icon_state) ADD_KEEP_TOGETHER(source, MATERIAL_SOURCE(src)) - source.filters += cached_texture_filter + source.add_filter("material_texture_[name]",1,layering_filter(icon=cached_texture_filter,blend_mode=BLEND_INSET_OVERLAY)) + if(alpha < 255) + source.opacity = FALSE if(material_flags & MATERIAL_ADD_PREFIX) source.name = "[name] [source.name]" @@ -59,7 +87,7 @@ Simple datum which is instanced once per type and is used for every object of sa if(istype(source, /obj)) //objs on_applied_obj(source, amount, material_flags) - else if(isturf(source, /turf)) //turfs + if(istype(source, /turf)) //turfs on_applied_turf(source, amount, material_flags) source.mat_update_desc(src) @@ -67,8 +95,9 @@ Simple datum which is instanced once per type and is used for every object of sa ///This proc is called when a material updates an object's description /atom/proc/mat_update_desc(/datum/material/mat) return + ///This proc is called when the material is added to an object specifically. -/datum/material/proc/on_applied_obj(var/obj/o, amount, material_flags) +/datum/material/proc/on_applied_obj(obj/o, amount, material_flags) if(material_flags & MATERIAL_AFFECT_STATISTICS) var/new_max_integrity = CEILING(o.max_integrity * integrity_modifier, 1) o.modify_max_integrity(new_max_integrity) @@ -92,43 +121,73 @@ Simple datum which is instanced once per type and is used for every object of sa I.hitsound = item_sound_override I.usesound = item_sound_override I.throwhitsound = item_sound_override + // I.mob_throw_hit_sound = item_sound_override + // I.equip_sound = item_sound_override + // I.pickup_sound = item_sound_override + // I.drop_sound = item_sound_override -/datum/material/proc/on_applied_turf(var/turf/T, amount, material_flags) +/datum/material/proc/on_applied_turf(turf/T, amount, material_flags) if(isopenturf(T)) - if(!turf_sound_override) - return - var/turf/open/O = T - O.footstep = turf_sound_override - O.barefootstep = turf_sound_override - O.clawfootstep = turf_sound_override - O.heavyfootstep = turf_sound_override + if(turf_sound_override) + var/turf/open/O = T + O.footstep = turf_sound_override + O.barefootstep = turf_sound_override + O.clawfootstep = turf_sound_override + O.heavyfootstep = turf_sound_override + // if(alpha < 255) + // T.AddElement(/datum/element/turf_z_transparency, TRUE) + return ///This proc is called when the material is removed from an object. -/datum/material/proc/on_removed(atom/source, material_flags) +/datum/material/proc/on_removed(atom/source, amount, material_flags) if(material_flags & MATERIAL_COLOR) //Prevent changing things with pre-set colors, to keep colored toolboxes their looks for example if(color) source.remove_atom_colour(FIXED_COLOUR_PRIORITY, color) - source.alpha = initial(source.alpha) if(texture_layer_icon_state) - source.filters -= cached_texture_filter + source.remove_filter("material_texture_[name]") REMOVE_KEEP_TOGETHER(source, MATERIAL_SOURCE(src)) + source.alpha = initial(source.alpha) if(material_flags & MATERIAL_ADD_PREFIX) source.name = initial(source.name) - if(istype(source, /obj)) //objs - on_removed_obj(source, material_flags) + if(beauty_modifier) //component/beauty/InheritComponent() will handle the removal. + addtimer(CALLBACK(source, /datum.proc/_AddElement, list(/datum/element/beauty, -beauty_modifier * amount)), 0) - else if(istype(source, /turf)) //turfs - on_removed_turf(source, material_flags) + if(istype(source, /obj)) //objs + on_removed_obj(source, amount, material_flags) + + if(istype(source, /turf)) //turfs + on_removed_turf(source, amount, material_flags) ///This proc is called when the material is removed from an object specifically. -/datum/material/proc/on_removed_obj(obj/o, material_flags) +/datum/material/proc/on_removed_obj(obj/o, amount, material_flags) if(material_flags & MATERIAL_AFFECT_STATISTICS) var/new_max_integrity = initial(o.max_integrity) o.modify_max_integrity(new_max_integrity) o.force = initial(o.force) o.throwforce = initial(o.throwforce) -/datum/material/proc/on_removed_turf(turf/T, material_flags) - return +/datum/material/proc/on_removed_turf(turf/T, amount, material_flags) + // if(alpha) + // RemoveElement(/datum/element/turf_z_transparency, FALSE) + +/** + * This proc is called when the mat is found in an item that's consumed by accident. see /obj/item/proc/on_accidental_consumption. + * Arguments + * * M - person consuming the mat + * * S - (optional) item the mat is contained in (NOT the item with the mat itself) + */ +/datum/material/proc/on_accidental_mat_consumption(mob/living/carbon/M, obj/item/S) + return FALSE + +/** Returns the composition of this material. + * + * Mostly used for alloys when breaking down materials. + * + * Arguments: + * - amount: The amount of the material to break down. + * - breakdown_flags: Some flags dictating how exactly this material is being broken down. + */ +/datum/material/proc/return_composition(amount=1, breakdown_flags=NONE) + return list((src) = amount) // Yes we need the parenthesis, without them BYOND stringifies src into "src" and things break. diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 0a866449cc..18674cdb17 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1214,6 +1214,10 @@ filter_data -= name update_filters() +/atom/proc/clear_filters() + filter_data = null + filters = null + /atom/proc/intercept_zImpact(atom/movable/AM, levels = 1) . |= SEND_SIGNAL(src, COMSIG_ATOM_INTERCEPT_Z_FALL, AM, levels) @@ -1222,7 +1226,7 @@ if(custom_materials) //Only runs if custom materials existed at first. Should usually be the case but check anyways for(var/i in custom_materials) var/datum/material/custom_material = SSmaterials.GetMaterialRef(i) - custom_material.on_removed(src, material_flags) //Remove the current materials + custom_material.on_removed(src, custom_materials[i], material_flags) //Remove the current materials if(!length(materials)) custom_materials = null diff --git a/code/game/objects/items/stacks/cash.dm b/code/game/objects/items/stacks/cash.dm index e2036835ce..68762a63c7 100644 --- a/code/game/objects/items/stacks/cash.dm +++ b/code/game/objects/items/stacks/cash.dm @@ -14,7 +14,7 @@ grind_results = list(/datum/reagent/cellulose = 10) var/value = 0 -/obj/item/stack/spacecash/Initialize() +/obj/item/stack/spacecash/Initialize(mapload, new_amount, merge = TRUE) . = ..() update_desc() diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index de2e3b89fe..026b73ca15 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -41,6 +41,8 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ material_type = /datum/material/glass point_value = 1 tableVariant = /obj/structure/table/glass + matter_amount = 4 + cost = 500 shard_type = /obj/item/shard /obj/item/stack/sheet/glass/suicide_act(mob/living/carbon/user) @@ -69,12 +71,13 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ if (get_amount() < 1 || CC.get_amount() < 5) to_chat(user, "You attach wire to the [name].") var/obj/item/stack/light_w/new_tile = new(user.loc) new_tile.add_fingerprint(user) - else if(istype(W, /obj/item/stack/rods)) + return + if(istype(W, /obj/item/stack/rods)) var/obj/item/stack/rods/V = W if (V.get_amount() >= 1 && get_amount() >= 1) var/obj/item/stack/sheet/rglass/RG = new (get_turf(user)) @@ -86,9 +89,8 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ user.put_in_hands(RG) else to_chat(user, "You need one rod and one sheet of glass to make reinforced glass!") - return - else - return ..() + return + return ..() @@ -164,6 +166,7 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ merge_type = /obj/item/stack/sheet/rglass grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/iron = 10) point_value = 4 + matter_amount = 6 shard_type = /obj/item/shard /obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, params) @@ -211,6 +214,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ merge_type = /obj/item/stack/sheet/plasmarglass grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10, /datum/reagent/iron = 10) point_value = 23 + matter_amount = 8 shard_type = /obj/item/shard/plasma /obj/item/stack/sheet/plasmarglass/get_main_recipes() diff --git a/code/game/objects/items/stacks/sheets/sheets.dm b/code/game/objects/items/stacks/sheets/sheets.dm index 57c8ba75d8..57d0659ef6 100644 --- a/code/game/objects/items/stacks/sheets/sheets.dm +++ b/code/game/objects/items/stacks/sheets/sheets.dm @@ -19,7 +19,7 @@ ///What type of wall does this sheet spawn var/walltype -/obj/item/stack/sheet/Initialize(mapload, new_amount, merge) +/obj/item/stack/sheet/Initialize(mapload, new_amount, merge = TRUE) . = ..() pixel_x = rand(-4, 4) pixel_y = rand(-4, 4) diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 436c59ff7d..017c210070 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -42,6 +42,11 @@ var/matter_amount = 0 /obj/item/stack/Initialize(mapload, new_amount, merge = TRUE) + //do this first, lazily inflate the value + if(LAZYLEN(custom_materials)) + for(var/i in custom_materials) + custom_materials[i] *= amount + if(new_amount != null) amount = new_amount while(amount > max_amount) @@ -88,7 +93,13 @@ /** Updates the custom materials list of this stack. */ /obj/item/stack/proc/update_custom_materials() - set_custom_materials(mats_per_unit, amount) + set_custom_materials(mats_per_unit, amount, is_update=TRUE) + +/** + * Override to make things like metalgen accurately set custom materials + */ +/obj/item/stack/set_custom_materials(list/materials, multiplier=1, is_update=FALSE) + return is_update ? ..() : set_mats_per_unit(materials, multiplier / (amount || 1)) /obj/item/stack/on_grind() . = ..() @@ -297,50 +308,55 @@ return TRUE return ..() -/obj/item/stack/proc/building_checks(datum/stack_recipe/R, multiplier) - if (get_amount() < R.req_amount*multiplier) - if (R.req_amount*multiplier>1) - to_chat(usr, "You haven't got enough [src] to build \the [R.req_amount*multiplier] [R.title]\s!") +/obj/item/stack/proc/building_checks(datum/stack_recipe/recipe, multiplier) + if (get_amount() < recipe.req_amount*multiplier) + if (recipe.req_amount*multiplier>1) + to_chat(usr, "You haven't got enough [src] to build \the [recipe.req_amount*multiplier] [recipe.title]\s!") else - to_chat(usr, "You haven't got enough [src] to build \the [R.title]!") + to_chat(usr, "You haven't got enough [src] to build \the [recipe.title]!") return FALSE - var/turf/T = get_turf(usr) + var/turf/dest_turf = get_turf(usr) - var/obj/D = R.result_type - if(R.window_checks && !valid_window_location(T, initial(D.dir) == FULLTILE_WINDOW_DIR ? FULLTILE_WINDOW_DIR : usr.dir)) - to_chat(usr, "The [R.title] won't fit here!") - return FALSE - if(R.one_per_turf && (locate(R.result_type) in T)) - to_chat(usr, "There is another [R.title] here!") - return FALSE - if(R.on_floor) - if(!isfloorturf(T)) - to_chat(usr, "\The [R.title] must be constructed on the floor!") + // If we're making a window, we have some special snowflake window checks to do. + if(ispath(recipe.result_type, /obj/structure/window)) + var/obj/structure/window/result_path = recipe.result_type + if(!valid_window_location(dest_turf, usr.dir, is_fulltile = initial(result_path.fulltile))) + to_chat(usr, "The [recipe.title] won't fit here!") return FALSE - for(var/obj/AM in T) - if(istype(AM,/obj/structure/grille)) + + if(recipe.one_per_turf && (locate(recipe.result_type) in dest_turf)) + to_chat(usr, "There is another [recipe.title] here!") + return FALSE + + if(recipe.on_floor) + if(!isfloorturf(dest_turf)) + to_chat(usr, "\The [recipe.title] must be constructed on the floor!") + return FALSE + + for(var/obj/object in dest_turf) + if(istype(object, /obj/structure/grille)) continue - if(istype(AM,/obj/structure/table)) + if(istype(object, /obj/structure/table)) continue - if(istype(AM,/obj/structure/window)) - var/obj/structure/window/W = AM - if(!W.fulltile) + if(istype(object, /obj/structure/window)) + var/obj/structure/window/window_structure = object + if(!window_structure.fulltile) continue - if(AM.density) - to_chat(usr, "Theres a [AM.name] here. You cant make a [R.title] here!") + if(object.density) + to_chat(usr, "There is \a [object.name] here. You cant make \a [recipe.title] here!") return FALSE - if(R.placement_checks) - switch(R.placement_checks) + if(recipe.placement_checks) + switch(recipe.placement_checks) if(STACK_CHECK_CARDINALS) var/turf/step for(var/direction in GLOB.cardinals) - step = get_step(T, direction) - if(locate(R.result_type) in step) - to_chat(usr, "\The [R.title] must not be built directly adjacent to another!") + step = get_step(dest_turf, direction) + if(locate(recipe.result_type) in step) + to_chat(usr, "\The [recipe.title] must not be built directly adjacent to another!") return FALSE if(STACK_CHECK_ADJACENT) - if(locate(R.result_type) in range(1, T)) - to_chat(usr, "\The [R.title] must be constructed at least one tile away from others of its type!") + if(locate(recipe.result_type) in range(1, dest_turf)) + to_chat(usr, "\The [recipe.title] must be constructed at least one tile away from others of its type!") return FALSE return TRUE @@ -513,15 +529,12 @@ var/time = 0 var/one_per_turf = FALSE var/on_floor = FALSE - var/window_checks = FALSE var/placement_checks = FALSE var/applies_mats = FALSE var/trait_booster = null var/trait_modifier = 1 /datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1,time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE, placement_checks = FALSE, applies_mats = FALSE, trait_booster = null, trait_modifier = 1) - - src.title = title src.result_type = result_type src.req_amount = req_amount @@ -530,7 +543,6 @@ src.time = time src.one_per_turf = one_per_turf src.on_floor = on_floor - src.window_checks = window_checks src.placement_checks = placement_checks src.applies_mats = applies_mats src.trait_booster = trait_booster diff --git a/code/modules/admin/callproc/callproc.dm b/code/modules/admin/callproc/callproc.dm index c13353b7cd..21bf732493 100644 --- a/code/modules/admin/callproc/callproc.dm +++ b/code/modules/admin/callproc/callproc.dm @@ -1,4 +1,3 @@ - /client/proc/callproc() set category = "Debug" set name = "Advanced ProcCall" @@ -21,7 +20,7 @@ return target = value["value"] if(!istype(target)) - to_chat(usr, "Invalid target.") + to_chat(usr, "Invalid target.", confidential = TRUE) return if("No") target = null @@ -41,12 +40,12 @@ if(targetselected) if(!hascall(target, procname)) - to_chat(usr, "Error: callproc(): type [target.type] has no [proctype] named [procpath].") + to_chat(usr, "Error: callproc(): type [target.type] has no [proctype] named [procpath].", confidential = TRUE) return else procpath = "/[proctype]/[procname]" if(!text2path(procpath)) - to_chat(usr, "Error: callproc(): [procpath] does not exist.") + to_chat(usr, "Error: callproc(): [procpath] does not exist.", confidential = TRUE) return var/list/lst = get_callproc_args() @@ -55,24 +54,24 @@ if(targetselected) if(!target) - to_chat(usr, "Error: callproc(): owner of proc no longer exists.") + to_chat(usr, "Error: callproc(): owner of proc no longer exists.", confidential = TRUE) return var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]." log_admin(msg) - message_admins(msg) //Proccall announce removed. + message_admins(msg) //Proccall announce removed. admin_ticket_log(target, msg) returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc else //this currently has no hascall protection. wasn't able to get it working. log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") - message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") //Proccall announce removed. + message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") //Proccall announce removed. returnval = WrapAdminProcCall(GLOBAL_PROC, procname, lst) // Pass the lst as an argument list to the proc SSblackbox.record_feedback("tally", "admin_verb", 1, "Advanced ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! if(get_retval) get_retval += returnval . = get_callproc_returnval(returnval, procname) if(.) - to_chat(usr, .) + to_chat(usr, ., confidential = TRUE) GLOBAL_VAR(AdminProcCaller) GLOBAL_PROTECT(AdminProcCaller) @@ -84,34 +83,30 @@ GLOBAL_VAR(LastAdminCalledTarget) GLOBAL_PROTECT(LastAdminCalledTarget) GLOBAL_VAR(LastAdminCalledProc) GLOBAL_PROTECT(LastAdminCalledProc) -GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention) -GLOBAL_PROTECT(AdminProcCallSpamPrevention) +/// Wrapper for proccalls where the datum is flagged as vareditted /proc/WrapAdminProcCall(datum/target, procname, list/arguments) - if(target != GLOBAL_PROC && procname == "Del") - to_chat(usr, "Calling Del() is not allowed") + if(target && procname == "Del") + to_chat(usr, "Calling Del() is not allowed", confidential = TRUE) return if(target != GLOBAL_PROC && !target.CanProcCall(procname)) - to_chat(usr, "Proccall on [target.type]/proc/[procname] is disallowed!") + to_chat(usr, "Proccall on [target.type]/proc/[procname] is disallowed!", confidential = TRUE) return var/current_caller = GLOB.AdminProcCaller var/ckey = usr ? usr.client.ckey : GLOB.AdminProcCaller if(!ckey) CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]") + if(current_caller && current_caller != ckey) - if(!GLOB.AdminProcCallSpamPrevention[ckey]) - to_chat(usr, "Another set of admin called procs are still running, your proc will be run after theirs finish.") - GLOB.AdminProcCallSpamPrevention[ckey] = TRUE - UNTIL(!GLOB.AdminProcCaller) - to_chat(usr, "Running your proc") - GLOB.AdminProcCallSpamPrevention -= ckey - else - UNTIL(!GLOB.AdminProcCaller) + // hey kev i removed the sleep here because it blocks this proc + to_chat(usr, "Another set of admin called procs are still running. Try again later.", confidential = TRUE) + return + GLOB.LastAdminCalledProc = procname if(target != GLOBAL_PROC) - GLOB.LastAdminCalledTargetRef = "[REF(target)]" - GLOB.AdminProcCaller = ckey //if this runtimes, too bad for you + GLOB.LastAdminCalledTargetRef = REF(target) + GLOB.AdminProcCaller = ckey //if this runtimes, too bad for you ++GLOB.AdminProcCallCount . = world.WrapAdminProcCall(target, procname, arguments) if(--GLOB.AdminProcCallCount == 0) @@ -120,11 +115,11 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) //adv proc call this, ya nerds /world/proc/WrapAdminProcCall(datum/target, procname, list/arguments) if(target == GLOBAL_PROC) - return call(text2path("/proc/[procname]"))(arglist(arguments)) + return call("/proc/[procname]")(arglist(arguments)) else if(target != world) return call(target, procname)(arglist(arguments)) else - log_admin_private("[key_name(usr)] attempted to call world/proc/[procname] with arguments: [english_list(arguments)]") + log_admin("[key_name(usr)] attempted to call world/proc/[procname] with arguments: [english_list(arguments)]") /proc/IsAdminAdvancedProcCall() #ifdef TESTING @@ -145,17 +140,17 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) if(!procname) return if(!hascall(A,procname)) - to_chat(usr, "Error: callproc_datum(): type [A.type] has no proc named [procname].") + to_chat(usr, "Error: callproc_datum(): type [A.type] has no proc named [procname].", confidential = TRUE) return var/list/lst = get_callproc_args() if(!lst) return if(!A || !IsValidSrc(A)) - to_chat(usr, "Error: callproc_datum(): owner of proc no longer exists.") + to_chat(usr, "Error: callproc_datum(): owner of proc no longer exists.", confidential = TRUE) return + log_admin("[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]." - log_admin(msg) message_admins(msg) admin_ticket_log(A, msg) SSblackbox.record_feedback("tally", "admin_verb", 1, "Atom ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -163,7 +158,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) var/returnval = WrapAdminProcCall(A, procname, lst) // Pass the lst as an argument list to the proc . = get_callproc_returnval(returnval,procname) if(.) - to_chat(usr, .) + to_chat(usr, ., confidential = TRUE) /client/proc/get_callproc_args() var/argnum = input("Number of arguments","Number:",0) as num|null @@ -188,7 +183,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) . = "" if(islist(returnval)) var/list/returnedlist = returnval - . = "" + . = "" if(returnedlist.len) var/assoc_check = returnedlist[1] if(istext(assoc_check) && (returnedlist[assoc_check] != null)) @@ -202,7 +197,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) . += "\n[elem]" else . = "[procname] returned an empty list" - . += "" + . += "" else - . = "[procname] returned: [!isnull(returnval) ? returnval : "null"]" + . = "[procname] returned: [!isnull(returnval) ? html_encode(returnval) : "null"]" diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index 494942691a..ad0f7927a4 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -194,7 +194,6 @@ can_min_release_pressure = (ONE_ATMOSPHERE / 30) prototype = TRUE - /obj/machinery/portable_atmospherics/canister/proto/default/oxygen name = "prototype canister" desc = "A prototype canister for a prototype bike, what could go wrong?" @@ -209,7 +208,6 @@ air_contents.copy_from(existing_mixture) else create_gas() - update_icon() diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 1058277cdf..9e779b9c1b 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -531,7 +531,7 @@ By design, d1 is the smallest direction and d2 is the highest user.visible_message("[user] is strangling [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") return(OXYLOSS) -/obj/item/stack/cable_coil/Initialize(mapload, new_amount = null) +/obj/item/stack/cable_coil/Initialize(mapload, new_amount, merge = TRUE) . = ..() pixel_x = rand(-2,2) pixel_y = rand(-2,2) @@ -823,7 +823,7 @@ By design, d1 is the smallest direction and d2 is the highest /obj/item/stack/cable_coil/random color = "#ffffff" -/obj/item/stack/cable_coil/random/Initialize(mapload, new_amount = null, param_color = null) +/obj/item/stack/cable_coil/random/Initialize(mapload, new_amount, merge = TRUE, param_color = null) . = ..() var/list/cable_colors = GLOB.cable_colors color = pick(cable_colors) @@ -835,12 +835,13 @@ By design, d1 is the smallest direction and d2 is the highest amount = null icon_state = "coil2" -/obj/item/stack/cable_coil/cut/Initialize(mapload) - . = ..() +/obj/item/stack/cable_coil/cut/Initialize(mapload, new_amount, merge = TRUE) + // do random amount calls BEFORE we add the mats or else the code eats shit and dies if(!amount) amount = rand(1,2) pixel_x = rand(-2,2) pixel_y = rand(-2,2) + . = ..() update_icon() /obj/item/stack/cable_coil/cut/red @@ -869,7 +870,7 @@ By design, d1 is the smallest direction and d2 is the highest /obj/item/stack/cable_coil/cut/random color = "#ffffff" -/obj/item/stack/cable_coil/cut/random/Initialize(mapload, new_amount = null, param_color = null) +/obj/item/stack/cable_coil/cut/random/Initialize(mapload, new_amount, merge = TRUE, param_color = null) . = ..() var/list/cable_colors = GLOB.cable_colors color = pick(cable_colors) diff --git a/tools/build/build.js b/tools/build/build.js index 6236ec6b53..089a78f1bc 100755 --- a/tools/build/build.js +++ b/tools/build/build.js @@ -48,6 +48,7 @@ const taskDm = new Task('dm') .depends('tgui/public/tgui.html') .depends('tgui/public/*.bundle.*') .depends('tgui/public/*.chunk.*') + .depends(process.platform === 'win32' ? 'byond-extools.*' : 'libbyond-extools.*') .depends('tgstation.dme') .provides('tgstation.dmb') .provides('tgstation.rsc') diff --git a/tools/ci/check_grep.sh b/tools/ci/check_grep.sh index 51a53ac4be..fe92630aad 100755 --- a/tools/ci/check_grep.sh +++ b/tools/ci/check_grep.sh @@ -70,7 +70,7 @@ while read f; do done < <(find . -type f -name '*.dm') if grep -P '^/[\w/]\S+\(.*(var/|, ?var/.*).*\)' code/**/*.dm; then echo "changed files contains proc argument starting with 'var'" - st=1 + # st=1 fi; if grep -i 'centcomm' code/**/*.dm; then echo "ERROR: Misspelling(s) of CENTCOM detected in code, please remove the extra M(s)." diff --git a/tools/ci/run_server.sh b/tools/ci/run_server.sh index 4d943846f0..ef548370f1 100755 --- a/tools/ci/run_server.sh +++ b/tools/ci/run_server.sh @@ -7,6 +7,11 @@ mkdir ci_test/config #test config cp tools/ci/ci_config.txt ci_test/config/config.txt +#throw extools into ldd +cp libbyond-extools.so ~/.byond/bin/libbyond-extools.so +chmod +x ~/.byond/bin/libbyond-extools.so +ldd ~/.byond/bin/libbyond-extools.so + cd ci_test DreamDaemon tgstation.dmb -close -trusted -verbose -params "log-directory=ci" cd ..