Merge remote-tracking branch 'origin/master' into TGUI_Updoot
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -43,7 +43,7 @@
|
||||
},
|
||||
/area/shuttle/escape/arena)
|
||||
"l" = (
|
||||
/obj/structure/closet/crate/necropolis/tendril,
|
||||
/obj/structure/closet/crate/necropolis/tendril/magic,
|
||||
/turf/open/indestructible/necropolis/air,
|
||||
/area/shuttle/escape/arena)
|
||||
"m" = (
|
||||
@@ -65,10 +65,18 @@
|
||||
/obj/structure/healingfountain,
|
||||
/turf/open/indestructible/necropolis/air,
|
||||
/area/shuttle/escape/arena)
|
||||
"t" = (
|
||||
/obj/structure/closet/crate/necropolis/tendril/misc,
|
||||
/turf/open/indestructible/necropolis/air,
|
||||
/area/shuttle/escape/arena)
|
||||
"z" = (
|
||||
/obj/effect/landmark/shuttle_arena_safe,
|
||||
/turf/open/indestructible/necropolis/air,
|
||||
/area/shuttle/escape/arena)
|
||||
"H" = (
|
||||
/obj/structure/closet/crate/necropolis/tendril/weapon_armor,
|
||||
/turf/open/indestructible/necropolis/air,
|
||||
/area/shuttle/escape/arena)
|
||||
|
||||
(1,1,1) = {"
|
||||
a
|
||||
@@ -264,16 +272,16 @@ m
|
||||
l
|
||||
j
|
||||
m
|
||||
l
|
||||
H
|
||||
j
|
||||
k
|
||||
l
|
||||
H
|
||||
j
|
||||
m
|
||||
l
|
||||
t
|
||||
j
|
||||
m
|
||||
j
|
||||
t
|
||||
j
|
||||
p
|
||||
g
|
||||
@@ -524,16 +532,16 @@ m
|
||||
l
|
||||
j
|
||||
m
|
||||
l
|
||||
H
|
||||
j
|
||||
m
|
||||
l
|
||||
H
|
||||
j
|
||||
m
|
||||
l
|
||||
t
|
||||
j
|
||||
m
|
||||
j
|
||||
t
|
||||
j
|
||||
p
|
||||
g
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
#define EXTOOLS (world.system_type == MS_WINDOWS ? "byond-extools.dll" : "libbyond-extools.so")
|
||||
@@ -1,6 +1,6 @@
|
||||
// Defines for managed input/keybinding system.
|
||||
/// Max length of a keypress command before it's considered to be a forged packet/bogus command
|
||||
#define MAX_KEYPRESS_COMMANDLENGTH 32
|
||||
#define MAX_KEYPRESS_COMMANDLENGTH 64
|
||||
/// Maximum keys that can be bound to one button
|
||||
#define MAX_COMMANDS_PER_KEY 5
|
||||
/// Maximum keys per keybind
|
||||
|
||||
@@ -281,8 +281,6 @@ GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0))
|
||||
#define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1
|
||||
#endif
|
||||
|
||||
#define EXTOOLS (world.system_type == MS_WINDOWS ? "byond-extools.dll" : "libbyond-extools.so")
|
||||
|
||||
GLOBAL_VAR(atmos_extools_initialized) // this must be an uninitialized (null) one or init_monstermos will be called twice because reasons
|
||||
#define ATMOS_EXTOOLS_CHECK if(!GLOB.atmos_extools_initialized){\
|
||||
GLOB.atmos_extools_initialized=TRUE;\
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
// /atom signals
|
||||
//from base of atom/proc/Initialize(): sent any time a new atom is created
|
||||
#define COMSIG_ATOM_CREATED "atom_created"
|
||||
//from SSatoms InitAtom - Only if the atom was not deleted or failed initialization
|
||||
#define COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE "atom_init_success"
|
||||
#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params)
|
||||
#define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called
|
||||
#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human)
|
||||
@@ -290,6 +292,10 @@
|
||||
#define COMPONENT_INTERRUPT_LIFE_BIOLOGICAL 1 // interrupt biological processes
|
||||
#define COMPONENT_INTERRUPT_LIFE_PHYSICAL 2 // interrupt physical handling
|
||||
|
||||
#define COMSIG_LIVING_BIOLOGICAL_LIFE "biological_life" //from base of mob/living/BiologicalLife() (seconds, times_fired)
|
||||
|
||||
#define COMSIG_LIVING_PHYSICAL_LIFE "physical_life" //from base of mob/living/PhysicalLife() (seconds, times_fired)
|
||||
|
||||
// /mob/living/carbon physiology signals
|
||||
#define COMSIG_CARBON_GAIN_WOUND "carbon_gain_wound" //from /datum/wound/proc/apply_wound() (/mob/living/carbon/C, /datum/wound/W, /obj/item/bodypart/L)
|
||||
#define COMSIG_CARBON_LOSE_WOUND "carbon_lose_wound" //from /datum/wound/proc/remove_wound() (/mob/living/carbon/C, /datum/wound/W, /obj/item/bodypart/L)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#define TOXIC (1<<11)
|
||||
#define PINEAPPLE (1<<12)
|
||||
#define BREAKFAST (1<<13)
|
||||
#define ANTITOXIC (1<<14)
|
||||
|
||||
#define DRINK_NICE 1
|
||||
#define DRINK_GOOD 2
|
||||
|
||||
@@ -54,3 +54,16 @@
|
||||
|
||||
//donator items
|
||||
#define LOADOUT_CATEGORY_DONATOR "Donator"
|
||||
|
||||
//how many prosthetics can we have
|
||||
#define MAXIMUM_LOADOUT_PROSTHETICS 2
|
||||
|
||||
//what limbs can be amputated or be prosthetic
|
||||
#define LOADOUT_ALLOWED_LIMB_TARGETS list(BODY_ZONE_L_ARM,BODY_ZONE_R_ARM,BODY_ZONE_L_LEG,BODY_ZONE_R_LEG)
|
||||
|
||||
//options for modifiying limbs
|
||||
#define LOADOUT_LIMB_NORMAL "Normal"
|
||||
#define LOADOUT_LIMB_PROSTHETIC "Prosthetic"
|
||||
#define LOADOUT_LIMB_AMPUTATED "Amputated"
|
||||
|
||||
#define LOADOUT_LIMBS list(LOADOUT_LIMB_NORMAL,LOADOUT_LIMB_PROSTHETIC,LOADOUT_LIMB_AMPUTATED) //you can amputate your legs/arms though
|
||||
@@ -0,0 +1,21 @@
|
||||
// Anomaly core types
|
||||
/// Bluespace cores
|
||||
#define ANOMALY_CORE_BLUESPACE /obj/item/assembly/signaler/anomaly/bluespace
|
||||
/// Gravitational cores
|
||||
#define ANOMALY_CORE_GRAVITATIONAL /obj/item/assembly/signaler/anomaly/grav
|
||||
/// Flux
|
||||
#define ANOMALY_CORE_FLUX /obj/item/assembly/signaler/anomaly/flux
|
||||
/// Vortex
|
||||
#define ANOMALY_CORE_VORTEX /obj/item/assembly/signaler/anomaly/vortex
|
||||
/// Pyro
|
||||
#define ANOMALY_CORE_PYRO /obj/item/assembly/signaler/anomaly/pyro
|
||||
|
||||
// Max amounts of cores you can make
|
||||
#define MAX_CORES_BLUESPACE 8
|
||||
#define MAX_CORES_GRAVITATIONAL 8
|
||||
#define MAX_CORES_FLUX 8
|
||||
#define MAX_CORES_VORTEX 8
|
||||
#define MAX_CORES_PYRO 8
|
||||
|
||||
/// chance supermatter anomalies drop real cores
|
||||
#define SUPERMATTER_ANOMALY_DROP_CHANCE 20
|
||||
@@ -0,0 +1,5 @@
|
||||
#define EXTOOLS_LOGGING // rust_g is used as a fallback if this is undefined
|
||||
|
||||
/proc/extools_log_write()
|
||||
|
||||
/proc/extools_finalize_logging()
|
||||
@@ -4,10 +4,15 @@
|
||||
#define SEND_SOUND(target, sound) DIRECT_OUTPUT(target, sound)
|
||||
#define SEND_TEXT(target, text) DIRECT_OUTPUT(target, text)
|
||||
#define WRITE_FILE(file, text) DIRECT_OUTPUT(file, text)
|
||||
#ifdef EXTOOLS_LOGGING
|
||||
// proc hooked, so we can just put in standard TRUE and FALSE
|
||||
#define WRITE_LOG(log, text) extools_log_write(log,text,TRUE)
|
||||
#define WRITE_LOG_NO_FORMAT(log, text) extools_log_write(log,text,FALSE)
|
||||
#else
|
||||
//This is an external call, "true" and "false" are how rust parses out booleans
|
||||
#define WRITE_LOG(log, text) rustg_log_write(log, text, "true")
|
||||
#define WRITE_LOG_NO_FORMAT(log, text) rustg_log_write(log, text, "false")
|
||||
|
||||
#endif
|
||||
//print a warning message to world.log
|
||||
#define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [UNLINT(src)] usr: [usr].")
|
||||
/proc/warning(msg)
|
||||
@@ -234,7 +239,11 @@
|
||||
|
||||
/* Close open log handles. This should be called as late as possible, and no logging should hapen after. */
|
||||
/proc/shutdown_logging()
|
||||
#ifdef EXTOOLS_LOGGING
|
||||
extools_finalize_logging()
|
||||
#else
|
||||
rustg_log_close_all()
|
||||
#endif
|
||||
|
||||
|
||||
/* Helper procs for building detailed log lines */
|
||||
|
||||
@@ -71,3 +71,18 @@
|
||||
|
||||
/proc/pathflatten(path)
|
||||
return replacetext(path, "/", "_")
|
||||
|
||||
/// Returns the md5 of a file at a given path.
|
||||
/proc/md5filepath(path)
|
||||
. = md5(file(path))
|
||||
|
||||
/// Save file as an external file then md5 it.
|
||||
/// Used because md5ing files stored in the rsc sometimes gives incorrect md5 results.
|
||||
/proc/md5asfile(file)
|
||||
var/static/notch = 0
|
||||
// its importaint this code can handle md5filepath sleeping instead of hard blocking, if it's converted to use rust_g.
|
||||
var/filename = "tmp/md5asfile.[world.realtime].[world.timeofday].[world.time].[world.tick_usage].[notch]"
|
||||
notch = WRAP(notch+1, 0, 2^15)
|
||||
fcopy(file, filename)
|
||||
. = md5filepath(filename)
|
||||
fdel(filename)
|
||||
|
||||
+15
-5
@@ -1126,12 +1126,13 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico
|
||||
var/list/partial = splittext(iconData, "{")
|
||||
return replacetext(copytext_char(partial[2], 3, -5), "\n", "")
|
||||
|
||||
/proc/icon2html(thing, target, icon_state, dir, frame = 1, moving = FALSE)
|
||||
/proc/icon2html(thing, target, icon_state, dir = SOUTH, frame = 1, moving = FALSE, sourceonly = FALSE)
|
||||
if (!thing)
|
||||
return
|
||||
|
||||
var/key
|
||||
var/icon/I = thing
|
||||
|
||||
if (!target)
|
||||
return
|
||||
if (target == world)
|
||||
@@ -1147,17 +1148,26 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico
|
||||
if (!isicon(I))
|
||||
if (isfile(thing)) //special snowflake
|
||||
var/name = sanitize_filename("[generate_asset_name(thing)].png")
|
||||
if(!SSassets.cache[name])
|
||||
if (!SSassets.cache[name])
|
||||
SSassets.transport.register_asset(name, thing)
|
||||
for (var/thing2 in targets)
|
||||
SSassets.transport.send_assets(thing2, name)
|
||||
if(sourceonly)
|
||||
return SSassets.transport.get_asset_url(name)
|
||||
return "<img class='icon icon-misc' src='[SSassets.transport.get_asset_url(name)]'>"
|
||||
var/atom/A = thing
|
||||
if (isnull(dir))
|
||||
dir = A.dir
|
||||
|
||||
I = A.icon
|
||||
if (isnull(icon_state))
|
||||
icon_state = A.icon_state
|
||||
I = A.icon
|
||||
if (!(icon_state in icon_states(I, 1)))
|
||||
icon_state = initial(A.icon_state)
|
||||
if (isnull(dir))
|
||||
dir = initial(A.dir)
|
||||
|
||||
if (isnull(dir))
|
||||
dir = A.dir
|
||||
|
||||
if (ishuman(thing)) // Shitty workaround for a BYOND issue.
|
||||
var/icon/temp = I
|
||||
I = icon()
|
||||
|
||||
@@ -279,7 +279,8 @@ GLOBAL_LIST_INIT(unlocked_mutant_parts, list("horns", "insect_fluff"))
|
||||
//parts in either of the above two lists that require a second option that allows them to be coloured
|
||||
GLOBAL_LIST_INIT(colored_mutant_parts, list("insect_wings" = "wings_color", "deco_wings" = "wings_color", "horns" = "horns_color"))
|
||||
|
||||
//species ids that have greyscale sprites
|
||||
//body ids that have greyscale sprites
|
||||
GLOBAL_LIST_INIT(greyscale_limb_types, list("human","moth","lizard","pod","plant","jelly","slime","golem","lum","stargazer","mush","ethereal","snail","c_golem","b_golem","mammal","xeno","ipc","insect","synthliz","avian","aquatic"))
|
||||
|
||||
//species ids that need snowflake coloring applied
|
||||
//body ids that have prosthetic sprites
|
||||
GLOBAL_LIST_INIT(prosthetic_limb_types, list("xion","bishop","cybersolutions","grayson","hephaestus","nanotrasen","talon"))
|
||||
|
||||
@@ -184,14 +184,23 @@
|
||||
|
||||
/obj/screen/alert/hot
|
||||
name = "Too Hot"
|
||||
desc = "You're flaming hot! Get somewhere cooler and take off any insulating clothing like a fire suit."
|
||||
desc = "The air around you is pretty toasty! Consider putting on some insulating clothing, or moving to a cooler area."
|
||||
icon_state = "hot"
|
||||
|
||||
/obj/screen/alert/cold
|
||||
name = "Too Cold"
|
||||
desc = "You're freezing cold! Get somewhere warmer and take off any insulating clothing like a space suit."
|
||||
desc = "The air around you is pretty cold! Consider wearing a coat, or moving to a warmer area."
|
||||
icon_state = "cold"
|
||||
|
||||
/obj/screen/alert/sweat
|
||||
name = "Sweating"
|
||||
desc = "You're sweating! Get somewhere cooler and take off any insulating clothing like a fire suit."
|
||||
icon_state = "sweat"
|
||||
|
||||
/obj/screen/alert/shiver
|
||||
name = "Shivering"
|
||||
desc = "You're shivering! Get somewhere warmer and take off any insulating clothing like a space suit."
|
||||
|
||||
/obj/screen/alert/lowpressure
|
||||
name = "Low Pressure"
|
||||
desc = "The air around you is hazardously thin. A space suit would protect you."
|
||||
|
||||
@@ -90,6 +90,8 @@ SUBSYSTEM_DEF(atoms)
|
||||
qdeleted = TRUE
|
||||
else if(!(A.flags_1 & INITIALIZED_1))
|
||||
BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT
|
||||
else
|
||||
SEND_SIGNAL(A,COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE)
|
||||
|
||||
return qdeleted || QDELING(A)
|
||||
|
||||
|
||||
@@ -48,25 +48,6 @@ SUBSYSTEM_DEF(persistence)
|
||||
/datum/controller/subsystem/persistence/proc/LoadSatchels()
|
||||
var/placed_satchel = 0
|
||||
var/path
|
||||
if(fexists("data/npc_saves/SecretSatchels.sav")) //legacy conversion. Will only ever run once.
|
||||
var/savefile/secret_satchels = new /savefile("data/npc_saves/SecretSatchels.sav")
|
||||
for(var/map in secret_satchels)
|
||||
var/json_file = file("data/npc_saves/SecretSatchels[map].json")
|
||||
var/list/legacy_secret_satchels = splittext(secret_satchels[map],"#")
|
||||
var/list/satchels = list()
|
||||
for(var/i=1,i<=legacy_secret_satchels.len,i++)
|
||||
var/satchel_string = legacy_secret_satchels[i]
|
||||
var/list/chosen_satchel = splittext(satchel_string,"|")
|
||||
if(chosen_satchel.len == 3)
|
||||
var/list/data = list()
|
||||
data["x"] = text2num(chosen_satchel[1])
|
||||
data["y"] = text2num(chosen_satchel[2])
|
||||
data["saved_obj"] = chosen_satchel[3]
|
||||
satchels += list(data)
|
||||
var/list/file_data = list()
|
||||
file_data["data"] = satchels
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
fdel("data/npc_saves/SecretSatchels.sav")
|
||||
|
||||
var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
|
||||
var/list/json = list()
|
||||
|
||||
@@ -294,6 +294,17 @@ SUBSYSTEM_DEF(research)
|
||||
//[88nodes * 5000points/node] / [1.5hr * 90min/hr * 60s/min]
|
||||
//Around 450000 points max???
|
||||
|
||||
/// The global list of raw anomaly types that have been refined, for hard limits.
|
||||
var/list/created_anomaly_types = list()
|
||||
/// The hard limits of cores created for each anomaly type. For faster code lookup without switch statements.
|
||||
var/list/anomaly_hard_limit_by_type = list(
|
||||
ANOMALY_CORE_BLUESPACE = MAX_CORES_BLUESPACE,
|
||||
ANOMALY_CORE_PYRO = MAX_CORES_PYRO,
|
||||
ANOMALY_CORE_GRAVITATIONAL = MAX_CORES_GRAVITATIONAL,
|
||||
ANOMALY_CORE_VORTEX = MAX_CORES_VORTEX,
|
||||
ANOMALY_CORE_FLUX = MAX_CORES_FLUX
|
||||
)
|
||||
|
||||
/datum/controller/subsystem/research/Initialize()
|
||||
point_types = TECHWEB_POINT_TYPE_LIST_ASSOCIATIVE_NAMES
|
||||
initialize_all_techweb_designs()
|
||||
|
||||
@@ -396,6 +396,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
SSjob.EquipRank(N, player.mind.assigned_role, 0)
|
||||
if(CONFIG_GET(flag/roundstart_traits) && ishuman(N.new_character))
|
||||
SSquirks.AssignQuirks(N.new_character, N.client, TRUE, TRUE, SSjob.GetJob(player.mind.assigned_role), FALSE, N)
|
||||
N.client.prefs.post_copy_to(player)
|
||||
CHECK_TICK
|
||||
if(captainless)
|
||||
for(var/mob/dead/new_player/N in GLOB.player_list)
|
||||
|
||||
@@ -78,23 +78,22 @@
|
||||
speech_args[SPEECH_MESSAGE] = lowertext(message)
|
||||
return speech_args
|
||||
|
||||
/datum/accent/bone
|
||||
/datum/accent/span
|
||||
var/span_flag
|
||||
|
||||
/datum/accent/bone/modify_speech(list/speech_args)
|
||||
speech_args[SPEECH_SPANS] = span_flag
|
||||
/datum/accent/span/modify_speech(list/speech_args)
|
||||
speech_args[SPEECH_SPANS] |= span_flag
|
||||
return speech_args
|
||||
|
||||
//bone tongues either have the sans accent or the papyrus accent
|
||||
/datum/accent/bone/sans
|
||||
/datum/accent/span/sans
|
||||
span_flag = SPAN_SANS
|
||||
|
||||
/datum/accent/bone/papyrus
|
||||
/datum/accent/span/papyrus
|
||||
span_flag = SPAN_PAPYRUS
|
||||
|
||||
/datum/accent/robot/modify_speech(list/speech_args)
|
||||
speech_args[SPEECH_SPANS] = SPAN_ROBOT
|
||||
return speech_args
|
||||
/datum/accent/span/robot
|
||||
span_flag = SPAN_ROBOT
|
||||
|
||||
/datum/accent/dullahan/modify_speech(list/speech_args, datum/source, mob/living/carbon/owner)
|
||||
if(owner)
|
||||
|
||||
@@ -273,6 +273,16 @@
|
||||
time = 30
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/twinsheath
|
||||
name = "Twin Sword Sheath"
|
||||
result = /obj/item/storage/belt/sabre/twin
|
||||
reqs = list(/obj/item/stack/sheet/mineral/wood = 3,
|
||||
/obj/item/stack/sheet/leather = 8)
|
||||
tools = list(TOOL_WIRECUTTER)
|
||||
time = 70
|
||||
category = CAT_CLOTHING
|
||||
|
||||
|
||||
/datum/crafting_recipe/durathread_reinforcement_kit
|
||||
name = "Durathread Reinforcement Kit"
|
||||
result = /obj/item/armorkit
|
||||
|
||||
@@ -120,6 +120,53 @@
|
||||
category = CAT_MISC
|
||||
always_availible = FALSE // Disabled til learned
|
||||
|
||||
/datum/crafting_recipe/furnace
|
||||
name = "Sandstone Furnace"
|
||||
result = /obj/structure/furnace
|
||||
time = 300
|
||||
reqs = list(/obj/item/stack/sheet/mineral/sandstone = 15,
|
||||
/obj/item/stack/sheet/metal = 4,
|
||||
/obj/item/stack/rods = 2)
|
||||
tools = list(TOOL_CROWBAR)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/tableanvil
|
||||
name = "Table Anvil"
|
||||
result = /obj/structure/anvil/obtainable/table
|
||||
time = 300
|
||||
reqs = list(/obj/item/stack/sheet/metal = 4,
|
||||
/obj/item/stack/rods = 2)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/sandvil
|
||||
name = "Sandstone Anvil"
|
||||
result = /obj/structure/anvil/obtainable/sandstone
|
||||
time = 300
|
||||
reqs = list(/obj/item/stack/sheet/mineral/sandstone = 24)
|
||||
tools = list(TOOL_CROWBAR)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/basaltblock
|
||||
name = "Sintered Basalt Block"
|
||||
result = /obj/item/basaltblock
|
||||
time = 200
|
||||
reqs = list(/obj/item/stack/ore/glass/basalt = 50)
|
||||
tools = list(TOOL_WELDER)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/basaltanvil
|
||||
name = "Basalt Anvil"
|
||||
result = /obj/structure/anvil/obtainable/basalt
|
||||
time = 200
|
||||
reqs = list(/obj/item/basaltblock = 5)
|
||||
tools = list(TOOL_CROWBAR)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
///////////////////
|
||||
//Tools & Storage//
|
||||
///////////////////
|
||||
@@ -175,6 +222,17 @@
|
||||
subcategory = CAT_TOOL
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/toolboxhammer
|
||||
name = "Toolbox Hammer"
|
||||
result = /obj/item/melee/smith/hammer/toolbox
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
|
||||
reqs = list(/obj/item/storage/toolbox = 1,
|
||||
/obj/item/stack/sheet/metal = 4,
|
||||
/obj/item/stack/rods = 2)
|
||||
time = 40
|
||||
subcategory = CAT_TOOL
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/papersack
|
||||
name = "Paper Sack"
|
||||
result = /obj/item/storage/box/papersack
|
||||
@@ -358,6 +416,25 @@
|
||||
//Unsorted//
|
||||
////////////
|
||||
|
||||
|
||||
|
||||
/datum/crafting_recipe/stick
|
||||
name = "Stick"
|
||||
time = 30
|
||||
reqs = list(/obj/item/stack/sheet/mineral/wood = 1)
|
||||
result = /obj/item/stick
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
|
||||
/datum/crafting_recipe/swordhilt
|
||||
name = "Sword Hilt"
|
||||
time = 30
|
||||
reqs = list(/obj/item/stack/sheet/mineral/wood = 2)
|
||||
result = /obj/item/swordhandle
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/blackcarpet
|
||||
name = "Black Carpet"
|
||||
reqs = list(/obj/item/stack/tile/carpet = 50, /obj/item/toy/crayon/black = 1)
|
||||
|
||||
@@ -45,8 +45,9 @@
|
||||
|
||||
/datum/fantasy_affix/tactical/apply(datum/component/fantasy/comp, newName)
|
||||
var/obj/item/master = comp.parent
|
||||
master.AddElement(/datum/element/tactical)
|
||||
comp.appliedElements += list(/datum/element/tactical)
|
||||
var/list/dat = list(/datum/element/tactical)
|
||||
master._AddElement(dat)
|
||||
comp.appliedElements += list(dat)
|
||||
return "tactical [newName]"
|
||||
|
||||
/datum/fantasy_affix/pyromantic
|
||||
|
||||
@@ -41,19 +41,27 @@
|
||||
var/atom/A = target
|
||||
num_decals_per_atom[A]--
|
||||
if(!num_decals_per_atom[A])
|
||||
UnregisterSignal(A, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE, COMSIG_ATOM_UPDATE_OVERLAYS))
|
||||
UnregisterSignal(A, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE,
|
||||
COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE, COMSIG_ATOM_UPDATE_OVERLAYS))
|
||||
LAZYREMOVE(num_decals_per_atom, A)
|
||||
apply(A)
|
||||
return ..()
|
||||
|
||||
/datum/element/decal/proc/apply(atom/target)
|
||||
target.update_icon()
|
||||
if(target.flags_1 & INITIALIZED_1)
|
||||
target.update_icon() //could use some queuing here now maybe.
|
||||
else if(!QDELETED(target) && num_decals_per_atom[target] == 1)
|
||||
RegisterSignal(target, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE, .proc/late_update_icon)
|
||||
if(isitem(target))
|
||||
addtimer(CALLBACK(target, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
|
||||
|
||||
/datum/element/decal/proc/late_update_icon(atom/source)
|
||||
source.update_icon()
|
||||
UnregisterSignal(source,COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE)
|
||||
|
||||
/datum/element/decal/proc/apply_overlay(atom/source, list/overlay_list)
|
||||
if(first_dir)
|
||||
pic.dir = turn(first_dir, -dir2angle(source.dir))
|
||||
pic.dir = first_dir == SOUTH ? source.dir : turn(first_dir, dir2angle(source.dir)-180) //Never turn a dir by 0.
|
||||
for(var/i in 1 to num_decals_per_atom[source])
|
||||
overlay_list += pic
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
A.AddElement(/datum/element/update_icon_updates_onmob)
|
||||
RegisterSignal(A, COMSIG_ITEM_WORN_OVERLAYS, .proc/apply_worn_overlays)
|
||||
if(suits_with_helmet_typecache[A.type])
|
||||
RegisterSignal(A, COMSIG_SUIT_MADE_HELMET, .proc/register_helmet)
|
||||
RegisterSignal(A, COMSIG_SUIT_MADE_HELMET, .proc/register_helmet) //you better work now you slut
|
||||
else if(_flags & POLYCHROMIC_ACTION && ismob(A)) //in the event mob update icon procs are ever standarized.
|
||||
var/datum/action/polychromic/P = new(A)
|
||||
RegisterSignal(P, COMSIG_ACTION_TRIGGER, .proc/activate_action)
|
||||
@@ -166,6 +166,15 @@
|
||||
examine_list += "<span class='notice'>Alt-click to recolor it.</span>"
|
||||
|
||||
/datum/element/polychromic/proc/register_helmet(atom/source, obj/item/clothing/head/H)
|
||||
if(!isitem(H)) //backup in case if it messes up somehow
|
||||
if(istype(source,/obj/item/clothing/suit/hooded)) //so how come it be like this, where toggleable headslots are named separately (helmet/hood) anyways?
|
||||
var/obj/item/clothing/suit/hooded/sourcesuit = source
|
||||
H = sourcesuit.hood
|
||||
else if(istype(source,/obj/item/clothing/suit/space/hardsuit))
|
||||
var/obj/item/clothing/suit/space/hardsuit/sourcesuit = source
|
||||
H = sourcesuit.helmet
|
||||
else
|
||||
return
|
||||
suit_by_helmet[H] = source
|
||||
helmet_by_suit[source] = H
|
||||
colors_by_atom[H] = colors_by_atom[source]
|
||||
|
||||
@@ -35,23 +35,24 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
value_per_unit = 0.025
|
||||
beauty_modifier = 0.075
|
||||
|
||||
///Slight force increase
|
||||
///Slight force decrease. It's gold, it's soft as fuck.
|
||||
/datum/material/gold
|
||||
name = "gold"
|
||||
desc = "Gold"
|
||||
color = list(340/255, 240/255, 50/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) //gold is shiny, but not as bright as bananium
|
||||
strength_modifier = 1.2
|
||||
strength_modifier = 0.8
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/gold
|
||||
value_per_unit = 0.0625
|
||||
beauty_modifier = 0.15
|
||||
armor_modifiers = list("melee" = 1.1, "bullet" = 1.1, "laser" = 1.15, "energy" = 1.15, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 0.7, "acid" = 1.1)
|
||||
|
||||
///Has no special properties
|
||||
///Small force increase, for diamond swords
|
||||
/datum/material/diamond
|
||||
name = "diamond"
|
||||
desc = "Highly pressurized carbon"
|
||||
color = list(48/255, 272/255, 301/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0)
|
||||
strength_modifier = 1.1
|
||||
alpha = 132
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/diamond
|
||||
@@ -106,6 +107,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
name = "bluespace crystal"
|
||||
desc = "Crystals with bluespace properties"
|
||||
color = list(119/255, 217/255, 396/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0)
|
||||
integrity_modifier = 0.2 //these things shatter when thrown.
|
||||
alpha = 200
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE)
|
||||
beauty_modifier = 0.5
|
||||
@@ -139,7 +141,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
name = "titanium"
|
||||
desc = "Titanium"
|
||||
color = "#b3c0c7"
|
||||
strength_modifier = 1.3
|
||||
strength_modifier = 1.1
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/titanium
|
||||
value_per_unit = 0.0625
|
||||
@@ -203,7 +205,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
name = "adamantine"
|
||||
desc = "A powerful material made out of magic, I mean science!"
|
||||
color = "#6d7e8e"
|
||||
strength_modifier = 1.5
|
||||
strength_modifier = 1.3
|
||||
categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/adamantine
|
||||
value_per_unit = 0.25
|
||||
@@ -276,16 +278,29 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
desc = "Mir'ntrath barhah Nar'sie."
|
||||
color = "#3C3434"
|
||||
categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE)
|
||||
strength_modifier = 1.2
|
||||
sheet_type = /obj/item/stack/sheet/runed_metal
|
||||
value_per_unit = 0.75
|
||||
armor_modifiers = list("melee" = 1.2, "bullet" = 1.2, "laser" = 1, "energy" = 1, "bomb" = 1.2, "bio" = 1.2, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5)
|
||||
beauty_modifier = -0.15
|
||||
texture_layer_icon_state = "runed"
|
||||
|
||||
/datum/material/brass
|
||||
name = "brass"
|
||||
desc = "Tybel gb-Ratvar"
|
||||
color = "#917010"
|
||||
categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE)
|
||||
strength_modifier = 1.3 // Replicant Alloy is very good for skull beatings..
|
||||
sheet_type = /obj/item/stack/tile/brass
|
||||
value_per_unit = 0.75
|
||||
armor_modifiers = list("melee" = 1.4, "bullet" = 1.4, "laser" = 0, "energy" = 0, "bomb" = 1.4, "bio" = 1.2, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5) //But it has.. a few problems that can't easily be compensated for.
|
||||
beauty_modifier = 0.3 //It really beats the cold plain plating of the station, doesn't it?
|
||||
|
||||
/datum/material/bronze
|
||||
name = "bronze"
|
||||
desc = "Clock Cult? Never heard of it."
|
||||
color = "#92661A"
|
||||
strength_modifier = 1.1
|
||||
categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/bronze
|
||||
value_per_unit = 0.025
|
||||
|
||||
@@ -204,6 +204,11 @@
|
||||
mood_change = -1
|
||||
timeout = 2 MINUTES
|
||||
|
||||
/datum/mood_event/plush_bite
|
||||
description = "<span class='warning'>IT BIT ME!! OW!</span>\n"
|
||||
mood_change = -3
|
||||
timeout = 2 MINUTES
|
||||
|
||||
//Cursed stuff below
|
||||
|
||||
/datum/mood_event/emptypred
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
var/lowest_value = 256 * 8
|
||||
var/text_gain_indication = ""
|
||||
var/text_lose_indication = ""
|
||||
var/list/mutable_appearance/visual_indicators = list()
|
||||
var/list/visual_indicators = list()
|
||||
var/obj/effect/proc_holder/spell/power
|
||||
var/layer_used = MUTATIONS_LAYER //which mutation layer to use
|
||||
var/list/species_allowed = list() //to restrict mutation to only certain species
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
|
||||
/**
|
||||
* Automatic skill increase, multiplied by skill affinity if existing.
|
||||
* Only works if skill is numerical.
|
||||
* Only works if skill is numerical or levelled..
|
||||
*/
|
||||
/datum/mind/proc/auto_gain_experience(skill, value, maximum, silent = FALSE)
|
||||
if(!ispath(skill, /datum/skill))
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/datum/skill/level/dorfy/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
|
||||
@@ -533,6 +533,38 @@
|
||||
if(100)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN,20)
|
||||
|
||||
/datum/status_effect/corrosion_curse/lesser
|
||||
id = "corrosion_curse_lesser"
|
||||
duration = 20 SECONDS
|
||||
|
||||
/datum/status_effect/corrosion_curse/lesser/tick()
|
||||
. = ..()
|
||||
if(!ishuman(owner))
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner
|
||||
var/chance = rand(0,100)
|
||||
switch(chance)
|
||||
if(0 to 19)
|
||||
H.adjustBruteLoss(6)
|
||||
if(20 to 29)
|
||||
H.Dizzy(10)
|
||||
if(30 to 39)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_LIVER,2)
|
||||
if(40 to 49)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_HEART,2)
|
||||
if(50 to 59)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_STOMACH,2)
|
||||
if(60 to 69)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_EYES,5)
|
||||
if(70 to 79)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_EARS,5)
|
||||
if(80 to 89)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_LUNGS,5)
|
||||
if(90 to 99)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_TONGUE,5)
|
||||
if(100)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN,10)
|
||||
|
||||
/datum/status_effect/amok
|
||||
id = "amok"
|
||||
status_type = STATUS_EFFECT_REPLACE
|
||||
|
||||
@@ -211,24 +211,27 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
H.gain_trauma(T, TRAUMA_RESILIENCE_ABSOLUTE)
|
||||
|
||||
/datum/quirk/paraplegic/on_spawn()
|
||||
if(quirk_holder.buckled) // Handle late joins being buckled to arrival shuttle chairs.
|
||||
quirk_holder.buckled.unbuckle_mob(quirk_holder)
|
||||
if(quirk_holder.client)
|
||||
var/modified_limbs = quirk_holder.client.prefs.modified_limbs
|
||||
if(!(modified_limbs[BODY_ZONE_L_LEG] == LOADOUT_LIMB_AMPUTATED && modified_limbs[BODY_ZONE_R_LEG] == LOADOUT_LIMB_AMPUTATED && !isjellyperson(quirk_holder)))
|
||||
if(quirk_holder.buckled) // Handle late joins being buckled to arrival shuttle chairs.
|
||||
quirk_holder.buckled.unbuckle_mob(quirk_holder)
|
||||
|
||||
var/turf/T = get_turf(quirk_holder)
|
||||
var/obj/structure/chair/spawn_chair = locate() in T
|
||||
var/turf/T = get_turf(quirk_holder)
|
||||
var/obj/structure/chair/spawn_chair = locate() in T
|
||||
|
||||
var/obj/vehicle/ridden/wheelchair/wheels = new(T)
|
||||
if(spawn_chair) // Makes spawning on the arrivals shuttle more consistent looking
|
||||
wheels.setDir(spawn_chair.dir)
|
||||
var/obj/vehicle/ridden/wheelchair/wheels = new(T)
|
||||
if(spawn_chair) // Makes spawning on the arrivals shuttle more consistent looking
|
||||
wheels.setDir(spawn_chair.dir)
|
||||
|
||||
wheels.buckle_mob(quirk_holder)
|
||||
wheels.buckle_mob(quirk_holder)
|
||||
|
||||
// During the spawning process, they may have dropped what they were holding, due to the paralysis
|
||||
// So put the things back in their hands.
|
||||
// During the spawning process, they may have dropped what they were holding, due to the paralysis
|
||||
// So put the things back in their hands.
|
||||
|
||||
for(var/obj/item/I in T)
|
||||
if(I.fingerprintslast == quirk_holder.ckey)
|
||||
quirk_holder.put_in_hands(I)
|
||||
for(var/obj/item/I in T)
|
||||
if(I.fingerprintslast == quirk_holder.ckey)
|
||||
quirk_holder.put_in_hands(I)
|
||||
|
||||
/datum/quirk/poor_aim
|
||||
name = "Poor Aim"
|
||||
@@ -244,42 +247,6 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
mob_trait = TRAIT_PROSOPAGNOSIA
|
||||
medical_record_text = "Patient suffers from prosopagnosia and cannot recognize faces."
|
||||
|
||||
/datum/quirk/prosthetic_limb
|
||||
name = "Prosthetic Limb"
|
||||
desc = "An accident caused you to lose one of your limbs. Because of this, you now have a random prosthetic!"
|
||||
value = -1
|
||||
var/slot_string = "limb"
|
||||
|
||||
/datum/quirk/prosthetic_limb/on_spawn()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/limb_slot
|
||||
if(HAS_TRAIT(H, TRAIT_PARA))//Prevent paraplegic legs being replaced
|
||||
limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)
|
||||
else
|
||||
limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
|
||||
var/obj/item/bodypart/old_part = H.get_bodypart(limb_slot)
|
||||
var/obj/item/bodypart/prosthetic
|
||||
switch(limb_slot)
|
||||
if(BODY_ZONE_L_ARM)
|
||||
prosthetic = new/obj/item/bodypart/l_arm/robot/surplus(quirk_holder)
|
||||
slot_string = "left arm"
|
||||
if(BODY_ZONE_R_ARM)
|
||||
prosthetic = new/obj/item/bodypart/r_arm/robot/surplus(quirk_holder)
|
||||
slot_string = "right arm"
|
||||
if(BODY_ZONE_L_LEG)
|
||||
prosthetic = new/obj/item/bodypart/l_leg/robot/surplus(quirk_holder)
|
||||
slot_string = "left leg"
|
||||
if(BODY_ZONE_R_LEG)
|
||||
prosthetic = new/obj/item/bodypart/r_leg/robot/surplus(quirk_holder)
|
||||
slot_string = "right leg"
|
||||
prosthetic.replace_limb(H)
|
||||
qdel(old_part)
|
||||
H.regenerate_icons()
|
||||
|
||||
/datum/quirk/prosthetic_limb/post_add()
|
||||
to_chat(quirk_holder, "<span class='boldannounce'>Your [slot_string] has been replaced with a surplus prosthetic. It is fragile and will easily come apart under duress. Additionally, \
|
||||
you need to use a welding tool and cables to repair it, instead of bruise packs and ointment.</span>")
|
||||
|
||||
/datum/quirk/insanity
|
||||
name = "Reality Dissociation Syndrome"
|
||||
desc = "You suffer from a severe disorder that causes very vivid hallucinations. Mindbreaker toxin can suppress its effects, and you are immune to mindbreaker's hallucinogenic properties. <b>This is not a license to grief.</b>"
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
/datum/wires/airlock/on_pulse(wire)
|
||||
set waitfor = FALSE
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
if(!A.hasSiliconAccessInArea(usr) && A.isElectrified() && A.shock(usr, 100))
|
||||
if(usr && !A.hasSiliconAccessInArea(usr) && A.isElectrified() && A.shock(usr, 100))
|
||||
return FALSE
|
||||
switch(wire)
|
||||
if(WIRE_POWER1, WIRE_POWER2) // Pulse to loose power.
|
||||
@@ -127,7 +127,7 @@
|
||||
|
||||
/datum/wires/airlock/on_cut(wire, mend)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
if(!A.hasSiliconAccessInArea(usr) && A.isElectrified() && A.shock(usr, 100))
|
||||
if(usr && !A.hasSiliconAccessInArea(usr) && A.isElectrified() && A.shock(usr, 100))
|
||||
return FALSE
|
||||
switch(wire)
|
||||
if(WIRE_POWER1, WIRE_POWER2) // Cut to loose power, repair all to gain power.
|
||||
|
||||
@@ -43,6 +43,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
outdoors = TRUE
|
||||
ambientsounds = SPACE
|
||||
blob_allowed = FALSE //Eating up space doesn't count for victory as a blob.
|
||||
considered_hull_exterior = TRUE
|
||||
|
||||
/area/space/nearstation
|
||||
icon_state = "space_near"
|
||||
@@ -1592,4 +1593,4 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
valid_territory = FALSE
|
||||
outdoors = TRUE
|
||||
ambientsounds = SPACE
|
||||
blob_allowed = FALSE //While part of the station, what good will it do you?
|
||||
blob_allowed = FALSE //While part of the station, what good will it do you?
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
/// If megafauna can be spawned by natural random generation
|
||||
var/megafauna_spawn_allowed = FALSE
|
||||
|
||||
/// Considered space for hull shielding
|
||||
var/considered_hull_exterior = FALSE
|
||||
|
||||
var/fire = null
|
||||
var/atmos = TRUE
|
||||
var/atmosalm = FALSE
|
||||
|
||||
@@ -6,10 +6,6 @@ GLOBAL_VAR_INIT(dynamic_latejoin_delay_max, (30 MINUTES))
|
||||
GLOBAL_VAR_INIT(dynamic_midround_delay_min, (10 MINUTES))
|
||||
GLOBAL_VAR_INIT(dynamic_midround_delay_max, (30 MINUTES))
|
||||
|
||||
GLOBAL_VAR_INIT(dynamic_event_delay_min, (10 MINUTES))
|
||||
GLOBAL_VAR_INIT(dynamic_event_delay_max, (30 MINUTES)) // this is on top of regular events, so can't be quite as often
|
||||
|
||||
|
||||
// -- Roundstart injection delays
|
||||
GLOBAL_VAR_INIT(dynamic_first_latejoin_delay_min, (2 MINUTES))
|
||||
GLOBAL_VAR_INIT(dynamic_first_latejoin_delay_max, (30 MINUTES))
|
||||
@@ -58,7 +54,7 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
|
||||
// Threat logging vars
|
||||
/// Starting threat level, for things that increase it but can bring it back down.
|
||||
var/initial_threat_level = 0
|
||||
/// Target threat level right now. Events and antags will try to keep the round at this level.
|
||||
/// Target threat level right now. Antags will try to keep the round at this level.
|
||||
var/threat_level = 0
|
||||
/// The current antag threat. Recalculated every time a ruletype starts or ends.
|
||||
var/threat = 0
|
||||
@@ -80,8 +76,6 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
|
||||
var/list/latejoin_rules = list()
|
||||
/// List of midround rules used for selecting the rules.
|
||||
var/list/midround_rules = list()
|
||||
/// List of events used for reducing threat without causing antag injection (necessarily).
|
||||
var/list/events = list()
|
||||
/** # Pop range per requirement.
|
||||
* If the value is five the range is:
|
||||
* 0-4, 5-9, 10-14, 15-19, 20-24, 25-29, 30-34, 35-39, 40-54, 45+
|
||||
@@ -119,8 +113,6 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
|
||||
var/latejoin_injection_cooldown = 0
|
||||
/// When world.time is over this number the mode tries to inject a midround ruleset.
|
||||
var/midround_injection_cooldown = 0
|
||||
/// When wor.dtime is over this number the mode tries to do an event.
|
||||
var/event_injection_cooldown = 0
|
||||
/// When TRUE GetInjectionChance returns 100.
|
||||
var/forced_injection = FALSE
|
||||
/// Forced ruleset to be executed for the next latejoin.
|
||||
@@ -184,7 +176,6 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
|
||||
dat += "<br>Injection Timers: (<b>[storyteller.get_injection_chance(TRUE)]%</b> chance)<BR>"
|
||||
dat += "Latejoin: [(latejoin_injection_cooldown-world.time)>60*10 ? "[round((latejoin_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(latejoin_injection_cooldown-world.time)/10] seconds"] <a href='?src=\ref[src];[HrefToken()];injectlate=1'>\[Now!\]</a><BR>"
|
||||
dat += "Midround: [(midround_injection_cooldown-world.time)>60*10 ? "[round((midround_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(midround_injection_cooldown-world.time)/10] seconds"] <a href='?src=\ref[src];[HrefToken()];injectmid=1'>\[Now!\]</a><BR>"
|
||||
dat += "Event: [(event_injection_cooldown-world.time)>60*10 ? "[round((event_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(event_injection_cooldown-world.time)/10] seconds"] <a href='?src=\ref[src];[HrefToken()];forceevent=1'>\[Now!\]</a><BR>"
|
||||
usr << browse(dat.Join(), "window=gamemode_panel;size=500x500")
|
||||
|
||||
/datum/game_mode/dynamic/Topic(href, href_list)
|
||||
@@ -204,10 +195,7 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
|
||||
var/threatadd = input("Specify how much threat to add (negative to subtract). This can inflate the threat level.", "Adjust Threat", 0) as null|num
|
||||
if(!threatadd)
|
||||
return
|
||||
if(threatadd > 0)
|
||||
create_threat(threatadd)
|
||||
else
|
||||
remove_threat(threatadd)
|
||||
create_threat(threatadd)
|
||||
else if (href_list["injectlate"])
|
||||
latejoin_injection_cooldown = 0
|
||||
forced_injection = TRUE
|
||||
@@ -216,10 +204,6 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
|
||||
midround_injection_cooldown = 0
|
||||
forced_injection = TRUE
|
||||
message_admins("[key_name(usr)] forced a midround injection.", 1)
|
||||
else if (href_list["forceevent"])
|
||||
event_injection_cooldown = 0
|
||||
// events always happen anyway
|
||||
message_admins("[key_name(usr)] forced an event.", 1)
|
||||
else if (href_list["threatlog"])
|
||||
show_threatlog(usr)
|
||||
else if (href_list["stacking_limit"])
|
||||
@@ -377,8 +361,6 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
|
||||
generate_threat()
|
||||
|
||||
storyteller.start_injection_cooldowns()
|
||||
SSevents.frequency_lower = storyteller.event_frequency_lower // 6 minutes by default
|
||||
SSevents.frequency_upper = storyteller.event_frequency_upper // 20 minutes by default
|
||||
log_game("DYNAMIC: Dynamic Mode initialized with a Threat Level of... [threat_level]!")
|
||||
initial_threat_level = threat_level
|
||||
return TRUE
|
||||
@@ -397,9 +379,6 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
|
||||
if ("Midround")
|
||||
if (ruleset.weight)
|
||||
midround_rules += ruleset
|
||||
if("Event")
|
||||
if(ruleset.weight)
|
||||
events += ruleset
|
||||
for(var/mob/dead/new_player/player in GLOB.player_list)
|
||||
if(player.ready == PLAYER_READY_TO_PLAY && player.mind)
|
||||
roundstart_pop_ready++
|
||||
@@ -596,8 +575,6 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
|
||||
latejoin_rules = remove_from_list(latejoin_rules, rule.type)
|
||||
else if(rule.ruletype == "Midround")
|
||||
midround_rules = remove_from_list(midround_rules, rule.type)
|
||||
else if(rule.ruletype == "Event")
|
||||
events = remove_from_list(events,rule.type)
|
||||
addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/execute_midround_latejoin_rule, rule), rule.delay)
|
||||
return TRUE
|
||||
|
||||
@@ -706,17 +683,6 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
|
||||
picking_midround_latejoin_rule(drafted_rules)
|
||||
// get_injection_chance can do things on fail
|
||||
|
||||
if(event_injection_cooldown < world.time)
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Attempted event injections")
|
||||
event_injection_cooldown = storyteller.get_event_cooldown() + world.time
|
||||
message_admins("DYNAMIC: Doing event injection.")
|
||||
log_game("DYNAMIC: Doing event injection.")
|
||||
update_playercounts()
|
||||
var/list/drafted_rules = storyteller.event_draft()
|
||||
if(drafted_rules.len > 0)
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Successful event injections")
|
||||
picking_midround_latejoin_rule(drafted_rules)
|
||||
|
||||
/// Updates current_players.
|
||||
/datum/game_mode/dynamic/proc/update_playercounts()
|
||||
current_players[CURRENT_LIVING_PLAYERS] = list()
|
||||
|
||||
@@ -1,454 +0,0 @@
|
||||
/datum/dynamic_ruleset/event
|
||||
ruletype = "Event"
|
||||
var/typepath // typepath of the event
|
||||
var/triggering
|
||||
var/earliest_start = 20 MINUTES
|
||||
|
||||
/datum/dynamic_ruleset/event/get_blackbox_info()
|
||||
var/list/ruleset_data = list()
|
||||
ruleset_data["name"] = name
|
||||
ruleset_data["rule_type"] = ruletype
|
||||
ruleset_data["cost"] = total_cost
|
||||
ruleset_data["weight"] = weight
|
||||
ruleset_data["scaled_times"] = scaled_times
|
||||
ruleset_data["event_type"] = typepath
|
||||
ruleset_data["population_tier"] = indice_pop
|
||||
return ruleset_data
|
||||
|
||||
/datum/dynamic_ruleset/event/execute()
|
||||
var/datum/round_event/E = new typepath()
|
||||
E.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1)
|
||||
// E.control = src // can't be done! we just don't use events that require these, those can be from_ghost almost always
|
||||
|
||||
testing("[time2text(world.time, "hh:mm:ss")] [E.type]")
|
||||
deadchat_broadcast("<span class='deadsay'><b>[name]</b> has just been triggered by dynamic!</span>")
|
||||
log_game("Random Event triggering: [name] ([typepath])")
|
||||
|
||||
return E
|
||||
|
||||
/datum/dynamic_ruleset/event/ready(forced = FALSE)
|
||||
if (!forced)
|
||||
if(earliest_start >= world.time-SSticker.round_start_time)
|
||||
return FALSE
|
||||
var/job_check = 0
|
||||
if (enemy_roles.len > 0)
|
||||
for (var/mob/M in mode.current_players[CURRENT_LIVING_PLAYERS])
|
||||
if (M.stat == DEAD)
|
||||
continue // Dead players cannot count as opponents
|
||||
if (M.mind && M.mind.assigned_role && (M.mind.assigned_role in enemy_roles))
|
||||
job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that rule, or have a job that restricts them from it
|
||||
|
||||
var/threat = round(mode.threat_level/10)
|
||||
if (job_check < required_enemies[threat])
|
||||
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough enemy roles")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// PIRATES //
|
||||
// //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/datum/dynamic_ruleset/event/pirates
|
||||
name = "Space Pirates"
|
||||
config_tag = "pirates"
|
||||
typepath = /datum/round_event/pirates
|
||||
antag_flag = ROLE_TRAITOR
|
||||
enemy_roles = list("AI","Security Officer","Head of Security","Captain")
|
||||
required_enemies = list(2,2,1,1,0,0,0,0,0,0)
|
||||
weight = 5
|
||||
cost = 10
|
||||
earliest_start = 30 MINUTES
|
||||
blocking_rules = list(/datum/dynamic_ruleset/roundstart/nuclear,/datum/dynamic_ruleset/midround/from_ghosts/nuclear)
|
||||
requirements = list(70,60,50,50,40,40,40,30,20,15)
|
||||
property_weights = list("story_potential" = 1, "trust" = 1, "chaos" = 1)
|
||||
high_population_requirement = 15
|
||||
|
||||
/datum/dynamic_ruleset/event/pirates/ready(forced = FALSE)
|
||||
if (!SSmapping.empty_space)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// SPIDERS //
|
||||
// //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/datum/dynamic_ruleset/event/spiders
|
||||
name = "Spider Infestation"
|
||||
config_tag = "spiders"
|
||||
typepath = /datum/round_event/spider_infestation
|
||||
enemy_roles = list("AI","Security Officer","Head of Security","Captain")
|
||||
required_enemies = list(2,2,1,1,0,0,0,0,0,0)
|
||||
weight = 5
|
||||
cost = 10
|
||||
requirements = list(70,60,50,50,40,40,40,30,20,15)
|
||||
high_population_requirement = 15
|
||||
property_weights = list("chaos" = 1, "valid" = 1)
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// CLOGGED VENTS //
|
||||
// //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/datum/dynamic_ruleset/event/ventclog
|
||||
name = "Clogged Vents"
|
||||
config_tag = "ventclog"
|
||||
typepath = /datum/round_event/vent_clog
|
||||
enemy_roles = list("Chemist","Medical Doctor","Chief Medical Officer")
|
||||
required_enemies = list(1,1,1,0,0,0,0,0,0,0)
|
||||
cost = 2
|
||||
weight = 4
|
||||
repeatable_weight_decrease = 3
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5) // yes, can happen on fake-extended
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("chaos" = 1, "extended" = 2)
|
||||
|
||||
/datum/dynamic_ruleset/event/ventclog/ready()
|
||||
if(mode.threat_level > 30 && mode.threat >= 5 && prob(20))
|
||||
name = "Clogged Vents: Threatening"
|
||||
cost = 5
|
||||
required_enemies = list(3,3,3,2,2,2,1,1,1,1)
|
||||
typepath = /datum/round_event/vent_clog/threatening
|
||||
else if(mode.threat_level > 15 && mode.threat > 15 && prob(30))
|
||||
name = "Clogged Vents: Catastrophic"
|
||||
cost = 15
|
||||
required_enemies = list(2,2,1,1,1,1,0,0,0,0)
|
||||
typepath = /datum/round_event/vent_clog/catastrophic
|
||||
else
|
||||
cost = 2
|
||||
name = "Clogged Vents: Normal"
|
||||
required_enemies = list(1,1,1,0,0,0,0,0,0,0)
|
||||
typepath = /datum/round_event/vent_clog
|
||||
return ..()
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// ION STORM //
|
||||
// //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/datum/dynamic_ruleset/event/ion_storm
|
||||
name = "Ion Storm"
|
||||
config_tag = "ion_storm"
|
||||
typepath = /datum/round_event/ion_storm
|
||||
enemy_roles = list("Research Director","Captain","Chief Engineer")
|
||||
required_enemies = list(1,1,0,0,0,0,0,0,0,0)
|
||||
weight = 4
|
||||
// no repeatable weight decrease. too variable to be unfun multiple times in one round
|
||||
cost = 1
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("story_potential" = 1, "extended" = 1)
|
||||
always_max_weight = TRUE
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// METEORS //
|
||||
// //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/datum/dynamic_ruleset/event/meteor_wave
|
||||
name = "Meteor Wave"
|
||||
config_tag = "meteor_wave"
|
||||
typepath = /datum/round_event/meteor_wave
|
||||
enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Captain","Cyborg")
|
||||
required_enemies = list(3,3,3,3,3,3,3,3,3,3)
|
||||
cost = 15
|
||||
weight = 3
|
||||
earliest_start = 25 MINUTES
|
||||
repeatable_weight_decrease = 2
|
||||
requirements = list(60,50,40,30,30,30,30,30,30,30)
|
||||
high_population_requirement = 30
|
||||
property_weights = list("extended" = -2)
|
||||
|
||||
/datum/dynamic_ruleset/event/meteor_wave/ready()
|
||||
if(world.time-SSticker.round_start_time > 35 MINUTES && mode.threat_level > 40 && mode.threat >= 25 && prob(30))
|
||||
name = "Meteor Wave: Threatening"
|
||||
cost = 25
|
||||
typepath = /datum/round_event/meteor_wave/threatening
|
||||
else if(world.time-SSticker.round_start_time > 45 MINUTES && mode.threat_level > 50 && mode.threat >= 40 && prob(30))
|
||||
name = "Meteor Wave: Catastrophic"
|
||||
cost = 40
|
||||
typepath = /datum/round_event/meteor_wave/catastrophic
|
||||
else
|
||||
name = "Meteor Wave: Normal"
|
||||
cost = 15
|
||||
typepath = /datum/round_event/meteor_wave
|
||||
return ..()
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// ANOMALIES //
|
||||
// //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/datum/dynamic_ruleset/event/anomaly_bluespace
|
||||
name = "Anomaly: Bluespace"
|
||||
config_tag = "anomaly_bluespace"
|
||||
typepath = /datum/round_event/anomaly/anomaly_bluespace
|
||||
enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain")
|
||||
required_enemies = list(1,1,1,0,0,0,0,0,0,0)
|
||||
weight = 2
|
||||
repeatable_weight_decrease = 1
|
||||
cost = 3
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/anomaly_flux
|
||||
name = "Anomaly: Hyper-Energetic Flux"
|
||||
config_tag = "anomaly_flux"
|
||||
typepath = /datum/round_event/anomaly/anomaly_flux
|
||||
enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain")
|
||||
required_enemies = list(1,1,1,0,0,0,0,0,0,0)
|
||||
weight = 2
|
||||
repeatable_weight_decrease = 1
|
||||
cost = 5
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 10
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/anomaly_gravitational
|
||||
name = "Anomaly: Gravitational"
|
||||
config_tag = "anomaly_gravitational"
|
||||
typepath = /datum/round_event/anomaly/anomaly_grav
|
||||
weight = 2
|
||||
repeatable_weight_decrease = 1
|
||||
cost = 3
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/anomaly_pyroclastic
|
||||
name = "Anomaly: Pyroclastic"
|
||||
config_tag = "anomaly_pyroclastic"
|
||||
typepath = /datum/round_event/anomaly/anomaly_pyro
|
||||
weight = 2
|
||||
repeatable_weight_decrease = 1
|
||||
cost = 5
|
||||
enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg")
|
||||
required_enemies = list(1,1,1,1,1,1,1,1,1,1)
|
||||
requirements = list(10,10,10,10,10,10,10,10,10,10)
|
||||
high_population_requirement = 10
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/anomaly_vortex
|
||||
name = "Anomaly: Vortex"
|
||||
config_tag = "anomaly_vortex"
|
||||
typepath = /datum/round_event/anomaly/anomaly_vortex
|
||||
weight = 2
|
||||
repeatable_weight_decrease = 1
|
||||
cost = 5
|
||||
enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg")
|
||||
required_enemies = list(1,1,1,1,1,1,1,1,1,1)
|
||||
requirements = list(10,10,10,10,10,10,10,10,10,10)
|
||||
high_population_requirement = 10
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// WOW THAT'S A LOT OF EVENTS //
|
||||
// //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/datum/dynamic_ruleset/event/brand_intelligence
|
||||
name = "Brand Intelligence"
|
||||
config_tag = "brand_intelligence"
|
||||
typepath = /datum/round_event/brand_intelligence
|
||||
weight = 1
|
||||
repeatable_weight_decrease = 1
|
||||
cost = 2
|
||||
enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg")
|
||||
required_enemies = list(1,1,1,1,0,0,0,0,0,0)
|
||||
requirements = list(10,10,10,10,10,10,10,10,10,10)
|
||||
high_population_requirement = 10
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = -1, "chaos" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/carp_migration
|
||||
name = "Carp Migration"
|
||||
config_tag = "carp_migration"
|
||||
typepath = /datum/round_event/carp_migration
|
||||
weight = 7
|
||||
repeatable_weight_decrease = 3
|
||||
cost = 4
|
||||
requirements = list(10,10,10,10,10,10,10,10,10,10)
|
||||
high_population_requirement = 10
|
||||
earliest_start = 10 MINUTES
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/communications_blackout
|
||||
name = "Communications Blackout"
|
||||
config_tag = "communications_blackout"
|
||||
typepath = /datum/round_event/communications_blackout
|
||||
cost = 4
|
||||
weight = 2
|
||||
repeatable_weight_decrease = 3
|
||||
enemy_roles = list("Chief Engineer","Station Engineer")
|
||||
required_enemies = list(1,1,1,0,0,0,0,0,0,0)
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1, "chaos" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/processor_overload
|
||||
name = "Processor Overload"
|
||||
config_tag = "processor_overload"
|
||||
typepath = /datum/round_event/processor_overload
|
||||
cost = 4
|
||||
weight = 2
|
||||
repeatable_weight_decrease = 3
|
||||
enemy_roles = list("Chief Engineer","Station Engineer")
|
||||
required_enemies = list(1,1,1,0,0,0,0,0,0,0)
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1, "chaos" = 1)
|
||||
always_max_weight = TRUE
|
||||
|
||||
/datum/dynamic_ruleset/event/space_dust
|
||||
name = "Minor Space Dust"
|
||||
config_tag = "space_dust"
|
||||
typepath = /datum/round_event/space_dust
|
||||
cost = 2
|
||||
weight = 2
|
||||
repeatable_weight_decrease = 1
|
||||
enemy_roles = list("Chief Engineer","Station Engineer")
|
||||
required_enemies = list(1,1,1,0,0,0,0,0,0,0)
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
earliest_start = 0 MINUTES
|
||||
property_weights = list("extended" = 1)
|
||||
always_max_weight = TRUE
|
||||
|
||||
/datum/dynamic_ruleset/event/major_dust
|
||||
name = "Major Space Dust"
|
||||
config_tag = "major_dust"
|
||||
typepath = /datum/round_event/meteor_wave/major_dust
|
||||
cost = 4
|
||||
weight = 2
|
||||
repeatable_weight_decrease = 1
|
||||
enemy_roles = list("Chief Engineer","Station Engineer")
|
||||
required_enemies = list(2,2,2,2,2,2,2,2,2,2)
|
||||
requirements = list(10,10,10,10,10,10,10,10,10,10)
|
||||
high_population_requirement = 10
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/electrical_storm
|
||||
name = "Electrical Storm"
|
||||
config_tag = "electrical_storm"
|
||||
typepath = /datum/round_event/electrical_storm
|
||||
cost = 1
|
||||
weight = 2
|
||||
repeatable_weight_decrease = 1
|
||||
enemy_roles = list("Chief Engineer","Station Engineer")
|
||||
required_enemies = list(1,1,1,0,0,0,0,0,0,0)
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/heart_attack
|
||||
name = "Random Heart Attack"
|
||||
config_tag = "heart_attack"
|
||||
typepath = /datum/round_event/heart_attack
|
||||
cost = 3
|
||||
weight = 2
|
||||
repeatable_weight_decrease = 1
|
||||
enemy_roles = list("Medical Doctor","Chief Medical Officer")
|
||||
required_enemies = list(2,2,2,2,2,2,2,2,2,2)
|
||||
requirements = list(101,101,101,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
always_max_weight = TRUE
|
||||
|
||||
/datum/dynamic_ruleset/event/radiation_storm
|
||||
name = "Radiation Storm"
|
||||
config_tag = "radiation_storm"
|
||||
typepath = /datum/round_event/radiation_storm
|
||||
cost = 3
|
||||
weight = 1
|
||||
enemy_roles = list("Chemist","Chief Medical Officer","Geneticist","Medical Doctor","AI","Captain")
|
||||
required_enemies = list(1,1,1,1,1,1,1,1,1,1)
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
property_weights = list("extended" = 1,"chaos" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/portal_storm_syndicate
|
||||
name = "Portal Storm"
|
||||
config_tag = "portal_storm"
|
||||
typepath = /datum/round_event/portal_storm/syndicate_shocktroop
|
||||
cost = 10
|
||||
weight = 1
|
||||
enemy_roles = list("Head of Security","Security Officer","AI","Captain","Shaft Miner")
|
||||
required_enemies = list(2,2,2,2,2,2,2,2,2,2)
|
||||
requirements = list(101,101,101,30,30,30,30,30,30,30)
|
||||
high_population_requirement = 30
|
||||
earliest_start = 30 MINUTES
|
||||
property_weights = list("teamwork" = 1,"chaos" = 1, "extended" = -1)
|
||||
|
||||
/datum/dynamic_ruleset/event/wormholes
|
||||
name = "Wormholes"
|
||||
config_tag = "wormhole"
|
||||
typepath = /datum/round_event/wormholes
|
||||
cost = 3
|
||||
weight = 4
|
||||
enemy_roles = list("AI","Medical Doctor","Station Engineer","Head of Personnel","Captain")
|
||||
required_enemies = list(2,2,2,2,2,2,2,2,2,2)
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/swarmers
|
||||
name = "Swarmers"
|
||||
config_tag = "swarmer"
|
||||
typepath = /datum/round_event/spawn_swarmer
|
||||
cost = 10
|
||||
weight = 1
|
||||
earliest_start = 30 MINUTES
|
||||
enemy_roles = list("AI","Security Officer","Head of Security","Captain","Station Engineer","Atmos Technician","Chief Engineer")
|
||||
required_enemies = list(4,4,4,4,3,3,2,2,1,1)
|
||||
requirements = list(101,101,101,101,101,101,101,101,101,101)
|
||||
high_population_requirement = 5
|
||||
property_weights = list("extended" = -2)
|
||||
|
||||
/datum/dynamic_ruleset/event/sentient_disease
|
||||
name = "Sentient Disease"
|
||||
config_tag = "sentient_disease"
|
||||
typepath = /datum/round_event/ghost_role/sentient_disease
|
||||
enemy_roles = list("Virologist","Chief Medical Officer","Captain","Chemist")
|
||||
required_enemies = list(2,1,1,1,0,0,0,0,0,0)
|
||||
required_candidates = 1
|
||||
weight = 4
|
||||
cost = 5
|
||||
requirements = list(30,30,20,20,15,10,10,10,10,5) // yes, it can even happen in "extended"!
|
||||
property_weights = list("story_potential" = 1, "extended" = 1, "valid" = -2)
|
||||
high_population_requirement = 5
|
||||
|
||||
/datum/dynamic_ruleset/event/revenant
|
||||
name = "Revenant"
|
||||
config_tag = "revenant"
|
||||
typepath = /datum/round_event/ghost_role/revenant
|
||||
enemy_roles = list("Chief Engineer","Station Engineer","Captain","Chaplain","AI")
|
||||
required_enemies = list(2,1,1,1,0,0,0,0,0,0)
|
||||
required_candidates = 1
|
||||
weight = 4
|
||||
cost = 5
|
||||
requirements = list(30,30,30,30,20,15,15,15,15,15)
|
||||
high_population_requirement = 15
|
||||
property_weights = list("story_potential" = -2, "extended" = -1)
|
||||
@@ -39,9 +39,6 @@ Property weights are added to the config weight of the ruleset. They are:
|
||||
var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_first_midround_delay_min + GLOB.dynamic_first_midround_delay_max)
|
||||
mode.midround_injection_cooldown = round(clamp(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_first_midround_delay_min, GLOB.dynamic_first_midround_delay_max)) + world.time
|
||||
|
||||
var/event_injection_cooldown_middle = 0.5*(GLOB.dynamic_event_delay_max + GLOB.dynamic_event_delay_min)
|
||||
mode.event_injection_cooldown = (round(clamp(EXP_DISTRIBUTION(event_injection_cooldown_middle), GLOB.dynamic_event_delay_min, GLOB.dynamic_event_delay_max)) + world.time)
|
||||
|
||||
/datum/dynamic_storyteller/proc/calculate_threat()
|
||||
var/threat = 0
|
||||
for(var/datum/antagonist/A in GLOB.antagonists)
|
||||
@@ -99,10 +96,6 @@ Property weights are added to the config weight of the ruleset. They are:
|
||||
var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_midround_delay_max + GLOB.dynamic_midround_delay_min)
|
||||
return round(clamp(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_midround_delay_min, GLOB.dynamic_midround_delay_max))
|
||||
|
||||
/datum/dynamic_storyteller/proc/get_event_cooldown()
|
||||
var/event_injection_cooldown_middle = 0.5*(GLOB.dynamic_event_delay_max + GLOB.dynamic_event_delay_min)
|
||||
return round(clamp(EXP_DISTRIBUTION(event_injection_cooldown_middle), GLOB.dynamic_event_delay_min, GLOB.dynamic_event_delay_max))
|
||||
|
||||
/datum/dynamic_storyteller/proc/get_latejoin_cooldown()
|
||||
var/latejoin_injection_cooldown_middle = 0.5*(GLOB.dynamic_latejoin_delay_max + GLOB.dynamic_latejoin_delay_min)
|
||||
return round(clamp(EXP_DISTRIBUTION(latejoin_injection_cooldown_middle), GLOB.dynamic_latejoin_delay_min, GLOB.dynamic_latejoin_delay_max))
|
||||
@@ -195,20 +188,6 @@ Property weights are added to the config weight of the ruleset. They are:
|
||||
drafted_rules[rule] = calced_weight
|
||||
return drafted_rules
|
||||
|
||||
/datum/dynamic_storyteller/proc/event_draft()
|
||||
var/list/drafted_rules = list()
|
||||
for(var/datum/dynamic_ruleset/event/rule in mode.events)
|
||||
if(rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level) && (mode.threat_level + 20 - mode.threat) >= rule.cost && rule.ready())
|
||||
var/property_weight = 0
|
||||
for(var/property in property_weights)
|
||||
if(property in rule.property_weights)
|
||||
property_weight += rule.property_weights[property] * property_weights[property]
|
||||
var/calced_weight = (rule.get_weight() + property_weight) * rule.weight_mult
|
||||
if(calced_weight > 0)
|
||||
drafted_rules[rule] = calced_weight
|
||||
return drafted_rules
|
||||
|
||||
|
||||
/datum/dynamic_storyteller/chaotic
|
||||
name = "Chaotic"
|
||||
config_tag = "chaotic"
|
||||
@@ -271,9 +250,6 @@ Property weights are added to the config weight of the ruleset. They are:
|
||||
/datum/dynamic_storyteller/random/get_midround_cooldown()
|
||||
return rand(GLOB.dynamic_midround_delay_min/2, GLOB.dynamic_midround_delay_max*2)
|
||||
|
||||
/datum/dynamic_storyteller/random/get_event_cooldown()
|
||||
return rand(GLOB.dynamic_event_delay_min/2, GLOB.dynamic_event_delay_max*2)
|
||||
|
||||
/datum/dynamic_storyteller/random/get_latejoin_cooldown()
|
||||
return rand(GLOB.dynamic_latejoin_delay_min/2, GLOB.dynamic_latejoin_delay_max*2)
|
||||
|
||||
@@ -319,13 +295,6 @@ Property weights are added to the config weight of the ruleset. They are:
|
||||
drafted_rules[rule] = 1
|
||||
return drafted_rules
|
||||
|
||||
/datum/dynamic_storyteller/random/event_draft()
|
||||
var/list/drafted_rules = list()
|
||||
for(var/datum/dynamic_ruleset/event/rule in mode.events)
|
||||
if(rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level) && rule.ready())
|
||||
drafted_rules[rule] = 1
|
||||
return drafted_rules
|
||||
|
||||
/datum/dynamic_storyteller/story
|
||||
name = "Story"
|
||||
config_tag = "story"
|
||||
@@ -365,7 +334,7 @@ Property weights are added to the config weight of the ruleset. They are:
|
||||
/datum/dynamic_storyteller/no_antag
|
||||
name = "Extended"
|
||||
config_tag = "semiextended"
|
||||
desc = "No standard antags. Threatening events may still spawn."
|
||||
desc = "No standard antags."
|
||||
curve_centre = -5
|
||||
curve_width = 0.5
|
||||
flags = NO_ASSASSIN | FORCE_IF_WON
|
||||
@@ -377,15 +346,3 @@ Property weights are added to the config weight of the ruleset. They are:
|
||||
|
||||
/datum/dynamic_storyteller/no_antag/get_injection_chance(dry_run)
|
||||
return 0
|
||||
|
||||
/datum/dynamic_storyteller/extended
|
||||
name = "Super Extended"
|
||||
config_tag = "extended"
|
||||
desc = "No antags. No dangerous events."
|
||||
curve_centre = -20
|
||||
weight = 0
|
||||
curve_width = 0.5
|
||||
|
||||
/datum/dynamic_storyteller/extended/on_start()
|
||||
..()
|
||||
GLOB.dynamic_forced_extended = TRUE
|
||||
|
||||
@@ -112,7 +112,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
var/turf/T = get_turf(loc)
|
||||
ram_turf(T)
|
||||
|
||||
if(prob(10) && !isspaceturf(T))//randomly takes a 'hit' from ramming
|
||||
if(prob(10) && !isspaceturf(T) && !istype(T, /turf/closed/mineral) && !istype(T, /turf/open/floor/plating/asteroid))//randomly takes a 'hit' from ramming
|
||||
get_hit()
|
||||
|
||||
/obj/effect/meteor/Destroy()
|
||||
@@ -136,7 +136,8 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
if(A)
|
||||
ram_turf(get_turf(A))
|
||||
playsound(src.loc, meteorsound, 40, 1)
|
||||
get_hit()
|
||||
if(!istype(A, /turf/closed/mineral) && !istype(A, /turf/open/floor/plating/asteroid))
|
||||
get_hit()
|
||||
|
||||
/obj/effect/meteor/proc/ram_turf(turf/T)
|
||||
//first bust whatever is in the turf
|
||||
|
||||
@@ -551,4 +551,4 @@ Class Procs:
|
||||
AM.pixel_y = -8 + (round( . / 3)*8)
|
||||
|
||||
/obj/machinery/rust_heretic_act()
|
||||
take_damage(500, BRUTE, "melee", 1)
|
||||
take_damage(500, BRUTE, "melee", 1)
|
||||
|
||||
@@ -178,9 +178,12 @@
|
||||
table[y1][x1] += 10
|
||||
if(href_list["same_board"]) //Reset the board... kinda
|
||||
if(game_status != MINESWEEPER_GAME_PLAYING)
|
||||
mine_sound = TRUE
|
||||
game_status = MINESWEEPER_GAME_PLAYING
|
||||
if(table[y1][x1] >= 10) //If revealed, become unrevealed!
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
if(mine_sound)
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
mine_sound = FALSE
|
||||
table[y1][x1] -= 10
|
||||
if(table[y1][x1] > 10 && !reset_board)
|
||||
safe_squares_revealed += 1
|
||||
|
||||
@@ -38,3 +38,14 @@
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
drive()
|
||||
|
||||
/obj/machinery/mass_driver/pressure_plate
|
||||
name = "pressure plated mass driver"
|
||||
var/drive_delay = 10
|
||||
|
||||
/obj/machinery/mass_driver/pressure_plate/Crossed(atom/movable/O)
|
||||
. = ..()
|
||||
if(isliving(O))
|
||||
var/mob/living/L = O
|
||||
to_chat(L, "<span class='warning'>You feel something click beneath you!</span>")
|
||||
addtimer(CALLBACK(src, .proc/drive), drive_delay)
|
||||
@@ -17,11 +17,15 @@
|
||||
var/countdown_colour
|
||||
var/obj/effect/countdown/anomaly/countdown
|
||||
|
||||
/obj/effect/anomaly/Initialize(mapload, new_lifespan)
|
||||
/// chance we drop a core when neutralized
|
||||
var/core_drop_chance = 100
|
||||
|
||||
/obj/effect/anomaly/Initialize(mapload, new_lifespan, core_drop_chance = 100)
|
||||
. = ..()
|
||||
GLOB.poi_list |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
impact_area = get_area(src)
|
||||
src.core_drop_chance = core_drop_chance
|
||||
|
||||
if (!impact_area)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
@@ -54,6 +58,8 @@
|
||||
GLOB.poi_list.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
qdel(countdown)
|
||||
if(aSignal)
|
||||
QDEL_NULL(aSignal)
|
||||
return ..()
|
||||
|
||||
/obj/effect/anomaly/proc/anomalyEffect()
|
||||
@@ -70,12 +76,12 @@
|
||||
/obj/effect/anomaly/proc/anomalyNeutralize()
|
||||
new /obj/effect/particle_effect/smoke/bad(loc)
|
||||
|
||||
for(var/atom/movable/O in src)
|
||||
O.forceMove(drop_location())
|
||||
if(prob(core_drop_chance))
|
||||
aSignal.forceMove(drop_location())
|
||||
aSignal = null
|
||||
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/effect/anomaly/attackby(obj/item/I, mob/user, params)
|
||||
if(I.tool_behaviour == TOOL_ANALYZER) //revert if runtimed
|
||||
to_chat(user, "<span class='notice'>Analyzing... [src]'s unstable field is fluctuating along frequency [format_frequency(aSignal.frequency)], code [aSignal.code].</span>")
|
||||
|
||||
@@ -46,4 +46,5 @@
|
||||
var/turf/T = loc
|
||||
if(!istype(T)) //you know this will happen somehow
|
||||
CRASH("Turf decal initialized in an object/nullspace")
|
||||
T.AddElement(/datum/element/decal, icon, icon_state, dir, CLEAN_GOD, color, null, null, alpha)
|
||||
var/turn_dir = 180 - dir2angle(T.dir) //Turning a dir by 0 results in a roulette of random dirs.
|
||||
T.AddElement(/datum/element/decal, icon, icon_state, turn_dir ? turn(dir, turn_dir) : dir, CLEAN_GOD, color, null, null, alpha)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
var/ignores_timeout = FALSE
|
||||
var/response_timer_id = null
|
||||
var/approval_time = 600
|
||||
var/allow_unicode = FALSE
|
||||
|
||||
var/static/regex/standard_station_regex
|
||||
|
||||
@@ -48,6 +49,9 @@
|
||||
|
||||
if(!new_name)
|
||||
return
|
||||
if(!allow_unicode && (length(new_name) != length_char(new_name)))
|
||||
to_chat(user, "Unicode is not allowed. Adminhelp if you want to use it so badly.")
|
||||
return
|
||||
log_game("[key_name(user)] has proposed to name the station as \
|
||||
[new_name]")
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@
|
||||
|
||||
/obj/item/circuitboard/machine/thermomachine/examine()
|
||||
. = ..()
|
||||
. += "<span class='notice'>It is set to layer [pipe_layer].</span>"
|
||||
. += "<span class='notice'>It is set to layer [pipe_layer]. Use a Multitool on the circuit to change this.</span>"
|
||||
|
||||
/obj/item/circuitboard/machine/thermomachine/heater
|
||||
name = "Heater (Machine Board)"
|
||||
@@ -1146,3 +1146,8 @@
|
||||
build_path = /obj/machinery/atmospherics/components/unary/shuttle/heater
|
||||
req_components = list(/obj/item/stock_parts/micro_laser = 2,
|
||||
/obj/item/stock_parts/matter_bin = 1)
|
||||
|
||||
/obj/item/circuitboard/machine/explosive_compressor
|
||||
name = "Explosive Compressor (Machine Board)"
|
||||
build_path = /obj/machinery/research/explosive_compressor
|
||||
req_components = list(/obj/item/stock_parts/matter_bin = 3)
|
||||
|
||||
@@ -394,8 +394,6 @@
|
||||
to_chat(user, "<span class='warning'>[src] are recharging!</span>")
|
||||
return
|
||||
|
||||
user.stop_pulling() //User has hands full, and we don't care about anyone else pulling on it, their problem. CLEAR!!
|
||||
|
||||
if(user.a_intent == INTENT_DISARM)
|
||||
do_disarm(M, user)
|
||||
return
|
||||
@@ -447,8 +445,7 @@
|
||||
if(do_after(user, isnull(defib?.disarm_shock_time)? disarm_shock_time : defib.disarm_shock_time, target = M))
|
||||
M.visible_message("<span class='danger'>[user] zaps [M] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] zaps [M] with [src]!</span>")
|
||||
M.adjustStaminaLoss(50)
|
||||
M.DefaultCombatKnockdown(100)
|
||||
M.DefaultCombatKnockdown(140)
|
||||
M.updatehealth() //forces health update before next life tick
|
||||
playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
M.emote("gasp")
|
||||
|
||||
@@ -113,8 +113,7 @@
|
||||
if (loc != user)
|
||||
return ..()
|
||||
if(SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED))
|
||||
ui_interact(user)
|
||||
return
|
||||
INVOKE_ASYNC(src, /datum.proc/ui_interact, user)
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/attack_self(mob/user)
|
||||
if(loc == user)
|
||||
|
||||
@@ -289,3 +289,9 @@
|
||||
. = TRUE
|
||||
|
||||
update_icon()
|
||||
|
||||
/**
|
||||
* Returns if this is ready to be detonated. Checks if both tanks are in place.
|
||||
*/
|
||||
/obj/item/transfer_valve/proc/ready()
|
||||
return tank_one && tank_two
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
wound_bonus = -110
|
||||
bare_wound_bonus = 20
|
||||
block_parry_data = /datum/block_parry_data/dual_esword
|
||||
block_chance = 60
|
||||
var/hacked = FALSE
|
||||
/// Can this reflect all energy projectiles?
|
||||
var/can_reflect = TRUE
|
||||
@@ -38,7 +39,8 @@
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
var/slowdown_wielded = 0
|
||||
|
||||
/datum/block_parry_data/dual_esword
|
||||
/datum/block_parry_data/dual_esword // please run at the man going apeshit with his funny doublesword
|
||||
can_block_directions = BLOCK_DIR_NORTH | BLOCK_DIR_NORTHEAST | BLOCK_DIR_NORTHWEST | BLOCK_DIR_WEST | BLOCK_DIR_EAST
|
||||
block_damage_absorption = 2
|
||||
block_damage_multiplier = 0.15
|
||||
block_damage_multiplier_override = list(
|
||||
@@ -50,10 +52,10 @@
|
||||
block_lock_sprinting = TRUE
|
||||
// no attacking while blocking
|
||||
block_lock_attacking = TRUE
|
||||
block_projectile_mitigation = 75
|
||||
block_projectile_mitigation = 85
|
||||
// more efficient vs projectiles
|
||||
block_stamina_efficiency_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 4
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 6
|
||||
)
|
||||
|
||||
parry_time_windup = 0
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
/obj/item/choice_beacon/box/plushie/generate_display_names()
|
||||
var/list/plushie_list = list()
|
||||
//plushie set 1: just subtypes of /obj/item/toy/plush
|
||||
var/list/plushies_set_one = subtypesof(/obj/item/toy/plush) - list(/obj/item/toy/plush/narplush, /obj/item/toy/plush/awakenedplushie, /obj/item/toy/plush/random_snowflake, /obj/item/toy/plush/random) //don't allow these special ones (you can still get narplush/hugbox)
|
||||
var/list/plushies_set_one = subtypesof(/obj/item/toy/plush) - list(/obj/item/toy/plush/narplush, /obj/item/toy/plush/awakenedplushie, /obj/item/toy/plush/random_snowflake, /obj/item/toy/plush/plushling, /obj/item/toy/plush/random) //don't allow these special ones (you can still get narplush/hugbox)
|
||||
for(var/V in plushies_set_one)
|
||||
var/atom/A = V
|
||||
plushie_list[initial(A.name)] = A
|
||||
@@ -272,4 +272,3 @@
|
||||
icon_state = "skub"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
attack_verb = list("skubbed")
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
return
|
||||
log_game("[key_name(user)] activated a hidden grenade in [src].")
|
||||
grenade.preprime(user, msg = FALSE, volume = 10)
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"plushpet", /datum/mood_event/plushpet)
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"plushpet", /datum/mood_event/plushpet)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You try to pet [src], but it has no stuffing. Aww...</span>")
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"plush_nostuffing", /datum/mood_event/plush_nostuffing)
|
||||
@@ -688,18 +688,6 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
|
||||
icon_state = "scrubpuppy"
|
||||
item_state = "scrubpuppy"
|
||||
|
||||
/obj/item/toy/plush/borgplushie/meddrake
|
||||
name = "MediDrake Plushie"
|
||||
desc = "An adorable stuffed toy of a Medidrake."
|
||||
icon_state = "meddrake"
|
||||
item_state = "meddrake"
|
||||
|
||||
/obj/item/toy/plush/borgplushie/secdrake
|
||||
name = "SecDrake Plushie"
|
||||
desc = "An adorable stuffed toy of a Secdrake."
|
||||
icon_state = "secdrake"
|
||||
item_state = "secdrake"
|
||||
|
||||
/obj/item/toy/plush/aiplush
|
||||
name = "AI plushie"
|
||||
desc = "A little stuffed toy AI core... it appears to be malfunctioning."
|
||||
@@ -766,8 +754,8 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
|
||||
attack_verb = list("headbutt", "scritched", "bit")
|
||||
squeak_override = list('modular_citadel/sound/voice/nya.ogg' = 1)
|
||||
can_random_spawn = FALSE
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/toy/plush/hairball
|
||||
name = "Hairball"
|
||||
desc = "A bundle of undigested fibers and scales. Yuck."
|
||||
@@ -777,3 +765,78 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
|
||||
squeak_override = list('sound/misc/splort.ogg'=1)
|
||||
attack_verb = list("sploshed", "splorted", "slushed")
|
||||
can_random_spawn = FALSE
|
||||
|
||||
/obj/item/toy/plush/plushling
|
||||
name = "peculiar plushie"
|
||||
desc = "An adorable stuffed toy- wait, did it just move?"
|
||||
can_random_spawn = FALSE
|
||||
var/absorb_cooldown = 100 //ticks cooldown between absorbs
|
||||
var/next_absorb = 0 //When can it absorb another plushie
|
||||
var/check_interval = 20
|
||||
var/next_check = 0
|
||||
|
||||
//Overrides parent proc
|
||||
/obj/item/toy/plush/plushling/attack_self(mob/user)
|
||||
if(!user) //hmmmmm
|
||||
return
|
||||
to_chat(user, "<span class='warning'>You try to pet the plushie, but recoil as it bites your hand instead! OW!</span>")
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"plush_bite", /datum/mood_event/plush_bite)
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!H)
|
||||
return //Type safety.
|
||||
H.apply_damage(5, BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
|
||||
addtimer(CALLBACK(H, /mob/living/carbon/human.proc/dropItemToGround, src, TRUE), 1)
|
||||
|
||||
/obj/item/toy/plush/plushling/New()
|
||||
var/initial_state = pick("plushie_lizard", "plushie_snake", "plushie_slime", "fox")
|
||||
icon_state = initial_state
|
||||
item_state = initial_state
|
||||
START_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/toy/plush/plushling/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/toy/plush/plushling/process()
|
||||
if(world.time < next_absorb || world.time < next_check)
|
||||
return
|
||||
next_check = world.time + check_interval
|
||||
var/obj/item/toy/plush/target
|
||||
for(var/obj/item/toy/plush/possible_target in loc) //First, it tries to get anything in its same location, be it a tile or a backpack
|
||||
if(possible_target == src || istype(possible_target, /obj/item/toy/plush/plushling))
|
||||
continue
|
||||
target = possible_target
|
||||
break
|
||||
if(!target)
|
||||
if(!isturf(loc))
|
||||
return
|
||||
for(var/obj/item/toy/plush/P in oview(1, src)) //If that doesn't work, it hunts for plushies adjacent to its own tile
|
||||
if(istype(P, /obj/item/toy/plush/plushling)) //These do not hunt their own kind
|
||||
continue
|
||||
src.throw_at(P, 1, 2)
|
||||
visible_message("<span class='danger'>[src] leaps at [P]!</span>")
|
||||
break
|
||||
return
|
||||
if(istype(target, /obj/item/toy/plush/plushling)) //These do not consume their own.
|
||||
return
|
||||
next_absorb = world.time + absorb_cooldown
|
||||
plushie_absorb(target)
|
||||
|
||||
/obj/item/toy/plush/plushling/proc/plushie_absorb(obj/item/toy/plush/victim)
|
||||
if(!victim)
|
||||
return
|
||||
visible_message("<span class='warning'>[src] gruesomely mutilliates [victim], leaving nothing more than dust!</span>")
|
||||
name = victim.name
|
||||
desc = victim.desc + " Wait, did it just move..?"
|
||||
icon_state = victim.icon_state
|
||||
item_state = victim.item_state
|
||||
squeak_override = victim.squeak_override
|
||||
attack_verb = victim.attack_verb
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(victim))
|
||||
qdel(victim)
|
||||
|
||||
/obj/item/toy/plush/plushling/love(obj/item/toy/plush/Kisser, mob/living/user) //You shouldn't have come here, poor plush.
|
||||
if(!Kisser)
|
||||
return
|
||||
plushie_absorb(Kisser)
|
||||
|
||||
@@ -269,8 +269,8 @@
|
||||
to_chat(user, "<span class='notice'>[M] is at full health.</span>")
|
||||
return FALSE
|
||||
user.visible_message("<span class='green'>[user] applies \the [src] on [M].</span>", "<span class='green'>You apply \the [src] on [M].</span>")
|
||||
return heal_carbon(M, user, heal_brute, heal_burn)
|
||||
|
||||
M.heal_bodypart_damage(heal_brute)
|
||||
return TRUE
|
||||
to_chat(user, "<span class='warning'>You can't heal [M] with \the [src]!</span>")
|
||||
|
||||
/obj/item/stack/medical/ointment
|
||||
|
||||
@@ -117,6 +117,7 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \
|
||||
new/datum/stack_recipe("Captain Statue", /obj/structure/statue/diamond/captain, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("AI Hologram Statue", /obj/structure/statue/diamond/ai1, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("AI Core Statue", /obj/structure/statue/diamond/ai2, 5, one_per_turf = 1, on_floor = 1), \
|
||||
// new/datum/stack_recipe("diamond brick", /obj/item/ingot/diamond, 6, time = 100), \ not yet
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/diamond/get_main_recipes()
|
||||
@@ -145,6 +146,7 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \
|
||||
new/datum/stack_recipe("uranium tile", /obj/item/stack/tile/mineral/uranium, 1, 4, 20), \
|
||||
new/datum/stack_recipe("Nuke Statue", /obj/structure/statue/uranium/nuke, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Engineer Statue", /obj/structure/statue/uranium/eng, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("uranium ingot", /obj/item/ingot/uranium, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/uranium/get_main_recipes()
|
||||
@@ -177,6 +179,7 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \
|
||||
new/datum/stack_recipe("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("plasma tile", /obj/item/stack/tile/mineral/plasma, 1, 4, 20), \
|
||||
new/datum/stack_recipe("Scientist Statue", /obj/structure/statue/plasma/scientist, 5, one_per_turf = 1, on_floor = 1), \
|
||||
// new/datum/stack_recipe("plasma ingot", /obj/item/ingot/plasma, 6, time = 100), \ no
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/plasma/get_main_recipes()
|
||||
@@ -221,6 +224,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \
|
||||
new/datum/stack_recipe("RD Statue", /obj/structure/statue/gold/rd, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Simple Crown", /obj/item/clothing/head/crown, 5), \
|
||||
new/datum/stack_recipe("CMO Statue", /obj/structure/statue/gold/cmo, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("gold ingot", /obj/item/ingot/gold, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/gold/get_main_recipes()
|
||||
@@ -252,6 +256,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \
|
||||
new/datum/stack_recipe("Sec Officer Statue", /obj/structure/statue/silver/sec, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Sec Borg Statue", /obj/structure/statue/silver/secborg, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Med Borg Statue", /obj/structure/statue/silver/medborg, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("silver ingot", /obj/item/ingot/silver, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/silver/get_main_recipes()
|
||||
@@ -278,6 +283,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \
|
||||
GLOBAL_LIST_INIT(bananium_recipes, list ( \
|
||||
new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \
|
||||
new/datum/stack_recipe("Clown Statue", /obj/structure/statue/bananium/clown, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("hilarious ingot", /obj/item/ingot/bananium, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/bananium/get_main_recipes()
|
||||
@@ -306,6 +312,7 @@ GLOBAL_LIST_INIT(bananium_recipes, list ( \
|
||||
|
||||
GLOBAL_LIST_INIT(titanium_recipes, list ( \
|
||||
new/datum/stack_recipe("titanium tile", /obj/item/stack/tile/mineral/titanium, 1, 4, 20), \
|
||||
new/datum/stack_recipe("titanic ingot", /obj/item/ingot/titanium, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/titanium/get_main_recipes()
|
||||
@@ -353,6 +360,7 @@ GLOBAL_LIST_INIT(plastitanium_recipes, list ( \
|
||||
*/
|
||||
GLOBAL_LIST_INIT(adamantine_recipes, list(
|
||||
new /datum/stack_recipe("incomplete servant golem shell", /obj/item/golem_shell/servant, req_amount=1, res_amount=1),
|
||||
new/datum/stack_recipe("adamant ingot", /obj/item/ingot/adamantine, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/adamantine
|
||||
|
||||
@@ -121,6 +121,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
|
||||
new/datum/stack_recipe("iron door", /obj/structure/mineral_door/iron, 20, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("pestle", /obj/item/pestle, 1, time = 50), \
|
||||
new/datum/stack_recipe("floodlight frame", /obj/structure/floodlight_frame, 5, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("iron ingot", /obj/item/ingot/iron, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/metal
|
||||
@@ -556,6 +557,9 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
|
||||
new/datum/stack_recipe("forge", /obj/structure/destructible/cult/forge, 3, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("archives", /obj/structure/destructible/cult/tome, 3, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("altar", /obj/structure/destructible/cult/talisman, 3, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("anvil", /obj/structure/anvil/obtainable/narsie, 4, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("runic ingot", /obj/item/ingot/cult, 2, time = 100), \
|
||||
new/datum/stack_recipe("rune smith's hammer", /obj/item/melee/smith/hammer/narsie, 6), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/runed_metal
|
||||
@@ -618,6 +622,8 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
|
||||
new/datum/stack_recipe("brass bar stool", /obj/structure/chair/stool/bar/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("brass stool", /obj/structure/chair/stool/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("brass anvil", /obj/structure/anvil/obtainable/ratvar, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("brass furnace", /obj/structure/furnace/infinite/ratvar, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
null, \
|
||||
new/datum/stack_recipe("sender - pressure sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("sender - mech sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor/mech, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
@@ -629,6 +635,8 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
|
||||
new/datum/stack_recipe("receiver - power nullifier", /obj/structure/destructible/clockwork/trap/power_nullifier, 5, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \
|
||||
null, \
|
||||
new/datum/stack_recipe("brass flask", /obj/item/reagent_containers/food/drinks/bottle/holyoil/empty), \
|
||||
new/datum/stack_recipe("brass smith's hammer", /obj/item/melee/smith/hammer/ratvar, 6), \
|
||||
new/datum/stack_recipe("brass ingot", /obj/item/ingot/ratvar, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/tile/brass
|
||||
@@ -684,7 +692,10 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
|
||||
new/datum/stack_recipe("bronze chair", /obj/structure/chair/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("bronze bar stool", /obj/structure/chair/stool/bar/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("bronze stool", /obj/structure/chair/stool/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new /datum/stack_recipe("bronze floor tiles", /obj/item/stack/tile/bronze, 1, 4, 20), \
|
||||
new/datum/stack_recipe("bronze anvil",/obj/structure/anvil/obtainable/bronze, 20, time = 110, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
null,
|
||||
new/datum/stack_recipe("bronze ingot", /obj/item/ingot/bronze, 6, time = 100), \
|
||||
new/datum/stack_recipe("bronze floor tiles", /obj/item/stack/tile/bronze, 1, 4, 20), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/bronze
|
||||
|
||||
@@ -815,3 +815,18 @@
|
||||
attack_verb = list("bashed", "slashes", "prods", "pokes")
|
||||
fitting_swords = list(/obj/item/melee/rapier)
|
||||
starting_sword = /obj/item/melee/rapier
|
||||
|
||||
/obj/item/storage/belt/sabre/twin
|
||||
name = "twin sheath"
|
||||
desc = "Two sheaths. One is capable of holding a katana (or bokken) and the other a wakizashi. You could put two wakizashis in if you really wanted to. Now you can really roleplay as a samurai."
|
||||
icon_state = "twinsheath"
|
||||
item_state = "quiver" //this'll do.
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
fitting_swords = list(/obj/item/melee/smith/wakizashi, /obj/item/melee/smith/twohand/katana, /obj/item/melee/bokken)
|
||||
starting_sword = null
|
||||
|
||||
/obj/item/storage/belt/sabre/twin/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 2
|
||||
STR.max_w_class = WEIGHT_CLASS_BULKY + WEIGHT_CLASS_NORMAL //katana and waki.
|
||||
|
||||
@@ -237,6 +237,11 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
resistance_flags = FIRE_PROOF
|
||||
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
|
||||
|
||||
/obj/item/katana/lavaland
|
||||
desc = "Woefully underpowered in Lavaland."
|
||||
block_chance = 30
|
||||
force = 25 //Like a fireaxe but one handed and can block!
|
||||
|
||||
/obj/item/katana/cursed
|
||||
slot_flags = null
|
||||
|
||||
|
||||
@@ -204,9 +204,6 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
/obj/proc/acid_processing()
|
||||
. = 1
|
||||
if(!(resistance_flags & ACID_PROOF))
|
||||
for(var/armour_value in armor)
|
||||
if(armour_value != "acid" && armour_value != "fire")
|
||||
armor = armor.modifyAllRatings(0 - round(sqrt(acid_level)*0.1))
|
||||
if(prob(33))
|
||||
playsound(loc, 'sound/items/welder.ogg', 150, 1)
|
||||
take_damage(min(1 + round(sqrt(acid_level)*0.3), 300), BURN, "acid", 0)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
max_mobs = 3
|
||||
max_integrity = 250
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril)
|
||||
var/loot_type = /obj/structure/closet/crate/necropolis/tendril/all
|
||||
|
||||
move_resist=INFINITY // just killing it tears a massive hole in the ground, let's not move it
|
||||
anchored = TRUE
|
||||
@@ -41,7 +42,7 @@ GLOBAL_LIST_INIT(tendrils, list())
|
||||
|
||||
/obj/structure/spawner/lavaland/deconstruct(disassembled)
|
||||
new /obj/effect/collapse(loc)
|
||||
new /obj/structure/closet/crate/necropolis/tendril(loc)
|
||||
new loot_type(loc)
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
var/icon_regular_floor = "floor" //used to remember what icon the tile should have by default
|
||||
var/icon_plating = "plating"
|
||||
thermal_conductivity = 0.040
|
||||
thermal_conductivity = 0.004
|
||||
heat_capacity = 10000
|
||||
intact = 1
|
||||
var/broken = 0
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
name = "reinforced floor"
|
||||
desc = "Extremely sturdy."
|
||||
icon_state = "engine"
|
||||
thermal_conductivity = 0.025
|
||||
thermal_conductivity = 0.0025
|
||||
heat_capacity = INFINITY
|
||||
floor_tile = /obj/item/stack/rods
|
||||
footstep = FOOTSTEP_PLATING
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
icon = 'icons/turf/walls/plasma_wall.dmi'
|
||||
icon_state = "plasma"
|
||||
sheet_type = /obj/item/stack/sheet/mineral/plasma
|
||||
thermal_conductivity = 0.04
|
||||
thermal_conductivity = 0.004
|
||||
canSmoothWith = list(/turf/closed/wall/mineral/plasma, /obj/structure/falsewall/plasma)
|
||||
|
||||
/turf/closed/wall/mineral/plasma/attackby(obj/item/W, mob/user, params)
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
if(prob(hardness))
|
||||
playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE)
|
||||
user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
|
||||
hulk_recoil(arm, user)
|
||||
//hulk_recoil(arm, user) // citadel edit - no, hulks are already subject to stamina combat
|
||||
dismantle_wall(1)
|
||||
|
||||
else
|
||||
|
||||
@@ -11,6 +11,11 @@ GLOBAL_LIST(topic_status_cache)
|
||||
/world/New()
|
||||
if (fexists(EXTOOLS))
|
||||
call(EXTOOLS, "maptick_initialize")()
|
||||
#ifdef EXTOOLS_LOGGING
|
||||
call(EXTOOLS, "init_logging")()
|
||||
else
|
||||
CRASH("[EXTOOLS] does not exist!")
|
||||
#endif
|
||||
enable_debugger()
|
||||
#ifdef REFERENCE_TRACKING
|
||||
enable_reference_tracking()
|
||||
@@ -274,6 +279,7 @@ GLOBAL_LIST(topic_status_cache)
|
||||
GM.__gasmixture_unregister()
|
||||
num_deleted++
|
||||
log_world("Deallocated [num_deleted] gas mixtures")
|
||||
shutdown_logging() // makes sure the thread is closed before end, else we terminate
|
||||
..()
|
||||
|
||||
/world/proc/update_status()
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
if(owner.current.gender == MALE)
|
||||
if(prob(10)) // Gender override
|
||||
bloodsucker_reputation = pick("King of the Damned", "Blood King", "Emperor of Blades", "Sinlord", "God-King")
|
||||
else
|
||||
else if(owner.current.gender == FEMALE)
|
||||
if(prob(10)) // Gender override
|
||||
bloodsucker_reputation = pick("Queen of the Damned", "Blood Queen", "Empress of Blades", "Sinlady", "God-Queen")
|
||||
|
||||
@@ -341,10 +341,12 @@
|
||||
|
||||
//This handles the application of antag huds/special abilities
|
||||
/datum/antagonist/bloodsucker/apply_innate_effects(mob/living/mob_override)
|
||||
RegisterSignal(owner.current,COMSIG_LIVING_BIOLOGICAL_LIFE,.proc/LifeTick)
|
||||
return
|
||||
|
||||
//This handles the removal of antag huds/special abilities
|
||||
/datum/antagonist/bloodsucker/remove_innate_effects(mob/living/mob_override)
|
||||
UnregisterSignal(owner.current,COMSIG_LIVING_BIOLOGICAL_LIFE)
|
||||
return
|
||||
|
||||
//Assign default team and creates one for one of a kind team antagonists
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
/datum/action/bloodsucker/targeted/brawn
|
||||
name = "Brawn"//"Cellular Emporium"
|
||||
name = "Brawn"
|
||||
desc = "Snap restraints with ease, or deal terrible damage with your bare hands."
|
||||
button_icon_state = "power_strength"
|
||||
bloodcost = 10
|
||||
@@ -107,8 +107,6 @@
|
||||
if(user_C.handcuffed)
|
||||
var/obj/O = user_C.get_item_by_slot(SLOT_HANDCUFFED)
|
||||
if(istype(O))
|
||||
//user_C.visible_message("<span class='warning'>[user_C] attempts to remove [O]!</span>", \
|
||||
// "<span class='warning'>You snap [O] like it's nothing!</span>")
|
||||
user_C.clear_cuffs(O,TRUE)
|
||||
playsound(get_turf(usr), 'sound/effects/grillehit.ogg', 80, 1, -1)
|
||||
return TRUE
|
||||
@@ -128,8 +126,6 @@
|
||||
if(user_C.legcuffed)
|
||||
var/obj/O = user_C.get_item_by_slot(SLOT_LEGCUFFED)
|
||||
if(istype(O))
|
||||
//user_C.visible_message("<span class='warning'>[user_C] attempts to remove [O]!</span>", \
|
||||
// "<span class='warning'>You snap [O] like it's nothing!</span>")
|
||||
user_C.clear_cuffs(O,TRUE)
|
||||
playsound(get_turf(usr), 'sound/effects/grillehit.ogg', 80, 1, -1)
|
||||
return TRUE
|
||||
|
||||
@@ -165,8 +165,8 @@
|
||||
// Broadcast Message
|
||||
if(amSilent)
|
||||
//if (!iscarbon(target))
|
||||
// user.visible_message("<span class='notice'>[user] shifts [target] closer to [user.p_their()] mouth.</span>", \
|
||||
// "<span class='notice'>You secretly slip your fangs into [target]'s flesh.</span>", \
|
||||
// user.visible_message("<span class='notice'>[user] shifts [target] closer to [user.p_their()] mouth.</span>",
|
||||
// "<span class='notice'>You secretly slip your fangs into [target]'s flesh.</span>",
|
||||
// vision_distance = 2, ignored_mobs=target) // Only people who AREN'T the target will notice this action.
|
||||
//else
|
||||
var/deadmessage = target.stat == DEAD ? "" : " <i>[target.p_they(TRUE)] looks dazed, and will not remember this.</i>"
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
B.decoy_override = FALSE
|
||||
remove_changeling_powers()
|
||||
owner.special_role = null
|
||||
owner.current.hud_used?.lingchemdisplay?.invisibility = INVISIBILITY_ABSTRACT
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/changeling/proc/remove_clownmut()
|
||||
@@ -225,6 +226,8 @@
|
||||
else //not dead? no chem/geneticdamage caps.
|
||||
chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), chem_storage)
|
||||
geneticdamage = max(0, geneticdamage-1)
|
||||
owner.current.hud_used?.lingchemdisplay?.invisibility = 0
|
||||
owner.current.hud_used?.lingchemdisplay?.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#dd66dd'>[round(chem_charges)]</font></div>"
|
||||
|
||||
|
||||
/datum/antagonist/changeling/proc/get_dna(dna_owner)
|
||||
@@ -357,10 +360,12 @@
|
||||
B.organ_flags &= ~ORGAN_VITAL
|
||||
B.decoy_override = TRUE
|
||||
update_changeling_icons_added()
|
||||
RegisterSignal(owner.current,COMSIG_LIVING_BIOLOGICAL_LIFE,.proc/regenerate)
|
||||
return
|
||||
|
||||
/datum/antagonist/changeling/remove_innate_effects()
|
||||
update_changeling_icons_removed()
|
||||
UnregisterSignal(owner.current,COMSIG_LIVING_BIOLOGICAL_LIFE)
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -174,7 +174,14 @@
|
||||
new reward(get_turf(src))
|
||||
to_chat(user, "<span class='cultitalic'>You work the forge as dark knowledge guides your hands, creating the [choice]!</span>")
|
||||
|
||||
|
||||
/obj/structure/destructible/cult/forge/attackby(obj/item/I, mob/user)
|
||||
if(!iscultist(user))
|
||||
to_chat(user, "<span class='warning'>The heat radiating from [src] pushes you back.</span>")
|
||||
return
|
||||
if(istype(I, /obj/item/ingot))
|
||||
var/obj/item/ingot/notsword = I
|
||||
to_chat(user, "You heat the [notsword] in the [src].")
|
||||
notsword.workability = "shapeable"
|
||||
|
||||
/obj/structure/destructible/cult/pylon
|
||||
name = "pylon"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
name = "Spawn Sentient Disease"
|
||||
typepath = /datum/round_event/ghost_role/sentient_disease
|
||||
weight = 7
|
||||
gamemode_blacklist = list("dynamic")
|
||||
max_occurrences = 1
|
||||
min_players = 5
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
/datum/antagonist/heretic/on_gain()
|
||||
var/mob/living/current = owner.current
|
||||
owner.teach_crafting_recipe(/datum/crafting_recipe/heretic/codex)
|
||||
if(ishuman(current))
|
||||
forge_primary_objectives()
|
||||
gain_knowledge(/datum/eldritch_knowledge/spell/basic)
|
||||
@@ -41,7 +42,6 @@
|
||||
START_PROCESSING(SSprocessing,src)
|
||||
if(give_equipment)
|
||||
equip_cultist()
|
||||
owner.teach_crafting_recipe(/datum/crafting_recipe/heretic/codex)
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/heretic/on_removal()
|
||||
@@ -111,17 +111,12 @@
|
||||
P.find_target(owners,assasination)
|
||||
protection += P.target
|
||||
objectives += P
|
||||
|
||||
|
||||
var/datum/objective/sacrifice_ecult/SE = new
|
||||
SE.owner = owner
|
||||
SE.update_explanation_text()
|
||||
objectives += SE
|
||||
|
||||
var/datum/objective/escape/escape_objective = new
|
||||
escape_objective.owner = owner
|
||||
objectives += escape_objective
|
||||
|
||||
/datum/antagonist/heretic/apply_innate_effects(mob/living/mob_override)
|
||||
. = ..()
|
||||
var/mob/living/current = owner.current
|
||||
|
||||
@@ -20,9 +20,11 @@
|
||||
if(!is_in_use)
|
||||
INVOKE_ASYNC(src, .proc/activate , user)
|
||||
|
||||
/obj/effect/eldritch/attacked_by(obj/item/I, mob/living/user)
|
||||
/obj/effect/eldritch/attackby(obj/item/I, mob/living/user)
|
||||
. = ..()
|
||||
if(istype(I,/obj/item/nullrod))
|
||||
if(istype(I, /obj/item/storage/book/bible) || istype(I, /obj/item/nullrod))
|
||||
user.say("BEGONE FOUL MAGICKS!!", forced = "bible")
|
||||
to_chat(user, "<span class='danger'>You disrupt the magic of [src] with [I].</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/eldritch/proc/activate(mob/living/user)
|
||||
|
||||
@@ -16,16 +16,19 @@
|
||||
return
|
||||
var/dist = get_dist(user.loc,target.loc)
|
||||
var/dir = get_dir(user.loc,target.loc)
|
||||
|
||||
switch(dist)
|
||||
if(0 to 15)
|
||||
to_chat(user,"<span class='warning'>[target.real_name] is near you. They are to the [dir2text(dir)] of you!</span>")
|
||||
if(16 to 31)
|
||||
to_chat(user,"<span class='warning'>[target.real_name] is somewhere in your vicinty. They are to the [dir2text(dir)] of you!</span>")
|
||||
if(32 to 127)
|
||||
to_chat(user,"<span class='warning'>[target.real_name] is far away from you. They are to the [dir2text(dir)] of you!</span>")
|
||||
else
|
||||
to_chat(user,"<span class='warning'>[target.real_name] is beyond our reach.</span>")
|
||||
|
||||
if(user.z != target.z)
|
||||
to_chat(user,"<span class='warning'>[target.real_name] is beyond our reach.</span>")
|
||||
else
|
||||
switch(dist)
|
||||
if(0 to 15)
|
||||
to_chat(user,"<span class='warning'>[target.real_name] is near you. They are to the [dir2text(dir)] of you!</span>")
|
||||
if(16 to 31)
|
||||
to_chat(user,"<span class='warning'>[target.real_name] is somewhere in your vicinty. They are to the [dir2text(dir)] of you!</span>")
|
||||
if(32 to 127)
|
||||
to_chat(user,"<span class='warning'>[target.real_name] is far away from you. They are to the [dir2text(dir)] of you!</span>")
|
||||
else
|
||||
to_chat(user,"<span class='warning'>[target.real_name] is beyond our reach.</span>")
|
||||
|
||||
if(target.stat == DEAD)
|
||||
to_chat(user,"<span class='warning'>[target.real_name] is dead. Bring them onto a transmutation rune!</span>")
|
||||
@@ -86,8 +89,8 @@
|
||||
desc = "A crescent blade born from a fleshwarped creature. Keenly aware, it seeks to spread to others the excruciations it has endured from dead origins."
|
||||
icon_state = "flesh_blade"
|
||||
item_state = "flesh_blade"
|
||||
wound_bonus = 5
|
||||
bare_wound_bonus = 15
|
||||
wound_bonus = 10
|
||||
bare_wound_bonus = 20
|
||||
|
||||
/obj/item/clothing/neck/eldritch_amulet
|
||||
name = "warm eldritch medallion"
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
name = "Break of Dawn"
|
||||
desc = "Starts your journey in the mansus. Allows you to select a target using a living heart on a transmutation rune."
|
||||
gain_text = "Gates of Mansus open up to your mind."
|
||||
next_knowledge = list(/datum/eldritch_knowledge/base_rust,/datum/eldritch_knowledge/base_ash,/datum/eldritch_knowledge/base_flesh)
|
||||
next_knowledge = list(/datum/eldritch_knowledge/base_rust,/datum/eldritch_knowledge/base_ash,/datum/eldritch_knowledge/base_flesh,/datum/eldritch_knowledge/spell/silence)
|
||||
cost = 0
|
||||
spell_to_add = /obj/effect/proc_holder/spell/targeted/touch/mansus_grasp
|
||||
required_atoms = list(/obj/item/living_heart)
|
||||
@@ -301,3 +301,11 @@
|
||||
required_atoms = list(/obj/item/shard,/obj/item/stack/rods)
|
||||
result_atoms = list(/obj/item/melee/sickly_blade)
|
||||
route = "Start"
|
||||
|
||||
/datum/eldritch_knowledge/spell/silence
|
||||
name = "Silence"
|
||||
desc = "Allows you to use the power of the Mansus to force an individual's tongue to be held down for up to twenty seconds. They'll notice quickly, however."
|
||||
gain_text = "They must hold their tongues, for they do not understand."
|
||||
cost = 1
|
||||
spell_to_add = /obj/effect/proc_holder/spell/pointed/trigger/mute/eldritch
|
||||
route = PATH_SIDE
|
||||
|
||||
@@ -43,8 +43,9 @@
|
||||
/obj/item/melee/touch_attack/mansus_fist
|
||||
name = "Mansus Grasp"
|
||||
desc = "A sinister looking aura that distorts the flow of reality around it. Causes knockdown, major stamina damage aswell as some Brute. It gains additional beneficial effects with certain knowledges you can research."
|
||||
icon_state = "disintegrate"
|
||||
item_state = "disintegrate"
|
||||
icon = 'icons/obj/eldritch.dmi'
|
||||
icon_state = "mansus_grasp"
|
||||
item_state = "mansus"
|
||||
catchphrase = "T'IESA SIE'KTI VISATA"
|
||||
|
||||
/obj/item/melee/touch_attack/mansus_fist/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
@@ -118,6 +119,7 @@
|
||||
/obj/item/melee/touch_attack/blood_siphon
|
||||
name = "Blood Siphon"
|
||||
desc = "A sinister looking aura that distorts the flow of reality around it."
|
||||
color = RUNE_COLOR_RED
|
||||
icon_state = "disintegrate"
|
||||
item_state = "disintegrate"
|
||||
catchphrase = "SUN'AI'KINI'MAS"
|
||||
@@ -260,41 +262,82 @@
|
||||
/obj/effect/proc_holder/spell/pointed/cleave/long
|
||||
charge_max = 650
|
||||
|
||||
/obj/effect/proc_holder/spell/pointed/touch/mad_touch
|
||||
/obj/effect/proc_holder/spell/targeted/touch/mad_touch
|
||||
name = "Touch of Madness"
|
||||
desc = "Touch spell that drains your enemies sanity."
|
||||
school = "transmutation"
|
||||
charge_max = 150
|
||||
desc = "Touch spell that allows you to force the knowledge of the mansus upon your foes."
|
||||
hand_path = /obj/item/melee/touch_attack/mad_touch
|
||||
school = "evocation"
|
||||
charge_max = 1800
|
||||
clothes_req = FALSE
|
||||
invocation_type = "none"
|
||||
range = 2
|
||||
action_icon = 'icons/mob/actions/actions_ecult.dmi'
|
||||
action_icon_state = "mad_touch"
|
||||
action_background_icon_state = "bg_ecult"
|
||||
|
||||
/obj/effect/proc_holder/spell/pointed/touch/mad_touch/can_target(atom/target, mob/user, silent)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
if(!istype(target,/mob/living/carbon/human))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>You are unable to touch [target]!</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
/obj/item/melee/touch_attack/mad_touch
|
||||
name = "Touch of Madness"
|
||||
desc = "A sinister looking aura that shatters your enemies minds."
|
||||
icon = 'icons/obj/eldritch.dmi'
|
||||
icon_state = "mad_touch"
|
||||
item_state = "madness"
|
||||
catchphrase = "SUNA'IKINTI PROTA"
|
||||
|
||||
/obj/effect/proc_holder/spell/pointed/touch/mad_touch/cast(list/targets, mob/user)
|
||||
. = ..()
|
||||
for(var/mob/living/carbon/target in targets)
|
||||
if(ishuman(targets))
|
||||
var/mob/living/carbon/human/tar = target
|
||||
if(tar.anti_magic_check())
|
||||
tar.visible_message("<span class='danger'>Spell bounces off of [target]!</span>","<span class='danger'>The spell bounces off of you!</span>")
|
||||
return
|
||||
if(target.mind && !target.mind.has_antag_datum(/datum/antagonist/heretic))
|
||||
to_chat(user,"<span class='warning'>[target.name] has been cursed!</span>")
|
||||
SEND_SIGNAL(target, COMSIG_ADD_MOOD_EVENT, "gates_of_mansus", /datum/mood_event/gates_of_mansus)
|
||||
/obj/item/melee/touch_attack/mad_touch/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
|
||||
/obj/effect/proc_holder/spell/pointed/ash_final
|
||||
if(!proximity_flag || target == user)
|
||||
return
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/tar = target
|
||||
if(tar.anti_magic_check())
|
||||
tar.visible_message("<span class='danger'>Spell bounces off of [target]!</span>","<span class='danger'>The spell bounces off of you!</span>")
|
||||
return ..()
|
||||
|
||||
if(iscarbon(target))
|
||||
playsound(user, 'sound/effects/curseattack.ogg', 75, TRUE)
|
||||
var/mob/living/carbon/C = target
|
||||
C.adjustOrganLoss(ORGAN_SLOT_BRAIN,35)
|
||||
C.DefaultCombatKnockdown(50, override_stamdmg = 0)
|
||||
C.gain_trauma(/datum/brain_trauma/mild/phobia)
|
||||
to_chat(user,"<span class='warning'>[target.name] has been cursed!</span>")
|
||||
SEND_SIGNAL(target, COMSIG_ADD_MOOD_EVENT, "gates_of_mansus", /datum/mood_event/gates_of_mansus)
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/touch/grasp_of_decay
|
||||
name = "Grasp of Decay"
|
||||
desc = "A sinister looking touch that rots your foes from the inside out for twenty seconds."
|
||||
hand_path = /obj/item/melee/touch_attack/grasp_of_decay
|
||||
school = "evocation"
|
||||
charge_max = 1200
|
||||
clothes_req = FALSE
|
||||
action_icon = 'icons/mob/actions/actions_ecult.dmi'
|
||||
action_icon_state = "mansus_grasp"
|
||||
action_background_icon_state = "bg_ecult"
|
||||
|
||||
/obj/item/melee/touch_attack/grasp_of_decay
|
||||
name = "Grasp of Decay"
|
||||
desc = "A sinister looking aura that rots your foes from the inside out."
|
||||
icon = 'icons/obj/eldritch.dmi'
|
||||
icon_state = "mansus_grasp"
|
||||
item_state = "mansus"
|
||||
catchphrase = "SKILI'EDUONIS"
|
||||
|
||||
/obj/item/melee/touch_attack/grasp_of_decay/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
|
||||
if(!proximity_flag || target == user)
|
||||
return
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/tar = target
|
||||
if(tar.anti_magic_check())
|
||||
tar.visible_message("<span class='danger'>Spell bounces off of [target]!</span>","<span class='danger'>The spell bounces off of you!</span>")
|
||||
return ..()
|
||||
|
||||
if(iscarbon(target))
|
||||
playsound(user, 'sound/effects/curseattack.ogg', 75, TRUE)
|
||||
var/mob/living/carbon/C = target
|
||||
C.DefaultCombatKnockdown(50, override_stamdmg = 0)
|
||||
C.apply_status_effect(/datum/status_effect/corrosion_curse/lesser)
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/pointed/nightwatchers_rite
|
||||
name = "Nightwatcher's Rite"
|
||||
desc = "Powerful spell that releases 5 streams of fire away from you."
|
||||
school = "transmutation"
|
||||
@@ -307,7 +350,7 @@
|
||||
action_icon_state = "flames"
|
||||
action_background_icon_state = "bg_ecult"
|
||||
|
||||
/obj/effect/proc_holder/spell/pointed/ash_final/cast(list/targets, mob/user)
|
||||
/obj/effect/proc_holder/spell/pointed/nightwatchers_rite/cast(list/targets, mob/user)
|
||||
for(var/X in targets)
|
||||
var/T
|
||||
T = line_target(-25, range, X, user)
|
||||
@@ -322,11 +365,12 @@
|
||||
INVOKE_ASYNC(src, .proc/fire_line, user,T)
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/pointed/ash_final/proc/line_target(offset, range, atom/at , atom/user)
|
||||
/obj/effect/proc_holder/spell/pointed/nightwatchers_rite/proc/line_target(offset, range, atom/at , atom/user)
|
||||
if(!at)
|
||||
return
|
||||
var/angle = ATAN2(at.x - user.x, at.y - user.y) + offset
|
||||
var/turf/T = get_turf(user)
|
||||
playsound(user,'sound/magic/fireball.ogg', 200, 1)
|
||||
for(var/i in 1 to range)
|
||||
var/turf/check = locate(user.x + cos(angle) * i, user.y + sin(angle) * i, user.z)
|
||||
if(!check)
|
||||
@@ -334,7 +378,7 @@
|
||||
T = check
|
||||
return (getline(user, T) - get_turf(user))
|
||||
|
||||
/obj/effect/proc_holder/spell/pointed/ash_final/proc/fire_line(atom/source, list/turfs)
|
||||
/obj/effect/proc_holder/spell/pointed/nightwatchers_rite/proc/fire_line(atom/source, list/turfs)
|
||||
var/list/hit_list = list()
|
||||
for(var/turf/T in turfs)
|
||||
if(istype(T, /turf/closed))
|
||||
@@ -347,8 +391,8 @@
|
||||
if(L in hit_list || L == source)
|
||||
continue
|
||||
hit_list += L
|
||||
L.adjustFireLoss(20)
|
||||
to_chat(L, "<span class='userdanger'>You're hit by [source]'s fire breath!</span>")
|
||||
L.adjustFireLoss(15)
|
||||
to_chat(L, "<span class='userdanger'>You're hit by a blast of fire!</span>")
|
||||
|
||||
new /obj/effect/hotspot(T)
|
||||
T.hotspot_expose(700,50,1)
|
||||
@@ -368,7 +412,7 @@
|
||||
possible_shapes = list(/mob/living/simple_animal/mouse,\
|
||||
/mob/living/simple_animal/pet/dog/corgi,\
|
||||
/mob/living/simple_animal/hostile/carp,\
|
||||
/mob/living/simple_animal/bot/secbot, \
|
||||
/mob/living/simple_animal/bot/secbot,\
|
||||
/mob/living/simple_animal/pet/fox,\
|
||||
/mob/living/simple_animal/pet/cat )
|
||||
|
||||
@@ -430,7 +474,7 @@
|
||||
action_background_icon_state = "bg_ecult"
|
||||
range = -1
|
||||
include_user = TRUE
|
||||
charge_max = 700
|
||||
charge_max = 1200
|
||||
action_icon = 'icons/mob/actions/actions_ecult.dmi'
|
||||
action_icon_state = "fire_ring"
|
||||
///how long it lasts
|
||||
@@ -595,6 +639,39 @@
|
||||
invocation = "AK'LIS"
|
||||
action_background_icon_state = "bg_ecult"
|
||||
|
||||
/obj/effect/proc_holder/spell/pointed/trigger/mute/eldritch
|
||||
name = "Silence"
|
||||
desc = "Using the power of the mansus, silences a selected unbeliever for twenty seconds."
|
||||
school = "transmutation"
|
||||
charge_max = 1800
|
||||
clothes_req = FALSE
|
||||
invocation = "VIS'TIEK TAVO'LIZUVIS"
|
||||
invocation_type = "whisper"
|
||||
message = "<span class='userdanger'>It feels as if your tongue is being held down by an unseen force!</span>"
|
||||
starting_spells = list("/obj/effect/proc_holder/spell/targeted/genetic/mute")
|
||||
ranged_mousepointer = 'icons/effects/mouse_pointers/mute_target.dmi'
|
||||
action_background_icon_state = "bg_ecult"
|
||||
action_icon = 'icons/mob/actions/actions_ecult.dmi'
|
||||
action_icon_state = "mute"
|
||||
active_msg = "You prepare to silence a target..."
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/mute
|
||||
mutations = list(MUT_MUTE)
|
||||
duration = 200
|
||||
charge_max = 1200 // needs to be higher than the duration or it'll be permanent
|
||||
sound = 'sound/magic/blind.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/pointed/trigger/mute/can_target(atom/target, mob/user, silent)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
if(!isliving(target))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>You can only silence living beings!</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/effect/temp_visual/dir_setting/entropic
|
||||
icon = 'icons/effects/160x160.dmi'
|
||||
icon_state = "entropic_plume"
|
||||
|
||||
@@ -95,7 +95,30 @@
|
||||
desc = "Drains nearby alive people that are engulfed in flames. It heals 10 of each damage type per person. If a person is in critical condition it finishes them off."
|
||||
cost = 1
|
||||
spell_to_add = /obj/effect/proc_holder/spell/targeted/fiery_rebirth
|
||||
next_knowledge = list(/datum/eldritch_knowledge/spell/cleave,/datum/eldritch_knowledge/summon/ashy,/datum/eldritch_knowledge/final/ash_final)
|
||||
next_knowledge = list(/datum/eldritch_knowledge/spell/cleave,/datum/eldritch_knowledge/summon/ashy,/datum/eldritch_knowledge/flame_immunity)
|
||||
route = PATH_ASH
|
||||
|
||||
/datum/eldritch_knowledge/flame_immunity
|
||||
name = "Nightwatcher's Blessing"
|
||||
gain_text = "The True Light will destroy and make something anew of any individual. If only they accepted it."
|
||||
desc = "Becoming one with the ash, you become immune to fire and heat, allowing you to thrive in a more extreme environment.."
|
||||
cost = 2
|
||||
next_knowledge = list(/datum/eldritch_knowledge/spell/nightwatchers_rite)
|
||||
route = PATH_ASH
|
||||
var/list/trait_list = list(TRAIT_RESISTHEAT,TRAIT_NOFIRE)
|
||||
|
||||
/datum/eldritch_knowledge/flame_immunity/on_gain(mob/living/user)
|
||||
to_chat(user, "<span class='warning'>[gain_text]</span>")
|
||||
for(var/X in trait_list)
|
||||
ADD_TRAIT(user,X,MAGIC_TRAIT)
|
||||
|
||||
/datum/eldritch_knowledge/spell/nightwatchers_rite
|
||||
name = "Nightwatcher's Rite"
|
||||
gain_text = "When the Glory of the Lantern scorches and sears their skin, nothing will protect them from the ashes."
|
||||
desc = "Fire off five streams of fire from your hand, each setting ablaze targets hit and scorching them upon contact."
|
||||
cost = 2
|
||||
spell_to_add = /obj/effect/proc_holder/spell/pointed/nightwatchers_rite
|
||||
next_knowledge = list(/datum/eldritch_knowledge/final/ash_final)
|
||||
route = PATH_ASH
|
||||
|
||||
/datum/eldritch_knowledge/ash_blade_upgrade
|
||||
@@ -167,7 +190,7 @@
|
||||
required_atoms = list(/mob/living/carbon/human)
|
||||
cost = 5
|
||||
route = PATH_ASH
|
||||
var/list/trait_list = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_BOMBIMMUNE)
|
||||
var/list/trait_list = list(TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_BOMBIMMUNE)
|
||||
|
||||
/datum/eldritch_knowledge/final/ash_final/on_finished_recipe(mob/living/user, list/atoms, loc)
|
||||
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# Fear the blaze, for Ashbringer [user.real_name] has come! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", 'sound/announcer/classic/spanomalies.ogg')
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
desc = "Empowers your Mansus Grasp to be able to create a single ghoul out of a dead player. You cannot raise the same person twice. Ghouls have only 50 HP and look like husks."
|
||||
cost = 1
|
||||
next_knowledge = list(/datum/eldritch_knowledge/flesh_ghoul)
|
||||
var/ghoul_amt = 6
|
||||
var/ghoul_amt = 4
|
||||
var/list/spooky_scaries
|
||||
route = PATH_FLESH
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
cost = 1
|
||||
required_atoms = list(/obj/item/kitchen/knife,/obj/item/reagent_containers/food/snacks/grown/poppy,/obj/item/pen,/obj/item/paper)
|
||||
mob_to_summon = /mob/living/simple_animal/hostile/eldritch/stalker
|
||||
next_knowledge = list(/datum/eldritch_knowledge/summon/ashy,/datum/eldritch_knowledge/summon/rusty,/datum/eldritch_knowledge/final/flesh_final)
|
||||
next_knowledge = list(/datum/eldritch_knowledge/summon/ashy,/datum/eldritch_knowledge/summon/rusty,/datum/eldritch_knowledge/flesh_blade_upgrade_2)
|
||||
route = PATH_FLESH
|
||||
|
||||
/datum/eldritch_knowledge/summon/ashy
|
||||
@@ -250,3 +250,28 @@
|
||||
carbon_user.gib()
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/eldritch_knowledge/flesh_blade_upgrade_2
|
||||
name = "Remembrance"
|
||||
gain_text = "Pain isn't something easily forgotten."
|
||||
desc = "Your blade remembers more, and remembers how easily bones broke just as its flesh did, guaranteeing dislocated, or broken bones."
|
||||
cost = 2
|
||||
next_knowledge = list(/datum/eldritch_knowledge/spell/touch_of_madness)
|
||||
route = PATH_FLESH
|
||||
|
||||
/datum/eldritch_knowledge/flesh_blade_upgrade_2/on_eldritch_blade(target,user,proximity_flag,click_parameters)
|
||||
. = ..()
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/carbon_target = target
|
||||
var/obj/item/bodypart/bodypart = pick(carbon_target.bodyparts)
|
||||
var/datum/wound/blunt/moderate/moderate_wound = new
|
||||
moderate_wound.apply_wound(bodypart)
|
||||
|
||||
/datum/eldritch_knowledge/spell/touch_of_madness
|
||||
name = "Touch of Madness"
|
||||
gain_text = "The ignorant mind that inhabits their feeble bodies will crumble when they acknowledge - willingly or not, the truth."
|
||||
desc = "By forcing the knowledge of the Mansus upon my foes, I can show them things that would drive any normal man insane."
|
||||
cost = 2
|
||||
spell_to_add = /obj/effect/proc_holder/spell/targeted/touch/mad_touch
|
||||
next_knowledge = list(/datum/eldritch_knowledge/final/flesh_final)
|
||||
route = PATH_FLESH
|
||||
|
||||
@@ -27,8 +27,13 @@
|
||||
if(E)
|
||||
E.on_effect()
|
||||
H.adjustOrganLoss(pick(ORGAN_SLOT_BRAIN,ORGAN_SLOT_EARS,ORGAN_SLOT_EYES,ORGAN_SLOT_LIVER,ORGAN_SLOT_LUNGS,ORGAN_SLOT_STOMACH,ORGAN_SLOT_HEART),25)
|
||||
else
|
||||
for(var/X in user.mind.spell_list)
|
||||
if(!istype(X,/obj/effect/proc_holder/spell/targeted/touch/mansus_grasp))
|
||||
continue
|
||||
var/obj/effect/proc_holder/spell/targeted/touch/mansus_grasp/MG = X
|
||||
MG.charge_counter = min(round(MG.charge_counter + MG.charge_max * 0.75),MG.charge_max)
|
||||
target.rust_heretic_act()
|
||||
target.emp_act(EMP_HEAVY)
|
||||
return TRUE
|
||||
|
||||
/datum/eldritch_knowledge/spell/area_conversion
|
||||
@@ -43,7 +48,7 @@
|
||||
/datum/eldritch_knowledge/spell/rust_wave
|
||||
name = "Patron's Reach"
|
||||
desc = "You can now send a bolt of rust that corrupts the immediate area, and poisons the first target hit."
|
||||
gain_text = "Messengers of hope fear the rustbringer."
|
||||
gain_text = "Messengers of hope fear the Rustbringer."
|
||||
cost = 1
|
||||
spell_to_add = /obj/effect/proc_holder/spell/aimed/rust_wave
|
||||
route = PATH_RUST
|
||||
@@ -92,19 +97,20 @@
|
||||
banned_knowledge = list(/datum/eldritch_knowledge/ash_blade_upgrade,/datum/eldritch_knowledge/flesh_blade_upgrade)
|
||||
route = PATH_RUST
|
||||
|
||||
/datum/eldritch_knowledge/rust_blade_upgrade/on_eldritch_blade(target,user,proximity_flag,click_parameters)
|
||||
/datum/eldritch_knowledge/rust_blade_upgrade/on_eldritch_blade(mob/target,user,proximity_flag,click_parameters)
|
||||
. = ..()
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/carbon_target = target
|
||||
carbon_target.reagents.add_reagent(/datum/reagent/eldritch, 5)
|
||||
if(!IS_HERETIC(target))
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/carbon_target = target
|
||||
carbon_target.reagents.add_reagent(/datum/reagent/eldritch, 5)
|
||||
|
||||
/datum/eldritch_knowledge/spell/entropic_plume
|
||||
name = "Entropic Plume"
|
||||
desc = "You can now send a befuddling plume that blinds, poisons and makes enemies strike each other, while also converting the immediate area into rust."
|
||||
gain_text = "Messengers of hope fear the rustbringer."
|
||||
gain_text = "If they knew, the truth would turn them against eachother."
|
||||
cost = 1
|
||||
spell_to_add = /obj/effect/proc_holder/spell/cone/staggered/entropic_plume
|
||||
next_knowledge = list(/datum/eldritch_knowledge/final/rust_final,/datum/eldritch_knowledge/spell/cleave,/datum/eldritch_knowledge/summon/rusty)
|
||||
next_knowledge = list(/datum/eldritch_knowledge/rust_fist_upgrade,/datum/eldritch_knowledge/spell/cleave,/datum/eldritch_knowledge/summon/rusty)
|
||||
route = PATH_RUST
|
||||
|
||||
/datum/eldritch_knowledge/armor
|
||||
@@ -119,12 +125,38 @@
|
||||
/datum/eldritch_knowledge/essence
|
||||
name = "Priest's Ritual"
|
||||
desc = "You can now transmute a tank of water into a bottle of eldritch fluid."
|
||||
gain_text = "This is an old recipe, i got it from an owl."
|
||||
gain_text = "This is an old recipe, I got it from an owl."
|
||||
cost = 1
|
||||
next_knowledge = list(/datum/eldritch_knowledge/rust_regen,/datum/eldritch_knowledge/spell/ashen_shift)
|
||||
required_atoms = list(/obj/structure/reagent_dispensers/watertank)
|
||||
result_atoms = list(/obj/item/reagent_containers/glass/beaker/eldritch)
|
||||
|
||||
/datum/eldritch_knowledge/rust_fist_upgrade
|
||||
name = "Vile Grip"
|
||||
desc = "Empowers your Mansus Grasp further, sickening your foes and making them vomit, while also strengthening the rate at which your hand decays objects."
|
||||
gain_text = "A sickly diseased touch that was, yet, so welcoming."
|
||||
cost = 2
|
||||
next_knowledge = list(/datum/eldritch_knowledge/spell/grasp_of_decay)
|
||||
var/rust_force = 750
|
||||
var/static/list/blacklisted_turfs = typecacheof(list(/turf/closed,/turf/open/space,/turf/open/lava,/turf/open/chasm,/turf/open/floor/plating/rust))
|
||||
route = PATH_RUST
|
||||
|
||||
/datum/eldritch_knowledge/rust_fist_upgrade/on_mansus_grasp(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
. = ..()
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
H.set_disgust(75)
|
||||
return TRUE
|
||||
|
||||
/datum/eldritch_knowledge/spell/grasp_of_decay
|
||||
name = "Grasp of Decay"
|
||||
desc = "Applying your knowledge of rust to the human body, a knowledge that could decay your foes from the inside out, resulting in organ failure, vomiting, or eventual death through peeling flesh."
|
||||
gain_text = "Decay, similar to Rust, yet so much more terribly uninviting."
|
||||
cost = 2
|
||||
spell_to_add = /obj/effect/proc_holder/spell/targeted/touch/grasp_of_decay
|
||||
next_knowledge = list(/datum/eldritch_knowledge/final/rust_final)
|
||||
route = PATH_RUST
|
||||
|
||||
/datum/eldritch_knowledge/final/rust_final
|
||||
name = "Rustbringer's Oath"
|
||||
desc = "Bring three corpses onto a transmutation rune. After you finish the ritual, rust will now automatically spread from the rune. Your healing on rust is also tripled, while you become more resilient overall."
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
name = "Spawn Revenant" // Did you mean 'griefghost'?
|
||||
typepath = /datum/round_event/ghost_role/revenant
|
||||
weight = 7
|
||||
gamemode_blacklist = list("dynamic")
|
||||
max_occurrences = 1
|
||||
min_players = 5
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
max_occurrences = 1 //Only once okay fam
|
||||
earliest_start = 30 MINUTES
|
||||
min_players = 35
|
||||
gamemode_blacklist = list("dynamic")
|
||||
|
||||
|
||||
/datum/round_event/spawn_swarmer
|
||||
|
||||
@@ -13,7 +13,9 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
|
||||
/obj/machinery/syndicatebomb/badmin/clown,
|
||||
/obj/machinery/syndicatebomb/empty,
|
||||
/obj/machinery/syndicatebomb/self_destruct,
|
||||
/obj/machinery/syndicatebomb/training
|
||||
/obj/machinery/syndicatebomb/training,
|
||||
/obj/machinery/gravity_generator,
|
||||
/obj/machinery/gravity_generator/main
|
||||
)))
|
||||
|
||||
//The malf AI action subtype. All malf actions are subtypes of this.
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
R.reaction(turfing ? target : target.loc, TOUCH, 1, 0)
|
||||
if(!turfing)
|
||||
R.trans_to(target, R.total_volume * (spill ? G.fluid_transfer_factor : 1))
|
||||
G.time_since_last_orgasm = 0
|
||||
G.last_orgasmed = world.time
|
||||
R.clear_reagents()
|
||||
|
||||
/mob/living/carbon/human/proc/mob_climax_outside(obj/item/organ/genital/G, mb_time = 30) //This is used for forced orgasms and other hands-free climaxes
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
var/fluid_efficiency = 1
|
||||
var/fluid_rate = CUM_RATE
|
||||
var/fluid_mult = 1
|
||||
var/time_since_last_orgasm = 500
|
||||
var/last_orgasmed = 0
|
||||
var/aroused_state = FALSE //Boolean used in icon_state strings
|
||||
var/obj/item/organ/genital/linked_organ
|
||||
var/linked_organ_slot //used for linking an apparatus' organ to its other half on update_link().
|
||||
@@ -24,10 +24,6 @@
|
||||
|
||||
/obj/item/organ/genital/Initialize(mapload, do_update = TRUE)
|
||||
. = ..()
|
||||
if(fluid_id)
|
||||
create_reagents(fluid_max_volume, NONE, NO_REAGENTS_VALUE)
|
||||
if(CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION))
|
||||
reagents.add_reagent(fluid_id, fluid_max_volume)
|
||||
if(do_update)
|
||||
update()
|
||||
|
||||
@@ -140,8 +136,6 @@
|
||||
/obj/item/organ/genital/proc/modify_size(modifier, min = -INFINITY, max = INFINITY)
|
||||
fluid_max_volume += modifier*2.5
|
||||
fluid_rate += modifier/10
|
||||
if(reagents)
|
||||
reagents.maximum_volume = fluid_max_volume
|
||||
return
|
||||
|
||||
/obj/item/organ/genital/proc/update_size()
|
||||
@@ -151,18 +145,14 @@
|
||||
if(!owner || owner.stat == DEAD)
|
||||
aroused_state = FALSE
|
||||
|
||||
/obj/item/organ/genital/on_life()
|
||||
. = ..()
|
||||
if(!reagents || !.)
|
||||
return
|
||||
reagents.maximum_volume = fluid_max_volume
|
||||
if(fluid_id && CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION))
|
||||
time_since_last_orgasm++
|
||||
|
||||
/obj/item/organ/genital/proc/generate_fluid(datum/reagents/R)
|
||||
var/amount = clamp(fluid_rate * time_since_last_orgasm * fluid_mult,0,fluid_max_volume)
|
||||
var/amount = clamp((fluid_rate * ((world.time - last_orgasmed) / SSmobs.wait) * fluid_mult),0,fluid_max_volume)
|
||||
R.clear_reagents()
|
||||
R.add_reagent(fluid_id,amount)
|
||||
R.maximum_volume = fluid_max_volume
|
||||
if(fluid_id)
|
||||
R.add_reagent(fluid_id,amount)
|
||||
else if(linked_organ?.fluid_id)
|
||||
R.add_reagent(linked_organ.fluid_id,amount)
|
||||
return TRUE
|
||||
|
||||
/obj/item/organ/genital/proc/update_link()
|
||||
|
||||
@@ -24,12 +24,10 @@
|
||||
/datum/asset_cache_item/New(name, file)
|
||||
if (!isfile(file))
|
||||
file = fcopy_rsc(file)
|
||||
hash = md5(file)
|
||||
|
||||
hash = md5asfile(file) //icons sent to the rsc sometimes md5 incorrectly
|
||||
if (!hash)
|
||||
hash = md5(fcopy_rsc(file))
|
||||
if (!hash)
|
||||
CRASH("invalid asset sent to asset cache")
|
||||
debug_world_log("asset cache unexpected success of second fcopy_rsc")
|
||||
CRASH("invalid asset sent to asset cache")
|
||||
src.name = name
|
||||
var/extstart = findlasttext(name, ".")
|
||||
if (extstart)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/turf
|
||||
//used for temperature calculations
|
||||
var/thermal_conductivity = 0.05
|
||||
var/thermal_conductivity = 0.005
|
||||
var/heat_capacity = 1
|
||||
var/temperature_archived
|
||||
|
||||
@@ -270,7 +270,7 @@
|
||||
|
||||
/turf/proc/super_conduct()
|
||||
var/conductivity_directions = conductivity_directions()
|
||||
|
||||
archive()
|
||||
if(conductivity_directions)
|
||||
//Conduct with tiles around me
|
||||
for(var/direction in GLOB.cardinals)
|
||||
@@ -331,6 +331,7 @@
|
||||
var/heat = thermal_conductivity*delta_temperature* \
|
||||
(heat_capacity*HEAT_CAPACITY_VACUUM/(heat_capacity+HEAT_CAPACITY_VACUUM))
|
||||
temperature -= heat/heat_capacity
|
||||
temperature = max(temperature,T0C) //otherwise we just sorta get stuck at super cold temps forever
|
||||
|
||||
/turf/open/proc/temperature_share_open_to_solid(turf/sharer)
|
||||
sharer.temperature = air.temperature_share(null, sharer.thermal_conductivity, sharer.temperature, sharer.heat_capacity)
|
||||
@@ -344,3 +345,5 @@
|
||||
|
||||
temperature -= heat/heat_capacity
|
||||
sharer.temperature += heat/sharer.heat_capacity
|
||||
temperature = max(temperature,T0C)
|
||||
sharer.temperature = max(sharer.temperature,T0C)
|
||||
|
||||
@@ -188,7 +188,7 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
|
||||
//Performs air sharing calculations between two gas_mixtures assuming only 1 boundary length
|
||||
//Returns: amount of gas exchanged (+ if sharer received)
|
||||
|
||||
/datum/gas_mixture/proc/temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
|
||||
/datum/gas_mixture/proc/temperature_share(datum/gas_mixture/sharer, conduction_coefficient,temperature=null,heat_capacity=null)
|
||||
//Performs temperature sharing calculations (via conduction) between two gas_mixtures assuming only 1 boundary length
|
||||
//Returns: new temperature of the sharer
|
||||
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
/datum/gas_reaction/proc/react(datum/gas_mixture/air, atom/location)
|
||||
return NO_REACTION
|
||||
|
||||
/datum/gas_reaction/proc/test()
|
||||
return list("success" = TRUE)
|
||||
|
||||
/datum/gas_reaction/nobliumsupression
|
||||
priority = INFINITY
|
||||
name = "Hyper-Noblium Reaction Suppression"
|
||||
@@ -70,6 +73,8 @@
|
||||
air.adjust_moles(/datum/gas/water_vapor,-MOLES_GAS_VISIBLE)
|
||||
. = REACTING
|
||||
|
||||
// no test cause it's entirely based on location
|
||||
|
||||
//tritium combustion: combustion of oxygen and tritium (treated as hydrocarbons). creates hotspots. exothermic
|
||||
/datum/gas_reaction/tritfire
|
||||
priority = -1 //fire should ALWAYS be last, but tritium fires happen before plasma fires
|
||||
@@ -126,6 +131,18 @@
|
||||
|
||||
return cached_results["fire"] ? REACTING : NO_REACTION
|
||||
|
||||
/datum/gas_reaction/tritfire/test()
|
||||
var/datum/gas_mixture/G = new
|
||||
G.set_moles(/datum/gas/tritium,50)
|
||||
G.set_moles(/datum/gas/oxygen,50)
|
||||
G.set_temperature(500)
|
||||
var/result = G.react()
|
||||
if(result != REACTING)
|
||||
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
|
||||
if(!G.reaction_results["fire"])
|
||||
return list("success" = FALSE, "message" = "Trit fires aren't setting fire results correctly!")
|
||||
return ..()
|
||||
|
||||
//plasma combustion: combustion of oxygen and plasma (treated as hydrocarbons). creates hotspots. exothermic
|
||||
/datum/gas_reaction/plasmafire
|
||||
priority = -2 //fire should ALWAYS be last, but plasma fires happen after tritium fires
|
||||
@@ -198,6 +215,28 @@
|
||||
|
||||
return cached_results["fire"] ? REACTING : NO_REACTION
|
||||
|
||||
/datum/gas_reaction/plasmafire/test()
|
||||
var/datum/gas_mixture/G = new
|
||||
G.set_moles(/datum/gas/plasma,50)
|
||||
G.set_moles(/datum/gas/oxygen,50)
|
||||
G.set_volume(1000)
|
||||
G.set_temperature(500)
|
||||
var/result = G.react()
|
||||
if(result != REACTING)
|
||||
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
|
||||
if(!G.reaction_results["fire"])
|
||||
return list("success" = FALSE, "message" = "Plasma fires aren't setting fire results correctly!")
|
||||
if(!G.get_moles(/datum/gas/carbon_dioxide))
|
||||
return list("success" = FALSE, "message" = "Plasma fires aren't making CO2!")
|
||||
G.clear()
|
||||
G.set_moles(/datum/gas/plasma,10)
|
||||
G.set_moles(/datum/gas/oxygen,1000)
|
||||
G.set_temperature(500)
|
||||
result = G.react()
|
||||
if(!G.get_moles(/datum/gas/tritium))
|
||||
return list("success" = FALSE, "message" = "Plasma fires aren't making trit!")
|
||||
return ..()
|
||||
|
||||
//fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. Again (and again, and again). Again!
|
||||
//Fusion Rework Counter: Please increment this if you make a major overhaul to this system again.
|
||||
//6 reworks
|
||||
@@ -282,6 +321,31 @@
|
||||
air.set_temperature(clamp(((air.return_temperature()*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB,INFINITY))
|
||||
return REACTING
|
||||
|
||||
/datum/gas_reaction/fusion/test()
|
||||
var/datum/gas_mixture/G = new
|
||||
G.set_moles(/datum/gas/carbon_dioxide,300)
|
||||
G.set_moles(/datum/gas/plasma,1000)
|
||||
G.set_moles(/datum/gas/tritium,100.61)
|
||||
G.set_moles(/datum/gas/nitryl,1)
|
||||
G.set_temperature(15000)
|
||||
G.set_volume(1000)
|
||||
var/result = G.react()
|
||||
if(result != REACTING)
|
||||
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
|
||||
if(abs(G.analyzer_results["fusion"] - 3) > 0.0000001)
|
||||
var/instability = G.analyzer_results["fusion"]
|
||||
return list("success" = FALSE, "message" = "Fusion is not calculating analyzer results correctly, should be 3.000000045, is instead [instability]")
|
||||
if(abs(G.get_moles(/datum/gas/plasma) - 850.616) > 0.5)
|
||||
var/plas = G.get_moles(/datum/gas/plasma)
|
||||
return list("success" = FALSE, "message" = "Fusion is not calculating plasma correctly, should be 850.616, is instead [plas]")
|
||||
if(abs(G.get_moles(/datum/gas/carbon_dioxide) - 1699.384) > 0.5)
|
||||
var/co2 = G.get_moles(/datum/gas/carbon_dioxide)
|
||||
return list("success" = FALSE, "message" = "Fusion is not calculating co2 correctly, should be 1699.384, is instead [co2]")
|
||||
if(abs(G.return_temperature() - 27600) > 200) // calculating this manually sucks dude
|
||||
var/temp = G.return_temperature()
|
||||
return list("success" = FALSE, "message" = "Fusion is not calculating temperature correctly, should be around 27600, is instead [temp]")
|
||||
return ..()
|
||||
|
||||
/datum/gas_reaction/nitrylformation //The formation of nitryl. Endothermic. Requires N2O as a catalyst.
|
||||
priority = 3
|
||||
name = "Nitryl formation"
|
||||
@@ -313,6 +377,20 @@
|
||||
air.set_temperature(max(((temperature*old_heat_capacity - energy_used)/new_heat_capacity),TCMB))
|
||||
return REACTING
|
||||
|
||||
/datum/gas_reaction/nitrylformation/test()
|
||||
var/datum/gas_mixture/G = new
|
||||
G.set_moles(/datum/gas/oxygen,30)
|
||||
G.set_moles(/datum/gas/nitrogen,30)
|
||||
G.set_moles(/datum/gas/nitrous_oxide,10)
|
||||
G.set_volume(1000)
|
||||
G.set_temperature(150000)
|
||||
var/result = G.react()
|
||||
if(result != REACTING)
|
||||
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
|
||||
if(!G.get_moles(/datum/gas/nitryl) < 0.8)
|
||||
return list("success" = FALSE, "message" = "Nitryl isn't being generated correctly!")
|
||||
return ..()
|
||||
|
||||
/datum/gas_reaction/bzformation //Formation of BZ by combining plasma and tritium at low pressures. Exothermic.
|
||||
priority = 4
|
||||
name = "BZ Gas formation"
|
||||
@@ -348,6 +426,19 @@
|
||||
air.set_temperature(max(((temperature*old_heat_capacity + energy_released)/new_heat_capacity),TCMB))
|
||||
return REACTING
|
||||
|
||||
/datum/gas_reaction/bzformation/test()
|
||||
var/datum/gas_mixture/G = new
|
||||
G.set_moles(/datum/gas/plasma,15)
|
||||
G.set_moles(/datum/gas/nitrous_oxide,15)
|
||||
G.set_volume(1000)
|
||||
G.set_temperature(10)
|
||||
var/result = G.react()
|
||||
if(result != REACTING)
|
||||
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
|
||||
if(!G.get_moles(/datum/gas/bz) < 4) // efficiency is 4.0643 and bz generation == efficiency
|
||||
return list("success" = FALSE, "message" = "Nitryl isn't being generated correctly!")
|
||||
return ..()
|
||||
|
||||
/datum/gas_reaction/stimformation //Stimulum formation follows a strange pattern of how effective it will be at a given temperature, having some multiple peaks and some large dropoffs. Exo and endo thermic.
|
||||
priority = 5
|
||||
name = "Stimulum formation"
|
||||
@@ -380,6 +471,23 @@
|
||||
air.set_temperature(max(((air.return_temperature()*old_heat_capacity + stim_energy_change)/new_heat_capacity),TCMB))
|
||||
return REACTING
|
||||
|
||||
/datum/gas_reaction/stimformation/test()
|
||||
//above mentioned "strange pattern" is a basic quintic polynomial, it's fine, can calculate it manually
|
||||
var/datum/gas_mixture/G = new
|
||||
G.set_moles(/datum/gas/bz,30)
|
||||
G.set_moles(/datum/gas/plasma,1000)
|
||||
G.set_moles(/datum/gas/tritium,1000)
|
||||
G.set_moles(/datum/gas/nitryl,1000)
|
||||
G.set_volume(1000)
|
||||
G.set_temperature(12998000) // yeah, really
|
||||
|
||||
var/result = G.react()
|
||||
if(result != REACTING)
|
||||
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
|
||||
if(!G.get_moles(/datum/gas/stimulum) < 900)
|
||||
return list("success" = FALSE, "message" = "Stimulum isn't being generated correctly!")
|
||||
return ..()
|
||||
|
||||
/datum/gas_reaction/nobliumformation //Hyper-Noblium formation is extrememly endothermic, but requires high temperatures to start. Due to its high mass, hyper-nobelium uses large amounts of nitrogen and tritium. BZ can be used as a catalyst to make it less endothermic.
|
||||
priority = 6
|
||||
name = "Hyper-Noblium condensation"
|
||||
@@ -408,6 +516,19 @@
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
air.set_temperature(max(((air.return_temperature()*old_heat_capacity - energy_taken)/new_heat_capacity),TCMB))
|
||||
|
||||
/datum/gas_reaction/nobliumformation/test()
|
||||
var/datum/gas_mixture/G = new
|
||||
G.set_moles(/datum/gas/nitrogen,100)
|
||||
G.set_moles(/datum/gas/tritium,500)
|
||||
G.set_volume(1000)
|
||||
G.set_temperature(5000000) // yeah, really
|
||||
var/result = G.react()
|
||||
if(result != REACTING)
|
||||
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
|
||||
if(abs(G.thermal_energy() - 23000000000) > 1000000) // god i hate floating points
|
||||
return list("success" = FALSE, "message" = "Hyper-nob formation isn't removing the right amount of heat! Should be 23,000,000,000, is instead [G.thermal_energy()]")
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/gas_reaction/miaster //dry heat sterilization: clears out pathogens in the air
|
||||
priority = -10 //after all the heating from fires etc. is done
|
||||
@@ -433,3 +554,20 @@
|
||||
//Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable
|
||||
air.set_temperature(air.return_temperature() + cleaned_air * 0.002)
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, cleaned_air*MIASMA_RESEARCH_AMOUNT)//Turns out the burning of miasma is kinda interesting to scientists
|
||||
|
||||
/datum/gas_reaction/miaster/test()
|
||||
var/datum/gas_mixture/G = new
|
||||
G.set_moles(/datum/gas/miasma,1)
|
||||
G.set_volume(1000)
|
||||
G.set_temperature(450)
|
||||
var/result = G.react()
|
||||
if(result != REACTING)
|
||||
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
|
||||
G.clear()
|
||||
G.set_moles(/datum/gas/miasma,1)
|
||||
G.set_temperature(450)
|
||||
G.set_moles(/datum/gas/water_vapor,0.5)
|
||||
result = G.react()
|
||||
if(result != NO_REACTION)
|
||||
return list("success" = FALSE, "message" = "Miasma sterilization not stopping due to water vapor correctly!")
|
||||
return ..()
|
||||
|
||||
@@ -52,8 +52,8 @@
|
||||
cost = 300
|
||||
contains = list(/obj/item/storage/toolbox/mechanical)
|
||||
|
||||
/datum/supply_pack/goody/electrical_toolbox // mostly just to water down coupon probability
|
||||
name = "Mechanical Toolbox"
|
||||
/datum/supply_pack/goody/electrical_toolbox
|
||||
name = "Electrical Toolbox"
|
||||
desc = "A fully stocked electrical toolbox, for when you're too lazy to just print them out."
|
||||
cost = 300
|
||||
contains = list(/obj/item/storage/toolbox/electrical)
|
||||
|
||||
@@ -13,6 +13,13 @@
|
||||
//////////////////// Paperwork and Writing Supplies //////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/datum/supply_pack/misc/anvil
|
||||
name = "Anvil Crate"
|
||||
desc = "An anvil in a crate, we had to dig this out of the old warehouse. It's got wheels on it so you can move it."
|
||||
cost = 7500
|
||||
contains = list(/obj/structure/anvil/obtainable/basic)
|
||||
|
||||
/datum/supply_pack/misc/artsupply
|
||||
name = "Art Supplies"
|
||||
desc = "Make some happy little accidents with six canvasses, two easels, two boxes of crayons, and a rainbow crayon!"
|
||||
|
||||
@@ -192,3 +192,49 @@
|
||||
crate_type = /obj/structure/closet/crate/secure/science
|
||||
dangerous = TRUE
|
||||
|
||||
//////// RAW ANOMALY CORES
|
||||
|
||||
/datum/supply_pack/science/raw_flux_anomaly
|
||||
name = "Raw Flux Anomaly"
|
||||
desc = "The raw core of a flux anomaly, ready to be implosion-compressed into a powerful artifact."
|
||||
cost = 5000
|
||||
access = ACCESS_TOX
|
||||
contains = list(/obj/item/raw_anomaly_core/flux)
|
||||
crate_name = "raw flux anomaly"
|
||||
crate_type = /obj/structure/closet/crate/secure/science
|
||||
|
||||
/datum/supply_pack/science/raw_grav_anomaly
|
||||
name = "Raw Gravitational Anomaly"
|
||||
desc = "The raw core of a gravitational anomaly, ready to be implosion-compressed into a powerful artifact."
|
||||
cost = 5000
|
||||
access = ACCESS_TOX
|
||||
contains = list(/obj/item/raw_anomaly_core/grav)
|
||||
crate_name = "raw pyro anomaly"
|
||||
crate_type = /obj/structure/closet/crate/secure/science
|
||||
|
||||
/datum/supply_pack/science/raw_vortex_anomaly
|
||||
name = "Raw Vortex Anomaly"
|
||||
desc = "The raw core of a vortex anomaly, ready to be implosion-compressed into a powerful artifact."
|
||||
cost = 5000
|
||||
access = ACCESS_TOX
|
||||
contains = list(/obj/item/raw_anomaly_core/vortex)
|
||||
crate_name = "raw vortex anomaly"
|
||||
crate_type = /obj/structure/closet/crate/secure/science
|
||||
|
||||
/datum/supply_pack/science/raw_bluespace_anomaly
|
||||
name = "Raw Bluespace Anomaly"
|
||||
desc = "The raw core of a bluespace anomaly, ready to be implosion-compressed into a powerful artifact."
|
||||
cost = 5000
|
||||
access = ACCESS_TOX
|
||||
contains = list(/obj/item/raw_anomaly_core/bluespace)
|
||||
crate_name = "raw bluespace anomaly"
|
||||
crate_type = /obj/structure/closet/crate/secure/science
|
||||
|
||||
/datum/supply_pack/science/raw_pyro_anomaly
|
||||
name = "Raw Pyro Anomaly"
|
||||
desc = "The raw core of a pyro anomaly, ready to be implosion-compressed into a powerful artifact."
|
||||
cost = 5000
|
||||
access = ACCESS_TOX
|
||||
contains = list(/obj/item/raw_anomaly_core/pyro)
|
||||
crate_name = "raw pyro anomaly"
|
||||
crate_type = /obj/structure/closet/crate/secure/science
|
||||
|
||||
@@ -163,6 +163,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
)
|
||||
var/custom_speech_verb = "default" //if your say_mod is to be something other than your races
|
||||
var/custom_tongue = "default" //if your tongue is to be something other than your races
|
||||
var/modified_limbs = list() //prosthetic/amputated limbs
|
||||
var/chosen_limb_id //body sprite selected to load for the users limbs, null means default, is sanitized when loaded
|
||||
|
||||
/// Security record note section
|
||||
@@ -429,12 +430,19 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<b>Gender:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=gender;task=input'>[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]</a><BR>"
|
||||
if(gender != NEUTER && pref_species.sexes)
|
||||
dat += "<b>Body Model:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=body_model'>[features["body_model"] == MALE ? "Masculine" : "Feminine"]</a><BR>"
|
||||
dat += "<b>Limb Modification:</b><BR>"
|
||||
dat += "<a href='?_src_=prefs;preference=modify_limbs;task=input'>Modify Limbs</a><BR>"
|
||||
for(var/modification in modified_limbs)
|
||||
if(modified_limbs[modification][1] == LOADOUT_LIMB_PROSTHETIC)
|
||||
dat += "<b>[modification]: [modified_limbs[modification][2]]</b><BR>"
|
||||
else
|
||||
dat += "<b>[modification]: [modified_limbs[modification][1]]</b><BR>"
|
||||
dat += "<BR>"
|
||||
dat += "<b>Species:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=species;task=input'>[pref_species.name]</a><BR>"
|
||||
dat += "<b>Custom Species Name:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=custom_species;task=input'>[custom_species ? custom_species : "None"]</a><BR>"
|
||||
dat += "<b>Random Body:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=all;task=random'>Randomize!</A><BR>"
|
||||
dat += "<b>Always Random Body:</b><a href='?_src_=prefs;preference=all'>[be_random_body ? "Yes" : "No"]</A><BR>"
|
||||
dat += "<br><b>Cycle background:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=cycle_bg;task=input'>[bgstate]</a><BR>"
|
||||
|
||||
var/use_skintones = pref_species.use_skintones
|
||||
if(use_skintones)
|
||||
dat += APPEARANCE_CATEGORY_COLUMN
|
||||
@@ -1235,6 +1243,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
for(var/V in all_quirks)
|
||||
var/datum/quirk/T = SSquirks.quirks[V]
|
||||
bal -= initial(T.value)
|
||||
for(var/modification in modified_limbs)
|
||||
if(modified_limbs[modification][1] == LOADOUT_LIMB_PROSTHETIC)
|
||||
return bal + 1 //max 1 point regardless of how many prosthetics
|
||||
return bal
|
||||
|
||||
/datum/preferences/proc/GetPositiveQuirkCount()
|
||||
@@ -1492,6 +1503,29 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("cycle_bg")
|
||||
bgstate = next_list_item(bgstate, bgstate_options)
|
||||
|
||||
if("modify_limbs")
|
||||
var/limb_type = input(user, "Choose the limb to modify:", "Character Preference") as null|anything in LOADOUT_ALLOWED_LIMB_TARGETS
|
||||
if(limb_type)
|
||||
var/modification_type = input(user, "Choose the modification to the limb:", "Character Preference") as null|anything in LOADOUT_LIMBS
|
||||
if(modification_type)
|
||||
if(modification_type == LOADOUT_LIMB_PROSTHETIC)
|
||||
var/prosthetic_type = input(user, "Choose the type of prosthetic", "Character Preference") as null|anything in (list("prosthetic") + GLOB.prosthetic_limb_types)
|
||||
if(prosthetic_type)
|
||||
var/number_of_prosthetics = 0
|
||||
for(var/modification in modified_limbs)
|
||||
if(modified_limbs[modification][1] == LOADOUT_LIMB_PROSTHETIC)
|
||||
number_of_prosthetics += 1
|
||||
if(number_of_prosthetics >= MAXIMUM_LOADOUT_PROSTHETICS && !(limb_type in modified_limbs && modified_limbs[limb_type][1] == LOADOUT_LIMB_PROSTHETIC))
|
||||
to_chat(user, "<span class='danger'>You can only have up to two prosthetic limbs!</span>")
|
||||
else
|
||||
//save the actual prosthetic data
|
||||
modified_limbs[limb_type] = list(modification_type, prosthetic_type)
|
||||
else
|
||||
if(modification_type == LOADOUT_LIMB_NORMAL)
|
||||
modified_limbs -= limb_type
|
||||
else
|
||||
modified_limbs[limb_type] = list(modification_type)
|
||||
|
||||
if("underwear")
|
||||
var/new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_list
|
||||
if(new_underwear)
|
||||
@@ -2478,7 +2512,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
ShowChoices(user)
|
||||
return 1
|
||||
|
||||
/datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = 1, roundstart_checks = TRUE)
|
||||
/datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = 1, roundstart_checks = TRUE, initial_spawn = FALSE)
|
||||
if(be_random_name)
|
||||
real_name = pref_species.random_name(gender)
|
||||
|
||||
@@ -2573,6 +2607,35 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(custom_speech_verb != "default")
|
||||
character.dna.species.say_mod = custom_speech_verb
|
||||
|
||||
//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
|
||||
for(var/obj/item/bodypart/part in character.bodyparts)
|
||||
if(part.status == BODYPART_ROBOTIC)
|
||||
qdel(part)
|
||||
character.regenerate_limbs() //regenerate limbs so now you only have normal limbs
|
||||
for(var/modified_limb in modified_limbs)
|
||||
var/modification = modified_limbs[modified_limb][1]
|
||||
var/obj/item/bodypart/old_part = character.get_bodypart(modified_limb)
|
||||
if(modification == LOADOUT_LIMB_PROSTHETIC)
|
||||
var/obj/item/bodypart/new_limb
|
||||
switch(modified_limb)
|
||||
if(BODY_ZONE_L_ARM)
|
||||
new_limb = new/obj/item/bodypart/l_arm/robot/surplus(character)
|
||||
if(BODY_ZONE_R_ARM)
|
||||
new_limb = new/obj/item/bodypart/r_arm/robot/surplus(character)
|
||||
if(BODY_ZONE_L_LEG)
|
||||
new_limb = new/obj/item/bodypart/l_leg/robot/surplus(character)
|
||||
if(BODY_ZONE_R_LEG)
|
||||
new_limb = new/obj/item/bodypart/r_leg/robot/surplus(character)
|
||||
var/prosthetic_type = modified_limbs[modified_limb][2]
|
||||
if(prosthetic_type != "prosthetic") //lets just leave the old sprites as they are
|
||||
new_limb.icon = file("icons/mob/augmentation/cosmetic_prosthetic/[prosthetic_type].dmi")
|
||||
new_limb.replace_limb(character)
|
||||
qdel(old_part)
|
||||
|
||||
if(length(modified_limbs))
|
||||
character.regenerate_icons()
|
||||
|
||||
SEND_SIGNAL(character, COMSIG_HUMAN_PREFS_COPIED_TO, src, icon_updates, roundstart_checks)
|
||||
|
||||
@@ -2581,6 +2644,18 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
character.update_body()
|
||||
character.update_hair()
|
||||
|
||||
/datum/preferences/proc/post_copy_to(mob/living/carbon/human/character)
|
||||
//if no legs, and not a paraplegic or a slime, give them a free wheelchair
|
||||
if(modified_limbs[BODY_ZONE_L_LEG] == LOADOUT_LIMB_AMPUTATED && modified_limbs[BODY_ZONE_R_LEG] == LOADOUT_LIMB_AMPUTATED && !character.has_quirk(/datum/quirk/paraplegic) && !isjellyperson(character))
|
||||
if(character.buckled)
|
||||
character.buckled.unbuckle_mob(character)
|
||||
var/turf/T = get_turf(character)
|
||||
var/obj/structure/chair/spawn_chair = locate() in T
|
||||
var/obj/vehicle/ridden/wheelchair/wheels = new(T)
|
||||
if(spawn_chair) // Makes spawning on the arrivals shuttle more consistent looking
|
||||
wheels.setDir(spawn_chair.dir)
|
||||
wheels.buckle_mob(character)
|
||||
|
||||
/datum/preferences/proc/get_default_name(name_id)
|
||||
switch(name_id)
|
||||
if("human")
|
||||
|
||||
@@ -514,6 +514,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["scars3"] >> scars_list["3"]
|
||||
S["scars4"] >> scars_list["4"]
|
||||
S["scars5"] >> scars_list["5"]
|
||||
var/limbmodstr
|
||||
S["modified_limbs"] >> limbmodstr
|
||||
if(length(limbmodstr))
|
||||
modified_limbs = safe_json_decode(limbmodstr)
|
||||
else
|
||||
modified_limbs = list()
|
||||
S["chosen_limb_id"] >> chosen_limb_id
|
||||
S["hide_ckey"] >> hide_ckey //saved per-character
|
||||
|
||||
@@ -845,8 +851,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
|
||||
WRITE_FILE(S["feature_ooc_notes"], features["ooc_notes"])
|
||||
|
||||
WRITE_FILE(S["chosen_limb_id"], chosen_limb_id)
|
||||
|
||||
//Custom names
|
||||
for(var/custom_name_id in GLOB.preferences_custom_names)
|
||||
var/savefile_slot_name = custom_name_id + "_name" //TODO remove this
|
||||
@@ -874,6 +878,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["scars3"] , scars_list["3"])
|
||||
WRITE_FILE(S["scars4"] , scars_list["4"])
|
||||
WRITE_FILE(S["scars5"] , scars_list["5"])
|
||||
if(islist(modified_limbs))
|
||||
WRITE_FILE(S["modified_limbs"] , safe_json_encode(modified_limbs))
|
||||
WRITE_FILE(S["chosen_limb_id"], chosen_limb_id)
|
||||
|
||||
|
||||
//gear loadout
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
var/obj/item/clothing/head/hooded/hood
|
||||
var/hoodtype = /obj/item/clothing/head/hooded/winterhood //so the chaplain hoodie or other hoodies can override this
|
||||
|
||||
/obj/item/clothing/suit/hooded/New()
|
||||
/obj/item/clothing/suit/hooded/Initialize()
|
||||
. = ..()
|
||||
hood = MakeHelmet()
|
||||
..()
|
||||
|
||||
/obj/item/clothing/suit/hooded/Destroy()
|
||||
. = ..()
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
/obj/item/clothing/suit/hooded/update_icon_state()
|
||||
icon_state = "[initial(icon_state)]"
|
||||
if(ishuman(hood.loc))
|
||||
if(ishuman(hood?.loc))
|
||||
var/mob/living/carbon/human/H = hood.loc
|
||||
if(H.head == hood)
|
||||
icon_state += "_t"
|
||||
@@ -131,8 +131,8 @@
|
||||
|
||||
//Hardsuit toggle code
|
||||
/obj/item/clothing/suit/space/hardsuit/Initialize()
|
||||
helmet = MakeHelmet()
|
||||
. = ..()
|
||||
helmet = MakeHelmet()
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/Destroy()
|
||||
if(helmet)
|
||||
|
||||
@@ -267,7 +267,7 @@
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON|USE_TAUR_CLIP_MASK
|
||||
|
||||
/obj/item/clothing/under/costume/christmas/croptop/green
|
||||
name = "green feminine christmas suit"
|
||||
name = "green croptop christmas suit"
|
||||
desc = "A simple green christmas suit. Smells minty!"
|
||||
icon_state = "christmasfemaleg"
|
||||
item_state = "christmasfemaleg"
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
max_occurrences = 1
|
||||
weight = 5
|
||||
gamemode_blacklist = list("dynamic")
|
||||
|
||||
/datum/round_event/anomaly/anomaly_bluespace
|
||||
startWhen = 3
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
min_players = 10
|
||||
max_occurrences = 5
|
||||
weight = 20
|
||||
gamemode_blacklist = list("dynamic")
|
||||
|
||||
/datum/round_event/anomaly/anomaly_flux
|
||||
startWhen = 10
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
max_occurrences = 5
|
||||
weight = 20
|
||||
gamemode_blacklist = list("dynamic")
|
||||
|
||||
|
||||
/datum/round_event/anomaly/anomaly_grav
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
max_occurrences = 5
|
||||
weight = 20
|
||||
gamemode_blacklist = list("dynamic")
|
||||
|
||||
/datum/round_event/anomaly/anomaly_pyro
|
||||
startWhen = 3
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user