Merge remote-tracking branch 'origin/master' into rustsql
This commit is contained in:
@@ -69,6 +69,9 @@
|
||||
#define LINGBLOOD_EXPLOSION_THRESHOLD (LINGBLOOD_DETECTION_THRESHOLD * LINGBLOOD_EXPLOSION_MULT) //Hey, important to note here: the explosion threshold is explicitly more than, rather than more than or equal to. This stops a single loud ability from triggering the explosion threshold.
|
||||
|
||||
///Heretics --
|
||||
GLOBAL_LIST_EMPTY(living_heart_cache) //A list of all living hearts in existance, for us to iterate through.
|
||||
|
||||
|
||||
#define IS_HERETIC(mob) (mob.mind?.has_antag_datum(/datum/antagonist/heretic))
|
||||
#define IS_HERETIC_MONSTER(mob) (mob.mind?.has_antag_datum(/datum/antagonist/heretic_monster))
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@
|
||||
|
||||
#define COMSIG_LIVING_ACTIVE_BLOCK_START "active_block_start" //from base of mob/living/keybind_start_active_blocking(): (obj/item/blocking_item, list/backup_items)
|
||||
#define COMPONENT_PREVENT_BLOCK_START 1
|
||||
#define COMSIG_LIVING_ACTIVE_PARRY_START "active_parry_start" //from base of mob/living/initiate_parry_sequence(): (parrying_method, datum/parrying_item_mob_or_art, list/backup_items)
|
||||
#define COMSIG_LIVING_ACTIVE_PARRY_START "active_parry_start" //from base of mob/living/initiate_parry_sequence(): (parrying_method, datum/parrying_item_mob_or_art, list/backup_items, list/override)
|
||||
#define COMPONENT_PREVENT_PARRY_START 1
|
||||
|
||||
//ALL OF THESE DO NOT TAKE INTO ACCOUNT WHETHER AMOUNT IS 0 OR LOWER AND ARE SENT REGARDLESS!
|
||||
@@ -541,6 +541,9 @@
|
||||
#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob)
|
||||
#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob)
|
||||
|
||||
// /datum/element/ventcrawling signals
|
||||
#define COMSIG_HANDLE_VENTCRAWL "handle_ventcrawl" //when atom with ventcrawling element attempts to ventcrawl
|
||||
#define COMSIG_CHECK_VENTCRAWL "check_ventcrawl" //to check an atom's ventcrawling element tier (if applicable)
|
||||
// twitch plays
|
||||
/// Returns direction: (wipe_votes)
|
||||
#define COMSIG_TWITCH_PLAYS_MOVEMENT_DATA "twitch_plays_movement_data"
|
||||
|
||||
@@ -24,3 +24,4 @@
|
||||
#define LANGUAGE_STONER "stoner"
|
||||
#define LANGUAGE_VASSAL "vassal"
|
||||
#define LANGUAGE_VOICECHANGE "voicechange"
|
||||
#define LANGUAGE_MULTILINGUAL "multilingual"
|
||||
|
||||
@@ -72,9 +72,11 @@
|
||||
#define LOADOUT_LIMBS list(LOADOUT_LIMB_NORMAL,LOADOUT_LIMB_PROSTHETIC,LOADOUT_LIMB_AMPUTATED) //you can amputate your legs/arms though
|
||||
|
||||
//loadout saving/loading specific defines
|
||||
#define MAXIMUM_LOADOUT_SAVES 5
|
||||
#define LOADOUT_ITEM "loadout_item"
|
||||
#define LOADOUT_COLOR "loadout_color"
|
||||
#define MAXIMUM_LOADOUT_SAVES 5
|
||||
#define LOADOUT_ITEM "loadout_item"
|
||||
#define LOADOUT_COLOR "loadout_color"
|
||||
#define LOADOUT_CUSTOM_NAME "loadout_custom_name"
|
||||
#define LOADOUT_CUSTOM_DESCRIPTION "loadout_custom_description"
|
||||
|
||||
//loadout item flags
|
||||
#define LOADOUT_CAN_NAME (1<<0) //renaming items
|
||||
|
||||
@@ -69,8 +69,8 @@
|
||||
//Checks to determine borg availability depending on the server's config. These are defines in the interest of reducing copypasta
|
||||
#define BORG_SEC_AVAILABLE (!CONFIG_GET(flag/disable_secborg) && GLOB.security_level >= CONFIG_GET(number/minimum_secborg_alert))
|
||||
|
||||
//silicon_priviledges flags
|
||||
#define PRIVILEDGES_SILICON (1<<0)
|
||||
#define PRIVILEDGES_PAI (1<<1)
|
||||
#define PRIVILEDGES_BOT (1<<2)
|
||||
#define PRIVILEDGES_DRONE (1<<3)
|
||||
//silicon_privileges flags
|
||||
#define PRIVILEGES_SILICON (1<<0)
|
||||
#define PRIVILEGES_PAI (1<<1)
|
||||
#define PRIVILEGES_BOT (1<<2)
|
||||
#define PRIVILEGES_DRONE (1<<3)
|
||||
|
||||
@@ -204,7 +204,7 @@
|
||||
///Compile all the overlays for an atom from the cache lists
|
||||
// |= on overlays is not actually guaranteed to not add same appearances but we're optimistically using it anyway.
|
||||
#define COMPILE_OVERLAYS(A)\
|
||||
if (TRUE) {\
|
||||
do {\
|
||||
var/list/ad = A.add_overlays;\
|
||||
var/list/rm = A.remove_overlays;\
|
||||
if(LAZYLEN(rm)){\
|
||||
@@ -216,7 +216,7 @@
|
||||
ad.Cut();\
|
||||
}\
|
||||
A.flags_1 &= ~OVERLAY_QUEUED_1;\
|
||||
}
|
||||
} while(FALSE)
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -197,6 +197,7 @@
|
||||
#define TRAIT_EMPATH "empath"
|
||||
#define TRAIT_FRIENDLY "friendly"
|
||||
#define TRAIT_SNOB "snob"
|
||||
#define TRAIT_MULTILINGUAL "multilingual"
|
||||
#define TRAIT_CULT_EYES "cult_eyes"
|
||||
#define TRAIT_AUTO_CATCH_ITEM "auto_catch_item"
|
||||
#define TRAIT_CLOWN_MENTALITY "clown_mentality" // The future is now, clownman.
|
||||
@@ -253,6 +254,7 @@
|
||||
|
||||
// item traits
|
||||
#define TRAIT_NODROP "nodrop"
|
||||
#define TRAIT_SPOOKY_THROW "spooky_throw"
|
||||
|
||||
// common trait sources
|
||||
#define TRAIT_GENERIC "generic"
|
||||
|
||||
+46
-17
@@ -66,25 +66,54 @@
|
||||
} while(FALSE)
|
||||
|
||||
//Returns a list in plain english as a string
|
||||
/proc/english_list(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" )
|
||||
var/total = input.len
|
||||
if (!total)
|
||||
return nothing_text
|
||||
else if (total == 1)
|
||||
return "[input[1]]"
|
||||
else if (total == 2)
|
||||
return "[input[1]][and_text][input[2]]"
|
||||
else
|
||||
var/output = ""
|
||||
var/index = 1
|
||||
while (index < total)
|
||||
if (index == total - 1)
|
||||
comma_text = final_comma_text
|
||||
/proc/english_list(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "")
|
||||
var/total = length(input)
|
||||
switch(total)
|
||||
if (0)
|
||||
return "[nothing_text]"
|
||||
if (1)
|
||||
return "[input[1]]"
|
||||
if (2)
|
||||
return "[input[1]][and_text][input[2]]"
|
||||
else
|
||||
var/output = ""
|
||||
var/index = 1
|
||||
while (index < total)
|
||||
if (index == total - 1)
|
||||
comma_text = final_comma_text
|
||||
|
||||
output += "[input[index]][comma_text]"
|
||||
index++
|
||||
output += "[input[index]][comma_text]"
|
||||
index++
|
||||
|
||||
return "[output][and_text][input[index]]"
|
||||
return "[output][and_text][input[index]]"
|
||||
|
||||
/**
|
||||
* English_list but associative supporting. Higher overhead.
|
||||
*/
|
||||
/proc/english_list_assoc(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "")
|
||||
var/total = length(input)
|
||||
switch(total)
|
||||
if (0)
|
||||
return "[nothing_text]"
|
||||
if (1)
|
||||
var/assoc = input[input[1]] == null? "" : " = [input[input[1]]]"
|
||||
return "[input[1]][assoc]"
|
||||
if (2)
|
||||
var/assoc = input[input[1]] == null? "" : " = [input[input[1]]]"
|
||||
var/assoc2 = input[input[2]] == null? "" : " = [input[input[2]]]"
|
||||
return "[input[1]][assoc][and_text][input[2]][assoc2]"
|
||||
else
|
||||
var/output = ""
|
||||
var/index = 1
|
||||
var/assoc
|
||||
while (index < total)
|
||||
if (index == total - 1)
|
||||
comma_text = final_comma_text
|
||||
assoc = input[input[index]] == null? "" : " = [input[input[index]]]"
|
||||
output += "[input[index]][assoc][comma_text]"
|
||||
++index
|
||||
assoc = input[input[index]] == null? "" : " = [input[input[index]]]"
|
||||
return "[output][and_text][input[index]]"
|
||||
|
||||
//Returns list element or null. Should prevent "index out of bounds" error.
|
||||
/proc/listgetindex(list/L, index)
|
||||
|
||||
@@ -231,10 +231,10 @@
|
||||
src_object = window.locked_by.src_object
|
||||
// Insert src_object info
|
||||
if(src_object)
|
||||
entry += "\nUsing: [src_object.type] [REF(src_object)]"
|
||||
entry += "Using: [src_object.type] [REF(src_object)]"
|
||||
// Insert message
|
||||
if(message)
|
||||
entry += "\n[message]"
|
||||
entry += "[message]"
|
||||
WRITE_LOG(GLOB.tgui_log, entry)
|
||||
|
||||
/* Close open log handles. This should be called as late as possible, and no logging should hapen after. */
|
||||
|
||||
@@ -19,22 +19,6 @@
|
||||
/proc/arachnid_name()
|
||||
return "[pick(GLOB.arachnid_first)] [pick(GLOB.arachnid_last)]"
|
||||
|
||||
/proc/church_name()
|
||||
var/static/church_name
|
||||
if (church_name)
|
||||
return church_name
|
||||
|
||||
var/name = ""
|
||||
|
||||
name += pick("Holy", "United", "First", "Second", "Last")
|
||||
|
||||
if (prob(20))
|
||||
name += " Space"
|
||||
|
||||
name += " " + pick("Church", "Cathedral", "Body", "Worshippers", "Movement", "Witnesses")
|
||||
name += " of [religion_name()]"
|
||||
|
||||
return name
|
||||
|
||||
GLOBAL_VAR(command_name)
|
||||
/proc/command_name()
|
||||
@@ -52,17 +36,6 @@ GLOBAL_VAR(command_name)
|
||||
|
||||
return name
|
||||
|
||||
/proc/religion_name()
|
||||
var/static/religion_name
|
||||
if (religion_name)
|
||||
return religion_name
|
||||
|
||||
var/name = ""
|
||||
|
||||
name += pick("bee", "science", "edu", "captain", "assistant", "monkey", "alien", "space", "unit", "sprocket", "gadget", "bomb", "revolution", "beyond", "station", "goon", "robot", "ivor", "hobnob")
|
||||
name += pick("ism", "ia", "ology", "istism", "ites", "ick", "ian", "ity")
|
||||
|
||||
return capitalize(name)
|
||||
|
||||
/proc/station_name()
|
||||
if(!GLOB.station_name)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
announcement += "<br><h2 class='alert'>[html_encode(title)]</h2>"
|
||||
else if(type == "Captain")
|
||||
announcement += "<h1 class='alert'>Captain Announces</h1>"
|
||||
GLOB.news_network.SubmitArticle(text, "Captain's Announcement", "Station Announcements", null)
|
||||
GLOB.news_network.SubmitArticle(html_encode(text), "Captain's Announcement", "Station Announcements", null)
|
||||
|
||||
else
|
||||
if(!sender_override)
|
||||
|
||||
+16
-16
@@ -78,21 +78,21 @@
|
||||
//Turns a direction into text
|
||||
/proc/dir2text(direction)
|
||||
switch(direction)
|
||||
if(1)
|
||||
if(NORTH)
|
||||
return "north"
|
||||
if(2)
|
||||
if(SOUTH)
|
||||
return "south"
|
||||
if(4)
|
||||
if(EAST)
|
||||
return "east"
|
||||
if(8)
|
||||
if(WEST)
|
||||
return "west"
|
||||
if(5)
|
||||
if(NORTHEAST)
|
||||
return "northeast"
|
||||
if(6)
|
||||
if(SOUTHEAST)
|
||||
return "southeast"
|
||||
if(9)
|
||||
if(NORTHWEST)
|
||||
return "northwest"
|
||||
if(10)
|
||||
if(SOUTHWEST)
|
||||
return "southwest"
|
||||
else
|
||||
return
|
||||
@@ -101,21 +101,21 @@
|
||||
/proc/text2dir(direction)
|
||||
switch(uppertext(direction))
|
||||
if("NORTH")
|
||||
return 1
|
||||
return NORTH
|
||||
if("SOUTH")
|
||||
return 2
|
||||
return SOUTH
|
||||
if("EAST")
|
||||
return 4
|
||||
return EAST
|
||||
if("WEST")
|
||||
return 8
|
||||
return WEST
|
||||
if("NORTHEAST")
|
||||
return 5
|
||||
return NORTHEAST
|
||||
if("NORTHWEST")
|
||||
return 9
|
||||
return NORTHWEST
|
||||
if("SOUTHEAST")
|
||||
return 6
|
||||
return SOUTHEAST
|
||||
if("SOUTHWEST")
|
||||
return 10
|
||||
return SOUTHWEST
|
||||
else
|
||||
return
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
return .
|
||||
|
||||
//Returns a list of all items of interest with their name
|
||||
/proc/getpois(mobs_only=0,skip_mindless=0)
|
||||
/proc/getpois(mobs_only = FALSE, skip_mindless = FALSE, specify_dead_role = TRUE)
|
||||
var/list/mobs = sortmobs()
|
||||
var/list/namecounts = list()
|
||||
var/list/pois = list()
|
||||
@@ -277,7 +277,7 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
|
||||
if(M.real_name && M.real_name != M.name)
|
||||
name += " \[[M.real_name]\]"
|
||||
if(M.stat == DEAD)
|
||||
if(M.stat == DEAD && specify_dead_role)
|
||||
if(isobserver(M))
|
||||
name += " \[ghost\]"
|
||||
else
|
||||
@@ -1070,7 +1070,7 @@ B --><-- A
|
||||
return closest_atom
|
||||
|
||||
|
||||
proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
|
||||
/proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
|
||||
if (value == FALSE) //nothing should be calling us with a number, so this is safe
|
||||
value = input("Enter type to find (blank for all, cancel to cancel)", "Search for type") as null|text
|
||||
if (isnull(value))
|
||||
|
||||
@@ -274,7 +274,7 @@ GLOBAL_LIST_INIT(redacted_strings, list("\[REDACTED\]", "\[CLASSIFIED\]", "\[ARC
|
||||
GLOBAL_LIST_INIT(wisdoms, world.file2list("strings/wisdoms.txt"))
|
||||
|
||||
//LANGUAGE CHARACTER CUSTOMIZATION
|
||||
GLOBAL_LIST_INIT(speech_verbs, list("default","says","gibbers", "states", "chitters", "chimpers", "declares", "bellows", "buzzes" ,"beeps", "chirps", "clicks", "hisses" ,"poofs" , "puffs", "rattles", "mewls" ,"barks", "blorbles", "squeaks", "squawks", "flutters", "warbles"))
|
||||
GLOBAL_LIST_INIT(speech_verbs, list("default","says","gibbers", "states", "chitters", "chimpers", "declares", "bellows", "buzzes" ,"beeps", "chirps", "clicks", "hisses" ,"poofs" , "puffs", "rattles", "mewls" ,"barks", "blorbles", "squeaks", "squawks", "flutters", "warbles", "caws", "gekkers", "clucks"))
|
||||
GLOBAL_LIST_INIT(roundstart_tongues, list("default","human tongue" = /obj/item/organ/tongue, "lizard tongue" = /obj/item/organ/tongue/lizard, "skeleton tongue" = /obj/item/organ/tongue/bone, "fly tongue" = /obj/item/organ/tongue/fly, "ipc tongue" = /obj/item/organ/tongue/robot/ipc, "xeno tongue" = /obj/item/organ/tongue/alien))
|
||||
|
||||
//SPECIES BODYPART LISTS
|
||||
|
||||
@@ -130,7 +130,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
),
|
||||
/obj/item = list(
|
||||
"TRAIT_NODROP" = TRAIT_NODROP,
|
||||
"TRAIT_NO_TELEPORT" = TRAIT_NO_TELEPORT
|
||||
"TRAIT_NO_TELEPORT" = TRAIT_NO_TELEPORT,
|
||||
"TRAIT_SPOOKY_THROW" = TRAIT_SPOOKY_THROW
|
||||
)
|
||||
))
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@
|
||||
|
||||
/obj/screen/alert/shiver
|
||||
name = "Shivering"
|
||||
desc = "You're shivering! Get somewhere warmer and take off any insulating clothing like a space suit."
|
||||
desc = "You're shivering! Get somewhere warmer and take off any insulating clothing like a space suit."
|
||||
|
||||
/obj/screen/alert/lowpressure
|
||||
name = "Low Pressure"
|
||||
@@ -306,6 +306,39 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
|
||||
if(CHECK_MOBILITY(L, MOBILITY_MOVE))
|
||||
return L.resist_fire() //I just want to start a flame in your hearrrrrrtttttt.
|
||||
|
||||
/obj/screen/alert/give // information set when the give alert is made
|
||||
icon_state = "default"
|
||||
var/mob/living/carbon/giver
|
||||
var/obj/item/receiving
|
||||
|
||||
/**
|
||||
* Handles assigning most of the variables for the alert that pops up when an item is offered
|
||||
*
|
||||
* Handles setting the name, description and icon of the alert and tracking the person giving
|
||||
* and the item being offered, also registers a signal that removes the alert from anyone who moves away from the giver
|
||||
* Arguments:
|
||||
* * taker - The person receiving the alert
|
||||
* * giver - The person giving the alert and item
|
||||
* * receiving - The item being given by the giver
|
||||
*/
|
||||
/obj/screen/alert/give/proc/setup(mob/living/carbon/taker, mob/living/carbon/giver, obj/item/receiving)
|
||||
name = "[giver] is offering [receiving]"
|
||||
desc = "[giver] is offering [receiving]. Click this alert to take it."
|
||||
icon_state = "template"
|
||||
cut_overlays()
|
||||
add_overlay(receiving)
|
||||
src.receiving = receiving
|
||||
src.giver = giver
|
||||
RegisterSignal(taker, COMSIG_MOVABLE_MOVED, .proc/removeAlert)
|
||||
|
||||
/obj/screen/alert/give/proc/removeAlert()
|
||||
to_chat(usr, "<span class='warning'>You moved out of range of [giver]!</span>")
|
||||
usr.clear_alert("[giver]")
|
||||
|
||||
/obj/screen/alert/give/Click(location, control, params)
|
||||
. = ..()
|
||||
var/mob/living/carbon/C = usr
|
||||
C.take(giver, receiving)
|
||||
|
||||
//ALIENS
|
||||
|
||||
|
||||
+46
-21
@@ -118,27 +118,7 @@
|
||||
action_intent.hud = src
|
||||
static_inventory += action_intent
|
||||
|
||||
using = new /obj/screen/mov_intent
|
||||
using.icon = tg_ui_icon_to_cit_ui(ui_style) // CIT CHANGE - overrides mov intent icon
|
||||
using.icon_state = (mymob.m_intent == MOVE_INTENT_RUN ? "running" : "walking")
|
||||
using.screen_loc = ui_movi
|
||||
using.hud = src
|
||||
static_inventory += using
|
||||
|
||||
//CITADEL CHANGES - sprint button
|
||||
using = new /obj/screen/sprintbutton
|
||||
using.icon = tg_ui_icon_to_cit_ui(ui_style)
|
||||
using.icon_state = ((owner.combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) ? "act_sprint_on" : "act_sprint")
|
||||
using.screen_loc = ui_movi
|
||||
using.hud = src
|
||||
static_inventory += using
|
||||
//END OF CITADEL CHANGES
|
||||
|
||||
//same as above but buffer.
|
||||
sprint_buffer = new /obj/screen/sprint_buffer
|
||||
sprint_buffer.screen_loc = ui_sprintbufferloc
|
||||
sprint_buffer.hud = src
|
||||
static_inventory += sprint_buffer
|
||||
assert_move_intent_ui(owner, TRUE)
|
||||
|
||||
// clickdelay
|
||||
clickdelay = new
|
||||
@@ -393,6 +373,51 @@
|
||||
|
||||
update_locked_slots()
|
||||
|
||||
/datum/hud/human/proc/assert_move_intent_ui(mob/living/carbon/human/owner = mymob, on_new = FALSE)
|
||||
var/obj/screen/using
|
||||
// delete old ones
|
||||
var/list/obj/screen/victims = list()
|
||||
victims += locate(/obj/screen/mov_intent) in static_inventory
|
||||
victims += locate(/obj/screen/sprintbutton) in static_inventory
|
||||
victims += locate(/obj/screen/sprint_buffer) in static_inventory
|
||||
if(victims)
|
||||
static_inventory -= victims
|
||||
if(mymob?.client)
|
||||
mymob.client.screen -= victims
|
||||
QDEL_LIST(victims)
|
||||
|
||||
// make new ones
|
||||
// walk/run
|
||||
using = new /obj/screen/mov_intent
|
||||
using.icon = tg_ui_icon_to_cit_ui(ui_style) // CIT CHANGE - overrides mov intent icon
|
||||
using.screen_loc = ui_movi
|
||||
using.hud = src
|
||||
using.update_icon()
|
||||
static_inventory += using
|
||||
if(!on_new)
|
||||
owner?.client?.screen += using
|
||||
|
||||
if(!CONFIG_GET(flag/sprint_enabled))
|
||||
return
|
||||
|
||||
// sprint button
|
||||
using = new /obj/screen/sprintbutton
|
||||
using.icon = tg_ui_icon_to_cit_ui(ui_style)
|
||||
using.icon_state = ((owner.combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) ? "act_sprint_on" : "act_sprint")
|
||||
using.screen_loc = ui_movi
|
||||
using.hud = src
|
||||
static_inventory += using
|
||||
if(!on_new)
|
||||
owner?.client?.screen += using
|
||||
|
||||
// same as above but buffer.
|
||||
sprint_buffer = new /obj/screen/sprint_buffer
|
||||
sprint_buffer.screen_loc = ui_sprintbufferloc
|
||||
sprint_buffer.hud = src
|
||||
static_inventory += sprint_buffer
|
||||
if(!on_new)
|
||||
owner?.client?.screen += using
|
||||
|
||||
/datum/hud/human/update_locked_slots()
|
||||
if(!mymob)
|
||||
return
|
||||
|
||||
@@ -351,6 +351,10 @@
|
||||
icon = 'icons/mob/screen_midnight.dmi'
|
||||
icon_state = "running"
|
||||
|
||||
/obj/screen/mov_intent/Initialize(mapload)
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
/obj/screen/mov_intent/Click()
|
||||
toggle(usr)
|
||||
|
||||
@@ -359,7 +363,7 @@
|
||||
if(MOVE_INTENT_WALK)
|
||||
icon_state = "walking"
|
||||
if(MOVE_INTENT_RUN)
|
||||
icon_state = "running"
|
||||
icon_state = CONFIG_GET(flag/sprint_enabled)? "running" : "running_nosprint"
|
||||
|
||||
/obj/screen/mov_intent/proc/toggle(mob/user)
|
||||
if(isobserver(user))
|
||||
|
||||
@@ -290,6 +290,17 @@
|
||||
var/datum/movespeed_modifier/config_walk_run/M = get_cached_movespeed_modifier(/datum/movespeed_modifier/config_walk_run/walk)
|
||||
M.sync()
|
||||
|
||||
/datum/config_entry/flag/sprint_enabled
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/sprint_enabled/ValidateAndSet(str_val)
|
||||
. = ..()
|
||||
for(var/datum/hud/human/H)
|
||||
H.assert_move_intent_ui()
|
||||
if(!config_entry_value) // disabled
|
||||
for(var/mob/living/L in world)
|
||||
L.disable_intentional_sprint_mode()
|
||||
|
||||
/datum/config_entry/number/movedelay/sprint_speed_increase
|
||||
config_entry_value = 1
|
||||
|
||||
@@ -484,6 +495,8 @@
|
||||
|
||||
/datum/config_entry/flag/modetier_voting
|
||||
|
||||
/datum/config_entry/flag/must_be_readied_to_vote_gamemode
|
||||
|
||||
/datum/config_entry/number/dropped_modes
|
||||
config_entry_value = 3
|
||||
|
||||
|
||||
@@ -26,50 +26,6 @@
|
||||
|
||||
/datum/config_entry/flag/hub // if the game appears on the hub or not
|
||||
|
||||
/datum/config_entry/flag/log_ooc // log OOC channel
|
||||
|
||||
/datum/config_entry/flag/log_access // log login/logout
|
||||
|
||||
/datum/config_entry/flag/log_say // log client say
|
||||
|
||||
/datum/config_entry/flag/log_admin // log admin actions
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
/datum/config_entry/flag/log_prayer // log prayers
|
||||
|
||||
/datum/config_entry/flag/log_law // log lawchanges
|
||||
|
||||
/datum/config_entry/flag/log_game // log game events
|
||||
|
||||
/datum/config_entry/flag/log_virus // log virology data
|
||||
|
||||
/datum/config_entry/flag/log_vote // log voting
|
||||
|
||||
/datum/config_entry/flag/log_craft // log crafting
|
||||
|
||||
/datum/config_entry/flag/log_whisper // log client whisper
|
||||
|
||||
/datum/config_entry/flag/log_attack // log attack messages
|
||||
|
||||
/datum/config_entry/flag/log_emote // log emotes
|
||||
|
||||
/datum/config_entry/flag/log_adminchat // log admin chat messages
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
/datum/config_entry/flag/log_shuttle // log shuttle related actions, ie shuttle computers, shuttle manipulator, emergency console
|
||||
|
||||
/datum/config_entry/flag/log_pda // log pda messages
|
||||
|
||||
/datum/config_entry/flag/log_telecomms // log telecomms messages
|
||||
|
||||
/datum/config_entry/flag/log_twitter // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases.
|
||||
|
||||
/datum/config_entry/flag/log_world_topic // log all world.Topic() calls
|
||||
|
||||
/datum/config_entry/flag/log_manifest // log crew manifest to seperate file
|
||||
|
||||
/datum/config_entry/flag/log_job_debug // log roundstart divide occupations debug information to a file
|
||||
|
||||
/datum/config_entry/flag/allow_admin_ooccolor // Allows admins with relevant permissions to have their own ooc colour
|
||||
|
||||
/datum/config_entry/flag/allow_vote_restart // allow votes to restart
|
||||
@@ -477,10 +433,6 @@
|
||||
/datum/config_entry/string/default_view_square
|
||||
config_entry_value = "15x15"
|
||||
|
||||
/datum/config_entry/flag/log_pictures
|
||||
|
||||
/datum/config_entry/flag/picture_logging_camera
|
||||
|
||||
/datum/config_entry/number/max_bunker_days
|
||||
config_entry_value = 7
|
||||
min_val = 1
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/datum/config_entry/flag/log_ooc // log OOC channel
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_access // log login/logout
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_say // log client say
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_admin // log admin actions
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
/datum/config_entry/flag/log_prayer // log prayers
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_law // log lawchanges
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_game // log game events
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_virus // log virology data
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_vote // log voting
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_craft // log crafting
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_whisper // log client whisper
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_attack // log attack messages
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_emote // log emotes
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_adminchat // log admin chat messages
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
/datum/config_entry/flag/log_shuttle // log shuttle related actions, ie shuttle computers, shuttle manipulator, emergency console
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_pda // log pda messages
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_telecomms // log telecomms messages
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_twitter // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases.
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_world_topic // log all world.Topic() calls
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_manifest // log crew manifest to seperate file
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_job_debug // log roundstart divide occupations debug information to a file
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/log_pictures
|
||||
|
||||
/datum/config_entry/flag/picture_logging_camera
|
||||
|
||||
/// forces log_href for tgui
|
||||
/datum/config_entry/flag/emergency_tgui_logging
|
||||
config_entry_value = FALSE
|
||||
@@ -490,6 +490,28 @@ SUBSYSTEM_DEF(job)
|
||||
job.after_spawn(H, M, joined_late) // note: this happens before the mob has a key! M will always have a client, H might not.
|
||||
equip_loadout(N, H, TRUE)//CIT CHANGE - makes players spawn with in-backpack loadout items properly. A little hacky but it works
|
||||
|
||||
if(ishuman(H) && H.client && N)
|
||||
if(H.client && H.client.prefs && length(H.client.prefs.tcg_cards))
|
||||
var/obj/item/tcgcard_binder/binder = new(get_turf(H))
|
||||
if(!H.equip_to_slot_if_possible(binder, SLOT_IN_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE))
|
||||
qdel(binder)
|
||||
else
|
||||
for(var/card_type in H.client.prefs.tcg_cards)
|
||||
var/obj/item/tcg_card/card = new(get_turf(H), card_type, H.client.prefs.tcg_cards[card_type])
|
||||
card.forceMove(binder)
|
||||
binder.cards.Add(card)
|
||||
binder.check_for_exodia()
|
||||
else
|
||||
if(H && N.client.prefs && length(N.client.prefs.tcg_cards))
|
||||
var/obj/item/tcgcard_binder/binder = new(get_turf(H))
|
||||
if(!H.equip_to_slot_if_possible(binder, SLOT_IN_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE))
|
||||
qdel(binder)
|
||||
else
|
||||
for(var/card_type in N.client.prefs.tcg_cards)
|
||||
var/obj/item/tcg_card/card = new(get_turf(H), card_type, H.client.prefs.tcg_cards[card_type])
|
||||
card.forceMove(binder)
|
||||
binder.cards.Add(card)
|
||||
|
||||
return H
|
||||
/*
|
||||
/datum/controller/subsystem/job/proc/handle_auto_deadmin_roles(client/C, rank)
|
||||
@@ -691,21 +713,29 @@ SUBSYSTEM_DEF(job)
|
||||
if(!permitted)
|
||||
continue
|
||||
var/obj/item/I = new G.path
|
||||
if(I && length(i[LOADOUT_COLOR])) //handle loadout colors
|
||||
//handle polychromic items
|
||||
if((G.loadout_flags & LOADOUT_CAN_COLOR_POLYCHROMIC) && length(G.loadout_initial_colors))
|
||||
var/datum/element/polychromic/polychromic = I.comp_lookup["item_worn_overlays"] //stupid way to do it but GetElement does not work for this
|
||||
if(polychromic && istype(polychromic))
|
||||
var/list/polychromic_entry = polychromic.colors_by_atom[I]
|
||||
if(polychromic_entry)
|
||||
if(polychromic.suits_with_helmet_typecache[I.type]) //is this one of those toggleable hood/helmet things?
|
||||
polychromic.connect_helmet(I,i[LOADOUT_COLOR])
|
||||
polychromic.colors_by_atom[I] = i[LOADOUT_COLOR]
|
||||
I.update_icon()
|
||||
else
|
||||
//handle non-polychromic items (they only have one color)
|
||||
I.add_atom_colour(i[LOADOUT_COLOR][1], FIXED_COLOUR_PRIORITY)
|
||||
I.update_icon()
|
||||
if(I)
|
||||
if(length(i[LOADOUT_COLOR])) //handle loadout colors
|
||||
//handle polychromic items
|
||||
if((G.loadout_flags & LOADOUT_CAN_COLOR_POLYCHROMIC) && length(G.loadout_initial_colors))
|
||||
var/datum/element/polychromic/polychromic = I.comp_lookup["item_worn_overlays"] //stupid way to do it but GetElement does not work for this
|
||||
if(polychromic && istype(polychromic))
|
||||
var/list/polychromic_entry = polychromic.colors_by_atom[I]
|
||||
if(polychromic_entry)
|
||||
if(polychromic.suits_with_helmet_typecache[I.type]) //is this one of those toggleable hood/helmet things?
|
||||
polychromic.connect_helmet(I,i[LOADOUT_COLOR])
|
||||
polychromic.colors_by_atom[I] = i[LOADOUT_COLOR]
|
||||
I.update_icon()
|
||||
else
|
||||
//handle non-polychromic items (they only have one color)
|
||||
I.add_atom_colour(i[LOADOUT_COLOR][1], FIXED_COLOUR_PRIORITY)
|
||||
I.update_icon()
|
||||
//when inputting the data it's already sanitized
|
||||
if(i[LOADOUT_CUSTOM_NAME])
|
||||
var/custom_name = i[LOADOUT_CUSTOM_NAME]
|
||||
I.name = custom_name
|
||||
if(i[LOADOUT_CUSTOM_DESCRIPTION])
|
||||
var/custom_description = i[LOADOUT_CUSTOM_DESCRIPTION]
|
||||
I.desc = custom_description
|
||||
if(!M.equip_to_slot_if_possible(I, G.slot, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) // If the job's dresscode compliant, try to put it in its slot, first
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
|
||||
@@ -88,6 +88,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
SavePhotoPersistence() //THIS IS PERSISTENCE, NOT THE LOGGING PORTION.
|
||||
SavePaintings()
|
||||
SaveScars()
|
||||
SaveTCGCards()
|
||||
|
||||
/**
|
||||
* Loads persistent data relevant to the current map: Objects, etc.
|
||||
@@ -349,3 +350,25 @@ SUBSYSTEM_DEF(persistence)
|
||||
if(!ending_human.client)
|
||||
return
|
||||
ending_human.client.prefs.save_character()
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/SaveTCGCards()
|
||||
for(var/i in GLOB.joined_player_list)
|
||||
var/mob/living/carbon/human/ending_human = get_mob_by_ckey(i)
|
||||
if(!istype(ending_human) || !ending_human.mind || !ending_human.client || !ending_human.client.prefs || !ending_human.client.prefs.tcg_cards)
|
||||
continue
|
||||
|
||||
var/mob/living/carbon/human/original_human = ending_human.mind.original_character
|
||||
if(!original_human || original_human.stat == DEAD || !(original_human == ending_human))
|
||||
continue
|
||||
|
||||
var/obj/item/tcgcard_binder/binder = locate() in ending_human
|
||||
if(!binder || !length(binder.cards))
|
||||
continue
|
||||
|
||||
var/list/card_types = list()
|
||||
for(var/obj/item/tcg_card/card in binder.cards)
|
||||
//if(!card.illegal) //Uncomment if you want to block syndie cards from saving
|
||||
card_types[card.datum_type] = card.illegal
|
||||
|
||||
ending_human.client.prefs.tcg_cards = card_types
|
||||
ending_human.client.prefs.save_character(TRUE)
|
||||
|
||||
@@ -84,6 +84,8 @@ SUBSYSTEM_DEF(throwing)
|
||||
|
||||
|
||||
/datum/thrownthing/Destroy()
|
||||
if(HAS_TRAIT_FROM(thrownthing, TRAIT_SPOOKY_THROW, "revenant"))
|
||||
REMOVE_TRAIT(thrownthing, TRAIT_SPOOKY_THROW, "revenant")
|
||||
SSthrowing.processing -= thrownthing
|
||||
thrownthing.throwing = null
|
||||
thrownthing = null
|
||||
|
||||
@@ -68,6 +68,10 @@ SUBSYSTEM_DEF(vote)
|
||||
//get the highest number of votes
|
||||
var/greatest_votes = 0
|
||||
var/total_votes = 0
|
||||
if(mode == "gamemode" && CONFIG_GET(flag/must_be_readied_to_vote_gamemode))
|
||||
for(var/mob/dead/new_player/P in GLOB.player_list)
|
||||
if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey])
|
||||
choices[choices[voted[P.ckey]]]--
|
||||
for(var/option in choices)
|
||||
var/votes = choices[option]
|
||||
total_votes += votes
|
||||
@@ -101,6 +105,10 @@ SUBSYSTEM_DEF(vote)
|
||||
|
||||
/datum/controller/subsystem/vote/proc/calculate_condorcet_votes(var/blackbox_text)
|
||||
// https://en.wikipedia.org/wiki/Schulze_method#Implementation
|
||||
if((mode == "gamemode" || mode == "dynamic") && CONFIG_GET(flag/must_be_readied_to_vote_gamemode))
|
||||
for(var/mob/dead/new_player/P in GLOB.player_list)
|
||||
if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey])
|
||||
voted -= P.ckey
|
||||
var/list/d[][] = new/list(choices.len,choices.len) // the basic vote matrix, how many times a beats b
|
||||
for(var/ckey in voted)
|
||||
var/list/this_vote = voted[ckey]
|
||||
@@ -147,6 +155,10 @@ SUBSYSTEM_DEF(vote)
|
||||
for(var/choice in choices)
|
||||
scores_by_choice += "[choice]"
|
||||
scores_by_choice["[choice]"] = list()
|
||||
if((mode == "gamemode" || mode == "dynamic") && CONFIG_GET(flag/must_be_readied_to_vote_gamemode))
|
||||
for(var/mob/dead/new_player/P in GLOB.player_list)
|
||||
if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey])
|
||||
voted -= P.ckey
|
||||
for(var/ckey in voted)
|
||||
var/list/this_vote = voted[ckey]
|
||||
var/list/pretty_vote = list()
|
||||
|
||||
@@ -21,12 +21,15 @@ GLOBAL_LIST_EMPTY(GPS_list)
|
||||
var/updating = TRUE //Automatic updating of GPS list. Can be set to manual by user.
|
||||
var/global_mode = TRUE //If disabled, only GPS signals of the same Z level are shown
|
||||
|
||||
/datum/component/gps/item/Initialize(_gpstag = "COM0", emp_proof = FALSE)
|
||||
/datum/component/gps/item/Initialize(_gpstag = "COM0", emp_proof = FALSE, starton = TRUE)
|
||||
. = ..()
|
||||
if(. == COMPONENT_INCOMPATIBLE || !isitem(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
var/atom/A = parent
|
||||
A.add_overlay("working")
|
||||
if(starton)
|
||||
A.add_overlay("working")
|
||||
else
|
||||
tracking = FALSE
|
||||
A.name = "[initial(A.name)] ([gpstag])"
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/interact)
|
||||
if(!emp_proof)
|
||||
|
||||
@@ -146,9 +146,11 @@
|
||||
if(!istype(A) || !get_turf(A) || A == src)
|
||||
return
|
||||
|
||||
orbit_target = A
|
||||
return A.AddComponent(/datum/component/orbiter, src, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
|
||||
|
||||
/atom/movable/proc/stop_orbit(datum/component/orbiter/orbits)
|
||||
orbit_target = null
|
||||
return // We're just a simple hook
|
||||
|
||||
/atom/proc/transfer_observers_to(atom/target)
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
qdel(src)
|
||||
|
||||
/datum/component/riding/proc/vehicle_mob_buckle(datum/source, mob/living/M, force)
|
||||
handle_vehicle_offsets()
|
||||
handle_vehicle_offsets(M.buckled?.dir)
|
||||
|
||||
/datum/component/riding/proc/handle_vehicle_layer(dir)
|
||||
var/atom/movable/AM = parent
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
*A storage component to be used on card piles, for use as hands/decks/discard piles. Don't use on something that's not a card pile!
|
||||
*/
|
||||
/datum/component/storage/concrete/tcg
|
||||
display_numerical_stacking = FALSE
|
||||
max_w_class = WEIGHT_CLASS_TINY
|
||||
max_items = 30
|
||||
max_combined_w_class = WEIGHT_CLASS_TINY * 30
|
||||
///The deck that the card pile is using for FAIR PLAY.
|
||||
|
||||
/datum/component/storage/concrete/tcg/can_be_inserted(obj/item/I, stop_messages, mob/M)
|
||||
. = ..()
|
||||
return istype(I, /obj/item/tcg_card)
|
||||
|
||||
/datum/component/storage/concrete/tcg/PostTransfer()
|
||||
. = ..()
|
||||
handle_empty_deck()
|
||||
|
||||
/datum/component/storage/concrete/tcg/remove_from_storage(atom/movable/AM, atom/new_location)
|
||||
. = ..()
|
||||
handle_empty_deck()
|
||||
|
||||
/datum/component/storage/concrete/tcg/ui_show(mob/M)
|
||||
. = ..()
|
||||
M.visible_message("<span class='notice'>[M] starts to look through the contents of \the [parent]!</span>", \
|
||||
"<span class='notice'>You begin looking into the contents of \the [parent]!</span>")
|
||||
|
||||
/datum/component/storage/concrete/tcg/close(mob/M)
|
||||
. = ..()
|
||||
var/list/card_contents = contents()
|
||||
var/obj/temp_parent = parent
|
||||
temp_parent.visible_message("<span class='notice'>\the [parent] is shuffled after looking through it.</span>")
|
||||
card_contents = shuffle(card_contents)
|
||||
|
||||
/datum/component/storage/concrete/tcg/mass_remove_from_storage(atom/target, list/things, datum/progressbar/progress, trigger_on_found)
|
||||
. = ..()
|
||||
if(!things.len)
|
||||
qdel(parent)
|
||||
|
||||
/datum/component/storage/concrete/tcg/proc/handle_empty_deck()
|
||||
var/list/contents = contents()
|
||||
//You can't have a deck of one card!
|
||||
if(contents.len == 1)
|
||||
var/obj/item/tcgcard_deck/deck = parent
|
||||
var/obj/item/tcg_card/card = contents[1]
|
||||
remove_from_storage(card, card.drop_location())
|
||||
card.flipped = deck.flipped
|
||||
card.update_icon_state()
|
||||
qdel(parent)
|
||||
@@ -449,6 +449,10 @@
|
||||
// this must come before the screen objects only block, dunno why it wasn't before
|
||||
if(over_object == M)
|
||||
user_show_to_mob(M)
|
||||
return
|
||||
if(isrevenant(M))
|
||||
RevenantThrow(over_object, M, source)
|
||||
return
|
||||
if(!M.incapacitated())
|
||||
if(!istype(over_object, /obj/screen))
|
||||
dump_content_at(over_object, M)
|
||||
|
||||
@@ -85,6 +85,10 @@
|
||||
to_chat(user, "<span class='warning'>You're not ready to tackle!</span>")
|
||||
return
|
||||
|
||||
if(!user.mob_has_gravity() ||!user.loc.has_gravity() || isspaceturf(user.loc))
|
||||
to_chat(user, "<span class='warning'>You can't find your footing without gravity!</span>")
|
||||
return
|
||||
|
||||
if(user.has_status_effect(STATUS_EFFECT_TASED)) // can't tackle if you just got tased
|
||||
to_chat(user, "<span class='warning'>You can't tackle while tased!</span>")
|
||||
return
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
add_monkey(affected_mob.mind)
|
||||
if(ishuman(affected_mob))
|
||||
var/mob/living/carbon/monkey/M = affected_mob.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)
|
||||
M.ventcrawler = VENTCRAWLER_ALWAYS
|
||||
M.AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
|
||||
|
||||
|
||||
/datum/disease/transformation/jungle_fever/stage_act()
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
|
||||
/obj/item/clothing/head/mob_holder/dropped(mob/user)
|
||||
. = ..()
|
||||
if(held_mob && isturf(loc))//don't release on soft-drops
|
||||
if(held_mob && !ismob(loc))//don't release on soft-drops
|
||||
release()
|
||||
|
||||
/obj/item/clothing/head/mob_holder/proc/release()
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/datum/element/ventcrawling
|
||||
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
|
||||
id_arg_index = 2
|
||||
var/tier
|
||||
|
||||
/datum/element/ventcrawling/Attach(datum/target, duration = 0, given_tier = VENTCRAWLER_NUDE)
|
||||
. = ..()
|
||||
|
||||
var/mob/living/person = target
|
||||
if(!istype(person))
|
||||
return FALSE
|
||||
|
||||
src.tier = given_tier
|
||||
|
||||
RegisterSignal(target, COMSIG_HANDLE_VENTCRAWL, .proc/handle_ventcrawl)
|
||||
RegisterSignal(target, COMSIG_CHECK_VENTCRAWL, .proc/check_ventcrawl)
|
||||
to_chat(target, "<span class='notice'>You can ventcrawl! Use alt+click on vents to quickly travel about the station.</span>")
|
||||
|
||||
if(duration!=0)
|
||||
addtimer(CALLBACK(src, .proc/Detach, target), duration)
|
||||
|
||||
/datum/element/ventcrawling/Detach(datum/target)
|
||||
UnregisterSignal(target, list(COMSIG_HANDLE_VENTCRAWL, COMSIG_CHECK_VENTCRAWL))
|
||||
to_chat(target, "<span class='notice'>You can no longer ventcrawl.</span>")
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/element/ventcrawling/proc/handle_ventcrawl(datum/target,atom/A)
|
||||
var/mob/living/person = target
|
||||
if(!istype(person))
|
||||
return FALSE
|
||||
|
||||
person.handle_ventcrawl(A,tier)
|
||||
|
||||
/datum/element/ventcrawling/proc/check_ventcrawl()
|
||||
return tier
|
||||
@@ -239,8 +239,13 @@ GLOBAL_LIST_EMPTY(explosions)
|
||||
atoms += A
|
||||
for(var/i in atoms)
|
||||
var/atom/A = i
|
||||
if(!QDELETED(A))
|
||||
A.ex_act(dist)
|
||||
if(QDELETED(A))
|
||||
continue
|
||||
A.ex_act(dist, null, src)
|
||||
if(QDELETED(A) || !ismovable(A))
|
||||
continue
|
||||
var/atom/movable/AM = A
|
||||
LAZYADD(AM.acted_explosions, explosion_id)
|
||||
|
||||
if(flame_dist && prob(40) && !isspaceturf(T) && !T.density)
|
||||
new /obj/effect/hotspot(T) //Mostly for ambience!
|
||||
|
||||
@@ -887,7 +887,7 @@
|
||||
L.remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND)
|
||||
|
||||
|
||||
datum/status_effect/pacify
|
||||
/datum/status_effect/pacify
|
||||
id = "pacify"
|
||||
status_type = STATUS_EFFECT_REPLACE
|
||||
tick_interval = 1
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
var/antag_removal_text // Text will be given to the quirk holder if they get an antag that has it blacklisted.
|
||||
var/mood_quirk = FALSE //if true, this quirk affects mood and is unavailable if moodlets are disabled
|
||||
var/mob_trait //if applicable, apply and remove this mob trait
|
||||
/// should we immediately call on_spawn or add a timer to trigger
|
||||
var/on_spawn_immediate = TRUE
|
||||
var/mob/living/quirk_holder
|
||||
|
||||
/datum/quirk/New(mob/living/quirk_mob, spawn_effects)
|
||||
@@ -26,7 +28,10 @@
|
||||
START_PROCESSING(SSquirks, src)
|
||||
add()
|
||||
if(spawn_effects)
|
||||
on_spawn()
|
||||
if(on_spawn_immediate)
|
||||
on_spawn()
|
||||
else
|
||||
addtimer(CALLBACK(src, .proc/on_spawn), 0)
|
||||
addtimer(CALLBACK(src, .proc/post_add), 30)
|
||||
|
||||
/datum/quirk/Destroy()
|
||||
|
||||
@@ -219,3 +219,19 @@
|
||||
/datum/quirk/night_vision/on_spawn()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
H.update_sight()
|
||||
|
||||
/datum/quirk/multilingual
|
||||
name = "Multi-Lingual"
|
||||
desc = "You spent a portion of your life learning to understand an additional language. You may or may not be able to speak it based on your anatomy."
|
||||
value = 1
|
||||
mob_trait = TRAIT_MULTILINGUAL
|
||||
gain_text = "You've learned an extra language!"
|
||||
lose_text = "You've forgotten your extra language."
|
||||
|
||||
/datum/quirk/multilingual/post_add()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
H.grant_language(H.client.prefs.language, TRUE, TRUE, LANGUAGE_MULTILINGUAL)
|
||||
|
||||
/datum/quirk/multilingual/remove()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
H.remove_language(H.client.prefs.language, TRUE, TRUE, LANGUAGE_MULTILINGUAL)
|
||||
|
||||
@@ -184,6 +184,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
gain_text = null // Handled by trauma.
|
||||
lose_text = null
|
||||
medical_record_text = "Patient has an untreatable impairment in motor function in the lower extremities."
|
||||
on_spawn_immediate = FALSE
|
||||
|
||||
/datum/quirk/paraplegic/add()
|
||||
var/datum/brain_trauma/severe/paralysis/paraplegic/T = new()
|
||||
|
||||
@@ -168,7 +168,7 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
datum/atom_hud/alternate_appearance/basic/onePerson
|
||||
/datum/atom_hud/alternate_appearance/basic/onePerson
|
||||
var/mob/seer
|
||||
|
||||
/datum/atom_hud/alternate_appearance/basic/onePerson/mobShouldSee(mob/M)
|
||||
|
||||
+4
-1
@@ -99,6 +99,9 @@
|
||||
///Mobs that are currently do_after'ing this atom, to be cleared from on Destroy()
|
||||
var/list/targeted_by
|
||||
|
||||
///Reference to atom being orbited
|
||||
var/atom/orbit_target
|
||||
|
||||
/**
|
||||
* Called when an atom is created in byond (built in engine proc)
|
||||
*
|
||||
@@ -548,7 +551,7 @@
|
||||
/atom/proc/contents_explosion(severity, target)
|
||||
return //For handling the effects of explosions on contents that would not normally be effected
|
||||
|
||||
/atom/proc/ex_act(severity, target)
|
||||
/atom/proc/ex_act(severity, target, datum/explosion/E)
|
||||
set waitfor = FALSE
|
||||
contents_explosion(severity, target)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_EX_ACT, severity, target)
|
||||
|
||||
@@ -31,7 +31,14 @@
|
||||
var/list/client_mobs_in_contents // This contains all the client mobs within this container
|
||||
var/list/acted_explosions //for explosion dodging
|
||||
var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm
|
||||
var/movement_type = GROUND //Incase you have multiple types, you automatically use the most useful one. IE: Skating on ice, flippers on water, flying over chasm/space, etc.
|
||||
|
||||
/**
|
||||
* In case you have multiple types, you automatically use the most useful one.
|
||||
* IE: Skating on ice, flippers on water, flying over chasm/space, etc.
|
||||
* I reccomend you use the movetype_handler system and not modify this directly, especially for living mobs.
|
||||
*/
|
||||
var/movement_type = GROUND
|
||||
|
||||
var/atom/movable/pulling
|
||||
var/grab_state = 0
|
||||
var/throwforce = 0
|
||||
@@ -567,8 +574,8 @@
|
||||
return TRUE
|
||||
|
||||
//TODO: Better floating
|
||||
/atom/movable/proc/float(on)
|
||||
if(throwing)
|
||||
/atom/movable/proc/float(on, throw_override)
|
||||
if(throwing || !throw_override)
|
||||
return
|
||||
if(on && !(movement_type & FLOATING))
|
||||
animate(src, pixel_y = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
icon_state = "knuckles"
|
||||
w_class = 3
|
||||
|
||||
datum/gang_item/clothing/shades //Addition: Why not have cool shades on a gang member anyways?
|
||||
/datum/gang_item/clothing/shades //Addition: Why not have cool shades on a gang member anyways?
|
||||
name = "Cool Sunglasses"
|
||||
id = "glasses"
|
||||
cost = 5
|
||||
@@ -313,13 +313,13 @@ datum/gang_item/clothing/shades //Addition: Why not have cool shades on a gang m
|
||||
permeability_coefficient = 0.01
|
||||
clothing_flags = NOSLIP
|
||||
|
||||
datum/gang_item/equipment/shield
|
||||
/datum/gang_item/equipment/shield
|
||||
name = "Riot Shield"
|
||||
id = "riot_shield"
|
||||
cost = 25
|
||||
item_path = /obj/item/shield/riot
|
||||
|
||||
datum/gang_item/equipment/gangsheild
|
||||
/datum/gang_item/equipment/gangsheild
|
||||
name = "Tower Shield"
|
||||
id = "metal"
|
||||
cost = 45 //High block of melee and even higher for bullets
|
||||
|
||||
@@ -455,7 +455,7 @@ If not set, defaults to check_completion instead. Set it. It's used by cryo.
|
||||
var/target_real_name // Has to be stored because the target's real_name can change over the course of the round
|
||||
var/target_missing_id
|
||||
|
||||
/datum/objective/escape/escape_with_identity/find_target()
|
||||
/datum/objective/escape/escape_with_identity/find_target(dupe_search_range, blacklist)
|
||||
target = ..()
|
||||
update_explanation_text()
|
||||
|
||||
@@ -553,7 +553,7 @@ GLOBAL_LIST_EMPTY(possible_items)
|
||||
for(var/I in subtypesof(/datum/objective_item/steal))
|
||||
new I
|
||||
|
||||
/datum/objective/steal/find_target()
|
||||
/datum/objective/steal/find_target(dupe_search_range, blacklist)
|
||||
var/list/datum/mind/owners = get_owners()
|
||||
var/approved_targets = list()
|
||||
check_items:
|
||||
@@ -631,7 +631,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
||||
for(var/I in subtypesof(/datum/objective_item/special) + subtypesof(/datum/objective_item/stack))
|
||||
new I
|
||||
|
||||
/datum/objective/steal/special/find_target()
|
||||
/datum/objective/steal/special/find_target(dupe_search_range, blacklist)
|
||||
return set_target(pick(GLOB.possible_items_special))
|
||||
|
||||
/datum/objective/steal/exchange
|
||||
@@ -844,7 +844,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
||||
name = "destroy AI"
|
||||
martyr_compatible = 1
|
||||
|
||||
/datum/objective/destroy/find_target()
|
||||
/datum/objective/destroy/find_target(dupe_search_range, blacklist)
|
||||
var/list/possible_targets = active_ais(1)
|
||||
var/mob/living/silicon/ai/target_ai = pick(possible_targets)
|
||||
target = target_ai.mind
|
||||
@@ -1124,7 +1124,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
||||
/datum/objective/hoard/heirloom
|
||||
name = "steal heirloom"
|
||||
|
||||
/datum/objective/hoard/heirloom/find_target()
|
||||
/datum/objective/hoard/heirloom/find_target(dupe_search_range, blacklist)
|
||||
set_target(pick(GLOB.family_heirlooms))
|
||||
|
||||
GLOBAL_LIST_EMPTY(traitor_contraband)
|
||||
@@ -1141,7 +1141,7 @@ GLOBAL_LIST_EMPTY(cult_contraband)
|
||||
if(!GLOB.cult_contraband.len)
|
||||
GLOB.cult_contraband = list(/obj/item/clockwork/slab,/obj/item/clockwork/component/belligerent_eye,/obj/item/clockwork/component/belligerent_eye/lens_gem,/obj/item/shuttle_curse,/obj/item/cult_shift)
|
||||
|
||||
/datum/objective/hoard/collector/find_target()
|
||||
/datum/objective/hoard/collector/find_target(dupe_search_range, blacklist)
|
||||
var/obj/item/I
|
||||
var/I_type
|
||||
if(prob(50))
|
||||
@@ -1172,7 +1172,7 @@ GLOBAL_LIST_EMPTY(possible_sabotages)
|
||||
for(var/I in subtypesof(/datum/sabotage_objective))
|
||||
new I
|
||||
|
||||
/datum/objective/sabotage/find_target()
|
||||
/datum/objective/sabotage/find_target(dupe_search_range, blacklist)
|
||||
var/list/datum/mind/owners = get_owners()
|
||||
var/approved_targets = list()
|
||||
check_sabotages:
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
/datum/sabotage_objective/processing/check_conditions()
|
||||
return won
|
||||
|
||||
/*
|
||||
/datum/sabotage_objective/processing/power_sink
|
||||
name = "Drain at least 100 megajoules of power using a power sink."
|
||||
sabotage_type = "powersink"
|
||||
@@ -44,6 +45,7 @@
|
||||
for(var/s in GLOB.power_sinks)
|
||||
var/obj/item/powersink/sink = s
|
||||
won = max(won,sink.power_drained/1e8)
|
||||
*/
|
||||
|
||||
/obj/item/paper/guides/antag/supermatter_sabotage
|
||||
info = "Ways to sabotage a supermatter:<br>\
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
circuit = /obj/item/circuitboard/machine/cell_charger
|
||||
pass_flags = PASSTABLE
|
||||
var/obj/item/stock_parts/cell/charging = null
|
||||
var/charge_rate = 500
|
||||
var/recharge_coeff = 1
|
||||
|
||||
/obj/machinery/cell_charger/update_overlays()
|
||||
. += ..()
|
||||
@@ -28,9 +28,10 @@
|
||||
. = ..()
|
||||
. += "There's [charging ? "a" : "no"] cell in the charger."
|
||||
if(charging)
|
||||
. += "Current charge: [round(charging.percent(), 1)]%."
|
||||
var/obj/item/stock_parts/cell/C = charging.get_cell()
|
||||
. += "Current charge: [C.percent()]%."
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
. += "<span class='notice'>The status display reads: Charge rate at <b>[charge_rate]J</b> per cycle.</span>"
|
||||
. += "<span class='notice'>The status display reads: Charge rate at <b>[recharge_coeff*10]J</b> per cycle.</span>"
|
||||
|
||||
/obj/machinery/cell_charger/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/stock_parts/cell) && !panel_open)
|
||||
@@ -122,17 +123,18 @@
|
||||
charging.emp_act(severity)
|
||||
|
||||
/obj/machinery/cell_charger/RefreshParts()
|
||||
charge_rate = 500
|
||||
for(var/obj/item/stock_parts/capacitor/C in component_parts)
|
||||
charge_rate *= C.rating
|
||||
recharge_coeff = C.rating
|
||||
|
||||
/obj/machinery/cell_charger/process()
|
||||
if(!charging || !anchored || (stat & (BROKEN|NOPOWER)))
|
||||
return
|
||||
|
||||
if(charging.percent() >= 100)
|
||||
return
|
||||
use_power(charge_rate)
|
||||
charging.give(charge_rate) //this is 2558, efficient batteries exist
|
||||
if(charging)
|
||||
var/obj/item/stock_parts/cell/C = charging.get_cell()
|
||||
if(C)
|
||||
if(C.charge < C.maxcharge)
|
||||
C.give(C.chargerate * recharge_coeff)
|
||||
use_power(250 * recharge_coeff)
|
||||
|
||||
update_icon()
|
||||
|
||||
@@ -6,10 +6,12 @@
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
circuit = /obj/item/circuitboard/machine/colormate
|
||||
var/obj/item/inserted
|
||||
var/atom/movable/inserted
|
||||
var/activecolor = "#FFFFFF"
|
||||
var/list/color_matrix_last
|
||||
var/matrix_mode = FALSE
|
||||
/// Allow holder'd mobs
|
||||
var/allow_mobs = TRUE
|
||||
/// Minimum lightness for normal mode
|
||||
var/minimum_normal_lightness = 50
|
||||
/// Minimum lightness for matrix mode, tested using 4 test colors of full red, green, blue, white.
|
||||
@@ -57,11 +59,22 @@
|
||||
return
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
if(allow_mobs && istype(I, /obj/item/clothing/head/mob_holder))
|
||||
var/obj/item/clothing/head/mob_holder/H = I
|
||||
var/mob/victim = H.held_mob
|
||||
if(!user.transferItemToLoc(I, src))
|
||||
to_chat(user, "<span class='warning'>[I] is stuck to your hand!</span>")
|
||||
return
|
||||
if(!QDELETED(H))
|
||||
H.release()
|
||||
insert_mob(victim, user)
|
||||
|
||||
if(is_type_in_list(I, allowed_types) && is_operational())
|
||||
if(!user.transferItemToLoc(I, src))
|
||||
to_chat(user, "<span class='warning'>[I] is stuck to your hand!</span>")
|
||||
return
|
||||
if(QDELETED(I))
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] inserts [I] into [src]'s receptable.</span>")
|
||||
|
||||
inserted = I
|
||||
@@ -69,9 +82,22 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/gear_painter/proc/insert_mob(mob/victim, mob/user)
|
||||
if(inserted)
|
||||
return
|
||||
if(user)
|
||||
visible_message("<span class='warning'>[user] stuffs [victim] into [src]!</span>")
|
||||
inserted = victim
|
||||
inserted.forceMove(src)
|
||||
|
||||
/obj/machinery/gear_painter/AllowDrop()
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/gear_painter/handle_atom_del(atom/movable/AM)
|
||||
if(AM == inserted)
|
||||
inserted = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/gear_painter/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!user.CanReach(src))
|
||||
|
||||
@@ -151,7 +151,14 @@
|
||||
var/obj/machinery/power/apc/target = locate(ref) in GLOB.apcs_list
|
||||
if(!target)
|
||||
return
|
||||
target.vars[type] = target.setsubsystem(text2num(value))
|
||||
value = target.setsubsystem(text2num(value))
|
||||
switch(type) // Sanity check
|
||||
if("equipment", "lighting", "environ")
|
||||
target.vars[type] = value
|
||||
else
|
||||
message_admins("Warning: possible href exploit by [key_name(usr)] - attempted to set [type] on [target] to [value]")
|
||||
log_game("Warning: possible href exploit by [key_name(usr)] - attempted to set [type] on [target] to [value]")
|
||||
return
|
||||
target.update_icon()
|
||||
target.update()
|
||||
var/setTo = ""
|
||||
|
||||
@@ -264,6 +264,8 @@ What a mess.*/
|
||||
active1 = null
|
||||
if(!( GLOB.data_core.security.Find(active2) ))
|
||||
active2 = null
|
||||
if(!authenticated && href_list["choice"] != "Log In") // logging in is the only action you can do if not logged in
|
||||
return
|
||||
if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || hasSiliconAccessInArea(usr) || IsAdminGhost(usr))
|
||||
usr.set_machine(src)
|
||||
switch(href_list["choice"])
|
||||
|
||||
@@ -393,6 +393,27 @@
|
||||
spark_system.start() //creates some sparks because they look cool
|
||||
qdel(cover) //deletes the cover - no need on keeping it there!
|
||||
|
||||
//turret healing
|
||||
/obj/machinery/porta_turret/examine(mob/user)
|
||||
. = ..()
|
||||
if(obj_integrity < max_integrity)
|
||||
. += "<span class='notice'>[src] is damaged, use a lit welder to fix it.</span>"
|
||||
|
||||
/obj/machinery/porta_turret/welder_act(mob/living/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(cover && obj_integrity < max_integrity)
|
||||
if(!I.tool_start_check(user, amount=0))
|
||||
return
|
||||
user.visible_message("[user] is welding the turret.", \
|
||||
"<span class='notice'>You begin repairing the turret...</span>", \
|
||||
"<span class='italics'>You hear welding.</span>")
|
||||
if(I.use_tool(src, user, 40, volume=50))
|
||||
obj_integrity = max_integrity
|
||||
user.visible_message("[user.name] has repaired [src].", \
|
||||
"<span class='notice'>You finish repairing the turret.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The turret doesn't need repairing.</span>")
|
||||
|
||||
/obj/machinery/porta_turret/process()
|
||||
//the main machinery process
|
||||
if(cover == null && anchored) //if it has no cover and is anchored
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
icon_state = "mecha_ion"
|
||||
energy_drain = 120
|
||||
projectile = /obj/item/projectile/ion
|
||||
fire_sound = 'sound/weapons/laser.ogg'
|
||||
fire_sound = 'sound/weapons/IonRifle.ogg'
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/tesla
|
||||
equip_cooldown = 35
|
||||
@@ -195,7 +195,7 @@
|
||||
//Base ballistic weapon type
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic
|
||||
name = "general ballistic weapon"
|
||||
fire_sound = 'sound/weapons/gunshot.ogg'
|
||||
fire_sound = 'sound/weapons/lmgshot.ogg'
|
||||
var/projectiles
|
||||
var/projectiles_cache //ammo to be loaded in, if possible.
|
||||
var/projectiles_cache_max
|
||||
@@ -285,6 +285,7 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot
|
||||
name = "\improper LBX AC 10 \"Scattershot\""
|
||||
desc = "A weapon for combat exosuits. Shoots a spread of pellets."
|
||||
fire_sound = 'sound/weapons/gunshotshotgunshot.ogg'
|
||||
icon_state = "mecha_scatter"
|
||||
equip_cooldown = 20
|
||||
projectile = /obj/item/projectile/bullet/scattershot
|
||||
@@ -299,6 +300,7 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/seedscatter
|
||||
name = "\improper Melon Seed \"Scattershot\""
|
||||
desc = "A weapon for combat exosuits. Shoots a spread of pellets, shaped as seed."
|
||||
fire_sound = 'sound/weapons/gunshotshotgunshot.ogg'
|
||||
icon_state = "mecha_scatter"
|
||||
equip_cooldown = 20
|
||||
projectile = /obj/item/projectile/bullet/seed
|
||||
@@ -331,7 +333,7 @@
|
||||
desc = "A weapon for combat exosuits. Launches light explosive missiles."
|
||||
icon_state = "mecha_missilerack"
|
||||
projectile = /obj/item/projectile/bullet/a84mm_he
|
||||
fire_sound = 'sound/weapons/grenadelaunch.ogg'
|
||||
fire_sound = 'sound/weapons/rocketlaunch.ogg'
|
||||
projectiles = 8
|
||||
projectiles_cache = 0
|
||||
projectiles_cache_max = 0
|
||||
@@ -345,7 +347,7 @@
|
||||
desc = "A weapon for combat exosuits. Launches low-explosive breaching missiles designed to explode only when striking a sturdy target."
|
||||
icon_state = "mecha_missilerack_six"
|
||||
projectile = /obj/item/projectile/bullet/a84mm_br
|
||||
fire_sound = 'sound/weapons/grenadelaunch.ogg'
|
||||
fire_sound = 'sound/weapons/rocketlaunch.ogg'
|
||||
projectiles = 6
|
||||
projectiles_cache = 0
|
||||
projectiles_cache_max = 0
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
|
||||
/obj/effect/decal/cleanable/trail_holder //not a child of blood on purpose
|
||||
name = "blood"
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "ltrails_1"
|
||||
desc = "Your instincts say you shouldn't be following these."
|
||||
random_icon_states = null
|
||||
|
||||
@@ -49,6 +49,42 @@
|
||||
/obj/effect/overlay/vis
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
anchored = TRUE
|
||||
vis_flags = NONE
|
||||
var/unused = 0 //When detected to be unused it gets set to world.time, after a while it gets removed
|
||||
var/cache_expiration = 2 MINUTES // overlays which go unused for 2 minutes get cleaned up
|
||||
vis_flags = VIS_INHERIT_DIR
|
||||
///When detected to be unused it gets set to world.time, after a while it gets removed
|
||||
var/unused = 0
|
||||
///overlays which go unused for this amount of time get cleaned up
|
||||
var/cache_expiration = 2 MINUTES
|
||||
|
||||
// /obj/effect/overlay/atmos_excited
|
||||
// name = "excited group"
|
||||
// icon = null
|
||||
// icon_state = null
|
||||
// anchored = TRUE // should only appear in vis_contents, but to be safe
|
||||
// appearance_flags = RESET_TRANSFORM | TILE_BOUND
|
||||
// invisibility = INVISIBILITY_ABSTRACT
|
||||
// mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
// layer = ATMOS_GROUP_LAYER
|
||||
// plane = ATMOS_GROUP_PLANE
|
||||
|
||||
// /obj/effect/overlay/light_visible
|
||||
// name = ""
|
||||
// icon = 'icons/effects/light_overlays/light_32.dmi'
|
||||
// icon_state = "light"
|
||||
// layer = O_LIGHTING_VISUAL_LAYER
|
||||
// plane = O_LIGHTING_VISUAL_PLANE
|
||||
// appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
|
||||
// mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
// alpha = 0
|
||||
// vis_flags = NONE
|
||||
|
||||
// /obj/effect/overlay/light_cone
|
||||
// name = ""
|
||||
// icon = 'icons/effects/light_overlays/light_cone.dmi'
|
||||
// icon_state = "light"
|
||||
// layer = O_LIGHTING_VISUAL_LAYER
|
||||
// plane = O_LIGHTING_VISUAL_PLANE
|
||||
// appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
|
||||
// mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
// vis_flags = NONE
|
||||
// alpha = 110
|
||||
|
||||
@@ -468,6 +468,10 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
|
||||
melee_attack_chain(usr, over)
|
||||
usr.FlushCurrentAction()
|
||||
return TRUE //returning TRUE as a "is this overridden?" flag
|
||||
if(isrevenant(usr))
|
||||
if(RevenantThrow(over, usr, src))
|
||||
return
|
||||
|
||||
if(!Adjacent(usr) || !over.Adjacent(usr))
|
||||
return // should stop you from dragging through windows
|
||||
|
||||
@@ -939,6 +943,10 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
|
||||
/obj/item/proc/get_part_rating()
|
||||
return 0
|
||||
|
||||
//Can this item be given to people?
|
||||
/obj/item/proc/can_give()
|
||||
return TRUE
|
||||
|
||||
/obj/item/doMove(atom/destination)
|
||||
if (ismob(loc))
|
||||
var/mob/M = loc
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
last = C
|
||||
break
|
||||
|
||||
obj/item/rcl/proc/getMobhook(mob/to_hook)
|
||||
/obj/item/rcl/proc/getMobhook(mob/to_hook)
|
||||
if(listeningTo == to_hook)
|
||||
return
|
||||
if(listeningTo)
|
||||
|
||||
@@ -10,35 +10,41 @@
|
||||
/obj/item/armorkit/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
// yeah have fun making subtypes and modifying the afterattack if you want to make variants
|
||||
// idiot
|
||||
// - hatter
|
||||
var/used = FALSE
|
||||
|
||||
if(isobj(target) && istype(target, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/C = target
|
||||
if(C.armor.melee < 10)
|
||||
C.armor.melee = 10
|
||||
if(C.damaged_clothes)
|
||||
to_chat(user,"<span class='warning'>You should repair the damage done to [C] first.</span>")
|
||||
return
|
||||
if(C.attached_accessory)
|
||||
to_chat(user,"<span class='warning'>Kind of hard to sew around [C.attached_accessory].</span>")
|
||||
return
|
||||
if(C.armor.getRating("melee") < 10)
|
||||
C.armor = C.armor.setRating("melee" = 10)
|
||||
used = TRUE
|
||||
if(C.armor.laser < 10)
|
||||
C.armor.laser = 10
|
||||
if(C.armor.getRating("laser") < 10)
|
||||
C.armor = C.armor.setRating("laser" = 10)
|
||||
used = TRUE
|
||||
if(C.armor.fire < 40)
|
||||
C.armor.fire = 40
|
||||
if(C.armor.getRating("fire") < 40)
|
||||
C.armor = C.armor.setRating("fire" = 40)
|
||||
used = TRUE
|
||||
if(C.armor.acid < 10)
|
||||
C.armor.acid = 10
|
||||
if(C.armor.getRating("acid") < 10)
|
||||
C.armor = C.armor.setRating("acid" = 10)
|
||||
used = TRUE
|
||||
if(C.armor.bomb < 5)
|
||||
C.armor.bomb = 5
|
||||
if(C.armor.getRating("bomb") < 5)
|
||||
C.armor = C.armor.setRating("bomb" = 5)
|
||||
used = TRUE
|
||||
|
||||
if(used)
|
||||
user.visible_message("<span class = 'notice'>[user] uses [src] on [C], reinforcing it and tossing the empty case away afterwards.</span>", \
|
||||
"<span class = 'notice'>You reinforce [C] with [src], making it a little more protective! You toss the empty casing away afterwards.</span>")
|
||||
C.name = "durathread [C.name]" // this disappears if it gets repaired, which is annoying
|
||||
user.visible_message("<span class = 'notice'>[user] reinforces [C] with [src].</span>", \
|
||||
"<span class = 'notice'>You reinforce [C] with [src], making it as protective as a durathread jumpsuit.</span>")
|
||||
C.name = "durathread [C.name]"
|
||||
C.upgrade_prefix = "durathread" // god i hope this works
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class = 'notice'>You stare at [src] and [C], coming to the conclusion that you probably don't need to reinforce it any further.")
|
||||
to_chat(user, "<span class = 'notice'>You don't need to reinforce [C] any further.")
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
@@ -82,4 +82,8 @@
|
||||
/obj/item/candle/infinite/hugbox
|
||||
heats_space = FALSE
|
||||
|
||||
/obj/item/candle/DoRevenantThrowEffects(atom/target)
|
||||
if(!infinite)
|
||||
put_out_candle()
|
||||
|
||||
#undef CANDLE_LUMINOSITY
|
||||
|
||||
@@ -779,16 +779,40 @@
|
||||
/obj/item/card/id/departmental_budget/update_label()
|
||||
return
|
||||
|
||||
/obj/item/card/id/departmental_budget/civ
|
||||
department_ID = ACCOUNT_CIV
|
||||
department_name = ACCOUNT_CIV_NAME
|
||||
|
||||
/obj/item/card/id/departmental_budget/eng
|
||||
department_ID = ACCOUNT_ENG
|
||||
department_name = ACCOUNT_ENG_NAME
|
||||
|
||||
/obj/item/card/id/departmental_budget/sci
|
||||
department_ID = ACCOUNT_SCI
|
||||
department_name = ACCOUNT_SCI_NAME
|
||||
|
||||
/obj/item/card/id/departmental_budget/med
|
||||
department_ID = ACCOUNT_MED
|
||||
department_name = ACCOUNT_MED_NAME
|
||||
|
||||
/obj/item/card/id/departmental_budget/srv
|
||||
department_ID = ACCOUNT_SRV
|
||||
department_name = ACCOUNT_SRV_NAME
|
||||
|
||||
/obj/item/card/id/departmental_budget/car
|
||||
department_ID = ACCOUNT_CAR
|
||||
department_name = ACCOUNT_CAR_NAME
|
||||
|
||||
/obj/item/card/id/departmental_budget/sec
|
||||
department_ID = ACCOUNT_SEC
|
||||
department_name = ACCOUNT_SEC_NAME
|
||||
|
||||
//Polychromatic Knight Badge
|
||||
|
||||
/obj/item/card/id/knight
|
||||
name = "knight badge"
|
||||
icon_state = "knight"
|
||||
desc = "A badge denoting the owner as a knight! It has a strip for swiping like an ID"
|
||||
desc = "A badge denoting the owner as a knight! It has a strip for swiping like an ID."
|
||||
var/id_color = "#00FF00" //defaults to green
|
||||
var/mutable_appearance/id_overlay
|
||||
|
||||
|
||||
@@ -136,6 +136,12 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/clothing/mask/cigarette/DoRevenantThrowEffects(atom/target)
|
||||
if(lit)
|
||||
attackby()
|
||||
else
|
||||
light()
|
||||
|
||||
/obj/item/clothing/mask/cigarette/attackby(obj/item/W, mob/user, params)
|
||||
if(!lit && smoketime > 0)
|
||||
var/lighting_text = W.ignition_effect(src, user)
|
||||
@@ -517,6 +523,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
overlay_state = pick(overlay_list)
|
||||
update_icon()
|
||||
|
||||
/obj/item/lighter/DoRevenantThrowEffects(atom/target)
|
||||
set_lit()
|
||||
|
||||
/obj/item/lighter/suicide_act(mob/living/carbon/user)
|
||||
if (lit)
|
||||
user.visible_message("<span class='suicide'>[user] begins holding \the [src]'s flame up to [user.p_their()] face! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
|
||||
@@ -37,11 +37,14 @@
|
||||
/obj/item/flashlight/attack_self(mob/user)
|
||||
on = !on
|
||||
update_brightness(user)
|
||||
playsound(user, on ? 'sound/weapons/magin.ogg' : 'sound/weapons/magout.ogg', 40, 1)
|
||||
playsound(src, on ? 'sound/weapons/magin.ogg' : 'sound/weapons/magout.ogg', 40, TRUE)
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/item/flashlight/DoRevenantThrowEffects(atom/target)
|
||||
attack_self()
|
||||
|
||||
/obj/item/flashlight/suicide_act(mob/living/carbon/human/user)
|
||||
if (user.eye_blind)
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
obj_flags = UNIQUE_RENAME
|
||||
var/gpstag = "COM0"
|
||||
var/emp_proof = FALSE
|
||||
var/starton = TRUE
|
||||
|
||||
/obj/item/gps/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/gps/item, gpstag)
|
||||
AddComponent(/datum/component/gps/item, gpstag, emp_proof, starton)
|
||||
|
||||
/obj/item/gps/science
|
||||
icon_state = "gps-s"
|
||||
@@ -26,6 +28,9 @@
|
||||
gpstag = "MINE0"
|
||||
desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life."
|
||||
|
||||
/obj/item/gps/mining/off
|
||||
starton = FALSE
|
||||
|
||||
/obj/item/gps/cyborg
|
||||
icon_state = "gps-b"
|
||||
gpstag = "BORG0"
|
||||
|
||||
@@ -69,7 +69,8 @@ GLOBAL_LIST_INIT(channel_tokens, list(
|
||||
/obj/item/radio/headset/talk_into(mob/living/M, message, channel, list/spans,datum/language/language)
|
||||
if (!listening)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
return ..()
|
||||
if (language != /datum/language/signlanguage)
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/headset/can_receive(freq, level, AIuser)
|
||||
if(ishuman(src.loc))
|
||||
@@ -283,14 +284,12 @@ GLOBAL_LIST_INIT(channel_tokens, list(
|
||||
SSradio.remove_object(src, GLOB.radiochannels[ch_name])
|
||||
secure_radio_connections[ch_name] = null
|
||||
|
||||
var/turf/T = user.drop_location()
|
||||
if(T)
|
||||
if(keyslot)
|
||||
keyslot.forceMove(T)
|
||||
keyslot = null
|
||||
if(keyslot2)
|
||||
keyslot2.forceMove(T)
|
||||
keyslot2 = null
|
||||
if(keyslot)
|
||||
user.put_in_hands(keyslot)
|
||||
keyslot = null
|
||||
if(keyslot2)
|
||||
user.put_in_hands(keyslot2)
|
||||
keyslot2 = null
|
||||
|
||||
recalculateChannels()
|
||||
to_chat(user, "<span class='notice'>You pop out the encryption keys in the headset.</span>")
|
||||
|
||||
@@ -208,6 +208,8 @@
|
||||
return
|
||||
if(!M.IsVocal())
|
||||
return
|
||||
if(language == /datum/language/signlanguage)
|
||||
return
|
||||
|
||||
if(use_command)
|
||||
spans |= commandspan
|
||||
|
||||
@@ -306,18 +306,6 @@ GENETICS SCANNER
|
||||
if(T.name == "fluffy tongue")
|
||||
temp_message += " <span class='danger'>Subject is suffering from a fluffified tongue. Suggested cure: Yamerol or a tongue transplant.</span>"
|
||||
|
||||
//HECK
|
||||
else if(istype(O, /obj/item/organ/genital/penis))
|
||||
var/obj/item/organ/genital/penis/P = O
|
||||
if(P.length>20)
|
||||
temp_message += " <span class='info'>Subject has a sizeable gentleman's organ at [P.length] inches.</span>"
|
||||
|
||||
else if(istype(O, /obj/item/organ/genital/breasts))
|
||||
var/obj/item/organ/genital/breasts/Br = O
|
||||
if(Br.cached_size>5)
|
||||
temp_message += " <span class='info'>Subject has a sizeable bosom with a [Br.size] cup.</span>"
|
||||
|
||||
|
||||
|
||||
//GENERAL HANDLER
|
||||
if(!damage_message)
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
if(.)
|
||||
new /obj/item/toy/eightball/haunted(loc)
|
||||
|
||||
/obj/item/toy/eightball/DoRevenantThrowEffects(atom/target)
|
||||
MakeHaunted()
|
||||
|
||||
/obj/item/toy/eightball/attack_self(mob/user)
|
||||
if(shaking)
|
||||
return
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
name = "advanced fire extinguisher"
|
||||
desc = "Used to stop thermonuclear fires from spreading inside your engine."
|
||||
icon_state = "foam_extinguisher0"
|
||||
//item_state = "foam_extinguisher" needs sprite
|
||||
item_state = "foam_extinguisher"
|
||||
dog_fashion = null
|
||||
chem = /datum/reagent/firefighting_foam
|
||||
tanktype = /obj/structure/reagent_dispensers/foamtank
|
||||
@@ -235,16 +235,23 @@
|
||||
return
|
||||
EmptyExtinguisher(user)
|
||||
|
||||
/obj/item/extinguisher/proc/EmptyExtinguisher(var/mob/user)
|
||||
if(loc == user && reagents.total_volume)
|
||||
/obj/item/extinguisher/DoRevenantThrowEffects(atom/target)
|
||||
EmptyExtinguisher()
|
||||
|
||||
/obj/item/extinguisher/proc/EmptyExtinguisher(mob/user)
|
||||
if(!reagents.total_volume)
|
||||
return
|
||||
if(loc == user || !user)
|
||||
reagents.clear_reagents()
|
||||
|
||||
var/turf/T = get_turf(loc)
|
||||
if(isopenturf(T))
|
||||
var/turf/open/theturf = T
|
||||
theturf.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
|
||||
|
||||
user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "<span class='info'>You quietly empty out \the [src] by using its release valve.</span>")
|
||||
if(user)
|
||||
user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "<span class='info'>You quietly empty out \the [src] by using its release valve.</span>")
|
||||
else
|
||||
user.visible_message("The release valve of \the [src] suddenly opens and sprays it's contents on the floor!")
|
||||
|
||||
//firebot assembly
|
||||
/obj/item/extinguisher/attackby(obj/O, mob/user, params)
|
||||
|
||||
@@ -245,6 +245,9 @@
|
||||
slowdown = 7
|
||||
breakouttime = 300 //Deciseconds = 30s = 0.5 minute
|
||||
|
||||
/obj/item/restraints/legcuffs/proc/on_removed()
|
||||
return
|
||||
|
||||
/obj/item/restraints/legcuffs/beartrap
|
||||
name = "bear trap"
|
||||
throw_speed = 1
|
||||
@@ -376,4 +379,8 @@
|
||||
icon_state = "ebola"
|
||||
hitsound = 'sound/weapons/taserhit.ogg'
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
breakouttime = 60
|
||||
breakouttime = 25
|
||||
|
||||
/obj/item/restraints/legcuffs/bola/energy/on_removed()
|
||||
do_sparks(1, TRUE, src)
|
||||
qdel(src)
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
icon_state = "warp"
|
||||
uses = -1
|
||||
var/total_delay = 10 SECONDS
|
||||
var/cooldown = 10 SECONDS
|
||||
var/cooldown = 30 SECONDS
|
||||
var/last_use = 0
|
||||
var/list/positions = list()
|
||||
var/next_prune = 0
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
|
||||
var/ignore_suit_sensor_level = FALSE // Do we find people even if their suit sensors are turned off
|
||||
var/alert = FALSE // TRUE to display things more seriously
|
||||
/// resets target on toggle
|
||||
var/resets_target = TRUE
|
||||
|
||||
/obj/item/pinpointer/Initialize()
|
||||
. = ..()
|
||||
@@ -27,17 +29,22 @@
|
||||
/obj/item/pinpointer/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
GLOB.pinpointer_list -= src
|
||||
target = null
|
||||
unset_target()
|
||||
return ..()
|
||||
|
||||
/obj/item/pinpointer/DoRevenantThrowEffects(atom/target)
|
||||
attack_self()
|
||||
|
||||
/obj/item/pinpointer/attack_self(mob/living/user)
|
||||
active = !active
|
||||
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates [user.p_their()] pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
|
||||
if(user)
|
||||
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates [user.p_their()] pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
if(active)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
target = null
|
||||
if(resets_target)
|
||||
unset_target()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
update_icon()
|
||||
|
||||
@@ -50,6 +57,18 @@
|
||||
/obj/item/pinpointer/proc/scan_for_target()
|
||||
return
|
||||
|
||||
/obj/item/pinpointer/proc/set_target(atom/movable/newtarget)
|
||||
if(target)
|
||||
unset_target()
|
||||
target = newtarget
|
||||
RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/unset_target)
|
||||
|
||||
/obj/item/pinpointer/proc/unset_target()
|
||||
if(!target)
|
||||
return
|
||||
UnregisterSignal(target, COMSIG_PARENT_QDELETING)
|
||||
target = null
|
||||
|
||||
/obj/item/pinpointer/update_overlays()
|
||||
. = ..()
|
||||
if(!active)
|
||||
@@ -101,7 +120,8 @@
|
||||
active = FALSE
|
||||
user.visible_message("<span class='notice'>[user] deactivates [user.p_their()] pinpointer.</span>", "<span class='notice'>You deactivate your pinpointer.</span>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
target = null //Restarting the pinpointer forces a target reset
|
||||
if(resets_target)
|
||||
unset_target() //Restarting the pinpointer forces a target reset
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
update_icon()
|
||||
return
|
||||
@@ -137,7 +157,7 @@
|
||||
if(!A || QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated())
|
||||
return
|
||||
|
||||
target = names[A]
|
||||
set_target(names[A])
|
||||
active = TRUE
|
||||
user.visible_message("<span class='notice'>[user] activates [user.p_their()] pinpointer.</span>", "<span class='notice'>You activate your pinpointer.</span>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
@@ -149,7 +169,7 @@
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(!trackable(H))
|
||||
target = null
|
||||
unset_target()
|
||||
if(!target) //target can be set to null from above code, or elsewhere
|
||||
active = FALSE
|
||||
|
||||
@@ -163,7 +183,7 @@
|
||||
. = ..()
|
||||
|
||||
/obj/item/pinpointer/pair/scan_for_target()
|
||||
target = other_pair
|
||||
set_target(other_pair)
|
||||
|
||||
/obj/item/pinpointer/pair/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -195,7 +215,7 @@
|
||||
shuttleport = SSshuttle.getShuttle("huntership")
|
||||
|
||||
/obj/item/pinpointer/shuttle/scan_for_target()
|
||||
target = shuttleport
|
||||
set_target(shuttleport)
|
||||
|
||||
/obj/item/pinpointer/shuttle/Destroy()
|
||||
shuttleport = null
|
||||
@@ -207,4 +227,8 @@
|
||||
icon_state = "pinpointer_ian"
|
||||
|
||||
/obj/item/pinpointer/ian/scan_for_target()
|
||||
target = locate(/mob/living/simple_animal/pet/dog/corgi/Ian) in GLOB.mob_living_list
|
||||
set_target(locate(/mob/living/simple_animal/pet/dog/corgi/Ian) in GLOB.mob_living_list)
|
||||
|
||||
/obj/item/pinpointer/custom
|
||||
resets_target = FALSE
|
||||
|
||||
|
||||
@@ -45,6 +45,10 @@
|
||||
return
|
||||
set_snowflake_from_config(id)
|
||||
|
||||
/obj/item/toy/plush/DoRevenantThrowEffects(atom/target)
|
||||
var/datum/component/squeak/squeaker = GetComponent(/datum/component/squeak)
|
||||
squeaker.do_play_squeak(TRUE)
|
||||
|
||||
/obj/item/toy/plush/Initialize(mapload, set_snowflake_id)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/squeak, squeak_override)
|
||||
|
||||
@@ -43,6 +43,13 @@
|
||||
/obj/item/pneumatic_cannon/proc/init_charge() //wrapper so it can be vv'd easier
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/pneumatic_cannon/DoRevenantThrowEffects(atom/target)
|
||||
var/picked_target
|
||||
var/list/possible_targets = range(3,src)
|
||||
picked_target = pick(possible_targets)
|
||||
if(target)
|
||||
Fire(null, picked_target)
|
||||
|
||||
/obj/item/pneumatic_cannon/process()
|
||||
if(++charge_tick >= charge_ticks && charge_type)
|
||||
fill_with_type(charge_type, charge_amount)
|
||||
@@ -134,21 +141,29 @@
|
||||
Fire(user, target)
|
||||
|
||||
/obj/item/pneumatic_cannon/proc/Fire(mob/living/user, var/atom/target)
|
||||
if(!istype(user) && !target)
|
||||
if(!target)
|
||||
return
|
||||
if(user)
|
||||
if(!isliving(user))
|
||||
return
|
||||
var/discharge = 0
|
||||
if(!can_trigger_gun(user))
|
||||
if(user && !can_trigger_gun(user))
|
||||
return
|
||||
if(!loadedItems || !loadedWeightClass)
|
||||
to_chat(user, "<span class='warning'>\The [src] has nothing loaded.</span>")
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>\The [src] has nothing loaded.</span>")
|
||||
return
|
||||
if(!tank && checktank)
|
||||
to_chat(user, "<span class='warning'>\The [src] can't fire without a source of gas.</span>")
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>\The [src] can't fire without a source of gas.</span>")
|
||||
return
|
||||
if(tank && !tank.air_contents.remove(gasPerThrow * pressureSetting))
|
||||
to_chat(user, "<span class='warning'>\The [src] lets out a weak hiss and doesn't react!</span>")
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>\The [src] lets out a weak hiss and doesn't react!</span>")
|
||||
else
|
||||
visible_message(src, "<span class='warning'>\The [src] lets out a weak hiss and doesn't react!</span>")
|
||||
return
|
||||
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(75) && clumsyCheck && iscarbon(user))
|
||||
if(user && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(75) && clumsyCheck && iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.visible_message("<span class='warning'>[C] loses [C.p_their()] grip on [src], causing it to go off!</span>", "<span class='userdanger'>[src] slips out of your hands and goes off!</span>")
|
||||
C.dropItemToGround(src, TRUE)
|
||||
@@ -157,15 +172,18 @@
|
||||
else
|
||||
var/list/possible_targets = range(3,src)
|
||||
target = pick(possible_targets)
|
||||
discharge = 1
|
||||
if(!discharge)
|
||||
discharge = TRUE
|
||||
if(!discharge && user)
|
||||
user.visible_message("<span class='danger'>[user] fires \the [src]!</span>", \
|
||||
"<span class='danger'>You fire \the [src]!</span>")
|
||||
log_combat(user, target, "fired at", src)
|
||||
var/turf/T = get_target(target, get_turf(src))
|
||||
playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 50, 1)
|
||||
fire_items(T, user)
|
||||
if(pressureSetting >= 3 && iscarbon(user))
|
||||
playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 50, TRUE)
|
||||
if(user)
|
||||
log_combat(user, target, "fired at", src)
|
||||
fire_items(T, user)
|
||||
else
|
||||
fire_items(T)
|
||||
if(user && pressureSetting >= 3 && iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.visible_message("<span class='warning'>[C] is thrown down by the force of the cannon!</span>", "<span class='userdanger'>[src] slams into your shoulder, knocking you down!")
|
||||
C.DefaultCombatKnockdown(60)
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 300
|
||||
|
||||
obj/item/shield/riot/bullet_proof
|
||||
/obj/item/shield/riot/bullet_proof
|
||||
name = "bullet resistant shield"
|
||||
desc = "A far more frail shield made of resistant plastics and kevlar meant to block ballistics."
|
||||
armor = list("melee" = 30, "bullet" = 80, "laser" = 0, "energy" = 0, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
|
||||
|
||||
@@ -20,7 +20,7 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
|
||||
custom_materials = list(/datum/material/iron=1000)
|
||||
max_amount = 50
|
||||
attack_verb = list("hit", "bludgeoned", "whacked")
|
||||
hitsound = 'sound/weapons/grenadelaunch.ogg'
|
||||
hitsound = 'sound/items/trayhit1.ogg'
|
||||
embedding = list()
|
||||
novariants = TRUE
|
||||
|
||||
|
||||
@@ -466,6 +466,7 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \
|
||||
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), \
|
||||
new/datum/stack_recipe("cardboard card", /obj/item/cardboard_card, 1), \
|
||||
// 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), \
|
||||
|
||||
@@ -639,7 +639,7 @@
|
||||
new /obj/item/bikehorn(src)
|
||||
new /obj/item/implanter/sad_trombone(src)
|
||||
|
||||
obj/item/storage/backpack/duffelbag/syndie/shredderbundle
|
||||
/obj/item/storage/backpack/duffelbag/syndie/shredderbundle
|
||||
desc = "A large duffel bag containing two CX Shredders, some magazines, an elite hardsuit, and a chest rig."
|
||||
|
||||
/obj/item/storage/backpack/duffelbag/syndie/shredderbundle/PopulateContents()
|
||||
|
||||
@@ -857,7 +857,7 @@
|
||||
icon_state = "2sheath"
|
||||
item_state = "katana" //this'll do.
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
fitting_swords = list(/obj/item/melee/smith/wakizashi, /obj/item/melee/smith/twohand/katana, /obj/item/melee/bokken)
|
||||
fitting_swords = list(/obj/item/melee/smith/wakizashi, /obj/item/melee/smith/twohand/katana, /obj/item/melee/bokken, /obj/item/katana)
|
||||
starting_sword = null
|
||||
|
||||
/obj/item/storage/belt/sabre/twin/ComponentInitialize()
|
||||
|
||||
@@ -275,7 +275,7 @@
|
||||
for(var/i in 1 to 7)
|
||||
new /obj/item/grenade/flashbang(src)
|
||||
|
||||
obj/item/storage/box/stingbangs
|
||||
/obj/item/storage/box/stingbangs
|
||||
name = "box of stingbangs (WARNING)"
|
||||
desc = "<B>WARNING: These devices are extremely dangerous and can cause severe injuries or death in repeated use.</B>"
|
||||
icon_state = "secbox"
|
||||
|
||||
@@ -526,3 +526,8 @@
|
||||
new /obj/item/book/granter/martial/carp(src)
|
||||
new /obj/item/clothing/suit/hooded/carp_costume(src)
|
||||
new /obj/item/staff/bostaff(src)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/sleepytime/cardpack/PopulateContents()
|
||||
. = ..()
|
||||
new /obj/item/cardpack/syndicate(src)
|
||||
new /obj/item/cardpack/syndicate(src)
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
cell = new preload_cell_type(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/melee/baton/DoRevenantThrowEffects(atom/target)
|
||||
switch_status()
|
||||
|
||||
/obj/item/melee/baton/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
..()
|
||||
//Only mob/living types have stun handling
|
||||
@@ -236,6 +239,12 @@
|
||||
if(!iscyborg(loc))
|
||||
deductcharge(severity*10, TRUE, FALSE)
|
||||
|
||||
/obj/item/melee/baton/can_give()
|
||||
if(turned_on)
|
||||
return FALSE
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/melee/baton/stunsword
|
||||
name = "stunsword"
|
||||
desc = "Not actually sharp, this sword is functionally identical to its baton counterpart."
|
||||
@@ -269,21 +278,22 @@
|
||||
icon_state = "refill_donksoft"
|
||||
var/product = /obj/item/melee/baton/stunsword //what it makes
|
||||
var/list/fromitem = list(/obj/item/melee/baton, /obj/item/melee/baton/loaded) //what it needs
|
||||
afterattack(obj/O, mob/user as mob)
|
||||
if(istype(O, product))
|
||||
to_chat(user,"<span class='warning'>[O] is already modified!")
|
||||
else if(O.type in fromitem) //makes sure O is the right thing
|
||||
var/obj/item/melee/baton/B = O
|
||||
if(!B.cell) //checks for a powercell in the baton. If there isn't one, continue. If there is, warn the user to take it out
|
||||
new product(usr.loc) //spawns the product
|
||||
user.visible_message("<span class='warning'>[user] modifies [O]!","<span class='warning'>You modify the [O]!")
|
||||
qdel(O) //Gets rid of the baton
|
||||
qdel(src) //gets rid of the kit
|
||||
|
||||
else
|
||||
to_chat(user,"<span class='warning'>Remove the powercell first!</span>") //We make this check because the stunsword starts without a battery.
|
||||
/obj/item/ssword_kit/afterattack(obj/O, mob/user as mob)
|
||||
if(istype(O, product))
|
||||
to_chat(user,"<span class='warning'>[O] is already modified!")
|
||||
return
|
||||
if(O.type in fromitem) //makes sure O is the right thing
|
||||
var/obj/item/melee/baton/B = O
|
||||
if(!B.cell) //checks for a powercell in the baton. If there isn't one, continue. If there is, warn the user to take it out
|
||||
new product(usr.loc) //spawns the product
|
||||
user.visible_message("<span class='warning'>[user] modifies [O]!","<span class='warning'>You modify the [O]!")
|
||||
qdel(O) //Gets rid of the baton
|
||||
qdel(src) //gets rid of the kit
|
||||
else
|
||||
to_chat(user, "<span class='warning'> You can't modify [O] with this kit!</span>")
|
||||
to_chat(user,"<span class='warning'>Remove the powercell first!</span>") //We make this check because the stunsword starts without a battery.
|
||||
else
|
||||
to_chat(user, "<span class='warning'> You can't modify [O] with this kit!</span>")
|
||||
|
||||
//Makeshift stun baton. Replacement for stun gloves.
|
||||
/obj/item/melee/baton/cattleprod
|
||||
|
||||
@@ -73,6 +73,15 @@
|
||||
/obj/item/tank/proc/populate_gas()
|
||||
return
|
||||
|
||||
/obj/item/tank/DoRevenantThrowEffects(atom/target)
|
||||
if(air_contents)
|
||||
var/turf/open/location = get_turf(src)
|
||||
if(istype(location))
|
||||
location.assume_air(air_contents)
|
||||
air_contents.clear()
|
||||
SSair.add_to_active(location)
|
||||
visible_message("<span class='warning'[src] leaks gas!")
|
||||
|
||||
/obj/item/tank/Destroy()
|
||||
if(air_contents)
|
||||
qdel(air_contents)
|
||||
|
||||
@@ -57,6 +57,9 @@
|
||||
else
|
||||
item_state = "[initial(item_state)]"
|
||||
|
||||
/obj/item/weldingtool/DoRevenantThrowEffects(atom/target)
|
||||
attack_self()
|
||||
|
||||
/obj/item/weldingtool/update_overlays()
|
||||
. = ..()
|
||||
if(change_icons)
|
||||
@@ -208,12 +211,14 @@
|
||||
//Switches the welder on
|
||||
/obj/item/weldingtool/proc/switched_on(mob/user)
|
||||
if(!status)
|
||||
to_chat(user, "<span class='warning'>[src] can't be turned on while unsecured!</span>")
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>[src] can't be turned on while unsecured!</span>")
|
||||
return
|
||||
welding = !welding
|
||||
if(welding)
|
||||
if(get_fuel() >= 1)
|
||||
to_chat(user, "<span class='notice'>You switch [src] on.</span>")
|
||||
if(user)
|
||||
to_chat(user, "<span class='notice'>You switch [src] on.</span>")
|
||||
playsound(loc, acti_sound, 50, 1)
|
||||
force = 15
|
||||
damtype = "fire"
|
||||
|
||||
@@ -302,7 +302,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
damtype = STAMINA
|
||||
attack_verb = list("whacked", "smacked", "struck")
|
||||
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
|
||||
hitsound = 'sound/weapons/grenadelaunch.ogg' // no good wood thunk sounds
|
||||
hitsound = 'sound/weapons/woodbonk.ogg'
|
||||
var/harm = FALSE // TRUE = brute, FALSE = stam
|
||||
var/reinforced = FALSE
|
||||
var/burnt = FALSE
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
return 1
|
||||
|
||||
var/mob/living/M = caller
|
||||
if(!M.ventcrawler && M.mob_size != MOB_SIZE_TINY)
|
||||
if(!(SEND_SIGNAL(M, COMSIG_CHECK_VENTCRAWL)) && M.mob_size != MOB_SIZE_TINY)
|
||||
return 0
|
||||
var/atom/movable/M = caller
|
||||
if(M && M.pulling)
|
||||
@@ -91,7 +91,7 @@
|
||||
return 1
|
||||
if(M.buckled && istype(M.buckled, /mob/living/simple_animal/bot/mulebot)) // mulebot passenger gets a free pass.
|
||||
return 1
|
||||
if(!M.lying && !M.ventcrawler && M.mob_size != MOB_SIZE_TINY) //If your not laying down, or a ventcrawler or a small creature, no pass.
|
||||
if(!M.lying && !(SEND_SIGNAL(M, COMSIG_CHECK_VENTCRAWL)) && M.mob_size != MOB_SIZE_TINY) //If your not laying down, or a ventcrawler or a small creature, no pass.
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -56,17 +56,17 @@
|
||||
desc = "A direction sign, pointing out which way the Cafe is."
|
||||
icon_state = "direction_cafe"
|
||||
|
||||
obj/structure/sign/directions/rooms
|
||||
/obj/structure/sign/directions/rooms
|
||||
name = "room"
|
||||
desc = "Room numbers, helps others find you!"
|
||||
icon_state = "roomnum"
|
||||
|
||||
obj/structure/sign/directions/dorms
|
||||
/obj/structure/sign/directions/dorms
|
||||
name = "dorm"
|
||||
desc = "Dorm numbers, help others find you, or you find others."
|
||||
icon_state = "dormnum"
|
||||
|
||||
obj/structure/sign/directions/cells
|
||||
/obj/structure/sign/directions/cells
|
||||
name = "room"
|
||||
desc = "So the less fortunate amongst us know where they'll be staying."
|
||||
icon_state = "cellnum"
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
/turf/open
|
||||
plane = FLOOR_PLANE
|
||||
/// Does dirt buildup happen on us?
|
||||
var/dirt_buildup_allowed = FALSE
|
||||
/// Dirt level.
|
||||
var/dirtyness = 0
|
||||
/// Dirt level to spawn dirt. Null to use config.
|
||||
var/dirt_spawn_threshold
|
||||
/// Slowdown applied to mobs on us.
|
||||
var/slowdown = 0 //negative for faster, positive for slower
|
||||
|
||||
var/postdig_icon_change = FALSE
|
||||
@@ -18,6 +11,15 @@
|
||||
var/clawfootstep = null
|
||||
var/heavyfootstep = null
|
||||
|
||||
/// Dirtyness system, cit specific.
|
||||
|
||||
/// Does dirt buildup happen on us?
|
||||
var/dirt_buildup_allowed = FALSE
|
||||
/// Dirt level.
|
||||
var/dirtyness = 0
|
||||
/// Dirt level to spawn dirt. Null to use config.
|
||||
var/dirt_spawn_threshold
|
||||
|
||||
/turf/open/ComponentInitialize()
|
||||
. = ..()
|
||||
if(wet)
|
||||
|
||||
@@ -10,6 +10,8 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
plane = OPENSPACE_BACKDROP_PLANE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
layer = SPLASHSCREEN_LAYER
|
||||
//I don't know why the others are aligned but I shall do the same.
|
||||
vis_flags = VIS_INHERIT_ID
|
||||
|
||||
/turf/open/transparent/openspace
|
||||
name = "open space"
|
||||
@@ -17,6 +19,7 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
icon_state = "transparent"
|
||||
baseturfs = /turf/open/transparent/openspace
|
||||
CanAtmosPassVertical = ATMOS_PASS_YES
|
||||
intact = FALSE //this means wires go on top
|
||||
//mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
var/can_cover_up = TRUE
|
||||
var/can_build_on = TRUE
|
||||
@@ -32,10 +35,14 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
/turf/open/transparent/openspace/show_bottom_level()
|
||||
return FALSE
|
||||
|
||||
/turf/open/transparent/openspace/Initialize() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker
|
||||
/turf/open/openspace/Initialize() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker
|
||||
. = ..()
|
||||
|
||||
vis_contents += GLOB.openspace_backdrop_one_for_all //Special grey square for projecting backdrop darkness filter on it.
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/turf/open/openspace/LateInitialize()
|
||||
. = ..()
|
||||
// AddElement(/datum/element/turf_z_transparency, FALSE)
|
||||
|
||||
/turf/open/transparent/openspace/can_have_cabling()
|
||||
if(locate(/obj/structure/lattice/catwalk, src))
|
||||
@@ -95,6 +102,7 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
return
|
||||
if(L)
|
||||
if(R.use(1))
|
||||
qdel(L)
|
||||
to_chat(user, "<span class='notice'>You construct a catwalk.</span>")
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE)
|
||||
new/obj/structure/lattice/catwalk(src)
|
||||
@@ -148,9 +156,22 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
/turf/open/transparent/openspace/icemoon
|
||||
name = "ice chasm"
|
||||
baseturfs = /turf/open/transparent/openspace/icemoon
|
||||
can_cover_up = TRUE
|
||||
can_build_on = TRUE
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
planetary_atmos = TRUE
|
||||
var/replacement_turf = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
|
||||
/turf/open/transparent/openspace/icemoon/Initialize()
|
||||
. = ..()
|
||||
var/turf/T = below()
|
||||
// if(T.flags_1 & NO_RUINS_1)
|
||||
// ChangeTurf(replacement_turf, null, CHANGETURF_IGNORE_AIR)
|
||||
// return
|
||||
// if(!ismineralturf(T))
|
||||
// return
|
||||
var/turf/closed/mineral/M = T
|
||||
M.mineralAmt = 0
|
||||
M.gets_drilled()
|
||||
baseturfs = /turf/open/transparent/openspace/icemoon //This is to ensure that IF random turf generation produces a openturf, there won't be other turfs assigned other than openspace.
|
||||
|
||||
/turf/open/transparent/openspace/icemoon/can_zFall(atom/movable/A, levels = 1, turf/target)
|
||||
return TRUE
|
||||
|
||||
@@ -66,7 +66,12 @@
|
||||
|
||||
/turf/open/transparent/glass/Initialize()
|
||||
icon_state = "" //Prevent the normal icon from appearing behind the smooth overlays
|
||||
return ..()
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/turf/open/floor/glass/LateInitialize()
|
||||
. = ..()
|
||||
// AddElement(/datum/element/turf_z_transparency, TRUE)
|
||||
|
||||
/turf/open/transparent/glass/wrench_act(mob/living/user, obj/item/I)
|
||||
to_chat(user, "<span class='notice'>You begin removing glass...</span>")
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
bullet_bounce_sound = null
|
||||
|
||||
vis_flags = VIS_INHERIT_ID //when this be added to vis_contents of something it be associated with something on clicking, important for visualisation of turf in openspace and interraction with openspace that show you turf.
|
||||
|
||||
/turf/open/space/basic/New() //Do not convert to Initialize
|
||||
//This is used to optimize the map loader
|
||||
|
||||
@@ -197,6 +197,14 @@ GLOBAL_LIST(topic_status_cache)
|
||||
/world/Topic(T, addr, master, key)
|
||||
TGS_TOPIC //redirect to server tools if necessary
|
||||
|
||||
if(!SSfail2topic)
|
||||
return "Server not initialized."
|
||||
if(SSfail2topic.IsRateLimited(addr))
|
||||
return "Rate limited."
|
||||
|
||||
if(length(T) > CONFIG_GET(number/topic_max_size))
|
||||
return "Payload too large!"
|
||||
|
||||
var/static/list/topic_handlers = TopicHandlers()
|
||||
|
||||
var/list/input = params2list(T)
|
||||
|
||||
@@ -174,7 +174,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
//is_bwoink is TRUE if this ticket was started by an admin PM
|
||||
/datum/admin_help/New(msg, client/C, is_bwoink)
|
||||
//clean the input msg
|
||||
msg = sanitize(copytext_char(msg,1,MAX_MESSAGE_LEN))
|
||||
msg = copytext_char(msg,1,MAX_MESSAGE_LEN)
|
||||
if(!msg || !C || !C.mob)
|
||||
qdel(src)
|
||||
return
|
||||
@@ -263,7 +263,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
//message from the initiator without a target, all admins will see this
|
||||
//won't bug irc
|
||||
/datum/admin_help/proc/MessageNoRecipient(msg)
|
||||
msg = sanitize(copytext_char(msg, 1, MAX_MESSAGE_LEN))
|
||||
msg = copytext_char(msg, 1, MAX_MESSAGE_LEN)
|
||||
var/ref_src = "[REF(src)]"
|
||||
//Message to be sent to all admins
|
||||
var/admin_msg = "<span class='adminnotice'><span class='adminhelp'>Ticket [TicketHref("#[id]", ref_src)]</span><b>: [LinkedReplyName(ref_src)] [FullMonty(ref_src)]:</b> <span class='linkify'>[keywords_lookup(msg)]</span></span>"
|
||||
@@ -523,7 +523,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
if(handle_spam_prevention(msg,MUTE_ADMINHELP))
|
||||
return
|
||||
|
||||
msg = trim(msg)
|
||||
msg = sanitize(trim(msg))
|
||||
|
||||
if(!msg)
|
||||
return
|
||||
|
||||
@@ -113,7 +113,6 @@
|
||||
to_chat(src, "<span class='danger'>Error: Use the admin IRC/Discord channel, nerd.</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
|
||||
else
|
||||
//get message text, limit it's length.and clean/escape html
|
||||
if(!msg)
|
||||
@@ -128,11 +127,16 @@
|
||||
else
|
||||
if(holder)
|
||||
to_chat(src, "<span class='danger'>Error: Admin-PM: Client not found.</span>", confidential = TRUE)
|
||||
to_chat(src, "<span class='danger'><b>Message not sent:</b></span><br>[msg]", confidential = TRUE)
|
||||
to_chat(src, "<span class='danger'><b>Message not sent:</b></span><br>[sanitize(msg)]", confidential = TRUE)
|
||||
if(recipient_ticket)
|
||||
recipient_ticket.AddInteraction("<b>No client found, message not sent:</b><br>[msg]")
|
||||
return
|
||||
else
|
||||
//clean the message if it's not sent by a high-rank admin
|
||||
if(!check_rights(R_SERVER|R_DEBUG,0)||external)//no sending html to the poor bots
|
||||
msg = sanitize(copytext_char(msg, 1, MAX_MESSAGE_LEN))
|
||||
if(!msg)
|
||||
return
|
||||
current_ticket.MessageNoRecipient(msg)
|
||||
return
|
||||
|
||||
@@ -141,7 +145,7 @@
|
||||
to_chat(src, "<span class='danger'>Error: Admin-PM: You are unable to use admin PM-s (muted).</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
if (src.handle_spam_prevention(msg,MUTE_ADMINHELP))
|
||||
if(src.handle_spam_prevention(msg,MUTE_ADMINHELP))
|
||||
return
|
||||
|
||||
//clean the message if it's not sent by a high-rank admin
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
|
||||
/obj/item/organ/heart/gland/ventcrawling/activate()
|
||||
to_chat(owner, "<span class='notice'>You feel very stretchy.</span>")
|
||||
owner.ventcrawler = VENTCRAWLER_ALWAYS
|
||||
owner.AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
|
||||
|
||||
@@ -277,3 +277,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
var/datum/antagonist/blob/B = mind.has_antag_datum(/datum/antagonist/blob)
|
||||
if(!B)
|
||||
mind.add_antag_datum(/datum/antagonist/blob)
|
||||
|
||||
//the same but it's forced to be allowed by default as cameras usually don't allow emoting
|
||||
/mob/camera/blob/emote(act, m_type=1, message = null, intentional = FALSE, forced = TRUE)
|
||||
. = ..()
|
||||
|
||||
@@ -149,8 +149,6 @@
|
||||
if(prob(50))
|
||||
if(LAZYLEN(active_ais()) && prob(100/GLOB.joined_player_list.len))
|
||||
add_objective(new/datum/objective/destroy, TRUE)
|
||||
else if(prob(30))
|
||||
add_objective(new/datum/objective/maroon, TRUE)
|
||||
else
|
||||
add_objective(new/datum/objective/assassinate, TRUE)
|
||||
else
|
||||
|
||||
@@ -441,19 +441,20 @@
|
||||
else
|
||||
kill_objective.find_target()
|
||||
objectives += kill_objective
|
||||
else
|
||||
|
||||
/*else
|
||||
var/datum/objective/maroon/maroon_objective = new
|
||||
maroon_objective.owner = owner
|
||||
if(team_mode)
|
||||
maroon_objective.find_target_by_role(role = ROLE_CHANGELING, role_type = 1, invert = 1)
|
||||
else
|
||||
maroon_objective.find_target()
|
||||
objectives += maroon_objective
|
||||
objectives += maroon_objective*/
|
||||
|
||||
if (!(locate(/datum/objective/escape) in objectives) && escape_objective_possible)
|
||||
var/datum/objective/escape/escape_with_identity/identity_theft = new
|
||||
identity_theft.owner = owner
|
||||
identity_theft.target = maroon_objective.target
|
||||
identity_theft.target = kill_objective.target
|
||||
identity_theft.update_explanation_text()
|
||||
objectives += identity_theft
|
||||
escape_objective_possible = FALSE
|
||||
|
||||
@@ -165,14 +165,16 @@
|
||||
/datum/clockwork_rite/treat_wounds/cast(var/mob/living/invoker, var/turf/T, var/mob/living/carbon/human/target)
|
||||
if(!target)
|
||||
return FALSE
|
||||
if(!target.all_wounds.len)
|
||||
if(!target.all_wounds || !target.all_wounds.len)
|
||||
to_chat(invoker, "<span class='inathneq_small'>This one does not require mending.</span>")
|
||||
return FALSE
|
||||
.= ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
target.adjustToxLoss(10 * target.all_wounds.len)
|
||||
QDEL_LIST(target.all_wounds)
|
||||
for(var/i in target.all_wounds)
|
||||
var/datum/wound/mended = i
|
||||
mended.remove_wound()
|
||||
to_chat(target, "<span class='warning'>You feel your wounds heal, but are overcome with deep nausea.</span>")
|
||||
new /obj/effect/temp_visual/ratvar/sigil/vitality(T)
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
. = ..()
|
||||
desc = initial(desc)
|
||||
|
||||
obj/item/shield/riot/ratvarian/proc/calc_bash_mult()
|
||||
/obj/item/shield/riot/ratvarian/proc/calc_bash_mult()
|
||||
var/bash_mult = 0
|
||||
if(!dam_absorbed)
|
||||
return 1
|
||||
|
||||
@@ -203,10 +203,10 @@
|
||||
to_chat(user, "<span class='warning'>You need to hold the slab in your active hand to recite scripture!</span>")
|
||||
return FALSE
|
||||
var/initial_tier = initial(scripture.tier)
|
||||
if(initial_tier == SCRIPTURE_PERIPHERAL)
|
||||
if(initial_tier == SCRIPTURE_PERIPHERAL && !issilicon(user)) //Silicons use peripheral scripture & cannot open the slab.
|
||||
to_chat(user, "<span class='warning'>Nice try using href exploits</span>")
|
||||
return
|
||||
if(!GLOB.ratvar_awakens && !no_cost && !SSticker.scripture_states[initial_tier])
|
||||
if(!GLOB.ratvar_awakens && !no_cost && !SSticker.scripture_states[initial_tier] &&!issilicon(user)) //silicons can't choose their spells, so lets allow them to always cast their assigned ones.
|
||||
to_chat(user, "<span class='warning'>That scripture is not unlocked, and cannot be recited!</span>")
|
||||
return FALSE
|
||||
var/datum/clockwork_scripture/scripture_to_recite = new scripture
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
descname = "Powers Nearby Structures"
|
||||
name = "Sigil of Transmission"
|
||||
desc = "Places a sigil that can drain and will store energy to power clockwork structures."
|
||||
invocations = list("Divinity...", "...power our creations!")
|
||||
invocations = list("Divinity...", "...power our creations.")
|
||||
channel_time = 70
|
||||
power_cost = 200
|
||||
whispered = TRUE
|
||||
@@ -28,7 +28,7 @@
|
||||
descname = "Powered Structure, Delay Emergency Shuttles"
|
||||
name = "Prolonging Prism"
|
||||
desc = "Creates a mechanized prism which will delay the arrival of an emergency shuttle by 2 minutes at a massive power cost."
|
||||
invocations = list("May this prism...", "...grant us time to enact his will!")
|
||||
invocations = list("May this prism...", "...grant us time to enact his will.")
|
||||
channel_time = 80
|
||||
power_cost = 300
|
||||
object_path = /obj/structure/destructible/clockwork/powered/prolonging_prism
|
||||
@@ -60,7 +60,7 @@
|
||||
descname = "Powered Structure, Area Denial"
|
||||
name = "Mania Motor"
|
||||
desc = "Creates a mania motor which causes minor damage and a variety of negative mental effects in nearby non-Servant humans, potentially up to and including conversion."
|
||||
invocations = list("May this transmitter...", "...break the will of all who oppose us!")
|
||||
invocations = list("May this transmitter...", "...break the will of all who oppose us.")
|
||||
channel_time = 80
|
||||
power_cost = 750
|
||||
object_path = /obj/structure/destructible/clockwork/powered/mania_motor
|
||||
@@ -83,7 +83,7 @@
|
||||
descname = "Powered Structure, Teleportation Hub"
|
||||
name = "Clockwork Obelisk"
|
||||
desc = "Creates a clockwork obelisk that can broadcast messages over the Hierophant Network or open a Spatial Gateway to any living Servant or clockwork obelisk."
|
||||
invocations = list("May this obelisk...", "...take us to all places!")
|
||||
invocations = list("May this obelisk...", "...take us to all places.")
|
||||
channel_time = 80
|
||||
power_cost = 300
|
||||
object_path = /obj/structure/destructible/clockwork/powered/clockwork_obelisk
|
||||
@@ -163,7 +163,7 @@
|
||||
descname = "Well-Rounded Combat Construct"
|
||||
name = "Clockwork Marauder"
|
||||
desc = "Creates a shell for a clockwork marauder, a balanced frontline construct that can deflect projectiles with its shield."
|
||||
invocations = list("Arise, avatar of Arbiter!", "Defend the Ark with vengeful zeal.")
|
||||
invocations = list("Arise, avatar of Arbiter!", "Defend the Ark with vengeful zeal!")
|
||||
channel_time = 80
|
||||
power_cost = 8000
|
||||
creator_message = "<span class='brass'>Your slab disgorges several chunks of replicant alloy that form into a suit of thrumming armor.</span>"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
descname = "Generates Power From Starlight"
|
||||
name = "Stargazer"
|
||||
desc = "Forms a weak structure that generates power every second while within three tiles of starlight."
|
||||
invocations = list("Capture their inferior light for us!")
|
||||
invocations = list("Capture their inferior light for us.")
|
||||
channel_time = 50
|
||||
power_cost = 200
|
||||
object_path = /obj/structure/destructible/clockwork/stargazer
|
||||
@@ -16,6 +16,7 @@
|
||||
usage_tip = "For obvious reasons, make sure to place this near a window or somewhere else that can see space!"
|
||||
tier = SCRIPTURE_DRIVER
|
||||
one_per_tile = TRUE
|
||||
whispered = TRUE
|
||||
primary_component = HIEROPHANT_ANSIBLE
|
||||
sort_priority = 1
|
||||
quickbind = TRUE
|
||||
@@ -34,7 +35,7 @@
|
||||
descname = "Power Generation"
|
||||
name = "Integration Cog"
|
||||
desc = "Fabricates an integration cog, which can be used on an open APC to replace its innards and passively siphon its power."
|
||||
invocations = list("Take that which sustains them!")
|
||||
invocations = list("Take that which sustains them.")
|
||||
channel_time = 10
|
||||
power_cost = 10
|
||||
whispered = TRUE
|
||||
@@ -55,7 +56,7 @@
|
||||
descname = "Trap, Stunning"
|
||||
name = "Sigil of Transgression"
|
||||
desc = "Wards a tile with a sigil, which will briefly stun the next non-Servant to cross it and apply Belligerent to them."
|
||||
invocations = list("Divinity, smite...", "...those who trespass here!")
|
||||
invocations = list("Divinity, smite...", "...those who trespass here.")
|
||||
channel_time = 50
|
||||
power_cost = 50
|
||||
whispered = TRUE
|
||||
@@ -75,7 +76,7 @@
|
||||
descname = "Trap, Conversion"
|
||||
name = "Sigil of Submission"
|
||||
desc = "Places a luminous sigil that will convert any non-Servants that remain on it for 8 seconds."
|
||||
invocations = list("Divinity, enlighten...", "...those who trespass here!")
|
||||
invocations = list("Divinity, enlighten...", "...those who trespass here.")
|
||||
channel_time = 60
|
||||
power_cost = 125
|
||||
whispered = TRUE
|
||||
@@ -95,7 +96,7 @@
|
||||
descname = "Short-Range Single-Target Stun"
|
||||
name = "Kindle"
|
||||
desc = "Charges your slab with divine energy, allowing you to overwhelm a target with Ratvar's light."
|
||||
invocations = list("Divinity, show them your light!")
|
||||
invocations = list("Divinity, show them your light.")
|
||||
whispered = TRUE
|
||||
channel_time = 25 //2.5 seconds should be a okay compromise between being able to use it when needed, and not being able to just pause in combat for a second and hardstunning your enemy
|
||||
power_cost = 125
|
||||
@@ -118,7 +119,7 @@
|
||||
descname = "Handcuffs"
|
||||
name = "Hateful Manacles"
|
||||
desc = "Forms replicant manacles around a target's wrists that function like handcuffs."
|
||||
invocations = list("Shackle the heretic!", "Break them in body and spirit!")
|
||||
invocations = list("Shackle the heretic!", "Break them in body and spirit.")
|
||||
channel_time = 15
|
||||
power_cost = 25
|
||||
whispered = TRUE
|
||||
@@ -269,7 +270,7 @@
|
||||
descname = "New Clockwork Slab"
|
||||
name = "Replicant"
|
||||
desc = "Creates a new clockwork slab."
|
||||
invocations = list("Metal, become greater!")
|
||||
invocations = list("Metal, become greater.")
|
||||
channel_time = 10
|
||||
power_cost = 25
|
||||
whispered = TRUE
|
||||
@@ -290,7 +291,7 @@
|
||||
descname = "Limited Xray Vision Glasses"
|
||||
name = "Wraith Spectacles"
|
||||
desc = "Fabricates a pair of glasses which grant true sight but cause gradual vision loss."
|
||||
invocations = list("Show the truth of this world to me!")
|
||||
invocations = list("Show the truth of this world to me.")
|
||||
channel_time = 10
|
||||
power_cost = 50
|
||||
whispered = TRUE
|
||||
@@ -310,7 +311,7 @@
|
||||
name = "Spatial Gateway"
|
||||
desc = "Tears open a miniaturized gateway in spacetime to any conscious servant that can transport objects or creatures to its destination. \
|
||||
Each servant assisting in the invocation adds one additional use and four additional seconds to the gateway's uses and duration."
|
||||
invocations = list("Spatial Gateway...", "...activate!")
|
||||
invocations = list("Spatial Gateway...", "...activate.")
|
||||
channel_time = 30
|
||||
power_cost = 400
|
||||
whispered = TRUE
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user