Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -9,32 +9,47 @@ jobs:
|
||||
name: "Compile changelogs"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "Check for CHANGELOG_ENABLER secret and pass true to output if it exists to be checked by later steps"
|
||||
id: value_holder
|
||||
env:
|
||||
CHANGELOG_ENABLER: ${{ secrets.CHANGELOG_ENABLER }}
|
||||
run: |
|
||||
unset SECRET_EXISTS
|
||||
if [-n $CHANGELOG_ENABLER]; then SECRET_EXISTS='true' ; fi
|
||||
echo ::set-output name=CL_ENABLED::${SECRET_EXISTS}
|
||||
- name: "Setup python"
|
||||
if: steps.value_holder.outputs.CL_ENABLED
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: "Install deps"
|
||||
if: steps.value_holder.outputs.CL_ENABLED
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install pyyaml
|
||||
sudo apt-get install dos2unix
|
||||
- name: "Checkout"
|
||||
if: steps.value_holder.outputs.CL_ENABLED
|
||||
uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 25
|
||||
- name: "Compile"
|
||||
if: steps.value_holder.outputs.CL_ENABLED
|
||||
run: |
|
||||
python tools/ss13_genchangelog.py html/changelog.html html/changelogs
|
||||
- name: "Convert Lineendings"
|
||||
if: steps.value_holder.outputs.CL_ENABLED
|
||||
run: |
|
||||
unix2dos html/changelogs/.all_changelog.yml
|
||||
- name: Commit
|
||||
if: steps.value_holder.outputs.CL_ENABLED
|
||||
run: |
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "Changelogs"
|
||||
git pull origin master
|
||||
git commit -m "Automatic changelog compile [ci skip]" -a || true
|
||||
- name: "Push"
|
||||
if: steps.value_holder.outputs.CL_ENABLED
|
||||
uses: ad-m/github-push-action@master
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -5,9 +5,21 @@
|
||||
// global signals
|
||||
// These are signals which can be listened to by any component on any parent
|
||||
// start global signals with "!", this used to be necessary but now it's just a formatting choice
|
||||
#define COMSIG_GLOB_NEW_Z "!new_z" //from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args)
|
||||
#define COMSIG_GLOB_VAR_EDIT "!var_edit" //called after a successful var edit somewhere in the world: (list/args)
|
||||
#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special" //global living say plug - use sparingly: (mob/speaker , message)
|
||||
/// from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args)
|
||||
#define COMSIG_GLOB_NEW_Z "!new_z"
|
||||
/// called after a successful var edit somewhere in the world: (list/args)
|
||||
#define COMSIG_GLOB_VAR_EDIT "!var_edit"
|
||||
/// called after an explosion happened : (epicenter, devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range)
|
||||
#define COMSIG_GLOB_EXPLOSION "!explosion"
|
||||
/// mob was created somewhere : (mob)
|
||||
#define COMSIG_GLOB_MOB_CREATED "!mob_created"
|
||||
/// mob died somewhere : (mob , gibbed)
|
||||
#define COMSIG_GLOB_MOB_DEATH "!mob_death"
|
||||
/// global living say plug - use sparingly: (mob/speaker , message)
|
||||
#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special"
|
||||
/// called by datum/cinematic/play() : (datum/cinematic/new_cinematic)
|
||||
#define COMSIG_GLOB_PLAY_CINEMATIC "!play_cinematic"
|
||||
#define COMPONENT_GLOB_BLOCK_CINEMATIC 1
|
||||
|
||||
// signals from globally accessible objects
|
||||
/// from SSsun when the sun changes position : (azimuth)
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
name = "Initializing..."
|
||||
var/target
|
||||
|
||||
/obj/effect/statclick/New(loc, text, target) //Don't port this to Initialize it's too critical
|
||||
INITIALIZE_IMMEDIATE(/obj/effect/statclick) //it's new, but rebranded.
|
||||
|
||||
/obj/effect/statclick/Initialize(mapload, text, target) //Don't port this to Initialize it's too critical
|
||||
. = ..()
|
||||
name = text
|
||||
src.target = target
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/**
|
||||
* Failsafe
|
||||
*
|
||||
* Pretty much pokes the MC to make sure it's still alive.
|
||||
@@ -31,7 +31,7 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
|
||||
Initialize()
|
||||
|
||||
/datum/controller/failsafe/Initialize()
|
||||
set waitfor = 0
|
||||
set waitfor = FALSE
|
||||
Failsafe.Loop()
|
||||
if(!QDELETED(src))
|
||||
qdel(src) //when Loop() returns, we delete ourselves and let the mc recreate us
|
||||
@@ -97,4 +97,4 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
|
||||
|
||||
/datum/controller/failsafe/stat_entry(msg)
|
||||
msg = "Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"
|
||||
return msg
|
||||
return msg
|
||||
@@ -20,8 +20,9 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
|
||||
Initialize()
|
||||
|
||||
/datum/controller/global_vars/Destroy()
|
||||
//fuck off kevinz
|
||||
/datum/controller/global_vars/Destroy(force)
|
||||
// This is done to prevent an exploit where admins can get around protected vars
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
return QDEL_HINT_IWILLGC
|
||||
|
||||
/datum/controller/global_vars/stat_entry(msg)
|
||||
|
||||
@@ -97,9 +97,9 @@
|
||||
return
|
||||
|
||||
//This is used so the mc knows when the subsystem sleeps. do not override.
|
||||
/datum/controller/subsystem/proc/ignite(resumed = 0)
|
||||
/datum/controller/subsystem/proc/ignite(resumed = FALSE)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
set waitfor = 0
|
||||
set waitfor = FALSE
|
||||
. = SS_SLEEPING
|
||||
fire(resumed)
|
||||
. = state
|
||||
|
||||
@@ -451,7 +451,7 @@
|
||||
// otherwise, just reset the client mob's machine var.
|
||||
//
|
||||
/client/verb/windowclose(atomref as text)
|
||||
set hidden = 1 // hide this verb from the user's panel
|
||||
set hidden = TRUE // hide this verb from the user's panel
|
||||
set name = ".windowclose" // no autocomplete on cmd line
|
||||
|
||||
if(atomref!="null") // if passed a real atomref
|
||||
|
||||
+51
-34
@@ -1,5 +1,3 @@
|
||||
GLOBAL_LIST_EMPTY(cinematics)
|
||||
|
||||
// Use to play cinematics.
|
||||
// Watcher can be world,mob, or a list of mobs
|
||||
// Blocks until sequence is done.
|
||||
@@ -18,6 +16,7 @@ GLOBAL_LIST_EMPTY(cinematics)
|
||||
playing.is_global = TRUE
|
||||
watcher = GLOB.mob_list
|
||||
playing.play(watcher)
|
||||
qdel(playing)
|
||||
|
||||
/obj/screen/cinematic
|
||||
icon = 'icons/effects/station_explosion.dmi'
|
||||
@@ -25,12 +24,13 @@ GLOBAL_LIST_EMPTY(cinematics)
|
||||
plane = SPLASHSCREEN_PLANE
|
||||
layer = SPLASHSCREEN_LAYER
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
screen_loc = "1,1"
|
||||
screen_loc = "BOTTOM,LEFT+50%"
|
||||
appearance_flags = APPEARANCE_UI | TILE_BOUND
|
||||
|
||||
/datum/cinematic
|
||||
var/id = CINEMATIC_DEFAULT
|
||||
var/list/watching = list() //List of clients watching this
|
||||
var/list/locked = list() //Who had mob_transforming set during the cinematic
|
||||
var/list/locked = list() //Who had mob_transforming set during the cinematic
|
||||
var/is_global = FALSE //Global cinematics will override mob-specific ones
|
||||
var/obj/screen/cinematic/screen
|
||||
var/datum/callback/special_callback //For special effects synced with animation (explosions after the countdown etc)
|
||||
@@ -38,28 +38,35 @@ GLOBAL_LIST_EMPTY(cinematics)
|
||||
var/stop_ooc = TRUE //Turns off ooc when played globally.
|
||||
|
||||
/datum/cinematic/New()
|
||||
GLOB.cinematics += src
|
||||
screen = new(src)
|
||||
|
||||
/datum/cinematic/Destroy()
|
||||
GLOB.cinematics -= src
|
||||
for(var/CC in watching)
|
||||
if(!CC)
|
||||
continue
|
||||
var/client/C = CC
|
||||
//C.mob.clear_fullscreen("cinematic")
|
||||
C.screen -= screen
|
||||
watching = null
|
||||
QDEL_NULL(screen)
|
||||
for(var/mob/M in locked)
|
||||
M.mob_transforming = FALSE
|
||||
QDEL_NULL(special_callback)
|
||||
for(var/MM in locked)
|
||||
if(!MM)
|
||||
continue
|
||||
var/mob/M = MM
|
||||
M.mob_transforming = FALSE
|
||||
locked = null
|
||||
return ..()
|
||||
|
||||
/datum/cinematic/proc/play(watchers)
|
||||
//Check if you can actually play it (stop mob cinematics for global ones) and create screen objects
|
||||
for(var/A in GLOB.cinematics)
|
||||
var/datum/cinematic/C = A
|
||||
if(C == src)
|
||||
continue
|
||||
if(C.is_global || !is_global)
|
||||
return //Can't play two global or local cinematics at the same time
|
||||
//Check if cinematic can actually play (stop mob cinematics for global ones)
|
||||
if(SEND_GLOBAL_SIGNAL(COMSIG_GLOB_PLAY_CINEMATIC, src) & COMPONENT_GLOB_BLOCK_CINEMATIC)
|
||||
return
|
||||
|
||||
//Close all open windows if global
|
||||
if(is_global)
|
||||
SStgui.close_all_uis()
|
||||
//We are now playing this cinematic
|
||||
|
||||
//Handle what happens when a different cinematic tries to play over us
|
||||
RegisterSignal(SSdcs, COMSIG_GLOB_PLAY_CINEMATIC, .proc/replacement_cinematic)
|
||||
|
||||
//Pause OOC
|
||||
var/ooc_toggled = FALSE
|
||||
@@ -67,24 +74,17 @@ GLOBAL_LIST_EMPTY(cinematics)
|
||||
ooc_toggled = TRUE
|
||||
toggle_ooc(FALSE)
|
||||
|
||||
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
if(M in watchers)
|
||||
M.mob_transforming = TRUE //Should this be done for non-global cinematics or even at all ?
|
||||
locked += M
|
||||
//Close watcher ui's
|
||||
SStgui.close_user_uis(M)
|
||||
if(M.client)
|
||||
watching += M.client
|
||||
M.client.screen += screen
|
||||
else
|
||||
if(is_global)
|
||||
M.mob_transforming = TRUE
|
||||
locked += M
|
||||
//Place /obj/screen/cinematic into everyone's screens, prevent them from moving
|
||||
for(var/MM in watchers)
|
||||
var/mob/M = MM
|
||||
show_to(M, M.client)
|
||||
RegisterSignal(M, COMSIG_MOB_CLIENT_LOGIN, .proc/show_to)
|
||||
//Close watcher ui's
|
||||
SStgui.close_user_uis(M)
|
||||
|
||||
//Actually play it
|
||||
content()
|
||||
|
||||
|
||||
//Cleanup
|
||||
sleep(cleanup_time)
|
||||
|
||||
@@ -92,7 +92,17 @@ GLOBAL_LIST_EMPTY(cinematics)
|
||||
if(ooc_toggled)
|
||||
toggle_ooc(TRUE)
|
||||
|
||||
qdel(src)
|
||||
/datum/cinematic/proc/show_to(mob/M, client/C)
|
||||
//SIGNAL_HANDLER //must not wait.
|
||||
|
||||
if(!M.mob_transforming)
|
||||
locked += M
|
||||
M.mob_transforming = TRUE //Should this be done for non-global cinematics or even at all ?
|
||||
if(!C)
|
||||
return
|
||||
watching += C
|
||||
//M.overlay_fullscreen("cinematic",/obj/screen/fullscreen/cinematic_backdrop)
|
||||
C.screen += screen
|
||||
|
||||
//Sound helper
|
||||
/datum/cinematic/proc/cinematic_sound(s)
|
||||
@@ -111,6 +121,13 @@ GLOBAL_LIST_EMPTY(cinematics)
|
||||
/datum/cinematic/proc/content()
|
||||
sleep(50)
|
||||
|
||||
/datum/cinematic/proc/replacement_cinematic(datum/source, datum/cinematic/other)
|
||||
//SIGNAL_HANDLER
|
||||
|
||||
if(!is_global && other.is_global) //Allow it to play if we're local and it's global
|
||||
return NONE
|
||||
return COMPONENT_GLOB_BLOCK_CINEMATIC
|
||||
|
||||
/datum/cinematic/nuke_win
|
||||
id = CINEMATIC_NUKE_WIN
|
||||
|
||||
|
||||
+45
-17
@@ -15,22 +15,32 @@
|
||||
* If this is non zero then the object has been garbage collected and is awaiting either
|
||||
* a hard del by the GC subsystme, or to be autocollected (if it has no references)
|
||||
*/
|
||||
var/gc_destroyed //Time when this object was destroyed.
|
||||
var/gc_destroyed
|
||||
|
||||
/// Active timers with this datum as the target
|
||||
var/list/active_timers
|
||||
/// Status traits attached to this datum
|
||||
var/list/status_traits
|
||||
/// Components attached to this datum
|
||||
/// Lazy associated list in the structure of `type:component/list of components`
|
||||
|
||||
/**
|
||||
* Components attached to this datum
|
||||
*
|
||||
* Lazy associated list in the structure of `type:component/list of components`
|
||||
*/
|
||||
var/list/datum_components
|
||||
/// Any datum registered to receive signals from this datum is in this list
|
||||
/// Lazy associated list in the structure of `signal:registree/list of registrees`
|
||||
var/list/comp_lookup //it used to be for looking up components which had registered a signal but now anything can register
|
||||
/**
|
||||
* Any datum registered to receive signals from this datum is in this list
|
||||
*
|
||||
* Lazy associated list in the structure of `signal:registree/list of registrees`
|
||||
*/
|
||||
var/list/comp_lookup
|
||||
/// Lazy associated list in the structure of `signals:proctype` that are run when the datum receives that signal
|
||||
var/list/list/datum/callback/signal_procs
|
||||
/// Is this datum capable of sending signals?
|
||||
/// Set to true when a signal has been registered
|
||||
/**
|
||||
* Is this datum capable of sending signals?
|
||||
*
|
||||
* Set to true when a signal has been registered
|
||||
*/
|
||||
var/signal_enabled = FALSE
|
||||
|
||||
/// Datum level flags
|
||||
@@ -39,7 +49,12 @@
|
||||
/// A weak reference to another datum
|
||||
var/datum/weakref/weak_reference
|
||||
|
||||
///Lazy associative list of currently active cooldowns.
|
||||
/*
|
||||
* Lazy associative list of currently active cooldowns.
|
||||
*
|
||||
* cooldowns [ COOLDOWN_INDEX ] = add_timer()
|
||||
* add_timer() returns the truthy value of -1 when not stoppable, and else a truthy numeric index
|
||||
*/
|
||||
var/list/cooldowns
|
||||
|
||||
#ifdef TESTING
|
||||
@@ -51,23 +66,34 @@
|
||||
var/list/cached_vars
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Called when a href for this datum is clicked
|
||||
*
|
||||
* Sends a [COMSIG_TOPIC] signal
|
||||
*/
|
||||
/datum/Topic(href, href_list[])
|
||||
..()
|
||||
SEND_SIGNAL(src, COMSIG_TOPIC, usr, href_list)
|
||||
|
||||
|
||||
/**
|
||||
* Default implementation of clean-up code.
|
||||
*
|
||||
* This should be overridden to remove all references pointing to the object being destroyed, if
|
||||
* you do override it, make sure to call the parent and return it's return value by default
|
||||
*
|
||||
* Return an appropriate QDEL_HINT to modify handling of your deletion;
|
||||
* in most cases this is QDEL_HINT_QUEUE.
|
||||
* Return an appropriate [QDEL_HINT][QDEL_HINT_QUEUE] to modify handling of your deletion;
|
||||
* in most cases this is [QDEL_HINT_QUEUE].
|
||||
*
|
||||
* The base case is responsible for doing the following
|
||||
* * Erasing timers pointing to this datum
|
||||
* * Erasing compenents on this datum
|
||||
* * Notifying datums listening to signals from this datum that we are going away
|
||||
*
|
||||
* Returns QDEL_HINT_QUEUE
|
||||
* Returns [QDEL_HINT_QUEUE]
|
||||
*/
|
||||
/datum/proc/Destroy(force=FALSE, ...)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
tag = null
|
||||
datum_flags &= ~DF_USE_TAG //In case something tries to REF us
|
||||
weak_reference = null //ensure prompt GCing of weakref.
|
||||
@@ -112,7 +138,7 @@
|
||||
UnregisterSignal(target, signal_procs[target])
|
||||
//END: ECS SHIT
|
||||
|
||||
SSsounds.free_datum_channels(src)
|
||||
SSsounds.free_datum_channels(src) //?? (not on tg)
|
||||
|
||||
return QDEL_HINT_QUEUE
|
||||
|
||||
@@ -143,15 +169,15 @@
|
||||
to_chat(target, txt_changed_vars())
|
||||
#endif
|
||||
|
||||
//Return a LIST for serialize_datum to encode! Not the actual json!
|
||||
///Return a LIST for serialize_datum to encode! Not the actual json!
|
||||
/datum/proc/serialize_list(list/options)
|
||||
CRASH("Attempted to serialize datum [src] of type [type] without serialize_list being implemented!")
|
||||
|
||||
//Accepts a LIST from deserialize_datum. Should return src or another datum.
|
||||
///Accepts a LIST from deserialize_datum. Should return src or another datum.
|
||||
/datum/proc/deserialize_list(json, list/options)
|
||||
CRASH("Attempted to deserialize datum [src] of type [type] without deserialize_list being implemented!")
|
||||
|
||||
//Serializes into JSON. Does not encode type.
|
||||
///Serializes into JSON. Does not encode type.
|
||||
/datum/proc/serialize_json(list/options)
|
||||
. = serialize_list(options)
|
||||
if(!islist(.))
|
||||
@@ -159,13 +185,14 @@
|
||||
else
|
||||
. = json_encode(.)
|
||||
|
||||
//Deserializes from JSON. Does not parse type.
|
||||
///Deserializes from JSON. Does not parse type.
|
||||
/datum/proc/deserialize_json(list/input, list/options)
|
||||
var/list/jsonlist = json_decode(input)
|
||||
. = deserialize_list(jsonlist)
|
||||
if(!istype(., /datum))
|
||||
. = null
|
||||
|
||||
///Convert a datum into a json blob
|
||||
/proc/json_serialize_datum(datum/D, list/options)
|
||||
if(!istype(D))
|
||||
return
|
||||
@@ -174,6 +201,7 @@
|
||||
jsonlist["DATUM_TYPE"] = D.type
|
||||
return json_encode(jsonlist)
|
||||
|
||||
/// Convert a list of json to datum
|
||||
/proc/json_deserialize_datum(list/jsonlist, list/options, target_type, strict_target_type = FALSE)
|
||||
if(!islist(jsonlist))
|
||||
if(!istext(jsonlist))
|
||||
|
||||
@@ -214,6 +214,7 @@
|
||||
|
||||
/datum/point/vector/processed/Destroy()
|
||||
STOP_PROCESSING(SSprojectiles, src)
|
||||
return ..()
|
||||
|
||||
/datum/point/vector/processed/proc/start()
|
||||
last_process = world.time
|
||||
|
||||
@@ -171,6 +171,7 @@ GLOBAL_LIST_INIT_TYPED(skill_datums, /datum/skill, init_skill_datums())
|
||||
continue
|
||||
max_assoc = levels[lvl-1]
|
||||
levels["[max_assoc] +[max_assoc_start++]"] = value
|
||||
continue
|
||||
levels[key] = value
|
||||
|
||||
/datum/skill/level/sanitize_value(new_value)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/skill/level/dorfy/blacksmithing
|
||||
/datum/skill/level/dwarfy/blacksmithing
|
||||
name = "Blacksmithing"
|
||||
desc = "Making metal into fancy shapes using heat and force. Higher levels increase both your working speed at an anvil as well as the quality of your works."
|
||||
name_color = COLOR_FLOORTILE_GRAY
|
||||
skill_traits = list(SKILL_SANITY, SKILL_INTELLIGENCE, SKILL_USE_TOOL, SKILL_TRAINING_TOOL)
|
||||
ui_category = SKILL_UI_CAT_MISC
|
||||
standard_xp_lvl_up = 100 //Effectively 200xp for level 1 because of how this code works. 300 more for 2, Etc,
|
||||
|
||||
@@ -16,8 +16,12 @@
|
||||
/datum/weakref/New(datum/thing)
|
||||
reference = REF(thing)
|
||||
|
||||
/datum/weakref/Destroy()
|
||||
return QDEL_HINT_LETMELIVE //Let BYOND autoGC thiswhen nothing is using it anymore.
|
||||
/datum/weakref/Destroy(force)
|
||||
if(!force)
|
||||
return QDEL_HINT_LETMELIVE //Let BYOND autoGC thiswhen nothing is using it anymore.
|
||||
var/datum/target = resolve()
|
||||
target?.weak_reference = null
|
||||
return ..()
|
||||
|
||||
/datum/weakref/proc/resolve()
|
||||
var/datum/D = locate(reference)
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
|
||||
/// Used to "load" a persistent scar
|
||||
/datum/scar/proc/load(obj/item/bodypart/BP, version, description, specific_location, severity=WOUND_SEVERITY_SEVERE)
|
||||
if(!(BP.body_zone in applicable_zones) || !BP.is_organic_limb())
|
||||
if(!(BP.body_zone in applicable_zones) || !(BP.is_organic_limb() || BP.render_like_organic))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
* * smited- If this is a smite, we don't care about this wound for stat tracking purposes (not yet implemented)
|
||||
*/
|
||||
/datum/wound/proc/apply_wound(obj/item/bodypart/L, silent = FALSE, datum/wound/old_wound = null, smited = FALSE)
|
||||
if(!istype(L) || !L.owner || !(L.body_zone in viable_zones) || isalien(L.owner) || !L.is_organic_limb())
|
||||
if(!istype(L) || !L.owner || !(L.body_zone in viable_zones) || isalien(L.owner) || !(L.is_organic_limb() || L.render_like_organic))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
|
||||
@@ -27,6 +27,13 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/*
|
||||
This proc gets called by upgrades after installing them. Use this for things that for example need to be moved into a specific borg item,
|
||||
as performing this in action() will cause the upgrade to end up in the borg instead of its intended location due to forceMove() being called afterwards..
|
||||
*/
|
||||
/obj/item/borg/upgrade/proc/afterInstall(mob/living/silicon/robot/R, user = usr)
|
||||
return
|
||||
|
||||
/obj/item/borg/upgrade/proc/deactivate(mob/living/silicon/robot/R, user = usr)
|
||||
if (!(src in R.upgrades))
|
||||
return FALSE
|
||||
|
||||
@@ -211,6 +211,12 @@
|
||||
turf_type = /turf/open/floor/carpet/black
|
||||
tableVariant = /obj/structure/table/wood/fancy/black
|
||||
|
||||
/obj/item/stack/tile/carpet/arcade
|
||||
name = "arcade carpet"
|
||||
icon_state = "tile-carpet-arcade"
|
||||
turf_type = /turf/open/floor
|
||||
tableVariant = null
|
||||
|
||||
/obj/item/stack/tile/carpet/blackred
|
||||
name = "red carpet"
|
||||
icon_state = "tile-carpet-blackred"
|
||||
@@ -297,6 +303,15 @@
|
||||
/obj/item/stack/tile/carpet/black/fifty
|
||||
amount = 50
|
||||
|
||||
/obj/item/stack/tile/carpet/arcade/ten
|
||||
amount = 10
|
||||
|
||||
/obj/item/stack/tile/carpet/arcade/twenty
|
||||
amount = 20
|
||||
|
||||
/obj/item/stack/tile/carpet/arcade/fifty
|
||||
amount = 50
|
||||
|
||||
/obj/item/stack/tile/carpet/blackred/ten
|
||||
amount = 10
|
||||
|
||||
|
||||
@@ -131,15 +131,12 @@
|
||||
return ..()
|
||||
|
||||
/obj/structure/toilet/secret
|
||||
var/obj/item/secret
|
||||
var/secret_type = null
|
||||
|
||||
/obj/structure/toilet/secret/Initialize(mapload)
|
||||
/obj/structure/toilet/secret/Initialize()
|
||||
. = ..()
|
||||
if (secret_type)
|
||||
secret = new secret_type(src)
|
||||
secret.desc += "" //In case you want to add something to the item that spawns
|
||||
contents += secret
|
||||
new secret_type(src)
|
||||
|
||||
/obj/structure/toilet/secret/LateInitialize()
|
||||
. = ..()
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"basalt0","basalt1","basalt2","basalt3","basalt4",
|
||||
"basalt5","basalt6","basalt7","basalt8","basalt9","basalt10","basalt11","basalt12",
|
||||
"oldburning","light-on-r","light-on-y","light-on-g","light-on-b", "wood", "carpetsymbol", "carpetstar",
|
||||
"carpetcorner", "carpetside", "carpet", "ironsand1", "ironsand2", "ironsand3", "ironsand4", "ironsand5",
|
||||
"carpetcorner", "carpetside", "carpet", "arcade", "ironsand1", "ironsand2", "ironsand3", "ironsand4", "ironsand5",
|
||||
"ironsand6", "ironsand7", "ironsand8", "ironsand9", "ironsand10", "ironsand11",
|
||||
"ironsand12", "ironsand13", "ironsand14", "ironsand15",
|
||||
"snow", "snow0", "snow1", "snow2", "snow3", "snow4", "snow5", "snow6", "snow7", "snow8", "snow9", "snow10", "snow11", "snow12", "snow-ice", "snow_dug",
|
||||
|
||||
@@ -273,6 +273,13 @@
|
||||
smooth = SMOOTH_MORE
|
||||
canSmoothWith = list(/turf/open/floor/carpet/black, /turf/open/floor/carpet/blackred, /turf/open/floor/carpet/monochrome)
|
||||
|
||||
/turf/open/floor/carpet/arcade
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "arcade"
|
||||
floor_tile = /obj/item/stack/tile/carpet/arcade
|
||||
smooth = SMOOTH_FALSE
|
||||
canSmoothWith = list()
|
||||
|
||||
/turf/open/floor/carpet/blackred
|
||||
icon = 'icons/turf/floors/carpet_blackred.dmi'
|
||||
floor_tile = /obj/item/stack/tile/carpet/blackred
|
||||
|
||||
@@ -180,10 +180,12 @@
|
||||
button.screen_loc = DEFAULT_BLOODSPELLS
|
||||
button.moved = DEFAULT_BLOODSPELLS
|
||||
button.ordered = FALSE
|
||||
|
||||
/datum/action/bloodsucker/passive/Destroy()
|
||||
if(owner)
|
||||
Remove(owner)
|
||||
target = null
|
||||
return ..()
|
||||
|
||||
/////////////////////////////////// TARGETTED POWERS ///////////////////////////////////
|
||||
|
||||
|
||||
@@ -456,6 +456,7 @@
|
||||
|
||||
/obj/structure/bloodsucker/candelabrum/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..() //return a hint
|
||||
|
||||
/obj/structure/bloodsucker/candelabrum/update_icon_state()
|
||||
icon_state = "candelabrum[lit ? "_lit" : ""]"
|
||||
|
||||
@@ -390,7 +390,7 @@
|
||||
if(old_key)
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
if(M.client && M.client.key == old_key) //Only recreates the mob if the mob the client is in is dead
|
||||
M.transfer_ckey(revenant.key, FALSE)
|
||||
M.transfer_ckey(revenant, FALSE)
|
||||
key_of_revenant = TRUE
|
||||
break
|
||||
if(!key_of_revenant)
|
||||
@@ -403,7 +403,7 @@
|
||||
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
|
||||
return
|
||||
var/mob/C = pick(candidates)
|
||||
C.transfer_ckey(revenant.key, FALSE)
|
||||
C.transfer_ckey(revenant, FALSE)
|
||||
if(!revenant.key)
|
||||
qdel(revenant)
|
||||
message_admins("No ckey was found for the new revenant. Oh well!")
|
||||
@@ -411,8 +411,8 @@
|
||||
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
|
||||
return
|
||||
|
||||
message_admins("[key_of_revenant] has been [old_key == revenant.key ? "re":""]made into a revenant by reforming ectoplasm.")
|
||||
log_game("[key_of_revenant] was [old_key == revenant.key ? "re":""]made as a revenant by reforming ectoplasm.")
|
||||
message_admins("[revenant.key] has been [old_key == revenant.key ? "re":""]made into a revenant by reforming ectoplasm.")
|
||||
log_game("[revenant.key] was [old_key == revenant.key ? "re":""]made as a revenant by reforming ectoplasm.")
|
||||
visible_message("<span class='revenboldnotice'>[src] suddenly rises into the air before fading away.</span>")
|
||||
|
||||
revenant.essence = essence
|
||||
|
||||
@@ -351,6 +351,10 @@
|
||||
name = "Black Carpet Single-Pack"
|
||||
contains = list(/obj/item/stack/tile/carpet/black/fifty)
|
||||
|
||||
/datum/supply_pack/misc/carpet/arcade
|
||||
name = "Arcade Carpet Single-Pack"
|
||||
contains = list(/obj/item/stack/tile/carpet/arcade/fifty)
|
||||
|
||||
/datum/supply_pack/misc/carpet/premium
|
||||
name = "Monochrome Carpet Single-Pack"
|
||||
desc = "Exotic carpets for all your decorating needs. This 30 units stack of extra soft carpet will tie any room together."
|
||||
|
||||
@@ -2639,9 +2639,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
//limb stuff, only done when initially spawning in
|
||||
if(initial_spawn)
|
||||
//delete any existing prosthetic limbs to make sure no remnant prosthetics are left over
|
||||
//delete any existing prosthetic limbs to make sure no remnant prosthetics are left over - But DO NOT delete those that are species-related
|
||||
for(var/obj/item/bodypart/part in character.bodyparts)
|
||||
if(part.status == BODYPART_ROBOTIC)
|
||||
if(part.status == BODYPART_ROBOTIC && !part.render_like_organic)
|
||||
qdel(part)
|
||||
character.regenerate_limbs() //regenerate limbs so now you only have normal limbs
|
||||
for(var/modified_limb in modified_limbs)
|
||||
|
||||
@@ -134,12 +134,13 @@
|
||||
return num;
|
||||
}
|
||||
window.onload = function() {
|
||||
var datas = \[[jointext(datas, ",")]]
|
||||
if(!window.HTMLCanvasElement){
|
||||
//something has gone horribly wrong!
|
||||
if(!window.HTMLCanvasElement) {
|
||||
var label = document.getElementById("label-1");
|
||||
label.textContent = "<h1>WARNING! HTMLCanvasElement not found!</h1>"
|
||||
return false
|
||||
}
|
||||
for(var i = 0; i < [length(minimaps)]; i++){
|
||||
var datas = \[[jointext(datas, ",")]]
|
||||
for(var i = 0; i < [length(minimaps)]; i++) {
|
||||
//the fuck is this wrapped?
|
||||
var data = datas\[i];
|
||||
var img = document.getElementById("map-" + (i + 1));
|
||||
@@ -160,13 +161,16 @@
|
||||
ctx.drawImage(document.getElementById("map-" + (i+1) + "-meta"), 0, 0);
|
||||
|
||||
var imagedata = ctx.getImageData(0, 0, img.width, img.height);
|
||||
var label = document.getElementById("label-" + (i+1));
|
||||
|
||||
canvas.onmousemove = function(e){
|
||||
var rect = canvas.getBoundingClientRect();
|
||||
var x = Math.floor(e.offsetX * img.width / rect.width);
|
||||
var y = Math.floor(e.offsetY * img.height / rect.height);
|
||||
|
||||
var color_idx = x * 4 + (y * 4 * imagedata.width);
|
||||
var color = "#" + hexify(imagedata.data\[color_idx]) + hexify(imagedata.data\[color_idx+1]) + hexify(imagedata.data\[color_idx+2]);
|
||||
var label = document.getElementById("label-" + (i+1)); //label-String(n)
|
||||
|
||||
label.textContent = data\[color];
|
||||
canvas.title = data\[color];
|
||||
}
|
||||
|
||||
@@ -454,10 +454,12 @@
|
||||
if(U.action(src))
|
||||
to_chat(user, "<span class='notice'>You apply the upgrade to [src].</span>")
|
||||
if(U.one_use)
|
||||
U.afterInstall(src)
|
||||
qdel(U)
|
||||
else
|
||||
U.forceMove(src)
|
||||
upgrades += U
|
||||
U.afterInstall(src)
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Upgrade error.</span>")
|
||||
U.forceMove(drop_location())
|
||||
|
||||
@@ -105,10 +105,20 @@
|
||||
holds_charge = TRUE
|
||||
unique_frequency = TRUE
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/cyborg/Destroy()
|
||||
for(var/obj/item/borg/upgrade/modkit/M in modkits)
|
||||
M.uninstall(src)
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg
|
||||
holds_charge = TRUE
|
||||
unique_frequency = TRUE
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg/Destroy()
|
||||
for(var/obj/item/borg/upgrade/modkit/M in modkits)
|
||||
M.uninstall(src)
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/minebot
|
||||
trigger_guard = TRIGGER_GUARD_ALLOW_ALL
|
||||
overheat_time = 20
|
||||
@@ -284,11 +294,11 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/borg/upgrade/modkit/action(mob/living/silicon/robot/R)
|
||||
. = ..()
|
||||
if (.)
|
||||
for(var/obj/item/gun/energy/kinetic_accelerator/cyborg/H in R.module.modules)
|
||||
return install(H, usr)
|
||||
/obj/item/borg/upgrade/modkit/afterInstall(mob/living/silicon/robot/R)
|
||||
for(var/obj/item/gun/energy/kinetic_accelerator/H in R.module.modules)
|
||||
if(install(H, R)) //It worked
|
||||
return
|
||||
to_chat(R, "<span class='alert'>Upgrade error - Aborting Kinetic Accelerator linking.</span>") //No applicable KA found, insufficient capacity, or some other problem.
|
||||
|
||||
/obj/item/borg/upgrade/modkit/proc/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user)
|
||||
. = TRUE
|
||||
@@ -323,12 +333,6 @@
|
||||
to_chat(user, "<span class='notice'>You don't have room(<b>[KA.get_remaining_mod_capacity()]%</b> remaining, [cost]% needed) to install this modkit. Use a crowbar to remove existing modkits.</span>")
|
||||
. = FALSE
|
||||
|
||||
/obj/item/borg/upgrade/modkit/deactivate(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
if (.)
|
||||
for(var/obj/item/gun/energy/kinetic_accelerator/cyborg/KA in R.module.modules)
|
||||
uninstall(KA)
|
||||
|
||||
/obj/item/borg/upgrade/modkit/proc/uninstall(obj/item/gun/energy/kinetic_accelerator/KA, forcemove = TRUE)
|
||||
KA.modkits -= src
|
||||
if(forcemove)
|
||||
|
||||
@@ -1978,6 +1978,11 @@
|
||||
color = "#363636"
|
||||
carpet_type = /turf/open/floor/carpet/black
|
||||
|
||||
/datum/reagent/carpet/arcade
|
||||
name = "Liquid Arcade Carpet"
|
||||
color = "#b51d05"
|
||||
carpet_type = /turf/open/floor/carpet/arcade
|
||||
|
||||
/datum/reagent/carpet/blackred
|
||||
name = "Liquid Red Black Carpet"
|
||||
color = "#342125"
|
||||
|
||||
@@ -757,6 +757,12 @@
|
||||
results = list(/datum/reagent/carpet/black = 2)
|
||||
required_reagents = list(/datum/reagent/carpet = 1, /datum/reagent/carbon = 1)
|
||||
|
||||
/datum/chemical_reaction/carpet/arcade
|
||||
name = "liquid arcade carpet"
|
||||
id = /datum/reagent/carpet/arcade
|
||||
results = list(/datum/reagent/carpet/arcade = 2)
|
||||
required_reagents = list(/datum/reagent/carpet = 1, /datum/reagent/consumable/pwr_game = 1)
|
||||
|
||||
/datum/chemical_reaction/carpet/blackred
|
||||
name = "liquid red black carpet"
|
||||
id = /datum/reagent/carpet/blackred
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
icon_state = "anvil"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
var/busy = FALSE //If someone is already interacting with this anvil
|
||||
var/workpiece_state = FALSE
|
||||
var/datum/material/workpiece_material
|
||||
var/anvilquality = 0
|
||||
@@ -84,7 +85,7 @@
|
||||
currentquality = anvilquality
|
||||
var/skillmod = 0
|
||||
if(user.mind.skill_holder)
|
||||
skillmod = user.mind.get_skill_level(/datum/skill/level/dorfy/blacksmithing)/2
|
||||
skillmod = user.mind.get_skill_level(/datum/skill/level/dwarfy/blacksmithing)/2
|
||||
currentquality += skillmod
|
||||
qdel(notsword)
|
||||
else
|
||||
@@ -93,12 +94,14 @@
|
||||
return
|
||||
else if(istype(I, /obj/item/melee/smith/hammer))
|
||||
var/obj/item/melee/smith/hammer/hammertime = I
|
||||
if(workpiece_state == WORKPIECE_PRESENT || workpiece_state == WORKPIECE_INPROGRESS)
|
||||
do_shaping(user, hammertime.qualitymod)
|
||||
return
|
||||
else
|
||||
to_chat(user, "You can't work an empty anvil!")
|
||||
return FALSE
|
||||
if(!(workpiece_state == WORKPIECE_PRESENT || workpiece_state == WORKPIECE_INPROGRESS))
|
||||
to_chat(user, "You can't work an empty anvil!")
|
||||
return FALSE
|
||||
if(busy)
|
||||
to_chat(user, "This anvil is already being worked!")
|
||||
return FALSE
|
||||
do_shaping(user, hammertime.qualitymod)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/structure/anvil/wrench_act(mob/living/user, obj/item/I)
|
||||
@@ -108,16 +111,18 @@
|
||||
|
||||
|
||||
/obj/structure/anvil/proc/do_shaping(mob/user, var/qualitychange)
|
||||
busy = TRUE
|
||||
currentquality += qualitychange
|
||||
var/list/shapingsteps = list("weak hit", "strong hit", "heavy hit", "fold", "draw", "shrink", "bend", "punch", "upset") //weak/strong/heavy hit affect strength. All the other steps shape.
|
||||
workpiece_state = WORKPIECE_INPROGRESS
|
||||
var/stepdone = input(user, "How would you like to work the metal?") in shapingsteps
|
||||
var/steptime = 50
|
||||
if(user.mind.skill_holder)
|
||||
var/skillmod = user.mind.get_skill_level(/datum/skill/level/dorfy/blacksmithing)/10 + 1
|
||||
var/skillmod = user.mind.get_skill_level(/datum/skill/level/dwarfy/blacksmithing)/10 + 1
|
||||
steptime = 50 / skillmod
|
||||
playsound(src, 'sound/effects/clang2.ogg',40, 2)
|
||||
if(!do_after(user, steptime, target = src))
|
||||
busy = FALSE
|
||||
return FALSE
|
||||
switch(stepdone)
|
||||
if("weak hit")
|
||||
@@ -162,16 +167,17 @@
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/effects/clang2.ogg', 40, 2), 15)
|
||||
if(length(stepsdone) >= 3)
|
||||
tryfinish(user)
|
||||
busy = FALSE
|
||||
|
||||
/obj/structure/anvil/proc/tryfinish(mob/user)
|
||||
var/artifactchance = 0
|
||||
if(!artifactrolled)
|
||||
artifactchance = (1+(user.mind.get_skill_level(/datum/skill/level/dorfy/blacksmithing)/4))/2500
|
||||
artifactchance = (1+(user.mind.get_skill_level(/datum/skill/level/dwarfy/blacksmithing)/4))/2500
|
||||
artifactrolled = TRUE
|
||||
var/artifact = max(prob(artifactchance), debug)
|
||||
var/finalfailchance = outrightfailchance
|
||||
if(user.mind.skill_holder)
|
||||
var/skillmod = user.mind.get_skill_level(/datum/skill/level/dorfy/blacksmithing)/10 + 1
|
||||
var/skillmod = user.mind.get_skill_level(/datum/skill/level/dwarfy/blacksmithing)/10 + 1
|
||||
finalfailchance = max(0, finalfailchance / skillmod) //lv 2 gives 20% less to fail, 3 30%, etc
|
||||
if((currentsteps > 10 || (rng && prob(finalfailchance))) && !artifact)
|
||||
to_chat(user, "<span class='warning'>You overwork the metal, causing it to turn into useless slag!</span>")
|
||||
@@ -184,7 +190,7 @@
|
||||
outrightfailchance = 1
|
||||
artifactrolled = FALSE
|
||||
if(user.mind.skill_holder)
|
||||
user.mind.auto_gain_experience(/datum/skill/level/dorfy/blacksmithing, 25, 400, silent = FALSE)
|
||||
user.mind.auto_gain_experience(/datum/skill/level/dwarfy/blacksmithing, 25, 400, silent = FALSE)
|
||||
for(var/i in smithrecipes)
|
||||
if(i == stepsdone)
|
||||
var/turf/T = get_turf(user)
|
||||
@@ -217,7 +223,7 @@
|
||||
outrightfailchance = 1
|
||||
artifactrolled = FALSE
|
||||
if(user.mind.skill_holder)
|
||||
user.mind.auto_gain_experience(/datum/skill/level/dorfy/blacksmithing, 50, 10000000, silent = FALSE)
|
||||
user.mind.auto_gain_experience(/datum/skill/level/dwarfy/blacksmithing, 50, 10000000, silent = FALSE)
|
||||
break
|
||||
|
||||
/obj/structure/anvil/debugsuper
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
if(G.max_heat_protection_temperature)
|
||||
prot = (G.max_heat_protection_temperature > 360)
|
||||
else
|
||||
prot = 1
|
||||
prot = 0
|
||||
if(prot > 0 || HAS_TRAIT(user, TRAIT_RESISTHEAT) || HAS_TRAIT(user, TRAIT_RESISTHEATHANDS))
|
||||
to_chat(user, "<span class='notice'>You pick up the [src].</span>")
|
||||
return ..()
|
||||
|
||||
@@ -581,7 +581,7 @@
|
||||
C = owner
|
||||
no_update = FALSE
|
||||
|
||||
if(HAS_TRAIT(C, TRAIT_HUSK) && is_organic_limb())
|
||||
if(HAS_TRAIT(C, TRAIT_HUSK) && (is_organic_limb() || render_like_organic))
|
||||
species_id = "husk" //overrides species_id
|
||||
dmg_overlay_type = "" //no damage overlay shown when husked
|
||||
should_draw_gender = FALSE
|
||||
|
||||
@@ -434,5 +434,8 @@
|
||||
var/datum/scar/scaries = new
|
||||
var/datum/wound/loss/phantom_loss = new // stolen valor, really
|
||||
scaries.generate(L, phantom_loss)
|
||||
if(HAS_TRAIT(src, ROBOTIC_LIMBS)) //Snowflake trait moment, but needed.
|
||||
L.render_like_organic = TRUE
|
||||
L.change_bodypart_status(BODYPART_ROBOTIC, FALSE, TRUE) //Haha what if IPC-lings actually regenerated the right limbs instead of organic ones? That'd be pretty cool, right?
|
||||
L.attach_limb(src, 1)
|
||||
return TRUE
|
||||
|
||||
@@ -529,7 +529,7 @@ GLOBAL_LIST_EMPTY(vending_products)
|
||||
if(5) // limb squish!
|
||||
for(var/i in C.bodyparts)
|
||||
var/obj/item/bodypart/squish_part = i
|
||||
if(squish_part.is_organic_limb())
|
||||
if(squish_part.is_organic_limb() || squish_part.render_like_organic)
|
||||
var/type_wound = pick(list(/datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/moderate))
|
||||
squish_part.force_wound_upwards(type_wound)
|
||||
else
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
/datum/vore_look/Destroy()
|
||||
loop = null
|
||||
selected = null
|
||||
..() //this is a must
|
||||
return QDEL_HINT_HARDDEL
|
||||
|
||||
/datum/vore_look/Topic(href,href_list[])
|
||||
|
||||
@@ -53,6 +53,11 @@
|
||||
<h2 class="date">04 October 2020</h2>
|
||||
<h3 class="author">DeltaFire15 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Synths / IPCs are no longer wound immune.</li>
|
||||
<li class="bugfix">Husked IPCs / Synths should now be rendered correctly.</li>
|
||||
<li class="bugfix">Falling vendors now squish synths / IPCs' limbs again.</li>
|
||||
<li class="bugfix">Synths and IPCs now do not have some fun roundstart oversights anymore.</li>
|
||||
<li class="bugfix">Regenerate_limbs now works for carbons with the ROBOTIC_LIMBS trait.</li>
|
||||
<li class="bugfix">Pacifists no longer counterattack on parries if that attack would be harmful.</li>
|
||||
<li class="tweak">Heretic sacrifices now husk with the reason of burn, and deal some additional damage.</li>
|
||||
<li class="bugfix">Neovgre can no longer become invincible on clock tiles.</li>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "Detective-Google"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "arcade carpet"
|
||||
@@ -0,0 +1,5 @@
|
||||
author: "LetterN"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "minimap text"
|
||||
- code_imp: "ports cinematic upgrades"
|
||||
@@ -0,0 +1,6 @@
|
||||
author: "DeltaFire15"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "the blacksmithing skill now works properly"
|
||||
- tweak: "Anvils cannot be interacted with with hammers whilst they are already being used"
|
||||
- tweak: "If someone has no gloves when interacting with heated ingots, they no longer ignore their effects."
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "DeltaFire15"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "The Revenant self-revive ability is no longer broken."
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "DeltaFire15"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "People installing KA modkits in miner borgs is no longer broken."
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "Putnam3145"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Toilet loot spawners don't lag the server on server start with forced hard dels."
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 341 KiB After Width: | Height: | Size: 340 KiB |
Reference in New Issue
Block a user