This commit is contained in:
Putnam
2020-01-05 19:12:28 -08:00
100 changed files with 8918 additions and 12230 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+65 -63
View File
@@ -3528,7 +3528,6 @@
pixel_x = -22
},
/obj/structure/rack,
/obj/item/storage/fancy/donut_box,
/obj/item/gun/energy/e_gun/dragnet,
/obj/item/gun/energy/e_gun/dragnet,
/obj/effect/turf_decal/tile/neutral{
@@ -4004,8 +4003,7 @@
dir = 8
},
/obj/structure/rack,
/obj/item/gun/energy/pumpaction/blaster,
/obj/item/gun/energy/pumpaction/blaster,
/obj/item/storage/fancy/donut_box,
/turf/open/floor/plasteel/dark,
/area/ai_monitored/security/armory)
"ahJ" = (
@@ -27117,6 +27115,10 @@
/obj/effect/turf_decal/tile/neutral{
dir = 2
},
/obj/structure/sign/departments/custodian{
pixel_x = 32;
pixel_y = -32
},
/turf/open/floor/plasteel,
/area/hallway/primary/central)
"baI" = (
@@ -83444,6 +83446,10 @@
},
/turf/open/floor/plasteel/white,
/area/science/lab)
"iCn" = (
/obj/machinery/vr_sleeper,
/turf/open/floor/plasteel,
/area/security/prison)
"iLj" = (
/obj/structure/table,
/turf/open/floor/plating,
@@ -83462,6 +83468,16 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel/dark,
/area/crew_quarters/fitness/recreation)
"jhu" = (
/obj/structure/cable/yellow{
icon_state = "1-2"
},
/obj/machinery/door/airlock/public/glass{
id_tag = "permahydro";
name = "Recreation Module"
},
/turf/open/floor/plasteel,
/area/security/prison)
"jwW" = (
/turf/closed/wall/mineral/plastitanium,
/area/crew_quarters/fitness/recreation)
@@ -83519,16 +83535,6 @@
"krD" = (
/turf/closed/wall,
/area/science/circuit)
"kwg" = (
/obj/structure/cable/yellow{
icon_state = "1-2"
},
/obj/machinery/door/airlock/public/glass{
id_tag = "permahydro";
name = "Recreation Module"
},
/turf/open/floor/plasteel,
/area/security/prison)
"kwI" = (
/obj/item/wrench,
/obj/item/clothing/suit/apron,
@@ -83589,10 +83595,6 @@
},
/turf/open/floor/plasteel/white,
/area/science/circuit)
"kRT" = (
/obj/machinery/vr_sleeper,
/turf/open/floor/plasteel,
/area/security/prison)
"kVo" = (
/obj/structure/cable/yellow{
icon_state = "1-2"
@@ -83612,13 +83614,6 @@
/obj/item/integrated_circuit_printer,
/turf/open/floor/plasteel/white,
/area/science/circuit)
"lmg" = (
/obj/machinery/computer/arcade{
icon_state = "arcade";
dir = 1
},
/turf/open/floor/plasteel,
/area/security/prison)
"lsv" = (
/obj/machinery/power/apc{
areastring = "/area/science/circuit";
@@ -83667,6 +83662,10 @@
},
/turf/open/floor/plating,
/area/maintenance/starboard/fore)
"lWL" = (
/obj/machinery/smartfridge/organ/preloaded,
/turf/closed/wall,
/area/medical/surgery)
"lWY" = (
/obj/machinery/door/airlock/hatch{
name = "Telecomms Server Room"
@@ -83788,13 +83787,6 @@
/obj/item/storage/fancy/candle_box,
/turf/open/floor/engine/cult,
/area/library)
"oba" = (
/obj/structure/chair/stool,
/obj/machinery/light/small{
dir = 4
},
/turf/open/floor/plasteel,
/area/security/prison)
"obb" = (
/obj/structure/target_stake,
/obj/effect/turf_decal/stripes/line{
@@ -84063,6 +84055,20 @@
},
/turf/open/floor/plasteel/dark,
/area/crew_quarters/cryopod)
"ram" = (
/obj/machinery/computer/arcade{
icon_state = "arcade";
dir = 1
},
/turf/open/floor/plasteel,
/area/security/prison)
"roa" = (
/obj/structure/chair/stool,
/obj/machinery/light/small{
dir = 4
},
/turf/open/floor/plasteel,
/area/security/prison)
"rzX" = (
/obj/structure/chair/office/light{
dir = 1;
@@ -84076,6 +84082,17 @@
},
/turf/open/floor/plasteel/white,
/area/science/lab)
"rLV" = (
/obj/structure/table,
/obj/item/folder,
/obj/item/paper/guides/jobs/hydroponics,
/obj/structure/cable/yellow{
icon_state = "1-2"
},
/obj/item/pen,
/obj/item/storage/crayons,
/turf/open/floor/plasteel,
/area/security/prison)
"rMS" = (
/obj/machinery/status_display/supply,
/turf/closed/wall,
@@ -84271,15 +84288,6 @@
},
/turf/open/floor/plating,
/area/maintenance/starboard)
"uHA" = (
/obj/structure/cable/yellow{
icon_state = "1-2"
},
/obj/structure/cable/yellow{
icon_state = "2-8"
},
/turf/open/floor/plasteel,
/area/security/prison)
"uJU" = (
/obj/structure/cable/yellow{
icon_state = "1-2"
@@ -84364,10 +84372,6 @@
/obj/structure/lattice,
/turf/open/space/basic,
/area/space)
"vPN" = (
/obj/machinery/smartfridge/organ/preloaded,
/turf/closed/wall,
/area/medical/surgery)
"wdu" = (
/obj/structure/grille,
/obj/structure/lattice,
@@ -84440,17 +84444,6 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel,
/area/science/misc_lab)
"xcb" = (
/obj/structure/table,
/obj/item/folder,
/obj/item/paper/guides/jobs/hydroponics,
/obj/structure/cable/yellow{
icon_state = "1-2"
},
/obj/item/pen,
/obj/item/storage/crayons,
/turf/open/floor/plasteel,
/area/security/prison)
"xeC" = (
/obj/machinery/light,
/turf/open/floor/plasteel/dark,
@@ -84507,6 +84500,15 @@
},
/turf/open/floor/plating,
/area/maintenance/port/aft)
"xIi" = (
/obj/structure/cable/yellow{
icon_state = "1-2"
},
/obj/structure/cable/yellow{
icon_state = "2-8"
},
/turf/open/floor/plasteel,
/area/security/prison)
"xVl" = (
/turf/closed/wall,
/area/hallway/secondary/service)
@@ -104237,7 +104239,7 @@ cia
cia
cpX
cia
vPN
lWL
cia
ceu
dyg
@@ -106710,11 +106712,11 @@ aaa
aaf
aaf
aay
xcb
uHA
rLV
xIi
abC
kwg
uHA
jhu
xIi
abC
abC
acr
@@ -106968,10 +106970,10 @@ aaf
aaa
aax
abl
oba
lmg
roa
ram
aax
kRT
iCn
aaR
aaR
aaI
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+7
View File
@@ -427,6 +427,7 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
//Dummy mob reserve slots
#define DUMMY_HUMAN_SLOT_PREFERENCES "dummy_preference_preview"
#define DUMMY_HUMAN_SLOT_HOLOFORM "dummy_holoform_generation"
#define DUMMY_HUMAN_SLOT_ADMIN "admintools"
#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation"
@@ -529,4 +530,10 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define CRYOMOBS 'icons/obj/cryo_mobs.dmi'
#define CUSTOM_HOLOFORM_DELAY 10 SECONDS //prevents spamming to make lag. it's pretty expensive to do this.
#define HOLOFORM_FILTER_AI "FILTER_AI"
#define HOLOFORM_FILTER_PAI "FILTER_PAI"
#define HOLOFORM_FILTER_STATIC "FILTER_STATIC"
#define CANT_REENTER_ROUND -1
+1 -1
View File
@@ -171,7 +171,7 @@
#define TRAIT_AUTO_CATCH_ITEM "auto_catch_item"
#define TRAIT_CLOWN_MENTALITY "clown_mentality" // The future is now, clownman.
#define TRAIT_FREESPRINT "free_sprinting"
#define TRAIT_NO_ALCOHOL "alcohol_intolerance"
// common trait sources
#define TRAIT_GENERIC "generic"
+62
View File
@@ -0,0 +1,62 @@
// Generates a holoform appearance
// Equipment list is slot = path.
/proc/generate_custom_holoform_from_prefs(datum/preferences/prefs, list/equipment_by_slot, list/inhand_equipment, copy_job = FALSE, apply_loadout = FALSE)
ASSERT(prefs)
var/mob/living/carbon/human/dummy/mannequin = generate_or_wait_for_human_dummy(DUMMY_HUMAN_SLOT_HOLOFORM)
prefs.copy_to(mannequin)
if(apply_loadout && prefs.parent)
SSjob.equip_loadout(prefs.parent.mob, mannequin, bypass_prereqs = TRUE)
if(copy_job)
var/datum/job/highest = prefs.get_highest_job()
if(highest && !istype(highest, /datum/job/ai) && !istype(highest, /datum/job/cyborg))
highest.equip(mannequin, TRUE, preference_source = prefs.parent)
if(length(equipment_by_slot))
for(var/slot in equipment_by_slot)
var/obj/item/I = new equipment_by_slot[slot]
mannequin.equip_to_slot_if_possible(I, slot, TRUE, TRUE, TRUE, TRUE)
if(length(inhand_equipment))
for(var/path in inhand_equipment)
var/obj/item/I = new path
mannequin.equip_to_slot_if_possible(I, SLOT_HANDS, TRUE, TRUE, TRUE, TRUE)
var/icon/combined = new
for(var/d in GLOB.cardinals)
mannequin.setDir(d)
COMPILE_OVERLAYS(mannequin)
CHECK_TICK
var/icon/capture = getFlatIcon(mannequin)
CHECK_TICK
combined.Insert(capture, dir = d)
CHECK_TICK
unset_busy_human_dummy(DUMMY_HUMAN_SLOT_HOLOFORM)
return combined
/proc/process_holoform_icon_filter(icon/I, filter_type, clone = TRUE)
if(clone)
I = icon(I) //Clone
switch(filter_type)
if(HOLOFORM_FILTER_AI)
I = getHologramIcon(I)
if(HOLOFORM_FILTER_STATIC)
I = getStaticIcon(I)
if(HOLOFORM_FILTER_PAI)
I = getPAIHologramIcon(I)
return I
//Errors go to user.
/proc/generate_custom_holoform_from_prefs_safe(datum/preferences/prefs, mob/user)
if(user)
if(user.client.prefs.last_custom_holoform > world.time - CUSTOM_HOLOFORM_DELAY)
to_chat(user, "<span class='boldwarning'>You are attempting to set your custom holoform too fast!</span>")
return
return generate_custom_holoform_from_prefs(prefs, null, null, TRUE, TRUE)
//Prompts this client for custom holoform parameters.
/proc/user_interface_custom_holoform(client/C)
var/datum/preferences/target_prefs = C.prefs
ASSERT(target_prefs)
//In the future, maybe add custom path allowances a la admin create outfit but for now..
return generate_custom_holoform_from_prefs_safe(target_prefs, C.mob)
+2 -6
View File
@@ -444,12 +444,8 @@
candidates -= M
/proc/pollGhostCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE)
var/list/candidates = list()
for(var/mob/dead/observer/G in GLOB.player_list)
if(G.can_reenter_round(TRUE))
candidates += G
var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(/datum/element/ghost_role_eligibility)
var/list/candidates = eligibility.get_all_ghost_role_eligible()
return pollCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category, flashwindow, candidates)
/proc/pollCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE, list/group = null)
+9 -1
View File
@@ -939,7 +939,7 @@ world
I.pixel_y++
add_overlay(I)//And finally add the overlay.
/proc/getHologramIcon(icon/A, safety=1)//If safety is on, a new icon is not created.
/proc/getHologramIcon(icon/A, safety = TRUE)//If safety is on, a new icon is not created.
var/icon/flat_icon = safety ? A : new(A)//Has to be a new icon to not constantly change the same icon.
flat_icon.ColorTone(rgb(125,180,225))//Let's make it bluish.
flat_icon.ChangeOpacity(0.5)//Make it half transparent.
@@ -947,6 +947,14 @@ world
flat_icon.AddAlphaMask(alpha_mask)//Finally, let's mix in a distortion effect.
return flat_icon
/proc/getPAIHologramIcon(icon/A, safety = TRUE)
var/icon/flat_icon = safety? A : new(A)
flat_icon.SetIntensity(0.75, 1, 0.75)
flat_icon.ChangeOpacity(0.7)
var/icon/alpha_mask = new('icons/effects/effects.dmi', "scanlineslow")//Scanline effect.
flat_icon.AddAlphaMask(alpha_mask)//Finally, let's mix in a distortion effect.
return flat_icon
//What the mob looks like as animated static
//By vg's ComicIronic
/proc/getStaticIcon(icon/A, safety = TRUE)
+2
View File
@@ -23,6 +23,8 @@ GLOBAL_VAR_INIT(bsa_unlock, FALSE) //BSA unlocked by head ID swipes
GLOBAL_LIST_EMPTY(player_details) // ckey -> /datum/player_details
GLOBAL_LIST_EMPTY(clientless_round_timeouts) // ckey -> time that ckey can rejoin round
// All religion stuff
GLOBAL_VAR(religion)
GLOBAL_VAR(deity)
@@ -386,6 +386,8 @@
config_entry_value = 72000
min_val = 0
/datum/config_entry/flag/pai_custom_holoforms
/datum/config_entry/number/marauder_delay_non_reebe
config_entry_value = 1800
min_val = 0
+2 -2
View File
@@ -658,7 +658,7 @@ SUBSYSTEM_DEF(job)
message_admins(msg)
CRASH(msg)
/datum/controller/subsystem/job/proc/equip_loadout(mob/dead/new_player/N, mob/living/M, equipbackpackstuff)
/datum/controller/subsystem/job/proc/equip_loadout(mob/dead/new_player/N, mob/living/M, equipbackpackstuff, bypass_prereqs = FALSE)
var/mob/the_mob = N
if(!the_mob)
the_mob = M // cause this doesn't get assigned if player is a latejoiner
@@ -671,7 +671,7 @@ SUBSYSTEM_DEF(job)
if(!G)
continue
var/permitted = TRUE
if(G.restricted_roles && G.restricted_roles.len && !(M.mind.assigned_role in G.restricted_roles))
if(!bypass_prereqs && G.restricted_roles && G.restricted_roles.len && !(M.mind.assigned_role in G.restricted_roles))
permitted = FALSE
if(G.donoritem && !G.donator_ckey_check(the_mob.client.ckey))
permitted = FALSE
@@ -17,7 +17,7 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
/datum/controller/subsystem/processing/quirks/Initialize(timeofday)
if(!quirks.len)
SetupQuirks()
quirk_blacklist = list(list("Blind","Nearsighted"),list("Jolly","Depression","Apathetic"),list("Ageusia","Deviant Tastes"),list("Ananas Affinity","Ananas Aversion"))
quirk_blacklist = list(list("Blind","Nearsighted"),list("Jolly","Depression","Apathetic"),list("Ageusia","Deviant Tastes"),list("Ananas Affinity","Ananas Aversion"),list("Alcohol Tolerance","Alcohol Intolerance"),list("Alcohol Intolerance","Drunken Resilience"))
return ..()
/datum/controller/subsystem/processing/quirks/proc/SetupQuirks()
@@ -46,8 +46,8 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
badquirk = TRUE
if(badquirk)
cli.prefs.save_character()
if(!silent && LAZYLEN(cut))
to_chat(to_chat_target || user, "<span class='boldwarning'>All of your non-neutral character quirks have been cut due to these quirks conflicting with your job assignment: [english_list(cut)].</span>")
if (!silent && LAZYLEN(cut))
to_chat(to_chat_target || user, "<span class='boldwarning'>Some quirks have been cut from your character because of these quirks conflicting with your job assignment: [english_list(cut)].</span>")
/datum/controller/subsystem/processing/quirks/proc/quirk_path_by_name(name)
return quirks[name]
@@ -66,6 +66,7 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
/datum/controller/subsystem/processing/quirks/proc/filter_quirks(list/our_quirks, datum/job/job)
var/list/cut = list()
var/list/banned_names = list()
var/pointscut = 0
for(var/i in job.blacklisted_quirks)
var/name = quirk_name_by_path(i)
if(name)
@@ -75,7 +76,17 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
for(var/i in blacklisted)
our_quirks -= i
cut += i
pointscut += quirk_points_by_name(i)
if (pointscut != 0)
for (var/i in shuffle(our_quirks))
if (quirk_points_by_name(i) < pointscut || (pointscut < 0) ? quirk_points_by_name(i) <= 0 : quirk_points_by_name(i) >= 0)
continue
else
our_quirks -= i
cut += i
pointscut += quirk_points_by_name(i)
if (pointscut >= 0) //with how it works, it needs to be above zero, not below, as points for positive is positive, and negative is negative, we only want it to break if it's above zero, ie. we cut more positive than negative
break
/* //Code to automatically reduce positive quirks until balance is even.
var/points_used = total_points(our_quirks)
if(points_used > 0)
@@ -91,10 +102,11 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
*/
//Nah, let's null all non-neutrals out.
if(cut.len)
for(var/i in our_quirks)
if(quirk_points_by_name(i) != 0)
//cut += i -- Commented out: Only show the ones that triggered the quirk purge.
our_quirks -= i
if (pointscut != 0)// only if the pointscutting didn't work.
if(cut.len)
for(var/i in our_quirks)
if(quirk_points_by_name(i) != 0)
//cut += i -- Commented out: Only show the ones that triggered the quirk purge.
our_quirks -= i
return cut
+1 -1
View File
@@ -37,7 +37,7 @@ SUBSYSTEM_DEF(shuttle)
var/points = 5000 //number of trade-points we have
var/centcom_message = "" //Remarks from CentCom on how well you checked the last order.
var/list/discoveredPlants = list() //Typepaths for unusual plants we've already sent CentCom, associated with their potencies
var/passive_supply_points_per_minute = 750
var/passive_supply_points_per_minute = 500
var/list/supply_packs = list()
var/list/shoppinglist = list()
+11
View File
@@ -141,6 +141,17 @@
current_button.add_overlay(mutable_appearance(icon_icon, button_icon_state))
current_button.button_icon_state = button_icon_state
/datum/action/ghost
icon_icon = 'icons/mob/mob.dmi'
button_icon_state = "ghost"
name = "Ghostize"
desc = "Turn into a ghost and freely come back to your body."
/datum/action/ghost/Trigger()
if(!..())
return 0
var/mob/M = target
M.ghostize(1)
//Presets for item actions
/datum/action/item_action
@@ -66,7 +66,7 @@
/datum/component/storage/concrete/_insert_physical_item(obj/item/I, override = FALSE)
. = TRUE
var/atom/real_location = real_location()
if(I.loc != real_location)
if(I.loc != real_location && real_location)
I.forceMove(real_location)
refresh_mob_views()
+2 -2
View File
@@ -11,7 +11,7 @@
if(type == /datum/element)
return ELEMENT_INCOMPATIBLE
if(element_flags & ELEMENT_DETACH)
RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/Detach)
RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/Detach, override = TRUE)
/datum/element/proc/Detach(datum/source, force)
UnregisterSignal(source, COMSIG_PARENT_QDELETING)
@@ -36,4 +36,4 @@
*/
/datum/proc/RemoveElement(eletype, ...)
var/datum/element/ele = SSdcs.GetElement(arglist(args))
ele.Detach(src)
ele.Detach(src)
@@ -0,0 +1,54 @@
/datum/element/ghost_role_eligibility
element_flags = ELEMENT_DETACH
var/list/timeouts = list()
var/list/mob/eligible_mobs = list()
/datum/element/ghost_role_eligibility/Attach(datum/target,penalize = FALSE)
. = ..()
if(!ismob(target))
return ELEMENT_INCOMPATIBLE
var/mob/M = target
if(!(M in eligible_mobs))
eligible_mobs += M
if(penalize) //penalizing them from making a ghost role / midround antag comeback right away.
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
if(world.time < roundstart_quit_limit) //add up the time difference to their antag rolling penalty if they quit before half a (ingame) hour even passed.
penalty += roundstart_quit_limit - world.time
if(penalty)
penalty += world.realtime
if(penalty - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
penalty = CANT_REENTER_ROUND
if(!(M.ckey in timeouts))
timeouts += M.ckey
timeouts[M.ckey] = 0
timeouts[M.ckey] = max(timeouts[M.ckey],penalty)
/datum/element/ghost_role_eligibility/Detach(mob/M)
. = ..()
if(M in eligible_mobs)
eligible_mobs -= M
/datum/element/ghost_role_eligibility/proc/get_all_ghost_role_eligible(silent = FALSE)
var/list/candidates = list()
for(var/m in eligible_mobs)
var/mob/M = m
if(M.can_reenter_round(TRUE))
candidates += M
return candidates
/mob/proc/can_reenter_round(silent = FALSE)
var/datum/element/ghost_role_eligibility/eli = SSdcs.GetElement(/datum/element/ghost_role_eligibility)
return eli.can_reenter_round(src,silent)
/datum/element/ghost_role_eligibility/proc/can_reenter_round(var/mob/M,silent = FALSE)
if(!(M in eligible_mobs))
return FALSE
if(!(M.ckey in timeouts))
return TRUE
var/timeout = timeouts[M.ckey]
if(timeout != CANT_REENTER_ROUND && timeout <= world.realtime)
return TRUE
if(!silent && M.client)
to_chat(M, "<span class='warning'>You are unable to reenter the round[timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(timeout - world.realtime)]" : ""].</span>")
return FALSE
+2 -1
View File
@@ -136,9 +136,10 @@
/datum/emote/sound
var/sound //Sound to play when emote is called
var/vary = FALSE //used for the honk borg emote
var/volume = 50
mob_type_allowed_typecache = list(/mob/living/brain, /mob/living/silicon)
/datum/emote/sound/run_emote(mob/user, params)
. = ..()
if(.)
playsound(user.loc, sound, 50, vary)
playsound(user.loc, sound, volume, vary)
+18
View File
@@ -87,3 +87,21 @@
/datum/quirk/monochromatic/remove()
if(quirk_holder)
quirk_holder.remove_client_colour(/datum/client_colour/monochrome)
/datum/quirk/alcohol_intolerance
name = "Alcohol Intolerance"
desc = "You take toxin damage from alcohol rather than getting drunk."
value = 0
mob_trait = TRAIT_NO_ALCOHOL
medical_record_text = "Patient's body does not react properly to ethyl alcohol."
/datum/quirk/alcohol_intolerance/add()
var/mob/living/carbon/human/H = quirk_holder
var/datum/species/species = H.dna.species
species.disliked_food |= ALCOHOL
/datum/quirk/alcohol_intolerance/remove()
var/mob/living/carbon/human/H = quirk_holder
if(H)
var/datum/species/species = H.dna.species
species.disliked_food &= ~ALCOHOL
@@ -17,10 +17,10 @@
var/list/living_antags = list()
var/list/dead_players = list()
var/list/list_observers = list()
var/list/ghost_eligible = list()
/datum/dynamic_ruleset/midround/from_ghosts
weight = 0
required_type = /mob/dead/observer
/// Whether the ruleset should call generate_ruleset_body or not.
var/makeBody = TRUE
@@ -34,6 +34,8 @@
living_players = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS])
living_antags = trim_list(mode.current_players[CURRENT_LIVING_ANTAGS])
list_observers = trim_list(mode.current_players[CURRENT_OBSERVERS])
var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(/datum/element/ghost_role_eligibility)
ghost_eligible = trim_list(eligibility.get_all_ghost_role_eligible())
/datum/dynamic_ruleset/midround/proc/trim_list(list/L = list())
var/list/trimmed_list = L.Copy()
@@ -70,6 +72,25 @@
continue
return trimmed_list
/datum/dynamic_ruleset/midround/from_ghosts/trim_list(list/L = list())
var/list/trimmed_list = L.Copy()
for(var/mob/M in trimmed_list)
if (!M.client) // Are they connected?
trimmed_list.Remove(M)
continue
if(!mode.check_age(M.client, minimum_required_age))
trimmed_list.Remove(M)
continue
if(antag_flag_override)
if(!(antag_flag_override in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag_override))
trimmed_list.Remove(M)
continue
else
if(!(antag_flag in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag))
trimmed_list.Remove(M)
continue
return trimmed_list
// You can then for example prompt dead players in execute() to join as strike teams or whatever
// Or autotator someone
@@ -91,11 +112,15 @@
return FALSE
return TRUE
/datum/dynamic_ruleset/midround/from_ghosts/ready(forced = FALSE)
if (required_candidates > ghost_eligible.len)
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
return ..()
/datum/dynamic_ruleset/midround/from_ghosts/execute()
var/list/possible_candidates = list()
possible_candidates.Add(dead_players)
possible_candidates.Add(list_observers)
var/application_successful = send_applications(possible_candidates)
var/application_successful = send_applications(ghost_eligible)
return assigned.len > 0 && application_successful
/// This sends a poll to ghosts if they want to be a ghost spawn from a ruleset.
@@ -303,9 +328,6 @@
var/datum/mind/wizard
/datum/dynamic_ruleset/midround/from_ghosts/wizard/ready(forced = FALSE)
if (required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
if(GLOB.wizardstart.len == 0)
log_admin("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.")
message_admins("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.")
@@ -366,12 +388,6 @@
required_candidates = operative_cap[indice_pop]
return ..()
/datum/dynamic_ruleset/midround/from_ghosts/nuclear/ready(forced = FALSE)
if (required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
return ..()
/datum/dynamic_ruleset/midround/from_ghosts/nuclear/finish_setup(mob/new_character, index)
new_character.mind.special_role = "Nuclear Operative"
new_character.mind.assigned_role = "Nuclear Operative"
@@ -404,12 +420,6 @@
repeatable = TRUE
property_weights = list("story_potential" = -1, "trust" = 2, "chaos" = 2, "extended" = -2, "valid" = 2)
/datum/dynamic_ruleset/midround/from_ghosts/blob/ready(forced = FALSE)
if (required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
return ..()
/datum/dynamic_ruleset/midround/from_ghosts/blob/generate_ruleset_body(mob/applicant)
var/body = applicant.become_overmind()
return body
@@ -437,12 +447,6 @@
property_weights = list("story_potential" = -1, "trust" = 1, "chaos" = 2, "extended" = -2, "valid" = 2)
var/list/vents = list()
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/ready(forced = FALSE)
if (required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
return ..()
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/execute()
// 50% chance of being incremented by one
required_candidates += prob(50)
@@ -539,12 +543,6 @@
property_weights = list("story_potential" = 1, "extended" = 1, "valid" = -2)
high_population_requirement = 5
/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/ready(forced = FALSE)
if (required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
return ..()
/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/generate_ruleset_body(mob/applicant)
var/mob/camera/disease/virus = new /mob/camera/disease(SSmapping.get_station_center())
applicant.transfer_ckey(virus, FALSE)
@@ -583,9 +581,6 @@
return ..()
/datum/dynamic_ruleset/midround/from_ghosts/revenant/ready(forced = FALSE)
if(required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
for(var/mob/living/L in GLOB.dead_mob_list) //look for any dead bodies
var/turf/T = get_turf(L)
if(T && is_station_level(T.z))
@@ -632,9 +627,6 @@
var/list/spawn_locs = list()
/datum/dynamic_ruleset/midround/from_ghosts/slaughter_demon/ready(forced = FALSE)
if(required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
spawn_locs += L.loc
@@ -685,9 +677,6 @@
repeatable = TRUE
/datum/dynamic_ruleset/midround/from_ghosts/abductors/ready(forced = FALSE)
if(required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
team = new /datum/team/abductor_team
if(team.team_number > ABDUCTOR_MAX_TEAMS)
return FALSE
@@ -726,9 +715,6 @@
var/spawn_loc
/datum/dynamic_ruleset/midround/from_ghosts/ninja/ready(forced = FALSE)
if(required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
if(!spawn_loc)
var/list/spawn_locs = list()
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
+1 -1
View File
@@ -491,4 +491,4 @@
//Attacks/effects.
/obj/machinery/cryopod/blob_act()
return //Sorta gamey, but we don't really want these to be destroyed.
return //Sorta gamey, but we don't really want these to be destroyed.
+3 -1
View File
@@ -500,7 +500,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
else
return FALSE
/obj/machinery/holopad/proc/move_hologram(mob/living/user, turf/new_turf)
/obj/machinery/holopad/proc/move_hologram(mob/living/user, turf/new_turf, direction)
if(LAZYLEN(masters) && masters[user])
var/obj/effect/overlay/holo_pad_hologram/holo = masters[user]
var/transfered = FALSE
@@ -512,6 +512,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
transfered = TRUE
//All is good.
holo.forceMove(new_turf)
if(direction)
holo.setDir(direction)
if(!transfered)
update_holoray(user,new_turf)
return TRUE
+1 -1
View File
@@ -107,7 +107,7 @@
//Wrapper procs that handle sanity and user feedback
/atom/movable/proc/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE)
if(!in_range(user, src) || !isturf(user.loc) || user.incapacitated() || M.anchored)
if(!in_range(user, src) || !isturf(user.loc) || user.incapacitated() || M.anchored || !user.can_buckle_others(M, src))
return FALSE
add_fingerprint(user)
+6 -2
View File
@@ -8,7 +8,8 @@
w_class = WEIGHT_CLASS_SMALL
slot_flags = ITEM_SLOT_BELT
var/mob/living/silicon/pai/pai
resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE
resistance_flags = FIRE_PROOF | ACID_PROOF
max_integrity = 200
/obj/item/paicard/suicide_act(mob/living/user)
user.visible_message("<span class='suicide'>[user] is staring sadly at [src]! [user.p_they()] can't keep living without real human intimacy!</span>")
@@ -45,6 +46,8 @@
dat += "<b>Radio Uplink</b><br>"
dat += "Transmit: <A href='byond://?src=[REF(src)];wires=[WIRE_TX]'>[(pai.radio.wires.is_cut(WIRE_TX)) ? "Disabled" : "Enabled"]</A><br>"
dat += "Receive: <A href='byond://?src=[REF(src)];wires=[WIRE_RX]'>[(pai.radio.wires.is_cut(WIRE_RX)) ? "Disabled" : "Enabled"]</A><br>"
if(pai.radio_short)
dat += "<font color='red'>Reset radio short: <a href='byond://?src=[REF(src)];reset_radio_short=1'>\[RESET\]</a><br>"
else
dat += "<b>Radio Uplink</b><br>"
dat += "<font color=red><i>Radio firmware not loaded. Please install a pAI personality to load firmware.</i></font><br>"
@@ -82,7 +85,6 @@
pai.master = M.real_name
pai.master_dna = M.dna.unique_enzymes
to_chat(pai, "<span class='notice'>You have been bound to a new master.</span>")
pai.emittersemicd = FALSE
if(href_list["wipe"])
var/confirm = input("Are you CERTAIN you wish to delete the current personality? This action cannot be undone.", "Personality Wipe") in list("Yes", "No")
if(confirm == "Yes")
@@ -96,6 +98,8 @@
var/wire = text2num(href_list["wires"])
if(pai.radio)
pai.radio.wires.cut(wire)
if(href_list["reset_radio_short"])
pai.unshort_radio()
if(href_list["setlaws"])
var/newlaws = copytext(sanitize(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.laws.supplied[1]) as message),1,MAX_MESSAGE_LEN)
if(newlaws && pai)
+2 -2
View File
@@ -479,10 +479,10 @@
possessed = TRUE
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_POSSESSED_BLADE)
var/list/mob/candidates = pollGhostCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_POSSESSED_BLADE)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
var/mob/C = pick(candidates)
var/mob/living/simple_animal/shade/S = new(src)
S.real_name = name
S.name = name
+34 -19
View File
@@ -50,7 +50,6 @@
if(tank)
updateTank(tank, 1, user)
/obj/item/melee/powerfist/proc/updateTank(obj/item/tank/internals/thetank, removing = 0, mob/living/carbon/human/user)
if(removing)
if(!tank)
@@ -71,26 +70,42 @@
/obj/item/melee/powerfist/attack(mob/living/target, mob/living/user)
if(!tank)
to_chat(user, "<span class='warning'>\The [src] can't operate without a source of gas!</span>")
return
if(tank && !tank.air_contents.remove(gasperfist * fisto_setting))
to_chat(user, "<span class='warning'>\The [src]'s piston-ram lets out a weak hiss, it needs more gas!</span>")
playsound(loc, 'sound/effects/refill.ogg', 50, 1)
return
target.apply_damage(force * fisto_setting, BRUTE)
target.visible_message("<span class='danger'>[user]'s powerfist lets out a loud hiss as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
"<span class='userdanger'>You cry out in pain as [user]'s punch flings you backwards!</span>")
new /obj/effect/temp_visual/kinetic_blast(target.loc)
playsound(loc, 'sound/weapons/resonator_blast.ogg', 50, 1)
playsound(loc, 'sound/weapons/genhit2.ogg', 50, 1)
if(!tank)
to_chat(user, "<span class='warning'>\The [src] can't operate without a source of gas!</span>")
return
var/datum/gas_mixture/gasused = tank.air_contents.remove(gasperfist * fisto_setting)
var/turf/T = get_turf(src)
if(!T)
return
T.assume_air(gasused)
T.air_update_turf()
if(!gasused)
to_chat(user, "<span class='warning'>\The [src]'s tank is empty!</span>")
target.apply_damage((force / 5), BRUTE)
playsound(loc, 'sound/weapons/punch1.ogg', 50, 1)
target.visible_message("<span class='danger'>[user]'s powerfist lets out a dull thunk as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
"<span class='userdanger'>[user]'s punches you!</span>")
return
if(gasused.total_moles() < gasperfist * fisto_setting)
to_chat(user, "<span class='warning'>\The [src]'s piston-ram lets out a weak hiss, it needs more gas!</span>")
playsound(loc, 'sound/weapons/punch4.ogg', 50, 1)
target.apply_damage((force / 2), BRUTE)
target.visible_message("<span class='danger'>[user]'s powerfist lets out a weak hiss as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
"<span class='userdanger'>[user]'s punch strikes with force!</span>")
return
target.apply_damage(force * fisto_setting, BRUTE)
target.visible_message("<span class='danger'>[user]'s powerfist lets out a loud hiss as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
"<span class='userdanger'>You cry out in pain as [user]'s punch flings you backwards!</span>")
new /obj/effect/temp_visual/kinetic_blast(target.loc)
playsound(loc, 'sound/weapons/resonator_blast.ogg', 50, 1)
playsound(loc, 'sound/weapons/genhit2.ogg', 50, 1)
var/atom/throw_target = get_edge_target_turf(target, get_dir(src, get_step_away(target, src)))
var/atom/throw_target = get_edge_target_turf(target, get_dir(src, get_step_away(target, src)))
target.throw_at(throw_target, 5 * fisto_setting, 0.2)
target.throw_at(throw_target, 5 * fisto_setting, 0.5 + (fisto_setting / 2))
log_combat(user, target, "power fisted", src)
log_combat(user, target, "power fisted", src)
user.changeNext_move(CLICK_CD_MELEE * click_delay)
user.changeNext_move(CLICK_CD_MELEE * click_delay)
return
return
@@ -398,39 +398,64 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
* Cardboard
*/
GLOBAL_LIST_INIT(cardboard_recipes, list ( \
new/datum/stack_recipe("box", /obj/item/storage/box), \
new/datum/stack_recipe("sec box", /obj/item/storage/box/seclooking), \
new/datum/stack_recipe("light tubes", /obj/item/storage/box/lights/tubes), \
new/datum/stack_recipe("light bulbs", /obj/item/storage/box/lights/bulbs), \
new/datum/stack_recipe("mouse traps", /obj/item/storage/box/mousetraps), \
new/datum/stack_recipe("pizza box", /obj/item/pizzabox), \
new/datum/stack_recipe("power cell", /obj/item/storage/box/cells), \
new/datum/stack_recipe("02", /obj/item/storage/box/otwo), \
null, \
new/datum/stack_recipe("lethal ammo box", /obj/item/storage/box/lethalshot), \
new/datum/stack_recipe("rubber shot ammo box", /obj/item/storage/box/rubbershot), \
new/datum/stack_recipe("bean bag ammo box", /obj/item/storage/box/beanbag), \
new/datum/stack_recipe("12g ammo box", /obj/item/storage/box/lethalslugs), \
new/datum/stack_recipe("stun slug ammo box", /obj/item/storage/box/stunslug), \
new/datum/stack_recipe("tech shell ammo box", /obj/item/storage/box/techsslug), \
new/datum/stack_recipe("incendiary ammo box", /obj/item/storage/box/fireshot), \
new/datum/stack_recipe("firing pins", /obj/item/storage/box/firingpins), \
new/datum/stack_recipe("loose ammo", /obj/item/storage/box/ammoshells), \
null, \
new/datum/stack_recipe("cardborg suit", /obj/item/clothing/suit/cardborg, 3), \
new/datum/stack_recipe("cardborg helmet", /obj/item/clothing/head/cardborg), \
new/datum/stack_recipe("folder", /obj/item/folder), \
new/datum/stack_recipe("large box", /obj/structure/closet/cardboard, 4), \
new/datum/stack_recipe("cardboard cutout", /obj/item/cardboard_cutout, 5), \
null, \
new/datum/stack_recipe("colored brown", /obj/item/storage/box/brown), \
new/datum/stack_recipe("colored green", /obj/item/storage/box/green), \
new/datum/stack_recipe("colored red", /obj/item/storage/box/blue), \
new/datum/stack_recipe("colored blue", /obj/item/storage/box/red), \
new/datum/stack_recipe("colored yellow", /obj/item/storage/box/yellow), \
new/datum/stack_recipe("colored pink", /obj/item/storage/box/pink), \
new/datum/stack_recipe("colored purple", /obj/item/storage/box/purple), \
))
new/datum/stack_recipe("box", /obj/item/storage/box), \
new/datum/stack_recipe("cardborg suit", /obj/item/clothing/suit/cardborg, 3), \
new/datum/stack_recipe("cardborg helmet", /obj/item/clothing/head/cardborg), \
new/datum/stack_recipe("large box", /obj/structure/closet/cardboard, 4), \
new/datum/stack_recipe("cardboard cutout", /obj/item/cardboard_cutout, 5), \
new/datum/stack_recipe("pizza box", /obj/item/pizzabox), \
new/datum/stack_recipe("folder", /obj/item/folder), \
// holy fuck why are there so many boxes
new/datum/stack_recipe_list("fancy boxes", list ( \
new /datum/stack_recipe("donut box", /obj/item/storage/fancy/donut_box), \
new /datum/stack_recipe("egg box", /obj/item/storage/fancy/egg_box), \
new /datum/stack_recipe("donk-pockets box", /obj/item/storage/box/donkpockets), \
new /datum/stack_recipe("monkey cube box", /obj/item/storage/box/monkeycubes), \
new /datum/stack_recipe("box (internals)", /obj/item/storage/box/otwo), \
null, \
new /datum/stack_recipe("security-styled box", /obj/item/storage/box/seclooking), \
new /datum/stack_recipe("buckshot shell box", /obj/item/storage/box/lethalshot), \
new /datum/stack_recipe("rubber shot shell box", /obj/item/storage/box/rubbershot), \
new /datum/stack_recipe("beanbag shell box", /obj/item/storage/box/beanbag), \
new /datum/stack_recipe("slug shell box", /obj/item/storage/box/lethalslugs), \
new /datum/stack_recipe("stunslug shell box", /obj/item/storage/box/stunslug), \
new /datum/stack_recipe("tech shell box", /obj/item/storage/box/techsslug), \
new /datum/stack_recipe("incendiary ammo box", /obj/item/storage/box/fireshot), \
new /datum/stack_recipe("loose ammo box", /obj/item/storage/box/ammoshells), \
new /datum/stack_recipe("firing pins box", /obj/item/storage/box/firingpins), \
null, \
new /datum/stack_recipe("flashbang box", /obj/item/storage/box/flashbangs), \
new /datum/stack_recipe("flashes box", /obj/item/storage/box/flashes), \
new /datum/stack_recipe("handcuffs box", /obj/item/storage/box/handcuffs), \
new /datum/stack_recipe("ID card box", /obj/item/storage/box/ids), \
new /datum/stack_recipe("PDA box", /obj/item/storage/box/PDAs), \
null, \
new /datum/stack_recipe("pill bottle box", /obj/item/storage/box/pillbottles), \
new /datum/stack_recipe("beaker box", /obj/item/storage/box/beakers), \
new /datum/stack_recipe("syringe box", /obj/item/storage/box/syringes), \
new /datum/stack_recipe("latex gloves box", /obj/item/storage/box/gloves), \
new /datum/stack_recipe("sterile masks box", /obj/item/storage/box/masks), \
new /datum/stack_recipe("body bag box", /obj/item/storage/box/bodybags), \
new /datum/stack_recipe("prescription glasses box", /obj/item/storage/box/rxglasses), \
null, \
new /datum/stack_recipe("disk box", /obj/item/storage/box/disks), \
new /datum/stack_recipe("light tubes box", /obj/item/storage/box/lights/tubes), \
new /datum/stack_recipe("light bulbs box", /obj/item/storage/box/lights/bulbs), \
new /datum/stack_recipe("mixed lights box", /obj/item/storage/box/lights/mixed), \
new /datum/stack_recipe("power cell box", /obj/item/storage/box/cells), \
new /datum/stack_recipe("mouse traps box", /obj/item/storage/box/mousetraps), \
new /datum/stack_recipe("candle box", /obj/item/storage/fancy/candle_box), \
null, \
new /datum/stack_recipe("box (brown)", /obj/item/storage/box/brown), \
new /datum/stack_recipe("box (green)", /obj/item/storage/box/green), \
new /datum/stack_recipe("box (blue)", /obj/item/storage/box/blue), \
new /datum/stack_recipe("box (red)", /obj/item/storage/box/red), \
new /datum/stack_recipe("box (yellow)", /obj/item/storage/box/yellow), \
new /datum/stack_recipe("box (pink)", /obj/item/storage/box/pink), \
new /datum/stack_recipe("box (purple)", /obj/item/storage/box/purple), \
)),
null, \
))
/obj/item/stack/sheet/cardboard //BubbleWrap //it's cardboard you fuck
name = "cardboard"
@@ -456,7 +481,7 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \
var/atom/droploc = drop_location()
if(use(1))
playsound(I, 'sound/items/bikehorn.ogg', 50, 1, -1)
to_chat(user, "<span class='notice'>You stamp the cardboard! Its a clown box! Honk!</span>")
to_chat(user, "<span class='notice'>You stamp the cardboard! It's a clown box! Honk!</span>")
if (amount >= 0)
new/obj/item/storage/box/clown(droploc) //bugfix
else
@@ -521,31 +546,30 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
*/
GLOBAL_LIST_INIT(brass_recipes, list ( \
new/datum/stack_recipe("wall gear", /obj/structure/destructible/clockwork/wall_gear, 3, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
null,
null, \
new/datum/stack_recipe("brass pinion airlock", /obj/machinery/door/airlock/clockwork, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass pinion airlock - windowed", /obj/machinery/door/airlock/clockwork/brass, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass windoor", /obj/machinery/door/window/clockwork, 2, time = 30, on_floor = TRUE, window_checks = TRUE), \
null,
null, \
new/datum/stack_recipe("brass reflector", /obj/structure/destructible/clockwork/reflector, 10, time = 100, one_per_turf = TRUE, on_floor = TRUE, window_checks = TRUE), \
null,
null, \
new/datum/stack_recipe("brass window - directional", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("brass window - fulltile", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("brass chair", /obj/structure/chair/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass bar stool", /obj/structure/chair/stool/bar/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass stool", /obj/structure/chair/stool/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \
null,
null, \
new/datum/stack_recipe("sender - pressure sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("sender - mech sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor/mech, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("sender - lever", /obj/structure/destructible/clockwork/trap/trigger/lever, 1, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("sender - repeater", /obj/structure/destructible/clockwork/trap/trigger/repeater, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
null,
null, \
new/datum/stack_recipe("receiver - brass skewer", /obj/structure/destructible/clockwork/trap/brass_skewer, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_ADJACENT), \
new/datum/stack_recipe("receiver - steam vent", /obj/structure/destructible/clockwork/trap/steam_vent, 3, time = 30, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \
new/datum/stack_recipe("receiver - power nullifier", /obj/structure/destructible/clockwork/trap/power_nullifier, 5, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \
null,
null, \
new/datum/stack_recipe("brass flask", /obj/item/reagent_containers/food/drinks/bottle/holyoil/empty), \
))
/obj/item/stack/tile/brass
+2 -1
View File
@@ -197,6 +197,7 @@
if(!isturf(T))
return
T.PlaceOnTop(R.result_type, flags = CHANGETURF_INHERIT_AIR)
else
O = new R.result_type(usr.drop_location())
if(O)
O.setDir(usr.dir)
@@ -444,4 +445,4 @@
/datum/stack_recipe_list/New(title, recipes)
src.title = title
src.recipes = recipes
src.recipes = recipes
@@ -626,7 +626,13 @@
O.equip(new_spawn, FALSE, new_spawn.client)
SSjob.equip_loadout(null, new_spawn, FALSE)
SSquirks.AssignQuirks(new_spawn, new_spawn.client, TRUE, TRUE, null, FALSE, new_spawn)
new_spawn.AddElement(/datum/element/ghost_role_eligibility)
ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT)
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
to_chat(new_spawn,"<span class='boldwarning'>You maybe sharing your cafe with some ninja-captured individuals, so make sure to only interact with the ghosts you hear as a ghost!</span>")
to_chat(new_spawn,"<span class='boldwarning'>You can turn yourself into a ghost and freely reenter your body with the ghost action.</span>")
var/datum/action/ghost/G = new(new_spawn)
G.Grant(new_spawn)
/datum/outfit/ghostcafe
name = "ID, jumpsuit and shoes"
+3 -1
View File
@@ -5,6 +5,8 @@
icon_state = "toilet00"
density = FALSE
anchored = TRUE
can_buckle = TRUE
buckle_lying = 0
var/open = FALSE //if the lid is up
var/cistern = 0 //if the cistern bit is open
var/w_items = 0 //the combined w_class of all the items in the cistern
@@ -682,4 +684,4 @@
else
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
playsound(loc, 'sound/items/welder.ogg', 80, 1)
playsound(loc, 'sound/items/welder.ogg', 80, 1)
+9 -2
View File
@@ -16,8 +16,16 @@
if (text2num(computer_id) == 2147483647) //this cid causes stickybans to go haywire
log_access("Failed Login (invalid cid): [key] [address]-[computer_id]")
return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided an invalid Computer ID.)")
var/admin = 0
if (type == "world")
return ..() //shunt world topic banchecks to purely to byond's internal ban system
var/ckey = ckey(key)
var/client/C = GLOB.directory[ckey]
if (C && ckey == C.ckey && computer_id == C.computer_id && address == C.address)
return //don't recheck connected clients.
var/admin = FALSE
if(GLOB.admin_datums[ckey] || GLOB.deadmins[ckey])
admin = 1
@@ -126,7 +134,6 @@
bannedckey = ban["ckey"]
var/newmatch = FALSE
var/client/C = GLOB.directory[ckey]
var/cachedban = SSstickyban.cache[bannedckey]
//rogue ban in the process of being reverted.
+7 -7
View File
@@ -137,9 +137,9 @@
/datum/admins/proc/makeWizard()
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered for the position of a Wizard Foundation 'diplomat'?", ROLE_WIZARD, null)
var/list/mob/candidates = pollGhostCandidates("Do you wish to be considered for the position of a Wizard Foundation 'diplomat'?", ROLE_WIZARD, null)
var/mob/dead/observer/selected = pick_n_take(candidates)
var/mob/selected = pick_n_take(candidates)
var/mob/living/carbon/human/new_character = makeBody(selected)
new_character.mind.make_Wizard()
@@ -214,9 +214,9 @@
/datum/admins/proc/makeNukeTeam()
var/datum/game_mode/nuclear/temp = new
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered for a nuke team being sent in?", ROLE_OPERATIVE, temp)
var/list/mob/dead/observer/chosen = list()
var/mob/dead/observer/theghost = null
var/list/mob/candidates = pollGhostCandidates("Do you wish to be considered for a nuke team being sent in?", ROLE_OPERATIVE, temp)
var/list/mob/chosen = list()
var/mob/theghost = null
if(candidates.len)
var/numagents = 5
@@ -378,7 +378,7 @@
ertemplate.enforce_human = prefs["enforce_human"]["value"] == "Yes" ? TRUE : FALSE
ertemplate.opendoors = prefs["open_armory"]["value"] == "Yes" ? TRUE : FALSE
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered for [ertemplate.polldesc] ?", "deathsquad", null)
var/list/mob/candidates = pollGhostCandidates("Do you wish to be considered for [ertemplate.polldesc] ?", "deathsquad", null)
var/teamSpawned = FALSE
if(candidates.len > 0)
@@ -404,7 +404,7 @@
numagents--
continue // This guy's unlucky, not enough spawn points, we skip him.
var/spawnloc = spawnpoints[numagents]
var/mob/dead/observer/chosen_candidate = pick(candidates)
var/mob/chosen_candidate = pick(candidates)
candidates -= chosen_candidate
if(!chosen_candidate.key)
continue
+2 -2
View File
@@ -166,7 +166,7 @@
if(!can_buy(40))
return
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as a [blob_reagent_datum.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50) //players must answer rapidly
var/list/mob/candidates = pollGhostCandidates("Do you want to play as a [blob_reagent_datum.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50) //players must answer rapidly
if(LAZYLEN(candidates)) //if we got at least one candidate, they're a blobbernaut now.
B.max_integrity = initial(B.max_integrity) * 0.25 //factories that produced a blobbernaut have much lower health
B.obj_integrity = min(B.obj_integrity, B.max_integrity)
@@ -181,7 +181,7 @@
blobber.update_icons()
blobber.adjustHealth(blobber.maxHealth * 0.5)
blob_mobs += blobber
var/mob/dead/observer/C = pick(candidates)
var/mob/C = pick(candidates)
C.transfer_ckey(blobber)
SEND_SOUND(blobber, sound('sound/effects/blobattack.ogg'))
SEND_SOUND(blobber, sound('sound/effects/attackblob.ogg'))
@@ -61,8 +61,6 @@
//Actually transfer the gas
var/datum/gas_mixture/removed = air2.remove(transfer_moles)
removed.react(src)
update_parents()
return removed
-4
View File
@@ -80,7 +80,3 @@
var/next_keysend_reset = 0
var/next_keysend_trip_reset = 0
var/keysend_tripped = FALSE
// stops players from coming back through ghost/midround roles after suicide/cryo
// for a duration set by CONFIG_GET(number/suicide_reenter_round_timer) and CONFIG_GET(number/roundstart_suicide_time_limit)
var/reenter_round_timeout = 0
+12
View File
@@ -21,6 +21,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/last_ip
var/last_id
var/icon/custom_holoform_icon
var/list/cached_holoform_icons
var/last_custom_holoform = 0
//Cooldowns for saving/loading. These are four are all separate due to loading code calling these one after another
var/saveprefcooldown
var/loadprefcooldown
@@ -2422,3 +2426,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
return
else
custom_names[name_id] = sanitized_name
/datum/preferences/proc/get_filtered_holoform(filter_type)
if(!custom_holoform_icon)
return
LAZYINITLIST(cached_holoform_icons)
if(!cached_holoform_icons[filter_type])
cached_holoform_icons[filter_type] = process_holoform_icon_filter(custom_holoform_icon, filter_type)
return cached_holoform_icons[filter_type]
-1
View File
@@ -57,7 +57,6 @@
//No idea what this is but eh -tori
var/force_alternate_icon = FALSE
/obj/item/clothing/Initialize()
. = ..()
if(CHECK_BITFIELD(clothing_flags, VOICEBOX_TOGGLABLE))
+4 -1
View File
@@ -627,7 +627,9 @@
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage, /obj/item/construction/rcd, /obj/item/pipe_dispenser)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient/mason
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | IMMUTABLE_SLOW
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
flags_1 = TESLA_IGNORE_1
/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason
name = "M.A.S.O.N RIG helmet"
@@ -637,12 +639,13 @@
armor = list("melee" = 20, "bullet" = 15, "laser" = 15, "energy" = 45, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
item_color = "ancient"
brightness_on = 16
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS
flash_protect = 5 //We will not be flash by bombs
tint = 1
var/obj/machinery/doppler_array/integrated/bomb_radar
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
flags_1 = TESLA_IGNORE_1
/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/Initialize()
. = ..()
+1 -1
View File
@@ -75,7 +75,7 @@
/datum/round_event/santa/start()
var/list/candidates = pollGhostCandidates("Santa is coming to town! Do you want to be Santa?", poll_time=150)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
var/mob/C = pick(candidates)
santa = new /mob/living/carbon/human(pick(GLOB.blobstart))
C.transfer_ckey(santa, FALSE)
@@ -439,7 +439,6 @@
desc = "Quinine tastes funny, but at least it'll keep that Space Malaria away."
icon_state = "tonic"
list_reagents = list("tonic" = 50)
foodtype = ALCOHOL
/obj/item/reagent_containers/food/drinks/soda_cans/sodawater
name = "soda water"
@@ -84,14 +84,6 @@
required_temp = 413
mob_react = FALSE
/datum/chemical_reaction/caramel_burned
name = "Caramel burned"
id = "caramel_burned"
results = list("carbon" = 1)
required_reagents = list("caramel" = 1)
required_temp = 483
mob_react = FALSE
/datum/chemical_reaction/cheesewheel
name = "Cheesewheel"
id = "cheesewheel"
@@ -182,4 +174,4 @@
name = "BBQ Sauce"
id = "bbqsauce"
results = list("bbqsauce" = 5)
required_reagents = list("ash" = 1, "tomatojuice" = 1, "salglu_solution" = 3, "blackpepper" = 1)
required_reagents = list("ash" = 1, "tomatojuice" = 1, "salglu_solution" = 3, "blackpepper" = 1)
+1
View File
@@ -117,6 +117,7 @@
anchored = TRUE
max_integrity = 30
layer = LATTICE_LAYER
light_power = 0.3
var/hidden_message
var/creator_key
@@ -27,12 +27,7 @@
/datum/preferences/proc/update_preview_icon(equip_job = TRUE)
// Determine what job is marked as 'High' priority, and dress them up as such.
var/datum/job/previewJob
var/highest_pref = 0
for(var/job in job_preferences)
if(job_preferences["[job]"] > highest_pref)
previewJob = SSjob.GetJob(job)
highest_pref = job_preferences["[job]"]
var/datum/job/previewJob = get_highest_job()
if(previewJob)
// Silicons only need a very basic preview since there is no customization for them.
@@ -57,3 +52,11 @@
parent.show_character_previews(new /mutable_appearance(mannequin))
unset_busy_human_dummy(DUMMY_HUMAN_SLOT_PREFERENCES)
/datum/preferences/proc/get_highest_job()
var/highest_pref = 0
var/datum/job/highest_job
for(var/job in job_preferences)
if(job_preferences["[job]"] > highest_pref)
highest_job = SSjob.GetJob(job)
highest_pref = job_preferences["[job]"]
return highest_job
-3
View File
@@ -18,6 +18,3 @@
update_icon(preferred_form)
updateghostimages()
client.reenter_round_timeout = max(client.reenter_round_timeout, clientless_round_timeout)
clientless_round_timeout = client.reenter_round_timeout
+4 -24
View File
@@ -19,7 +19,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
hud_type = /datum/hud/ghost
movement_type = GROUND | FLYING
var/can_reenter_corpse
var/clientless_round_timeout = 0 //mobs will lack a client as long as their player is disconnected. See client_defines.dm "reenter_round_timeout"
var/datum/hud/living/carbon/hud = null // hud
var/bootime = 0
var/started_as_observer //This variable is set to 1 when you enter the game as an observer.
@@ -135,7 +134,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
AA.onNewMob(src)
. = ..()
AddElement(/datum/element/ghost_role_eligibility)
grant_all_languages()
/mob/dead/observer/get_photo_description(obj/item/camera/camera)
@@ -270,23 +269,12 @@ Works together with spawning an observer, noted above.
var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
ghost.can_reenter_corpse = can_reenter_corpse
if(penalize) //penalizing them from making a ghost role / midround antag comeback right away.
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
if(world.time < roundstart_quit_limit) //add up the time difference to their antag rolling penalty if they quit before half a (ingame) hour even passed.
penalty += roundstart_quit_limit - world.time
if(penalty)
penalty += world.realtime
if(penalty - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
penalty = CANT_REENTER_ROUND
if(client)
client.reenter_round_timeout = penalty
else //A disconnected player (quite likely for cryopods)
ghost.clientless_round_timeout = penalty
if (client && client.prefs && client.prefs.auto_ooc)
if (!(client.prefs.chat_toggles & CHAT_OOC))
client.prefs.chat_toggles ^= CHAT_OOC
transfer_ckey(ghost, FALSE)
ghost.AddElement(/datum/element/ghost_role_eligibility,penalize) // technically already run earlier, but this adds the penalty
// needs to be done AFTER the ckey transfer, too
return ghost
/*
@@ -343,15 +331,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
ghostize(0, penalize = TRUE)
/mob/dead/observer/proc/can_reenter_round(silent = FALSE)
var/timeout = clientless_round_timeout
if(client)
timeout = client.reenter_round_timeout
if(timeout != CANT_REENTER_ROUND && timeout <= world.realtime)
return TRUE
if(!silent && client)
to_chat(src, "<span class='warning'>You are unable to reenter the round[timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(timeout - world.realtime)]" : ""].</span>")
return FALSE
/mob/dead/observer/Move(NewLoc, direct)
if(updatedir)
@@ -14,10 +14,9 @@
var/max_grown = 100
var/time_of_birth
rotate_on_lying = 0
rotate_on_lying = FALSE
bodyparts = list(/obj/item/bodypart/chest/larva, /obj/item/bodypart/head/larva)
//This is fine right now, if we're adding organ specific damage this needs to be updated
/mob/living/carbon/alien/larva/Initialize()
@@ -40,7 +40,7 @@
var/gib_type = /obj/effect/decal/cleanable/blood/gibs
var/rotate_on_lying = 1
rotate_on_lying = TRUE
var/tinttotal = 0 // Total level of visualy impairing items
+1
View File
@@ -22,6 +22,7 @@
muzzle_ignore = TRUE
restraint_check = TRUE
emote_type = EMOTE_AUDIBLE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/carbon/clap/run_emote(mob/living/user, params)
. = ..()
@@ -333,7 +333,7 @@
switch (severity)
if (1)
if(bomb_armor)
b_loss = 500*bomb_armor
b_loss = (350*bomb_armor)+150
var/atom/throw_target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src)))
throw_at(throw_target, 200, 4)
damage_clothes(400*bomb_armor, BRUTE, "bomb")
@@ -1,31 +1,3 @@
//IMPORTANT: Multiple animate() calls do not stack well, so try to do them all at once if you can.
/mob/living/carbon/update_transform()
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
var/final_pixel_y = pixel_y
var/final_dir = dir
var/changed = 0
if(lying != lying_prev && rotate_on_lying)
changed++
ntransform.TurnTo(lying_prev,lying)
if(lying == 0) //Lying to standing
final_pixel_y = get_standard_pixel_y_offset()
else //if(lying != 0)
if(lying_prev == 0) //Standing to lying
pixel_y = get_standard_pixel_y_offset()
final_pixel_y = get_standard_pixel_y_offset(lying)
if(dir & (EAST|WEST)) //Facing east or west
final_dir = pick(NORTH, SOUTH) //So you fall on your side rather than your face or ass
if(resize != RESIZE_DEFAULT_SIZE)
changed++
ntransform.Scale(resize)
resize = RESIZE_DEFAULT_SIZE
if(changed)
animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, dir = final_dir, easing = EASE_IN|EASE_OUT)
setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life().
/mob/living/carbon
var/list/overlays_standing[TOTAL_LAYERS]
+3 -1
View File
@@ -111,4 +111,6 @@
var/list/diseases = list() // list of all diseases in a mob
var/list/disease_resistances = list()
var/drag_slowdown = TRUE //Whether the mob is slowed down when dragging another prone mob
var/drag_slowdown = TRUE //Whether the mob is slowed down when dragging another prone mob
var/rotate_on_lying = FALSE
+8 -3
View File
@@ -672,18 +672,23 @@
"green face" = 'icons/mob/ai.dmi',
"xeno queen" = 'icons/mob/alien.dmi',
"horror" = 'icons/mob/ai.dmi',
"creature" = 'icons/mob/ai.dmi'
"creature" = 'icons/mob/ai.dmi',
"custom"
)
input = input("Please select a hologram:") as null|anything in icon_list
if(input)
qdel(holo_icon)
switch(input)
if("xeno queen")
if("custom")
if(client?.prefs?.custom_holoform_icon)
holo_icon = client.prefs.get_filtered_holoform(HOLOFORM_FILTER_AI)
else
holo_icon = getHologramIcon(icon('icons/mob/ai.dmi', "female"))
else if("xeno queen")
holo_icon = getHologramIcon(icon(icon_list[input],"alienq"))
else
holo_icon = getHologramIcon(icon(icon_list[input], input))
return
/mob/living/silicon/ai/proc/corereturn()
set category = "Malfunction"
@@ -68,7 +68,7 @@
// Use this when setting the aiEye's location.
// It will also stream the chunk that the new loc is in.
/mob/camera/aiEye/proc/setLoc(T, force_update = FALSE)
/mob/camera/aiEye/proc/setLoc(T, force_update = FALSE, dir)
if(ai)
if(!isturf(ai.loc))
return
@@ -88,7 +88,7 @@
//Holopad
if(istype(ai.current, /obj/machinery/holopad))
var/obj/machinery/holopad/H = ai.current
H.move_hologram(ai, T)
H.move_hologram(ai, T, dir)
if(ai.camera_light_on)
ai.light_cameras()
if(ai.master_multicam)
@@ -139,7 +139,7 @@
for(var/i = 0; i < max(user.sprint, initial); i += 20)
var/turf/step = get_turf(get_step(user.eyeobj, direct))
if(step)
user.eyeobj.setLoc(step)
user.eyeobj.setLoc(step, null, direct)
user.cooldown = world.timeofday + 5
if(user.acceleration)
@@ -0,0 +1,28 @@
/mob/living/silicon/verb/clear_custom_holoform()
set name = "Clear Custom Holoform"
set desc = "Clear your current custom holoform"
set category = "OOC"
if(!client.prefs)
to_chat(src, "<span class='boldwarning'>No preferences datum on your client, contact an admin/coder!</span>")
return
client.prefs.custom_holoform_icon = null
client.prefs.cached_holoform_icons = null
to_chat(src, "<span class='boldnotice'>Holoform removed.</span>")
/mob/living/silicon/verb/set_custom_holoform()
set name = "Set Custom Holoform"
set desc = "Set your custom holoform using your current preferences slot and a specified set of gear."
set category = "OOC"
if(!client.prefs)
to_chat(src, "<span class='boldwarning'>No preferences datum on your client, contact an admin/coder!</span>")
return
if(client.prefs.last_custom_holoform > world.time - CUSTOM_HOLOFORM_DELAY)
to_chat(src, "<span class='warning'>You are attempting to change custom holoforms too fast!</span>")
var/icon/new_holoform = user_interface_custom_holoform(client)
if(new_holoform)
client.prefs.custom_holoform_icon = new_holoform
client.prefs.cached_holoform_icons = null
client.prefs.last_custom_holoform = world.time
to_chat(src, "<span class='boldnotice'>Holoform set.</span>")
+151 -16
View File
@@ -58,10 +58,12 @@
var/canholo = TRUE
var/obj/item/card/id/access_card = null
var/chassis = "repairbot"
var/list/possible_chassis = list("cat" = TRUE, "mouse" = TRUE, "monkey" = TRUE, "corgi" = FALSE,
"fox" = FALSE, "repairbot" = TRUE, "rabbit" = TRUE, "borgi" = FALSE ,
"parrot" = FALSE, "bear" = FALSE , "mushroom" = FALSE, "crow" = FALSE ,
"fairy" = FALSE , "spiderbot" = FALSE) //assoc value is whether it can be picked up.
var/dynamic_chassis
var/dynamic_chassis_sit = FALSE //whether we're sitting instead of resting spritewise
var/dynamic_chassis_bellyup = FALSE //whether we're lying down bellyup
var/list/possible_chassis //initialized in initialize.
var/list/dynamic_chassis_icons //ditto.
var/list/chassis_pixel_offsets_x //stupid dogborgs
var/static/item_head_icon = 'icons/mob/pai_item_head.dmi'
var/static/item_lh_icon = 'icons/mob/pai_item_lh.dmi'
var/static/item_rh_icon = 'icons/mob/pai_item_rh.dmi'
@@ -69,22 +71,20 @@
var/emitterhealth = 20
var/emittermaxhealth = 20
var/emitterregen = 0.25
var/emitter_next_use = 0
var/emitter_emp_cd = 300
var/emittercd = 50
var/emitteroverloadcd = 100
var/emittersemicd = FALSE
var/overload_ventcrawl = 0
var/overload_bulletblock = 0 //Why is this a good idea?
var/overload_maxhealth = 0
var/radio_short = FALSE
var/radio_short_cooldown = 5 MINUTES
var/radio_short_timerid
canmove = FALSE
var/silent = FALSE
var/brightness_power = 5
/mob/living/silicon/pai/can_unbuckle()
return FALSE
/mob/living/silicon/pai/can_buckle()
return FALSE
var/icon/custom_holoform_icon
/mob/living/silicon/pai/Destroy()
if (loc != card)
@@ -118,6 +118,13 @@
pda.owner = text("[]", src)
pda.name = pda.owner + " (" + pda.ownjob + ")"
possible_chassis = typelist(NAMEOF(src, possible_chassis), list("cat" = TRUE, "mouse" = TRUE, "monkey" = TRUE, "corgi" = FALSE,
"fox" = FALSE, "repairbot" = TRUE, "rabbit" = TRUE, "borgi" = FALSE ,
"parrot" = FALSE, "bear" = FALSE , "mushroom" = FALSE, "crow" = FALSE ,
"fairy" = FALSE , "spiderbot" = FALSE)) //assoc value is whether it can be picked up.
dynamic_chassis_icons = typelist(NAMEOF(src, dynamic_chassis_icons), initialize_dynamic_chassis_icons())
chassis_pixel_offsets_x = typelist(NAMEOF(src, chassis_pixel_offsets_x), default_chassis_pixel_offsets_x())
. = ..()
var/datum/action/innate/pai/software/SW = new
@@ -133,8 +140,7 @@
AR.Grant(src)
AL.Grant(src)
ALM.Grant(src)
emittersemicd = TRUE
addtimer(CALLBACK(src, .proc/emittercool), 600)
emitter_next_use = world.time + 10 SECONDS
/mob/living/silicon/pai/Life()
if(hacking)
@@ -228,7 +234,7 @@
/datum/action/innate/pai/shell/Trigger()
..()
if(P.holoform)
P.fold_in(0)
P.fold_in(FALSE)
else
P.fold_out()
@@ -292,3 +298,132 @@
/mob/living/silicon/pai/process()
emitterhealth = CLAMP((emitterhealth + emitterregen), -50, emittermaxhealth)
/mob/living/silicon/pai/proc/short_radio()
if(radio_short_timerid)
deltimer(radio_short_timerid)
radio_short = TRUE
to_chat(src, "<span class='danger'>Your radio shorts out!</span>")
radio_short_timerid = addtimer(CALLBACK(src, .proc/unshort_radio), radio_short_cooldown, flags = TIMER_STOPPABLE)
/mob/living/silicon/pai/proc/unshort_radio()
radio_short = FALSE
to_chat(src, "<span class='danger'>You feel your radio is operational once more.</span>")
if(radio_short_timerid)
deltimer(radio_short_timerid)
/mob/living/silicon/pai/proc/initialize_dynamic_chassis_icons()
. = list()
var/icon/curr //for inserts
//This is a horrible system and I wish I was not as lazy and did something smarter, like just generating a new icon in memory which is probably more efficient.
//Basic /tg/ cyborgs
.["Cyborg - Engineering (default)"] = process_holoform_icon_filter(icon('icons/mob/robots.dmi', "engineer"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Engineering (loaderborg)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "loaderborg"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Engineering (handyeng)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "handyeng"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Engineering (sleekeng)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "sleekeng"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Engineering (marinaeng)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "marinaeng"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Medical (default)"] = process_holoform_icon_filter(icon('icons/mob/robots.dmi', "medical"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Medical (marinamed)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "marinamed"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Medical (eyebotmed)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "eyebotmed"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Security (default)"] = process_holoform_icon_filter(icon('icons/mob/robots.dmi', "sec"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Security (sleeksec)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "sleeksec"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Security (marinasec)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/robots.dmi', "marinasec"), HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Clown (default)"] = process_holoform_icon_filter(icon('icons/mob/robots.dmi', "clown"), HOLOFORM_FILTER_PAI, FALSE)
//Citadel dogborgs
//Engi
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "valeeng")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeeng-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeeng-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeeng-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Engineering (dog - valeeng)"] = curr
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "pupdozer")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "pupdozer-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "pupdozer-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "pupdozer-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Engineering (dog - pupdozer)"] = curr
//Med
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "medihound")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "medihound-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "medihound-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "medihound-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Medical (dog - medihound)"] = curr
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "medihounddark")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "medihounddark-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "medihounddark-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "medihounddark-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Medical (dog - medihounddark)"] = curr
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "valemed")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valemed-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valemed-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valemed-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Medical (dog - valemed)"] = curr
//Sec
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "k9")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "k9-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "k9-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "k9-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Security (dog - k9)"] = curr
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "k9dark")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "k9dark-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "k9dark-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "k9dark-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Security (dog - k9dark)"] = curr
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "valesec")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valesec-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valesec-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valesec-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Security (dog - valesec)"] = curr
//Service
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "valeserv")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeserv-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeserv-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeserv-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Service (dog - valeserv)"] = curr
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "valeservdark")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeservdark-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeservdark-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valeservdark-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Service (dog - valeservdark)"] = curr
//Sci
curr = icon('modular_citadel/icons/mob/widerobot.dmi', "valesci")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valesci-rest"), "rest")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valesci-sit"), "sit")
curr.Insert(icon('modular_citadel/icons/mob/widerobot.dmi', "valesci-bellyup"), "bellyup")
process_holoform_icon_filter(curr, HOLOFORM_FILTER_PAI, FALSE)
.["Cyborg - Science (dog - valesci)"] = curr
//Misc
.["Cyborg - Misc (dog - blade)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/widerobot.dmi', "blade"), HOLOFORM_FILTER_PAI, FALSE)
/mob/living/silicon/pai/proc/default_chassis_pixel_offsets_x()
. = list()
//Engi
.["Cyborg - Engineering (dog - valeeng)"] = -16
.["Cyborg - Engineering (dog - pupdozer)"] = -16
//Med
.["Cyborg - Medical (dog - medihound)"] = -16
.["Cyborg - Medical (dog - medihounddark)"] = -16
.["Cyborg - Medical (dog - valemed)"] = -16
//Sec
.["Cyborg - Security (dog - k9)"] = -16
.["Cyborg - Security (dog - valesec)"] = -16
.["Cyborg - Security (dog - k9dark)"] = -16
//Service
.["Cyborg - Service (dog - valeserv)"] = -16
.["Cyborg - Service (dog - valeservdark)"] = -16
//Sci
.["Cyborg - Security (dog - valesci)"] = -16
//Misc
.["Cyborg - Misc (dog - blade)"] = -16
@@ -8,9 +8,10 @@
return
take_holo_damage(50/severity)
Knockdown(400/severity)
silent = max(30/severity, silent)
silent = max((3 MINUTES)/severity, silent)
if(holoform)
fold_in(force = TRUE)
emitter_next_use = world.time + emitter_emp_cd
//Need more effects that aren't instadeath or permanent law corruption.
/mob/living/silicon/pai/ex_act(severity, target)
@@ -12,12 +12,11 @@
. = fold_in(force)
return
if(emittersemicd)
if(world.time < emitter_next_use)
to_chat(src, "<span class='warning'>Error: Holochassis emitters recycling. Please try again later.</span>")
return FALSE
emittersemicd = TRUE
addtimer(CALLBACK(src, .proc/emittercool), emittercd)
emitter_next_use = world.time + emittercd
canmove = TRUE
density = TRUE
if(istype(card.loc, /obj/item/pda))
@@ -46,20 +45,17 @@
visible_message("<span class='boldnotice'>[src] folds out its holochassis emitter and forms a holoshell around itself!</span>")
holoform = TRUE
/mob/living/silicon/pai/proc/emittercool()
emittersemicd = FALSE
/mob/living/silicon/pai/proc/fold_in(force = FALSE)
emittersemicd = TRUE
if(!force)
addtimer(CALLBACK(src, .proc/emittercool), emittercd)
else
addtimer(CALLBACK(src, .proc/emittercool), emitteroverloadcd)
emitter_next_use = world.time + (force? emitteroverloadcd : emittercd)
icon_state = "[chassis]"
if(!holoform)
. = fold_out(force)
return
visible_message("<span class='notice'>[src] deactivates its holochassis emitter and folds back into a compact card!</span>")
if(force)
short_radio()
visible_message("<span class='warning'>[src] shorts out, collapsing back into their storage card, sparks emitted from their radio antenna!</span>")
else
visible_message("<span class='notice'>[src] deactivates its holochassis emitter and folds back into a compact card!</span>")
stop_pulling()
if(client)
client.perspective = EYE_PERSPECTIVE
@@ -78,28 +74,39 @@
if(!isturf(loc) && loc != card)
to_chat(src, "<span class='boldwarning'>You can not change your holochassis composite while not on the ground or in your card!</span>")
return FALSE
var/choice = input(src, "What would you like to use for your holochassis composite?") as null|anything in possible_chassis
if(!choice)
var/list/choices = list("Preset - Basic", "Preset - Dynamic")
if(CONFIG_GET(flag/pai_custom_holoforms))
choices += "Custom"
var/choicetype = input(src, "What type of chassis do you want to use?") as null|anything in choices
if(!choicetype)
return FALSE
chassis = choice
icon_state = "[chassis]"
if(resting)
icon_state = "[chassis]_rest"
switch(choicetype)
if("Custom")
chassis = "custom"
if("Preset - Basic")
var/choice = input(src, "What would you like to use for your holochassis composite?") as null|anything in possible_chassis
if(!choice)
return FALSE
chassis = choice
if("Preset - Dynamic")
var/choice = input(src, "What would you like to use for your holochassis composite?") as null|anything in dynamic_chassis_icons
if(!choice)
return FALSE
chassis = "dynamic"
dynamic_chassis = choice
resist_a_rest(FALSE, TRUE)
update_icon()
to_chat(src, "<span class='boldnotice'>You switch your holochassis projection composite to [chassis]</span>")
/mob/living/silicon/pai/lay_down()
..()
update_resting_icon(resting)
/mob/living/silicon/pai/proc/update_resting_icon(rest)
if(rest)
icon_state = "[chassis]_rest"
else
icon_state = "[chassis]"
. = ..()
if(loc != card)
visible_message("<span class='notice'>[src] [rest? "lays down for a moment..." : "perks up from the ground"]</span>")
visible_message("<span class='notice'>[src] [resting? "lays down for a moment..." : "perks up from the ground"]</span>")
update_icon()
/mob/living/silicon/pai/start_pulling(atom/movable/AM)
/mob/living/silicon/pai/start_pulling(atom/movable/AM, gs)
if(ispAI(AM))
return ..()
return FALSE
/mob/living/silicon/pai/proc/toggle_integrated_light()
@@ -122,3 +129,22 @@
to_chat(user, "<span class='warning'>[src]'s current form isn't able to be carried!</span>")
return FALSE
return ..()
/mob/living/silicon/pai/verb/toggle_chassis_sit()
set name = "Toggle Chassis Sit"
set category = "IC"
set desc = "Whether or not to try to use a sitting icon versus a resting icon. Takes priority over belly-up resting."
dynamic_chassis_sit = !dynamic_chassis_sit
to_chat(usr, "<span class='boldnotice'>You are now [dynamic_chassis_sit? "sitting" : "lying down"].</span>")
update_icon()
/mob/living/silicon/pai/verb/toggle_chassis_bellyup()
set name = "Toggle Chassis Belly Up"
set category = "IC"
set desc = "Whether or not to try to use a belly up icon while resting. Overridden by sitting."
dynamic_chassis_bellyup = !dynamic_chassis_bellyup
to_chat(usr, "<span class='boldnotice'>You are now lying on your [dynamic_chassis_bellyup? "back" : "front"].</span>")
update_icon()
/mob/living/silicon/pai/can_buckle_others(mob/living/target, atom/buckle_to)
return ispAI(target) && ..()
+8 -1
View File
@@ -5,4 +5,11 @@
..(message)
/mob/living/silicon/pai/binarycheck()
return 0
return FALSE
/mob/living/silicon/pai/radio(message, message_mode, list/spans, language)
if((message_mode == "robot") || (message_mode in GLOB.radiochannels))
if(radio_short)
to_chat(src, "<span class='warning'>Your radio is shorted out!</span>")
return ITALICS | REDUCE_RANGE
return ..()
@@ -283,7 +283,10 @@
dat += "<A href='byond://?src=[REF(src)];software=refresh'>Refresh</A><br>"
// Built-in
dat += "<A href='byond://?src=[REF(src)];software=directives'>Directives</A><br>"
dat += "<A href='byond://?src=[REF(src)];software=radio;sub=0'>Radio Configuration</A><br>"
if(radio_short)
dat += "\[RADIO SHORTED - Recalibrating!\]"
else
dat += "<A href='byond://?src=[REF(src)];software=radio;sub=0'>Radio Configuration</A><br>"
dat += "<A href='byond://?src=[REF(src)];software=image'>Screen Display</A><br>"
//dat += "Text Messaging <br>"
dat += "<br>"
@@ -0,0 +1,27 @@
/mob/living/silicon/pai/update_icon()
if(chassis == "custom") //Make sure custom exists if it's set to custom
custom_holoform_icon = client?.prefs?.get_filtered_holoform(HOLOFORM_FILTER_PAI)
if(!custom_holoform_icon)
chassis = pick(possible_chassis - "custom")
if(chassis == "dynamic") //handle dynamic generated icons
icon = dynamic_chassis_icons[dynamic_chassis]
var/list/states = icon_states(icon)
icon_state = ""
if(resting) //The next line is some bullshit but I can make it worse if you want and make it a single line instead of four.. :)
if(dynamic_chassis_sit && ("sit") in states)
icon_state = "sit"
else if(dynamic_chassis_bellyup && ("bellyup") in states)
icon_state = "bellyup"
else if("rest" in states)
icon_state = "rest"
rotate_on_lying = FALSE
else if(chassis == "custom")
icon = custom_holoform_icon
icon_state = ""
rotate_on_lying = TRUE
else
icon = initial(icon)
icon_state = "[chassis][resting? "_rest" : (stat == DEAD? "_dead" : "")]"
rotate_on_lying = FALSE
pixel_x = ((chassis == "dynamic") && chassis_pixel_offsets_x[dynamic_chassis]) || 0
update_transform()
@@ -130,6 +130,7 @@
hacked = TRUE
visualAppearence = CLOCKDRONE
can_be_held = FALSE
mouse_opacity = MOUSE_OPACITY_OPAQUE
flavortext = "<b><span class='nezbere'>You are a cogscarab,</span> a tiny building construct of Ratvar. While you're weak and can't recite scripture, \
you have a set of quick tools, as well as a replica fabricator that can create brass and convert objects.<br><br>Work with the servants of Ratvar \
to construct and maintain defenses at the City of Cogs. If there are no servants, use this time to experiment with base designs!"
@@ -424,9 +424,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
var/mob/living/simple_animal/hostile/guardian/G = input(src, "Pick the guardian you wish to reset", "Guardian Reset") as null|anything in guardians
if(G)
to_chat(src, "<span class='holoparasite'>You attempt to reset <font color=\"[G.namedatum.colour]\"><b>[G.real_name]</b></font>'s personality...</span>")
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as [src.real_name]'s [G.real_name]?", ROLE_PAI, null, FALSE, 100)
var/list/mob/candidates = pollGhostCandidates("Do you want to play as [src.real_name]'s [G.real_name]?", ROLE_PAI, null, FALSE, 100)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
var/mob/C = pick(candidates)
to_chat(G, "<span class='holoparasite'>Your user reset you, and your body was taken over by a ghost. Looks like they weren't happy with your performance.</span>")
to_chat(src, "<span class='holoparasite bold'>Your <font color=\"[G.namedatum.colour]\">[G.real_name]</font> has been successfully reset.</span>")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(G)])")
@@ -498,10 +498,10 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
return
used = TRUE
to_chat(user, "[use_message]")
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the [mob_name] of [user.real_name]?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_HOLOPARASITE)
var/list/mob/candidates = pollGhostCandidates("Do you want to play as the [mob_name] of [user.real_name]?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_HOLOPARASITE)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
var/mob/C = pick(candidates)
spawn_guardian(user, C.key)
else
to_chat(user, "[failure_message]")
+26
View File
@@ -0,0 +1,26 @@
//IMPORTANT: Multiple animate() calls do not stack well, so try to do them all at once if you can.
/mob/living/update_transform()
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
var/final_pixel_y = pixel_y
var/final_dir = dir
var/changed = 0
if(lying != lying_prev && rotate_on_lying)
changed++
ntransform.TurnTo(lying_prev,lying)
if(lying == 0) //Lying to standing
final_pixel_y = get_standard_pixel_y_offset()
else //if(lying != 0)
if(lying_prev == 0) //Standing to lying
pixel_y = get_standard_pixel_y_offset()
final_pixel_y = get_standard_pixel_y_offset(lying)
if(dir & (EAST|WEST)) //Facing east or west
final_dir = pick(NORTH, SOUTH) //So you fall on your side rather than your face or ass
if(resize != RESIZE_DEFAULT_SIZE)
changed++
ntransform.Scale(resize)
resize = RESIZE_DEFAULT_SIZE
if(changed)
animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, dir = final_dir, easing = EASE_IN|EASE_OUT)
setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life().
+13 -11
View File
@@ -567,9 +567,9 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
/mob/proc/is_muzzled()
return 0
/mob/Stat(delayoverride)
. = ..()
var/statdelay = delayoverride || 10
/mob/Stat()
..()
if(statpanel("Status"))
if (client)
stat(null, "Ping: [round(client.lastping, 1)]ms (Average: [round(client.avgping, 1)]ms)")
@@ -577,7 +577,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
var/datum/map_config/cached = SSmapping.next_map_config
if(cached)
stat(null, "Next Map: [cached.map_name]")
stat(null, "Round ID: [GLOB.round_id || "NULL"]")
stat(null, "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]")
stat(null, "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]")
stat(null, "Round Time: [WORLDTIME2TEXT("hh:mm:ss")]")
stat(null, "Station Time: [STATION_TIME_TIMESTAMP("hh:mm:ss")]")
@@ -587,9 +587,8 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
if(ETA)
stat(null, "[ETA] [SSshuttle.emergency.getTimerStr()]")
if(client?.holder)
if(client && client.holder)
if(statpanel("MC"))
statdelay = 0 //It's assumed that if you're doing this you are doing debug stuff, don't do ioditic things.
var/turf/T = get_turf(client.eye)
stat("Location:", COORD(T))
stat("CPU:", "[world.cpu]")
@@ -615,7 +614,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
GLOB.ahelp_tickets.stat_entry()
if(length(GLOB.sdql2_queries))
if(statpanel("SDQL2"))
statdelay = 0 //It's assumed that if you're doing this you are doing debug stuff, don't do ioditic things.
stat("Access Global SDQL2 List", GLOB.sdql2_vv_statobj)
for(var/i in GLOB.sdql2_queries)
var/datum/SDQL2_query/Q = i
@@ -639,13 +637,14 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
if(A.IsObscured())
continue
statpanel(listed_turf.name, null, A)
if(mind)
add_spells_to_statpanel(mind.spell_list)
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
if(changeling)
add_stings_to_statpanel(changeling.purchasedpowers)
add_spells_to_statpanel(mob_spell_list)
sleep(statdelay)
/mob/proc/add_spells_to_statpanel(list/spells)
for(var/obj/effect/proc_holder/spell/S in spells)
@@ -802,11 +801,14 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
//can the mob be buckled to something by default?
/mob/proc/can_buckle()
return 1
return TRUE
//can the mob be unbuckled from something by default?
/mob/proc/can_unbuckle()
return 1
return TRUE
/mob/proc/can_buckle_others(mob/living/target, atom/buckle_to)
return TRUE
//Can the mob interact() with an atom?
/mob/proc/can_interact_with(atom/A)
@@ -958,4 +960,4 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
/mob/setMovetype(newval)
. = ..()
update_movespeed(FALSE)
update_movespeed(FALSE)
+1 -1
View File
@@ -65,7 +65,7 @@
if(delta_temperature > 0 && cold_air_heat_capacity > 0 && hot_air_heat_capacity > 0)
var/efficiency = 0.00025 + (hot_air.reaction_results["fire"]*0.01)
var/efficiency = 0.45
var/energy_transfer = delta_temperature*hot_air_heat_capacity*cold_air_heat_capacity/(hot_air_heat_capacity+cold_air_heat_capacity)
@@ -36,7 +36,9 @@ All effects don't start immediately, but rather get worse over time; the rate is
*/
/datum/reagent/consumable/ethanol/on_mob_life(mob/living/carbon/C)
if(C.drunkenness < volume * boozepwr * ALCOHOL_THRESHOLD_MODIFIER)
if(HAS_TRAIT(C, TRAIT_NO_ALCOHOL))
C.adjustToxLoss((boozepwr/25)*REM,forced = TRUE)
else if(C.drunkenness < volume * boozepwr * ALCOHOL_THRESHOLD_MODIFIER)
var/booze_power = boozepwr
if(HAS_TRAIT(C, TRAIT_ALCOHOL_TOLERANCE)) //we're an accomplished drinker
booze_power *= 0.7
@@ -142,9 +142,9 @@
/datum/chemical_reaction/fermis_plush
name = "Fermis plush"
id = "fermis_plush"
required_reagents = list("sugar" = 10, "blood" = 10, "stable_plasma" = 10)
required_reagents = list("caramel" = 10, "blood" = 10, "stable_plasma" = 10)
mob_react = FALSE
required_temp = 400
required_temp = 300
/datum/chemical_reaction/fermis_plush/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
+21 -1
View File
@@ -19,18 +19,38 @@
var/container_HP = 2
var/cached_icon
/obj/item/reagent_containers/verb/set_APTFT(mob/user) //set amount_per_transfer_from_this
set name = "Set Transfer Amount"
set category = "Object"
var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts
if(N)
amount_per_transfer_from_this = N
to_chat(user, "<span class='notice'>[src]'s transfer amount is now [amount_per_transfer_from_this] units.</span>")
/obj/item/reagent_containers/Initialize(mapload, vol)
. = ..()
if(isnum(vol) && vol > 0)
volume = vol
if(!possible_transfer_amounts)
src.verbs -= /obj/item/reagent_containers/verb/set_APTFT
create_reagents(volume, reagent_flags)
if(spawned_disease)
var/datum/disease/F = new spawned_disease()
var/list/data = list("blood_DNA" = "UNKNOWN DNA", "blood_type" = "SY","viruses"= list(F))
reagents.add_reagent("blood", disease_amount, data)
add_initial_reagents()
/obj/item/reagent_containers/examine(mob/user)
. = ..()
. += "Currently transferring [amount_per_transfer_from_this] units per use."
if(possible_transfer_amounts && user.Adjacent(src))
. += "<span class='notice'>Alt-click it to set its transfer amount.</span>"
/obj/item/reagent_containers/AltClick(mob/user)
. = ..()
if(possible_transfer_amounts && user.Adjacent(src))
set_APTFT()
/obj/item/reagent_containers/proc/add_initial_reagents()
if(list_reagents)
reagents.add_reagent_list(list_reagents)
@@ -115,7 +115,7 @@
icon_state = "beaker"
item_state = "beaker"
materials = list(MAT_GLASS=500)
possible_transfer_amounts = list(5,10,15,20,25,30,60)
possible_transfer_amounts = list(5,10,15,20,25,30,50,60)
beaker_weakness_bitflag = PH_WEAK
/obj/item/reagent_containers/glass/beaker/Initialize()
@@ -169,7 +169,7 @@
materials = list(MAT_GLASS=2500)
volume = 120
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,40,60,120)
possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120)
container_HP = 3
/obj/item/reagent_containers/glass/beaker/plastic
@@ -179,7 +179,7 @@
materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000)
volume = 180
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,40,60,120,180)
possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120,180)
/obj/item/reagent_containers/glass/beaker/plastic/Initialize()
beaker_weakness_bitflag &= ~PH_WEAK
@@ -198,7 +198,7 @@
materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000, MAT_GOLD=1000, MAT_TITANIUM=1000)
volume = 240
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,40,60,120,200,240)
possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120,200,240)
/obj/item/reagent_containers/glass/beaker/meta/Initialize() // why the fuck can't you just set the beaker weakness bitflags to nothing? fuck you
beaker_weakness_bitflag &= ~PH_WEAK
@@ -341,6 +341,7 @@
materials = list(MAT_GLASS=0)
volume = 50
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50)
container_HP = 1
/obj/item/reagent_containers/glass/beaker/waterbottle/Initialize()
@@ -357,6 +358,7 @@
list_reagents = list("water" = 100)
volume = 100
amount_per_transfer_from_this = 20
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
container_HP = 1
/obj/item/reagent_containers/glass/beaker/waterbottle/large/empty
@@ -62,11 +62,11 @@
/obj/item/reagent_containers/glass/bottle/vial/small
name = "hypovial"
volume = 60
possible_transfer_amounts = list(1,2,5,10,20,30)
possible_transfer_amounts = list(1,2,5,10,20)
/obj/item/reagent_containers/glass/bottle/vial/small/bluespace
volume = 120
possible_transfer_amounts = list(1,2,5,10,20,30,40)
possible_transfer_amounts = list(1,2,5,10,20)
name = "bluespace hypovial"
icon_state = "hypovialbs"
unique_reskin = null
@@ -76,7 +76,7 @@
desc = "A large hypovial, for deluxe hypospray models."
icon_state = "hypoviallarge"
volume = 120
possible_transfer_amounts = list(1,2,5,10,20,30,40,60)
possible_transfer_amounts = list(1,2,5,10,20)
unique_reskin = list("large hypovial" = "hypoviallarge",
"large red hypovial" = "hypoviallarge-b",
"large blue hypovial" = "hypoviallarge-d",
@@ -108,7 +108,7 @@
add_overlay(filling)
/obj/item/reagent_containers/glass/bottle/vial/large/bluespace
possible_transfer_amounts = list(1,2,5,10,20,30,40,60)
possible_transfer_amounts = list(1,2,5,10,20)
name = "bluespace large hypovial"
volume = 240
icon_state = "hypoviallargebs"
@@ -51,6 +51,22 @@
make_reagents = list()
category = list("initial","Food")
/datum/design/enzyme
name = "10u Universal Enzyme"
id = "enzyme"
build_type = BIOGENERATOR
materials = list(MAT_BIOMASS = 30)
make_reagents = list("enzyme" = 10)
category = list("initial","Food")
/datum/design/flour_sack
name = "Flour Sack"
id = "flour_sack"
build_type = BIOGENERATOR
materials = list(MAT_BIOMASS = 150)
build_path = /obj/item/reagent_containers/food/condiment/flour
category = list("initial","Food")
/datum/design/monkey_cube
name = "Monkey Cube"
id = "mcube"
+1 -1
View File
@@ -216,4 +216,4 @@
P.original = user
P.firer = user
P.fire()
return ..()
return ..()
@@ -78,8 +78,8 @@
hand_path = /obj/item/melee/touch_attack/nuclearfist
school = "evocation"
charge_max = 200
charge_max = 100
clothes_req = 0
cooldown_min = 40
cooldown_min = 20
action_icon_state = "nuclearfist"
action_icon_state = "nuclearfist"
-2061
View File
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,5 @@
author: "kevinz000"
delete-after: True
changes:
- rscadd: "Custom holoforms have been added for pAIs and AIs. oh and cyborg holograms of specific modules too."
- balance: "pais are no longer indestructible-flagged while in card form. pai radios now short out if they are forcefully collapsed from damage."
@@ -0,0 +1,4 @@
author: "Seris02"
delete-after: True
changes:
- tweak: "made it so trait blacklisting removes random positives instead of removing everything"
@@ -0,0 +1,4 @@
author: "Putnam"
delete-after: True
changes:
- rscadd: "Alcohol intolerance trait, which forces vomiting on any alcohol ingestion"
@@ -0,0 +1,4 @@
author: "Trilbyspaceclone"
delete-after: True
changes:
- bugfix: "Fermi plushie can be made once again"
@@ -0,0 +1,4 @@
author: "Trilbyspaceclone"
delete-after: True
changes:
- bugfix: "issues with mapping done my Trilby"
@@ -0,0 +1,7 @@
author: "Putnam3145"
delete-after: True
changes:
- rscadd: "Ghost cafe mobs can now ghostize"
- rscadd: "Ghost cafe now has a cremator"
- rscadd: "Ghost cafe mobs are now eligible for ghost roles"
- refactor: "Ghost roles now use an element for eligibility purposes"
@@ -0,0 +1,4 @@
author: "Trilbyspaceclone"
delete-after: True
changes:
- server: "Cleans out the last years of changlogs"
@@ -0,0 +1,4 @@
author: "EmeraldSundisk"
delete-after: True
changes:
- rscadd: "Adds a sign outside MetaStation's custodial closet"
@@ -0,0 +1,6 @@
author: "Unit2E & JMoldy, ported by Hatterhat"
delete-after: True
changes:
- balance: "the powerfist now punches people away at high velocity depending on setting."
- rscadd: "the powerfist now leaks the gas it uses onto the tile you're on."
- tweak: "Adds weak punch variations for empty and near-empty punching."
@@ -0,0 +1,4 @@
author: "kevinz000"
delete-after: True
changes:
- balance: "Cargo passive gen is now 500 down from 750."
@@ -0,0 +1,4 @@
author: "Linzolle"
delete-after: True
changes:
- bugfix: "fixes matchboxes runtiming every time they spawn"
@@ -0,0 +1,4 @@
author: "nik707"
delete-after: True
changes:
- tweak: "engraving light_power from 1 to 0.3"
@@ -0,0 +1,4 @@
author: "Hatterhat"
delete-after: True
changes:
- tweak: "tweaks some values around with beaker transfer amounts, adds a transfer value verb (altclick)"
@@ -0,0 +1,4 @@
author: "Putnam3145"
delete-after: True
changes:
- balance: "Devastating bombs kills bomb armor'd mobs again"
@@ -0,0 +1,4 @@
author: "Trilbyspaceclone"
delete-after: True
changes:
- tweak: "Adds missing but needed flags to MASON RIG"
@@ -0,0 +1,4 @@
author: "kevinz000"
delete-after: True
changes:
- balance: "nuclear fist buffed."
@@ -0,0 +1,4 @@
author: "Trilbyspaceclone"
delete-after: True
changes:
- bugfix: "missing sprites with crushed cans"
@@ -0,0 +1,4 @@
author: "kevinz000"
delete-after: True
changes:
- balance: "cogscarabs are now fulltile-hitbox."
@@ -0,0 +1,5 @@
author: "FantasticFwoosh, ported by Hatterhat"
delete-after: True
changes:
- rscadd: "Both reagent universal enzyme & sacks of flour are now available for their respective costs from the biogenerator."
- rscadd: "New crafting recipies for donut boxes, eggboxes & candle boxes have been added to cardboard recipes for the collective benefit of service personnel and the station."
Binary file not shown.

Before

Width:  |  Height:  |  Size: 865 KiB

After

Width:  |  Height:  |  Size: 868 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 26 KiB

+91 -72
View File
@@ -70,113 +70,124 @@
message = "makes a very loud noise."
. = ..()
/datum/emote/sound/carbon/snap
key = "snap"
key_third_person = "snaps"
muzzle_ignore = TRUE
restraint_check = TRUE
emote_type = EMOTE_AUDIBLE
sound = 'sound/effects/snap01.ogg'
mob_type_allowed_typecache = list(/mob/living/carbon/)
/datum/emote/living/snap
key = "snap"
key_third_person = "snaps"
message = "snaps their fingers."
emote_type = EMOTE_AUDIBLE
muzzle_ignore = TRUE
restraint_check = TRUE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/snap/run_emote(mob/living/user, params)
if(ishuman(user))
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/snap.ogg', 50, 1, -1)
. = ..()
if(!(. = ..()))
return
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/snap.ogg', 50, 1, -1)
/datum/emote/living/snap2
key = "snap2"
key_third_person = "snaps twice"
message = "snaps twice."
emote_type = EMOTE_AUDIBLE
muzzle_ignore = TRUE
restraint_check = TRUE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/snap2/run_emote(mob/living/user, params)
if(ishuman(user))
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/snap2.ogg', 50, 1, -1)
. = ..()
if(!(. = ..()))
return
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/snap2.ogg', 50, 1, -1)
/datum/emote/living/snap3
key = "snap3"
key_third_person = "snaps thrice"
message = "snaps thrice."
emote_type = EMOTE_AUDIBLE
muzzle_ignore = TRUE
restraint_check = TRUE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/snap3/run_emote(mob/living/user, params)
if(ishuman(user))
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/snap3.ogg', 50, 1, -1)
. = ..()
if(!(. = ..()))
return
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/snap3.ogg', 50, 1, -1)
/datum/emote/living/awoo
key = "awoo"
key_third_person = "lets out an awoo"
message = "lets out an awoo!"
emote_type = EMOTE_AUDIBLE
muzzle_ignore = FALSE
restraint_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/awoo/run_emote(mob/living/user, params)
if(ishuman(user))
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/awoo.ogg', 50, 1, -1)
. = ..()
if(!(. = ..()))
return
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/awoo.ogg', 50, 1, -1)
/datum/emote/living/nya
key = "nya"
key_third_person = "lets out a nya"
message = "lets out a nya!"
emote_type = EMOTE_AUDIBLE
muzzle_ignore = FALSE
restraint_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/nya/run_emote(mob/living/user, params)
if(ishuman(user))
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/nya.ogg', 50, 1, -1)
. = ..()
if(!(. = ..()))
return
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/nya.ogg', 50, 1, -1)
/datum/emote/living/weh
key = "weh"
key_third_person = "lets out a weh"
message = "lets out a weh!"
emote_type = EMOTE_AUDIBLE
muzzle_ignore = FALSE
restraint_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/weh/run_emote(mob/living/user, params)
if(ishuman(user))
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/weh.ogg', 50, 1, -1)
. = ..()
if(!(. = ..()))
return
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/weh.ogg', 50, 1, -1)
/datum/emote/living/peep
key = "peep"
key_third_person = "peeps like a bird"
message = "peeps like a bird!"
emote_type = EMOTE_AUDIBLE
muzzle_ignore = FALSE
restraint_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/peep/run_emote(mob/living/user, params)
if(ishuman(user))
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/peep.ogg', 50, 1, -1)
. = ..()
if(!(. = ..()))
return
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/peep.ogg', 50, 1, -1)
/datum/emote/living/dab
key = "dab"
@@ -190,41 +201,49 @@
key_third_person = "lets out a tiny squeak"
message = "lets out a tiny squeak!"
emote_type = EMOTE_AUDIBLE
mob_type_allowed_typecache = list(/mob/living/carbon)
muzzle_ignore = FALSE
restraint_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/mothsqueak/run_emote(mob/living/user, params)
if(ishuman(user))
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/mothsqueak.ogg', 50, 1, -1)
. = ..()
if(!(. = ..()))
return
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/mothsqueak.ogg', 50, 1, -1)
/datum/emote/living/merp
key = "merp"
key_third_person = "merps"
message = "merps!"
emote_type = EMOTE_AUDIBLE
muzzle_ignore = FALSE
restraint_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/merp/run_emote(mob/living/user, params)
if(ishuman(user))
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/merp.ogg', 50, 1, -1)
. = ..()
if(!(. = ..()))
return
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/merp.ogg', 50, 1, -1)
/datum/emote/living/bark
key = "bark"
key_third_person = "barks"
message = "barks!"
emote_type = EMOTE_AUDIBLE
muzzle_ignore = FALSE
restraint_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/bark/run_emote(mob/living/user, params)
if(ishuman(user))
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
var/sound = pick('modular_citadel/sound/voice/bark1.ogg', 'modular_citadel/sound/voice/bark2.ogg')
playsound(user, sound, 50, 1, -1)
. = ..()
if(!(. = ..()))
return
if(user.nextsoundemote >= world.time)
return
user.nextsoundemote = world.time + 7
var/sound = pick('modular_citadel/sound/voice/bark1.ogg', 'modular_citadel/sound/voice/bark2.ogg')
playsound(user, sound, 50, 1, -1)
@@ -105,7 +105,7 @@
name = "Eigenstasium"
id = "eigenstate"
results = list("eigenstate" = 1)
required_reagents = list("bluespace" = 1, "stable_plasma" = 1, "sugar" = 1)
required_reagents = list("bluespace" = 1, "stable_plasma" = 1, "caramel" = 1)
mix_message = "the reaction zaps suddenly!"
//FermiChem vars:
OptimalTempMin = 350 // Lower area of bell curve for determining heat based rate reactions
@@ -504,7 +504,7 @@
name = "secretcatchem"
id = "secretcatchem"
results = list("secretcatchem" = 5)
required_reagents = list("stable_plasma" = 1, "sugar" = 1, "cream" = 1, "clonexadone" = 1)//Yes this will make a kitty if you don't lucky guess. It'll eat all your reagents too.
required_reagents = list("stable_plasma" = 1, "caramel" = 1, "cream" = 1, "clonexadone" = 1)//Yes this will make a kitty if you don't lucky guess. It'll eat all your reagents too.
required_catalysts = list("SDGF" = 1)
required_temp = 500
mix_message = "the reaction gives off a meow!"
+5
View File
@@ -120,6 +120,7 @@
#include "code\__HELPERS\areas.dm"
#include "code\__HELPERS\AStar.dm"
#include "code\__HELPERS\cmp.dm"
#include "code\__HELPERS\custom_holoforms.dm"
#include "code\__HELPERS\dates.dm"
#include "code\__HELPERS\donator_groupings.dm"
#include "code\__HELPERS\files.dm"
@@ -469,6 +470,7 @@
#include "code\datums\elements\_element.dm"
#include "code\datums\elements\cleaning.dm"
#include "code\datums\elements\earhealing.dm"
#include "code\datums\elements\ghost_role_eligibility.dm"
#include "code\datums\helper_datums\events.dm"
#include "code\datums\helper_datums\getrev.dm"
#include "code\datums\helper_datums\icon_snapshot.dm"
@@ -2111,6 +2113,7 @@
#include "code\modules\mob\living\say.dm"
#include "code\modules\mob\living\status_procs.dm"
#include "code\modules\mob\living\taste.dm"
#include "code\modules\mob\living\update_icons.dm"
#include "code\modules\mob\living\ventcrawling.dm"
#include "code\modules\mob\living\brain\brain.dm"
#include "code\modules\mob\living\brain\brain_item.dm"
@@ -2217,6 +2220,7 @@
#include "code\modules\mob\living\carbon\monkey\monkey_defense.dm"
#include "code\modules\mob\living\carbon\monkey\punpun.dm"
#include "code\modules\mob\living\carbon\monkey\update_icons.dm"
#include "code\modules\mob\living\silicon\custom_holoform.dm"
#include "code\modules\mob\living\silicon\damage_procs.dm"
#include "code\modules\mob\living\silicon\death.dm"
#include "code\modules\mob\living\silicon\examine.dm"
@@ -2248,6 +2252,7 @@
#include "code\modules\mob\living\silicon\pai\personality.dm"
#include "code\modules\mob\living\silicon\pai\say.dm"
#include "code\modules\mob\living\silicon\pai\software.dm"
#include "code\modules\mob\living\silicon\pai\update_icon.dm"
#include "code\modules\mob\living\silicon\robot\death.dm"
#include "code\modules\mob\living\silicon\robot\emote.dm"
#include "code\modules\mob\living\silicon\robot\examine.dm"