Merge branch 'master' into AI_announcer_new

This commit is contained in:
S34N
2021-08-05 09:53:03 +01:00
committed by GitHub
455 changed files with 7608 additions and 8049 deletions
+1 -1
View File
@@ -362,7 +362,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(usr, "Not when you're not dead!")
return
var/datum/async_input/A = input_autocomplete_async(usr, "Area to jump to: ", GLOB.ghostteleportlocs)
var/datum/async_input/A = input_autocomplete_async(usr, "Area to jump to: ", SSmapping.ghostteleportlocs)
A.on_close(CALLBACK(src, .proc/teleport))
/mob/dead/observer/proc/teleport(area/thearea)
+3 -1
View File
@@ -90,6 +90,8 @@
M.show_message(message, m_type)
O.show_message(message, m_type)
if(O.client?.prefs.toggles2 & PREFTOGGLE_2_RUNECHAT)
O.create_chat_message(src, input, symbol = RUNECHAT_SYMBOL_EMOTE)
// Type 2 (Audible) emotes are sent to anyone in hear range
// of the *LOCATION* -- this is important for pAIs to be heard
@@ -116,7 +118,7 @@
return
if(!src.client.holder)
if(!config.dsay_allowed)
if(!GLOB.dsay_enabled)
to_chat(src, "<span class='warning'>Deadchat is globally muted</span>")
return
@@ -126,7 +126,7 @@
/mob/living/carbon/alien/movement_delay()
. = ..()
. += move_delay_add + config.alien_delay //move_delay_add is used to slow aliens with stuns
. += move_delay_add + GLOB.configuration.movement.alien_delay //move_delay_add is used to slow aliens with stuns
/mob/living/carbon/alien/getDNA()
return null
@@ -99,7 +99,7 @@
new_xeno.mind.assigned_role = SPECIAL_ROLE_XENOMORPH
new_xeno.mind.special_role = SPECIAL_ROLE_XENOMORPH
new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100)//To get the player's attention
to_chat(new_xeno, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Xenomorph)</span>")
to_chat(new_xeno, "<span class='motd'>For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Xenomorph)</span>")
if(gib_on_success)
owner.gib()
+1 -1
View File
@@ -13,7 +13,7 @@
/mob/living/carbon/brain/Life()
. = ..()
if(.)
if(!container && (world.time - timeofhostdeath) > config.revival_brain_life)
if(!container && (world.time - timeofhostdeath) > GLOB.configuration.general.revival_brain_life)
death()
/mob/living/carbon/brain/breathe()
-2
View File
@@ -1130,8 +1130,6 @@ so that different stomachs can handle things in different ways VB*/
//to recalculate and update the mob's total tint from tinted equipment it's wearing.
/mob/living/carbon/proc/update_tint()
if(!GLOB.tinted_weldhelh)
return
var/tinttotal = get_total_tint()
if(tinttotal >= TINT_BLIND)
overlay_fullscreen("tint", /obj/screen/fullscreen/blind)
@@ -320,7 +320,7 @@
for(var/current_species_name in GLOB.all_species)
var/datum/species/current_species = GLOB.all_species[current_species_name]
if(check_whitelist && config.usealienwhitelist && !check_rights(R_ADMIN, 0, src)) //If we're using the whitelist, make sure to check it!
if(check_whitelist && !check_rights(R_ADMIN, 0, src)) //If we're using the whitelist, make sure to check it!
if(whitelist.len && !(current_species_name in whitelist))
continue
if(blacklist.len && (current_species_name in blacklist))
+14 -1
View File
@@ -134,6 +134,8 @@
on_CD = handle_emote_CD()
if("deathgasp", "deathgasps")
on_CD = handle_emote_CD(50)
if("spin", "spins")
on_CD = handle_emote_CD(50)
if("sneeze", "sneezes")
on_CD = handle_emote_CD()
if("clap", "claps")
@@ -443,6 +445,17 @@
message = "<B>[src]</B> does a flip!"
SpinAnimation(5,1)
if("spin", "spins")
if(!restrained() && !lying)
if(prob(5))
spin(30, 1)
message = "<B>[src]</B> spins too much!"
Dizzy(12)
Confused(12)
else
spin(20, 1)
message = "<B>[src]</B> spins!"
if("aflap", "aflaps")
if(!restrained())
message = "<B>[src]</B> flaps [p_their()] wings ANGRILY!"
@@ -950,7 +963,7 @@
var/emotelist = "aflap(s), airguitar, blink(s), blink(s)_r, blush(es), bow(s)-none/mob, burp(s), choke(s), chuckle(s), clap(s), collapse(s), cough(s), cry, cries, custom, dance, dap(s)-none/mob," \
+ " deathgasp(s), drool(s), eyebrow, fart(s), faint(s), flap(s), flip(s), frown(s), gasp(s), giggle(s), glare(s)-none/mob, grin(s), groan(s), grumble(s), grin(s)," \
+ " handshake-mob, hug(s)-none/mob, hem, highfive, johnny, jump, kiss(es), laugh(s), look(s)-none/mob, moan(s), mumble(s), nod(s), pale(s), point(s)-atom, quiver(s), raise(s), salute(s)-none/mob, scream(s), shake(s)," \
+ " shiver(s), shrug(s), sigh(s), signal(s)-#1-10, slap(s), smile(s),snap(s), sneeze(s), sniff(s), snore(s), stare(s)-none/mob, tremble(s), twitch(es), twitch(es)_s," \
+ " shiver(s), shrug(s), sigh(s), signal(s)-#1-10, slap(s), smile(s),snap(s), sneeze(s), sniff(s), snore(s), spin(s) stare(s)-none/mob, tremble(s), twitch(es), twitch(es)_s," \
+ " wave(s), whimper(s), wink(s), yawn(s)"
switch(dna.species.name)
@@ -1942,3 +1942,16 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
runechat_msg_location = loc
else
runechat_msg_location = src
/mob/living/carbon/human/verb/Examine_OOC()
set name = "Examine Meta-Info (OOC)"
set category = "OOC"
set src in view()
if(GLOB.configuration.general.allow_character_metadata)
if(client)
to_chat(usr, "[src]'s Metainfo:<br>[sanitize(client.prefs.metadata)]")
else
to_chat(usr, "[src] does not have any stored infomation!")
else
to_chat(usr, "OOC Metadata is not supported by this server!")
@@ -37,10 +37,16 @@ emp_act
return 2
if(mind?.martial_art?.deflection_chance) //Some martial arts users can deflect projectiles!
if(!lying && !HAS_TRAIT(src, TRAIT_HULK) && prob(mind.martial_art.deflection_chance)) //But only if they're not lying down, and hulks can't do it
if(!lying && !HAS_TRAIT(src, TRAIT_HULK) && mind.martial_art.try_deflect(src)) //But only if they're not lying down, and hulks can't do it
add_attack_logs(P.firer, src, "hit by [P.type] but got deflected by martial arts '[mind.martial_art]'")
visible_message("<span class='danger'>[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
return FALSE
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, TRUE)
if(mind.martial_art.reroute_deflection)
P.firer = src
P.setAngle(rand(0, 360))
return -1
else
return FALSE
var/obj/item/organ/external/organ = get_organ(check_zone(def_zone))
if(isnull(organ))
@@ -1,7 +1,7 @@
/mob/living/carbon/human/movement_delay()
. = 0
. += ..()
. += config.human_delay
. += GLOB.configuration.movement.human_delay
. += dna.species.movement_delay(src)
/mob/living/carbon/human/Process_Spacemove(movement_dir = 0)
+1 -1
View File
@@ -61,7 +61,7 @@
player_logged++
if(istype(loc, /obj/machinery/cryopod))
return
if(config.auto_cryo_ssd_mins && (player_logged >= (config.auto_cryo_ssd_mins * 30)) && player_logged % 30 == 0)
if(GLOB.configuration.afk.ssd_auto_cryo_minutes && (player_logged >= (GLOB.configuration.afk.ssd_auto_cryo_minutes * 30)) && player_logged % 30 == 0)
var/turf/T = get_turf(src)
if(!is_station_level(T.z))
return
@@ -129,17 +129,11 @@
if((head_organ.dna.species.name in tmp_hair.species_allowed) && (robohead.company in tmp_hair.models_allowed)) //Populate the list of available monitor styles only with styles that the monitor-head is allowed to use.
hair += i
var/file = file2text("config/custom_sprites.txt") //Pulls up the custom_sprites list
var/lines = splittext(file, "\n")
for(var/line in lines) // Looks for lines set up as screen:ckey:screen_name
var/list/Entry = splittext(line, ":") // split lines
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i]) // Cleans up lines
if(Entry.len != 3 || Entry[1] != "screen") // Ignore entries that aren't for screens
continue
if(Entry[2] == H.ckey) // They're in the list? Custom sprite time, var and icon change required
hair += Entry[3] // Adds custom screen to list
if(H.ckey in GLOB.configuration.custom_sprites.ipc_screen_map)
// key: ckey | value: list of icon states
for(var/style in GLOB.configuration.custom_sprites.ipc_screen_map[H.ckey])
hair += style
var/new_style = input(H, "Select a monitor display", "Monitor Display", head_organ.h_style) as null|anything in hair
var/new_color = input("Please select hair color.", "Monitor Color", head_organ.hair_colour) as null|color
@@ -572,9 +572,22 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
standing.alpha = w_uniform.alpha
standing.color = w_uniform.color
overlays_standing[UNIFORM_LAYER] = standing
else
else if(!dna.species.nojumpsuit)
var/list/uniform_slots = list()
var/obj/item/organ/external/L = get_organ(BODY_ZONE_L_LEG)
if(!(L?.status & ORGAN_ROBOT))
uniform_slots += l_store
var/obj/item/organ/external/R = get_organ(BODY_ZONE_R_LEG)
if(!(R?.status & ORGAN_ROBOT))
uniform_slots += r_store
var/obj/item/organ/external/C = get_organ(BODY_ZONE_CHEST)
if(!(C?.status & ORGAN_ROBOT))
uniform_slots += wear_id
uniform_slots += wear_pda
uniform_slots += belt
// Automatically drop anything in store / id / belt if you're not wearing a uniform. //CHECK IF NECESARRY
for(var/obj/item/thing in list(r_store, l_store, wear_id, wear_pda, belt)) // whoever made this
for(var/obj/item/thing in uniform_slots) // whoever made this
if(thing) // you're a piece of fucking garbage
unEquip(thing) // why the fuck would you goddamn do this motherfucking shit
if(client) // INVENTORY CODE IN FUCKING ICON CODE
+6 -19
View File
@@ -92,6 +92,9 @@
to_chat(src, "<span class='warning'>[L] is restrained, you cannot push past.</span>")
return TRUE
if(pulledby == L && a_intent != INTENT_HELP) //prevents boosting the person pulling you, but you can still move through them on help intent
return TRUE
if(L.pulling)
if(ismob(L.pulling))
var/mob/P = L.pulling
@@ -519,22 +522,6 @@
/mob/living/proc/UpdateDamageIcon()
return
/mob/living/proc/Examine_OOC()
set name = "Examine Meta-Info (OOC)"
set category = "OOC"
set src in view()
if(config.allow_Metadata)
if(client)
to_chat(usr, "[src]'s Metainfo:<br>[client.prefs.metadata]")
else
to_chat(usr, "[src] does not have any stored infomation!")
else
to_chat(usr, "OOC Metadata is not supported by this server!")
return
/mob/living/Move(atom/newloc, direct, movetime)
if(buckled && buckled.loc != newloc) //not updating position
if(!buckled.anchored)
@@ -928,15 +915,15 @@
if(forced_look)
. += 3
if(ignorewalk)
. += config.run_speed
. += GLOB.configuration.movement.base_run_speed
else
switch(m_intent)
if(MOVE_INTENT_RUN)
if(drowsyness > 0)
. += 6
. += config.run_speed
. += GLOB.configuration.movement.base_run_speed
if(MOVE_INTENT_WALK)
. += config.walk_speed
. += GLOB.configuration.movement.base_walk_speed
/mob/living/proc/can_use_guns(obj/item/gun/G)
+7 -31
View File
@@ -53,7 +53,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
var/list/connected_robots = list()
var/aiRestorePowerRoutine = 0
//var/list/laws = list()
alarms_listend_for = list("Motion", "Fire", "Atmosphere", "Power", "Camera", "Burglar")
alarms_listend_for = list("Motion", "Fire", "Atmosphere", "Power", "Burglar")
var/viewalerts = 0
var/icon/holo_icon//Default is assigned when AI is created.
var/obj/mecha/controlled_mech //For controlled_mech a mech, to determine whether to relaymove or use the AI eye.
@@ -365,20 +365,8 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
if(stat || aiRestorePowerRoutine)
return
if(!custom_sprite) //Check to see if custom sprite time, checking the appopriate file to change a var
var/file = file2text("config/custom_sprites.txt")
var/lines = splittext(file, "\n")
for(var/line in lines)
// split & clean up
var/list/Entry = splittext(line, ":")
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i])
if(Entry.len < 2 || Entry[1] != "ai") //ignore incorrectly formatted entries or entries that aren't marked for AI
continue
if(Entry[2] == ckey) //They're in the list? Custom sprite time, var and icon change required
custom_sprite = 1
if(ckey in GLOB.configuration.custom_sprites.ai_core_ckeys)
custom_sprite = TRUE
var/display_choices = list(
"Monochrome",
@@ -963,21 +951,9 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
if(check_unable())
return
if(!custom_hologram) //Check to see if custom sprite time, checking the appopriate file to change a var
var/file = file2text("config/custom_sprites.txt")
var/lines = splittext(file, "\n")
for(var/line in lines)
// split & clean up
var/list/Entry = splittext(line, ":")
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i])
if(Entry.len < 2 || Entry[1] != "hologram")
continue
if (Entry[2] == ckey) //Custom holograms
custom_hologram = 1 // option is given in hologram menu
if(!custom_hologram)
if(ckey in GLOB.configuration.custom_sprites.ai_hologram_ckeys)
custom_hologram = TRUE
var/input
switch(alert("Would you like to select a hologram based on a crew member, an animal, or switch to a unique avatar?",,"Crew Member","Unique","Animal"))
@@ -1319,7 +1295,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target)
if(!istype(target))
return
if(check_unable(AI_CHECK_WIRELESS))
return
+4 -5
View File
@@ -125,11 +125,10 @@
laws.sort_laws()
/mob/living/silicon/proc/make_laws()
switch(config.default_laws)
if(0)
laws = new /datum/ai_laws/crewsimov()
else
laws = get_random_lawset()
if(GLOB.configuration.general.random_ai_lawset)
laws = get_random_lawset()
else
laws = new /datum/ai_laws/crewsimov()
/mob/living/silicon/proc/get_random_lawset()
var/list/law_options[0]
+4 -16
View File
@@ -122,7 +122,7 @@
. = ..()
. += slowdown
. += 1 //A bit slower than humans, so they're easier to smash
. += config.robot_delay
. += GLOB.configuration.movement.robot_delay
/mob/living/silicon/pai/update_icons()
if(stat == DEAD)
@@ -286,21 +286,9 @@
//check for custom_sprite
if(!custom_sprite)
var/file = file2text("config/custom_sprites.txt")
var/lines = splittext(file, "\n")
for(var/line in lines)
// split & clean up
var/list/Entry = splittext(line, ":")
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i])
if(Entry.len < 2 || Entry[1] != "pai") //ignore incorrectly formatted entries or entries that aren't marked for pAI
continue
if(Entry[2] == ckey) //They're in the list? Custom sprite time, var and icon change required
custom_sprite = 1
my_choices["Custom"] = "[ckey]-pai"
if(ckey in GLOB.configuration.custom_sprites.pai_holoform_ckeys)
custom_sprite = TRUE
my_choices["Custom"] = "[ckey]-pai"
my_choices = possible_chassis.Copy()
if(custom_sprite)
@@ -48,6 +48,8 @@
if(brute_damage + electronics_damage >= max_damage)
destroy()
SStgui.update_uis(owner.self_diagnosis)
/datum/robot_component/proc/heal_damage(brute, electronics, updating_health = TRUE)
if(installed != 1)
// If it's not installed, can't repair it.
@@ -59,6 +61,8 @@
brute_damage = max(0, brute_damage - brute)
electronics_damage = max(0, electronics_damage - electronics)
SStgui.update_uis(owner.self_diagnosis)
/datum/robot_component/proc/is_powered()
return (installed == 1) && (brute_damage + electronics_damage < max_damage) && (powered)
@@ -68,6 +72,8 @@
return
powered = 1
SStgui.update_uis(owner.self_diagnosis)
/datum/robot_component/proc/disable()
if(!component_disabled)
go_offline()
@@ -85,6 +91,8 @@
else
go_offline()
SStgui.update_uis(owner.self_diagnosis)
/datum/robot_component/proc/go_online()
return
@@ -29,8 +29,8 @@
return FALSE
notransform = 1
canmove = 0
icon = null
invisibility = 101
dust_animation()
if(mmi)
qdel(mmi) //Delete the MMI first so that it won't go popping out.
GLOB.dead_mob_list -= src
@@ -133,6 +133,16 @@
if(emagged)
return FALSE
/mob/living/silicon/robot/drone/detailed_examine()
return "Drones are player-controlled synthetics which are lawed to maintain the station and not \
interact with anyone else, except for other drones. They hold a wide array of tools to build, repair, maintain, and clean. \
They function similarly to other synthetics, in that they require recharging regularly, have laws, and are resilient to many hazards, \
such as fire, radiation, vacuum, and more. Ghosts can join the round as a maintenance drone by using the appropriate verb in the 'ghost' tab. \
An inactive drone can be rebooted by swiping an ID card on it with engineering or robotics access."
/mob/living/silicon/robot/drone/detailed_examine_antag()
return "An Electromagnetic Sequencer can be used to subvert the drone to your cause."
//Drones cannot be upgraded with borg modules so we need to catch some items before they get used in ..().
/mob/living/silicon/robot/drone/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/borg/upgrade))
@@ -49,35 +49,6 @@
else
..()
/mob/living/silicon/robot/drone/verb/customize()
set name = "Customize Chassis"
set desc = "Reconfigure your chassis into a customized version."
set category = "Drone"
if(!custom_sprite) //Check to see if custom sprite time, checking the appopriate file to change a var
var/file = file2text("config/custom_sprites.txt")
var/lines = splittext(file, "\n")
for(var/line in lines)
// split & clean up
var/list/Entry = splittext(line, ":")
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i])
if(Entry.len < 2 || Entry[1] != "drone")
continue
if (Entry[2] == ckey) //Custom holograms
custom_sprite = 1 // option is given in hologram menu
if(!custom_sprite)
to_chat(src, "<span class='warning'>Error 404: Custom chassis not found. Revoking customization option.</span>")
else
icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi'
icon_state = "[ckey]-drone"
to_chat(src, "<span class='notice'>You reconfigure your chassis and improve the station through your new aesthetics.</span>")
verbs -= /mob/living/silicon/robot/drone/verb/customize
/mob/living/silicon/robot/drone/get_scooped(mob/living/carbon/grabber)
var/obj/item/holder/H = ..()
if(!istype(H))
@@ -1,3 +1,6 @@
#define DRONE_BUILD_TIME 2 MINUTES
#define MAX_MAINT_DRONES 5
/obj/machinery/drone_fabricator
name = "drone fabricator"
desc = "A large automated factory for producing maintenance drones."
@@ -37,14 +40,14 @@
icon_state = "drone_fab_active"
var/elapsed = world.time - time_last_drone
drone_progress = clamp(round((elapsed / config.drone_build_time) * 100), 0, 100)
drone_progress = clamp(round((elapsed / DRONE_BUILD_TIME) * 100), 0, 100)
if(drone_progress >= 100)
visible_message("[src] voices a strident beep, indicating a drone chassis is prepared.")
/obj/machinery/drone_fabricator/examine(mob/user)
. = ..()
if(produce_drones && drone_progress >= 100 && isobserver(user) && config.allow_drone_spawn && count_drones() < config.max_maint_drones)
if(produce_drones && drone_progress >= 100 && isobserver(user) && count_drones() < MAX_MAINT_DRONES)
. += "<BR><B>A drone is prepared. Select 'Join As Drone' from the Ghost tab to spawn as a maintenance drone.</B>"
/obj/machinery/drone_fabricator/proc/count_drones()
@@ -58,7 +61,7 @@
if(stat & NOPOWER)
return
if(!produce_drones || !config.allow_drone_spawn || count_drones() >= config.max_maint_drones)
if(!produce_drones || count_drones() >= MAX_MAINT_DRONES)
return
if(!player || !isobserver(player.mob))
@@ -80,10 +83,6 @@
set name = "Join As Drone"
set desc = "If there is a powered, enabled fabricator in the game world with a prepared chassis, join as a maintenance drone."
if(!(config.allow_drone_spawn))
to_chat(src, "<span class='warning'>That verb is not currently permitted.</span>")
return
if(stat != DEAD)
return
@@ -99,7 +98,7 @@
return
var/player_age_check = check_client_age(usr.client, 14) // 14 days to play as a drone
if(player_age_check && config.use_age_restriction_for_antags)
if(player_age_check && GLOB.configuration.gamemode.antag_account_age_restriction)
to_chat(usr, "<span class='warning'>This role is not yet available to you. You need to wait another [player_age_check] days.</span>")
return
@@ -141,7 +140,7 @@
if(DF.stat & NOPOWER || !DF.produce_drones)
continue
if(DF.count_drones() >= config.max_maint_drones)
if(DF.count_drones() >= MAX_MAINT_DRONES)
to_chat(src, "<span class='warning'>There are too many active drones in the world for you to spawn.</span>")
return
@@ -150,3 +149,6 @@
return
to_chat(src, "<span class='warning'>There are no available drone spawn points, sorry.</span>")
#undef DRONE_BUILD_TIME
#undef MAX_MAINT_DRONES
@@ -13,6 +13,8 @@
//Cooldown-inducing emotes
if("law","flip","flips","halt") //halt is exempt because it's used to stop criminal scum //WHOEVER THOUGHT THAT WAS A GOOD IDEA IS GOING TO GET SHOT.
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
if("spin","spins")
on_CD = handle_emote_CD(5 SECONDS)
//Everything else, including typos of the above emotes
else
on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown
@@ -157,8 +159,12 @@
message = "<B>[src]</B> does a flip!"
src.SpinAnimation(5,1)
if("spin","spins")
spin(20, 1)
message = "<B>[src]</B> spins!"
if("help")
to_chat(src, "salute, bow-(none)/mob, clap, flap, aflap, twitch, twitches, nod, deathgasp, glare-(none)/mob, stare-(none)/mob, look,\n law, halt")
to_chat(src, "salute, bow-(none)/mob, clap, flap, aflap, twitch, twitches, nod, deathgasp, glare-(none)/mob, stare-(none)/mob, look,\n law, halt, flip, spin")
..()
+6 -41
View File
@@ -138,6 +138,9 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
radio = new /obj/item/radio/borg(src)
common_radio = radio
if(!cell) // Make sure a new cell gets created *before* executing initialize_components(). The cell component needs an existing cell for it to get set up properly
cell = new default_cell_type(src)
init(alien, connect_to_AI, ai_to_sync_to)
if(has_camera && !camera)
@@ -151,9 +154,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
mmi = new /obj/item/mmi/robotic_brain(src) //Give the borg an MMI if he spawns without for some reason. (probably not the correct way to spawn a robotic brain, but it works)
mmi.icon_state = "boris"
if(!cell) // Make sure a new cell gets created *before* executing initialize_components(). The cell component needs an existing cell for it to get set up properly
cell = new default_cell_type(src)
initialize_components()
//if(!unfinished)
// Create all the robot parts.
@@ -215,20 +215,8 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
//Check for custom sprite
if(!custom_sprite)
var/file = file2text("config/custom_sprites.txt")
var/lines = splittext(file, "\n")
for(var/line in lines)
// split & clean up
var/list/Entry = splittext(line, ":")
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i])
if(Entry.len < 2 || Entry[1] != "cyborg") //ignore incorrectly formatted entries or entries that aren't marked for cyborg
continue
if(Entry[2] == ckey) //They're in the list? Custom sprite time, var and icon change required
custom_sprite = 1
if(ckey in GLOB.configuration.custom_sprites.cyborg_ckeys)
custom_sprite = TRUE
if(mmi && mmi.brainmob)
mmi.brainmob.name = newname
@@ -306,6 +294,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
QDEL_NULL(cell)
QDEL_NULL(robot_suit)
QDEL_NULL(spark_system)
QDEL_NULL(self_diagnosis)
return ..()
/mob/living/silicon/robot/proc/pick_module()
@@ -506,30 +495,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
set name = "Show Station Manifest"
show_station_manifest()
/mob/living/silicon/robot/proc/self_diagnosis()
if(!is_component_functioning("diagnosis unit"))
return null
var/dat = "<HEAD><TITLE>[src.name] Self-Diagnosis Report</TITLE></HEAD><BODY>\n"
for(var/V in components)
var/datum/robot_component/C = components[V]
if(C.installed == 0)
dat += "<b>[C.name]</b><br>MISSING<br>"
else
dat += "<b>[C.name]</b>[C.installed == -1 ? "<br>DESTROYED" : ""]<br><table><tr><td>Brute Damage:</td><td>[C.brute_damage]</td></tr><tr><td>Electronics Damage:</td><td>[C.electronics_damage]</td></tr><tr><td>Powered:</td><td>[C.is_powered() ? "Yes" : "No"]</td></tr><tr><td>Toggled:</td><td>[ C.toggled ? "Yes" : "No"]</td></table><br>"
return dat
/mob/living/silicon/robot/verb/self_diagnosis_verb()
set category = "Robot Commands"
set name = "Self Diagnosis"
if(!is_component_functioning("diagnosis unit"))
to_chat(src, "<span class='warning'>Your self-diagnosis component isn't functioning.</span>")
var/dat = self_diagnosis()
src << browse(dat, "window=robotdiagnosis")
/mob/living/silicon/robot/verb/toggle_component()
set category = "Robot Commands"
set name = "Toggle Component"
@@ -570,6 +570,7 @@
/obj/item/gun/energy/pulse/cyborg,
/obj/item/crowbar/cyborg
)
special_rechargables = list(/obj/item/gun/energy/pulse/cyborg)
// Sydicate assault cyborg module.
/obj/item/robot_module/syndicate
@@ -662,7 +663,10 @@
/obj/item/pickaxe/drill/jackhammer, // for breaking walls to execute flanking moves
/obj/item/borg/destroyer/mobility
)
special_rechargables = list(/obj/item/melee/baton/loaded)
special_rechargables = list(
/obj/item/melee/baton/loaded,
/obj/item/gun/energy/immolator/multi/cyborg
)
/obj/item/robot_module/combat
name = "combat robot module"
@@ -678,7 +682,10 @@
/obj/item/restraints/handcuffs/cable/zipties/cyborg,
/obj/item/pickaxe/drill/jackhammer // for breaking walls to execute flanking moves
)
special_rechargables = list(/obj/item/melee/baton/loaded)
special_rechargables = list(
/obj/item/melee/baton/loaded,
/obj/item/gun/energy/immolator/multi/cyborg
)
// Xenomorph cyborg module.
/obj/item/robot_module/alien/hunter
@@ -720,6 +727,7 @@
/obj/item/soap,
/obj/item/t_scanner,
/obj/item/rpd,
/obj/item/analyzer,
/obj/item/stack/sheet/metal/cyborg,
/obj/item/stack/rods/cyborg,
/obj/item/stack/tile/plasteel/cyborg,
@@ -11,7 +11,7 @@
. += speed
if(module_active && istype(module_active,/obj/item/borg/destroyer/mobility))
. -= 3
. += config.robot_delay
. += GLOB.configuration.movement.robot_delay
/mob/living/silicon/robot/mob_negates_gravity()
return magpulse
+7 -9
View File
@@ -13,9 +13,9 @@
var/list/stating_laws = list()// Channels laws are currently being stated on
var/list/alarms_to_show = list()
var/list/alarms_to_clear = list()
var/list/alarm_types_show = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
var/list/alarm_types_clear = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
var/list/alarms_listend_for = list("Motion", "Fire", "Atmosphere", "Power", "Camera")
var/list/alarm_types_show = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0)
var/list/alarm_types_clear = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0)
var/list/alarms_listend_for = list("Motion", "Fire", "Atmosphere", "Power")
//var/list/hud_list[10]
var/list/speech_synthesizer_langs = list() //which languages can be vocalized by the speech synthesizer
var/designation = ""
@@ -61,6 +61,10 @@
/mob/living/silicon/Destroy()
GLOB.silicon_mob_list -= src
QDEL_NULL(atmos_control)
QDEL_NULL(crew_monitor)
QDEL_NULL(law_manager)
QDEL_NULL(power_monitor)
return ..()
/mob/living/silicon/proc/alarm_triggered(src, class, area/A, list/O, obj/alarmsource)
@@ -106,9 +110,6 @@
if(alarm_types_show["Power"])
msg += "POWER: [alarm_types_show["Power"]] alarms detected. - "
if(alarm_types_show["Camera"])
msg += "CAMERA: [alarm_types_show["Camera"]] alarms detected. - "
msg += "<A href=?src=[UID()];showalerts=1'>\[Show Alerts\]</a>"
var/msg_text = msg.Join("")
to_chat(src, msg_text)
@@ -132,9 +133,6 @@
if(alarm_types_clear["Power"])
msg += "POWER: [alarm_types_clear["Power"]] alarms cleared. - "
if(alarm_types_show["Camera"])
msg += "CAMERA: [alarm_types_clear["Camera"]] alarms cleared. - "
msg += "<A href=?src=[UID()];showalerts=1'>\[Show Alerts\]</a>"
var/msg_text = msg.Join("")
@@ -18,8 +18,16 @@
/mob/living/silicon/proc/subsystem_power_monitor
)
/mob/living/silicon/robot
var/datum/ui_module/robot_self_diagnosis/self_diagnosis
silicon_subsystems = list(
/mob/living/silicon/robot/proc/self_diagnosis,
/mob/living/silicon/proc/subsystem_law_manager
)
/mob/living/silicon/robot/drone
silicon_subsystems = list(
/mob/living/silicon/robot/proc/self_diagnosis,
/mob/living/silicon/proc/subsystem_law_manager,
/mob/living/silicon/proc/subsystem_power_monitor
)
@@ -33,6 +41,10 @@
law_manager = new(src)
power_monitor = new(src)
/mob/living/silicon/robot/init_subsystems()
. = ..()
self_diagnosis = new(src)
/********************
* Atmos Control *
********************/
@@ -68,3 +80,12 @@
power_monitor.ui_interact(usr, state = GLOB.self_state)
/mob/living/silicon/robot/proc/self_diagnosis()
set category = "Robot Commands"
set name = "Self Diagnosis"
if(!is_component_functioning("diagnosis unit"))
to_chat(src, "<span class='warning'>Your self-diagnosis component isn't functioning.</span>")
return
self_diagnosis.ui_interact(src)
@@ -139,12 +139,22 @@
update_controls()
/mob/living/simple_animal/bot/New()
/*
HEY! LISTEN!
I see you're poking the the bot/New() proc
Assuming you are converting this to Initialize() [yay], please see my note in
code\game\jobs\job\job.dm | /datum/job/proc/get_access()
Theres a useless check that bugs me but needs to exist because these things New()
-AA07
*/
..()
GLOB.bots_list += src
icon_living = icon_state
icon_dead = icon_state
access_card = new /obj/item/card/id(src)
//This access is so bots can be immediately set to patrol and leave Robotics, instead of having to be let out first.
//This access is so bots can be immediately set to patrol and leave Robotics, instead of having to be let out first.
access_card.access += ACCESS_ROBOTICS
set_custom_texts()
Radio = new/obj/item/radio/headset/bot(src)
@@ -94,6 +94,17 @@
/mob/living/simple_animal/hostile/construct/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
return FALSE
/mob/living/simple_animal/hostile/construct/Life(seconds, times_fired)
if(holy_check(src))
throw_alert("holy_fire", /obj/screen/alert/holy_fire, override = TRUE)
visible_message("<span class='danger'>[src] slowly crumbles to dust in this holy place!</span>", \
"<span class='danger'>Your shell burns as you crumble to dust in this holy place!</span>")
playsound(loc, 'sound/items/welder.ogg', 150, TRUE)
adjustBruteLoss(maxHealth/8)
else
clear_alert("holy_fire", clear_override = TRUE)
return ..()
/////////////////Juggernaut///////////////
@@ -21,13 +21,16 @@
var/yelp_sound = 'sound/creatures/dog_yelp.ogg' //Used on death.
var/last_eaten = 0
footstep_type = FOOTSTEP_MOB_CLAW
var/next_spin_message = 0
/mob/living/simple_animal/pet/dog/verb/chasetail()
set name = "Chase your tail"
set desc = "d'awwww."
set category = "Dog"
visible_message("[src] [pick("dances around", "chases [p_their()] tail")].", "[pick("You dance around", "You chase your tail")].")
if(next_spin_message <= world.time)
visible_message("[src] [pick("dances around", "chases [p_their()] tail")].", "[pick("You dance around", "You chase your tail")].")
next_spin_message = world.time + 5 SECONDS
spin(20, 1)
/mob/living/simple_animal/pet/dog/death(gibbed)
@@ -29,6 +29,7 @@
can_collar = 1
blood_volume = BLOOD_VOLUME_NORMAL
var/obj/item/udder/udder = null
gender = FEMALE
footstep_type = FOOTSTEP_MOB_SHOE
/mob/living/simple_animal/hostile/retaliate/goat/New()
@@ -81,8 +81,8 @@
pixel_y = 8
if(is_type_in_typecache(get_area(loc), invalid_area_typecache))
var/area = pick(GLOB.teleportlocs)
var/area/tp = GLOB.teleportlocs[area]
var/area = pick(SSmapping.teleportlocs)
var/area/tp = SSmapping.teleportlocs[area]
forceMove(pick(get_area_turfs(tp.type)))
if((!current_victim && !admincluwne) || QDELETED(current_victim))
@@ -1,193 +0,0 @@
/mob/living/simple_animal/hostile/headcrab
name = "headcrab"
desc = "A small parasitic creature that would like to connect with your brain stem."
icon = 'icons/mob/headcrab.dmi'
icon_state = "headcrab"
icon_living = "headcrab"
icon_dead = "headcrab_dead"
health = 60
maxHealth = 60
dodging = 1
melee_damage_lower = 5
melee_damage_upper = 10
ranged = 1
ranged_message = "leaps"
ranged_cooldown_time = 40
var/jumpdistance = 4
var/jumpspeed = 1
attacktext = "bites"
attack_sound = 'sound/creatures/headcrab_attack.ogg'
speak_emote = list("hisses")
var/is_zombie = 0
stat_attack = DEAD // Necessary for them to attack (zombify) dead humans
robust_searching = 1
var/host_species = ""
var/list/human_overlays = list()
/mob/living/simple_animal/hostile/headcrab/Life(seconds, times_fired)
if(..() && !stat)
if(!is_zombie && isturf(src.loc))
for(var/mob/living/carbon/human/H in oview(src, 1)) //Only for corpse right next to/on same tile
if(H.stat == DEAD || (!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD))
Zombify(H)
break
if(times_fired % 4 == 0)
for(var/mob/living/simple_animal/K in oview(src, 1)) //Only for corpse right next to/on same tile
if(K.stat == DEAD || (!K.check_death_method() && K.health <= HEALTH_THRESHOLD_DEAD))
visible_message("<span class='danger'>[src] consumes [K] whole!</span>")
if(health < maxHealth)
health += 10
qdel(K)
break
/mob/living/simple_animal/hostile/headcrab/OpenFire(atom/A)
if(check_friendly_fire)
for(var/turf/T in getline(src,A)) // Not 100% reliable but this is faster than simulating actual trajectory
for(var/mob/living/L in T)
if(L == src || L == A)
continue
if(faction_check_mob(L) && !attack_same)
return
visible_message("<span class='danger'><b>[src]</b> [ranged_message] at [A]!</span>")
throw_at(A, jumpdistance, jumpspeed, spin = FALSE, diagonals_first = TRUE)
ranged_cooldown = world.time + ranged_cooldown_time
/mob/living/simple_animal/hostile/headcrab/proc/Zombify(mob/living/carbon/human/H)
if(!H.check_death_method())
H.death()
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
is_zombie = TRUE
if(H.wear_suit)
var/obj/item/clothing/suit/armor/A = H.wear_suit
if(A.armor && A.armor.getRating("melee"))
maxHealth += A.armor.getRating("melee") //That zombie's got armor, I want armor!
maxHealth += 200
health = maxHealth
name = "zombie"
desc = "A corpse animated by the alien being on its head."
melee_damage_lower = 10
melee_damage_upper = 15
ranged = 0
stat_attack = CONSCIOUS // Disables their targeting of dead mobs once they're already a zombie
icon = H.icon
speak = list('sound/creatures/zombie_idle1.ogg','sound/creatures/zombie_idle2.ogg','sound/creatures/zombie_idle3.ogg')
speak_chance = 50
speak_emote = list("groans")
attacktext = "bites"
attack_sound = 'sound/creatures/zombie_attack.ogg'
icon_state = "zombie2_s"
if(head_organ && !(NO_HAIR in H.dna.species.species_traits))
head_organ.h_style = null
H.update_hair()
host_species = H.dna.species.name
human_overlays = H.overlays
update_icons()
H.forceMove(src)
visible_message("<span class='warning'>The corpse of [H.name] suddenly rises!</span>")
/mob/living/simple_animal/hostile/headcrab/death()
..()
if(is_zombie)
qdel(src)
/mob/living/simple_animal/hostile/headcrab/handle_automated_speech() // This way they have different screams when attacking, sometimes. Might be seen as sphagetthi code though.
if(speak_chance)
if(rand(0,200) < speak_chance)
if(speak && speak.len)
playsound(get_turf(src), pick(speak), 200, 1)
/mob/living/simple_animal/hostile/headcrab/Destroy()
if(contents)
for(var/mob/M in contents)
M.loc = get_turf(src)
return ..()
/mob/living/simple_animal/hostile/headcrab/update_icons()
. = ..()
if(is_zombie)
overlays.Cut()
overlays = human_overlays
var/image/I = image('icons/mob/headcrab.dmi', icon_state = "headcrabpod")
if(host_species == "Vox")
I = image('icons/mob/headcrab.dmi', icon_state = "headcrabpod_vox")
else if(host_species == "Gray")
I = image('icons/mob/headcrab.dmi', icon_state = "headcrabpod_gray")
overlays += I
/mob/living/simple_animal/hostile/headcrab/CanAttack(atom/the_target)
if(stat_attack == DEAD && isliving(the_target) && !ishuman(the_target))
var/mob/living/L = the_target
if(L.stat == DEAD)
// Override default behavior of stat_attack, to stop headcrabs targeting dead mobs they cannot infect, such as silicons.
return FALSE
return ..()
/mob/living/simple_animal/hostile/headcrab/fast
name = "fast headcrab"
desc = "A fast parasitic creature that would like to connect with your brain stem."
icon = 'icons/mob/headcrab.dmi'
icon_state = "fast_headcrab"
icon_living = "fast_headcrab"
icon_dead = "fast_headcrab_dead"
health = 40
maxHealth = 40
ranged_cooldown_time = 30
jumpdistance = 8
jumpspeed = 2
speak_emote = list("screech")
/mob/living/simple_animal/hostile/headcrab/fast/update_icons()
. = ..()
if(is_zombie)
overlays.Cut()
overlays = human_overlays
var/image/I = image('icons/mob/headcrab.dmi', icon_state = "fast_headcrabpod")
if(host_species == "Vox")
I = image('icons/mob/headcrab.dmi', icon_state = "fast_headcrabpod_vox")
else if(host_species == "Gray")
I = image('icons/mob/headcrab.dmi', icon_state = "fast_headcrabpod_gray")
overlays += I
/mob/living/simple_animal/hostile/headcrab/fast/Zombify(mob/living/carbon/human/H)
. = ..()
speak = list('sound/creatures/fast_zombie_idle1.ogg','sound/creatures/fast_zombie_idle2.ogg','sound/creatures/fast_zombie_idle3.ogg')
/mob/living/simple_animal/hostile/headcrab/poison
name = "poison headcrab"
desc = "A poison parasitic creature that would like to connect with your brain stem."
icon = 'icons/mob/headcrab.dmi'
icon_state = "poison_headcrab"
icon_living = "poison_headcrab"
icon_dead = "poison_headcrab_dead"
health = 80
maxHealth = 80
ranged_cooldown_time = 50
jumpdistance = 3
jumpspeed = 1
melee_damage_lower = 8
melee_damage_upper = 20
attack_sound = 'sound/creatures/ph_scream1.ogg'
speak_emote = list("screech")
/mob/living/simple_animal/hostile/headcrab/poison/update_icons()
. = ..()
if(is_zombie)
overlays.Cut()
overlays = human_overlays
var/image/I = image('icons/mob/headcrab.dmi', icon_state = "poison_headcrabpod")
if(host_species == "Vox")
I = image('icons/mob/headcrab.dmi', icon_state = "poison_headcrabpod_vox")
else if(host_species == "Gray")
I = image('icons/mob/headcrab.dmi', icon_state = "poison_headcrabpod_gray")
overlays += I
/mob/living/simple_animal/hostile/headcrab/poison/AttackingTarget()
. = ..()
if(iscarbon(target) && target.reagents)
var/inject_target = pick("chest", "head")
var/mob/living/carbon/C = target
if(C.stunned || C.can_inject(null, FALSE, inject_target, FALSE))
if(C.eye_blurry < 60)
C.AdjustEyeBlurry(10)
visible_message("<span class='danger'>[src] buries its fangs deep into the [inject_target] of [target]!</span>")
@@ -193,7 +193,7 @@
M.Weaken(4) // 8 seconds.
if(iscarbon(M))
web_special_ability(M)
addtimer(CALLBACK(src, .proc/after_carbon_crossed, M), 0.7 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
addtimer(CALLBACK(src, .proc/after_carbon_crossed, M), 7 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
/**
* Called some time after a carbon mob crossed the terror web.
@@ -42,6 +42,6 @@
to_chat(user, "<span class='notice'>Someone else already took this spider.</span>")
return
key = user.key
to_chat(src, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Terror_Spider)</span>")
to_chat(src, "<span class='motd'>For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Terror_Spider)</span>")
for(var/mob/dead/observer/G in GLOB.player_list)
G.show_message("<i>A ghost has taken control of <b>[src]</b>. ([ghost_follow_link(src, ghost=G)]).</i>")
@@ -312,6 +312,8 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list)
/mob/living/simple_animal/hostile/poison/terror_spider/Destroy()
GLOB.ts_spiderlist -= src
var/datum/atom_hud/U = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
U.remove_hud_from(src)
handle_dying()
return ..()
@@ -332,7 +332,7 @@
. = speed
if(forced_look)
. += 3
. += config.animal_delay
. += GLOB.configuration.movement.animal_delay
/mob/living/simple_animal/Stat()
..()
@@ -157,7 +157,7 @@
if(health <= 0) // if damaged, the slime moves twice as slow
. *= 2
. += config.slime_delay
. += GLOB.configuration.movement.slime_delay
/mob/living/simple_animal/slime/update_health_hud()
if(hud_used)
+3 -2
View File
@@ -211,11 +211,12 @@
/mob/living/SetEyeBlurry(amount, updating = TRUE)
. = STATUS_UPDATE_BLURRY
if((!!amount) == (!!eye_blurry)) // We're not changing from + to 0 or vice versa
//if they're both above max or equal that means we won't change the blur filter
if(amount > MAX_EYE_BLURRY_FILTER_SIZE / EYE_BLUR_TO_FILTER_SIZE_MULTIPLIER && eye_blurry > MAX_EYE_BLURRY_FILTER_SIZE / EYE_BLUR_TO_FILTER_SIZE_MULTIPLIER || eye_blurry == amount)
updating = FALSE
. = STATUS_UPDATE_NONE
eye_blurry = max(amount, 0)
// We transitioned to/from 0, so update the eye blur overlays
if(updating)
update_blurry_effects()
+6 -5
View File
@@ -9,12 +9,13 @@
return 0
/mob/living/update_blurry_effects()
if(eyes_blurred())
overlay_fullscreen("blurry", /obj/screen/fullscreen/blurry)
return 1
var/atom/movable/plane_master_controller/game_plane_master_controller = hud_used?.plane_master_controllers[PLANE_MASTERS_GAME]
if(!game_plane_master_controller)
return
if(eye_blurry)
game_plane_master_controller.add_filter("eye_blur", 1, gauss_blur_filter(clamp(eye_blurry * EYE_BLUR_TO_FILTER_SIZE_MULTIPLIER, 0.6, MAX_EYE_BLURRY_FILTER_SIZE)))
else
clear_fullscreen("blurry")
return 0
game_plane_master_controller.remove_filter("eye_blur")
/mob/living/update_druggy_effects()
if(druggy)
+2 -6
View File
@@ -6,7 +6,7 @@
log_access_in(client)
create_attack_log("<font color='red'>Logged in at [atom_loc_line(get_turf(src))]</font>")
create_log(MISC_LOG, "Logged in")
if(config.log_access)
if(GLOB.configuration.logging.access_logging)
for(var/mob/M in GLOB.player_list)
if(M == src) continue
if( M.key && (M.key != key) )
@@ -16,7 +16,7 @@
if( (M.computer_id == client.computer_id) )
if(matches) matches += " and "
matches += "ID ([client.computer_id])"
if(!config.disable_cid_warn_popup)
if(!GLOB.configuration.general.disable_cid_warning_popup)
spawn() alert("You have logged in already with another key this round, please log out of this one NOW or risk being banned!")
if(matches)
if(M.client)
@@ -68,9 +68,5 @@
for(var/datum/alternate_appearance/AA in viewing_alternate_appearances)
AA.display_to(list(src))
if(!fexists("config/config.txt") || !fexists("config/game_options.txt"))
to_chat(src, "<span class='biggerdanger'>The game config files have not been properly set!\n Please copy ALL files from '/config/example' into the parent folder, '/config'.</span>")
log_world("The game config files have not been properly set! Please copy ALL files from /config/example into the parent folder, /config.")
update_client_colour(0)
update_morgue()
+8 -4
View File
@@ -7,14 +7,18 @@
create_log(MISC_LOG, "Logged out")
// `holder` is nil'd out by now, so we check the `admin_datums` array directly
//Only report this stuff if we are currently playing.
if(GLOB.admin_datums[ckey] && SSticker && SSticker.current_state == GAME_STATE_PLAYING)
if(GLOB.admin_datums[ckey] && SSticker.current_state == GAME_STATE_PLAYING)
var/datum/admins/temp_admin = GLOB.admin_datums[ckey]
// Triggers on people with banhammer power only - no mentors tripping the alarm
if(temp_admin.rights & R_BAN)
if(temp_admin.rights & R_MENTOR)
var/list/mentorcounter = staff_countup(R_MENTOR)
if(mentorcounter[1] == 0) // No active mentors
SSdiscord.send2discord_simple(DISCORD_WEBHOOK_MENTOR, "[key_name(src)] logged out - 0 active mentors, [mentorcounter[2]] non-mentor staff, [mentorcounter[3]] inactive mentors.")
else if(temp_admin.rights & R_BAN)
message_admins("Admin logout: [key_name_admin(src)]")
var/list/admincounter = staff_countup(R_BAN)
if(admincounter[1] == 0) // No active admins
SSdiscord.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "[key_name(src)] logged out - No active admins, [admincounter[2]] non-admin staff, [admincounter[3]] inactive staff.")
SSdiscord.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "[key_name(src)] logged out - 0 active admins, [admincounter[2]] non-admin staff, [admincounter[3]] inactive staff.")
..()
update_morgue()
+40 -15
View File
@@ -8,6 +8,7 @@
spellremove(src)
mobspellremove(src)
QDEL_LIST(viruses)
QDEL_LIST(actions)
ghostize()
QDEL_LIST_ASSOC_VAL(tkgrabbed_objects)
for(var/I in tkgrabbed_objects)
@@ -20,6 +21,7 @@
AA.viewers -= src
viewing_alternate_appearances = null
LAssailant = null
runechat_msg_location = null
return ..()
/mob/Initialize(mapload)
@@ -749,7 +751,7 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
set name = "Respawn"
set category = "OOC"
if(!GLOB.abandon_allowed)
if(!GLOB.configuration.general.respawn_enabled)
to_chat(usr, "<span class='warning'>Respawning is disabled.</span>")
return
@@ -1007,7 +1009,8 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
// this function displays the station time in the status panel
/mob/proc/show_stat_station_time()
stat(null, "Round Time: [worldtime2text()]")
stat(null, "Server Uptime: [worldtime2text()]")
stat(null, "Round Time: [ROUND_TIME ? time2text(ROUND_TIME, "hh:mm:ss") : "N/A"]")
stat(null, "Station Time: [station_time_timestamp()]")
// this function displays the shuttles ETA in the status panel if the shuttle has been called
@@ -1352,20 +1355,14 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
set waitfor = 0
if(!spintime || !speed || spintime > 100)
CRASH("Aborted attempted call of /mob/proc/spin with invalid args ([spintime],[speed]) which could have frozen the server.")
var/D = dir
while(spintime >= speed)
var/end_time = world.time + spintime
var/spin_dir = prob(50)
while(world.time <= end_time)
sleep(speed)
switch(D)
if(NORTH)
D = EAST
if(SOUTH)
D = WEST
if(EAST)
D = SOUTH
if(WEST)
D = NORTH
setDir(D)
spintime -= speed
if(spin_dir)
dir = turn(dir, 90)
else
dir = turn(dir, -90)
/mob/proc/is_literate()
return FALSE
@@ -1461,3 +1458,31 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
*/
/mob/proc/update_runechat_msg_location()
return
GLOBAL_LIST_INIT(holy_areas, typecacheof(list(
/area/chapel
)))
/mob/proc/holy_check()
if(!is_type_in_typecache(loc.loc, GLOB.holy_areas))
return FALSE
if(!mind)
return FALSE
//Allows fullpower vampires to bypass holy areas
var/datum/vampire/vampire = mind.vampire
if(vampire && vampire.get_ability(/datum/vampire_passive/full))
return FALSE
//Allows cult to bypass holy areas once they summon
var/datum/game_mode/gamemode = SSticker.mode
if(iscultist(src) && gamemode.cult_objs.cult_status == NARSIE_HAS_RISEN)
return FALSE
//Execption for Holy Constructs
if(isconstruct(src) && !iscultist(src))
return FALSE
to_chat(src, "<span class='warning'>Your powers are useless on this holy ground.</span>")
return TRUE
+1 -1
View File
@@ -79,7 +79,7 @@
/proc/cannotPossess(A)
var/mob/dead/observer/G = A
if(G.has_enabled_antagHUD && config.antag_hud_restricted)
if(G.has_enabled_antagHUD && GLOB.configuration.general.restrict_antag_hud_rejoin)
return 1
return 0
+4 -1
View File
@@ -169,7 +169,10 @@
n = get_step(mob, direct)
. = mob.SelfMove(n, direct, delay)
mob.setDir(direct)
if(mob.pulling?.face_while_pulling)
mob.setDir(get_dir(mob, mob.pulling)) // Face welding tanks and stuff when pulling
else
mob.setDir(direct)
if((direct & (direct - 1)) && mob.loc == n) //moved diagonally successfully
delay = mob.movement_delay() * 2 //Will prevent mob diagonal moves from smoothing accurately, sadly
+8 -8
View File
@@ -32,11 +32,11 @@
if(client)
client.playtitlemusic()
if(config.player_overflow_cap && config.overflow_server_url) //Overflow rerouting, if set, forces players to be moved to a different server once a player cap is reached. Less rough than a pure kick.
if(src.client.holder) return //admins are immune to overflow rerouting
if(config.overflow_whitelist.Find(lowertext(src.ckey))) return //Whitelisted people are immune to overflow rerouting.
var/tally = 0
for(var/client/C in GLOB.clients)
tally++
if(tally > config.player_overflow_cap)
src << link(config.overflow_server_url)
//Overflow rerouting, if set, forces players to be moved to a different server once a player cap is reached. Less rough than a pure kick.
if(GLOB.configuration.overflow.reroute_cap && GLOB.configuration.overflow.overflow_server_location)
if(client.holder)
return //admins are immune to overflow rerouting
if(ckey in GLOB.configuration.overflow.overflow_whitelist)
return //Whitelisted people are immune to overflow rerouting.
if(length(GLOB.clients) > GLOB.configuration.overflow.reroute_cap)
src << link(GLOB.configuration.overflow.overflow_server_location)
+7 -7
View File
@@ -115,7 +115,7 @@
return FALSE
if(href_list["consent_signed"])
var/datum/db_query/query = SSdbcore.NewQuery("REPLACE INTO [format_table_name("privacy")] (ckey, datetime, consent) VALUES (:ckey, Now(), 1)", list(
var/datum/db_query/query = SSdbcore.NewQuery("REPLACE INTO privacy (ckey, datetime, consent) VALUES (:ckey, Now(), 1)", list(
"ckey" = ckey
))
// If the query fails we dont want them permenantly stuck on being unable to accept TOS
@@ -129,7 +129,7 @@
if(href_list["consent_rejected"])
client.tos_consent = FALSE
to_chat(usr, "<span class='warning'>You must consent to the terms of service before you can join!</span>")
var/datum/db_query/query = SSdbcore.NewQuery("REPLACE INTO [format_table_name("privacy")] (ckey, datetime, consent) VALUES (:ckey, Now(), 0)", list(
var/datum/db_query/query = SSdbcore.NewQuery("REPLACE INTO privacy (ckey, datetime, consent) VALUES (:ckey, Now(), 0)", list(
"ckey" = ckey
))
// If the query fails we dont want them permenantly stuck on being unable to accept TOS
@@ -214,7 +214,7 @@
return
if(client.prefs.species in GLOB.whitelisted_species)
if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
if(!is_alien_whitelisted(src, client.prefs.species))
to_chat(src, alert("You are currently not whitelisted to play [client.prefs.species]."))
return FALSE
@@ -233,7 +233,7 @@
client.prefs.load_random_character_slot(client)
if(client.prefs.species in GLOB.whitelisted_species)
if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
if(!is_alien_whitelisted(src, client.prefs.species))
to_chat(src, alert("You are currently not whitelisted to play [client.prefs.species]."))
return FALSE
@@ -257,14 +257,14 @@
if(job.available_in_playtime(client))
return 0
if(config.assistantlimit)
if(GLOB.configuration.jobs.assistant_limit)
if(job.title == "Civilian")
var/count = 0
var/datum/job/officer = SSjobs.GetJob("Security Officer")
var/datum/job/warden = SSjobs.GetJob("Warden")
var/datum/job/hos = SSjobs.GetJob("Head of Security")
count += (officer.current_positions + warden.current_positions + hos.current_positions)
if(job.current_positions > (config.assistantratio * count))
if(job.current_positions > (GLOB.configuration.jobs.assistant_security_ratio * count))
if(count >= 5) // if theres more than 5 security on the station just let assistants join regardless, they should be able to handle the tide
return 1
return 0
@@ -603,7 +603,7 @@
/mob/new_player/proc/is_species_whitelisted(datum/species/S)
if(!S) return 1
return is_alien_whitelisted(src, S.name) || !config.usealienwhitelist || !(IS_WHITELISTED in S.species_traits)
return is_alien_whitelisted(src, S.name) || !(IS_WHITELISTED in S.species_traits)
/mob/new_player/get_gender()
if(!client || !client.prefs) ..()
@@ -616,3 +616,35 @@
/datum/sprite_accessory/socks/black_fishnet
name = "Black Fishnet"
icon_state = "black_fishnet"
/datum/sprite_accessory/socks/stockings_lpink
name = "Stockings (Programmer)"
icon_state = "stockings_lpink"
/datum/sprite_accessory/socks/stockings_purple
name = "Stockings (Purple)"
icon_state = "stockings_purple"
/datum/sprite_accessory/socks/stockings_green
name = "Stockings (Green)"
icon_state = "stockings_green"
/datum/sprite_accessory/socks/stockings_cyan
name = "Stockings (Cyan)"
icon_state = "stockings_cyan"
/datum/sprite_accessory/socks/stockings_orange
name = "Stockings (Orange)"
icon_state = "stockings_orange"
/datum/sprite_accessory/socks/stockings_yellow
name = "Stockings (Yellow)"
icon_state = "stockings_yellow"
/datum/sprite_accessory/socks/stockings_dpink
name = "Stockings (Dark Pink)"
icon_state = "stockings_dpink"
/datum/sprite_accessory/socks/stockings_blue
name = "Stockings (Blue)"
icon_state = "stockings_blue"
+1 -1
View File
@@ -47,7 +47,7 @@
/mob/proc/say_dead(message)
if(client)
if(!client.holder)
if(!config.dsay_allowed)
if(!GLOB.dsay_enabled)
to_chat(src, "<span class='danger'>Deadchat is globally muted.</span>")
return