Merge remote-tracking branch 'citadel/master' into lettern-git-updates

This commit is contained in:
silicons
2020-10-03 20:52:49 -07:00
711 changed files with 189780 additions and 97095 deletions
+29 -21
View File
@@ -11,7 +11,8 @@ GLOBAL_PROTECT(admin_verbs_default)
/client/proc/investigate_show, /*various admintools for investigation. Such as a singulo grief-log*/
/client/proc/debug_variables, /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/
/client/proc/toggleprayers,
/client/proc/toggleadminhelpsound
/client/proc/toggleadminhelpsound,
/client/proc/debugstatpanel,
)
GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin())
GLOBAL_PROTECT(admin_verbs_admin)
@@ -260,36 +261,36 @@ GLOBAL_PROTECT(admin_verbs_hideable)
control_freak = CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS
var/rights = holder.rank.rights
verbs += GLOB.admin_verbs_default
add_verb(src, GLOB.admin_verbs_default)
if(rights & R_BUILDMODE)
verbs += /client/proc/togglebuildmodeself
add_verb(src, /client/proc/togglebuildmodeself)
if(rights & R_ADMIN)
verbs += GLOB.admin_verbs_admin
add_verb(src, GLOB.admin_verbs_admin)
if(rights & R_BAN)
verbs += GLOB.admin_verbs_ban
add_verb(src, GLOB.admin_verbs_ban)
if(rights & R_FUN)
verbs += GLOB.admin_verbs_fun
add_verb(src, GLOB.admin_verbs_fun)
if(rights & R_SERVER)
verbs += GLOB.admin_verbs_server
add_verb(src, GLOB.admin_verbs_server)
if(rights & R_DEBUG)
verbs += GLOB.admin_verbs_debug
add_verb(src, GLOB.admin_verbs_debug)
if(rights & R_POSSESS)
verbs += GLOB.admin_verbs_possess
add_verb(src, GLOB.admin_verbs_possess)
if(rights & R_PERMISSIONS)
verbs += GLOB.admin_verbs_permissions
add_verb(src, GLOB.admin_verbs_permissions)
if(rights & R_STEALTH)
verbs += /client/proc/stealth
add_verb(src, /client/proc/stealth)
if(rights & R_ADMIN)
verbs += GLOB.admin_verbs_poll
add_verb(src, GLOB.admin_verbs_poll)
if(rights & R_SOUNDS)
verbs += GLOB.admin_verbs_sounds
add_verb(src, GLOB.admin_verbs_sounds)
if(CONFIG_GET(string/invoke_youtubedl))
verbs += /client/proc/play_web_sound
add_verb(src, /client/proc/play_web_sound)
if(rights & R_SPAWN)
verbs += GLOB.admin_verbs_spawn
add_verb(src, GLOB.admin_verbs_spawn)
/client/proc/remove_admin_verbs()
verbs.Remove(
remove_verb(src, list(
GLOB.admin_verbs_default,
/client/proc/togglebuildmodeself,
GLOB.admin_verbs_admin,
@@ -308,14 +309,15 @@ GLOBAL_PROTECT(admin_verbs_hideable)
GLOB.admin_verbs_debug_mapping,
/client/proc/disable_debug_verbs,
/client/proc/readmin
)
))
/client/proc/hide_most_verbs()//Allows you to keep some functionality while hiding some verbs
set name = "Adminverbs - Hide Most"
set category = "Admin"
verbs.Remove(/client/proc/hide_most_verbs, GLOB.admin_verbs_hideable)
verbs += /client/proc/show_verbs
remove_verb(src, GLOB.admin_verbs_hideable)
remove_verb(src, /client/proc/hide_most_verbs)
add_verb(src, /client/proc/show_verbs)
to_chat(src, "<span class='interface'>Most of your adminverbs have been hidden.</span>")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Hide Most Adminverbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -326,7 +328,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
set category = "Admin"
remove_admin_verbs()
verbs += /client/proc/show_verbs
add_verb(src, /client/proc/show_verbs)
to_chat(src, "<span class='interface'>Almost all of your adminverbs have been hidden.</span>")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Hide All Adminverbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -336,7 +338,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
set name = "Adminverbs - Show"
set category = "Admin"
verbs -= /client/proc/show_verbs
remove_verb(src, /client/proc/show_verbs)
add_admin_verbs()
to_chat(src, "<span class='interface'>All of your adminverbs are now visible.</span>")
@@ -724,3 +726,9 @@ GLOBAL_PROTECT(admin_verbs_hideable)
log_admin("[key_name(usr)] has [AI_Interact ? "activated" : "deactivated"] Admin AI Interact")
message_admins("[key_name_admin(usr)] has [AI_Interact ? "activated" : "deactivated"] their AI interaction")
/client/proc/debugstatpanel()
set name = "Debug Stat Panel"
set category = "Debug"
src << output("", "statbrowser:create_debug")
+3 -1
View File
@@ -24,7 +24,9 @@
H.facial_hair_style = random_facial_hair_style(H.gender)
H.hair_color = random_short_color()
H.facial_hair_color = H.hair_color
H.eye_color = random_eye_color()
var/random_eye_color = random_eye_color()
H.left_eye_color = random_eye_color
H.right_eye_color = random_eye_color
H.dna.blood_type = random_blood_type()
H.saved_underwear = H.underwear
H.saved_undershirt = H.undershirt
+4 -2
View File
@@ -91,7 +91,7 @@ GLOBAL_PROTECT(href_token)
var/client/C
if ((C = owner) || (C = GLOB.directory[target]))
disassociate()
C.verbs += /client/proc/readmin
add_verb(C, /client/proc/readmin)
/datum/admins/proc/associate(client/C)
if(IsAdminAdvancedProcCall())
@@ -111,7 +111,8 @@ GLOBAL_PROTECT(href_token)
owner = C
owner.holder = src
owner.add_admin_verbs() //TODO <--- todo what? the proc clearly exists and works since its the backbone to our entire admin system
owner.verbs -= /client/proc/readmin
remove_verb(owner, /client/proc/readmin)
owner.init_verbs() //re-initialize the verb list
GLOB.admins |= C
/datum/admins/proc/disassociate()
@@ -123,6 +124,7 @@ GLOBAL_PROTECT(href_token)
if(owner)
GLOB.admins -= owner
owner.remove_admin_verbs()
owner.init_verbs()
owner.holder = null
owner = null
+18 -4
View File
@@ -397,11 +397,13 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
delete_click = new(null, "INITIALIZING", src)
if(!action_click)
action_click = new(null, "INITIALIZNG", src)
stat("[id] ", delete_click.update("DELETE QUERY | STATE : [text_state()] | ALL/ELIG/FIN \
var/list/L = list()
L[++L.len] = list("[id] ", "[delete_click.update("DELETE QUERY | STATE : [text_state()] | ALL/ELIG/FIN \
[islist(obj_count_all)? length(obj_count_all) : (isnull(obj_count_all)? "0" : obj_count_all)]/\
[islist(obj_count_eligible)? length(obj_count_eligible) : (isnull(obj_count_eligible)? "0" : obj_count_eligible)]/\
[islist(obj_count_finished)? length(obj_count_finished) : (isnull(obj_count_finished)? "0" : obj_count_finished)] - [get_query_text()]"))
stat(" ", action_click.update("[SDQL2_IS_RUNNING? "HALT" : "RUN"]"))
[islist(obj_count_finished)? length(obj_count_finished) : (isnull(obj_count_finished)? "0" : obj_count_finished)] - [get_query_text()]")]", REF(delete_click))
L[++L.len] = list(" ", "[action_click.update("[SDQL2_IS_RUNNING? "HALT" : "RUN"]")]", REF(action_click))
return L
/datum/SDQL2_query/proc/delete_click()
admin_del(usr)
@@ -1189,15 +1191,27 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
return query_list
/obj/effect/statclick/SDQL2_delete/Click()
if(!usr.client?.holder)
message_admins("[key_name_admin(usr)] non-holder clicked on a statclick! ([src])")
log_game("[key_name(usr)] non-holder clicked on a statclick! ([src])")
return
var/datum/SDQL2_query/Q = target
Q.delete_click()
/obj/effect/statclick/SDQL2_action/Click()
if(!usr.client?.holder)
message_admins("[key_name_admin(usr)] non-holder clicked on a statclick! ([src])")
log_game("[key_name(usr)] non-holder clicked on a statclick! ([src])")
return
var/datum/SDQL2_query/Q = target
Q.action_click()
/obj/effect/statclick/SDQL2_VV_all
name = "VIEW VARIABLES"
/obj/effect/statclick/SDQL2_VV_all/Click()
/obj/effect/statclick/sdql2_vv_all/Click()
if(!usr.client?.holder)
message_admins("[key_name_admin(usr)] non-holder clicked on a statclick! ([src])")
log_game("[key_name(usr)] non-holder clicked on a statclick! ([src])")
return
usr.client.debug_variables(GLOB.sdql2_queries)
+16 -7
View File
@@ -89,18 +89,23 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
//Tickets statpanel
/datum/admin_help_tickets/proc/stat_entry()
SHOULD_CALL_PARENT(TRUE)
SHOULD_NOT_SLEEP(TRUE)
var/list/L = list()
var/num_disconnected = 0
stat("Active Tickets:", astatclick.update("[active_tickets.len]"))
L[++L.len] = list("Active Tickets:", "[astatclick.update("[active_tickets.len]")]", null, REF(astatclick))
astatclick.update("[active_tickets.len]")
for(var/I in active_tickets)
var/datum/admin_help/AH = I
if(AH.initiator)
stat("#[AH.id]. [AH.initiator_key_name]:", AH.statclick.update())
L[++L.len] = list("#[AH.id]. [AH.initiator_key_name]:", "[AH.statclick.update()]", REF(AH))
else
++num_disconnected
if(num_disconnected)
stat("Disconnected:", astatclick.update("[num_disconnected]"))
stat("Closed Tickets:", cstatclick.update("[closed_tickets.len]"))
stat("Resolved Tickets:", rstatclick.update("[resolved_tickets.len]"))
L[++L.len] = list("Disconnected:", "[astatclick.update("[num_disconnected]")]", null, REF(astatclick))
L[++L.len] = list("Closed Tickets:", "[cstatclick.update("[closed_tickets.len]")]", null, REF(cstatclick))
L[++L.len] = list("Resolved Tickets:", "[rstatclick.update("[resolved_tickets.len]")]", null, REF(rstatclick))
return L
//Reassociate still open ticket if one exists
/datum/admin_help_tickets/proc/ClientLogin(client/C)
@@ -137,6 +142,10 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
/obj/effect/statclick/ticket_list/Click()
GLOB.ahelp_tickets.BrowseTickets(current_state)
//called by admin topic
/obj/effect/statclick/ticket_list/proc/Action()
Click()
//
//TICKET DATUM
//
@@ -218,7 +227,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
//Removes the ahelp verb and returns it after 2 minutes
/datum/admin_help/proc/TimeoutVerb()
initiator.verbs -= /client/verb/adminhelp
remove_verb(initiator, /client/verb/adminhelp)
initiator.adminhelptimerid = addtimer(CALLBACK(initiator, /client/proc/giveadminhelpverb), 1200, TIMER_STOPPABLE) //2 minute cooldown of admin helps
//private
@@ -490,7 +499,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
//
/client/proc/giveadminhelpverb()
src.verbs |= /client/verb/adminhelp
add_verb(src, /client/verb/adminhelp)
deltimer(adminhelptimerid)
adminhelptimerid = 0
+2 -2
View File
@@ -199,7 +199,7 @@
borg.notify_ai(DISCONNECT)
if(borg.shell)
borg.undeploy()
borg.connected_ai = newai
borg.set_connected_ai(newai)
borg.notify_ai(TRUE)
message_admins("[key_name_admin(user)] slaved [ADMIN_LOOKUPFLW(borg)] to the AI [ADMIN_LOOKUPFLW(newai)].")
log_admin("[key_name(user)] slaved [key_name(borg)] to the AI [key_name(newai)].")
@@ -207,7 +207,7 @@
borg.notify_ai(DISCONNECT)
if(borg.shell)
borg.undeploy()
borg.connected_ai = null
borg.set_connected_ai(null)
message_admins("[key_name_admin(user)] freed [ADMIN_LOOKUPFLW(borg)] from being slaved to an AI.")
log_admin("[key_name(user)] freed [key_name(borg)] from being slaved to an AI.")
if (borg.lawupdate)
+4 -4
View File
@@ -205,15 +205,15 @@ GLOBAL_LIST_EMPTY(dirty_vars)
set name = "Debug verbs - Enable"
if(!check_rights(R_DEBUG))
return
verbs -= /client/proc/enable_debug_verbs
verbs.Add(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping)
remove_verb(src, /client/proc/enable_debug_verbs)
add_verb(src, list(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping))
SSblackbox.record_feedback("tally", "admin_verb", 1, "Enable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/disable_debug_verbs()
set category = "Debug"
set name = "Debug verbs - Disable"
verbs.Remove(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping)
verbs += /client/proc/enable_debug_verbs
remove_verb(src, list(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping))
add_verb(src, /client/proc/enable_debug_verbs)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Disable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/count_objects_on_z_level()
+2 -2
View File
@@ -48,6 +48,6 @@
set desc = "Give this guy possess/release verbs"
set category = "Debug"
set name = "Give Possessing Verbs"
M.verbs += /proc/possess
M.verbs += /proc/release
add_verb(M, /proc/possess)
add_verb(M, /proc/release)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Give Possessing Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+6 -15
View File
@@ -646,23 +646,14 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(!check_rights(R_ADMIN))
return
var/heavy = input("Range of heavy pulse.", text("Input")) as num|null
if(heavy == null)
return
var/light = input("Range of light pulse.", text("Input")) as num|null
if(light == null)
var/range = input("Range.", text("Input")) as num|null
if(!range)
return
log_admin("[key_name(usr)] created an EM Pulse - log below") //because we'll just log the empulse itself
message_admins("[key_name_admin(usr)] created an EM Pulse at [AREACOORD(O)] with range [range]")
empulse_using_range(O, range, TRUE) //its details get shown too
if (heavy || light)
empulse(O, heavy, light)
log_admin("[key_name(usr)] created an EM Pulse ([heavy],[light]) at [AREACOORD(O)]")
message_admins("[key_name_admin(usr)] created an EM Pulse ([heavy],[light]) at [AREACOORD(O)]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "EM Pulse") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
else
return
SSblackbox.record_feedback("tally", "admin_verb", 1, "EM Pulse") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_gib(mob/M in GLOB.mob_list)
set category = "Special Verbs"
@@ -18,7 +18,7 @@
/datum/blobstrain/reagent/electromagnetic_web/death_reaction(obj/structure/blob/B, damage_flag)
if(damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser")
empulse(B.loc, 1, 3) //less than screen range, so you can stand out of range to avoid it
empulse_using_range(B.loc, 5) //less than screen range, so you can stand out of range to avoid it
/datum/reagent/blob/electromagnetic_web
name = "Electromagnetic Web"
@@ -28,6 +28,6 @@
/datum/reagent/blob/electromagnetic_web/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
if(prob(reac_volume*2))
M.emp_act(EMP_LIGHT)
M.emp_act(50)
if(M)
M.apply_damage(reac_volume, BURN, wound_bonus=CANT_WOUND)
@@ -204,7 +204,7 @@
if(severity > 0)
if(overmind)
overmind.blobstrain.emp_reaction(src, severity)
if(prob(100 - severity * 30))
if(prob(severity/1.5))
new /obj/effect/temp_visual/emp(get_turf(src))
/obj/structure/blob/zap_act(power)
@@ -180,10 +180,12 @@
button.screen_loc = DEFAULT_BLOODSPELLS
button.moved = DEFAULT_BLOODSPELLS
button.ordered = FALSE
/datum/action/bloodsucker/passive/Destroy()
if(owner)
Remove(owner)
target = null
return ..()
/////////////////////////////////// TARGETTED POWERS ///////////////////////////////////
@@ -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
@@ -456,6 +456,7 @@
/obj/structure/bloodsucker/candelabrum/Destroy()
STOP_PROCESSING(SSobj, src)
return ..() //return a hint
/obj/structure/bloodsucker/candelabrum/update_icon_state()
icon_state = "candelabrum[lit ? "_lit" : ""]"
@@ -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
@@ -48,6 +48,6 @@
for(var/obj/machinery/light/L in range(5, usr))
L.on = 1
L.break_light_tube()
empulse(get_turf(user), 2, 5, 1)
empulse_using_range(get_turf(user), 8, TRUE)
playsound(get_turf(user), 'sound/effects/lingempscreech.ogg', 75, TRUE, 5, soundenvwet = 0)
return TRUE
@@ -223,7 +223,7 @@
L.flash_act(1, 1)
if(issilicon(target))
var/mob/living/silicon/S = L
S.emp_act(EMP_HEAVY)
S.emp_act(80)
else //for Nar'sian weaklings
to_chat(L, "<span class='heavy_brass'>\"How does it feel to see the light, dog?\"</span>")
L.visible_message("<span class='warning'>[L]'s eyes flare with burning light!</span>", \
@@ -11,7 +11,7 @@
/obj/structure/destructible/clockwork/trap/power_nullifier/activate()
if(!activated)
activated = TRUE
empulse(get_turf(src),1,1,TRUE)
empulse_using_range(get_turf(src),1,TRUE)
/obj/structure/destructible/clockwork/trap/power_nullifier/emp_act(var/strength=1)
activate()
+3 -3
View File
@@ -165,7 +165,7 @@
/datum/action/innate/cult/blood_spell/emp/Activate()
owner.visible_message("<span class='warning'>[owner]'s hand flashes a bright blue!</span>", \
"<span class='cultitalic'>You speak the cursed words, emitting an EMP blast from your hand.</span>")
empulse(owner, 2, 5)
empulse_using_range(owner, 8)
owner.whisper(invocation, language = /datum/language/common)
charges--
if(charges<=0)
@@ -451,7 +451,7 @@
L.flash_act(1,1)
if(issilicon(target))
var/mob/living/silicon/S = L
S.emp_act(EMP_HEAVY)
S.emp_act(80)
else if(iscarbon(target))
var/mob/living/carbon/C = L
C.silent += clamp(12 - C.silent, 0, 6)
@@ -610,7 +610,7 @@
var/prev_color = candidate.color
candidate.color = "black"
if(do_after(user, 90, target = candidate))
candidate.emp_act(EMP_HEAVY)
candidate.emp_act(80)
var/construct_class = alert(user, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer")
user.visible_message("<span class='danger'>The dark cloud receedes from what was formerly [candidate], revealing a\n [construct_class]!</span>")
switch(construct_class)
+12 -6
View File
@@ -142,8 +142,10 @@
if(ishuman(current))
var/mob/living/carbon/human/H = current
var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES)
H.eye_color = eyes?.eye_color || initial(H.eye_color)
H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK)
H.left_eye_color = eyes?.left_eye_color || initial(H.left_eye_color)
H.right_eye_color = eyes?.right_eye_color || initial(H.right_eye_color)
H.dna?.update_ui_block(DNA_LEFT_EYE_COLOR_BLOCK)
H.dna?.update_ui_block(DNA_RIGHT_EYE_COLOR_BLOCK)
REMOVE_TRAIT(H, TRAIT_CULT_EYES, "valid_cultist")
H.update_body()
H.cut_overlays()
@@ -236,8 +238,10 @@
if(ishuman(current))
var/mob/living/carbon/human/H = current
H.eye_color = initial(H.eye_color)
H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK)
H.left_eye_color = initial(H.left_eye_color)
H.right_eye_color = initial(H.right_eye_color)
H.dna?.update_ui_block(DNA_LEFT_EYE_COLOR_BLOCK)
H.dna?.update_ui_block(DNA_RIGHT_EYE_COLOR_BLOCK)
REMOVE_TRAIT(H, TRAIT_CULT_EYES, "valid_cultist")
H.cut_overlays()
H.regenerate_icons()
@@ -312,8 +316,10 @@
/datum/team/cult/proc/rise(cultist)
if(ishuman(cultist))
var/mob/living/carbon/human/H = cultist
H.eye_color = "f00"
H.dna?.update_ui_block(DNA_EYE_COLOR_BLOCK)
H.left_eye_color = "f00"
H.right_eye_color = "f00"
H.dna?.update_ui_block(DNA_LEFT_EYE_COLOR_BLOCK)
H.dna?.update_ui_block(DNA_RIGHT_EYE_COLOR_BLOCK)
ADD_TRAIT(H, TRAIT_CULT_EYES, "valid_cultist")
H.update_body()
@@ -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"
+1 -1
View File
@@ -982,7 +982,7 @@ structure_check() searches for nearby cultist structures required for the invoca
visible_message("<span class='warning'>A colossal shockwave of energy bursts from the rune, disintegrating it in the process!</span>")
for(var/mob/living/L in range(src, 3))
L.DefaultCombatKnockdown(30)
empulse(T, 0.42*(intensity), 1)
empulse_using_range(T, 0.65*(intensity))
var/list/images = list()
var/zmatch = T.z
var/datum/atom_hud/AH = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
@@ -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
@@ -83,17 +83,16 @@ the new instance inside the host to be updated to the template's stats.
to_chat(src, "<span class='warning'>You have [DisplayTimeText(freemove_end - world.time)] to select your first host. Click on a human to select your host.</span>")
/mob/camera/disease/Stat()
/mob/camera/disease/get_status_tab_items()
..()
if(statpanel("Status"))
if(freemove)
stat("Host Selection Time: [round((freemove_end - world.time)/10)]s")
else
stat("Adaptation Points: [points]/[total_points]")
stat("Hosts: [disease_instances.len]")
var/adapt_ready = next_adaptation_time - world.time
if(adapt_ready > 0)
stat("Adaptation Ready: [round(adapt_ready/10, 0.1)]s")
if(freemove)
. += "Host Selection Time: [round((freemove_end - world.time)/10)]s"
else
. += "Adaptation Points: [points]/[total_points]"
. += "Hosts: [disease_instances.len]"
var/adapt_ready = next_adaptation_time - world.time
if(adapt_ready > 0)
. += "Adaptation Ready: [round(adapt_ready/10, 0.1)]s"
/mob/camera/disease/examine(mob/user)
@@ -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)
@@ -247,7 +247,8 @@
if(LH.target && LH.target.stat == DEAD)
to_chat(carbon_user,"<span class='danger'>Your patrons accepts your offer...</span>")
var/mob/living/carbon/human/H = LH.target
H.become_husk()
H.become_husk("burn") //Husks the target with removable husking, but causes a bunch of additional burn damage to prevent it from being 'too easy' to do
H.adjustFireLoss(200)
LH.target = null
var/datum/antagonist/heretic/EC = carbon_user.mind.has_antag_datum(/datum/antagonist/heretic)
@@ -301,3 +302,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 )
@@ -380,8 +424,7 @@
range = -1
include_user = TRUE
charge_max = 300
emp_heavy = 6
emp_light = 10
range = 14
sound = 'sound/effects/lingscreech.ogg'
/obj/effect/proc_holder/spell/aoe_turf/fire_cascade
@@ -430,7 +473,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 +638,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."
@@ -30,7 +30,8 @@
if(visualsOnly)
return
H.fully_replace_character_name(null,"Waldo")
H.eye_color = "000"
H.left_eye_color = "000"
H.right_eye_color = "000"
H.gender = MALE
H.skin_tone = "caucasian3"
H.hair_style = "Business Hair 3"
+9 -10
View File
@@ -130,12 +130,11 @@
update_spooky_icon()
update_health_hud()
/mob/living/simple_animal/revenant/Stat()
..()
if(statpanel("Status"))
stat(null, "Current essence: [essence]/[essence_regen_cap]E")
stat(null, "Stolen essence: [essence_accumulated]E")
stat(null, "Stolen perfect souls: [perfectsouls]")
/mob/living/simple_animal/revenant/get_status_tab_items()
. = ..()
. += "Current essence: [essence]/[essence_regen_cap]E"
. += "Stolen essence: [essence_accumulated]E"
. += "Stolen perfect souls: [perfectsouls]"
/mob/living/simple_animal/revenant/update_health_hud()
if(hud_used)
@@ -391,7 +390,7 @@
if(old_key)
for(var/mob/M in GLOB.dead_mob_list)
if(M.client && M.client.key == old_key) //Only recreates the mob if the mob the client is in is dead
M.transfer_ckey(revenant.key, FALSE)
M.transfer_ckey(revenant, FALSE)
key_of_revenant = TRUE
break
if(!key_of_revenant)
@@ -404,7 +403,7 @@
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return
var/mob/C = pick(candidates)
C.transfer_ckey(revenant.key, FALSE)
C.transfer_ckey(revenant, FALSE)
if(!revenant.key)
qdel(revenant)
message_admins("No ckey was found for the new revenant. Oh well!")
@@ -412,8 +411,8 @@
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return
message_admins("[key_of_revenant] has been [old_key == revenant.key ? "re":""]made into a revenant by reforming ectoplasm.")
log_game("[key_of_revenant] was [old_key == revenant.key ? "re":""]made as a revenant by reforming ectoplasm.")
message_admins("[revenant.key] has been [old_key == revenant.key ? "re":""]made into a revenant by reforming ectoplasm.")
log_game("[revenant.key] was [old_key == revenant.key ? "re":""]made as a revenant by reforming ectoplasm.")
visible_message("<span class='revenboldnotice'>[src] suddenly rises into the air before fading away.</span>")
revenant.essence = essence
@@ -5,7 +5,7 @@
ShiftClickOn(A)
return
if(modifiers["alt"])
altclick_listed_turf(A)
AltClickNoInteract(src, A)
return
if(ishuman(A))
@@ -300,7 +300,7 @@
continue
to_chat(human, "<span class='revenwarning'>You feel [pick("your sense of direction flicker out", "a stabbing pain in your head", "your mind fill with static")].</span>")
new /obj/effect/temp_visual/revenant(human.loc)
human.emp_act(EMP_HEAVY)
human.emp_act(80)
for(var/obj/thing in T)
if(istype(thing, /obj/machinery/power/apc) || istype(thing, /obj/machinery/power/smes)) //Doesn't work on SMES and APCs, to prevent kekkery
continue
@@ -310,12 +310,12 @@
thing.emag_act(null)
else
if(!istype(thing, /obj/machinery/clonepod)) //I hate everything but mostly the fact there's no better way to do this without just not affecting it at all
thing.emp_act(EMP_HEAVY)
thing.emp_act(80)
for(var/mob/living/silicon/robot/S in T) //Only works on cyborgs, not AI
playsound(S, 'sound/machines/warning-buzzer.ogg', 50, 1)
new /obj/effect/temp_visual/revenant(S.loc)
S.spark_system.start()
S.emp_act(EMP_HEAVY)
S.emp_act(80)
//Blight: Infects nearby humans and in general messes living stuff up.
/obj/effect/proc_holder/spell/aoe_turf/revenant/blight
@@ -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
+1 -1
View File
@@ -109,7 +109,7 @@
/mob/living/simple_animal/hostile/swarmer/Initialize()
. = ..()
verbs -= /mob/living/verb/pulled
remove_verb(src, /mob/living/verb/pulled)
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
diag_hud.add_to_hud(src)
@@ -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
@@ -49,7 +49,7 @@
/datum/traitor_class/ai/on_removal(datum/antagonist/traitor/T)
var/mob/living/silicon/ai/A = T.owner.current
A.set_zeroth_law("")
A.verbs -= /mob/living/silicon/ai/proc/choose_modules
remove_verb(A, /mob/living/silicon/ai/proc/choose_modules)
A.malf_picker.remove_malf_verbs(A)
qdel(A.malf_picker)
@@ -23,18 +23,23 @@
maroon_objective.find_target()
T.add_objective(maroon_objective)
else
if(prob(15) && !(locate(/datum/objective/download) in T.objectives) && !(T.owner.assigned_role in list("Research Director", "Scientist", "Roboticist")))
var/datum/objective/download/download_objective = new
download_objective.owner = T.owner
download_objective.gen_amount_goal()
T.add_objective(download_objective)
else if(prob(70)) // cum. not counting download: 40%.
var/datum/objective/steal/steal_objective = new
steal_objective.owner = T.owner
steal_objective.find_target()
T.add_objective(steal_objective)
else
var/datum/objective/sabotage/sabotage_objective = new
sabotage_objective.owner = T.owner
sabotage_objective.find_target()
T.add_objective(sabotage_objective)
var/list/weights = list()
weights["sabo"] = length(subtypesof(/datum/sabotage_objective))
weights["steal"] = length(subtypesof(/datum/objective_item/steal))
weights["download"] = !(locate(/datum/objective/download) in T.objectives || (T.owner.assigned_role in list("Research Director", "Scientist", "Roboticist")))
switch(pickweight(weights))
if("sabo")
var/datum/objective/sabotage/sabotage_objective = new
sabotage_objective.owner = T.owner
sabotage_objective.find_target()
T.add_objective(sabotage_objective)
if("steal")
var/datum/objective/steal/steal_objective = new
steal_objective.owner = T.owner
steal_objective.find_target()
T.add_objective(steal_objective)
if("download")
var/datum/objective/download/download_objective = new
download_objective.owner = T.owner
download_objective.gen_amount_goal()
T.add_objective(download_objective)
@@ -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.
+2 -2
View File
@@ -11,7 +11,7 @@
var/hidden_socks = FALSE
//Mob procs
/mob/living/carbon/human/proc/underwear_toggle()
/mob/living/carbon/human/verb/underwear_toggle()
set name = "Toggle undergarments"
set category = "IC"
@@ -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
+7 -17
View File
@@ -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) / (10 SECONDS)) * 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()
+3 -5
View File
@@ -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)
+11 -11
View File
@@ -3,21 +3,21 @@
/datum/asset/simple/tgui_common
keep_local_name = TRUE
assets = list(
"tgui-common.chunk.js" = 'tgui/packages/tgui/public/tgui-common.chunk.js',
"tgui-common.chunk.js" = 'tgui/public/tgui-common.chunk.js',
)
/datum/asset/simple/tgui
keep_local_name = TRUE
assets = list(
"tgui.bundle.js" = 'tgui/packages/tgui/public/tgui.bundle.js',
"tgui.bundle.css" = 'tgui/packages/tgui/public/tgui.bundle.css',
"tgui.bundle.js" = 'tgui/public/tgui.bundle.js',
"tgui.bundle.css" = 'tgui/public/tgui.bundle.css',
)
/datum/asset/simple/tgui_panel
keep_local_name = TRUE
assets = list(
"tgui-panel.bundle.js" = 'tgui/packages/tgui/public/tgui-panel.bundle.js',
"tgui-panel.bundle.css" = 'tgui/packages/tgui/public/tgui-panel.bundle.css',
"tgui-panel.bundle.js" = 'tgui/public/tgui-panel.bundle.js',
"tgui-panel.bundle.css" = 'tgui/public/tgui-panel.bundle.css',
)
/datum/asset/simple/headers
@@ -113,15 +113,15 @@
)
/datum/asset/simple/IRV
/datum/asset/simple/irv
assets = list(
"jquery-ui.custom-core-widgit-mouse-sortable-min.js" = 'html/IRV/jquery-ui.custom-core-widgit-mouse-sortable-min.js',
)
/datum/asset/group/IRV
/datum/asset/group/irv
children = list(
/datum/asset/simple/jquery,
/datum/asset/simple/IRV
/datum/asset/simple/irv
)
/datum/asset/simple/namespaced/changelog
@@ -247,6 +247,7 @@
"clownthanks" = 'icons/UI_Icons/Achievements/Misc/clownthanks.png',
"rule8" = 'icons/UI_Icons/Achievements/Misc/rule8.png',
"snail" = 'icons/UI_Icons/Achievements/Misc/snail.png',
"ascension" = 'icons/UI_Icons/Achievements/Misc/ascension.png',
"mining" = 'icons/UI_Icons/Achievements/Skills/mining.png',
"assistant" = 'icons/UI_Icons/Achievements/Mafia/assistant.png',
"changeling" = 'icons/UI_Icons/Achievements/Mafia/changeling.png',
@@ -263,7 +264,8 @@
"psychologist" = 'icons/UI_Icons/Achievements/Mafia/psychologist.png',
"thoughtfeeder" = 'icons/UI_Icons/Achievements/Mafia/thoughtfeeder.png',
"traitor" = 'icons/UI_Icons/Achievements/Mafia/traitor.png',
"basemafia" ='icons/UI_Icons/Achievements/basemafia.png'
"basemafia" ='icons/UI_Icons/Achievements/basemafia.png',
"frenching" = 'icons/UI_Icons/Achievements/Misc/frenchingthebubble.png'
)
*/
@@ -447,11 +449,9 @@
Insert("polycrystal", 'icons/obj/telescience.dmi', "polycrystal")
..()
/datum/asset/spritesheet/mafia
name = "mafia"
/datum/asset/spritesheet/mafia/register()
InsertAll("", 'icons/obj/mafia.dmi')
..()
@@ -43,10 +43,10 @@
return "[url][get_asset_suffex(asset_cache_item)]"
/datum/asset_transport/webroot/proc/get_asset_suffex(datum/asset_cache_item/asset_cache_item)
var/base = ""
var/base = "[copytext(asset_cache_item.hash, 1, 3)]/"
var/filename = "asset.[asset_cache_item.hash][asset_cache_item.ext]"
if (length(asset_cache_item.namespace))
base = "namespaces/[asset_cache_item.namespace]/"
base = "namespaces/[copytext(asset_cache_item.namespace, 1, 3)]/[asset_cache_item.namespace]/"
if (!asset_cache_item.namespace_parent)
filename = "[asset_cache_item.name]"
return base + filename
@@ -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
@@ -196,7 +196,7 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
//Compares sample to self to see if within acceptable ranges that group processing may be enabled
//Returns: a string indicating what check failed, or "" if check passes
/datum/gas_mixture/proc/react(turf/open/dump_location)
/datum/gas_mixture/proc/react(datum/holder)
//Performs various reactions such as combustion or fusion (LOL)
//Returns: 1 if any reaction took place; 0 otherwise
@@ -243,7 +243,7 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
set_moles(path, text2num(gas[id]))
archive()
return 1
/*
/datum/gas_mixture/react(datum/holder)
. = NO_REACTION
if(!total_moles())
@@ -291,7 +291,7 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
. |= reaction.react(src, holder)
if (. & STOP_REACTIONS)
break
*/
//Takes the amount of the gas you want to PP as an argument
//So I don't have to do some hacky switches/defines/magic strings
//eg:
@@ -186,6 +186,20 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g
moles_visible = MOLES_GAS_VISIBLE * 60
rarity = 250
/datum/gas/methane
id = "methane"
specific_heat = 30
name = "Methane"
rarity = 320
/datum/gas/methyl_bromide
id = "methyl_bromide"
specific_heat = 42
name = "Methyl Bromide"
dangerous = TRUE
rarity = 310
/obj/effect/overlay/gas
icon = 'icons/effects/atmospherics.dmi'
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
@@ -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
@@ -236,7 +275,7 @@
for (var/gas_id in air.get_gases())
gas_power += (gas_fusion_powers[gas_id]*air.get_moles(gas_id))
var/instability = MODULUS((gas_power*INSTABILITY_GAS_POWER_FACTOR)**2,toroidal_size) //Instability effects how chaotic the behavior of the reaction is
cached_scan_results[id] = instability//used for analyzer feedback
cached_scan_results["fusion"] = instability//used for analyzer feedback
var/plasma = (initial_plasma-FUSION_MOLE_THRESHOLD)/(scale_factor) //We have to scale the amounts of carbon and plasma down a significant amount in order to show the chaotic dynamics we want
var/carbon = (initial_carbon-FUSION_MOLE_THRESHOLD)/(scale_factor) //We also subtract out the threshold amount to make it harder for fusion to burn itself out.
@@ -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 ..()
@@ -97,7 +97,7 @@
/datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
/datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000),
/datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10),
/datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5),
/datum/gas/miasma = new/datum/tlv(-1, -1, 2, 5),
/datum/gas/plasma = new/datum/tlv/dangerous,
/datum/gas/nitrous_oxide = new/datum/tlv/dangerous,
/datum/gas/bz = new/datum/tlv/dangerous,
@@ -106,7 +106,9 @@
/datum/gas/tritium = new/datum/tlv/dangerous,
/datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects
/datum/gas/nitryl = new/datum/tlv/dangerous,
/datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
/datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
/datum/gas/methane = new/datum/tlv(-1, -1, 3, 6),
/datum/gas/methyl_bromide = new/datum/tlv/dangerous
)
/obj/machinery/airalarm/server // No checks here.
@@ -125,7 +127,9 @@
/datum/gas/tritium = new/datum/tlv/no_checks,
/datum/gas/stimulum = new/datum/tlv/no_checks,
/datum/gas/nitryl = new/datum/tlv/no_checks,
/datum/gas/pluoxium = new/datum/tlv/no_checks
/datum/gas/pluoxium = new/datum/tlv/no_checks,
/datum/gas/methane = new/datum/tlv/no_checks,
/datum/gas/methyl_bromide = new/datum/tlv/no_checks
)
/obj/machinery/airalarm/kitchen_cold_room // Copypasta: to check temperatures.
@@ -144,7 +148,9 @@
/datum/gas/tritium = new/datum/tlv/dangerous,
/datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects
/datum/gas/nitryl = new/datum/tlv/dangerous,
/datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
/datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
/datum/gas/methane = new/datum/tlv(-1, -1, 3, 6),
/datum/gas/methyl_bromide = new/datum/tlv/dangerous
)
/obj/machinery/airalarm/unlocked
@@ -542,7 +548,9 @@
/datum/gas/tritium,
/datum/gas/bz,
/datum/gas/stimulum,
/datum/gas/pluoxium
/datum/gas/pluoxium,
/datum/gas/methane,
/datum/gas/methyl_bromide
),
"scrubbing" = 1,
"widenet" = 1,
@@ -206,7 +206,7 @@
. = other_airs + air
if(null in .)
stack_trace("[src]([REF(src)]) has one or more null gas mixtures, which may cause bugs. Null mixtures will not be considered in reconcile_air().")
return removeNullsFromList(.)
return listclearnulls(.)
/datum/pipeline/proc/reconcile_air()
var/list/datum/gas_mixture/GL = list()
@@ -50,7 +50,9 @@
"stimulum" = /obj/machinery/portable_atmospherics/canister/stimulum,
"pluoxium" = /obj/machinery/portable_atmospherics/canister/pluoxium,
"caution" = /obj/machinery/portable_atmospherics/canister,
"miasma" = /obj/machinery/portable_atmospherics/canister/miasma
"miasma" = /obj/machinery/portable_atmospherics/canister/miasma,
"methane" = /obj/machinery/portable_atmospherics/canister/methane,
"methyl bromide" = /obj/machinery/portable_atmospherics/canister/methyl_bromide
)
/obj/machinery/portable_atmospherics/canister/interact(mob/user)
@@ -62,7 +64,7 @@
/obj/machinery/portable_atmospherics/canister/nitrogen
name = "n2 canister"
desc = "Nitrogen gas. Reportedly useful for something."
desc = "Nitrogen. Reportedly useful for something."
icon_state = "red"
gas_type = /datum/gas/nitrogen
@@ -80,19 +82,19 @@
/obj/machinery/portable_atmospherics/canister/toxins
name = "plasma canister"
desc = "Plasma gas. The reason YOU are here. Highly toxic."
desc = "Plasma. The reason YOU are here. Highly toxic."
icon_state = "orange"
gas_type = /datum/gas/plasma
/obj/machinery/portable_atmospherics/canister/bz
name = "\improper BZ canister"
desc = "BZ, a powerful hallucinogenic nerve agent."
desc = "BZ. A powerful hallucinogenic nerve agent."
icon_state = "purple"
gas_type = /datum/gas/bz
/obj/machinery/portable_atmospherics/canister/nitrous_oxide
name = "n2o canister"
desc = "Nitrous oxide gas. Known to cause drowsiness."
desc = "Nitrous oxide. Known to cause drowsiness."
icon_state = "redws"
gas_type = /datum/gas/nitrous_oxide
@@ -115,7 +117,7 @@
/obj/machinery/portable_atmospherics/canister/nitryl
name = "nitryl canister"
desc = "Nitryl gas. Feels great 'til the acid eats your lungs."
desc = "Nitryl. Feels great 'til the acid eats your lungs."
icon_state = "brown"
gas_type = /datum/gas/nitryl
@@ -133,7 +135,7 @@
/obj/machinery/portable_atmospherics/canister/water_vapor
name = "water vapor canister"
desc = "Water Vapor. We get it, you vape."
desc = "Water vapor. We get it, you vape."
icon_state = "water_vapor"
gas_type = /datum/gas/water_vapor
filled = 1
@@ -145,6 +147,18 @@
gas_type = /datum/gas/miasma
filled = 1
/obj/machinery/portable_atmospherics/canister/methane
name = "methane canister"
desc = "Methane. The simplest of hydrocarbons. Non-toxic but highly flammable."
icon_state = "greyblackred"
gas_type = /datum/gas/methane
/obj/machinery/portable_atmospherics/canister/methyl_bromide
name = "methyl bromide canister"
desc = "Methyl bromide. A potent toxin to most, essential for the Kharmaan to live."
icon_state = "purplecyan"
gas_type = /datum/gas/methyl_bromide
/obj/machinery/portable_atmospherics/canister/proc/get_time_left()
if(timing)
. = round(max(0, valve_timer - world.time) / 10, 1)
@@ -63,9 +63,9 @@
if(. & EMP_PROTECT_SELF)
return
if(is_operational())
if(prob(50 / severity))
if(prob(severity/2))
on = !on
if(prob(100 / severity))
if(prob(severity))
direction = PUMP_OUT
pump.target_pressure = rand(0, 100 * ONE_ATMOSPHERE)
update_icon()
@@ -80,7 +80,6 @@
else if(on && holding && direction == PUMP_OUT)
investigate_log("[key_name(user)] started a transfer into [holding].", INVESTIGATE_ATMOS)
/obj/machinery/portable_atmospherics/pump/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
@@ -58,7 +58,7 @@
if(. & EMP_PROTECT_SELF)
return
if(is_operational())
if(prob(50 / severity))
if(prob(severity/3))
on = !on
update_icon()
+10 -12
View File
@@ -11,15 +11,15 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
/datum/gateway_destination
var/name = "Unknown Destination"
var/wait = 0 /// How long after roundstart this destination becomes active
var/enabled = TRUE /// If disabled, the destination won't be availible
var/enabled = TRUE /// If disabled, the destination won't be available
var/hidden = FALSE /// Will not show on gateway controls at all.
/* Can a gateway link to this destination right now. */
/datum/gateway_destination/proc/is_availible()
/datum/gateway_destination/proc/is_available()
return enabled && (world.time - SSticker.round_start_time >= wait)
/* Returns user-friendly description why you can't connect to this destination, displayed in UI */
/datum/gateway_destination/proc/get_availible_reason()
/datum/gateway_destination/proc/get_available_reason()
. = "Unreachable"
if(world.time - SSticker.round_start_time < wait)
. = "Connection desynchronized. Recalibration in progress."
@@ -52,8 +52,8 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
. = list()
.["ref"] = REF(src)
.["name"] = name
.["availible"] = is_availible()
.["reason"] = get_availible_reason()
.["available"] = is_available()
.["reason"] = get_available_reason()
if(wait)
.["timeout"] = max(1 - (wait - (world.time - SSticker.round_start_time)) / wait, 0)
@@ -72,10 +72,10 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
if(target_gateway.target == deactivated.destination)
target_gateway.deactivate()
/datum/gateway_destination/gateway/is_availible()
/datum/gateway_destination/gateway/is_available()
return ..() && target_gateway.calibrated && !target_gateway.target && target_gateway.powered()
/datum/gateway_destination/gateway/get_availible_reason()
/datum/gateway_destination/gateway/get_available_reason()
. = ..()
if(!target_gateway.calibrated)
. = "Exit gateway malfunction. Manual recalibration required."
@@ -217,8 +217,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
target = D
target.activate(destination)
generate_bumper()
if(use_power == IDLE_POWER_USE)
use_power = ACTIVE_POWER_USE
use_power = ACTIVE_POWER_USE
update_icon()
/obj/machinery/gateway/proc/Transfer(atom/movable/AM)
@@ -261,8 +260,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
if(!GLOB.the_gateway)
to_chat(user,"<span class='warning'>Home gateway is not responding!</span>")
if(GLOB.the_gateway.target)
to_chat(user,"<span class='warning'>Home gateway already in use!</span>")
return
GLOB.the_gateway.deactivate() //this will turn the home gateway off so that it's free for us to connect to
activate(GLOB.the_gateway.destination)
else
deactivate()
@@ -319,7 +317,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
/obj/machinery/computer/gateway_control/proc/try_to_connect(datum/gateway_destination/D)
if(!D || !G)
return
if(!D.is_availible() || G.target)
if(!D.is_available() || G.target)
return
G.activate(D)
@@ -105,7 +105,7 @@
if("Immortality")
to_chat(user, "<B>Your wish is granted, but at a terrible cost...</B>")
to_chat(user, "The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart.")
user.verbs += /mob/living/carbon/proc/immortality
add_verb(user, /mob/living/carbon/proc/immortality)
user.set_species(/datum/species/shadow)
if("To Kill")
to_chat(user, "<B>Your wish is granted, but at a terrible cost...</B>")
+2 -2
View File
@@ -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)
+11
View File
@@ -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!"
@@ -344,6 +351,10 @@
name = "Black Carpet Single-Pack"
contains = list(/obj/item/stack/tile/carpet/black/fifty)
/datum/supply_pack/misc/carpet/arcade
name = "Arcade Carpet Single-Pack"
contains = list(/obj/item/stack/tile/carpet/arcade/fifty)
/datum/supply_pack/misc/carpet/premium
name = "Monochrome Carpet Single-Pack"
desc = "Exotic carpets for all your decorating needs. This 30 units stack of extra soft carpet will tie any room together."
+46
View File
@@ -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
+21
View File
@@ -7,6 +7,9 @@
////////////////
//ADMIN THINGS//
////////////////
/// hides the byond verb panel as we use our own custom version
show_verb_panel = FALSE
///Contains admin info. Null if client is not an admin.
var/datum/admins/holder = null
var/datum/click_intercept = null // Needs to implement InterceptClickOn(user,params,atom) proc
var/AI_Interact = 0
@@ -123,6 +126,23 @@
/// Messages currently seen by this client
var/list/seen_messages
/// datum wrapper for client view
var/datum/view_data/view_size
/// our current tab
var/stat_tab
/// whether our browser is ready or not yet
var/statbrowser_ready = FALSE
/// list of all tabs
var/list/panel_tabs = list()
/// list of tabs containing spells and abilities
var/list/spell_tabs = list()
/// list of tabs containing verbs
var/list/verb_tabs = list()
///A lazy list of atoms we've examined in the last EXAMINE_MORE_TIME (default 1.5) seconds, so that we will call [atom/proc/examine_more()] instead of [atom/proc/examine()] on them when examining
var/list/recent_examines
///When was the last time we warned them about not cryoing without an ahelp, set to -5 minutes so that rounstart cryo still warns
@@ -152,3 +172,4 @@
//world.time of when the crew manifest can be accessed
var/crew_manifest_delay
+24 -4
View File
@@ -237,7 +237,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
debug_tools_allowed = TRUE
//END CITADEL EDIT
else if(GLOB.deadmins[ckey])
verbs += /client/proc/readmin
add_verb(src, /client/proc/readmin)
connecting_admin = TRUE
if(CONFIG_GET(flag/autoadmin))
if(!GLOB.admin_datums[ckey])
@@ -275,7 +275,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
fps = prefs.clientfps //(prefs.clientfps < 0) ? RECOMMENDED_FPS : prefs.clientfps
if(fexists(roundend_report_file()))
verbs += /client/proc/show_previous_roundend_report
add_verb(src, /client/proc/show_previous_roundend_report)
var/full_version = "[byond_version].[byond_build ? byond_build : "xxx"]"
log_access("Login: [key_name(src)] from [address ? address : "localhost"]-[computer_id] || BYOND v[full_version]")
@@ -342,6 +342,8 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
// Initialize tgui panel
tgui_panel.initialize()
src << browse(file('html/statbrowser.html'), "window=statbrowser")
if(alert_mob_dupe_login)
spawn()
@@ -857,9 +859,9 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
/client/proc/add_verbs_from_config()
if(CONFIG_GET(flag/see_own_notes))
verbs += /client/proc/self_notes
add_verb(src, /client/proc/self_notes)
if(CONFIG_GET(flag/use_exp_tracking))
verbs += /client/proc/self_playtime
add_verb(src, /client/proc/self_playtime)
#undef UPLOAD_LIMIT
@@ -1001,3 +1003,21 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
/client/proc/can_have_part(part_name)
return prefs.pref_species.mutant_bodyparts[part_name] || (part_name in GLOB.unlocked_mutant_parts)
/// compiles a full list of verbs and sends it to the browser
/client/proc/init_verbs()
if(IsAdminAdvancedProcCall())
return
var/list/verblist = list()
verb_tabs.Cut()
for(var/thing in (verbs + mob?.verbs))
var/procpath/verb_to_init = thing
if(!verb_to_init)
continue
if(verb_to_init.hidden)
continue
if(!istext(verb_to_init.category))
continue
verb_tabs |= verb_to_init.category
verblist[++verblist.len] = list(verb_to_init.category, verb_to_init.name)
src << output("[url_encode(json_encode(verb_tabs))];[url_encode(json_encode(verblist))]", "statbrowser:init_verbs")
+129 -25
View File
@@ -8,6 +8,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/client/parent
//doohickeys for savefiles
var/path
var/vr_path
var/default_slot = 1 //Holder so it doesn't default to slot 1, rather the last one used
var/max_save_slots = 16
@@ -95,7 +96,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/facial_hair_color = "000000" //Facial hair color
var/skin_tone = "caucasian1" //Skin color
var/use_custom_skin_tone = FALSE
var/eye_color = "000000" //Eye color
var/left_eye_color = "000000" //Eye color
var/right_eye_color = "000000"
var/split_eye_colors = FALSE
var/datum/species/pref_species = new /datum/species/human() //Mutant race
var/list/features = list("mcolor" = "FFFFFF",
"mcolor2" = "FFFFFF",
@@ -163,6 +166,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 +433,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
@@ -464,15 +475,22 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<b>Sprite Size:</b> <a href='?_src_=prefs;preference=body_size;task=input'>[features["body_size"]*100]%</a><br>"
if((EYECOLOR in pref_species.species_traits) && !(NOEYES in pref_species.species_traits))
if(!use_skintones && !mutant_colors)
dat += APPEARANCE_CATEGORY_COLUMN
dat += "<h3>Eye Color</h3>"
dat += "<span style='border: 1px solid #161616; background-color: #[eye_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=eyes;task=input'>Change</a><BR>"
dat += "</td>"
if(left_eye_color != right_eye_color)
split_eye_colors = TRUE
dat += "<h3>Heterochromia</h3>"
dat += "</b><a style='display:block;width:100px' href='?_src_=prefs;preference=toggle_split_eyes;task=input'>[split_eye_colors ? "Enabled" : "Disabled"]</a>"
if(!split_eye_colors)
dat += "<h3>Eye Color</h3>"
dat += "<span style='border: 1px solid #161616; background-color: #[left_eye_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=eyes;task=input'>Change</a>"
dat += "</td>"
else
dat += "<h3>Left Eye Color</h3>"
dat += "<span style='border: 1px solid #161616; background-color: #[left_eye_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=eye_left;task=input'>Change</a>"
dat += "<h3>Right Eye Color</h3>"
dat += "<span style='border: 1px solid #161616; background-color: #[right_eye_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=eye_right;task=input'>Change</a><BR>"
dat += "</td>"
else if(use_skintones || mutant_colors)
dat += "</td>"
@@ -527,7 +545,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(length(pref_species.allowed_limb_ids))
if(!chosen_limb_id || !(chosen_limb_id in pref_species.allowed_limb_ids))
chosen_limb_id = pref_species.id
chosen_limb_id = pref_species.limbs_id || pref_species.id
dat += "<h3>Body sprite</h3>"
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=bodysprite;task=input'>[chosen_limb_id]</a>"
@@ -1235,6 +1253,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()
@@ -1362,7 +1383,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
socks = random_socks()
socks_color = random_short_color()
if(BODY_ZONE_PRECISE_EYES)
eye_color = random_eye_color()
var/random_eye_color = random_eye_color()
left_eye_color = random_eye_color
right_eye_color = random_eye_color
if("s_tone")
skin_tone = random_skin_tone()
use_custom_skin_tone = null
@@ -1492,6 +1515,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)
@@ -1523,9 +1569,24 @@ GLOBAL_LIST_EMPTY(preferences_datums)
socks_color = sanitize_hexcolor(n_socks_color, 6)
if("eyes")
var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference","#"+eye_color) as color|null
var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference","#"+left_eye_color) as color|null
if(new_eyes)
eye_color = sanitize_hexcolor(new_eyes, 6)
left_eye_color = sanitize_hexcolor(new_eyes, 6)
right_eye_color = sanitize_hexcolor(new_eyes, 6)
if("eye_left")
var/new_eyes = input(user, "Choose your character's left eye colour:", "Character Preference","#"+left_eye_color) as color|null
if(new_eyes)
left_eye_color = sanitize_hexcolor(new_eyes, 6)
if("eye_right")
var/new_eyes = input(user, "Choose your character's right eye colour:", "Character Preference","#"+right_eye_color) as color|null
if(new_eyes)
right_eye_color = sanitize_hexcolor(new_eyes, 6)
if("toggle_split_eyes")
split_eye_colors = !split_eye_colors
right_eye_color = left_eye_color
if("species")
var/result = input(user, "Select a species", "Species Selection") as null|anything in GLOB.roundstart_race_names
@@ -1569,7 +1630,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_mutantcolor)
if(new_mutantcolor == "#000000")
features["mcolor"] = pref_species.default_color
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3]) // mutantcolors must be bright, but only if they affect the skin
features["mcolor"] = sanitize_hexcolor(new_mutantcolor, 6)
else
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -1580,7 +1641,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_mutantcolor)
if(new_mutantcolor == "#000000")
features["mcolor2"] = pref_species.default_color
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3]) // mutantcolors must be bright, but only if they affect the skin
features["mcolor2"] = sanitize_hexcolor(new_mutantcolor, 6)
else
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -1591,7 +1652,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_mutantcolor)
if(new_mutantcolor == "#000000")
features["mcolor3"] = pref_species.default_color
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3]) // mutantcolors must be bright, but only if they affect the skin
features["mcolor3"] = sanitize_hexcolor(new_mutantcolor, 6)
else
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -1907,7 +1968,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_cockcolor)
if(new_cockcolor == "#000000")
features["cock_color"] = pref_species.default_color
else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3])
features["cock_color"] = sanitize_hexcolor(new_cockcolor, 6)
else
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -1947,7 +2008,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_ballscolor)
if(new_ballscolor == "#000000")
features["balls_color"] = pref_species.default_color
else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3])
features["balls_color"] = sanitize_hexcolor(new_ballscolor, 6)
else
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -1974,7 +2035,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_breasts_color)
if(new_breasts_color == "#000000")
features["breasts_color"] = pref_species.default_color
else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3])
features["breasts_color"] = sanitize_hexcolor(new_breasts_color, 6)
else
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -1996,7 +2057,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_vagcolor)
if(new_vagcolor == "#000000")
features["vag_color"] = pref_species.default_color
else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3])
features["vag_color"] = sanitize_hexcolor(new_vagcolor, 6)
else
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -2478,7 +2539,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)
@@ -2502,12 +2563,15 @@ GLOBAL_LIST_EMPTY(preferences_datums)
character.gender = gender
character.age = age
character.eye_color = eye_color
character.left_eye_color = left_eye_color
character.right_eye_color = right_eye_color
var/obj/item/organ/eyes/organ_eyes = character.getorgan(/obj/item/organ/eyes)
if(organ_eyes)
if(!initial(organ_eyes.eye_color))
organ_eyes.eye_color = eye_color
organ_eyes.old_eye_color = eye_color
if(!initial(organ_eyes.left_eye_color))
organ_eyes.left_eye_color = left_eye_color
organ_eyes.right_eye_color = right_eye_color
organ_eyes.old_left_eye_color = left_eye_color
organ_eyes.old_right_eye_color = right_eye_color
character.hair_color = hair_color
character.facial_hair_color = facial_hair_color
character.skin_tone = skin_tone
@@ -2573,6 +2637,34 @@ 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 - But DO NOT delete those that are species-related
for(var/obj/item/bodypart/part in character.bodyparts)
if(part.status == BODYPART_ROBOTIC && !part.render_like_organic)
qdel(part)
character.regenerate_limbs() //regenerate limbs so now you only have normal limbs
for(var/modified_limb in modified_limbs)
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)
character.regenerate_icons()
SEND_SIGNAL(character, COMSIG_HUMAN_PREFS_COPIED_TO, src, icon_updates, roundstart_checks)
@@ -2581,6 +2673,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")
+71 -20
View File
@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
#define SAVEFILE_VERSION_MAX 35
#define SAVEFILE_VERSION_MAX 36
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -204,30 +204,39 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(S["species"] == "lizard")
features["mam_snouts"] = features["snout"]
if(current_version < 36)
left_eye_color = S["eye_color"]
right_eye_color = S["eye_color"]
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
if(!ckey)
return
path = "data/player_saves/[ckey[1]]/[ckey]/[filename]"
vr_path = "data/player_saves/[ckey[1]]/[ckey]/vore"
/datum/preferences/proc/load_preferences()
if(!path)
return 0
return FALSE
if(world.time < loadprefcooldown)
if(istype(parent))
to_chat(parent, "<span class='warning'>You're attempting to load your preferences a little too fast. Wait half a second, then try again.</span>")
return 0
return FALSE
loadprefcooldown = world.time + PREF_SAVELOAD_COOLDOWN
if(!fexists(path))
return 0
return FALSE
var/savefile/S = new /savefile(path)
if(!S)
return 0
return FALSE
S.cd = "/"
var/needs_update = savefile_needs_update(S)
if(needs_update == -2) //fatal, can't load any data
return 0
var/bacpath = "[path].updatebac" //todo: if the savefile version is higher then the server, check the backup, and give the player a prompt to load the backup
if (fexists(bacpath))
fdel(bacpath) //only keep 1 version of backup
fcopy(S, bacpath) //byond helpfully lets you use a savefile for the first arg.
return FALSE
. = TRUE
@@ -289,8 +298,14 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//try to fix any outdated data if necessary
if(needs_update >= 0)
var/bacpath = "[path].updatebac" //todo: if the savefile version is higher then the server, check the backup, and give the player a prompt to load the backup
if (fexists(bacpath))
fdel(bacpath) //only keep 1 version of backup
fcopy(S, bacpath) //byond helpfully lets you use a savefile for the first arg.
update_preferences(needs_update, S) //needs_update = savefile_version if we need an update (positive integer)
//Sanitize
ooccolor = sanitize_ooccolor(sanitize_hexcolor(ooccolor, 6, 1, initial(ooccolor)))
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
@@ -332,7 +347,25 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
verify_keybindings_valid() // one of these days this will runtime and you'll be glad that i put it in a different proc so no one gets their saves wiped
return 1
if(needs_update >= 0) //save the updated version
var/old_default_slot = default_slot
var/old_max_save_slots = max_save_slots
for (var/slot in S.dir) //but first, update all current character slots.
if (copytext(slot, 1, 10) != "character")
continue
var/slotnum = text2num(copytext(slot, 10))
if (!slotnum)
continue
max_save_slots = max(max_save_slots, slotnum) //so we can still update byond member slots after they lose memeber status
default_slot = slotnum
if (load_character()) // this updtates char slots
save_character()
default_slot = old_default_slot
max_save_slots = old_max_save_slots
save_preferences()
return TRUE
/datum/preferences/proc/verify_keybindings_valid()
// Sanitize the actual keybinds to make sure they exist.
@@ -422,17 +455,17 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
/datum/preferences/proc/load_character(slot)
if(!path)
return 0
return FALSE
if(world.time < loadcharcooldown) //This is before the check to see if the filepath exists to ensure that BYOND can't get hung up on read attempts when the hard drive is a little slow
if(istype(parent))
to_chat(parent, "<span class='warning'>You're attempting to load your character a little too fast. Wait half a second, then try again.</span>")
return "SLOW THE FUCK DOWN" //the reason this isn't null is to make sure that people don't have their character slots overridden by random chars if they accidentally double-click a slot
loadcharcooldown = world.time + PREF_SAVELOAD_COOLDOWN
if(!fexists(path))
return 0
return FALSE
var/savefile/S = new /savefile(path)
if(!S)
return 0
return FALSE
S.cd = "/"
if(!slot)
slot = default_slot
@@ -444,7 +477,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S.cd = "/character[slot]"
var/needs_update = savefile_needs_update(S)
if(needs_update == -2) //fatal, can't load any data
return 0
return FALSE
. = TRUE
@@ -462,7 +495,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
pref_species = new newtype
scars_index = rand(1,5)
scars_index = rand(1,5) // WHY
//Character
S["real_name"] >> real_name
@@ -476,7 +509,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["age"] >> age
S["hair_color"] >> hair_color
S["facial_hair_color"] >> facial_hair_color
S["eye_color"] >> eye_color
S["left_eye_color"] >> left_eye_color
S["right_eye_color"] >> right_eye_color
S["use_custom_skin_tone"] >> use_custom_skin_tone
S["skin_tone"] >> skin_tone
S["hair_style_name"] >> hair_style
@@ -514,6 +548,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
@@ -598,8 +638,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["vore_flags"] >> vore_flags
S["vore_taste"] >> vore_taste
S["belly_prefs"] >> belly_prefs
var/char_vr_path = "[vr_path]/character_[default_slot]_v2.json"
if(fexists(char_vr_path))
var/list/json_from_file = json_decode(file2text(char_vr_path))
if(json_from_file)
belly_prefs = json_from_file["belly_prefs"]
//gear loadout
var/text_to_load
S["loadout"] >> text_to_load
@@ -616,6 +659,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
gear_points -= init_cost
//try to fix any outdated data if necessary
//preference updating will handle saving the updated data for us.
if(needs_update >= 0)
update_character(needs_update, S) //needs_update == savefile_version if we need an update (positive integer)
@@ -648,7 +692,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age))
hair_color = sanitize_hexcolor(hair_color, 6, FALSE)
facial_hair_color = sanitize_hexcolor(facial_hair_color, 6, FALSE)
eye_color = sanitize_hexcolor(eye_color, 6, FALSE)
left_eye_color = sanitize_hexcolor(left_eye_color, 6, FALSE)
right_eye_color = sanitize_hexcolor(right_eye_color, 6, FALSE)
var/static/allow_custom_skintones
if(isnull(allow_custom_skintones))
@@ -777,7 +822,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["age"] , age)
WRITE_FILE(S["hair_color"] , hair_color)
WRITE_FILE(S["facial_hair_color"] , facial_hair_color)
WRITE_FILE(S["eye_color"] , eye_color)
WRITE_FILE(S["left_eye_color"] , left_eye_color)
WRITE_FILE(S["right_eye_color"] , right_eye_color)
WRITE_FILE(S["use_custom_skin_tone"] , use_custom_skin_tone)
WRITE_FILE(S["skin_tone"] , skin_tone)
WRITE_FILE(S["hair_style_name"] , hair_style)
@@ -845,8 +891,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
@@ -866,7 +910,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["vore_flags"] , vore_flags)
WRITE_FILE(S["vore_taste"] , vore_taste)
WRITE_FILE(S["belly_prefs"] , belly_prefs)
var/char_vr_path = "[vr_path]/character_[default_slot]_v2.json"
var/belly_prefs_json = safe_json_encode(list("belly_prefs" = belly_prefs))
if(fexists(char_vr_path))
fdel(char_vr_path)
text2file(belly_prefs_json,char_vr_path)
WRITE_FILE(S["persistent_scars"] , persistent_scars)
WRITE_FILE(S["scars1"] , scars_list["1"])
@@ -874,6 +922,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
+6
View File
@@ -280,3 +280,9 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8")
pct += delta
winset(src, "mainwindow.split", "splitter=[pct]")
/client/verb/fix_stat_panel()
set name = "Fix Stat Panel"
set hidden = TRUE
init_verbs()
+2 -2
View File
@@ -373,7 +373,7 @@
/obj/item/clothing/glasses/sunglasses/blindfold/white/update_icon(mob/living/carbon/human/user)
if(ishuman(user) && !colored_before)
add_atom_colour("#[user.eye_color]", FIXED_COLOUR_PRIORITY)
add_atom_colour("#[user.left_eye_color]", FIXED_COLOUR_PRIORITY)
colored_before = TRUE
/obj/item/clothing/glasses/sunglasses/blindfold/white/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
@@ -382,7 +382,7 @@
var/mob/living/carbon/human/H = loc
var/mutable_appearance/M = mutable_appearance('icons/mob/clothing/eyes.dmi', "blindfoldwhite")
M.appearance_flags |= RESET_COLOR
M.color = "#[H.eye_color]"
M.color = "#[H.left_eye_color]"
. += M
/obj/item/clothing/glasses/sunglasses/big
@@ -62,13 +62,12 @@
if(. & EMP_PROTECT_SELF)
return
var/mob/living/carbon/human/user = src.loc
switch(severity)
if(1)
if(activated && user && ishuman(user) && (user.wear_suit == src))
to_chat(user, "<span class='danger'>E:FATAL:RAM_READ_FAIL\nE:FATAL:STACK_EMPTY\nE:FATAL:READ_NULL_POINT\nE:FATAL:PWR_BUS_OVERLOAD</span>")
to_chat(user, "<span class='userdanger'>An electromagnetic pulse disrupts your [name] and violently tears you out of time-bluespace!</span>")
user.emote("scream")
deactivate(1, 1)
if(severity >= 70)
if(activated && user && ishuman(user) && (user.wear_suit == src))
to_chat(user, "<span class='danger'>E:FATAL:RAM_READ_FAIL\nE:FATAL:STACK_EMPTY\nE:FATAL:READ_NULL_POINT\nE:FATAL:PWR_BUS_OVERLOAD</span>")
to_chat(user, "<span class='userdanger'>An electromagnetic pulse disrupts your [name] and violently tears you out of time-bluespace!</span>")
user.emote("scream")
deactivate(1, 1)
/obj/item/clothing/suit/space/chronos/proc/finish_chronowalk(mob/living/carbon/human/user, turf/to_turf)
if(!user)
@@ -525,7 +525,7 @@ Contains:
icon_state = "hunter"
item_state = "swat_suit"
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/kitchen/knife/combat)
armor = list("melee" = 60, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wpound" = 25)
armor = list("melee" = 60, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 25)
strip_delay = 130
resistance_flags = FIRE_PROOF | ACID_PROOF
+17
View File
@@ -102,3 +102,20 @@
/obj/item/clothing/neck/cloak/polychromic/ComponentInitialize()
. = ..()
AddElement(/datum/element/polychromic, poly_colors, 3)
/obj/item/clothing/neck/cloak/alt
name = "cloak"
desc = "A ragged up white cloak. It reminds you of a place not far from here."
icon_state = "cloak"
item_state = "cloak"
/obj/item/clothing/neck/cloak/alt/polychromic
name = "polychromic cloak"
desc = "A ragged up cloak. It reminds you of a place not far from here."
icon_state = "cloak"
item_state = "cloak"
var/list/poly_colors = list("#FFFFFF", "#676767", "#4C4C4C")
/obj/item/clothing/neck/cloak/alt/polychromic/ComponentInitialize()
. = ..()
AddElement(/datum/element/polychromic, poly_colors, 3)
+34 -1
View File
@@ -117,6 +117,27 @@
icon_state = "greydet"
item_state = "greydet"
/obj/item/clothing/suit/det_suit/forensicsred
name = "red forensics coat"
icon_state = "forensics_red"
item_state = "forensics_red"
/obj/item/clothing/suit/det_suit/forensicsred/long
name = "long red forensics coat"
icon_state = "forensics_red_long"
item_state = "forensics_red_long"
/obj/item/clothing/suit/det_suit/forensicsblue
name = "blue forensics coat"
icon_state = "forensics_blue"
item_state = "forensics_blue"
/obj/item/clothing/suit/det_suit/forensicsblue/long
name = "long blue forensics coat"
icon_state = "forensics_blue_long"
item_state = "forensics_blue_long"
//Engineering
/obj/item/clothing/suit/hazardvest
name = "hazard vest"
@@ -222,4 +243,16 @@
desc = "A dark blue vest with reflective strips for emergency medical technicians."
icon_state = "labcoat_emt"
item_state = "labcoat_emt"
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
/obj/item/clothing/suit/toggle/labcoat/emt/red
name = "red emt vest"
desc = "A red vest with reflective strips for emergency medical technicians."
icon_state = "labcoat_emtred"
item_state = "labcoat_emtred"
/obj/item/clothing/suit/toggle/labcoat/emt/highvis
name = "high visibility emt vest"
desc = "a high visibility vest for emergency medical technicians."
icon_state = "labcoat_highvis"
item_state = "labcoat_highvis"
+45
View File
@@ -62,3 +62,48 @@
name = "scientist labcoat"
desc = "A suit that protects against minor chemical spills. Has a purple stripe on the shoulder."
icon_state = "labcoat_tox"
// Departmental Jackets
/obj/item/clothing/suit/toggle/labcoat/depjacket/sci
name = "science jacket"
desc = "A comfortable jacket in science purple."
icon_state = "sci_dep_jacket"
item_state = "sci_dep_jacket"
allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
/obj/item/clothing/suit/toggle/labcoat/depjacket/med
name = "medical jacket"
desc = "A comfortable jacket in medical blue."
icon_state = "med_dep_jacket"
item_state = "med_dep_jacket"
allowed = list(/obj/item/analyzer, /obj/item/sensor_device, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 0, "acid" = 45)
/obj/item/clothing/suit/toggle/labcoat/depjacket/sec
name = "security jacket"
desc = "A comfortable jacket in security red."
icon_state = "sec_dep_jacket"
item_state = "sec_dep_jacket"
armor = list("melee" = 25, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 45)
/obj/item/clothing/suit/toggle/labcoat/depjacket/sup
name = "supply jacket"
desc = "A comfortable jacket in supply brown."
icon_state = "supply_dep_jacket"
item_state = "supply_dep_jacket"
/obj/item/clothing/suit/toggle/labcoat/depjacket/sup/qm
name = "quartermaster's jacket"
desc = "A loose covering often warn by station quartermasters."
icon_state = "qmjacket"
item_state = "qmjacket"
/obj/item/clothing/suit/toggle/labcoat/depjacket/eng
name = "engineering jacket"
desc = "A comfortable jacket in engineering yellow."
icon_state = "engi_dep_jacket"
item_state = "engi_dep_jacket"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 20, "fire" = 30, "acid" = 45)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter)
@@ -94,6 +94,23 @@
flags_inv = HIDEJUMPSUIT
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
/obj/item/clothing/suit/tailcoat
name = "tailcoat"
desc = "A rather impractical, long coat."
icon_state = "tailcoat"
item_state = "tailcoat"
/obj/item/clothing/suit/vickyblack
name = "black victorian coat"
desc = "An overbearing black coat, it looks far older than you are."
icon_state = "vickyblack"
item_state = "vickyblack"
/obj/item/clothing/suit/vickyred
name = "red victorian coat"
desc = "An overbearing red coat, it looks far older than you are."
icon_state = "vickyred"
item_state = "vickyred"
/obj/item/clothing/suit/apron/overalls
name = "coveralls"
@@ -1064,3 +1081,9 @@
desc = "An outfit used by traditional japanese warriors."
icon_state = "samurai"
item_state = "samurai"
/obj/item/clothing/suit/bomber
name = "old bomber jacket"
desc = "It looks like someone dragged this out of a muddy lake."
icon_state = "bomberalt"
item_state = "bomberalt"
+4 -4
View File
@@ -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)
+1 -1
View File
@@ -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"
+15
View File
@@ -23,6 +23,14 @@
body_parts_covered = CHEST|GROIN|ARMS
alt_covers_chest = TRUE
/obj/item/clothing/under/rank/cargo/util
name = "cargo utility uniform"
desc = "a utility uniform for cargo personnel"
icon_state = "utilsupply"
item_state = "utilsupply"
can_adjust = FALSE
/obj/item/clothing/under/rank/cargo/tech/skirt
name = "cargo technician's jumpskirt"
desc = "Skiiiiirts! They're comfy and easy to wear"
@@ -33,6 +41,13 @@
fitted = FEMALE_UNIFORM_TOP
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
/obj/item/clothing/under/rank/cargo/tech/long
name = "cargo technician's jumpsuit (trousers)"
desc = "A variant of the cargo technician's uniform with proper trousers, suited for colder climates and modest workers."
icon_state = "cargo_long"
item_state = "lb_suit"
alt_covers_chest = TRUE
/obj/item/clothing/under/rank/cargo/miner
name = "shaft miner's jumpsuit"
desc = "It's a snappy jumpsuit with a sturdy set of overalls. It is very dirty."
@@ -23,6 +23,68 @@
fitted = FEMALE_UNIFORM_TOP
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
/obj/item/clothing/under/rank/civilian/util
name = "generic utility uniform"
desc = "A utility uniform worn by various crew."
icon_state = "utilgen"
item_state = "utilgen"
can_adjust = FALSE
/obj/item/clothing/under/rank/civilian/util/greyshirt
name = "grey uniform"
desc = "A bland, grey uniform."
icon_state = "greyshirt"
item_state = "greyshirt"
/obj/item/clothing/under/rank/civilian/victorian_redsleeves
name = "black vest red victorian suit"
desc = "A stark red victorian suit with a black vest."
icon_state = "victorianblred"
item_state = "victorianblred"
can_adjust = FALSE
/obj/item/clothing/under/rank/civilian/victorian_redvest
name = "red-vested victorian suit"
desc = "A victorian suit with a red vest."
icon_state = "victorianredvest"
item_state = "victorianredvest"
can_adjust = FALSE
/obj/item/clothing/under/rank/civilian/victorian_vest
name = "black victorian suit"
desc = "A simple black victorian suit."
icon_state = "victorianvest"
item_state = "victorianvest"
can_adjust = FALSE
/obj/item/clothing/under/rank/civilian/victorian_purple
name = "purple victorian suit"
desc = "A victorian suit in regal purple."
icon_state = "victorianlightfire"
item_state = "victorianlightfire"
can_adjust = FALSE
/obj/item/clothing/under/rank/civilian/victorianreddress
name = "red victorian dress"
desc = "A flashy red victorian dress."
icon_state = "victorianreddress"
item_state = "victorianreddress"
can_adjust = FALSE
/obj/item/clothing/under/rank/civilian/victorianblackdress
name = "black victorian dress"
desc = "A victorian dress in somber black."
icon_state = "victorianblackdress"
item_state = "victorianblackdress"
can_adjust = FALSE
/obj/item/clothing/under/rank/civilian/dutch
name = "dutch suit"
desc = "A dapper dutch suit."
icon_state = "dutch"
item_state = "dutch"
can_adjust = FALSE
/obj/item/clothing/under/rank/civilian/chaplain
desc = "It's a black jumpsuit, often worn by religious folk."
name = "chaplain's jumpsuit"
@@ -62,6 +124,12 @@
item_state = "b_suit"
can_adjust = FALSE
/obj/item/clothing/under/rank/civilian/head_of_personnel/whimsy
name = "casual head of personnel's jumpsuit"
desc = "It's a jumpsuit worn by someone who works in the position of \"Head of Personnel\", this one seems to be a bit more casual."
icon_state = "hop_casual"
item_state = "hop_casual"
/obj/item/clothing/under/rank/civilian/head_of_personnel/skirt
name = "head of personnel's jumpskirt"
desc = "It's a jumpskirt worn by someone who works in the position of \"Head of Personnel\"."
@@ -6,6 +6,13 @@
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
/obj/item/clothing/under/rank/captain/util
name = "Command Utiltiy Uniform"
desc = "A utility uniform for command personnel."
icon_state = "utilcom"
item_state = "utilcom"
can_adjust = FALSE
/obj/item/clothing/under/rank/captain/skirt
name = "captain's jumpskirt"
desc = "It's a blue jumpskirt with some gold markings denoting the rank of \"Captain\"."
@@ -42,13 +42,35 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 60, "acid" = 20, "wound" = 5)
resistance_flags = NONE
/obj/item/clothing/under/rank/engineering/engineer/mechanic
name = "mechanic's jumpsuit"
desc = "an old mechanic's jumpsuit"
icon_state = "mechanic"
item_state = "mechanic"
can_adjust = FALSE
/obj/item/clothing/under/rank/engineering/engineer/util
name = "engineering utility uniform"
desc = "a utility jumpsuit for engineering personnel"
icon_state = "utileng"
item_state = "utileng"
can_adjust = FALSE
/obj/item/clothing/under/rank/engineering/engineer/hazard
name = "engineer's hazard jumpsuit"
desc = "A high visibility jumpsuit made from heat and radiation resistant materials."
icon_state = "hazard"
item_state = "suit-orange"
icon_state = "hazard_orange"
item_state = "engi_suit"
alt_covers_chest = TRUE
/obj/item/clothing/under/rank/engineering/engineer/hazard/green
icon_state = "hazard_green"
item_state = "g_suit"
/obj/item/clothing/under/rank/engineering/engineer/hazard/white
icon_state = "hazard_white"
item_state = "gy_suit"
/obj/item/clothing/under/rank/engineering/engineer/skirt
name = "engineer's jumpskirt"
desc = "It's an orange high visibility jumpskirt worn by engineers."
@@ -86,6 +86,12 @@
permeability_coefficient = 0.5
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
/obj/item/clothing/under/rank/medical/paramedic/red
name = "red paramedic jumpsuit"
icon_state = "pmedred"
item_state = "pmedred"
can_adjust = FALSE
/obj/item/clothing/under/rank/medical/paramedic/light
desc = "It's made of a special fiber that provides minor protection against biohazards. It has a dark blue cross on the chest denoting that the wearer is a trained paramedic."
icon_state = "paramedic-light"
@@ -124,6 +130,13 @@
permeability_coefficient = 0.5
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
/obj/item/clothing/under/rank/medical/doctor/util
name = "Medical Utility Uniform"
desc = "Utility jumpsuit for medical personnel"
icon_state = "utilmed"
item_state = "utilmed"
can_adjust = FALSE
/obj/item/clothing/under/rank/medical/doctor/blue
name = "blue medical scrubs"
desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in baby blue."
+13
View File
@@ -61,6 +61,13 @@
permeability_coefficient = 0.5
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
/obj/item/clothing/under/rank/rnd/scientist/util
name = "Science Utility Uniform"
desc = "A utility uniform for science personnel"
icon_state = "utilsci"
item_state = "utilsci"
can_adjust = FALSE
/obj/item/clothing/under/rank/rnd/scientist/skirt
name = "scientist's jumpskirt"
desc = "It's made of a special fiber that provides minor protection against explosives. It has markings that denote the wearer as a scientist."
@@ -78,6 +85,12 @@
item_state = "robotics"
resistance_flags = NONE
/obj/item/clothing/under/rank/rnd/roboticist/sleek
name = "sleek roboticist's jumpsuit"
icon_state = "robosleek"
item_state = "robosleek"
can_adjust = FALSE
/obj/item/clothing/under/rank/rnd/roboticist/skirt
name = "roboticist's jumpskirt"
desc = "It's a slimming black with reinforced seams; great for industrial work."
+40 -1
View File
@@ -21,6 +21,13 @@
item_state = "r_suit"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10)
/obj/item/clothing/under/rank/security/officer/util
name = "security utility uniform"
desc = "a grey security uniform"
icon_state = "utilsec"
item_state = "utilsec"
can_adjust = FALSE
/obj/item/clothing/under/rank/security/officer/grey
name = "grey security jumpsuit"
desc = "A tactical relic of years past before Nanotrasen decided it was cheaper to dye the suits red instead of washing out the blood."
@@ -51,6 +58,28 @@
item_state = "blueshift"
can_adjust = FALSE
/obj/item/clothing/under/rank/security/officer/blueshirt/seccorp
name = "corporate security uniform"
desc = "How positively stuffy."
icon_state = "seccorp"
item_state = "seccorp"
can_adjust = FALSE
/obj/item/clothing/under/rank/security/officer/blueshirt/seccorp/wardencorp
name = "corporate warden uniform"
icon_state = "wardencorp"
item_state = "wardencorp"
/obj/item/clothing/under/rank/security/officer/blueshirt/seccorp/hoscorp
name = "corporate head of security's uniform"
icon_state = "hoscorp"
item_state = "hoscorp"
/obj/item/clothing/under/rank/security/officer/blueshirt/seccorp/detcorp
name = "corporate detective's uniform"
icon_state = "detcorp"
item_state = "detcorp"
/obj/item/clothing/under/rank/security/officer/spacepol
name = "police uniform"
desc = "Space not controlled by megacorporations, planets, or pirates is under the jurisdiction of Spacepol."
@@ -103,6 +132,16 @@
item_state = "det"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10)
/obj/item/clothing/under/rank/security/detective/brown
name = "dark boiled suit"
icon_state = "detectivebrown"
item_state = "detectivebrown"
/obj/item/clothing/under/rank/security/detective/brown/brown2
name = "padded suit"
icon_state = "detectivebrown2"
item_state = "detectivebrown2"
/obj/item/clothing/under/rank/security/detective/skirt
name = "detective's suitskirt"
desc = "Someone who wears this means business."
@@ -202,4 +241,4 @@
desc = "Space not controlled by megacorporations, planets, or pirates is under the jurisdiction of Spacepol."
icon_state = "spacepol"
item_state = "spacepol"
can_adjust = FALSE
can_adjust = FALSE
@@ -325,3 +325,22 @@
desc = "A blue bathrobe."
icon_state = "bathrobe"
item_state = "bathrobe"
/obj/item/clothing/under/misc/mechsuitred
name = "red mech suit"
desc = "What are you, stupid?"
icon_state = "red_mech_suit"
item_state = "red_mech_suit"
/obj/item/clothing/under/misc/mechsuitwhite
name = "white mech suit"
desc = "...Mom?"
icon_state = "white_mech_suit"
item_state = "white_mech_suit"
/obj/item/clothing/under/misc/mechsuitblue
name = "blue mech suit"
desc = "Get in the damn robot already!"
icon_state = "blue_mech_suit"
item_state = "blue_mech_suit"
+16
View File
@@ -116,3 +116,19 @@
/obj/item/clothing/under/suit/polychromic/ComponentInitialize()
. = ..()
AddElement(/datum/element/polychromic, list("#FFFFFF", "#FFFFFF", "#808080"), 3)
/obj/item/clothing/under/suit/turtle
desc = "a debatably stylish turtleneck."
can_adjust = FALSE
/obj/item/clothing/under/suit/turtle/teal
name = "teal turtleneck"
icon_state = "tealturtle"
item_state = "tealturtle"
can_adjust = FALSE
/obj/item/clothing/under/suit/turtle/grey
name = "grey turtleneck"
icon_state = "greyturtle"
item_state = "greyturtle"
can_adjust = FALSE
-1
View File
@@ -4,7 +4,6 @@
max_occurrences = 1
weight = 5
gamemode_blacklist = list("dynamic")
/datum/round_event/anomaly/anomaly_bluespace
startWhen = 3
-1
View File
@@ -5,7 +5,6 @@
min_players = 10
max_occurrences = 5
weight = 20
gamemode_blacklist = list("dynamic")
/datum/round_event/anomaly/anomaly_flux
startWhen = 10
-1
View File
@@ -4,7 +4,6 @@
max_occurrences = 5
weight = 20
gamemode_blacklist = list("dynamic")
/datum/round_event/anomaly/anomaly_grav
-1
View File
@@ -4,7 +4,6 @@
max_occurrences = 5
weight = 20
gamemode_blacklist = list("dynamic")
/datum/round_event/anomaly/anomaly_pyro
startWhen = 3
-1
View File
@@ -5,7 +5,6 @@
min_players = 20
max_occurrences = 2
weight = 5
gamemode_blacklist = list("dynamic")
/datum/round_event/anomaly/anomaly_vortex
startWhen = 10
+12 -4
View File
@@ -3,6 +3,13 @@
typepath = /datum/round_event/brain_trauma
weight = 25
/datum/round_event_control/brain_trauma/canSpawnEvent(var/players_amt, var/gamemode)
var/list/enemy_roles = list("Medical Doctor","Chief Medical Officer","Paramedic")
for (var/mob/M in GLOB.alive_mob_list)
if(M.stat != DEAD && (M.mind?.assigned_role in enemy_roles))
return TRUE
return FALSE
/datum/round_event/brain_trauma
fakeable = FALSE
@@ -16,18 +23,19 @@
continue
if(HAS_TRAIT(H,TRAIT_EXEMPT_HEALTH_EVENTS))
continue
if(!is_station_level(H.z))
continue
traumatize(H)
break
/datum/round_event/brain_trauma/proc/traumatize(mob/living/carbon/human/H)
var/resistance = pick(
65;TRAUMA_RESILIENCE_BASIC,
30;TRAUMA_RESILIENCE_SURGERY,
5;TRAUMA_RESILIENCE_LOBOTOMY)
35;TRAUMA_RESILIENCE_SURGERY)
var/trauma_type = pickweight(list(
BRAIN_TRAUMA_MILD = 60,
BRAIN_TRAUMA_SEVERE = 30,
BRAIN_TRAUMA_MILD = 80,
BRAIN_TRAUMA_SEVERE = 10,
BRAIN_TRAUMA_SPECIAL = 10
))
+1 -2
View File
@@ -5,7 +5,6 @@
min_players = 15
max_occurrences = 1
gamemode_blacklist = list("dynamic")
/datum/round_event/brand_intelligence
announceWhen = 21
@@ -65,7 +64,7 @@
originMachine.visible_message("[originMachine] beeps and seems lifeless.")
kill()
return
vendingMachines = removeNullsFromList(vendingMachines)
vendingMachines = listclearnulls(vendingMachines)
if(!vendingMachines.len) //if every machine is infected
for(var/obj/machinery/vending/upriser in infectedMachines)
if(prob(70) && !QDELETED(upriser))
-1
View File
@@ -5,7 +5,6 @@
min_players = 2
earliest_start = 10 MINUTES
max_occurrences = 6
gamemode_blacklist = list("dynamic")
/datum/round_event/carp_migration
announceWhen = 3
@@ -2,7 +2,6 @@
name = "Communications Blackout"
typepath = /datum/round_event/communications_blackout
weight = 30
gamemode_blacklist = list("dynamic")
/datum/round_event/communications_blackout
announceWhen = 1
@@ -24,4 +23,4 @@
/datum/round_event/communications_blackout/start()
for(var/obj/machinery/telecomms/T in GLOB.telecomms_list)
T.emp_act(EMP_HEAVY)
T.emp_act(80)
+1 -2
View File
@@ -5,7 +5,6 @@
max_occurrences = 1000
earliest_start = 0 MINUTES
alert_observers = FALSE
gamemode_blacklist = list("dynamic")
/datum/round_event/space_dust
startWhen = 1
@@ -29,4 +28,4 @@
fakeable = FALSE
/datum/round_event/sandstorm/tick()
spawn_meteors(10, GLOB.meteorsC)
spawn_meteors(10, GLOB.meteorsC)
-1
View File
@@ -5,7 +5,6 @@
min_players = 5
weight = 40
alert_observers = FALSE
gamemode_blacklist = list("dynamic")
/datum/round_event/electrical_storm
var/lightsoutAmount = 1
+1 -2
View File
@@ -4,7 +4,6 @@
weight = 20
max_occurrences = 2
min_players = 40 // To avoid shafting lowpop
gamemode_blacklist = list("dynamic")
/datum/round_event/heart_attack/start()
var/list/heart_attack_contestants = list()
@@ -20,4 +19,4 @@
var/mob/living/carbon/human/winner = pickweight(heart_attack_contestants)
var/datum/disease/D = new /datum/disease/heart_failure()
winner.ForceContractDisease(D, FALSE, TRUE)
announce_to_ghosts(winner)
announce_to_ghosts(winner)
-1
View File
@@ -3,7 +3,6 @@
/datum/round_event_control/ion_storm
name = "Ion Storm"
typepath = /datum/round_event/ion_storm
gamemode_blacklist = list("dynamic")
weight = 15
min_players = 2
-1
View File
@@ -2,7 +2,6 @@
name = "Major Space Dust"
typepath = /datum/round_event/meteor_wave/major_dust
weight = 8
gamemode_blacklist = list("dynamic")
/datum/round_event/meteor_wave/major_dust
wave_name = "space dust"
+1 -2
View File
@@ -10,7 +10,6 @@
min_players = 15
max_occurrences = 3
earliest_start = 25 MINUTES
gamemode_blacklist = list("dynamic")
/datum/round_event/meteor_wave
startWhen = 6
@@ -23,7 +22,7 @@
/datum/round_event/meteor_wave/setup()
announceWhen = 1
startWhen = rand(90, 180) // Apparently it is by 2 seconds, so 90 is actually 180 seconds, and 180 is 360 seconds. So this is 3-6 minutes
startWhen = 150 // 5 minutes
if(GLOB.singularity_counter)
startWhen *= 1 - min(GLOB.singularity_counter * SINGULO_BEACON_DISTURBANCE, SINGULO_BEACON_MAX_DISTURBANCE)
endWhen = startWhen + 60

Some files were not shown because too many files have changed in this diff Show More