diff --git a/Dockerfile b/Dockerfile
index 52f2872e98..97d2ccf2e7 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM tgstation/byond:512.1441 as base
+FROM tgstation/byond:512.1448 as base
#above version must be the same as the one in dependencies.sh
FROM base as build_base
@@ -14,9 +14,10 @@ WORKDIR /rust_g
RUN apt-get install -y --no-install-recommends \
libssl-dev \
- rustc \
- cargo \
pkg-config \
+ curl \
+ gcc-multilib \
+ && curl https://sh.rustup.rs -sSf | sh -s -- -y --default-host i686-unknown-linux-gnu \
&& git init \
&& git remote add origin https://github.com/tgstation/rust-g
@@ -87,4 +88,4 @@ RUN ln -s /tgstation/libBSQL.so /root/.byond/bin/libBSQL.so
VOLUME [ "/tgstation/config", "/tgstation/data" ]
-ENTRYPOINT [ "DreamDaemon", "tgstation.dmb", "-port", "1337", "-trusted", "-close", "-verbose" ]
+ENTRYPOINT [ "DreamDaemon", "tgstation.dmb", "-port", "1337", "-trusted", "-close", "-verbose" ]
\ No newline at end of file
diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index 6fff7e7017..edd77ecf6b 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -49,6 +49,7 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
//Movement Types
#define GROUND (1<<0)
#define FLYING (1<<1)
+#define VENTCRAWLING (1<<2)
// Flags for reagents
#define REAGENT_NOREACT (1<<0)
diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm
index 651be685c5..faa620613c 100644
--- a/code/__DEFINES/tgs.dm
+++ b/code/__DEFINES/tgs.dm
@@ -44,17 +44,33 @@
//EVENT CODES
+#define TGS_EVENT_PORT_SWAP -2 //before a port change is about to happen, extra parameter is new port
+#define TGS_EVENT_REBOOT_MODE_CHANGE -1 //before a reboot mode change, extras parameters are the current and new reboot mode enums
+
//TODO
+//OTHER ENUMS
+
+#define TGS_REBOOT_MODE_NORMAL 0
+#define TGS_REBOOT_MODE_SHUTDOWN 1
+#define TGS_REBOOT_MODE_RESTART 2
+
+#define TGS_SECURITY_TRUSTED 0
+#define TGS_SECURITY_SAFE 1
+#define TGS_SECURITY_ULTRASAFE 2
+
//REQUIRED HOOKS
//Call this somewhere in /world/New() that is always run
//event_handler: optional user defined event handler. The default behaviour is to broadcast the event in english to all connected admin channels
-/world/proc/TgsNew(datum/tgs_event_handler/event_handler)
+//minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated
+/world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE)
return
//Call this when your initializations are complete and your game is ready to play before any player interactions happen
//This may use world.sleep_offline to make this happen so ensure no changes are made to it while this call is running
+//Most importantly, before this point, note that any static files or directories may be in use by another server. Your code should account for this
+//This function should not be called before ..() in /world/New()
/world/proc/TgsInitializationComplete()
return
@@ -88,20 +104,22 @@
/datum/tgs_chat_channel
var/id //internal channel representation
var/friendly_name //user friendly channel name
- var/server_name //server name the channel resides on
- var/provider_name //chat provider for the channel
+ var/connection_name //the name of the configured chat connection
var/is_admin_channel //if the server operator has marked this channel for game admins only
var/is_private_channel //if this is a private chat channel
+ var/custom_tag //user defined string associated with channel
//represents a chat user
/datum/tgs_chat_user
- var/id //Internal user representation
+ var/id //Internal user representation, requires channel to be unique
var/friendly_name //The user's public name
var/mention //The text to use to ping this user in a message
var/datum/tgs_chat_channel/channel //The /datum/tgs_chat_channel this user was from
//user definable callback for handling events
-/datum/tgs_event_handler/proc/HandleEvent(event_code)
+//extra parameters may be specified depending on the event
+/datum/tgs_event_handler/proc/HandleEvent(event_code, ...)
+ set waitfor = FALSE
return
//user definable chat command
@@ -142,6 +160,10 @@
/world/proc/TgsRevision()
return
+//Get the current BYOND security level
+/world/proc/TgsSecurityLevel()
+ return
+
//Gets a list of active `/datum/tgs_revision_information/test_merge`s
/world/proc/TgsTestMerges()
return
@@ -199,4 +221,4 @@ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
+*/
\ No newline at end of file
diff --git a/code/datums/components/chasm.dm b/code/datums/components/chasm.dm
index bc1bbac423..013334bc27 100644
--- a/code/datums/components/chasm.dm
+++ b/code/datums/components/chasm.dm
@@ -19,7 +19,8 @@
/obj/effect/temp_visual,
/obj/effect/light_emitter/tendril,
/obj/effect/collapse,
- /obj/effect/particle_effect/ion_trails
+ /obj/effect/particle_effect/ion_trails,
+ /obj/effect/dummy/phased_mob
))
/datum/component/chasm/Initialize(turf/target)
diff --git a/code/datums/components/footstep.dm b/code/datums/components/footstep.dm
index 2276e7cd27..ccd3d30463 100644
--- a/code/datums/components/footstep.dm
+++ b/code/datums/components/footstep.dm
@@ -17,7 +17,7 @@
var/mob/living/LM = parent
var/v = volume
var/e = e_range
- if(!T.footstep || LM.lying || !LM.canmove || LM.resting || LM.buckled || LM.throwing)
+ if(!T.footstep || LM.lying || !LM.canmove || LM.resting || LM.buckled || LM.throwing || LM.movement_type & (VENTCRAWLING | FLYING))
return
if(iscarbon(LM))
var/mob/living/carbon/C = LM
diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm
index 9cbccb8fe9..0c43d33a4b 100644
--- a/code/datums/world_topic.dm
+++ b/code/datums/world_topic.dm
@@ -157,7 +157,7 @@
.["admins"] = presentmins.len + afkmins.len //equivalent to the info gotten from adminwho
.["gamestate"] = SSticker.current_state
- .["map_name"] = SSmapping.config.map_name
+ .["map_name"] = SSmapping.config?.map_name || "Loading..."
if(key_valid)
.["active_players"] = get_active_player_count()
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 7f45f88dcd..948a62de61 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -1199,7 +1199,7 @@
optionlist = list("Standard", "Public", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Freezer", "Science", "Virology", "Mining", "Maintenance", "External", "External Maintenance")
var/paintjob = input(user, "Please select a paintjob for this airlock.") in optionlist
- if((!in_range(src, usr) && src.loc != usr) || !W.use(user))
+ if((!in_range(src, usr) && src.loc != usr) || !W.use_paint(user))
return
switch(paintjob)
if("Standard")
diff --git a/code/game/objects/items/his_grace.dm b/code/game/objects/items/his_grace.dm
index f293b04fa9..49a5cfaf35 100644
--- a/code/game/objects/items/his_grace.dm
+++ b/code/game/objects/items/his_grace.dm
@@ -21,7 +21,7 @@
var/prev_bloodthirst = HIS_GRACE_SATIATED
var/force_bonus = 0
var/ascended = FALSE
- var/victims_needed = 25
+ var/victims_needed = 10 //Citadel change from 25 to 10
var/ascend_bonus = 15
/obj/item/his_grace/Initialize()
diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm
index 658a95b016..2e8cb569a6 100644
--- a/code/game/objects/items/tools/screwdriver.dm
+++ b/code/game/objects/items/tools/screwdriver.dm
@@ -101,6 +101,9 @@
toolspeed = 0.1
random_color = FALSE
+/obj/item/screwdriver/abductor/get_belt_overlay()
+ return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver_nuke")
+
/obj/item/screwdriver/power
name = "hand drill"
desc = "A simple powered hand drill. It's fitted with a screw bit."
diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm
index 4e274d5048..bd65a8b422 100644
--- a/code/game/objects/structures/flora.dm
+++ b/code/game/objects/structures/flora.dm
@@ -362,10 +362,6 @@
icon_state = "lavarocks"
desc = "A pile of rocks."
-/obj/structure/flora/rock/pile/Initialize()
- . = ..()
- icon_state = "[icon_state][rand(1,3)]"
-
//Jungle grass
/obj/structure/flora/grass/jungle
diff --git a/code/modules/admin/verbs/adminsay.dm b/code/modules/admin/verbs/adminsay.dm
index 7adb128239..84264a1b36 100644
--- a/code/modules/admin/verbs/adminsay.dm
+++ b/code/modules/admin/verbs/adminsay.dm
@@ -8,7 +8,7 @@
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
if(!msg)
return
-
+ msg = emoji_parse(msg)
mob.log_talk(msg, LOG_ASAY)
msg = keywords_lookup(msg)
diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm
index edf703b34d..c1e6ff826f 100644
--- a/code/modules/antagonists/_common/antag_spawner.dm
+++ b/code/modules/antagonists/_common/antag_spawner.dm
@@ -251,7 +251,7 @@
/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, kind = "", datum/mind/user)
- var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T)
+ var/obj/effect/dummy/phased_mob/slaughter/holder = new /obj/effect/dummy/phased_mob/slaughter(T)
var/mob/living/simple_animal/slaughter/S = new demon_type(holder)
S.holder = holder
S.key = C.key
diff --git a/code/modules/antagonists/devil/devil.dm b/code/modules/antagonists/devil/devil.dm
index fe05c9284c..3f2bd003a3 100644
--- a/code/modules/antagonists/devil/devil.dm
+++ b/code/modules/antagonists/devil/devil.dm
@@ -219,7 +219,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
H.set_species(/datum/species/human, 1)
H.regenerate_icons()
give_appropriate_spells()
- if(istype(owner.current.loc, /obj/effect/dummy/slaughter/))
+ if(istype(owner.current.loc, /obj/effect/dummy/phased_mob/slaughter/))
owner.current.forceMove(get_turf(owner.current))//Fixes dying while jaunted leaving you permajaunted.
form = BASIC_DEVIL
@@ -304,7 +304,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
sound_to_playing_players('sound/hallucinations/veryfar_noise.ogg')
give_appropriate_spells()
D.convert_to_archdevil()
- if(istype(D.loc, /obj/effect/dummy/slaughter/))
+ if(istype(D.loc, /obj/effect/dummy/phased_mob/slaughter/))
D.forceMove(get_turf(D))//Fixes dying while jaunted leaving you permajaunted.
var/area/A = get_area(owner.current)
if(A)
@@ -430,7 +430,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
update_hud()
if(body)
body.revive(TRUE, TRUE) //Adminrevive also recovers organs, preventing someone from resurrecting without a heart.
- if(istype(body.loc, /obj/effect/dummy/slaughter/))
+ if(istype(body.loc, /obj/effect/dummy/phased_mob/slaughter/))
body.forceMove(get_turf(body))//Fixes dying while jaunted leaving you permajaunted.
if(istype(body, /mob/living/carbon/true_devil))
var/mob/living/carbon/true_devil/D = body
diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm
index 61d890a743..4f31346136 100644
--- a/code/modules/antagonists/slaughter/slaughter.dm
+++ b/code/modules/antagonists/slaughter/slaughter.dm
@@ -51,8 +51,8 @@
..()
var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new
AddSpell(bloodspell)
- if(istype(loc, /obj/effect/dummy/slaughter))
- bloodspell.phased = 1
+ if(istype(loc, /obj/effect/dummy/phased_mob/slaughter))
+ bloodspell.phased = TRUE
/mob/living/simple_animal/slaughter/Life()
..()
diff --git a/code/modules/antagonists/slaughter/slaughterevent.dm b/code/modules/antagonists/slaughter/slaughterevent.dm
index 4d81741c91..6ace6a0536 100644
--- a/code/modules/antagonists/slaughter/slaughterevent.dm
+++ b/code/modules/antagonists/slaughter/slaughterevent.dm
@@ -31,7 +31,7 @@
message_admins("No valid spawn locations found, aborting...")
return MAP_ERROR
- var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter((pick(spawn_locs)))
+ var/obj/effect/dummy/phased_mob/slaughter/holder = new /obj/effect/dummy/phased_mob/slaughter((pick(spawn_locs)))
var/mob/living/simple_animal/slaughter/S = new (holder)
S.holder = holder
player_mind.transfer_to(S)
diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm
index 6e01181447..fc20d5d26f 100644
--- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm
+++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm
@@ -444,13 +444,13 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
PLEASE DO NOT REMOVE THIS CODE. the commenting is here only for a performance increase.
enabling these checks should be as easy as possible and the fact that they are disabled should be as clear as possible
- var/list/max_reqs = reaction.max_requirements.Copy()
+ var/list/max_reqs = reaction.max_requirements
if((max_reqs["TEMP"] && temp > max_reqs["TEMP"]) \
|| (max_reqs["ENER"] && ener > max_reqs["ENER"]))
continue
- max_reqs -= "TEMP"
- max_reqs -= "ENER"
for(var/id in max_reqs)
+ if(id == "TEMP" || id == "ENER")
+ continue
if(cached_gases[id] && cached_gases[id][MOLES] > max_reqs[id])
continue reaction_loop
//at this point, all requirements for the reaction are satisfied. we can now react()
diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm
index 9cfcc24557..84ad1e9258 100644
--- a/code/modules/atmospherics/gasmixtures/reactions.dm
+++ b/code/modules/atmospherics/gasmixtures/reactions.dm
@@ -455,6 +455,7 @@
//Replace miasma with oxygen
var/cleaned_air = min(cached_gases[/datum/gas/miasma][MOLES], 20 + (air.temperature - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
cached_gases[/datum/gas/miasma][MOLES] -= cleaned_air
+ ASSERT_GAS(/datum/gas/oxygen,air)
cached_gases[/datum/gas/oxygen][MOLES] += cleaned_air
//Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable
diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm
index 87a7d43b37..d23a5df958 100644
--- a/code/modules/atmospherics/machinery/portable/canister.dm
+++ b/code/modules/atmospherics/machinery/portable/canister.dm
@@ -480,6 +480,7 @@
if("eject")
if(holding)
if(valve_open)
+ message_admins("[ADMIN_LOOKUPFLW(usr)] removed [holding] from [src] with valve still open at [ADMIN_VERBOSEJMP(src)] releasing contents into the air
.")
investigate_log("[key_name(usr)] removed the [holding], leaving the valve open and transferring into the air
", INVESTIGATE_ATMOS)
holding.forceMove(get_turf(src))
holding = null
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 9199bd7051..f26925afd1 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -2039,8 +2039,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
character.backbag = backbag
- character.dna.features = features.Copy()
- character.dna.real_name = character.real_name
var/datum/species/chosen_species
if(!roundstart_checks || (pref_species.id in GLOB.roundstart_races))
chosen_species = pref_species.type
@@ -2048,7 +2046,17 @@ GLOBAL_LIST_EMPTY(preferences_datums)
chosen_species = /datum/species/human
pref_species = new /datum/species/human
save_character()
+
character.set_species(chosen_species, icon_update = FALSE, pref_load = TRUE)
+ character.dna.features = features.Copy()
+ character.dna.real_name = character.real_name
+
+ if("tail_lizard" in pref_species.default_features)
+ character.dna.species.mutant_bodyparts |= "tail_lizard"
+ else if("mam_tail" in pref_species.default_features)
+ character.dna.species.mutant_bodyparts |= "mam_tail"
+ else if("xenotail" in pref_species.default_features)
+ character.dna.species.mutant_bodyparts |= "xenotail"
if(icon_updates)
character.update_body()
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index e30bac4f41..58b71cfb3e 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -1096,6 +1096,8 @@ GLOBAL_LIST_INIT(hallucination_list, list(
/obj/effect/hallucination/danger/chasm/Crossed(atom/movable/AM)
if(AM == target)
+ if(istype(target, /obj/effect/dummy/phased_mob))
+ return
to_chat(target, "You fall into the chasm!")
target.Knockdown(40)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, target, "It's surprisingly shallow."), 15)
diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm
index d70007452c..2a5fdeaa33 100644
--- a/code/modules/mob/living/bloodcrawl.dm
+++ b/code/modules/mob/living/bloodcrawl.dm
@@ -1,4 +1,4 @@
-/obj/effect/dummy/slaughter //Can't use the wizard one, blocked by jaunt/slow
+/obj/effect/dummy/phased_mob/slaughter //Can't use the wizard one, blocked by jaunt/slow
name = "water"
icon = 'icons/effects/effects.dmi'
icon_state = "nothing"
@@ -8,15 +8,15 @@
invisibility = 60
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
-/obj/effect/dummy/slaughter/relaymove(mob/user, direction)
+/obj/effect/dummy/phased_mob/slaughter/relaymove(mob/user, direction)
forceMove(get_step(src,direction))
-/obj/effect/dummy/slaughter/ex_act()
+/obj/effect/dummy/phased_mob/slaughter/ex_act()
return
-/obj/effect/dummy/slaughter/bullet_act()
+/obj/effect/dummy/phased_mob/slaughter/bullet_act()
return
-/obj/effect/dummy/slaughter/singularity_act()
+/obj/effect/dummy/phased_mob/slaughter/singularity_act()
return
@@ -50,7 +50,7 @@
playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 100, 1, -1)
// Extinguish, unbuckle, stop being pulled, set our location into the
// dummy object
- var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(mobloc)
+ var/obj/effect/dummy/phased_mob/slaughter/holder = new /obj/effect/dummy/phased_mob/slaughter(mobloc)
src.ExtinguishMob()
// Keep a reference to whatever we're pulling, because forceMove()
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
index 3f68c15dc2..1784405f30 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
@@ -91,8 +91,8 @@ Difficulty: Hard
return INITIALIZE_HINT_QDEL //There can be only one
var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new
AddSpell(bloodspell)
- if(istype(loc, /obj/effect/dummy/slaughter))
- bloodspell.phased = 1
+ if(istype(loc, /obj/effect/dummy/phased_mob/slaughter))
+ bloodspell.phased = TRUE
internal = new/obj/item/gps/internal/bubblegum(src)
/mob/living/simple_animal/hostile/megafauna/bubblegum/grant_achievement(medaltype,scoretype)
diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm
index d795280686..251739c935 100644
--- a/code/modules/mob/living/ventcrawling.dm
+++ b/code/modules/mob/living/ventcrawling.dm
@@ -99,6 +99,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
pipes_shown += A.pipe_vision_img
if(client)
client.images += A.pipe_vision_img
+ movement_type |= VENTCRAWLING
/mob/living/proc/remove_ventcrawl()
@@ -106,6 +107,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
for(var/image/current_image in pipes_shown)
client.images -= current_image
pipes_shown.len = 0
+ movement_type &= ~VENTCRAWLING
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index eb4cfb47b2..a563aef86a 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -525,7 +525,7 @@
if(statpanel("Status"))
if (client)
stat(null, "Ping: [round(client.lastping, 1)]ms (Average: [round(client.avgping, 1)]ms)")
- stat(null, "Map: [SSmapping.config.map_name]")
+ stat(null, "Map: [SSmapping.config?.map_name || "Loading..."]")
var/datum/map_config/cached = SSmapping.next_map_config
if(cached)
stat(null, "Next Map: [cached.map_name]")
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index 2ab3b5f57e..9e127d4746 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -75,6 +75,7 @@
K = src.key
var/spanned = src.say_quote(message, get_spans())
+ message = emoji_parse(message)
var/rendered = "DEAD: [name][alt_name] [emoji_parse(spanned)]"
log_talk(message, LOG_SAY, tag="DEAD")
deadchat_broadcast(rendered, follow_target = src, speaker_key = K)
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index 8c9769f278..dee88f176f 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -344,9 +344,10 @@
flag = "magic"
var/weld = TRUE
var/created = FALSE //prevents creation of more then one locker if it has multiple hits
+ var/locker_suck = TRUE
/obj/item/projectile/magic/locker/prehit(atom/A)
- if(ismob(A))
+ if(ismob(A) && locker_suck)
var/mob/M = A
if(M.anti_magic_check())
M.visible_message("[src] vanishes on contact with [A]!")
@@ -371,6 +372,7 @@
return ..()
/obj/item/projectile/magic/locker/Destroy()
+ locker_suck = FALSE
for(var/atom/movable/AM in contents)
AM.forceMove(get_turf(src))
. = ..()
@@ -410,11 +412,6 @@
else
addtimer(CALLBACK(src, .proc/decay), 15 SECONDS)
-/obj/structure/closet/decay/contents_explosion(severity, target)
- for(var/atom/A in contents)
- A.ex_act(severity/2, target) //Difference is it does half the damage to contents from explosion, to make fireball not completely instakill
- CHECK_TICK
-
/obj/structure/closet/decay/proc/unmagify()
icon_state = weakened_icon
update_icon()
@@ -509,6 +506,4 @@
return
var/turf/T = get_turf(target)
for(var/i=0, i<50, i+=10)
- addtimer(CALLBACK(GLOBAL_PROC, .proc/explosion, T, -1, exp_heavy, exp_light, exp_flash, FALSE, FALSE, exp_fire), i)
-
-
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/explosion, T, -1, exp_heavy, exp_light, exp_flash, FALSE, FALSE, exp_fire), i)
\ No newline at end of file
diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm
index 61e4a1bb46..fd5f2f59fd 100644
--- a/code/modules/shuttle/special.dm
+++ b/code/modules/shuttle/special.dm
@@ -246,6 +246,17 @@
if(total_cash >= threshold)
break
+ if(AM.pulling)
+ if(istype(AM.pulling, /obj/item/coin))
+ var/obj/item/coin/C = AM.pulling
+ total_cash += C.value
+ counted_money += C
+
+ else if(istype(AM.pulling, /obj/item/stack/spacecash))
+ var/obj/item/stack/spacecash/S = AM.pulling
+ total_cash += S.value * S.amount
+ counted_money += S
+
if(total_cash >= threshold)
for(var/obj/I in counted_money)
qdel(I)
diff --git a/code/modules/spells/spell_types/devil.dm b/code/modules/spells/spell_types/devil.dm
index cbc9017ee9..8b8328abbe 100644
--- a/code/modules/spells/spell_types/devil.dm
+++ b/code/modules/spells/spell_types/devil.dm
@@ -104,7 +104,7 @@
/obj/effect/proc_holder/spell/targeted/infernal_jaunt/cast(list/targets, mob/living/user = usr)
if(istype(user))
- if(istype(user.loc, /obj/effect/dummy/slaughter/))
+ if(istype(user.loc, /obj/effect/dummy/phased_mob/slaughter/))
if(valid_location(user))
to_chat(user, "You are now phasing in.")
if(do_mob(user,user,150))
@@ -145,7 +145,7 @@
spawn_dust()
visible_message("[src] disappears in a flashfire!")
playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 100, 1, -1)
- var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(loc)
+ var/obj/effect/dummy/phased_mob/slaughter/holder = new /obj/effect/dummy/phased_mob/slaughter(loc)
ExtinguishMob()
forceMove(holder)
holder = holder
diff --git a/code/modules/spells/spell_types/ethereal_jaunt.dm b/code/modules/spells/spell_types/ethereal_jaunt.dm
index e438966f45..c003ffb2f2 100644
--- a/code/modules/spells/spell_types/ethereal_jaunt.dm
+++ b/code/modules/spells/spell_types/ethereal_jaunt.dm
@@ -25,7 +25,7 @@
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/do_jaunt(mob/living/target)
target.notransform = 1
var/turf/mobloc = get_turf(target)
- var/obj/effect/dummy/spell_jaunt/holder = new /obj/effect/dummy/spell_jaunt(mobloc)
+ var/obj/effect/dummy/phased_mob/spell_jaunt/holder = new /obj/effect/dummy/phased_mob/spell_jaunt(mobloc)
new jaunt_out_type(mobloc, target.dir)
target.ExtinguishMob()
target.forceMove(holder)
@@ -62,7 +62,7 @@
steam.set_up(10, 0, mobloc)
steam.start()
-/obj/effect/dummy/spell_jaunt
+/obj/effect/dummy/phased_mob/spell_jaunt
name = "water"
icon = 'icons/effects/effects.dmi'
icon_state = "nothing"
@@ -74,13 +74,13 @@
invisibility = 60
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
-/obj/effect/dummy/spell_jaunt/Destroy()
+/obj/effect/dummy/phased_mob/spell_jaunt/Destroy()
// Eject contents if deleted somehow
for(var/atom/movable/AM in src)
AM.forceMove(get_turf(src))
return ..()
-/obj/effect/dummy/spell_jaunt/relaymove(var/mob/user, direction)
+/obj/effect/dummy/phased_mob/spell_jaunt/relaymove(var/mob/user, direction)
if ((movedelay > world.time) || reappearing || !direction)
return
var/turf/newLoc = get_step(src,direction)
@@ -97,7 +97,7 @@
forceMove(newLoc)
-/obj/effect/dummy/spell_jaunt/ex_act(blah)
- return
-/obj/effect/dummy/spell_jaunt/bullet_act(blah)
+/obj/effect/dummy/phased_mob/spell_jaunt/ex_act(blah)
return
+/obj/effect/dummy/phased_mob/spell_jaunt/bullet_act(blah)
+ return
\ No newline at end of file
diff --git a/code/modules/spells/spell_types/shadow_walk.dm b/code/modules/spells/spell_types/shadow_walk.dm
index 9f9b4ac223..8dbb6d6532 100644
--- a/code/modules/spells/spell_types/shadow_walk.dm
+++ b/code/modules/spells/spell_types/shadow_walk.dm
@@ -15,8 +15,8 @@
/obj/effect/proc_holder/spell/targeted/shadowwalk/cast(list/targets,mob/living/user = usr)
var/L = user.loc
- if(istype(user.loc, /obj/effect/dummy/shadow))
- var/obj/effect/dummy/shadow/S = L
+ if(istype(user.loc, /obj/effect/dummy/phased_mob/shadow))
+ var/obj/effect/dummy/phased_mob/shadow/S = L
S.end_jaunt(FALSE)
return
else
@@ -28,13 +28,13 @@
user.SetStun(0, FALSE)
user.SetKnockdown(0, FALSE)
user.setStaminaLoss(0, 0)
- var/obj/effect/dummy/shadow/S2 = new(get_turf(user.loc))
+ var/obj/effect/dummy/phased_mob/shadow/S2 = new(get_turf(user.loc))
user.forceMove(S2)
S2.jaunter = user
else
to_chat(user, "It isn't dark enough here!")
-/obj/effect/dummy/shadow
+/obj/effect/dummy/phased_mob/shadow
name = "darkness"
icon = 'icons/effects/effects.dmi'
icon_state = "nothing"
@@ -45,7 +45,7 @@
invisibility = 60
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
-/obj/effect/dummy/shadow/relaymove(mob/user, direction)
+/obj/effect/dummy/phased_mob/shadow/relaymove(mob/user, direction)
var/turf/newLoc = get_step(src,direction)
if(isspaceturf(newLoc))
to_chat(user, "It really would not be wise to go into space.")
@@ -53,7 +53,7 @@
forceMove(newLoc)
check_light_level()
-/obj/effect/dummy/shadow/proc/check_light_level()
+/obj/effect/dummy/phased_mob/shadow/proc/check_light_level()
var/turf/T = get_turf(src)
var/light_amount = T.get_lumcount()
if(light_amount > 0.2) // jaunt ends
@@ -61,7 +61,7 @@
else if (light_amount < 0.2 && (!QDELETED(jaunter))) //heal in the dark
jaunter.heal_overall_damage(1,1)
-/obj/effect/dummy/shadow/proc/end_jaunt(forced = FALSE)
+/obj/effect/dummy/phased_mob/shadow/proc/end_jaunt(forced = FALSE)
if(jaunter)
if(forced)
visible_message("[jaunter] is revealed by the light!")
@@ -72,27 +72,26 @@
jaunter = null
qdel(src)
-/obj/effect/dummy/shadow/Initialize(mapload)
+/obj/effect/dummy/phased_mob/shadow/Initialize(mapload)
. = ..()
START_PROCESSING(SSobj, src)
-/obj/effect/dummy/shadow/Destroy()
+/obj/effect/dummy/phased_mob/shadow/Destroy()
STOP_PROCESSING(SSobj, src)
. = ..()
-/obj/effect/dummy/shadow/process()
+/obj/effect/dummy/phased_mob/shadow/process()
if(!jaunter)
qdel(src)
if(jaunter.loc != src)
qdel(src)
check_light_level()
-/obj/effect/dummy/shadow/ex_act()
+/obj/effect/dummy/phased_mob/shadow/ex_act()
return
-/obj/effect/dummy/shadow/bullet_act()
+/obj/effect/dummy/phased_mob/shadow/bullet_act()
return
-/obj/effect/dummy/shadow/singularity_act()
+/obj/effect/dummy/phased_mob/shadow/singularity_act()
return
-
diff --git a/dependencies.sh b/dependencies.sh
index 59f84f145a..1b61b37c88 100644
--- a/dependencies.sh
+++ b/dependencies.sh
@@ -7,7 +7,7 @@
#note, this also needs to be changed in the Dockerfile's initial FROM command
#If someone has an idea for how to set that version within the Dockerfile itself without any other dependencies, feel free to PR it
export BYOND_MAJOR=512
-export BYOND_MINOR=1441
+export BYOND_MINOR=1448
#rust_g git tag
export RUST_G_VERSION=0.4.1
diff --git a/tools/tgs4_scripts/PostCompile.sh b/tools/tgs4_scripts/PostCompile.sh
index d63cbced6b..36cb797d94 100644
--- a/tools/tgs4_scripts/PostCompile.sh
+++ b/tools/tgs4_scripts/PostCompile.sh
@@ -1,7 +1,87 @@
#!/bin/sh
-#Basically run deploy.sh, but first
+set -e
+#load dep exports
+. "$1/dependencies.sh"
+
+#find out what we have (+e is important for this)
+set +e
+has_git="$(command -v git)"
+has_cargo="$(command -v ~/.cargo/bin/cargo)"
+has_sudo="$(command -v sudo)"
+has_cmake="$(command -v cmake)"
+has_gpp="$(command -v g++-6)"
+has_grep="$(command -v grep)"
+set -e
+
+#install cargo if needful
+if ! [ -x "$has_cargo" ]; then
+ echo "Installing rust..."
+ curl https://sh.rustup.rs -sSf | sh -s -- -y --default-host i686-unknown-linux-gnu
+ . ~/.profile
+fi
+
+#apt packages
+if ! { [ -x "$has_git" ] && [ -x "$has_cmake" ] && [ -x "$has_gpp" ] && [ -f "/usr/lib/i386-linux-gnu/libmariadb.so.2" ] && [ -f "/usr/lib/i386-linux-gnu/libssl.so" ] && [ -d "/usr/share/doc/g++-6-multilib" ] && [ -d "/usr/include/mysql" ]; }; then
+ echo "Installing apt dependencies..."
+ if ! [ -x "$has_sudo" ]; then
+ dpkg --add-architecture i386
+ apt-get update
+ apt-get install -y git cmake libmariadb-dev:i386 libssl-dev:i386 grep g++-6 g++-6-multilib
+ ln -s /usr/include/mariadb /usr/include/mysql
+ rm -rf /var/lib/apt/lists/*
+ else
+ sudo dpkg --add-architecture i386
+ sudo apt-get update
+ apt-get install -y git cmake libmariadb-dev:i386 libssl-dev:i386 grep g++-6 g++-6-multilib
+ sudo ln -s /usr/include/mariadb /usr/include/mysql
+ sudo rm -rf /var/lib/apt/lists/*
+ fi
+fi
+
+#update rust-g
+if [ ! -d "rust-g" ]; then
+ echo "Cloning rust-g..."
+ git clone https://github.com/tgstation/rust-g
+else
+ echo "Fetching rust-g..."
+ cd rust-g
+ git fetch
+ cd ..
+fi
+
+#update BSQL
+if [ ! -d "BSQL" ]; then
+ echo "Cloning BSQL..."
+ git clone https://github.com/tgstation/BSQL
+else
+ echo "Fetching BSQL..."
+ cd BSQL
+ git fetch
+ cd ..
+fi
+
+echo "Deploying rust-g..."
+cd rust-g
+git clean -fxd
+git checkout $RUST_G_VERSION
+~/.cargo/bin/cargo build --release
+mv target/release/librust_g.so $1/rust_g
+cd ..
+
+echo "Deploying BSQL..."
+cd BSQL
+git clean -fxd
+git checkout $BSQL_VERSION
+mkdir mysql
+mkdir artifacts
+cd artifacts
+cmake .. -DCMAKE_CXX_COMPILER=g++-6 -DMARIA_LIBRARY=/usr/lib/i386-linux-gnu/libmariadb.so.2
+make
+mv src/BSQL/libBSQL.so $1/
+
+#run deploy.sh
echo 'Deploying tgstation compilation...'
cd $1
@@ -14,4 +94,4 @@ shopt -u dotglob
build/tools/deploy.sh $1 $1/build
-rm -rf build
+rm -rf build
\ No newline at end of file