Merge remote-tracking branch 'upstream/master'

This commit is contained in:
DeltaFire
2020-10-04 03:56:52 +02:00
45 changed files with 289 additions and 111 deletions
+15
View File
@@ -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 }}
+15 -3
View File
@@ -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 -1
View File
@@ -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
+3 -3
View File
@@ -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
+3 -2
View File
@@ -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)
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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))
+1
View File
@@ -214,6 +214,7 @@
/datum/point/vector/processed/Destroy()
STOP_PROCESSING(SSprojectiles, src)
return ..()
/datum/point/vector/processed/proc/start()
last_process = world.time
+1
View File
@@ -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)
+2 -1
View File
@@ -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,
+6 -2
View File
@@ -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)
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+2 -5
View File
@@ -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()
. = ..()
+1 -1
View File
@@ -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
+4
View File
@@ -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."
+2 -2
View File
@@ -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)
+9 -5
View File
@@ -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
+18 -12
View File
@@ -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
+1 -1
View File
@@ -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 ..()
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1
View File
@@ -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[])
+5
View File
@@ -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