Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into station_traits
This commit is contained in:
@@ -80,7 +80,7 @@
|
||||
//DNA - Because fuck you and your magic numbers being all over the codebase.
|
||||
#define DNA_BLOCK_SIZE 3
|
||||
|
||||
#define DNA_UNI_IDENTITY_BLOCKS 15
|
||||
#define DNA_UNI_IDENTITY_BLOCKS 19
|
||||
#define DNA_HAIR_COLOR_BLOCK 1
|
||||
#define DNA_FACIAL_HAIR_COLOR_BLOCK 2
|
||||
#define DNA_SKIN_TONE_BLOCK 3
|
||||
@@ -96,6 +96,10 @@
|
||||
#define DNA_MUTANTEAR_BLOCK 13
|
||||
#define DNA_MUTANTMARKING_BLOCK 14
|
||||
#define DNA_TAUR_BLOCK 15
|
||||
#define DNA_BARK_SOUND_BLOCK 16
|
||||
#define DNA_BARK_SPEED_BLOCK 17
|
||||
#define DNA_BARK_PITCH_BLOCK 18
|
||||
#define DNA_BARK_VARIANCE_BLOCK 19
|
||||
|
||||
#define DNA_SEQUENCE_LENGTH 4
|
||||
#define DNA_MUTATION_BLOCKS 8
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#define DEFINE_BITFIELD(_variable, _flags) /datum/bitfield/##_variable { \
|
||||
flags = ##_flags; \
|
||||
variable = #_variable; \
|
||||
}
|
||||
@@ -274,6 +274,8 @@
|
||||
// #define HEARING_SPANS 6
|
||||
#define HEARING_MESSAGE_MODE 7
|
||||
// #define HEARING_SOURCE 8
|
||||
#define COMSIG_MOVABLE_BARK "movable_bark" //from base of atom/movable/proc/bark(): (list/hearers, distance, volume, pitch)
|
||||
#define COMSIG_MOVABLE_QUEUE_BARK "movable_queue_bark" //from base of atom/movable/proc/send_speech(): (list/hearers, message, range, atom/movable/source, bubble_type, list/spans, datum/language/message_language, message_mode)
|
||||
#define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source)
|
||||
#define COMSIG_MOVABLE_TELEPORTED "movable_teleported" //from base of do_teleport(): (channel, turf/origin, turf/destination)
|
||||
#define COMSIG_MOVABLE_CHASM_DROP "movable_chasm_drop" //from base of /datum/component/chasm/drop() (/datum/component/chasm)
|
||||
@@ -417,7 +419,7 @@
|
||||
#define COMPONENT_INTERRUPT_LIFE_PHYSICAL 2 // interrupt physical handling
|
||||
#define COMPONET_INTERRUPT_STATUS_EFFECTS 3 // interrupt status effects
|
||||
|
||||
#define COMSIG_LIVING_BIOLOGICAL_LIFE "biological_life" //from base of mob/living/BiologicalLife() (seconds, times_fired)
|
||||
#define COMSIG_LIVING_BIOLOGICAL_LIFE "biological_life" //from base of mob/living/BiologicalLife() (delta_time, times_fired)
|
||||
|
||||
#define COMSIG_LIVING_PHYSICAL_LIFE "physical_life" //from base of mob/living/PhysicalLife() (seconds, times_fired)
|
||||
|
||||
@@ -569,7 +571,7 @@
|
||||
#define COMSIG_MECHA_EQUIPMENT_CLICK "mecha_action_equipment_click"
|
||||
/// Prevents click from happening.
|
||||
#define COMPONENT_CANCEL_EQUIPMENT_CLICK (1<<0)
|
||||
|
||||
|
||||
// /mob/living/carbon/human signals
|
||||
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target)
|
||||
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
/// Called from /mob/living/PushAM -- Called when this mob is about to push a movable, but before it moves
|
||||
/// (aotm/movable/being_pushed)
|
||||
#define COMSIG_LIVING_PUSHING_MOVABLE "living_pushing_movable"
|
||||
@@ -0,0 +1,2 @@
|
||||
///From base of mob/living/MobBump() (mob/living)
|
||||
#define COMSIG_LIVING_MOB_BUMP "living_mob_bump"
|
||||
@@ -0,0 +1,25 @@
|
||||
// Subsystem signals. Format:
|
||||
// When the signal is called: (signal arguments)
|
||||
// All signals send the source datum of the signal as the first argument
|
||||
|
||||
///Subsystem signals
|
||||
///From base of datum/controller/subsystem/Initialize: (start_timeofday)
|
||||
#define COMSIG_SUBSYSTEM_POST_INITIALIZE "subsystem_post_initialize"
|
||||
|
||||
///Called when the ticker enters the pre-game phase
|
||||
#define COMSIG_TICKER_ENTER_PREGAME "comsig_ticker_enter_pregame"
|
||||
|
||||
///Called when the ticker sets up the game for start
|
||||
#define COMSIG_TICKER_ENTER_SETTING_UP "comsig_ticker_enter_setting_up"
|
||||
|
||||
///Called when the ticker fails to set up the game for start
|
||||
#define COMSIG_TICKER_ERROR_SETTING_UP "comsig_ticker_error_setting_up"
|
||||
|
||||
/// Called when the round has started, but before GAME_STATE_PLAYING
|
||||
#define COMSIG_TICKER_ROUND_STARTING "comsig_ticker_round_starting"
|
||||
|
||||
// Point of interest signals
|
||||
/// Sent from base of /datum/controller/subsystem/points_of_interest/proc/on_poi_element_added : (atom/new_poi)
|
||||
#define COMSIG_ADDED_POINT_OF_INTEREST "added_point_of_interest"
|
||||
/// Sent from base of /datum/controller/subsystem/points_of_interest/proc/on_poi_element_removed : (atom/old_poi)
|
||||
#define COMSIG_REMOVED_POINT_OF_INTEREST "removed_point_of_interest"
|
||||
@@ -187,6 +187,9 @@
|
||||
#define ABOVE_HUD_LAYER 30
|
||||
#define ABOVE_HUD_RENDER_TARGET "ABOVE_HUD_PLANE"
|
||||
|
||||
#define LOBBY_BACKGROUND_LAYER 3
|
||||
#define LOBBY_BUTTON_LAYER 4
|
||||
|
||||
#define SPLASHSCREEN_LAYER 90
|
||||
#define SPLASHSCREEN_PLANE 90
|
||||
#define SPLASHSCREEN_RENDER_TARGET "SPLASHSCREEN_PLANE"
|
||||
|
||||
@@ -91,3 +91,8 @@
|
||||
#define LOADOUT_TAB 4
|
||||
#define CONTENT_PREFERENCES_TAB 5
|
||||
#define KEYBINDINGS_TAB 6
|
||||
|
||||
//quirks
|
||||
#define QUIRK_POSITIVE "Positive"
|
||||
#define QUIRK_NEGATIVE "Negative"
|
||||
#define QUIRK_NEUTRAL "Neutral"
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#define LOG_MECHA (1 << 17)
|
||||
#define LOG_SHUTTLE (1 << 18)
|
||||
#define LOG_VICTIM (1 << 19)
|
||||
#define LOG_ECON (1 << 20)
|
||||
|
||||
//Individual logging panel pages
|
||||
#define INDIVIDUAL_ATTACK_LOG (LOG_ATTACK | LOG_VICTIM)
|
||||
@@ -50,7 +51,7 @@
|
||||
#define INDIVIDUAL_COMMS_LOG (LOG_PDA | LOG_CHAT | LOG_COMMENT | LOG_TELECOMMS)
|
||||
#define INDIVIDUAL_OOC_LOG (LOG_OOC | LOG_ADMIN)
|
||||
#define INDIVIDUAL_OWNERSHIP_LOG (LOG_OWNERSHIP)
|
||||
#define INDIVIDUAL_SHOW_ALL_LOG (LOG_ATTACK | LOG_SAY | LOG_WHISPER | LOG_EMOTE | LOG_DSAY | LOG_PDA | LOG_CHAT | LOG_COMMENT | LOG_TELECOMMS | LOG_OOC | LOG_ADMIN | LOG_OWNERSHIP | LOG_GAME | LOG_VICTIM)
|
||||
#define INDIVIDUAL_SHOW_ALL_LOG (LOG_ATTACK | LOG_SAY | LOG_WHISPER | LOG_EMOTE | LOG_DSAY | LOG_PDA | LOG_CHAT | LOG_COMMENT | LOG_TELECOMMS | LOG_OOC | LOG_ADMIN | LOG_OWNERSHIP | LOG_GAME | LOG_VICTIM | LOG_ECON)
|
||||
|
||||
#define LOGSRC_CLIENT "Client"
|
||||
#define LOGSRC_MOB "Mob"
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// Ready states at roundstart for mob/dead/new_player
|
||||
#define PLAYER_NOT_READY 0
|
||||
#define PLAYER_READY_TO_PLAY 1
|
||||
#define PLAYER_READY_TO_OBSERVE 2
|
||||
|
||||
// movement intent defines for the m_intent var
|
||||
#define MOVE_INTENT_WALK "walk"
|
||||
|
||||
@@ -13,7 +13,7 @@ GLOBAL_VAR_INIT(glide_size_multiplier, 1.0)
|
||||
/// Then that's multiplied by the global glide size multiplier. 1.25 by default feels pretty close to spot on. This is just to try to get byond to behave.
|
||||
/// The whole result is then clamped to within the range above.
|
||||
/// Not very readable but it works
|
||||
#define DELAY_TO_GLIDE_SIZE(delay) (clamp(((32 / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE))
|
||||
#define DELAY_TO_GLIDE_SIZE(delay) (clamp(((world.icon_size / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE))
|
||||
|
||||
/// Enables smooth movement
|
||||
// #define SMOOTH_MOVEMENT
|
||||
|
||||
@@ -8,5 +8,6 @@
|
||||
GLOBAL_LIST_INIT(blacklisted_pool_reagents, list(
|
||||
/datum/reagent/toxin/plasma, /datum/reagent/oxygen, /datum/reagent/nitrous_oxide, /datum/reagent/nitrogen, //gases
|
||||
/datum/reagent/fermi, //blanket fermichem ban sorry. this also covers mkultra, genital enlargers, etc etc.
|
||||
/datum/reagent/consumable/semen //NO.
|
||||
/datum/reagent/consumable/semen, //NO.
|
||||
/datum/reagent/consumable/milk
|
||||
))
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define DISABLE_DEATHRATTLE (1<<12)
|
||||
#define DISABLE_ARRIVALRATTLE (1<<13)
|
||||
#define COMBOHUD_LIGHTING (1<<14)
|
||||
#define SOUND_BARK (1<<15)
|
||||
|
||||
#define DEADMIN_ALWAYS (1<<0)
|
||||
#define DEADMIN_ANTAGONIST (1<<1)
|
||||
@@ -22,7 +23,7 @@
|
||||
#define DEADMIN_POSITION_SECURITY (1<<3)
|
||||
#define DEADMIN_POSITION_SILICON (1<<4)
|
||||
|
||||
#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS)
|
||||
#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS|SOUND_BARK)
|
||||
|
||||
//Chat toggles
|
||||
#define CHAT_OOC (1<<0)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#define NOBLIUM_RESEARCH_AMOUNT 25
|
||||
#define BZ_RESEARCH_SCALE 4
|
||||
#define BZ_RESEARCH_MAX_AMOUNT 400
|
||||
#define QCD_RESEARCH_AMOUNT 0.2 // often made in absolutely massive quantities due to the simple nature of fusion
|
||||
#define MIASMA_RESEARCH_AMOUNT 6
|
||||
#define STIMULUM_RESEARCH_AMOUNT 50
|
||||
//Plasma fusion properties
|
||||
|
||||
@@ -73,7 +73,9 @@
|
||||
TECHWEB_POINT_TYPE_GENERIC = "General Research"\
|
||||
)
|
||||
|
||||
#define LARGEST_BOMB "bomb"
|
||||
|
||||
#define BOMB_TARGET_POINTS 50000 //Adjust as needed. Actual hard cap is double this, but will never be reached due to hyperbolic curve.
|
||||
#define BOMB_TARGET_SIZE (world.system_type == MS_WINDOWS ? 240 : 50000) // The shockwave radius required for a bomb to get TECHWEB_BOMB_MIDPOINT points.
|
||||
#define BOMB_TARGET_SIZE 300 // The shockwave radius required for a bomb to get TECHWEB_BOMB_MIDPOINT points.
|
||||
// Linux still has old trit fires, so
|
||||
#define BOMB_SUB_TARGET_EXPONENT 3 // The power of the points curve below the target size. Higher = less points for worse bombs, below target.
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#define MODE_ALIEN "alientalk"
|
||||
#define MODE_HOLOPAD "holopad"
|
||||
#define MODE_STATUSDISPLAY "statusdisplay"
|
||||
|
||||
#define MODE_CHANGELING "changeling"
|
||||
#define MODE_KEY_CHANGELING "g"
|
||||
@@ -91,11 +92,32 @@
|
||||
//ambition end
|
||||
#define MAX_MESSAGE_LEN 4096 //Citadel edit: What's the WORST that could happen?
|
||||
#define MAX_FLAVOR_LEN 4096
|
||||
#define MAX_FLAVOR_PREVIEW_LEN 40
|
||||
#define MAX_TASTE_LEN 40 //lick... vore... ew...
|
||||
#define MAX_NAME_LEN 42
|
||||
#define MAX_BROADCAST_LEN 512
|
||||
#define MAX_CHARTER_LEN 80
|
||||
|
||||
//Bark defines
|
||||
#define BARK_DEFAULT_MINPITCH 0.6
|
||||
#define BARK_DEFAULT_MAXPITCH 1.4
|
||||
#define BARK_DEFAULT_MINVARY 0.1
|
||||
#define BARK_DEFAULT_MAXVARY 0.4
|
||||
#define BARK_DEFAULT_MINSPEED 2
|
||||
#define BARK_DEFAULT_MAXSPEED 8
|
||||
|
||||
#define BARK_SPEED_BASELINE 4 //Used to calculate delay between barks, any bark speeds below this feature higher bark density, any speeds above feature lower bark density. Keeps barking length consistent
|
||||
|
||||
#define BARK_MAX_BARKS 128
|
||||
#define BARK_MAX_TIME (10 SECONDS) // More or less the amount of time the above takes to process through with a bark speed of 2.
|
||||
|
||||
#define BARK_PITCH_RAND(gend) ((gend == MALE ? rand(60, 120) : (gend == FEMALE ? rand(80, 140) : rand(60,140))) / 100) //Macro for determining random pitch based off gender
|
||||
#define BARK_VARIANCE_RAND (rand(BARK_DEFAULT_MINVARY * 100, BARK_DEFAULT_MAXVARY * 100) / 100) //Macro for randomizing bark variance to reduce the amount of copy-pasta necessary for that
|
||||
|
||||
#define BARK_DO_VARY(pitch, variance) (rand(((pitch * 100) - (variance*50)), ((pitch*100) + (variance*50))) / 100)
|
||||
|
||||
#define BARK_SOUND_FALLOFF_EXPONENT(distance) (distance/7) //At lower ranges, we want the exponent to be below 1 so that whispers don't sound too awkward. At higher ranges, we want the exponent fairly high to make yelling less obnoxious
|
||||
|
||||
// Is something in the IC chat filter? This is config dependent.
|
||||
#define CHAT_FILTER_CHECK(T) (config.ic_filter_regex && findtext(T, config.ic_filter_regex))
|
||||
|
||||
|
||||
@@ -233,6 +233,8 @@
|
||||
#define TRAIT_TRASHCAN "trashcan"
|
||||
///Used for fireman carry to have mobe not be dropped when passing by a prone individual.
|
||||
#define TRAIT_BEING_CARRIED "being_carried"
|
||||
#define TRAIT_GLASS_BONES "glass_bones"
|
||||
#define TRAIT_PAPER_SKIN "paper_skin"
|
||||
|
||||
// mobility flag traits
|
||||
// IN THE FUTURE, IT WOULD BE NICE TO DO SOMETHING SIMILAR TO https://github.com/tgstation/tgstation/pull/48923/files (ofcourse not nearly the same because I have my.. thoughts on it)
|
||||
|
||||
@@ -161,6 +161,10 @@
|
||||
if (CONFIG_GET(flag/log_telecomms))
|
||||
WRITE_LOG(GLOB.world_telecomms_log, "TCOMMS: [text]")
|
||||
|
||||
/proc/log_econ(text)
|
||||
if (CONFIG_GET(flag/log_econ))
|
||||
WRITE_LOG(GLOB.world_econ_log, "MONEY: [text]")
|
||||
|
||||
/proc/log_chat(text)
|
||||
if (CONFIG_GET(flag/log_pda))
|
||||
//same thing here
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
///Returns whether or not a player is a guest using their ckey as an input
|
||||
/proc/is_guest_key(key)
|
||||
if(findtext(key, "Guest-", 1, 7) != 1) //was findtextEx
|
||||
return FALSE
|
||||
|
||||
var/i, ch, len = length(key)
|
||||
|
||||
for(i = 7, i <= len, ++i) //we know the first 6 chars are Guest-
|
||||
ch = text2ascii(key, i)
|
||||
if (ch < 48 || ch > 57) //0-9
|
||||
return FALSE
|
||||
return TRUE
|
||||
@@ -79,6 +79,12 @@
|
||||
var/datum/emote/E = new path()
|
||||
E.emote_list[E.key] = E
|
||||
|
||||
for(var/path in subtypesof(/datum/bark))
|
||||
var/datum/bark/B = new path()
|
||||
GLOB.bark_list[B.id] = path
|
||||
if(B.allow_random)
|
||||
GLOB.bark_random_list[B.id] = path
|
||||
|
||||
// Hair Gradients - Initialise all /datum/sprite_accessory/hair_gradient into an list indexed by gradient-style name
|
||||
for(var/path in subtypesof(/datum/sprite_accessory/hair_gradient))
|
||||
var/datum/sprite_accessory/hair_gradient/H = new path()
|
||||
|
||||
@@ -138,6 +138,25 @@ round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), ro
|
||||
var/sinval = round(sin(angle), 0.001); var/cosval = round(cos(angle), 0.001)
|
||||
return list(cosval,sinval,0,0, -sinval,cosval,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0)
|
||||
|
||||
/**
|
||||
* Builds a color matrix that transforms the hue, saturation, and value, all in one operation.
|
||||
*/
|
||||
/proc/color_matrix_hsv(hue, saturation, value)
|
||||
hue = clamp(360 - hue, 0, 360)
|
||||
|
||||
// This is very much a rough approximation of hueshifting. This carries some artifacting, such as negative values that simply shouldn't exist, but it does get the job done, and that's what matters.
|
||||
var/cos_a = cos(hue) // These have to be inverted from 360, otherwise the hue's inverted
|
||||
var/sin_a = sin(hue)
|
||||
var/rot_x = cos_a + (1 - cos_a) / 3
|
||||
var/rot_y = (1 - cos_a) / 3 - 0.5774 * sin_a // 0.5774 is sqrt(1/3)
|
||||
var/rot_z = (1 - cos_a) / 3 + 0.5774 * sin_a
|
||||
|
||||
return list(
|
||||
round((((1-saturation) * LUMA_R) + (rot_x * saturation)) * value, 0.01), round((((1-saturation) * LUMA_R) + (rot_y * saturation)) * value, 0.01), round((((1-saturation) * LUMA_R) + (rot_z * saturation)) * value, 0.01),
|
||||
round((((1-saturation) * LUMA_G) + (rot_z * saturation)) * value, 0.01), round((((1-saturation) * LUMA_G) + (rot_x * saturation)) * value, 0.01), round((((1-saturation) * LUMA_G) + (rot_y * saturation)) * value, 0.01),
|
||||
round((((1-saturation) * LUMA_B) + (rot_y * saturation)) * value, 0.01), round((((1-saturation) * LUMA_B) + (rot_z * saturation)) * value, 0.01), round((((1-saturation) * LUMA_B) + (rot_x * saturation)) * value, 0.01),
|
||||
0, 0, 0
|
||||
)
|
||||
|
||||
//Returns a matrix addition of A with B
|
||||
/proc/color_matrix_add(list/A, list/B)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
speed /= segments
|
||||
|
||||
if(parallel)
|
||||
animate(src, transform = matrices[1], time = speed, loops , flags = ANIMATION_PARALLEL)
|
||||
animate(src, transform = matrices[1], time = speed, loops, flags = ANIMATION_PARALLEL)
|
||||
else
|
||||
animate(src, transform = matrices[1], time = speed, loops)
|
||||
|
||||
|
||||
@@ -258,15 +258,24 @@
|
||||
|
||||
send2adminchat("Server", "A round of [mode.name] just ended[mode_result == "undefined" ? "." : " with a [mode_result]."] Survival rate: [survival_rate]")
|
||||
|
||||
if(LAZYLEN(GLOB.round_end_notifiees))
|
||||
world.TgsTargetedChatBroadcast("[GLOB.round_end_notifiees.Join(", ")] the round has ended.", FALSE)
|
||||
|
||||
if(length(CONFIG_GET(keyed_list/cross_server)))
|
||||
send_news_report()
|
||||
|
||||
//tell the nice people on discord what went on before the salt cannon happens.
|
||||
world.TgsTargetedChatBroadcast("The current round has ended. Please standby for your shift interlude Nanotrasen News Network's report!", FALSE)
|
||||
world.TgsTargetedChatBroadcast(send_news_report(), FALSE)
|
||||
if(CONFIG_GET(string/chat_roundend_notice_tag))
|
||||
var/broadcastmessage = ""
|
||||
|
||||
if(LAZYLEN(GLOB.round_end_notifiees))
|
||||
broadcastmessage += "[GLOB.round_end_notifiees.Join(", ")], "
|
||||
|
||||
|
||||
broadcastmessage += "[((broadcastmessage == "") ? "the" : "The")] current round has ended. Please standby for your shift interlude Nanotrasen News Network's report!\n"
|
||||
broadcastmessage += "```\n[send_news_report()]\n```"
|
||||
|
||||
if(CONFIG_GET(string/chat_reboot_role))
|
||||
broadcastmessage += "\n\n<@&[CONFIG_GET(string/chat_reboot_role)]>, the server will reboot shortly!"
|
||||
|
||||
send2chat(broadcastmessage, CONFIG_GET(string/chat_roundend_notice_tag))
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
@@ -370,6 +379,8 @@
|
||||
|
||||
parts += "[FOURSPACES]Shift Duration: <B>[DisplayTimeText(world.time - SSticker.round_start_time)]</B>"
|
||||
parts += "[FOURSPACES]Station Integrity: <B>[mode.station_was_nuked ? "<span class='redtext'>Destroyed</span>" : "[popcount["station_integrity"]]%"]</B>"
|
||||
if(mode.station_was_nuked && SSevents.holidays && SSevents.holidays[PRIDE_MONTH])
|
||||
parts += "[FOURSPACES]Gender revealed: <B>[pick(500; "Male", 500; "Female", "Bigender", "Agender", "Demiboy", "Demigirl", "Genderfluid", "Pangender", "Xenogender", "Clown", 50; "What", 50; "Oh no.", 50; "Excuse me?")]</B>"
|
||||
var/total_players = GLOB.joined_player_list.len
|
||||
if(total_players)
|
||||
parts+= "[FOURSPACES]Total Population: <B>[total_players]</B>"
|
||||
@@ -548,7 +559,7 @@
|
||||
parts += "There were [station_vault] credits collected by crew this shift.<br>"
|
||||
if(total_players > 0)
|
||||
parts += "An average of [station_vault/total_players] credits were collected.<br>"
|
||||
// log_econ("Roundend credit total: [station_vault] credits. Average Credits: [station_vault/total_players]")
|
||||
log_econ("Roundend credit total: [station_vault] credits. Average Credits: [station_vault/total_players]")
|
||||
if(mr_moneybags)
|
||||
parts += "The most affluent crew member at shift end was <b>[mr_moneybags.account_holder] with [mr_moneybags.account_balance]</b> cr!</div>"
|
||||
else
|
||||
|
||||
@@ -1176,25 +1176,22 @@ GLOBAL_REAL_VAR(list/stack_trace_storage)
|
||||
var/initialpixely = pixel_y
|
||||
var/shiftx = rand(-pixelshiftx,pixelshiftx)
|
||||
var/shifty = rand(-pixelshifty,pixelshifty)
|
||||
animate(src, pixel_x = pixel_x + shiftx, pixel_y = pixel_y + shifty, time = 0.2, loop = duration)
|
||||
pixel_x = initialpixelx
|
||||
pixel_y = initialpixely
|
||||
animate(src, pixel_x = shiftx, pixel_y = shifty, time = 0.2, loop = duration, flags = ANIMATION_RELATIVE)
|
||||
animate(pixel_x = initialpixelx, pixel_y = initialpixely, time = 0.2)
|
||||
|
||||
/atom/proc/do_jiggle(targetangle = 45, timer = 20)
|
||||
/atom/proc/do_jiggle(targetangle = 25, timer = 20)
|
||||
var/matrix/OM = matrix(transform)
|
||||
var/matrix/M = matrix(transform)
|
||||
var/halftime = timer * 0.5
|
||||
M.Turn(pick(-targetangle, targetangle))
|
||||
animate(src, transform = M, time = halftime, easing = ELASTIC_EASING)
|
||||
animate(src, transform = OM, time = halftime, easing = ELASTIC_EASING)
|
||||
animate(src, transform = M, time = timer * 0.1, easing = BACK_EASING | EASE_IN)
|
||||
animate(transform = OM, time = timer * 0.4, easing = ELASTIC_EASING)
|
||||
|
||||
/atom/proc/do_squish(squishx = 1.2, squishy = 0.6, timer = 20)
|
||||
var/matrix/OM = matrix(transform)
|
||||
var/matrix/M = matrix(transform)
|
||||
var/halftime = timer * 0.5
|
||||
M.Scale(squishx, squishy)
|
||||
animate(src, transform = M, time = halftime, easing = BOUNCE_EASING)
|
||||
animate(src, transform = OM, time = halftime, easing = BOUNCE_EASING)
|
||||
animate(src, transform = M, time = timer * 0.5, easing = ELASTIC_EASING)
|
||||
animate(transform = OM, time = timer * 0.5, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL)
|
||||
|
||||
/proc/weightclass2text(var/w_class)
|
||||
switch(w_class)
|
||||
|
||||
+377
-328
@@ -1,329 +1,378 @@
|
||||
GLOBAL_LIST_INIT(bitfields, list(
|
||||
"appearance_flags" = list(
|
||||
"LONG_GLIDE" = LONG_GLIDE,
|
||||
"RESET_COLOR" = RESET_COLOR,
|
||||
"RESET_ALPHA" = RESET_ALPHA,
|
||||
"RESET_TRANSFORM" = RESET_TRANSFORM,
|
||||
"NO_CLIENT_COLOR" = NO_CLIENT_COLOR,
|
||||
"KEEP_TOGETHER" = KEEP_TOGETHER,
|
||||
"KEEP_APART" = KEEP_APART,
|
||||
"PLANE_MASTER" = PLANE_MASTER,
|
||||
"TILE_BOUND" = TILE_BOUND,
|
||||
"PIXEL_SCALE" = PIXEL_SCALE
|
||||
),
|
||||
"area_flags" = list(
|
||||
"ABDUCTOR_PROOF" = ABDUCTOR_PROOF,
|
||||
"BLOBS_ALLOWED" = BLOBS_ALLOWED,
|
||||
"BLOCK_SUICIDE" = BLOCK_SUICIDE,
|
||||
"CULT_PERMITTED" = CULT_PERMITTED,
|
||||
"FLORA_ALLOWED" = FLORA_ALLOWED,
|
||||
"HIDDEN_AREA" = HIDDEN_AREA,
|
||||
"MEGAFAUNA_SPAWN_ALLOWED" = MEGAFAUNA_SPAWN_ALLOWED,
|
||||
"MOB_SPAWN_ALLOWED" = MOB_SPAWN_ALLOWED,
|
||||
"NO_ALERTS" = NO_ALERTS,
|
||||
"NOTELEPORT" = NOTELEPORT,
|
||||
"CAVES_ALLOWED" = CAVES_ALLOWED,
|
||||
"UNIQUE_AREA" = UNIQUE_AREA,
|
||||
"VALID_TERRITORY" = VALID_TERRITORY,
|
||||
"XENOBIOLOGY_COMPATIBLE" = XENOBIOLOGY_COMPATIBLE,
|
||||
"NO_ALERTS" = NO_ALERTS,
|
||||
) ,
|
||||
"sight" = list(
|
||||
"SEE_INFRA" = SEE_INFRA,
|
||||
"SEE_SELF" = SEE_SELF,
|
||||
"SEE_MOBS" = SEE_MOBS,
|
||||
"SEE_OBJS" = SEE_OBJS,
|
||||
"SEE_TURFS" = SEE_TURFS,
|
||||
"SEE_PIXELS" = SEE_PIXELS,
|
||||
"SEE_THRU" = SEE_THRU,
|
||||
"SEE_BLACKNESS" = SEE_BLACKNESS,
|
||||
"BLIND" = BLIND
|
||||
),
|
||||
"obj_flags" = list(
|
||||
"EMAGGED" = EMAGGED,
|
||||
"IN_USE" = IN_USE,
|
||||
"CAN_BE_HIT" = CAN_BE_HIT,
|
||||
"BEING_SHOCKED" = BEING_SHOCKED,
|
||||
"DANGEROUS_POSSESSION" = DANGEROUS_POSSESSION,
|
||||
"ON_BLUEPRINTS" = ON_BLUEPRINTS,
|
||||
"UNIQUE_RENAME" = UNIQUE_RENAME,
|
||||
"USES_TGUI" = USES_TGUI,
|
||||
"FROZEN" = FROZEN,
|
||||
"SHOVABLE_ONTO" = SHOVABLE_ONTO,
|
||||
"BLOCK_Z_OUT_DOWN" = BLOCK_Z_OUT_DOWN,
|
||||
"BLOCK_Z_OUT_UP" = BLOCK_Z_OUT_UP,
|
||||
"BLOCK_Z_IN_DOWN" = BLOCK_Z_IN_DOWN,
|
||||
"BLOCK_Z_IN_UP" = BLOCK_Z_IN_UP,
|
||||
"EXAMINE_SKIP" = EXAMINE_SKIP
|
||||
),
|
||||
"datum_flags" = list(
|
||||
"DF_USE_TAG" = DF_USE_TAG,
|
||||
"DF_VAR_EDITED" = DF_VAR_EDITED,
|
||||
"DF_ISPROCESSING" = DF_ISPROCESSING,
|
||||
),
|
||||
"item_flags" = list(
|
||||
"BEING_REMOVED" = BEING_REMOVED,
|
||||
"IN_INVENTORY" = IN_INVENTORY,
|
||||
"FORCE_STRING_OVERRIDE" = FORCE_STRING_OVERRIDE,
|
||||
"NEEDS_PERMIT" = NEEDS_PERMIT,
|
||||
"SLOWS_WHILE_IN_HAND" = SLOWS_WHILE_IN_HAND,
|
||||
"NO_MAT_REDEMPTION" = NO_MAT_REDEMPTION,
|
||||
"DROPDEL" = DROPDEL,
|
||||
"NOBLUDGEON" = NOBLUDGEON,
|
||||
"ABSTRACT" = ABSTRACT,
|
||||
"IN_STORAGE" = IN_STORAGE,
|
||||
"ITEM_CAN_BLOCK" = ITEM_CAN_BLOCK,
|
||||
"ITEM_CAN_PARRY" = ITEM_CAN_PARRY
|
||||
),
|
||||
"admin_flags" = list(
|
||||
"BUILDMODE" = R_BUILDMODE,
|
||||
"ADMIN" = R_ADMIN,
|
||||
"BAN" = R_BAN,
|
||||
"FUN" = R_FUN,
|
||||
"SERVER" = R_SERVER,
|
||||
"DEBUG" = R_DEBUG,
|
||||
"POSSESS" = R_POSSESS,
|
||||
"PERMISSIONS" = R_PERMISSIONS,
|
||||
"STEALTH" = R_STEALTH,
|
||||
"POLL" = R_POLL,
|
||||
"VAREDIT" = R_VAREDIT,
|
||||
"SOUNDS" = R_SOUNDS,
|
||||
"SPAWN" = R_SPAWN,
|
||||
"AUTOLOGIN" = R_AUTOLOGIN,
|
||||
"DBRANKS" = R_DBRANKS,
|
||||
"SENSITIVE" = R_SENSITIVE
|
||||
),
|
||||
"interaction_flags_atom" = list(
|
||||
"INTERACT_ATOM_REQUIRES_ANCHORED" = INTERACT_ATOM_REQUIRES_ANCHORED,
|
||||
"INTERACT_ATOM_ATTACK_HAND" = INTERACT_ATOM_ATTACK_HAND,
|
||||
"INTERACT_ATOM_UI_INTERACT" = INTERACT_ATOM_UI_INTERACT,
|
||||
"INTERACT_ATOM_REQUIRES_DEXTERITY" = INTERACT_ATOM_REQUIRES_DEXTERITY,
|
||||
"INTERACT_ATOM_IGNORE_INCAPACITATED" = INTERACT_ATOM_IGNORE_INCAPACITATED,
|
||||
"INTERACT_ATOM_IGNORE_RESTRAINED" = INTERACT_ATOM_IGNORE_RESTRAINED,
|
||||
"INTERACT_ATOM_CHECK_GRAB" = INTERACT_ATOM_CHECK_GRAB,
|
||||
"INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND" = INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND,
|
||||
"INTERACT_ATOM_NO_FINGERPRINT_INTERACT" = INTERACT_ATOM_NO_FINGERPRINT_INTERACT
|
||||
),
|
||||
"interaction_flags_machine" = list(
|
||||
"INTERACT_MACHINE_OPEN" = INTERACT_MACHINE_OPEN,
|
||||
"INTERACT_MACHINE_OFFLINE" = INTERACT_MACHINE_OFFLINE,
|
||||
"INTERACT_MACHINE_WIRES_IF_OPEN" = INTERACT_MACHINE_WIRES_IF_OPEN,
|
||||
"INTERACT_MACHINE_ALLOW_SILICON" = INTERACT_MACHINE_ALLOW_SILICON,
|
||||
"INTERACT_MACHINE_OPEN_SILICON" = INTERACT_MACHINE_OPEN_SILICON,
|
||||
"INTERACT_MACHINE_REQUIRES_SILICON" = INTERACT_MACHINE_REQUIRES_SILICON,
|
||||
"INTERACT_MACHINE_SET_MACHINE" = INTERACT_MACHINE_SET_MACHINE
|
||||
),
|
||||
"interaction_flags_item" = list(
|
||||
"INTERACT_ITEM_ATTACK_HAND_PICKUP" = INTERACT_ITEM_ATTACK_HAND_PICKUP,
|
||||
),
|
||||
"pass_flags" = list(
|
||||
"PASSTABLE" = PASSTABLE,
|
||||
"PASSGLASS" = PASSGLASS,
|
||||
"PASSGRILLE" = PASSGRILLE,
|
||||
"PASSBLOB" = PASSBLOB,
|
||||
"PASSMOB" = PASSMOB,
|
||||
"PASSCLOSEDTURF" = PASSCLOSEDTURF,
|
||||
"LETPASSTHROW" = LETPASSTHROW
|
||||
),
|
||||
"movement_type" = list(
|
||||
"GROUND" = GROUND,
|
||||
"FLYING" = FLYING,
|
||||
"VENTCRAWLING" = VENTCRAWLING,
|
||||
"FLOATING" = FLOATING,
|
||||
"PHASING" = PHASING
|
||||
),
|
||||
"resistance_flags" = list(
|
||||
"LAVA_PROOF" = LAVA_PROOF,
|
||||
"FIRE_PROOF" = FIRE_PROOF,
|
||||
"FLAMMABLE" = FLAMMABLE,
|
||||
"ON_FIRE" = ON_FIRE,
|
||||
"UNACIDABLE" = UNACIDABLE,
|
||||
"ACID_PROOF" = ACID_PROOF,
|
||||
"INDESTRUCTIBLE" = INDESTRUCTIBLE,
|
||||
"FREEZE_PROOF" = FREEZE_PROOF,
|
||||
"GOLIATH_RESISTANCE" = GOLIATH_RESISTANCE,
|
||||
"GOLIATH_WEAKNESS" = GOLIATH_WEAKNESS
|
||||
),
|
||||
"flags_1" = list(
|
||||
"NOJAUNT_1" = NOJAUNT_1,
|
||||
"UNUSED_RESERVATION_TURF_1" = UNUSED_RESERVATION_TURF_1,
|
||||
"CAN_BE_DIRTY_1" = CAN_BE_DIRTY_1,
|
||||
"HEAR_1" = HEAR_1,
|
||||
"DEFAULT_RICOCHET_1" = DEFAULT_RICOCHET_1,
|
||||
"CONDUCT_1" = CONDUCT_1,
|
||||
"NO_LAVA_GEN_1" = NO_LAVA_GEN_1,
|
||||
"NODECONSTRUCT_1" = NODECONSTRUCT_1,
|
||||
"OVERLAY_QUEUED_1" = OVERLAY_QUEUED_1,
|
||||
"ON_BORDER_1" = ON_BORDER_1,
|
||||
"NO_RUINS_1" = NO_RUINS_1,
|
||||
"PREVENT_CLICK_UNDER_1" = PREVENT_CLICK_UNDER_1,
|
||||
"HOLOGRAM_1" = HOLOGRAM_1,
|
||||
"SHOCKED_1" = SHOCKED_1,
|
||||
"INITIALIZED_1" = INITIALIZED_1,
|
||||
"NO_SCREENTIPS_1" = NO_SCREENTIPS_1,
|
||||
"ADMIN_SPAWNED_1" = ADMIN_SPAWNED_1,
|
||||
"BLOCK_FACE_ATOM_1" = BLOCK_FACE_ATOM_1,
|
||||
"PREVENT_CONTENTS_EXPLOSION_1" = PREVENT_CONTENTS_EXPLOSION_1
|
||||
),
|
||||
"flags_ricochet" = list(
|
||||
"RICOCHET_SHINY" = RICOCHET_SHINY,
|
||||
"RICOCHET_HARD" = RICOCHET_HARD
|
||||
),
|
||||
"clothing_flags" = list(
|
||||
"LAVAPROTECT" = LAVAPROTECT,
|
||||
"STOPSPRESSUREDAMAGE" = STOPSPRESSUREDAMAGE,
|
||||
"BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT,
|
||||
"ALLOWINTERNALS" = ALLOWINTERNALS,
|
||||
"NOSLIP" = NOSLIP,
|
||||
"THICKMATERIAL" = THICKMATERIAL,
|
||||
"VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE,
|
||||
"VOICEBOX_DISABLED" = VOICEBOX_DISABLED,
|
||||
"IGNORE_HAT_TOSS" = IGNORE_HAT_TOSS,
|
||||
"SCAN_REAGENTS" = SCAN_REAGENTS
|
||||
),
|
||||
"zap_flags" = list(
|
||||
"ZAP_MOB_DAMAGE" = ZAP_MOB_DAMAGE,
|
||||
"ZAP_OBJ_DAMAGE" = ZAP_OBJ_DAMAGE,
|
||||
"ZAP_MOB_STUN" = ZAP_MOB_STUN,
|
||||
"ZAP_ALLOW_DUPLICATES" = ZAP_ALLOW_DUPLICATES,
|
||||
"ZAP_MACHINE_EXPLOSIVE" = ZAP_MACHINE_EXPLOSIVE,
|
||||
),
|
||||
"smooth" = list(
|
||||
"SMOOTH_TRUE" = SMOOTH_TRUE,
|
||||
"SMOOTH_MORE" = SMOOTH_MORE,
|
||||
"SMOOTH_DIAGONAL" = SMOOTH_DIAGONAL,
|
||||
"SMOOTH_BORDER" = SMOOTH_BORDER,
|
||||
"SMOOTH_QUEUED" = SMOOTH_QUEUED,
|
||||
),
|
||||
"reagents_holder_flags" = list(
|
||||
"INJECTABLE" = INJECTABLE,
|
||||
"DRAWABLE" = DRAWABLE,
|
||||
"REFILLABLE" = REFILLABLE,
|
||||
"DRAINABLE" = DRAINABLE,
|
||||
"TRANSPARENT" = TRANSPARENT,
|
||||
"AMOUNT_VISIBLE" = AMOUNT_VISIBLE,
|
||||
"NO_REACT" = NO_REACT,
|
||||
),
|
||||
"car_traits" = list(
|
||||
"CAN_KIDNAP" = CAN_KIDNAP,
|
||||
),
|
||||
"rad_flags" = list(
|
||||
"RAD_PROTECT_CONTENTS" = RAD_PROTECT_CONTENTS,
|
||||
"RAD_NO_CONTAMINATE" = RAD_NO_CONTAMINATE,
|
||||
),
|
||||
"disease_flags" = list(
|
||||
"CURABLE" = CURABLE,
|
||||
"CAN_CARRY" = CAN_CARRY,
|
||||
"CAN_RESIST" = CAN_RESIST
|
||||
),
|
||||
"chemical_flags" = list(
|
||||
"REAGENT_DEAD_PROCESS" = REAGENT_DEAD_PROCESS,
|
||||
"REAGENT_DONOTSPLIT" = REAGENT_DONOTSPLIT,
|
||||
"REAGENT_ONLYINVERSE" = REAGENT_ONLYINVERSE,
|
||||
"REAGENT_ONMOBMERGE" = REAGENT_ONMOBMERGE,
|
||||
"REAGENT_INVISIBLE" = REAGENT_INVISIBLE,
|
||||
"REAGENT_FORCEONNEW" = REAGENT_FORCEONNEW,
|
||||
"REAGENT_SNEAKYNAME" = REAGENT_SNEAKYNAME,
|
||||
"REAGENT_SPLITRETAINVOL" = REAGENT_SPLITRETAINVOL,
|
||||
"REAGENT_ORGANIC_PROCESS" = REAGENT_ORGANIC_PROCESS,
|
||||
"REAGENT_ROBOTIC_PROCESS" = REAGENT_ROBOTIC_PROCESS
|
||||
),
|
||||
"clear_conversion" = list(
|
||||
"REACTION_CLEAR_IMPURE" = REACTION_CLEAR_IMPURE,
|
||||
"REACTION_CLEAR_INVERSE" = REACTION_CLEAR_INVERSE
|
||||
),
|
||||
"organ_flags" = list(
|
||||
"ORGAN_SYNTHETIC" = ORGAN_SYNTHETIC,
|
||||
"ORGAN_FROZEN" = ORGAN_FROZEN,
|
||||
"ORGAN_FAILING" = ORGAN_FAILING,
|
||||
"ORGAN_EXTERNAL" = ORGAN_EXTERNAL,
|
||||
"ORGAN_VITAL" = ORGAN_VITAL,
|
||||
"ORGAN_NO_SPOIL" = ORGAN_NO_SPOIL
|
||||
),
|
||||
"genital_flags" = list(
|
||||
"GENITAL_BLACKLISTED" = GENITAL_BLACKLISTED,
|
||||
"GENITAL_INTERNAL" = GENITAL_INTERNAL,
|
||||
"GENITAL_HIDDEN" = GENITAL_HIDDEN,
|
||||
"GENITAL_THROUGH_CLOTHES" = GENITAL_THROUGH_CLOTHES,
|
||||
"GENITAL_FUID_PRODUCTION" = GENITAL_FUID_PRODUCTION,
|
||||
"CAN_MASTURBATE_WITH" = CAN_MASTURBATE_WITH,
|
||||
"MASTURBATE_LINKED_ORGAN" = MASTURBATE_LINKED_ORGAN,
|
||||
"CAN_CLIMAX_WITH" = CAN_CLIMAX_WITH
|
||||
GLOBAL_LIST_INIT(bitfields, generate_bitfields())
|
||||
|
||||
),
|
||||
"mob_biotypes" = list (
|
||||
"MOB_ORGANIC" = MOB_ORGANIC,
|
||||
"MOB_MINERAL" = MOB_MINERAL,
|
||||
"MOB_ROBOTIC" = MOB_ROBOTIC,
|
||||
"MOB_UNDEAD" = MOB_UNDEAD,
|
||||
"MOB_HUMANOID" = MOB_HUMANOID,
|
||||
"MOB_BUG" = MOB_BUG,
|
||||
"MOB_BEAST" = MOB_BEAST,
|
||||
"MOB_EPIC" = MOB_EPIC,
|
||||
"MOB_REPTILE" = MOB_REPTILE,
|
||||
"MOB_SPIRIT" = MOB_SPIRIT
|
||||
),
|
||||
"mobility_flags" = list(
|
||||
"MOBILITY_MOVE" = MOBILITY_MOVE,
|
||||
"MOBILITY_STAND" = MOBILITY_STAND,
|
||||
"MOBILITY_PICKUP" = MOBILITY_PICKUP,
|
||||
"MOBILITY_USE" = MOBILITY_USE,
|
||||
"MOBILITY_UI" = MOBILITY_UI,
|
||||
"MOBILITY_STORAGE" = MOBILITY_STORAGE,
|
||||
"MOBILITY_PULL" = MOBILITY_PULL,
|
||||
"MOBILITY_HOLD" = MOBILITY_HOLD,
|
||||
"MOBILITY_RESIST" = MOBILITY_RESIST
|
||||
),
|
||||
"combat_flags" = list(
|
||||
"COMBAT_FLAG_SPRINT_TOGGLED" = COMBAT_FLAG_SPRINT_TOGGLED,
|
||||
"COMBAT_FLAG_SPRINT_ACTIVE" = COMBAT_FLAG_SPRINT_ACTIVE,
|
||||
"COMBAT_FLAG_ATTEMPTING_CRAWL" = COMBAT_FLAG_ATTEMPTING_CRAWL,
|
||||
"COMBAT_FLAG_HARD_STAMCRIT" = COMBAT_FLAG_HARD_STAMCRIT,
|
||||
"COMBAT_FLAG_INTENTIONALLY_RESTING" = COMBAT_FLAG_INTENTIONALLY_RESTING,
|
||||
"COMBAT_FLAG_RESISTING_REST" = COMBAT_FLAG_RESISTING_REST,
|
||||
"COMBAT_FLAG_SPRINT_FORCED" = COMBAT_FLAG_SPRINT_FORCED
|
||||
),
|
||||
"shield_flags" = list(
|
||||
"SHIELD_TRANSPARENT" = SHIELD_TRANSPARENT,
|
||||
"SHIELD_ENERGY_WEAK" = SHIELD_ENERGY_WEAK,
|
||||
"SHIELD_KINETIC_WEAK" = SHIELD_KINETIC_WEAK,
|
||||
"SHIELD_KINETIC_STRONG" = SHIELD_KINETIC_STRONG,
|
||||
"SHIELD_ENERGY_STRONG" = SHIELD_ENERGY_STRONG,
|
||||
"SHIELD_DISABLER_DISRUPTED" = SHIELD_DISABLER_DISRUPTED,
|
||||
"SHIELD_NO_RANGED" = SHIELD_NO_RANGED,
|
||||
"SHIELD_NO_MELEE" = SHIELD_NO_MELEE,
|
||||
"SHIELD_CAN_BASH" = SHIELD_CAN_BASH,
|
||||
"SHIELD_BASH_WALL_KNOCKDOWN" = SHIELD_BASH_WALL_KNOCKDOWN,
|
||||
"SHIELD_BASH_ALWAYS_KNOCKDOWN" = SHIELD_BASH_ALWAYS_KNOCKDOWN,
|
||||
"SHIELD_BASH_WALL_DISARM" = SHIELD_BASH_WALL_DISARM,
|
||||
"SHIELD_BASH_ALWAYS_DISARM" = SHIELD_BASH_ALWAYS_DISARM,
|
||||
"SHIELD_BASH_GROUND_SLAM" = SHIELD_BASH_GROUND_SLAM,
|
||||
"SHIELD_BASH_GROUND_SLAM_DISARM" = SHIELD_BASH_GROUND_SLAM_DISARM
|
||||
),
|
||||
"storage_flags" = list(
|
||||
"STORAGE_LIMIT_MAX_ITEMS" = STORAGE_LIMIT_MAX_ITEMS,
|
||||
"STORAGE_LIMIT_MAX_W_CLASS" = STORAGE_LIMIT_MAX_W_CLASS,
|
||||
"STORAGE_LIMIT_COMBINED_W_CLASS" = STORAGE_LIMIT_COMBINED_W_CLASS,
|
||||
"STORAGE_LIMIT_VOLUME" = STORAGE_LIMIT_VOLUME
|
||||
),
|
||||
"mutantrace_variation" = list(
|
||||
"STYLE_DIGITIGRADE" = STYLE_DIGITIGRADE,
|
||||
"STYLE_MUZZLE" = STYLE_MUZZLE,
|
||||
"STYLE_SNEK_TAURIC" = STYLE_SNEK_TAURIC,
|
||||
"STYLE_PAW_TAURIC" = STYLE_PAW_TAURIC,
|
||||
"STYLE_HOOF_TAURIC" = STYLE_HOOF_TAURIC,
|
||||
"STYLE_NO_ANTHRO_ICON" = STYLE_NO_ANTHRO_ICON,
|
||||
"USE_SNEK_CLIP_MASK" = USE_SNEK_CLIP_MASK,
|
||||
"USE_QUADRUPED_CLIP_MASK" = USE_QUADRUPED_CLIP_MASK
|
||||
),
|
||||
"vis_flags" = list(
|
||||
"VIS_INHERIT_ICON" = VIS_INHERIT_ICON,
|
||||
"VIS_INHERIT_ICON_STATE" = VIS_INHERIT_ICON_STATE,
|
||||
"VIS_INHERIT_DIR" = VIS_INHERIT_DIR,
|
||||
"VIS_INHERIT_LAYER" = VIS_INHERIT_LAYER,
|
||||
"VIS_INHERIT_PLANE" = VIS_INHERIT_PLANE,
|
||||
"VIS_INHERIT_ID" = VIS_INHERIT_ID,
|
||||
"VIS_UNDERLAY" = VIS_UNDERLAY,
|
||||
"VIS_HIDE" = VIS_HIDE
|
||||
)
|
||||
))
|
||||
/// Specifies a bitfield for smarter debugging
|
||||
/datum/bitfield
|
||||
/// The variable name that contains the bitfield
|
||||
var/variable
|
||||
|
||||
/// An associative list of the readable flag and its true value
|
||||
var/list/flags
|
||||
|
||||
/// Turns /datum/bitfield subtypes into a list for use in debugging
|
||||
/proc/generate_bitfields()
|
||||
var/list/bitfields = list()
|
||||
for (var/_bitfield in subtypesof(/datum/bitfield))
|
||||
var/datum/bitfield/bitfield = new _bitfield
|
||||
bitfields[bitfield.variable] = bitfield.flags
|
||||
return bitfields
|
||||
|
||||
DEFINE_BITFIELD(admin_flags, list(
|
||||
"ADMIN" = R_ADMIN,
|
||||
"AUTOLOGIN" = R_AUTOLOGIN,
|
||||
"BAN" = R_BAN,
|
||||
"BUILDMODE" = R_BUILDMODE,
|
||||
"DBRANKS" = R_DBRANKS,
|
||||
"DEBUG" = R_DEBUG,
|
||||
"FUN" = R_FUN,
|
||||
"PERMISSIONS" = R_PERMISSIONS,
|
||||
"POLL" = R_POLL,
|
||||
"POSSESS" = R_POSSESS,
|
||||
"SENSITIVE" = R_SENSITIVE,
|
||||
"SERVER" = R_SERVER,
|
||||
"SOUNDS" = R_SOUNDS,
|
||||
"SPAWN" = R_SPAWN,
|
||||
"STEALTH" = R_STEALTH,
|
||||
"VAREDIT" = R_VAREDIT,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(appearance_flags, list(
|
||||
"KEEP_APART" = KEEP_APART,
|
||||
"KEEP_TOGETHER" = KEEP_TOGETHER,
|
||||
"LONG_GLIDE" = LONG_GLIDE,
|
||||
"NO_CLIENT_COLOR" = NO_CLIENT_COLOR,
|
||||
"PASS_MOUSE" = PASS_MOUSE,
|
||||
"PIXEL_SCALE" = PIXEL_SCALE,
|
||||
"PLANE_MASTER" = PLANE_MASTER,
|
||||
"RESET_ALPHA" = RESET_ALPHA,
|
||||
"RESET_COLOR" = RESET_COLOR,
|
||||
"RESET_TRANSFORM" = RESET_TRANSFORM,
|
||||
"TILE_BOUND" = TILE_BOUND,
|
||||
"TILE_MOVER" = TILE_MOVER,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(area_flags, list(
|
||||
"ABDUCTOR_PROOF" = ABDUCTOR_PROOF,
|
||||
"BLOBS_ALLOWED" = BLOBS_ALLOWED,
|
||||
"BLOCK_SUICIDE" = BLOCK_SUICIDE,
|
||||
"CULT_PERMITTED" = CULT_PERMITTED,
|
||||
"FLORA_ALLOWED" = FLORA_ALLOWED,
|
||||
"HIDDEN_AREA" = HIDDEN_AREA,
|
||||
"MEGAFAUNA_SPAWN_ALLOWED" = MEGAFAUNA_SPAWN_ALLOWED,
|
||||
"MOB_SPAWN_ALLOWED" = MOB_SPAWN_ALLOWED,
|
||||
"NO_ALERTS" = NO_ALERTS,
|
||||
"NOTELEPORT" = NOTELEPORT,
|
||||
"CAVES_ALLOWED" = CAVES_ALLOWED,
|
||||
"UNIQUE_AREA" = UNIQUE_AREA,
|
||||
"VALID_TERRITORY" = VALID_TERRITORY,
|
||||
"XENOBIOLOGY_COMPATIBLE" = XENOBIOLOGY_COMPATIBLE,
|
||||
"NO_ALERTS" = NO_ALERTS,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(car_traits, list(
|
||||
"CAN_KIDNAP" = CAN_KIDNAP,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(chemical_flags, list(
|
||||
"REAGENT_DEAD_PROCESS" = REAGENT_DEAD_PROCESS,
|
||||
"REAGENT_DONOTSPLIT" = REAGENT_DONOTSPLIT,
|
||||
"REAGENT_FORCEONNEW" = REAGENT_FORCEONNEW,
|
||||
"REAGENT_INVISIBLE" = REAGENT_INVISIBLE,
|
||||
"REAGENT_ONLYINVERSE" = REAGENT_ONLYINVERSE,
|
||||
"REAGENT_ONMOBMERGE" = REAGENT_ONMOBMERGE,
|
||||
"REAGENT_ORGANIC_PROCESS" = REAGENT_ORGANIC_PROCESS,
|
||||
"REAGENT_ROBOTIC_PROCESS" = REAGENT_ROBOTIC_PROCESS,
|
||||
"REAGENT_SNEAKYNAME" = REAGENT_SNEAKYNAME,
|
||||
"REAGENT_SPLITRETAINVOL" = REAGENT_SPLITRETAINVOL,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(clear_conversion, list(
|
||||
"REACTION_CLEAR_IMPURE" = REACTION_CLEAR_IMPURE,
|
||||
"REACTION_CLEAR_INVERSE" = REACTION_CLEAR_INVERSE
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(clothing_flags, list(
|
||||
"ALLOWINTERNALS" = ALLOWINTERNALS,
|
||||
"BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT,
|
||||
"IGNORE_HAT_TOSS" = IGNORE_HAT_TOSS,
|
||||
"LAVAPROTECT" = LAVAPROTECT,
|
||||
"NOSLIP" = NOSLIP,
|
||||
"SCAN_REAGENTS" = SCAN_REAGENTS,
|
||||
"STOPSPRESSUREDAMAGE" = STOPSPRESSUREDAMAGE,
|
||||
"THICKMATERIAL" = THICKMATERIAL,
|
||||
"VOICEBOX_DISABLED" = VOICEBOX_DISABLED,
|
||||
"VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(combat_flags, list(
|
||||
"COMBAT_FLAG_ATTEMPTING_CRAWL" = COMBAT_FLAG_ATTEMPTING_CRAWL,
|
||||
"COMBAT_FLAG_HARD_STAMCRIT" = COMBAT_FLAG_HARD_STAMCRIT,
|
||||
"COMBAT_FLAG_INTENTIONALLY_RESTING" = COMBAT_FLAG_INTENTIONALLY_RESTING,
|
||||
"COMBAT_FLAG_RESISTING_REST" = COMBAT_FLAG_RESISTING_REST,
|
||||
"COMBAT_FLAG_SPRINT_ACTIVE" = COMBAT_FLAG_SPRINT_ACTIVE,
|
||||
"COMBAT_FLAG_SPRINT_FORCED" = COMBAT_FLAG_SPRINT_FORCED,
|
||||
"COMBAT_FLAG_SPRINT_TOGGLED" = COMBAT_FLAG_SPRINT_TOGGLED,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(datum_flags, list(
|
||||
"DF_USE_TAG" = DF_USE_TAG,
|
||||
"DF_VAR_EDITED" = DF_VAR_EDITED,
|
||||
"DF_ISPROCESSING" = DF_ISPROCESSING,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(disease_flags, list(
|
||||
"CAN_CARRY" = CAN_CARRY,
|
||||
"CAN_RESIST" = CAN_RESIST,
|
||||
"CURABLE" = CURABLE,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(flags_1, list(
|
||||
"ADMIN_SPAWNED_1" = ADMIN_SPAWNED_1,
|
||||
"BLOCK_FACE_ATOM_1" = BLOCK_FACE_ATOM_1,
|
||||
"CAN_BE_DIRTY_1" = CAN_BE_DIRTY_1,
|
||||
"CONDUCT_1" = CONDUCT_1,
|
||||
"DEFAULT_RICOCHET_1" = DEFAULT_RICOCHET_1,
|
||||
"HEAR_1" = HEAR_1,
|
||||
"HOLOGRAM_1" = HOLOGRAM_1,
|
||||
"INITIALIZED_1" = INITIALIZED_1,
|
||||
"NODECONSTRUCT_1" = NODECONSTRUCT_1,
|
||||
"NOJAUNT_1" = NOJAUNT_1,
|
||||
"NO_LAVA_GEN_1" = NO_LAVA_GEN_1,
|
||||
"NO_RUINS_1" = NO_RUINS_1,
|
||||
"NO_SCREENTIPS_1" = NO_SCREENTIPS_1,
|
||||
"OVERLAY_QUEUED_1" = OVERLAY_QUEUED_1,
|
||||
"ON_BORDER_1" = ON_BORDER_1,
|
||||
"PREVENT_CLICK_UNDER_1" = PREVENT_CLICK_UNDER_1,
|
||||
"PREVENT_CONTENTS_EXPLOSION_1" = PREVENT_CONTENTS_EXPLOSION_1,
|
||||
"SHOCKED_1" = SHOCKED_1,
|
||||
"UNUSED_RESERVATION_TURF_1" = UNUSED_RESERVATION_TURF_1,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(flags_ricochet, list(
|
||||
"RICOCHET_SHINY" = RICOCHET_SHINY,
|
||||
"RICOCHET_HARD" = RICOCHET_HARD
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(genital_flags, list(
|
||||
"CAN_CLIMAX_WITH" = CAN_CLIMAX_WITH,
|
||||
"CAN_MASTURBATE_WITH" = CAN_MASTURBATE_WITH,
|
||||
"GENITAL_BLACKLISTED" = GENITAL_BLACKLISTED,
|
||||
"GENITAL_FUID_PRODUCTION" = GENITAL_FUID_PRODUCTION,
|
||||
"GENITAL_HIDDEN" = GENITAL_HIDDEN,
|
||||
"GENITAL_INTERNAL" = GENITAL_INTERNAL,
|
||||
"GENITAL_THROUGH_CLOTHES" = GENITAL_THROUGH_CLOTHES,
|
||||
"MASTURBATE_LINKED_ORGAN" = MASTURBATE_LINKED_ORGAN,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(interaction_flags_atom, list(
|
||||
"INTERACT_ATOM_ATTACK_HAND" = INTERACT_ATOM_ATTACK_HAND,
|
||||
"INTERACT_ATOM_CHECK_GRAB" = INTERACT_ATOM_CHECK_GRAB,
|
||||
"INTERACT_ATOM_IGNORE_INCAPACITATED" = INTERACT_ATOM_IGNORE_INCAPACITATED,
|
||||
"INTERACT_ATOM_IGNORE_RESTRAINED" = INTERACT_ATOM_IGNORE_RESTRAINED,
|
||||
"INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND" = INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND,
|
||||
"INTERACT_ATOM_NO_FINGERPRINT_INTERACT" = INTERACT_ATOM_NO_FINGERPRINT_INTERACT,
|
||||
"INTERACT_ATOM_REQUIRES_ANCHORED" = INTERACT_ATOM_REQUIRES_ANCHORED,
|
||||
"INTERACT_ATOM_REQUIRES_DEXTERITY" = INTERACT_ATOM_REQUIRES_DEXTERITY,
|
||||
"INTERACT_ATOM_UI_INTERACT" = INTERACT_ATOM_UI_INTERACT,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(interaction_flags_machine, list(
|
||||
"INTERACT_MACHINE_ALLOW_SILICON" = INTERACT_MACHINE_ALLOW_SILICON,
|
||||
"INTERACT_MACHINE_OFFLINE" = INTERACT_MACHINE_OFFLINE,
|
||||
"INTERACT_MACHINE_OPEN" = INTERACT_MACHINE_OPEN,
|
||||
"INTERACT_MACHINE_OPEN_SILICON" = INTERACT_MACHINE_OPEN_SILICON,
|
||||
"INTERACT_MACHINE_REQUIRES_SILICON" = INTERACT_MACHINE_REQUIRES_SILICON,
|
||||
"INTERACT_MACHINE_SET_MACHINE" = INTERACT_MACHINE_SET_MACHINE,
|
||||
"INTERACT_MACHINE_WIRES_IF_OPEN" = INTERACT_MACHINE_WIRES_IF_OPEN,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(interaction_flags_item, list(
|
||||
"INTERACT_ITEM_ATTACK_HAND_PICKUP" = INTERACT_ITEM_ATTACK_HAND_PICKUP,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(item_flags, list(
|
||||
"ABSTRACT" = ABSTRACT,
|
||||
"BEING_REMOVED" = BEING_REMOVED,
|
||||
"DROPDEL" = DROPDEL,
|
||||
"FORCE_STRING_OVERRIDE" = FORCE_STRING_OVERRIDE,
|
||||
"IN_INVENTORY" = IN_INVENTORY,
|
||||
"IN_STORAGE" = IN_STORAGE,
|
||||
"ITEM_CAN_BLOCK" = ITEM_CAN_BLOCK,
|
||||
"ITEM_CAN_PARRY" = ITEM_CAN_PARRY,
|
||||
"NEEDS_PERMIT" = NEEDS_PERMIT,
|
||||
"NOBLUDGEON" = NOBLUDGEON,
|
||||
"NO_MAT_REDEMPTION" = NO_MAT_REDEMPTION,
|
||||
"SLOWS_WHILE_IN_HAND" = SLOWS_WHILE_IN_HAND,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(mob_biotypes, list(
|
||||
"MOB_BEAST" = MOB_BEAST,
|
||||
"MOB_BUG" = MOB_BUG,
|
||||
"MOB_EPIC" = MOB_EPIC,
|
||||
"MOB_HUMANOID" = MOB_HUMANOID,
|
||||
"MOB_MINERAL" = MOB_MINERAL,
|
||||
"MOB_ORGANIC" = MOB_ORGANIC,
|
||||
"MOB_REPTILE" = MOB_REPTILE,
|
||||
"MOB_ROBOTIC" = MOB_ROBOTIC,
|
||||
"MOB_SPIRIT" = MOB_SPIRIT,
|
||||
"MOB_UNDEAD" = MOB_UNDEAD,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(mobility_flags, list(
|
||||
"MOBILITY_HOLD" = MOBILITY_HOLD,
|
||||
"MOBILITY_MOVE" = MOBILITY_MOVE,
|
||||
"MOBILITY_PICKUP" = MOBILITY_PICKUP,
|
||||
"MOBILITY_PULL" = MOBILITY_PULL,
|
||||
"MOBILITY_RESIST" = MOBILITY_RESIST,
|
||||
"MOBILITY_STAND" = MOBILITY_STAND,
|
||||
"MOBILITY_STORAGE" = MOBILITY_STORAGE,
|
||||
"MOBILITY_UI" = MOBILITY_UI,
|
||||
"MOBILITY_USE" = MOBILITY_USE,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(movement_type, list(
|
||||
"FLOATING" = FLOATING,
|
||||
"FLYING" = FLYING,
|
||||
"GROUND" = GROUND,
|
||||
"PHASING" = PHASING,
|
||||
"VENTCRAWLING" = VENTCRAWLING,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(mutantrace_variation, list(
|
||||
"STYLE_DIGITIGRADE" = STYLE_DIGITIGRADE,
|
||||
"STYLE_HOOF_TAURIC" = STYLE_HOOF_TAURIC,
|
||||
"STYLE_MUZZLE" = STYLE_MUZZLE,
|
||||
"STYLE_NO_ANTHRO_ICON" = STYLE_NO_ANTHRO_ICON,
|
||||
"STYLE_PAW_TAURIC" = STYLE_PAW_TAURIC,
|
||||
"STYLE_SNEK_TAURIC" = STYLE_SNEK_TAURIC,
|
||||
"USE_SNEK_CLIP_MASK" = USE_SNEK_CLIP_MASK,
|
||||
"USE_QUADRUPED_CLIP_MASK" = USE_QUADRUPED_CLIP_MASK,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(obj_flags, list(
|
||||
"BEING_SHOCKED" = BEING_SHOCKED,
|
||||
"BLOCK_Z_IN_DOWN" = BLOCK_Z_IN_DOWN,
|
||||
"BLOCK_Z_IN_UP" = BLOCK_Z_IN_UP,
|
||||
"BLOCK_Z_OUT_DOWN" = BLOCK_Z_OUT_DOWN,
|
||||
"BLOCK_Z_OUT_UP" = BLOCK_Z_OUT_UP,
|
||||
"CAN_BE_HIT" = CAN_BE_HIT,
|
||||
"DANGEROUS_POSSESSION" = DANGEROUS_POSSESSION,
|
||||
"EMAGGED" = EMAGGED,
|
||||
"EXAMINE_SKIP" = EXAMINE_SKIP,
|
||||
"FROZEN" = FROZEN,
|
||||
"IN_USE" = IN_USE,
|
||||
"ON_BLUEPRINTS" = ON_BLUEPRINTS,
|
||||
"SHOVABLE_ONTO" = SHOVABLE_ONTO,
|
||||
"UNIQUE_RENAME" = UNIQUE_RENAME,
|
||||
"USES_TGUI" = USES_TGUI,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(organ_flags, list(
|
||||
"ORGAN_EXTERNAL" = ORGAN_EXTERNAL,
|
||||
"ORGAN_FAILING" = ORGAN_FAILING,
|
||||
"ORGAN_FROZEN" = ORGAN_FROZEN,
|
||||
"ORGAN_NO_SPOIL" = ORGAN_NO_SPOIL,
|
||||
"ORGAN_SYNTHETIC" = ORGAN_SYNTHETIC,
|
||||
"ORGAN_VITAL" = ORGAN_VITAL,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(pass_flags, list(
|
||||
"LETPASSTHROW" = LETPASSTHROW,
|
||||
"PASSBLOB" = PASSBLOB,
|
||||
"PASSCLOSEDTURF" = PASSCLOSEDTURF,
|
||||
"PASSGLASS" = PASSGLASS,
|
||||
"PASSGRILLE" = PASSGRILLE,
|
||||
"PASSMOB" = PASSMOB,
|
||||
"PASSTABLE" = PASSTABLE,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(rad_flags, list(
|
||||
"RAD_PROTECT_CONTENTS" = RAD_PROTECT_CONTENTS,
|
||||
"RAD_NO_CONTAMINATE" = RAD_NO_CONTAMINATE,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(reagents_holder_flags, list(
|
||||
"AMOUNT_VISIBLE" = AMOUNT_VISIBLE,
|
||||
"DRAINABLE" = DRAINABLE,
|
||||
"DRAWABLE" = DRAWABLE,
|
||||
"INJECTABLE" = INJECTABLE,
|
||||
"NO_REACT" = NO_REACT,
|
||||
"REFILLABLE" = REFILLABLE,
|
||||
"TRANSPARENT" = TRANSPARENT,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(resistance_flags, list(
|
||||
"ACID_PROOF" = ACID_PROOF,
|
||||
"FIRE_PROOF" = FIRE_PROOF,
|
||||
"FLAMMABLE" = FLAMMABLE,
|
||||
"FREEZE_PROOF" = FREEZE_PROOF,
|
||||
"GOLIATH_RESISTANCE" = GOLIATH_RESISTANCE,
|
||||
"GOLIATH_WEAKNESS" = GOLIATH_WEAKNESS,
|
||||
"INDESTRUCTIBLE" = INDESTRUCTIBLE,
|
||||
"LAVA_PROOF" = LAVA_PROOF,
|
||||
"ON_FIRE" = ON_FIRE,
|
||||
"UNACIDABLE" = UNACIDABLE,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(shield_flags, list(
|
||||
"SHIELD_BASH_ALWAYS_DISARM" = SHIELD_BASH_ALWAYS_DISARM,
|
||||
"SHIELD_BASH_ALWAYS_KNOCKDOWN" = SHIELD_BASH_ALWAYS_KNOCKDOWN,
|
||||
"SHIELD_BASH_GROUND_SLAM" = SHIELD_BASH_GROUND_SLAM,
|
||||
"SHIELD_BASH_GROUND_SLAM_DISARM" = SHIELD_BASH_GROUND_SLAM_DISARM,
|
||||
"SHIELD_BASH_WALL_DISARM" = SHIELD_BASH_WALL_DISARM,
|
||||
"SHIELD_BASH_WALL_KNOCKDOWN" = SHIELD_BASH_WALL_KNOCKDOWN,
|
||||
"SHIELD_CAN_BASH" = SHIELD_CAN_BASH,
|
||||
"SHIELD_DISABLER_DISRUPTED" = SHIELD_DISABLER_DISRUPTED,
|
||||
"SHIELD_ENERGY_STRONG" = SHIELD_ENERGY_STRONG,
|
||||
"SHIELD_ENERGY_WEAK" = SHIELD_ENERGY_WEAK,
|
||||
"SHIELD_KINETIC_STRONG" = SHIELD_KINETIC_STRONG,
|
||||
"SHIELD_KINETIC_WEAK" = SHIELD_KINETIC_WEAK,
|
||||
"SHIELD_NO_MELEE" = SHIELD_NO_MELEE,
|
||||
"SHIELD_NO_RANGED" = SHIELD_NO_RANGED,
|
||||
"SHIELD_TRANSPARENT" = SHIELD_TRANSPARENT,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(sight, list(
|
||||
"BLIND" = BLIND,
|
||||
"SEE_BLACKNESS" = SEE_BLACKNESS,
|
||||
"SEE_INFRA" = SEE_INFRA,
|
||||
"SEE_MOBS" = SEE_MOBS,
|
||||
"SEE_OBJS" = SEE_OBJS,
|
||||
"SEE_PIXELS" = SEE_PIXELS,
|
||||
"SEE_SELF" = SEE_SELF,
|
||||
"SEE_THRU" = SEE_THRU,
|
||||
"SEE_TURFS" = SEE_TURFS,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(smooth, list(
|
||||
"SMOOTH_BORDER" = SMOOTH_BORDER,
|
||||
"SMOOTH_DIAGONAL" = SMOOTH_DIAGONAL,
|
||||
"SMOOTH_MORE" = SMOOTH_MORE,
|
||||
"SMOOTH_QUEUED" = SMOOTH_QUEUED,
|
||||
"SMOOTH_TRUE" = SMOOTH_TRUE,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(storage_flags, list(
|
||||
"STORAGE_LIMIT_COMBINED_W_CLASS" = STORAGE_LIMIT_COMBINED_W_CLASS,
|
||||
"STORAGE_LIMIT_MAX_ITEMS" = STORAGE_LIMIT_MAX_ITEMS,
|
||||
"STORAGE_LIMIT_MAX_W_CLASS" = STORAGE_LIMIT_MAX_W_CLASS,
|
||||
"STORAGE_LIMIT_VOLUME" = STORAGE_LIMIT_VOLUME,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(vis_flags, list(
|
||||
"VIS_HIDE" = VIS_HIDE,
|
||||
"VIS_INHERIT_DIR" = VIS_INHERIT_DIR,
|
||||
"VIS_INHERIT_ICON" = VIS_INHERIT_ICON,
|
||||
"VIS_INHERIT_ICON_STATE" = VIS_INHERIT_ICON_STATE,
|
||||
"VIS_INHERIT_ID" = VIS_INHERIT_ID,
|
||||
"VIS_INHERIT_LAYER" = VIS_INHERIT_LAYER,
|
||||
"VIS_INHERIT_PLANE" = VIS_INHERIT_PLANE,
|
||||
"VIS_UNDERLAY" = VIS_UNDERLAY,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(zap_flags, list(
|
||||
"ZAP_ALLOW_DUPLICATES" = ZAP_ALLOW_DUPLICATES,
|
||||
"ZAP_MACHINE_EXPLOSIVE" = ZAP_MACHINE_EXPLOSIVE,
|
||||
"ZAP_MOB_DAMAGE" = ZAP_MOB_DAMAGE,
|
||||
"ZAP_MOB_STUN" = ZAP_MOB_STUN,
|
||||
"ZAP_OBJ_DAMAGE" = ZAP_OBJ_DAMAGE,
|
||||
))
|
||||
|
||||
@@ -43,6 +43,10 @@ GLOBAL_LIST_EMPTY(arachnid_spinneret_list)
|
||||
GLOBAL_LIST_EMPTY(arachnid_mandibles_list)
|
||||
GLOBAL_LIST_EMPTY(caps_list)
|
||||
|
||||
//Bark bits
|
||||
GLOBAL_LIST_EMPTY(bark_list)
|
||||
GLOBAL_LIST_EMPTY(bark_random_list)
|
||||
|
||||
//a way to index the right bodypart list given the type of bodypart
|
||||
GLOBAL_LIST_INIT(mutant_reference_list, list(
|
||||
"tail_lizard" = GLOB.tails_list_lizard,
|
||||
|
||||
@@ -49,6 +49,8 @@ GLOBAL_VAR(tgui_log)
|
||||
GLOBAL_PROTECT(tgui_log)
|
||||
GLOBAL_VAR(world_shuttle_log)
|
||||
GLOBAL_PROTECT(world_shuttle_log)
|
||||
GLOBAL_VAR(world_econ_log)
|
||||
GLOBAL_PROTECT(world_econ_log)
|
||||
|
||||
GLOBAL_VAR(perf_log)
|
||||
GLOBAL_PROTECT(perf_log)
|
||||
|
||||
@@ -101,14 +101,6 @@
|
||||
..()
|
||||
|
||||
/client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params)
|
||||
var/list/L = params2list(params)
|
||||
if (L["middle"])
|
||||
if (src_object && src_location != over_location)
|
||||
middragtime = world.time
|
||||
middragatom = src_object
|
||||
else
|
||||
middragtime = 0
|
||||
middragatom = null
|
||||
mouseParams = params
|
||||
mouseLocation = over_location
|
||||
mouseObject = over_object
|
||||
@@ -121,9 +113,3 @@
|
||||
|
||||
/obj/item/proc/onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
|
||||
return
|
||||
|
||||
/client/MouseDrop(src_object, over_object, src_location, over_location, src_control, over_control, params)
|
||||
if (middragatom == src_object)
|
||||
middragtime = 0
|
||||
middragatom = null
|
||||
..()
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
if(client && hud_used)
|
||||
hud_used.reorganize_alerts()
|
||||
thealert.transform = matrix(32, 6, MATRIX_TRANSLATE)
|
||||
animate(thealert, transform = matrix(), time = 2.5, easing = CUBIC_EASING)
|
||||
animate(thealert, transform = matrix(), time = 2.5, easing = BACK_EASING)
|
||||
|
||||
if(thealert.timeout)
|
||||
addtimer(CALLBACK(src, .proc/alert_timeout, thealert, category), thealert.timeout)
|
||||
|
||||
@@ -0,0 +1,333 @@
|
||||
/datum/hud/new_player
|
||||
|
||||
/datum/hud/new_player/proc/populate_buttons(mob/dead/new_player/owner)
|
||||
var/list/buttons = subtypesof(/atom/movable/screen/lobby)
|
||||
for(var/button_type in buttons)
|
||||
var/atom/movable/screen/lobby/lobbyscreen = new button_type()
|
||||
lobbyscreen.SlowInit()
|
||||
lobbyscreen.hud = src
|
||||
static_inventory += lobbyscreen
|
||||
if(istype(lobbyscreen, /atom/movable/screen/lobby/button))
|
||||
var/atom/movable/screen/lobby/button/lobby_button = lobbyscreen
|
||||
lobby_button.owner = REF(owner)
|
||||
show_hud(hud_version)
|
||||
|
||||
/atom/movable/screen/lobby
|
||||
plane = SPLASHSCREEN_PLANE
|
||||
layer = LOBBY_BUTTON_LAYER
|
||||
screen_loc = "TOP,CENTER"
|
||||
|
||||
/// Run sleeping actions after initialize
|
||||
/atom/movable/screen/lobby/proc/SlowInit()
|
||||
return
|
||||
|
||||
/atom/movable/screen/lobby/background
|
||||
layer = LOBBY_BACKGROUND_LAYER
|
||||
icon = 'icons/hud/lobby/background.dmi'
|
||||
icon_state = "background"
|
||||
screen_loc = "TOP,CENTER:-61"
|
||||
|
||||
/atom/movable/screen/lobby/button
|
||||
///Is the button currently enabled?
|
||||
var/enabled = TRUE
|
||||
///Is the button currently being hovered over with the mouse?
|
||||
var/highlighted = FALSE
|
||||
/// The ref of the mob that owns this button. Only the owner can click on it.
|
||||
var/owner
|
||||
|
||||
/atom/movable/screen/lobby/button/Click(location, control, params)
|
||||
if(owner != REF(usr))
|
||||
return
|
||||
|
||||
. = ..()
|
||||
|
||||
if(!enabled)
|
||||
return
|
||||
flick("[base_icon_state]_pressed", src)
|
||||
update_appearance(UPDATE_ICON)
|
||||
return TRUE
|
||||
|
||||
/atom/movable/screen/lobby/button/MouseEntered(location,control,params)
|
||||
if(owner != REF(usr))
|
||||
return
|
||||
|
||||
. = ..()
|
||||
highlighted = TRUE
|
||||
update_appearance(UPDATE_ICON)
|
||||
|
||||
/atom/movable/screen/lobby/button/MouseExited()
|
||||
if(owner != REF(usr))
|
||||
return
|
||||
|
||||
. = ..()
|
||||
highlighted = FALSE
|
||||
update_appearance(UPDATE_ICON)
|
||||
|
||||
/atom/movable/screen/lobby/button/update_icon(updates)
|
||||
. = ..()
|
||||
if(!enabled)
|
||||
icon_state = "[base_icon_state]_disabled"
|
||||
return
|
||||
else if(highlighted)
|
||||
icon_state = "[base_icon_state]_highlighted"
|
||||
return
|
||||
icon_state = base_icon_state
|
||||
|
||||
/atom/movable/screen/lobby/button/proc/set_button_status(status)
|
||||
if(status == enabled)
|
||||
return FALSE
|
||||
enabled = status
|
||||
update_appearance(UPDATE_ICON)
|
||||
return TRUE
|
||||
|
||||
///Prefs menu
|
||||
/atom/movable/screen/lobby/button/character_setup
|
||||
screen_loc = "TOP:-70,CENTER:-54"
|
||||
icon = 'icons/hud/lobby/character_setup.dmi'
|
||||
icon_state = "character_setup"
|
||||
base_icon_state = "character_setup"
|
||||
|
||||
/atom/movable/screen/lobby/button/character_setup/Click(location, control, params)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
hud.mymob.client.prefs.current_tab = SETTINGS_TAB
|
||||
hud.mymob.client.prefs.ShowChoices(hud.mymob)
|
||||
|
||||
///Button that appears before the game has started
|
||||
/atom/movable/screen/lobby/button/ready
|
||||
screen_loc = "TOP:-8,CENTER:-65"
|
||||
icon = 'icons/hud/lobby/ready.dmi'
|
||||
icon_state = "not_ready"
|
||||
base_icon_state = "not_ready"
|
||||
var/ready = FALSE
|
||||
|
||||
/atom/movable/screen/lobby/button/ready/Initialize(mapload)
|
||||
. = ..()
|
||||
switch(SSticker.current_state)
|
||||
if(GAME_STATE_PREGAME, GAME_STATE_STARTUP)
|
||||
RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, .proc/hide_ready_button)
|
||||
if(GAME_STATE_SETTING_UP)
|
||||
set_button_status(FALSE)
|
||||
RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, .proc/show_ready_button)
|
||||
else
|
||||
set_button_status(FALSE)
|
||||
|
||||
/atom/movable/screen/lobby/button/ready/proc/hide_ready_button()
|
||||
SIGNAL_HANDLER
|
||||
set_button_status(FALSE)
|
||||
UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP)
|
||||
RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, .proc/show_ready_button)
|
||||
|
||||
/atom/movable/screen/lobby/button/ready/proc/show_ready_button()
|
||||
SIGNAL_HANDLER
|
||||
set_button_status(TRUE)
|
||||
UnregisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP)
|
||||
RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, .proc/hide_ready_button)
|
||||
|
||||
/atom/movable/screen/lobby/button/ready/Click(location, control, params)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
var/mob/dead/new_player/new_player = hud.mymob
|
||||
ready = !ready
|
||||
if(ready)
|
||||
new_player.ready = PLAYER_READY_TO_PLAY
|
||||
base_icon_state = "ready"
|
||||
else
|
||||
new_player.ready = PLAYER_NOT_READY
|
||||
base_icon_state = "not_ready"
|
||||
update_appearance(UPDATE_ICON)
|
||||
|
||||
///Shown when the game has started
|
||||
/atom/movable/screen/lobby/button/join
|
||||
screen_loc = "TOP:-13,CENTER:-58"
|
||||
icon = 'icons/hud/lobby/join.dmi'
|
||||
icon_state = "" //Default to not visible
|
||||
base_icon_state = "join_game"
|
||||
enabled = FALSE
|
||||
|
||||
/atom/movable/screen/lobby/button/join/Initialize(mapload)
|
||||
. = ..()
|
||||
switch(SSticker.current_state)
|
||||
if(GAME_STATE_PREGAME, GAME_STATE_STARTUP)
|
||||
RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, .proc/show_join_button)
|
||||
if(GAME_STATE_SETTING_UP)
|
||||
set_button_status(TRUE)
|
||||
RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, .proc/hide_join_button)
|
||||
else
|
||||
set_button_status(TRUE)
|
||||
|
||||
/atom/movable/screen/lobby/button/join/Click(location, control, params)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(!SSticker?.IsRoundInProgress())
|
||||
to_chat(hud.mymob, span_boldwarning("The round is either not ready, or has already finished..."))
|
||||
return
|
||||
|
||||
//Determines Relevent Population Cap
|
||||
var/relevant_cap
|
||||
var/hpc = CONFIG_GET(number/hard_popcap)
|
||||
var/epc = CONFIG_GET(number/extreme_popcap)
|
||||
if(hpc && epc)
|
||||
relevant_cap = min(hpc, epc)
|
||||
else
|
||||
relevant_cap = max(hpc, epc)
|
||||
|
||||
var/mob/dead/new_player/new_player = hud.mymob
|
||||
|
||||
if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(new_player.key) in GLOB.admin_datums)))
|
||||
to_chat(new_player, span_danger("[CONFIG_GET(string/hard_popcap_message)]"))
|
||||
|
||||
var/queue_position = SSticker.queued_players.Find(new_player)
|
||||
if(queue_position == 1)
|
||||
to_chat(new_player, span_notice("You are next in line to join the game. You will be notified when a slot opens up."))
|
||||
else if(queue_position)
|
||||
to_chat(new_player, span_notice("There are [queue_position-1] players in front of you in the queue to join the game."))
|
||||
else
|
||||
SSticker.queued_players += new_player
|
||||
to_chat(new_player, span_notice("You have been added to the queue to join the game. Your position in queue is [SSticker.queued_players.len]."))
|
||||
return
|
||||
new_player.LateChoices()
|
||||
|
||||
/atom/movable/screen/lobby/button/join/proc/show_join_button()
|
||||
SIGNAL_HANDLER
|
||||
set_button_status(TRUE)
|
||||
UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP)
|
||||
RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, .proc/hide_join_button)
|
||||
|
||||
/atom/movable/screen/lobby/button/join/proc/hide_join_button()
|
||||
SIGNAL_HANDLER
|
||||
set_button_status(FALSE)
|
||||
UnregisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP)
|
||||
RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, .proc/show_join_button)
|
||||
|
||||
/atom/movable/screen/lobby/button/observe
|
||||
screen_loc = "TOP:-40,CENTER:-54"
|
||||
icon = 'icons/hud/lobby/observe.dmi'
|
||||
icon_state = "observe_disabled"
|
||||
base_icon_state = "observe"
|
||||
enabled = FALSE
|
||||
|
||||
/atom/movable/screen/lobby/button/observe/Initialize(mapload)
|
||||
. = ..()
|
||||
if(SSticker.current_state > GAME_STATE_STARTUP)
|
||||
set_button_status(TRUE)
|
||||
else
|
||||
RegisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME, .proc/enable_observing)
|
||||
|
||||
/atom/movable/screen/lobby/button/observe/Click(location, control, params)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
var/mob/dead/new_player/new_player = hud.mymob
|
||||
new_player.make_me_an_observer()
|
||||
|
||||
/atom/movable/screen/lobby/button/observe/proc/enable_observing()
|
||||
SIGNAL_HANDLER
|
||||
flick("[base_icon_state]_enabled", src)
|
||||
set_button_status(TRUE)
|
||||
UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME, .proc/enable_observing)
|
||||
|
||||
/atom/movable/screen/lobby/button/settings
|
||||
icon = 'icons/hud/lobby/bottom_buttons.dmi'
|
||||
icon_state = "settings"
|
||||
base_icon_state = "settings"
|
||||
screen_loc = "TOP:-122,CENTER:+30"
|
||||
|
||||
/atom/movable/screen/lobby/button/settings/Click(location, control, params)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
hud.mymob.client.prefs.current_tab = GAME_PREFERENCES_TAB
|
||||
hud.mymob.client.prefs.ShowChoices(hud.mymob)
|
||||
|
||||
/atom/movable/screen/lobby/button/changelog_button
|
||||
icon = 'icons/hud/lobby/bottom_buttons.dmi'
|
||||
icon_state = "changelog"
|
||||
base_icon_state = "changelog"
|
||||
screen_loc ="TOP:-122,CENTER:+58"
|
||||
|
||||
|
||||
/atom/movable/screen/lobby/button/crew_manifest
|
||||
icon = 'icons/hud/lobby/bottom_buttons.dmi'
|
||||
icon_state = "crew_manifest"
|
||||
base_icon_state = "crew_manifest"
|
||||
screen_loc = "TOP:-122,CENTER:+2"
|
||||
|
||||
/atom/movable/screen/lobby/button/crew_manifest/Click(location, control, params)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
var/mob/dead/new_player/new_player = hud.mymob
|
||||
new_player.ViewManifest()
|
||||
|
||||
/atom/movable/screen/lobby/button/changelog_button/Click(location, control, params)
|
||||
. = ..()
|
||||
usr.client?.changelog()
|
||||
|
||||
/atom/movable/screen/lobby/button/poll
|
||||
icon = 'icons/hud/lobby/bottom_buttons.dmi'
|
||||
icon_state = "poll"
|
||||
base_icon_state = "poll"
|
||||
screen_loc = "TOP:-122,CENTER:-26"
|
||||
|
||||
var/new_poll = FALSE
|
||||
|
||||
/atom/movable/screen/lobby/button/poll/SlowInit(mapload)
|
||||
. = ..()
|
||||
if(!usr)
|
||||
return
|
||||
var/mob/dead/new_player/new_player = usr
|
||||
if(is_guest_key(new_player.key))
|
||||
set_button_status(FALSE)
|
||||
return
|
||||
if(!SSdbcore.Connect())
|
||||
set_button_status(FALSE)
|
||||
return
|
||||
var/isadmin = FALSE
|
||||
if(new_player.client?.holder)
|
||||
isadmin = TRUE
|
||||
var/datum/db_query/query_get_new_polls = SSdbcore.NewQuery({"
|
||||
SELECT id FROM [format_table_name("poll_question")]
|
||||
WHERE (adminonly = 0 OR :isadmin = 1)
|
||||
AND Now() BETWEEN starttime AND endtime
|
||||
AND deleted = 0
|
||||
AND id NOT IN (
|
||||
SELECT pollid FROM [format_table_name("poll_vote")]
|
||||
WHERE ckey = :ckey
|
||||
AND deleted = 0
|
||||
)
|
||||
AND id NOT IN (
|
||||
SELECT pollid FROM [format_table_name("poll_textreply")]
|
||||
WHERE ckey = :ckey
|
||||
AND deleted = 0
|
||||
)
|
||||
"}, list("isadmin" = isadmin, "ckey" = new_player.ckey))
|
||||
if(!query_get_new_polls.Execute())
|
||||
qdel(query_get_new_polls)
|
||||
set_button_status(FALSE)
|
||||
return
|
||||
if(query_get_new_polls.NextRow())
|
||||
new_poll = TRUE
|
||||
else
|
||||
new_poll = FALSE
|
||||
update_appearance(UPDATE_OVERLAYS)
|
||||
qdel(query_get_new_polls)
|
||||
if(QDELETED(new_player))
|
||||
set_button_status(FALSE)
|
||||
return
|
||||
|
||||
/atom/movable/screen/lobby/button/poll/update_overlays()
|
||||
. = ..()
|
||||
if(new_poll)
|
||||
. += mutable_appearance('icons/hud/lobby/poll_overlay.dmi', "new_poll")
|
||||
|
||||
/atom/movable/screen/lobby/button/poll/Click(location, control, params)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
var/mob/dead/new_player/new_player = hud.mymob
|
||||
new_player.handle_player_polling()
|
||||
@@ -178,7 +178,7 @@ GLOBAL_LIST_EMPTY(radial_menus)
|
||||
starting.Scale(0.1,0.1)
|
||||
E.transform = starting
|
||||
var/matrix/TM = matrix()
|
||||
animate(E,pixel_x = px,pixel_y = py, transform = TM, time = timing)
|
||||
animate(E,pixel_x = px,pixel_y = py, transform = TM, time = timing, easing = SINE_EASING | EASE_OUT)
|
||||
else
|
||||
E.pixel_y = py
|
||||
E.pixel_x = px
|
||||
|
||||
@@ -126,6 +126,8 @@
|
||||
return DISCARD_LAST_ACTION
|
||||
user.do_attack_animation(O)
|
||||
O.attacked_by(src, user)
|
||||
if(force >= 20)
|
||||
shake_camera(user, ((force - 15) * 0.01 + 1), ((force - 15) * 0.01))
|
||||
|
||||
/atom/movable/proc/attacked_by()
|
||||
return
|
||||
|
||||
@@ -29,7 +29,9 @@ GLOBAL_LIST_INIT(huds, list(
|
||||
ANTAG_HUD_BROTHER = new/datum/atom_hud/antag/hidden(),
|
||||
ANTAG_HUD_BLOODSUCKER = new/datum/atom_hud/antag/bloodsucker(),
|
||||
ANTAG_HUD_FUGITIVE = new/datum/atom_hud/antag(),
|
||||
ANTAG_HUD_HERETIC = new/datum/atom_hud/antag/hidden()
|
||||
ANTAG_HUD_HERETIC = new/datum/atom_hud/antag/hidden(),
|
||||
ANTAG_HUD_SPACECOP = new/datum/atom_hud/antag(),
|
||||
ANTAG_HUD_GANGSTER = new/datum/atom_hud/antag/hidden()
|
||||
))
|
||||
|
||||
/datum/atom_hud
|
||||
|
||||
@@ -248,7 +248,7 @@
|
||||
if(P.absolute)
|
||||
continue
|
||||
var/matrix/translate_matrix = matrix()
|
||||
translate_matrix.Translate(cos(turn) * 480, sin(turn) * 480)
|
||||
translate_matrix.Translate(sin(turn) * 480, cos(turn) * 480)
|
||||
var/matrix/target_matrix = matrix()
|
||||
var/move_speed = speed * P.speed
|
||||
// do the first segment by shifting down one screen
|
||||
@@ -282,7 +282,7 @@
|
||||
continue
|
||||
P.CancelAnimation()
|
||||
var/matrix/translate_matrix = matrix()
|
||||
translate_matrix.Translate(cos(turn) * 480, sin(turn) * 480)
|
||||
translate_matrix.Translate(sin(turn) * 480, cos(turn) * 480)
|
||||
P.transform = translate_matrix
|
||||
animate(P, transform = matrix(), time = time, easing = QUAD_EASING | EASE_OUT)
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/datum/config_entry/flag/irc_announce_new_game
|
||||
deprecated_by = /datum/config_entry/string/chat_announce_new_game
|
||||
|
||||
/datum/config_entry/flag/irc_announce_new_game/DeprecationUpdate(value)
|
||||
return "" //default broadcast
|
||||
|
||||
/datum/config_entry/string/chat_announce_new_game
|
||||
config_entry_value = null
|
||||
|
||||
/datum/config_entry/string/chat_reboot_role
|
||||
|
||||
/datum/config_entry/string/chat_roundend_notice_tag
|
||||
|
||||
/datum/config_entry/string/chat_squawk_tag
|
||||
@@ -39,16 +39,6 @@
|
||||
|
||||
/datum/config_entry/flag/show_irc_name
|
||||
|
||||
/datum/config_entry/flag/irc_announce_new_game
|
||||
deprecated_by = /datum/config_entry/string/chat_announce_new_game
|
||||
|
||||
/datum/config_entry/flag/irc_announce_new_game/DeprecationUpdate(value)
|
||||
return "" //default broadcast
|
||||
|
||||
/datum/config_entry/string/chat_announce_new_game
|
||||
|
||||
config_entry_value = null
|
||||
|
||||
/datum/config_entry/string/default_view
|
||||
config_entry_value = "15x15"
|
||||
|
||||
|
||||
@@ -79,6 +79,10 @@
|
||||
/datum/config_entry/flag/log_telecomms
|
||||
config_entry_value = TRUE
|
||||
|
||||
/// log economy
|
||||
/datum/config_entry/flag/log_econ
|
||||
config_entry_value = TRUE
|
||||
|
||||
/// log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases.
|
||||
/datum/config_entry/flag/log_twitter
|
||||
config_entry_value = TRUE
|
||||
|
||||
@@ -31,7 +31,7 @@ SUBSYSTEM_DEF(autotransfer)
|
||||
if(world.time < targettime)
|
||||
return
|
||||
if(maxvotes == NO_MAXVOTES_CAP || maxvotes > curvotes)
|
||||
SSvote.initiate_vote("transfer","server")
|
||||
SSvote.initiate_vote("transfer","server", votesystem=APPROVAL_VOTING)
|
||||
targettime = targettime + voteinterval
|
||||
curvotes++
|
||||
else
|
||||
|
||||
@@ -367,9 +367,14 @@ SUBSYSTEM_DEF(job)
|
||||
JobDebug("DO, Handling unrejectable unassigned")
|
||||
//Mop up people who can't leave.
|
||||
for(var/mob/dead/new_player/player in unassigned) //Players that wanted to back out but couldn't because they're antags (can you feel the edge case?)
|
||||
if(!GiveRandomJob(player))
|
||||
if(!AssignRole(player, SSjob.overflow_role)) //If everything is already filled, make them an assistant
|
||||
return FALSE //Living on the edge, the forced antagonist couldn't be assigned to overflow role (bans, client age) - just reroll
|
||||
if(player.client.prefs.joblessrole == BERANDOMJOB) //Gives the player a random role if their preferences are set to it
|
||||
if(!GiveRandomJob(player))
|
||||
if(!AssignRole(player, SSjob.overflow_role)) //If everything is already filled, make them the overflow role
|
||||
return FALSE //Living on the edge, the forced antagonist couldn't be assigned to overflow role (bans, client age) - just reroll
|
||||
else //If the player prefers to return to lobby or be an assistant, give them assistant
|
||||
if(!AssignRole(player, SSjob.overflow_role))
|
||||
if(!GiveRandomJob(player)) //The forced antagonist couldn't be assigned to overflow role (bans, client age) - give a random role
|
||||
return FALSE //Somehow the forced antagonist couldn't be assigned to the overflow role or the a random role - reroll
|
||||
|
||||
return validate_required_jobs(required_jobs)
|
||||
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
//As a brief warning to all those who dare tread upon these grounds:
|
||||
//The bulk of this code here was written years ago, back in the days of 512.
|
||||
//We were incredibly drunk back then. And nowadays, we've found that being drunk is a hard requirement for working with this code.
|
||||
//So if you're here to make changes? Brandish a glass. There are many sins here, but it's exactly as engineered as it needs to be.
|
||||
//We physically won't be able to tell you what half of this code does. The only thing that'll help you here is the ballmer peak.
|
||||
//Bottoms up, friend. And be sure to drink responsibly. Be sure to fetch some water, too; it eases the hangover. - Bhijn & Myr
|
||||
|
||||
|
||||
// Jukelist indices
|
||||
#define JUKE_TRACK 1
|
||||
#define JUKE_CHANNEL 2
|
||||
#define JUKE_BOX 3
|
||||
#define JUKE_FALLOFF 4
|
||||
#define JUKE_SOUND 5
|
||||
|
||||
|
||||
SUBSYSTEM_DEF(jukeboxes)
|
||||
name = "Jukeboxes"
|
||||
wait = 5
|
||||
@@ -25,27 +41,41 @@ SUBSYSTEM_DEF(jukeboxes)
|
||||
var/channeltoreserve = pick(freejukeboxchannels)
|
||||
if(!channeltoreserve)
|
||||
return FALSE
|
||||
var/sound/song_to_init = sound(T.song_path)
|
||||
freejukeboxchannels -= channeltoreserve
|
||||
var/list/youvegotafreejukebox = list(T, channeltoreserve, jukebox, jukefalloff)
|
||||
var/list/youvegotafreejukebox = list(T, channeltoreserve, jukebox, jukefalloff, song_to_init)
|
||||
|
||||
song_to_init.status = SOUND_MUTE
|
||||
song_to_init.environment = 7
|
||||
song_to_init.channel = channeltoreserve
|
||||
song_to_init.volume = 1
|
||||
song_to_init.falloff = jukefalloff
|
||||
song_to_init.echo = list(0, null, -10000, null, null, null, null, null, null, null, null, null, null, 1, 1, 1, null, null)
|
||||
|
||||
activejukeboxes.len++
|
||||
activejukeboxes[activejukeboxes.len] = youvegotafreejukebox
|
||||
|
||||
//Due to changes in later versions of 512, SOUND_UPDATE no longer properly plays audio when a file is defined in the sound datum. As such, we are now required to init the audio before we can actually do anything with it.
|
||||
//Downsides to this? This means that you can *only* hear the jukebox audio if you were present on the server when it started playing, and it means that it's now impossible to add loops to the jukebox track list.
|
||||
var/sound/song_to_init = sound(T.song_path)
|
||||
song_to_init.status = SOUND_MUTE
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client)
|
||||
continue
|
||||
if(!(M.client.prefs.toggles & SOUND_INSTRUMENTS))
|
||||
continue
|
||||
|
||||
M.playsound_local(M, null, 100, channel = youvegotafreejukebox[2], S = song_to_init)
|
||||
SEND_SOUND(M, song_to_init)
|
||||
return activejukeboxes.len
|
||||
|
||||
|
||||
//Updates jukebox by transferring to different object or modifying falloff.
|
||||
/datum/controller/subsystem/jukeboxes/proc/updatejukebox(IDtoupdate, obj/jukebox, jukefalloff)
|
||||
if(islist(activejukeboxes[IDtoupdate]))
|
||||
if(istype(jukebox))
|
||||
activejukeboxes[IDtoupdate][JUKE_BOX] = jukebox
|
||||
if(!isnull(jukefalloff))
|
||||
activejukeboxes[IDtoupdate][JUKE_FALLOFF] = jukefalloff
|
||||
|
||||
/datum/controller/subsystem/jukeboxes/proc/removejukebox(IDtoremove)
|
||||
if(islist(activejukeboxes[IDtoremove]))
|
||||
var/jukechannel = activejukeboxes[IDtoremove][2]
|
||||
var/jukechannel = activejukeboxes[IDtoremove][JUKE_CHANNEL]
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client)
|
||||
continue
|
||||
@@ -85,37 +115,74 @@ SUBSYSTEM_DEF(jukeboxes)
|
||||
if(!jukeinfo.len)
|
||||
stack_trace("Active jukebox without any associated metadata.")
|
||||
continue
|
||||
var/datum/track/juketrack = jukeinfo[1]
|
||||
var/datum/track/juketrack = jukeinfo[JUKE_TRACK]
|
||||
if(!istype(juketrack))
|
||||
stack_trace("Invalid jukebox track datum.")
|
||||
continue
|
||||
var/obj/jukebox = jukeinfo[3]
|
||||
var/obj/jukebox = jukeinfo[JUKE_BOX]
|
||||
if(!istype(jukebox))
|
||||
stack_trace("Nonexistant or invalid object associated with jukebox.")
|
||||
continue
|
||||
var/sound/song_played = sound(juketrack.song_path)
|
||||
|
||||
var/list/audible_zlevels = get_multiz_accessible_levels(jukebox.z) //TODO - for multiz refresh, this should use the cached zlevel connections var in SSMapping. For now this is fine!
|
||||
|
||||
var/sound/song_played = jukeinfo[JUKE_SOUND]
|
||||
var/turf/currentturf = get_turf(jukebox)
|
||||
var/area/currentarea = get_area(jukebox)
|
||||
var/list/hearerscache = hearers(7, jukebox)
|
||||
var/targetfalloff = jukeinfo[JUKE_FALLOFF]
|
||||
var/mixes = ((targetfalloff*250)-750)
|
||||
var/inrange
|
||||
var/pressure_factor
|
||||
|
||||
song_played.falloff = jukeinfo[4]
|
||||
|
||||
var/datum/gas_mixture/source_env = (istype(currentturf) ? currentturf.return_air() : null)
|
||||
var/datum/gas_mixture/hearer_env //We init this var outside of the mob loop for the sake of performance
|
||||
var/turf/hearerturf //ditto
|
||||
|
||||
var/source_pressure = (istype(source_env) ? source_env.return_pressure() : 0)
|
||||
|
||||
song_played.falloff = targetfalloff
|
||||
song_played.volume = min((targetfalloff * 50), 100)
|
||||
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client)
|
||||
continue
|
||||
if(!(M.client.prefs.toggles & SOUND_INSTRUMENTS) || !M.can_hear())
|
||||
M.stop_sound_channel(jukeinfo[2])
|
||||
if(!(M.client.prefs.toggles & SOUND_INSTRUMENTS))
|
||||
M.stop_sound_channel(jukeinfo[JUKE_CHANNEL])
|
||||
continue
|
||||
|
||||
var/inrange = FALSE
|
||||
if(jukebox.z == M.z) //todo - expand this to work with mining planet z-levels when robust jukebox audio gets merged to master
|
||||
song_played.status = SOUND_UPDATE
|
||||
if(get_area(M) == currentarea)
|
||||
inrange = TRUE
|
||||
else if(M in hearerscache)
|
||||
inrange = TRUE
|
||||
else
|
||||
song_played.status = SOUND_MUTE | SOUND_UPDATE //Setting volume = 0 doesn't let the sound properties update at all, which is lame.
|
||||
M.playsound_local(currentturf, null, 100, channel = jukeinfo[2], S = song_played, envwet = (inrange ? -250 : 0), envdry = (inrange ? 0 : -10000))
|
||||
inrange = FALSE
|
||||
song_played.status = SOUND_MUTE | SOUND_UPDATE
|
||||
|
||||
if(source_pressure)
|
||||
hearerturf = get_turf(M)
|
||||
hearer_env = (istype(hearerturf) ? hearerturf.return_air() : null)
|
||||
if(istype(hearer_env))
|
||||
pressure_factor = min(source_pressure, hearer_env.return_pressure())
|
||||
|
||||
if(pressure_factor && targetfalloff && M.can_hear() && (hearerturf.z in audible_zlevels))
|
||||
if(get_area(hearerturf) == currentarea)
|
||||
inrange = TRUE
|
||||
else if(M in hearerscache)
|
||||
inrange = TRUE
|
||||
|
||||
song_played.x = (currentturf.x - hearerturf.x) * SOUND_DEFAULT_DISTANCE_MULTIPLIER
|
||||
song_played.z = (currentturf.y - hearerturf.y) * SOUND_DEFAULT_DISTANCE_MULTIPLIER
|
||||
song_played.y = (((currentturf.z - hearerturf.z) * 10 * SOUND_DEFAULT_DISTANCE_MULTIPLIER) + ((currentturf.z < hearerturf.z) ? -5 : 5))
|
||||
|
||||
if(pressure_factor < ONE_ATMOSPHERE)
|
||||
song_played.volume = (min((targetfalloff * 50), 100) * max((pressure_factor - SOUND_MINIMUM_PRESSURE)/(ONE_ATMOSPHERE - SOUND_MINIMUM_PRESSURE), 1))
|
||||
|
||||
song_played.echo[1] = (inrange ? 0 : -10000)
|
||||
song_played.echo[3] = (inrange ? mixes : max(mixes, 0))
|
||||
song_played.status = SOUND_UPDATE
|
||||
SEND_SOUND(M, song_played)
|
||||
CHECK_TICK
|
||||
return
|
||||
|
||||
#undef JUKE_TRACK
|
||||
#undef JUKE_CHANNEL
|
||||
#undef JUKE_BOX
|
||||
#undef JUKE_FALLOFF
|
||||
#undef JUKE_SOUND
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Persists polly messages across rounds
|
||||
*/
|
||||
/datum/controller/subsystem/persistence/LoadGamePersistence()
|
||||
. = ..()
|
||||
LoadPolly()
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadPolly()
|
||||
for(var/mob/living/simple_animal/parrot/Polly/P in GLOB.alive_mob_list)
|
||||
twitterize(P.speech_buffer, "polytalk")
|
||||
break //Who's been duping the bird?!
|
||||
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* Persists poly messages across rounds
|
||||
*/
|
||||
/datum/controller/subsystem/persistence/LoadGamePersistence()
|
||||
. = ..()
|
||||
LoadPoly()
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadPoly()
|
||||
for(var/mob/living/simple_animal/parrot/Poly/P in GLOB.alive_mob_list)
|
||||
twitterize(P.speech_buffer, "polytalk")
|
||||
break //Who's been duping the bird?!
|
||||
@@ -164,8 +164,8 @@ SUBSYSTEM_DEF(ticker)
|
||||
to_chat(world, "<span class='boldnotice'>Welcome to [station_name()]!</span>")
|
||||
send2chat("New round starting on [SSmapping.config.map_name]!", CONFIG_GET(string/chat_announce_new_game))
|
||||
current_state = GAME_STATE_PREGAME
|
||||
//Everyone who wants to be an observer is now spawned
|
||||
create_observers()
|
||||
SEND_SIGNAL(src, COMSIG_TICKER_ENTER_PREGAME)
|
||||
|
||||
fire()
|
||||
if(GAME_STATE_PREGAME)
|
||||
//lobby stats for statpanels
|
||||
@@ -203,6 +203,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
for(var/client/C in SSvote.voting)
|
||||
C << browse(null, "window=vote;can_close=0")
|
||||
SSvote.reset()
|
||||
SEND_SIGNAL(src, COMSIG_TICKER_ENTER_SETTING_UP)
|
||||
current_state = GAME_STATE_SETTING_UP
|
||||
Master.SetRunLevel(RUNLEVEL_SETUP)
|
||||
if(start_immediately)
|
||||
@@ -215,6 +216,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10)
|
||||
timeLeft = null
|
||||
Master.SetRunLevel(RUNLEVEL_LOBBY)
|
||||
SEND_SIGNAL(src, COMSIG_TICKER_ERROR_SETTING_UP)
|
||||
|
||||
if(GAME_STATE_PLAYING)
|
||||
mode.process(wait * 0.1)
|
||||
@@ -378,8 +380,6 @@ SUBSYSTEM_DEF(ticker)
|
||||
LAZYOR(player.client.prefs.characters_joined_as, player.new_character.real_name)
|
||||
else
|
||||
stack_trace("WARNING: Either a player did not have a new_character, did not have a client, or did not have preferences. This is VERY bad.")
|
||||
else
|
||||
player.new_player_panel()
|
||||
CHECK_TICK
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/collect_minds()
|
||||
@@ -612,7 +612,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/list/ded = SSblackbox.first_death
|
||||
if(ded.len)
|
||||
var/last_words = ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : ""
|
||||
news_message += "\nNT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died. Their name was: [ded["name"]], [ded["role"]], at [ded["area"]].[last_words]"
|
||||
news_message += "\nNT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died.\nTheir name was: [ded["name"]], [ded["role"]], at [ded["area"]].[last_words]"
|
||||
else
|
||||
news_message += "\nNT Sanctioned Psykers proudly confirm reports that nobody died this shift!"
|
||||
|
||||
@@ -633,13 +633,6 @@ SUBSYSTEM_DEF(ticker)
|
||||
else
|
||||
timeLeft = newtime
|
||||
|
||||
//Everyone who wanted to be an observer gets made one now
|
||||
/datum/controller/subsystem/ticker/proc/create_observers()
|
||||
for(var/mob/dead/new_player/player in GLOB.player_list)
|
||||
if(player.ready == PLAYER_READY_TO_OBSERVE && player.mind)
|
||||
//Break chain since this has a sleep input in it
|
||||
addtimer(CALLBACK(player, /mob/dead/new_player.proc/make_me_an_observer), 1)
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/load_mode()
|
||||
var/mode = trim(file2text("data/mode.txt"))
|
||||
if(mode)
|
||||
|
||||
@@ -10,7 +10,7 @@ SUBSYSTEM_DEF(title)
|
||||
|
||||
/datum/controller/subsystem/title/Initialize()
|
||||
if(file_path && icon)
|
||||
return ..()
|
||||
return
|
||||
|
||||
if(fexists("data/previous_title.dat"))
|
||||
var/previous_path = file2text("data/previous_title.dat")
|
||||
@@ -31,13 +31,16 @@ SUBSYSTEM_DEF(title)
|
||||
if(length(title_screens))
|
||||
file_path = "[global.config.directory]/title_screens/images/[pick(title_screens)]"
|
||||
|
||||
if(!file_path || !fexists(file_path))
|
||||
file_path = "icons/default_title.dmi"
|
||||
if(!file_path)
|
||||
file_path = "icons/runtime/default_title.dmi"
|
||||
|
||||
if(fexists(file_path))
|
||||
icon = new(fcopy_rsc(file_path))
|
||||
if(splash_turf)
|
||||
splash_turf.icon = icon
|
||||
ASSERT(fexists(file_path))
|
||||
|
||||
icon = new(fcopy_rsc(file_path))
|
||||
|
||||
if(splash_turf)
|
||||
splash_turf.icon = icon
|
||||
splash_turf.handle_generic_titlescreen_sizes()
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ SUBSYSTEM_DEF(traumas)
|
||||
/obj/structure/fluff/empty_sleeper/syndicate, /obj/item/implant/radio/syndicate, /obj/item/clothing/head/helmet/space/syndicate, /obj/machinery/nuclearbomb/syndicate, /obj/item/grenade/syndieminibomb, /obj/item/storage/backpack/duffelbag/syndie, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver,
|
||||
/obj/item/gun/ballistic/automatic/shotgun/bulldog, /obj/item/gun/ballistic/automatic/c20r, /obj/item/gun/ballistic/automatic/m90, /obj/item/gun/ballistic/automatic/l6_saw, /obj/item/storage/belt/grenade/full, /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate, /obj/item/gun/energy/kinetic_accelerator/crossbow,
|
||||
/obj/item/melee/transforming/energy/sword/saber, /obj/item/dualsaber, /obj/item/melee/powerfist, /obj/item/storage/box/syndie_kit, /obj/item/grenade/spawnergrenade/manhacks, /obj/item/grenade/chem_grenade/bioterrorfoam, /obj/item/reagent_containers/spray/chemsprayer/bioterror, /obj/item/ammo_box/magazine/m10mm,
|
||||
/obj/item/ammo_box/magazine/pistolm9mm, /obj/item/ammo_box/a357, /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/mm195x129, /obj/item/antag_spawner/nuke_ops, /obj/vehicle/sealed/mecha/combat/gygax/dark, /obj/vehicle/sealed/mecha/combat/marauder/mauler, /obj/item/soap/syndie, /obj/item/gun/syringe/syndicate, /obj/item/cartridge/virus/syndicate,
|
||||
/obj/item/ammo_box/magazine/pistolm9mm, /obj/item/ammo_box/a357, /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/mm712x82, /obj/item/antag_spawner/nuke_ops, /obj/vehicle/sealed/mecha/combat/gygax/dark, /obj/vehicle/sealed/mecha/combat/marauder/mauler, /obj/item/soap/syndie, /obj/item/gun/syringe/syndicate, /obj/item/cartridge/virus/syndicate,
|
||||
/obj/item/cartridge/virus/frame, /obj/item/chameleon, /obj/item/storage/box/syndie_kit/cutouts, /obj/item/clothing/suit/space/hardsuit/syndi, /obj/item/card/emag, /obj/item/storage/toolbox/syndicate, /obj/item/storage/book/bible/syndicate, /obj/item/encryptionkey/binary, /obj/item/encryptionkey/syndicate, /obj/item/aiModule/syndicate,
|
||||
/obj/item/clothing/shoes/magboots/syndie, /obj/item/powersink, /obj/item/sbeacondrop, /obj/item/sbeacondrop/bomb, /obj/item/syndicatedetonator, /obj/item/shield/energy, /obj/item/assault_pod, /obj/item/slimepotion/slime/sentience/nuclear, /obj/item/stack/telecrystal, /obj/item/jammer, /obj/item/codespeak_manual/unlimited,
|
||||
/obj/item/toy/cards/deck/syndicate, /obj/item/storage/secure/briefcase/syndie, /obj/item/storage/fancy/cigarettes/cigpack_syndicate, /obj/item/toy/syndicateballoon, /obj/item/clothing/gloves/fingerless/pugilist/rapid, /obj/item/paper/fluff/ruins/thederelict/syndie_mission, /obj/item/organ/cyberimp/eyes/hud/security/syndicate, /obj/item/clothing/head/HoS/syndicate,
|
||||
|
||||
@@ -320,11 +320,11 @@ SUBSYSTEM_DEF(vote)
|
||||
admintext += "\nIt should be noted that this is not a raw tally of votes but rather the median score plus a tiebreaker!"
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/votes = choices[choices[i]]
|
||||
admintext += "\n<b>[choices[i]]:</b> [votes]"
|
||||
admintext += "\n<b>[choices[i]]:</b> [votes ? votes : "0"]" //This is raw data, but the raw data is null by default. If ya don't compensate for it, then it'll look weird!
|
||||
else
|
||||
for(var/i=1,i<=scores.len,i++)
|
||||
var/score = scores[scores[i]]
|
||||
admintext += "\n<b>[scores[i]]:</b> [score]"
|
||||
admintext += "\n<b>[scores[i]]:</b> [score ? score : "0"]"
|
||||
message_admins(admintext)
|
||||
return .
|
||||
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
//Datums for barks and bark accessories
|
||||
|
||||
/datum/bark
|
||||
var/name = "Default"
|
||||
var/id = "Default"
|
||||
var/soundpath //Path for the actual sound file used for the bark
|
||||
|
||||
// Pitch vars. The actual range for a bark is [(pitch - (maxvariance*0.5)) to (pitch + (maxvariance*0.5))]
|
||||
// Make absolutely sure to take variance into account when curating a sound for bark purposes.
|
||||
var/minpitch = BARK_DEFAULT_MINPITCH
|
||||
var/maxpitch = BARK_DEFAULT_MAXPITCH
|
||||
var/minvariance = BARK_DEFAULT_MINVARY
|
||||
var/maxvariance = BARK_DEFAULT_MAXVARY
|
||||
|
||||
// Speed vars. Speed determines the number of characters required for each bark, with lower speeds being faster with higher bark density
|
||||
var/minspeed = BARK_DEFAULT_MINSPEED
|
||||
var/maxspeed = BARK_DEFAULT_MAXSPEED
|
||||
|
||||
// Visibility vars. Regardless of what's set below, these can still be obtained via adminbus and genetics. Rule of fun.
|
||||
var/list/ckeys_allowed
|
||||
var/ignore = FALSE //Controls whether or not this can be chosen in chargen
|
||||
var/allow_random = FALSE //Allows chargen randomization to use this. This is mainly to restrict the pool to sounds that fit well for most characters
|
||||
|
||||
|
||||
// So the basic jist of the sound design here: We make use primarily of shorter instrument samples for barks. We would've went with animalese instead, but doing so would've involved quite a bit of overhead to saycode.
|
||||
// Short instrument samples tend to sound surprisingly nice for barks, being able to be played in rapid succession without being outright obnoxious.
|
||||
// It isn't just instruments that work well here, however. Anything that works well as a stab? Short attack, no sustain, a decent amount of release? Also works extremely well for barks.
|
||||
|
||||
/datum/bark/mutedc2
|
||||
name = "Muted String (Low)"
|
||||
id = "mutedc2"
|
||||
soundpath = 'sound/instruments/synthesis_samples/guitar/crisis_muted/C2.ogg'
|
||||
allow_random = TRUE
|
||||
|
||||
/datum/bark/mutedc3
|
||||
name = "Muted String (Medium)"
|
||||
id = "mutedc3"
|
||||
soundpath = 'sound/instruments/synthesis_samples/guitar/crisis_muted/C3.ogg'
|
||||
allow_random = TRUE
|
||||
|
||||
/datum/bark/mutedc4
|
||||
name = "Muted String (High)"
|
||||
id = "mutedc4"
|
||||
soundpath = 'sound/instruments/synthesis_samples/guitar/crisis_muted/C4.ogg'
|
||||
allow_random = TRUE
|
||||
|
||||
/datum/bark/banjoc3
|
||||
name = "Banjo (Medium)"
|
||||
id = "banjoc3"
|
||||
soundpath = 'sound/instruments/banjo/Cn3.ogg'
|
||||
allow_random = TRUE
|
||||
|
||||
/datum/bark/banjoc4
|
||||
name = "Banjo (High)"
|
||||
id = "banjoc4"
|
||||
soundpath = 'sound/instruments/banjo/Cn4.ogg'
|
||||
allow_random = TRUE
|
||||
|
||||
/datum/bark/squeaky
|
||||
name = "Squeaky"
|
||||
id = "squeak"
|
||||
soundpath = 'sound/items/toysqueak1.ogg'
|
||||
maxspeed = 4
|
||||
|
||||
/datum/bark/beep
|
||||
name = "Beepy"
|
||||
id = "beep"
|
||||
soundpath = 'sound/machines/terminal_select.ogg'
|
||||
maxpitch = 1 //Bringing the pitch higher just hurts your ears :<
|
||||
maxspeed = 4 //This soundbyte's too short for larger speeds to not sound awkward
|
||||
|
||||
/datum/bark/chitter
|
||||
name = "Chittery"
|
||||
id = "chitter"
|
||||
minspeed = 4 //Even with the sound being replaced with a unique, shorter sound, this is still a little too long for higher speeds
|
||||
soundpath = 'sound/voice/barks/chitter.ogg'
|
||||
|
||||
/datum/bark/synthetic_grunt
|
||||
name = "Synthetic (Grunt)"
|
||||
id = "synthgrunt"
|
||||
soundpath = 'sound/misc/bloop.ogg'
|
||||
|
||||
/datum/bark/synthetic
|
||||
name = "Synthetic (Normal)"
|
||||
id = "synth"
|
||||
soundpath = 'sound/machines/uplinkerror.ogg'
|
||||
|
||||
/datum/bark/bullet
|
||||
name = "Windy"
|
||||
id = "bullet"
|
||||
maxpitch = 1.6 //This works well with higher pitches!
|
||||
soundpath = 'sound/weapons/bulletflyby.ogg' //This works... Surprisingly well as a bark? It's neat!
|
||||
|
||||
/datum/bark/coggers
|
||||
name = "Brassy"
|
||||
id = "coggers"
|
||||
soundpath = 'sound/machines/clockcult/integration_cog_install.ogg' //Yet another unexpectedly good bark sound
|
||||
|
||||
|
||||
// Genetics-only/admin-only sounds. These either clash hard with the audio design of the above sounds, or have some other form of audio design issue, but aren't *too* awful as a sometimes thing.
|
||||
// Rule of fun very much applies to this section. Audio design is extremely important for the above section, but down here? No gods, no masters, pure anarchy.
|
||||
// The min/max variables simply don't apply to these, as only chargen cares about them. As such, there's no need to define those.
|
||||
|
||||
/datum/bark/bikehorn
|
||||
name = "Bikehorn"
|
||||
id = "horn"
|
||||
soundpath = 'sound/instruments/bikehorn/Cn4.ogg'
|
||||
ignore = TRUE // This is an unusually quiet sound.
|
||||
|
||||
/datum/bark/bwoink
|
||||
name = "Bwoink"
|
||||
id = "bwoink"
|
||||
soundpath = 'sound/effects/adminhelp.ogg'
|
||||
ignore = TRUE // Emergent heart attack generation
|
||||
|
||||
/datum/bark/merp
|
||||
name = "Merp"
|
||||
id = "merp"
|
||||
soundpath = 'modular_citadel/sound/voice/merp.ogg'
|
||||
ignore = TRUE
|
||||
|
||||
/datum/bark/bark
|
||||
name = "Bark"
|
||||
id = "bark"
|
||||
soundpath = 'modular_citadel/sound/voice/bark1.ogg'
|
||||
ignore = TRUE
|
||||
|
||||
/datum/bark/nya
|
||||
name = "Nya"
|
||||
id = "nya"
|
||||
soundpath = 'modular_citadel/sound/voice/nya.ogg'
|
||||
ignore = TRUE
|
||||
|
||||
/datum/bark/moff
|
||||
name = "Moff"
|
||||
id = "moff"
|
||||
soundpath = 'modular_citadel/sound/voice/mothsqueak.ogg'
|
||||
ignore = TRUE
|
||||
|
||||
/datum/bark/weh
|
||||
name = "Weh"
|
||||
id = "weh"
|
||||
soundpath = 'modular_citadel/sound/voice/weh.ogg'
|
||||
ignore = TRUE
|
||||
|
||||
/datum/bark/honk
|
||||
name = "Annoying Honk"
|
||||
id = "honk"
|
||||
soundpath = 'sound/creatures/goose1.ogg'
|
||||
ignore = TRUE
|
||||
@@ -123,7 +123,7 @@
|
||||
trauma = _trauma
|
||||
return ..()
|
||||
|
||||
/mob/living/split_personality/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/split_personality/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(QDELETED(body))
|
||||
|
||||
@@ -164,6 +164,7 @@
|
||||
message.maptext_height = mheight
|
||||
message.maptext_x = (CHAT_MESSAGE_WIDTH - owner.bound_width) * -0.5
|
||||
message.maptext = MAPTEXT(complete_text)
|
||||
message.pixel_x = -owner.pixel_x //Dogborgs and other wide boys have a pixel offset. This accounts for that
|
||||
|
||||
// View the message
|
||||
LAZYADDASSOC(owned_by.seen_messages, message_loc, src)
|
||||
@@ -174,10 +175,6 @@
|
||||
scheduled_destruction = world.time + (lifespan - CHAT_MESSAGE_EOL_FADE)
|
||||
enter_subsystem()
|
||||
|
||||
var/mob/living/silicon/robot/R = target
|
||||
if(iscyborg(R))
|
||||
if((R.module.dogborg == TRUE || R.dogborg == TRUE) && isturf(R.loc)) //I hate whoever that thought that putting two types of dogborg that don't even sync up properly was good
|
||||
message.pixel_x = 16
|
||||
|
||||
/**
|
||||
* Applies final animations to overlay CHAT_MESSAGE_EOL_FADE deciseconds prior to message deletion
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
var/atom/movable/A = parent
|
||||
switch(rand(1, 3))
|
||||
if(1)
|
||||
A.do_jiggle(45 + rand(-10, 10) * bouncy_mod, 14)
|
||||
A.do_jiggle(25 + rand(-5, 5) * bouncy_mod, 14)
|
||||
if(2)
|
||||
var/min_b = 0.6/bouncy_mod
|
||||
var/max_b = 1.2 * bouncy_mod
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
name = "tea cup"
|
||||
desc = "A glass cup made for sipping tea!"
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
icon_state = "tea_plate"
|
||||
icon_state = "tea_cup"
|
||||
|
||||
//////////////////////Chem Disk/////////////////////
|
||||
//Two Steps //
|
||||
@@ -145,7 +145,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/glass_lens_part5
|
||||
name = "unpolished glass lens"
|
||||
name = "unpolished glass (lens)"
|
||||
desc = "An unpolished glass lens. It needs to be polished with some dry cloth."
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
icon_state = "glass_optics"
|
||||
@@ -159,7 +159,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/glass_lens_part6
|
||||
name = "unrefined glass lens"
|
||||
name = "unrefined glass (lens)"
|
||||
desc = "A polished glass lens. It needs to be refined with some sandstone."
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
icon_state = "glass_optics"
|
||||
@@ -179,7 +179,7 @@
|
||||
|
||||
/obj/item/glasswork/glass_base/spouty
|
||||
name = "Glass fodder sheet (spout)"
|
||||
desc = "A set of glass sheets set aside for glass working. This one is ideal for a spouty flask. It needs to heated with something very hot."
|
||||
desc = "A set of glass sheets set aside for glass working. This one is ideal for a spouty flask. It needs to be cut with some glassworking tools."
|
||||
next_step = /obj/item/glasswork/glass_base/spouty_part2
|
||||
|
||||
/obj/item/glasswork/glass_base/spouty/attackby(obj/item/I, mob/user, params)
|
||||
@@ -413,7 +413,7 @@
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_cupe2
|
||||
/obj/item/glasswork/glass_base/tea_cup2
|
||||
name = "glassblowing rod (tea cup)"
|
||||
desc = "A hollow metal rod made for blowing glass. There is a blob of shapen glass at the end of it that needs to be cut off with some glassworking tools."
|
||||
icon_state = "blowing_rods_inuse"
|
||||
@@ -433,7 +433,7 @@
|
||||
icon_state = "glass_base_half"
|
||||
next_step = /obj/item/glasswork/glass_base/tea_cup4
|
||||
|
||||
/obj/item/glasswork/glass_base/cup3/attackby(obj/item/I, mob/user, params)
|
||||
/obj/item/glasswork/glass_base/tea_cup3/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/stack/sheet/cloth))
|
||||
if(do_after(user,10, target = src))
|
||||
@@ -446,7 +446,7 @@
|
||||
icon_state = "glass_base_half"
|
||||
next_step = /obj/item/tea_cup
|
||||
|
||||
/obj/item/glasswork/glass_base/cup4/attackby(obj/item/I, mob/user, params)
|
||||
/obj/item/glasswork/glass_base/tea_cup4/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/stack/sheet/glass))
|
||||
if(do_after(user,10, target = src))
|
||||
|
||||
@@ -346,9 +346,9 @@
|
||||
|
||||
/datum/component/embedded/proc/examineTurf(datum/source, mob/user, list/examine_list)
|
||||
if(harmful)
|
||||
examine_list += "\t <a href='?src=[REF(src)];embedded_object=[REF(weapon)]' class='warning'>There is \a [weapon] embedded in [parent]!</a>"
|
||||
examine_list += "<a href='?src=[REF(src)];embedded_object=[REF(weapon)]' class='warning'>There is \a [weapon] embedded in [parent]!</a>"
|
||||
else
|
||||
examine_list += "\t <a href='?src=[REF(src)];embedded_object=[REF(weapon)]' class='warning'>There is \a [weapon] stuck to [parent]!</a>"
|
||||
examine_list += "<a href='?src=[REF(src)];embedded_object=[REF(weapon)]' class='warning'>There is \a [weapon] stuck to [parent]!</a>"
|
||||
|
||||
|
||||
/// Someone is ripping out the item from the turf by hand
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
if(identification_method_flags & ID_COMPONENT_EFFECT_NO_ACTIONS)
|
||||
return COMPONENT_NO_GRANT_ACTIONS
|
||||
|
||||
/datum/component/identification/proc/check_knowledge(mob/user)
|
||||
/datum/component/identification/proc/check_knowledge(datum/source, mob/user)
|
||||
return ID_COMPONENT_KNOWLEDGE_NONE
|
||||
|
||||
/datum/component/identification/proc/on_identify(mob/user)
|
||||
@@ -83,7 +83,7 @@
|
||||
*/
|
||||
/datum/component/identification/syndicate
|
||||
|
||||
/datum/component/identification/syndicate/check_knowledge(mob/user)
|
||||
/datum/component/identification/syndicate/check_knowledge(datum/source, mob/user)
|
||||
. = ..()
|
||||
if(user?.mind?.has_antag_datum(/datum/antagonist/traitor))
|
||||
. = max(., ID_COMPONENT_KNOWLEDGE_FULL)
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/datum/component/mood/proc/print_mood(mob/user)
|
||||
var/msg = "<span class='info'>*---------*\n<EM>Your current mood</EM>\n"
|
||||
var/msg = "<blockquote class='[sanity > SANITY_DISTURBED ? "nicegreen" : "warning"]'><span class='info'><EM>Your current mood</EM></span>\n"
|
||||
msg += "<span class='notice'>My mental status: </span>" //Long term
|
||||
switch(sanity)
|
||||
if(SANITY_GREAT to INFINITY)
|
||||
@@ -69,23 +69,23 @@
|
||||
msg += "<span class='notice'>My current mood: </span>" //Short term
|
||||
switch(mood_level)
|
||||
if(1)
|
||||
msg += "<span class='boldwarning'>I wish I was dead!<span>\n"
|
||||
msg += "<span class='boldwarning'>I wish I was dead!</span>\n"
|
||||
if(2)
|
||||
msg += "<span class='boldwarning'>I feel terrible...<span>\n"
|
||||
msg += "<span class='boldwarning'>I feel terrible...</span>\n"
|
||||
if(3)
|
||||
msg += "<span class='boldwarning'>I feel very upset.<span>\n"
|
||||
msg += "<span class='boldwarning'>I feel very upset.</span>\n"
|
||||
if(4)
|
||||
msg += "<span class='boldwarning'>I'm a bit sad.<span>\n"
|
||||
msg += "<span class='boldwarning'>I'm a bit sad.</span>\n"
|
||||
if(5)
|
||||
msg += "<span class='nicegreen'>I'm alright.<span>\n"
|
||||
msg += "<span class='nicegreen'>I'm alright.</span>\n"
|
||||
if(6)
|
||||
msg += "<span class='nicegreen'>I feel pretty okay.<span>\n"
|
||||
msg += "<span class='nicegreen'>I feel pretty okay.</span>\n"
|
||||
if(7)
|
||||
msg += "<span class='nicegreen'>I feel pretty good.<span>\n"
|
||||
msg += "<span class='nicegreen'>I feel pretty good.</span>\n"
|
||||
if(8)
|
||||
msg += "<span class='nicegreen'>I feel amazing!<span>\n"
|
||||
msg += "<span class='nicegreen'>I feel amazing!</span>\n"
|
||||
if(9)
|
||||
msg += "<span class='nicegreen'>I love life!<span>\n"
|
||||
msg += "<span class='nicegreen'>I love life!</span>\n"
|
||||
|
||||
msg += "<span class='notice'>Moodlets:\n</span>"//All moodlets
|
||||
if(mood_events.len)
|
||||
@@ -93,7 +93,8 @@
|
||||
var/datum/mood_event/event = mood_events[i]
|
||||
msg += event.description
|
||||
else
|
||||
msg += "<span class='nicegreen'>I don't have much of a reaction to anything right now.<span>\n"
|
||||
msg += "<span class='nicegreen'>I don't have much of a reaction to anything right now.</span>\n"
|
||||
msg += "</blockquote>"
|
||||
to_chat(user || parent, msg)
|
||||
|
||||
///Called after moodevent/s have been added/removed.
|
||||
|
||||
@@ -431,25 +431,26 @@
|
||||
if(M.incapacitated() || !M.canUseStorage())
|
||||
return
|
||||
var/atom/A = parent
|
||||
A.add_fingerprint(M)
|
||||
// this must come before the screen objects only block, dunno why it wasn't before
|
||||
if(over_object == M)
|
||||
user_show_to_mob(M, trigger_on_found = TRUE)
|
||||
if(isrevenant(M))
|
||||
INVOKE_ASYNC(GLOBAL_PROC, .proc/RevenantThrow, over_object, M, source)
|
||||
return
|
||||
if(check_locked(null, M) || !M.CanReach(A) || (!M.CanReach(over_object) && !istype(over_object, /atom/movable/screen)))
|
||||
return
|
||||
playsound(A, "rustle", 50, TRUE, -5)
|
||||
A.do_jiggle()
|
||||
A.add_fingerprint(M)
|
||||
if(!istype(over_object, /atom/movable/screen))
|
||||
INVOKE_ASYNC(src, .proc/dump_content_at, over_object, M)
|
||||
return
|
||||
if(A.loc != M)
|
||||
return
|
||||
playsound(A, "rustle", 50, TRUE, -5)
|
||||
A.do_jiggle()
|
||||
if(istype(over_object, /atom/movable/screen/inventory/hand))
|
||||
var/atom/movable/screen/inventory/hand/H = over_object
|
||||
M.putItemFromInventoryInHandIfPossible(A, H.held_index)
|
||||
return
|
||||
A.add_fingerprint(M)
|
||||
|
||||
/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE, trigger_on_found = FALSE)
|
||||
var/atom/A = parent
|
||||
|
||||
@@ -63,6 +63,8 @@
|
||||
if(QDELETED(O))
|
||||
continue
|
||||
var/atom/movable/screen/storage/item_holder/D = new(null, src, O)
|
||||
// SNOWFLAKE: make O opaque too, pending storage rewrite
|
||||
O.mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
D.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip"
|
||||
D.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
|
||||
O.maptext = ""
|
||||
@@ -138,6 +140,8 @@
|
||||
I = i
|
||||
var/percent = percentage_by_item[I]
|
||||
var/atom/movable/screen/storage/volumetric_box/center/B = new /atom/movable/screen/storage/volumetric_box/center(null, src, I)
|
||||
// SNOWFLAKE: force it to icon until we unfuck storage/click passing
|
||||
I.mouse_opacity = MOUSE_OPACITY_ICON
|
||||
var/pixels_to_use = overrun? MINIMUM_PIXELS_PER_ITEM : max(using_horizontal_pixels * percent, MINIMUM_PIXELS_PER_ITEM)
|
||||
var/addrow = FALSE
|
||||
if(CEILING(pixels_to_use, 1) >= FLOOR(horizontal_pixels - current_pixel - VOLUMETRIC_STORAGE_EDGE_PADDING, 1))
|
||||
|
||||
@@ -84,9 +84,9 @@
|
||||
if(VR)
|
||||
VR.level_below = src
|
||||
level_above = VR
|
||||
M.transfer_ckey(vr_M, FALSE)
|
||||
mastermind = M.mind
|
||||
mastermind.current.audiovisual_redirect = parent
|
||||
M.transfer_ckey(vr_M, FALSE)
|
||||
RegisterSignal(mastermind, COMSIG_PRE_MIND_TRANSFER, .proc/switch_player)
|
||||
RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING), .proc/game_over)
|
||||
RegisterSignal(M, COMSIG_MOB_PRE_PLAYER_CHANGE, .proc/player_hijacked)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
severity = DISEASE_SEVERITY_MEDIUM
|
||||
infectable_biotypes = MOB_ORGANIC|MOB_UNDEAD|MOB_ROBOTIC|MOB_MINERAL
|
||||
bypasses_immunity = TRUE //2spook
|
||||
var/mob/living/simple_animal/parrot/Poly/ghost/parrot
|
||||
var/mob/living/simple_animal/parrot/Polly/ghost/parrot
|
||||
|
||||
/datum/disease/parrot_possession/stage_act()
|
||||
..()
|
||||
|
||||
+27
-10
@@ -77,6 +77,7 @@
|
||||
new_dna.species = new species.type
|
||||
new_dna.species.say_mod = species.say_mod
|
||||
new_dna.species.exotic_blood_color = species.exotic_blood_color //it can change from the default value
|
||||
new_dna.species.exotic_blood_blend_mode = species.exotic_blood_blend_mode
|
||||
new_dna.species.eye_type = species.eye_type
|
||||
new_dna.species.limbs_id = species.limbs_id || species.id
|
||||
new_dna.real_name = real_name
|
||||
@@ -137,9 +138,9 @@
|
||||
L[DNA_SKIN_TONE_BLOCK] = construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len)
|
||||
L[DNA_LEFT_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.left_eye_color)
|
||||
L[DNA_RIGHT_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.right_eye_color)
|
||||
L[DNA_COLOR_ONE_BLOCK] = sanitize_hexcolor(features["mcolor"], 6)
|
||||
L[DNA_COLOR_TWO_BLOCK] = sanitize_hexcolor(features["mcolor2"], 6)
|
||||
L[DNA_COLOR_THREE_BLOCK] = sanitize_hexcolor(features["mcolor3"], 6)
|
||||
L[DNA_COLOR_ONE_BLOCK] = sanitize_hexcolor(features["mcolor"])
|
||||
L[DNA_COLOR_TWO_BLOCK] = sanitize_hexcolor(features["mcolor2"])
|
||||
L[DNA_COLOR_THREE_BLOCK] = sanitize_hexcolor(features["mcolor3"])
|
||||
if(!GLOB.mam_tails_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/mam_tails, GLOB.mam_tails_list)
|
||||
L[DNA_MUTANTTAIL_BLOCK] = construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len)
|
||||
@@ -152,6 +153,10 @@
|
||||
if(!GLOB.taur_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/taur, GLOB.taur_list)
|
||||
L[DNA_TAUR_BLOCK] = construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len)
|
||||
L[DNA_BARK_SOUND_BLOCK] = construct_block(GLOB.bark_list.Find(H.vocal_bark_id), GLOB.bark_list.len)
|
||||
L[DNA_BARK_SPEED_BLOCK] = construct_block(H.vocal_speed * 4, 16)
|
||||
L[DNA_BARK_PITCH_BLOCK] = construct_block(H.vocal_pitch * 30, 48)
|
||||
L[DNA_BARK_VARIANCE_BLOCK] = construct_block(H.vocal_pitch_range * 48, 48)
|
||||
|
||||
for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++)
|
||||
if(L[i])
|
||||
@@ -247,19 +252,19 @@
|
||||
if(DNA_HAIR_STYLE_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len))
|
||||
if(DNA_COLOR_ONE_BLOCK)
|
||||
sanitize_hexcolor(features["mcolor"], 6)
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(features["mcolor"]))
|
||||
if(DNA_COLOR_TWO_BLOCK)
|
||||
sanitize_hexcolor(features["mcolor2"], 6)
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(features["mcolor2"]))
|
||||
if(DNA_COLOR_THREE_BLOCK)
|
||||
sanitize_hexcolor(features["mcolor3"], 6)
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(features["mcolor3"]))
|
||||
if(DNA_MUTANTTAIL_BLOCK)
|
||||
construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len))
|
||||
if(DNA_MUTANTEAR_BLOCK)
|
||||
construct_block(GLOB.mam_ears_list.Find(features["mam_ears"]), GLOB.mam_ears_list.len)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.mam_ears_list.Find(features["mam_ears"]), GLOB.mam_ears_list.len))
|
||||
if(DNA_MUTANTMARKING_BLOCK)
|
||||
construct_block(GLOB.mam_body_markings_list.Find(features["mam_body_markings"]), GLOB.mam_body_markings_list.len)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.mam_body_markings_list.Find(features["mam_body_markings"]), GLOB.mam_body_markings_list.len))
|
||||
if(DNA_TAUR_BLOCK)
|
||||
construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len))
|
||||
if(species.mutant_bodyparts["taur"] && ishuman(holder))
|
||||
var/datum/sprite_accessory/taur/T = GLOB.taur_list[features["taur"]]
|
||||
switch(T?.taur_mode)
|
||||
@@ -271,6 +276,14 @@
|
||||
H.physiology.footstep_type = FOOTSTEP_MOB_CRAWL
|
||||
else
|
||||
H.physiology.footstep_type = null
|
||||
if(DNA_BARK_SOUND_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.bark_list.Find(H.vocal_bark_id), GLOB.bark_list.len))
|
||||
if(DNA_BARK_SPEED_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(H.vocal_speed * 4, 16))
|
||||
if(DNA_BARK_PITCH_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(H.vocal_pitch * 30, 48))
|
||||
if(DNA_BARK_VARIANCE_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(H.vocal_pitch_range * 48, 48))
|
||||
|
||||
//Please use add_mutation or activate_mutation instead
|
||||
/datum/dna/proc/force_give(datum/mutation/human/HM)
|
||||
@@ -490,6 +503,10 @@
|
||||
update_body_parts()
|
||||
if(mutations_overlay_update)
|
||||
update_mutations_overlay()
|
||||
set_bark(GLOB.bark_list[deconstruct_block(getblock(structure, DNA_BARK_SOUND_BLOCK), GLOB.bark_list.len)])
|
||||
vocal_speed = (deconstruct_block(getblock(structure, DNA_BARK_SPEED_BLOCK), 16) / 4)
|
||||
vocal_pitch = (deconstruct_block(getblock(structure, DNA_BARK_PITCH_BLOCK), 48) / 30)
|
||||
vocal_pitch_range = (deconstruct_block(getblock(structure, DNA_BARK_VARIANCE_BLOCK), 48) / 48)
|
||||
|
||||
|
||||
/mob/proc/domutcheck()
|
||||
|
||||
@@ -76,10 +76,10 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
|
||||
if(examine_full_view)
|
||||
examine_list += "[msg]"
|
||||
return
|
||||
if(length_char(msg) <= 40)
|
||||
if(length_char(msg) <= MAX_FLAVOR_PREVIEW_LEN)
|
||||
examine_list += "<span class='notice'>[msg]</span>"
|
||||
else
|
||||
examine_list += "<span class='notice'>[copytext_char(msg, 1, 37)]... <a href='?src=[REF(src)];show_flavor=[REF(target)]'>More...</span></a>"
|
||||
examine_list += "<span class='notice'>[copytext_char(msg, 1, (MAX_FLAVOR_PREVIEW_LEN - 3))]... <a href='?src=[REF(src)];show_flavor=[REF(target)]'>More...</span></a>"
|
||||
|
||||
/datum/element/flavor_text/Topic(href, href_list)
|
||||
. = ..()
|
||||
@@ -199,7 +199,7 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
|
||||
if(ismob(target))
|
||||
add_verb(target, /mob/proc/set_pose)
|
||||
|
||||
/datum/element/flavor_Text/carbon/temporary/Detach(datum/source, force)
|
||||
/datum/element/flavor_text/carbon/temporary/Detach(datum/source, force)
|
||||
. = ..()
|
||||
if(ismob(source))
|
||||
remove_verb(source, /mob/proc/set_pose)
|
||||
|
||||
@@ -136,13 +136,19 @@
|
||||
if (isnull(item))
|
||||
return FALSE
|
||||
|
||||
source.visible_message(
|
||||
span_warning("[user] tries to remove [source]'s [item.name]."),
|
||||
span_userdanger("[user] tries to remove your [item.name]."),
|
||||
ignored_mobs = user,
|
||||
)
|
||||
var/strip_silence
|
||||
var/obj/item/clothing/gloves/gloves = user.get_item_by_slot(ITEM_SLOT_GLOVES)
|
||||
if(istype(gloves))
|
||||
strip_silence = gloves.strip_silence
|
||||
|
||||
to_chat(user, span_danger("You try to remove [source]'s [item]..."))
|
||||
if(!strip_silence)
|
||||
source.visible_message(
|
||||
span_warning("[user] tries to remove [source]'s [item.name]."),
|
||||
span_userdanger("[user] tries to remove your [item.name]."),
|
||||
ignored_mobs = user,
|
||||
)
|
||||
|
||||
to_chat(user, strip_silence ? span_danger("You try to remove [source]'s [item]...") : span_notice("You try to remove [source]'s [item]..."))
|
||||
user.log_message("[key_name(source)] is being stripped of [item] by [key_name(user)]", LOG_ATTACK, color="red")
|
||||
source.log_message("[key_name(source)] is being stripped of [item] by [key_name(user)]", LOG_VICTIM, color="red", log_globally=FALSE)
|
||||
item.add_fingerprint(source)
|
||||
@@ -284,7 +290,12 @@
|
||||
|
||||
/// A utility function for `/datum/strippable_item`s to start unequipping an item from a mob.
|
||||
/proc/start_unequip_mob(obj/item/item, mob/source, mob/user, strip_delay)
|
||||
if (!do_mob(user, source, strip_delay || item.strip_delay, ignorehelditem = TRUE))
|
||||
var/strip_mod = 1
|
||||
var/obj/item/clothing/gloves/gloves = user.get_item_by_slot(ITEM_SLOT_GLOVES)
|
||||
if(istype(gloves))
|
||||
strip_mod = gloves.strip_mod
|
||||
|
||||
if (!do_mob(user, source, (strip_delay || item.strip_delay) / strip_mod, ignorehelditem = TRUE))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
// And yes this does have to be in the constructor, BYOND ignores it if you set it as a normal var
|
||||
|
||||
// Helper similar to image()
|
||||
/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE, color = "#FFFFFF")
|
||||
/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE, color = "#FFFFFF", blend_mode = BLEND_DEFAULT)
|
||||
var/mutable_appearance/MA = new()
|
||||
MA.icon = icon
|
||||
MA.icon_state = icon_state
|
||||
@@ -19,5 +19,6 @@
|
||||
MA.alpha = alpha
|
||||
MA.appearance_flags |= appearance_flags
|
||||
MA.color = color
|
||||
MA.blend_mode = blend_mode
|
||||
return MA
|
||||
|
||||
|
||||
@@ -120,6 +120,17 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/saymode/statusdisplay
|
||||
key = "q"
|
||||
mode = MODE_STATUSDISPLAY
|
||||
|
||||
/datum/saymode/statusdisplay/handle_message(mob/living/user, message, datum/language/language)
|
||||
if(isAI(user))
|
||||
var/mob/living/silicon/ai/AI = user
|
||||
AI.statusdisplay_talk(message, language)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/saymode/monkey
|
||||
key = "k"
|
||||
mode = MODE_MONKEY
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
/// should we immediately call on_spawn or add a timer to trigger
|
||||
var/on_spawn_immediate = TRUE
|
||||
var/mob/living/quirk_holder
|
||||
var/processing_quirk = FALSE
|
||||
|
||||
/datum/quirk/New(mob/living/quirk_mob, spawn_effects)
|
||||
if(!quirk_mob || (human_only && !ishuman(quirk_mob)) || quirk_mob.has_quirk(type))
|
||||
@@ -25,7 +26,8 @@
|
||||
quirk_holder.roundstart_quirks += src
|
||||
if(mob_trait)
|
||||
ADD_TRAIT(quirk_holder, mob_trait, ROUNDSTART_TRAIT)
|
||||
START_PROCESSING(SSquirks, src)
|
||||
if(processing_quirk)
|
||||
START_PROCESSING(SSquirks, src)
|
||||
add()
|
||||
if(spawn_effects)
|
||||
if(on_spawn_immediate)
|
||||
@@ -35,7 +37,8 @@
|
||||
addtimer(CALLBACK(src, .proc/post_add), 30)
|
||||
|
||||
/datum/quirk/Destroy()
|
||||
STOP_PROCESSING(SSquirks, src)
|
||||
if(processing_quirk)
|
||||
STOP_PROCESSING(SSquirks, src)
|
||||
remove()
|
||||
if(quirk_holder)
|
||||
to_chat(quirk_holder, lose_text)
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
mob_trait = TRAIT_JOLLY
|
||||
mood_quirk = TRUE
|
||||
medical_record_text = "Patient demonstrates constant euthymia irregular for environment. It's a bit much, to be honest."
|
||||
processing_quirk = TRUE
|
||||
|
||||
/datum/quirk/jolly/on_process()
|
||||
if(prob(0.05))
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
lose_text = "<span class='notice'>You no longer feel depressed.</span>" //if only it were that easy!
|
||||
medical_record_text = "Patient has a severe mood disorder, causing them to experience acute episodes of depression."
|
||||
mood_quirk = TRUE
|
||||
processing_quirk = TRUE
|
||||
|
||||
/datum/quirk/depression/on_process()
|
||||
if(prob(0.05))
|
||||
@@ -38,6 +39,7 @@
|
||||
medical_record_text = "Patient demonstrates an unnatural attachment to a family heirloom."
|
||||
var/obj/item/heirloom
|
||||
var/where
|
||||
processing_quirk = TRUE
|
||||
|
||||
GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
|
||||
@@ -102,6 +104,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
gain_text = "<span class='danger'>You feel smooth.</span>"
|
||||
lose_text = "<span class='notice'>You feel wrinkled again.</span>"
|
||||
medical_record_text = "Patient has a tumor in their brain that is slowly driving them to brain death."
|
||||
processing_quirk = TRUE
|
||||
|
||||
/datum/quirk/brainproblems/on_process()
|
||||
quirk_holder.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2)
|
||||
@@ -129,25 +132,38 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
value = -1
|
||||
medical_record_text = "Patient demonstrates a fear of the dark. (Seriously?)"
|
||||
|
||||
/datum/quirk/nyctophobia/on_process()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
if(H.dna.species.id in list("shadow", "nightmare"))
|
||||
return //we're tied with the dark, so we don't get scared of it; don't cleanse outright to avoid cheese
|
||||
var/turf/T = get_turf(quirk_holder)
|
||||
var/lums = T.get_lumcount()
|
||||
if(lums <= 0.2)
|
||||
if(quirk_holder.m_intent == MOVE_INTENT_RUN)
|
||||
addtimer(CALLBACK(src, .proc/recheck),2) //0.2 seconds of being in the dark
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "nyctophobia", /datum/mood_event/nyctophobia)
|
||||
else
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "nyctophobia")
|
||||
/datum/quirk/nyctophobia/add()
|
||||
RegisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED, .proc/on_holder_moved)
|
||||
|
||||
/datum/quirk/nyctophobia/proc/recheck()
|
||||
var/turf/T = get_turf(quirk_holder)
|
||||
var/lums = T.get_lumcount()
|
||||
if(lums <= 0.2) //check again, did they remain in the dark for 0.2 seconds?
|
||||
to_chat(quirk_holder, "<span class='warning'>Easy, easy, take it slow... you're in the dark...</span>")
|
||||
/datum/quirk/nyctophobia/remove()
|
||||
UnregisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED)
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "nyctophobia")
|
||||
|
||||
/// Called when the quirk holder moves. Updates the quirk holder's mood.
|
||||
/datum/quirk/nyctophobia/proc/on_holder_moved(mob/living/source, atom/old_loc, dir, forced)
|
||||
if(quirk_holder.stat != CONSCIOUS || quirk_holder.IsSleeping() || quirk_holder.IsUnconscious())
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/human_holder = quirk_holder
|
||||
|
||||
if(human_holder.dna?.species.id in list(SPECIES_SHADOW, SPECIES_NIGHTMARE))
|
||||
return
|
||||
|
||||
if((human_holder.sight & SEE_TURFS) == SEE_TURFS)
|
||||
return
|
||||
|
||||
var/turf/holder_turf = get_turf(quirk_holder)
|
||||
|
||||
var/lums = holder_turf.get_lumcount()
|
||||
|
||||
if(lums > 0.2)
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "nyctophobia")
|
||||
return
|
||||
|
||||
if(quirk_holder.m_intent == MOVE_INTENT_RUN)
|
||||
to_chat(quirk_holder, span_warning("Easy, easy, take it slow... you're in the dark..."))
|
||||
quirk_holder.toggle_move_intent()
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "nyctophobia", /datum/mood_event/nyctophobia)
|
||||
|
||||
/datum/quirk/lightless
|
||||
name = "Light Sensitivity"
|
||||
@@ -157,6 +173,36 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
lose_text = "<span class='notice'>Enlightening.</span>"
|
||||
medical_record_text = "Despite my warnings, the patient refuses turn on the lights, only to end up rolling down a full flight of stairs and into the cellar."
|
||||
|
||||
/datum/quirk/lightless/add()
|
||||
RegisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED, .proc/on_holder_moved)
|
||||
|
||||
/datum/quirk/lightless/remove()
|
||||
UnregisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED)
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "brightlight")
|
||||
|
||||
/datum/quirk/lightless/proc/on_holder_moved(mob/living/source, atom/old_loc, dir, forced)
|
||||
if(quirk_holder.stat != CONSCIOUS || quirk_holder.IsSleeping() || quirk_holder.IsUnconscious())
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/human_holder = quirk_holder
|
||||
|
||||
if(human_holder.dna?.species.id in list(SPECIES_SHADOW, SPECIES_NIGHTMARE))
|
||||
return
|
||||
|
||||
if((human_holder.sight & SEE_TURFS) == SEE_TURFS)
|
||||
return
|
||||
|
||||
var/turf/holder_turf = get_turf(quirk_holder)
|
||||
|
||||
var/lums = holder_turf.get_lumcount()
|
||||
|
||||
if(lums < 0.8)
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "brightlight")
|
||||
return
|
||||
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "brightlight", /datum/mood_event/brightlight)
|
||||
|
||||
|
||||
/datum/quirk/lightless/on_process()
|
||||
var/turf/T = get_turf(quirk_holder)
|
||||
var/lums = T.get_lumcount()
|
||||
@@ -236,6 +282,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
gain_text = "<span class='userdanger'>...</span>"
|
||||
lose_text = "<span class='notice'>You feel in tune with the world again.</span>"
|
||||
medical_record_text = "Patient suffers from acute Reality Dissociation Syndrome and experiences vivid hallucinations."
|
||||
processing_quirk = TRUE
|
||||
|
||||
/datum/quirk/insanity/on_process()
|
||||
if(quirk_holder.reagents.has_reagent(/datum/reagent/toxin/mindbreaker))
|
||||
@@ -261,6 +308,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
lose_text = "<span class='notice'>You feel easier about talking again.</span>" //if only it were that easy!
|
||||
medical_record_text = "Patient is usually anxious in social encounters and prefers to avoid them."
|
||||
var/dumb_thing = TRUE
|
||||
processing_quirk = TRUE
|
||||
|
||||
/datum/quirk/social_anxiety/add()
|
||||
RegisterSignal(quirk_holder, COMSIG_MOB_EYECONTACT, .proc/eye_contact)
|
||||
@@ -425,3 +473,21 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
gain_text = "<span class='notice'>You can't smell anything!</span>"
|
||||
lose_text = "<span class='notice'>You can smell again!</span>"
|
||||
medical_record_text = "Patient suffers from anosmia and is incapable of smelling gases or particulates."
|
||||
|
||||
/datum/quirk/paper_skin
|
||||
name = "Paper Skin"
|
||||
desc = "Your flesh is weaker, resulting in receiving cuts more easily."
|
||||
value = -1
|
||||
mob_trait = TRAIT_PAPER_SKIN
|
||||
gain_text = "<span class='notice'>Your flesh feels weak!</span>"
|
||||
lose_text = "<span class='notice'>Your flesh feels more durable!</span>"
|
||||
medical_record_text = "Patient suffers from weak flesh, resulting in them receiving cuts far more easily."
|
||||
|
||||
/datum/quirk/glass_bones
|
||||
name = "Glass Bones"
|
||||
desc = "Your bones are far more brittle, and more vulnerable to breakage."
|
||||
value = -1
|
||||
mob_trait = TRAIT_GLASS_BONES
|
||||
gain_text = "<span class='notice'>Your bones feels weak!</span>"
|
||||
lose_text = "<span class='notice'>Your bones feels more durable!</span>"
|
||||
medical_record_text = "Patient suffers from brittle bones, resulting in them receiving breakages far more easily."
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
if(WOUND_SEVERITY_LOSS)
|
||||
msg = "[victim.p_their(TRUE)] [limb.name] [description]." // different format
|
||||
msg = "<span class='notice'><i><b>[msg]</b></i></span>"
|
||||
return "\t[msg]"
|
||||
return "[msg]"
|
||||
|
||||
/// Whether a scar can currently be seen by the viewer
|
||||
/datum/scar/proc/is_visible(mob/viewer)
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
if(WOUND_INFECTION_SEPTIC to INFINITY)
|
||||
. += "Infection Level: <span class='deadsay'>LOSS IMMINENT</span>\n"
|
||||
if(infestation > sanitization)
|
||||
. += "\tSurgical debridement, antiobiotics/sterilizers, or regenerative mesh will rid infection. Paramedic UV penlights are also effective.\n"
|
||||
. += "Surgical debridement, antiobiotics/sterilizers, or regenerative mesh will rid infection. Paramedic UV penlights are also effective.\n"
|
||||
|
||||
if(flesh_damage > 0)
|
||||
. += "Flesh damage detected: Please apply ointment or regenerative mesh to allow recovery.\n"
|
||||
|
||||
@@ -212,6 +212,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED
|
||||
// airlock_wires = /datum/wires/airlock/maint
|
||||
sound_environment = SOUND_AREA_TUNNEL_ENCLOSED
|
||||
minimap_color = "#454545"
|
||||
|
||||
//Maintenance - Departmental
|
||||
|
||||
@@ -435,6 +436,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/hallway
|
||||
nightshift_public_area = NIGHTSHIFT_AREA_PUBLIC
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
minimap_color = "#aaaaaa"
|
||||
|
||||
/area/hallway/primary
|
||||
name = "Primary Hallway"
|
||||
@@ -490,6 +492,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/hallway/secondary/exit
|
||||
name = "Escape Shuttle Hallway"
|
||||
icon_state = "escape"
|
||||
minimap_color = "#baa0a0"
|
||||
|
||||
/area/hallway/secondary/exit/departure_lounge
|
||||
name = "Departure Lounge"
|
||||
@@ -498,6 +501,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/hallway/secondary/entry
|
||||
name = "Arrival Shuttle Hallway"
|
||||
icon_state = "entry"
|
||||
minimap_color = "#a0a0ba"
|
||||
|
||||
/area/hallway/secondary/service
|
||||
name = "Service Hallway"
|
||||
|
||||
@@ -124,6 +124,10 @@
|
||||
/// Color on minimaps, if it's null (which is default) it makes one at random.
|
||||
var/minimap_color
|
||||
|
||||
var/minimap_color2 // if this isn't null, then this will show as a checkerboard pattern mixed in with the above. works even if the above is null (for better or worse)
|
||||
|
||||
var/minimap_show_walls = TRUE
|
||||
|
||||
/**
|
||||
* These two vars allow for multiple unique areas to be linked to a master area
|
||||
* and share some functionalities such as APC powernet nodes, fire alarms etc, without sacrificing
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
ambientsounds = RUINS
|
||||
sound_environment = SOUND_ENVIRONMENT_STONEROOM
|
||||
var/valid_territory = FALSE // hey so what if we did not allow things like cult summons to appear on ruins
|
||||
minimap_color = "#775940"
|
||||
minimap_color2 = "#6b5d48"
|
||||
minimap_show_walls = FALSE
|
||||
|
||||
|
||||
/area/ruin/unpowered
|
||||
|
||||
+16
-5
@@ -518,7 +518,7 @@
|
||||
. = list("[get_examine_string(user, TRUE)].")
|
||||
|
||||
if(desc)
|
||||
. += desc
|
||||
. += "<hr>[desc]"
|
||||
|
||||
if(custom_materials)
|
||||
var/list/materials_list = list()
|
||||
@@ -702,7 +702,7 @@
|
||||
var/blood_id = get_blood_id()
|
||||
if(!(blood_id in GLOB.blood_reagent_types))
|
||||
return
|
||||
return list("color" = BLOOD_COLOR_HUMAN, "ANIMAL DNA" = "Y-")
|
||||
return list("color" = BLOOD_COLOR_HUMAN, "blendmode" = BLEND_MULTIPLY, "ANIMAL DNA" = "Y-")
|
||||
|
||||
/mob/living/carbon/get_blood_dna_list()
|
||||
var/blood_id = get_blood_id()
|
||||
@@ -711,14 +711,16 @@
|
||||
var/list/blood_dna = list()
|
||||
if(dna)
|
||||
blood_dna["color"] = dna.species.exotic_blood_color //so when combined, the list grows with the number of colors
|
||||
blood_dna["blendmode"] = dna.species.exotic_blood_blend_mode
|
||||
blood_dna[dna.unique_enzymes] = dna.blood_type
|
||||
else
|
||||
blood_dna["color"] = BLOOD_COLOR_HUMAN
|
||||
blood_dna["blendmode"] = BLEND_MULTIPLY
|
||||
blood_dna["UNKNOWN DNA"] = "X*"
|
||||
return blood_dna
|
||||
|
||||
/mob/living/carbon/alien/get_blood_dna_list()
|
||||
return list("color" = BLOOD_COLOR_XENO, "UNKNOWN DNA" = "X*")
|
||||
return list("color" = BLOOD_COLOR_XENO, "blendmode" = BLEND_MULTIPLY, "UNKNOWN DNA" = "X*")
|
||||
|
||||
//to add a mob's dna info into an object's blood_DNA list.
|
||||
/atom/proc/transfer_mob_blood_dna(mob/living/L)
|
||||
@@ -737,6 +739,7 @@
|
||||
var/old = blood_DNA["color"]
|
||||
blood_DNA["color"] = BlendRGB(blood_DNA["color"], new_blood_dna["color"])
|
||||
changed = old != blood_DNA["color"]
|
||||
blood_DNA["blendmode"] = new_blood_dna["blendmode"]
|
||||
if(blood_DNA.len == old_length)
|
||||
return FALSE
|
||||
return changed
|
||||
@@ -756,6 +759,7 @@
|
||||
blood_DNA["color"] = blood_dna["color"]
|
||||
else
|
||||
blood_DNA["color"] = BlendRGB(blood_DNA["color"], blood_dna["color"])
|
||||
blood_DNA["blendmode"] = blood_dna["blendmode"]
|
||||
|
||||
//to add blood from a mob onto something, and transfer their dna info
|
||||
/atom/proc/add_mob_blood(mob/living/M)
|
||||
@@ -826,6 +830,11 @@
|
||||
/atom/proc/blood_DNA_to_color()
|
||||
return (blood_DNA && blood_DNA["color"]) || BLOOD_COLOR_HUMAN
|
||||
|
||||
/atom/proc/blood_DNA_to_blend()
|
||||
if(blood_DNA && !isnull(blood_DNA["blendmode"]))
|
||||
return blood_DNA["blendmode"]
|
||||
return BLEND_MULTIPLY
|
||||
|
||||
/atom/proc/clean_blood()
|
||||
. = blood_DNA? TRUE : FALSE
|
||||
blood_DNA = null
|
||||
@@ -1192,6 +1201,8 @@
|
||||
log_mecha(log_text)
|
||||
if(LOG_SHUTTLE)
|
||||
log_shuttle(log_text)
|
||||
if(LOG_ECON)
|
||||
log_econ(log_text)
|
||||
else
|
||||
stack_trace("Invalid individual logging type: [message_type]. Defaulting to [LOG_GAME] (LOG_GAME).")
|
||||
log_game(log_text)
|
||||
@@ -1295,7 +1306,7 @@
|
||||
filters += filter(arglist(arguments))
|
||||
UNSETEMPTY(filter_data)
|
||||
|
||||
/atom/proc/transition_filter(name, time, list/new_params, easing, loop)
|
||||
/atom/proc/transition_filter(name, time, list/new_params, easing, loop, parallel = TRUE)
|
||||
var/filter = get_filter(name)
|
||||
if(!filter)
|
||||
return
|
||||
@@ -1306,7 +1317,7 @@
|
||||
for(var/thing in new_params)
|
||||
params[thing] = new_params[thing]
|
||||
|
||||
animate(filter, new_params, time = time, easing = easing, loop = loop)
|
||||
animate(filter, new_params, time = time, easing = easing, loop = loop, flags = (parallel ? ANIMATION_PARALLEL : 0))
|
||||
for(var/param in params)
|
||||
filter_data[name][param] = params[param]
|
||||
|
||||
|
||||
@@ -64,6 +64,16 @@
|
||||
/// last time we yelled
|
||||
var/last_yell = 0
|
||||
|
||||
// Text-to-bark sounds
|
||||
var/sound/vocal_bark
|
||||
var/vocal_bark_id
|
||||
var/vocal_pitch = 1
|
||||
var/vocal_pitch_range = 0.2 //Actual pitch is (pitch - (vocal_pitch_range*0.5)) to (pitch + (vocal_pitch_range*0.5))
|
||||
var/vocal_volume = 70 //Baseline. This gets modified by yelling and other factors
|
||||
var/vocal_speed = 4 //Lower values are faster, higher values are slower
|
||||
|
||||
var/vocal_current_bark //When barks are queued, this gets passed to the bark proc. If vocal_current_bark doesn't match the args passed to the bark proc (if passed at all), then the bark simply doesn't play. Basic curtailing of spam~
|
||||
|
||||
/atom/movable/Initialize(mapload)
|
||||
. = ..()
|
||||
switch(blocks_emissive)
|
||||
@@ -217,6 +227,10 @@
|
||||
if(NAMEOF(src, glide_size))
|
||||
set_glide_size(var_value)
|
||||
. = TRUE
|
||||
if(NAMEOF(src, vocal_bark))
|
||||
if(isfile(var_value))
|
||||
vocal_bark = sound(var_value) //bark() expects vocal_bark to already be a sound datum, for performance reasons. adminbus QoL!
|
||||
. = TRUE
|
||||
|
||||
if(!isnull(.))
|
||||
datum_flags |= DF_VAR_EDITED
|
||||
@@ -604,11 +618,11 @@
|
||||
if(throwing && !throw_override)
|
||||
return
|
||||
if(on && !(movement_type & FLOATING))
|
||||
animate(src, pixel_y = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
animate(pixel_y = -2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
setMovetype(movement_type | FLOATING)
|
||||
else if (!on && (movement_type & FLOATING))
|
||||
animate(src, pixel_y = initial(pixel_y), time = 10)
|
||||
animate(src, pixel_z = initial(pixel_y), time = 10)
|
||||
setMovetype(movement_type & ~FLOATING)
|
||||
floating_need_update = FALSE // assume it's done
|
||||
|
||||
@@ -696,6 +710,17 @@
|
||||
var/datum/language_holder/LH = get_language_holder()
|
||||
return LH.update_atom_languages(src)
|
||||
|
||||
/// Sets the vocal bark for the atom, using the bark's ID
|
||||
/atom/movable/proc/set_bark(id)
|
||||
if(!id)
|
||||
return FALSE
|
||||
var/datum/bark/B = GLOB.bark_list[id]
|
||||
if(!B)
|
||||
return FALSE
|
||||
vocal_bark = sound(initial(B.soundpath))
|
||||
vocal_bark_id = id
|
||||
return vocal_bark
|
||||
|
||||
/* End language procs */
|
||||
|
||||
|
||||
@@ -774,4 +799,4 @@
|
||||
M.Turn(pick(-30, 30))
|
||||
animate(I, alpha = 175, pixel_x = to_x, pixel_y = to_y, time = 3, transform = M, easing = CUBIC_EASING)
|
||||
sleep(1)
|
||||
animate(I, alpha = 0, transform = matrix(), time = 1)
|
||||
animate(I, alpha = 0, transform = matrix(), time = 1, flags = ANIMATION_PARALLEL)
|
||||
|
||||
@@ -104,6 +104,10 @@ Class Procs:
|
||||
anchored = TRUE
|
||||
interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT
|
||||
|
||||
vocal_bark_id = "synth"
|
||||
vocal_pitch = 0.6
|
||||
vocal_volume = 40
|
||||
|
||||
var/stat = 0
|
||||
var/use_power = IDLE_POWER_USE
|
||||
//0 = dont run the auto
|
||||
@@ -312,6 +316,36 @@ Class Procs:
|
||||
|
||||
return TRUE // If we passed all of those checks, woohoo! We can interact with this machine.
|
||||
|
||||
/obj/machinery/proc/can_transact(obj/item/card/id/thecard, allowdepartment, silent)
|
||||
if(!istype(thecard))
|
||||
if(!silent)
|
||||
say("No card found.")
|
||||
return FALSE
|
||||
else if (!thecard.registered_account)
|
||||
if(!silent)
|
||||
say("No account found.")
|
||||
return FALSE
|
||||
else if(!allowdepartment && !thecard.registered_account.account_job)
|
||||
if(!silent)
|
||||
say("Departmental accounts have been blacklisted from personal expenses due to embezzlement.")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/proc/attempt_transact(obj/item/card/id/thecard, transaction_cost)
|
||||
if(!istype(thecard))
|
||||
return FALSE
|
||||
var/datum/bank_account/account = thecard.registered_account
|
||||
if(!istype(account))
|
||||
return FALSE
|
||||
|
||||
if(transaction_cost)
|
||||
if(!account.adjust_money(-transaction_cost))
|
||||
return FALSE
|
||||
var/datum/bank_account/D = SSeconomy.get_dep_account(payment_department)
|
||||
if(D)
|
||||
D.adjust_money(transaction_cost)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/proc/check_nap_violations()
|
||||
if(!SSeconomy.full_ancap)
|
||||
return TRUE
|
||||
|
||||
@@ -62,14 +62,15 @@
|
||||
if(!is_operational())
|
||||
return
|
||||
|
||||
if(shocked && !(stat & NOPOWER))
|
||||
shock(user,50)
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Autolathe", capitalize(src.name))
|
||||
ui.open()
|
||||
|
||||
if(shocked && !(stat & NOPOWER))
|
||||
if(shock(user,50))
|
||||
ui.close() //close the window if they got zapped successfully as to prevent them from getting zapped infinitely.
|
||||
|
||||
/obj/machinery/autolathe/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["materials"] = list()
|
||||
@@ -298,6 +299,16 @@
|
||||
wires.interact(user)
|
||||
return STOP_ATTACK_PROC_CHAIN
|
||||
|
||||
/obj/machinery/autolathe/wirecutter_act(mob/living/user, obj/item/I)
|
||||
. = ..()
|
||||
if(busy)
|
||||
balloon_alert(user, "it's busy!")
|
||||
return STOP_ATTACK_PROC_CHAIN
|
||||
|
||||
if(panel_open)
|
||||
wires.interact(user)
|
||||
return STOP_ATTACK_PROC_CHAIN
|
||||
|
||||
/obj/machinery/autolathe/proc/AfterMaterialInsert(obj/item/item_inserted, id_inserted, amount_inserted)
|
||||
if(istype(item_inserted, /obj/item/stack/ore/bluespace_crystal))
|
||||
use_power(MINERAL_MATERIAL_AMOUNT / 10)
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#define COLORMATE_TINT 1
|
||||
#define COLORMATE_HSV 2
|
||||
#define COLORMATE_MATRIX 3
|
||||
|
||||
/obj/machinery/gear_painter
|
||||
name = "\improper Color Mate"
|
||||
desc = "A machine to give your apparel a fresh new color! Recommended to use with white items for best results."
|
||||
desc = "A machine to give your apparel a fresh new color!"
|
||||
icon = 'icons/obj/vending.dmi'
|
||||
icon_state = "colormate"
|
||||
// light_mask = "colormate-light-mask"
|
||||
@@ -10,7 +14,11 @@
|
||||
var/atom/movable/inserted
|
||||
var/activecolor = "#FFFFFF"
|
||||
var/list/color_matrix_last
|
||||
var/matrix_mode = FALSE
|
||||
var/active_mode = COLORMATE_HSV
|
||||
|
||||
var/build_hue = 0
|
||||
var/build_sat = 1
|
||||
var/build_val = 1
|
||||
/// Allow holder'd mobs
|
||||
var/allow_mobs = TRUE
|
||||
/// Minimum lightness for normal mode
|
||||
@@ -71,8 +79,8 @@
|
||||
return
|
||||
if(!QDELETED(H))
|
||||
H.release()
|
||||
|
||||
insert_mob(victim, user)
|
||||
temp = "[victim] has been inserted."
|
||||
SStgui.update_uis(src)
|
||||
|
||||
if(is_type_in_list(I, allowed_types) && is_operational())
|
||||
@@ -85,7 +93,6 @@
|
||||
|
||||
inserted = I
|
||||
update_icon()
|
||||
temp = "[I] has been inserted."
|
||||
SStgui.update_uis(src)
|
||||
|
||||
else
|
||||
@@ -134,7 +141,7 @@
|
||||
|
||||
/obj/machinery/gear_painter/ui_data(mob/user)
|
||||
. = list()
|
||||
.["matrixactive"] = matrix_mode
|
||||
.["activemode"] = active_mode
|
||||
.["matrixcolors"] = list(
|
||||
"rr" = color_matrix_last[1],
|
||||
"rg" = color_matrix_last[2],
|
||||
@@ -149,6 +156,9 @@
|
||||
"cg" = color_matrix_last[11],
|
||||
"cb" = color_matrix_last[12]
|
||||
)
|
||||
.["buildhue"] = build_hue
|
||||
.["buildsat"] = build_sat
|
||||
.["buildval"] = build_val
|
||||
if(temp)
|
||||
.["temp"] = temp
|
||||
if(inserted)
|
||||
@@ -166,7 +176,7 @@
|
||||
if(inserted)
|
||||
switch(action)
|
||||
if("switch_modes")
|
||||
matrix_mode = text2num(params["mode"])
|
||||
active_mode = text2num(params["mode"])
|
||||
return TRUE
|
||||
if("choose_color")
|
||||
var/chosen_color = input(usr, "Choose a color: ", "Colormate color picking", activecolor) as color|null
|
||||
@@ -174,14 +184,11 @@
|
||||
activecolor = chosen_color
|
||||
return TRUE
|
||||
if("paint")
|
||||
if(!check_valid_color(activecolor, usr))
|
||||
return TRUE
|
||||
inserted.add_atom_colour(activecolor, FIXED_COLOUR_PRIORITY)
|
||||
playsound(src, 'sound/effects/spray3.ogg', 50, 1)
|
||||
do_paint(usr)
|
||||
temp = "Painted Successfully!"
|
||||
return TRUE
|
||||
if("drop")
|
||||
temp = "Ejected \the [inserted]!"
|
||||
temp = ""
|
||||
drop_item()
|
||||
return TRUE
|
||||
if("clear")
|
||||
@@ -192,76 +199,95 @@
|
||||
if("set_matrix_color")
|
||||
color_matrix_last[params["color"]] = params["value"]
|
||||
return TRUE
|
||||
if("matrix_paint")
|
||||
var/list/cm = rgb_construct_color_matrix(
|
||||
text2num(color_matrix_last[1]),
|
||||
text2num(color_matrix_last[2]),
|
||||
text2num(color_matrix_last[3]),
|
||||
text2num(color_matrix_last[4]),
|
||||
text2num(color_matrix_last[5]),
|
||||
text2num(color_matrix_last[6]),
|
||||
text2num(color_matrix_last[7]),
|
||||
text2num(color_matrix_last[8]),
|
||||
text2num(color_matrix_last[9]),
|
||||
text2num(color_matrix_last[10]),
|
||||
text2num(color_matrix_last[11]),
|
||||
text2num(color_matrix_last[12])
|
||||
)
|
||||
if(!check_valid_color(cm, usr))
|
||||
return TRUE
|
||||
inserted.add_atom_colour(cm, FIXED_COLOUR_PRIORITY)
|
||||
playsound(src, 'sound/effects/spray3.ogg', 50, 1)
|
||||
temp = "Matrix Painted Successfully!"
|
||||
if("set_hue")
|
||||
build_hue = clamp(text2num(params["buildhue"]), 0, 360)
|
||||
return TRUE
|
||||
if("set_sat")
|
||||
build_sat = clamp(text2num(params["buildsat"]), -10, 10)
|
||||
return TRUE
|
||||
if("set_val")
|
||||
build_val = clamp(text2num(params["buildval"]), -10, 10)
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/machinery/gear_painter/proc/do_paint(mob/user)
|
||||
var/color_to_use
|
||||
switch(active_mode)
|
||||
if(COLORMATE_TINT)
|
||||
color_to_use = activecolor
|
||||
if(COLORMATE_MATRIX)
|
||||
color_to_use = rgb_construct_color_matrix(
|
||||
text2num(color_matrix_last[1]),
|
||||
text2num(color_matrix_last[2]),
|
||||
text2num(color_matrix_last[3]),
|
||||
text2num(color_matrix_last[4]),
|
||||
text2num(color_matrix_last[5]),
|
||||
text2num(color_matrix_last[6]),
|
||||
text2num(color_matrix_last[7]),
|
||||
text2num(color_matrix_last[8]),
|
||||
text2num(color_matrix_last[9]),
|
||||
text2num(color_matrix_last[10]),
|
||||
text2num(color_matrix_last[11]),
|
||||
text2num(color_matrix_last[12])
|
||||
)
|
||||
if(COLORMATE_HSV)
|
||||
color_to_use = color_matrix_hsv(build_hue, build_sat, build_val)
|
||||
color_matrix_last = color_to_use
|
||||
if(!color_to_use || !check_valid_color(color_to_use, user))
|
||||
to_chat(user, "<span class='notice'>Invalid color.</span>")
|
||||
return FALSE
|
||||
inserted.add_atom_colour(color_to_use, FIXED_COLOUR_PRIORITY)
|
||||
playsound(src, 'sound/effects/spray3.ogg', 50, 1)
|
||||
return TRUE
|
||||
|
||||
|
||||
/// Produces the preview image of the item, used in the UI, the way the color is not stacking is a sin.
|
||||
/obj/machinery/gear_painter/proc/build_preview()
|
||||
if(inserted) //sanity
|
||||
if(matrix_mode)
|
||||
var/list/cm = rgb_construct_color_matrix(
|
||||
text2num(color_matrix_last[1]),
|
||||
text2num(color_matrix_last[2]),
|
||||
text2num(color_matrix_last[3]),
|
||||
text2num(color_matrix_last[4]),
|
||||
text2num(color_matrix_last[5]),
|
||||
text2num(color_matrix_last[6]),
|
||||
text2num(color_matrix_last[7]),
|
||||
text2num(color_matrix_last[8]),
|
||||
text2num(color_matrix_last[9]),
|
||||
text2num(color_matrix_last[10]),
|
||||
text2num(color_matrix_last[11]),
|
||||
text2num(color_matrix_last[12])
|
||||
)
|
||||
if(!check_valid_color(cm, usr))
|
||||
temp = "Failed to generate preview: Invalid color!"
|
||||
return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE)
|
||||
var/list/cm
|
||||
switch(active_mode)
|
||||
if(COLORMATE_MATRIX)
|
||||
cm = rgb_construct_color_matrix(
|
||||
text2num(color_matrix_last[1]),
|
||||
text2num(color_matrix_last[2]),
|
||||
text2num(color_matrix_last[3]),
|
||||
text2num(color_matrix_last[4]),
|
||||
text2num(color_matrix_last[5]),
|
||||
text2num(color_matrix_last[6]),
|
||||
text2num(color_matrix_last[7]),
|
||||
text2num(color_matrix_last[8]),
|
||||
text2num(color_matrix_last[9]),
|
||||
text2num(color_matrix_last[10]),
|
||||
text2num(color_matrix_last[11]),
|
||||
text2num(color_matrix_last[12])
|
||||
)
|
||||
if(!check_valid_color(cm, usr))
|
||||
return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE)
|
||||
|
||||
var/cur_color = inserted.color
|
||||
inserted.color = null
|
||||
inserted.color = cm
|
||||
var/icon/preview = getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE)
|
||||
inserted.color = cur_color
|
||||
if(COLORMATE_TINT)
|
||||
if(!check_valid_color(activecolor, usr))
|
||||
return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE)
|
||||
|
||||
. = preview
|
||||
if(COLORMATE_HSV)
|
||||
cm = color_matrix_hsv(build_hue, build_sat, build_val)
|
||||
color_matrix_last = cm
|
||||
if(!check_valid_color(cm, usr))
|
||||
return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE)
|
||||
|
||||
else
|
||||
if(!check_valid_color(activecolor, usr))
|
||||
temp = "Failed to generate preview: Invalid color!"
|
||||
return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE)
|
||||
var/cur_color = inserted.color
|
||||
inserted.color = null
|
||||
inserted.color = (active_mode == COLORMATE_TINT ? activecolor : cm)
|
||||
var/icon/preview = getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE)
|
||||
inserted.color = cur_color
|
||||
temp = ""
|
||||
|
||||
var/cur_color = inserted.color
|
||||
inserted.color = null
|
||||
inserted.color = activecolor
|
||||
var/icon/preview = getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE)
|
||||
inserted.color = cur_color
|
||||
|
||||
. = preview
|
||||
. = preview
|
||||
|
||||
/obj/machinery/gear_painter/proc/check_valid_color(list/cm, mob/user)
|
||||
if(!islist(cm)) // normal
|
||||
var/list/HSV = ReadHSV(RGBtoHSV(cm))
|
||||
if(HSV[3] < minimum_normal_lightness)
|
||||
temp = "[cm] is far too dark (min lightness [minimum_normal_lightness]!"
|
||||
temp = "[cm] is too dark (Minimum lightness: [minimum_normal_lightness])"
|
||||
return FALSE
|
||||
return TRUE
|
||||
else // matrix
|
||||
@@ -275,6 +301,6 @@
|
||||
COLORTEST("FFFFFF", cm)
|
||||
#undef COLORTEST
|
||||
if(passed < minimum_matrix_tests)
|
||||
temp = "[english_list(color)] is not allowed (passed [passed] out of 4, minimum [minimum_matrix_tests], minimum lightness [minimum_matrix_lightness])."
|
||||
temp = "Matrix is too dark. (passed [passed] out of [minimum_matrix_tests] required tests. Minimum lightness: [minimum_matrix_lightness])."
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -6,17 +6,22 @@
|
||||
verb_say = "states"
|
||||
density = TRUE
|
||||
req_one_access = list(ACCESS_BAR, ACCESS_KITCHEN, ACCESS_HYDROPONICS, ACCESS_ENGINE, ACCESS_CARGO, ACCESS_THEATRE)
|
||||
payment_department = ACCOUNT_SRV
|
||||
var/active = FALSE
|
||||
var/list/rangers = list()
|
||||
var/stop = 0
|
||||
var/volume = 70
|
||||
var/datum/track/selection = null
|
||||
var/queuecost = PRICE_CHEAP //Set to -1 to make this jukebox require access for queueing
|
||||
var/datum/track/playing = null
|
||||
var/datum/track/selectedtrack = null
|
||||
var/list/queuedplaylist = list()
|
||||
var/queuecooldown //This var exists solely to prevent accidental repeats of John Mulaney's 'What's New Pussycat?' incident. Intentional, however......
|
||||
|
||||
/obj/machinery/jukebox/disco
|
||||
name = "radiant dance machine mark IV"
|
||||
desc = "The first three prototypes were discontinued after mass casualty incidents."
|
||||
icon_state = "disco"
|
||||
req_access = list(ACCESS_ENGINE)
|
||||
req_one_access = list(ACCESS_ENGINE)
|
||||
anchored = FALSE
|
||||
var/list/spotlights = list()
|
||||
var/list/sparkles = list()
|
||||
@@ -24,7 +29,7 @@
|
||||
/obj/machinery/jukebox/disco/indestructible
|
||||
name = "radiant dance machine mark V"
|
||||
desc = "Now redesigned with data gathered from the extensive disco and plasma research."
|
||||
req_access = null
|
||||
req_one_access = null
|
||||
anchored = TRUE
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
flags_1 = NODECONSTRUCT_1
|
||||
@@ -46,6 +51,16 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/jukebox/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(obj_flags & EMAGGED)
|
||||
return
|
||||
obj_flags |= EMAGGED
|
||||
queuecost = PRICE_FREE
|
||||
req_one_access = null
|
||||
to_chat(user, "<span class='notice'>You've bypassed [src]'s audio volume limiter, and enabled free play.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/jukebox/update_icon_state()
|
||||
if(active)
|
||||
icon_state = "[initial(icon_state)]-active"
|
||||
@@ -56,7 +71,7 @@
|
||||
if(!anchored)
|
||||
to_chat(user,"<span class='warning'>This device must be anchored by a wrench!</span>")
|
||||
return UI_CLOSE
|
||||
if(!allowed(user) && !isobserver(user))
|
||||
if((queuecost < 0 && !allowed(user)) && !isobserver(user))
|
||||
to_chat(user,"<span class='warning'>Error: Access Denied.</span>")
|
||||
user.playsound_local(src, 'sound/misc/compiler-failure.ogg', 25, TRUE)
|
||||
return UI_CLOSE
|
||||
@@ -77,18 +92,21 @@
|
||||
data["active"] = active
|
||||
data["songs"] = list()
|
||||
for(var/datum/track/S in SSjukeboxes.songs)
|
||||
var/list/track_data = list(
|
||||
name = S.song_name
|
||||
)
|
||||
var/list/track_data = list(name = S.song_name)
|
||||
data["songs"] += list(track_data)
|
||||
data["queued_tracks"] = list()
|
||||
for(var/datum/track/S in queuedplaylist)
|
||||
var/list/track_data = list(name = S.song_name)
|
||||
data["queued_tracks"] += list(track_data)
|
||||
data["track_selected"] = null
|
||||
data["track_length"] = null
|
||||
data["track_beat"] = null
|
||||
if(selection)
|
||||
data["track_selected"] = selection.song_name
|
||||
data["track_length"] = DisplayTimeText(selection.song_length)
|
||||
data["track_beat"] = selection.song_beat
|
||||
if(playing)
|
||||
data["track_selected"] = playing.song_name
|
||||
data["track_length"] = DisplayTimeText(playing.song_length)
|
||||
data["volume"] = volume
|
||||
data["is_emagged"] = (obj_flags & EMAGGED)
|
||||
data["cost_for_play"] = queuecost
|
||||
data["has_access"] = allowed(user)
|
||||
return data
|
||||
|
||||
/obj/machinery/jukebox/ui_act(action, list/params)
|
||||
@@ -100,57 +118,91 @@
|
||||
if("toggle")
|
||||
if(QDELETED(src))
|
||||
return
|
||||
if(!active)
|
||||
if(stop > world.time)
|
||||
to_chat(usr, "<span class='warning'>Error: The device is still resetting from the last activation, it will be ready again in [DisplayTimeText(stop-world.time)].</span>")
|
||||
playsound(src, 'sound/misc/compiler-failure.ogg', 50, TRUE)
|
||||
return
|
||||
if(!allowed(usr))
|
||||
return
|
||||
if(!active && !playing)
|
||||
activate_music()
|
||||
START_PROCESSING(SSobj, src)
|
||||
return TRUE
|
||||
else
|
||||
stop = 0
|
||||
return TRUE
|
||||
if("select_track")
|
||||
if(active)
|
||||
to_chat(usr, "<span class='warning'>Error: You cannot change the song until the current one is over.</span>")
|
||||
return TRUE
|
||||
if("add_to_queue")
|
||||
if(QDELETED(src))
|
||||
return
|
||||
if(world.time < queuecooldown)
|
||||
return
|
||||
if(!istype(selectedtrack, /datum/track))
|
||||
return
|
||||
if(!allowed(usr) && queuecost)
|
||||
var/obj/item/card/id/C
|
||||
if(isliving(usr))
|
||||
var/mob/living/L = usr
|
||||
C = L.get_idcard(TRUE)
|
||||
if(!can_transact(C))
|
||||
queuecooldown = world.time + (1 SECONDS)
|
||||
playsound(src, 'sound/misc/compiler-failure.ogg', 25, TRUE)
|
||||
return
|
||||
if(!attempt_transact(C, queuecost))
|
||||
say("Insufficient funds.")
|
||||
queuecooldown = world.time + (1 SECONDS)
|
||||
playsound(src, 'sound/misc/compiler-failure.ogg', 25, TRUE)
|
||||
return
|
||||
to_chat(usr, "<span class='notice'>You spend [queuecost] credits to queue [selectedtrack.song_name].</span>")
|
||||
log_econ("[queuecost] credits were inserted into [src] by [key_name(usr)] (ID: [C.registered_name]) to queue [selectedtrack.song_name].")
|
||||
queuedplaylist += selectedtrack
|
||||
if(active)
|
||||
say("[selectedtrack.song_name] has been added to the queue.")
|
||||
else if(!playing)
|
||||
activate_music()
|
||||
playsound(src, 'sound/machines/ping.ogg', 50, TRUE)
|
||||
queuecooldown = world.time + (3 SECONDS)
|
||||
return TRUE
|
||||
if("select_track")
|
||||
var/list/available = list()
|
||||
for(var/datum/track/S in SSjukeboxes.songs)
|
||||
available[S.song_name] = S
|
||||
var/selected = params["track"]
|
||||
if(QDELETED(src) || !selected || !istype(available[selected], /datum/track))
|
||||
return
|
||||
selection = available[selected]
|
||||
selectedtrack = available[selected]
|
||||
return TRUE
|
||||
if("set_volume")
|
||||
if(!allowed(usr))
|
||||
return
|
||||
var/new_volume = params["volume"]
|
||||
if(new_volume == "reset")
|
||||
volume = initial(volume)
|
||||
return TRUE
|
||||
else if(new_volume == "min")
|
||||
volume = 0
|
||||
return TRUE
|
||||
else if(new_volume == "max")
|
||||
volume = 100
|
||||
return TRUE
|
||||
volume = ((obj_flags & EMAGGED) ? 210 : 100)
|
||||
else if(text2num(new_volume) != null)
|
||||
volume = text2num(new_volume)
|
||||
return TRUE
|
||||
volume = clamp(0, text2num(new_volume), ((obj_flags & EMAGGED) ? 210 : 100))
|
||||
var/wherejuke = SSjukeboxes.findjukeboxindex(src)
|
||||
if(wherejuke)
|
||||
SSjukeboxes.updatejukebox(wherejuke, jukefalloff = volume/35)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/jukebox/proc/activate_music()
|
||||
var/jukeboxslottotake = SSjukeboxes.addjukebox(src, selection, 2)
|
||||
if(playing || !queuedplaylist.len)
|
||||
return FALSE
|
||||
playing = queuedplaylist[1]
|
||||
var/jukeboxslottotake = SSjukeboxes.addjukebox(src, playing, volume/35)
|
||||
if(jukeboxslottotake)
|
||||
active = TRUE
|
||||
update_icon()
|
||||
START_PROCESSING(SSobj, src)
|
||||
stop = world.time + selection.song_length
|
||||
stop = world.time + playing.song_length
|
||||
queuedplaylist.Cut(1, 2)
|
||||
say("Now playing: [playing.song_name]")
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, TRUE)
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/jukebox/disco/activate_music()
|
||||
..()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
dance_setup()
|
||||
lights_spin()
|
||||
|
||||
@@ -243,7 +295,7 @@
|
||||
S.pixel_y = 7
|
||||
S.forceMove(get_turf(src))
|
||||
sleep(7)
|
||||
if(selection.song_name == "Engineering's Ultimate High-Energy Hustle")
|
||||
if(playing.song_name == "Engineering's Ultimate High-Energy Hustle")
|
||||
sleep(280)
|
||||
for(var/obj/reveal in sparkles)
|
||||
reveal.alpha = 255
|
||||
@@ -299,7 +351,7 @@
|
||||
continue
|
||||
if(prob(2)) // Unique effects for the dance floor that show up randomly to mix things up
|
||||
INVOKE_ASYNC(src, .proc/hierofunk)
|
||||
sleep(selection.song_beat)
|
||||
sleep(playing.song_beat)
|
||||
|
||||
#undef DISCO_INFENO_RANGE
|
||||
|
||||
@@ -431,6 +483,7 @@
|
||||
return
|
||||
SSjukeboxes.removejukebox(position)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
playing = null
|
||||
rangers = list()
|
||||
|
||||
/obj/machinery/jukebox/disco/dance_over()
|
||||
@@ -439,12 +492,21 @@
|
||||
QDEL_LIST(sparkles)
|
||||
|
||||
/obj/machinery/jukebox/process()
|
||||
if(active && world.time >= stop)
|
||||
active = FALSE
|
||||
dance_over()
|
||||
playsound(src,'sound/machines/terminal_off.ogg',50,1)
|
||||
update_icon()
|
||||
stop = world.time + 100
|
||||
if(active)
|
||||
if(world.time >= stop)
|
||||
active = FALSE
|
||||
dance_over()
|
||||
if(stop && queuedplaylist.len)
|
||||
activate_music()
|
||||
else
|
||||
playsound(src,'sound/machines/terminal_off.ogg',50,1)
|
||||
update_icon()
|
||||
playing = null
|
||||
stop = 0
|
||||
else if(volume > 140) // BOOM BOOM BOOM BOOM
|
||||
for(var/mob/living/carbon/C in hearers(round(volume/35), src)) // I WANT YOU IN MY ROOM
|
||||
if(istype(C)) // LETS SPEND THE NIGHT TOGETHER
|
||||
C.adjustEarDamage(max((((volume/35) - sqrt(get_dist(C, src) * 4)) - C.get_ear_protection())*0.1, 0)) // FROM NOW UNTIL FOREVER
|
||||
|
||||
|
||||
/obj/machinery/jukebox/disco/process()
|
||||
|
||||
@@ -1356,6 +1356,7 @@
|
||||
/obj/machinery/door/airlock/proc/remove_electrify()
|
||||
secondsElectrified = NOT_ELECTRIFIED
|
||||
unelectrify_timerid = null
|
||||
diag_hud_set_electrified()
|
||||
|
||||
/obj/machinery/door/airlock/proc/set_electrified(seconds, mob/user)
|
||||
secondsElectrified = seconds
|
||||
|
||||
@@ -203,9 +203,13 @@ GLOBAL_LIST_EMPTY(doppler_arrays)
|
||||
point_gain = (BOMB_TARGET_POINTS * 2 * orig_light) / (orig_light + BOMB_TARGET_SIZE)
|
||||
|
||||
/*****The Point Capper*****/
|
||||
if(point_gain > linked_techweb.largest_bomb_value)
|
||||
var/old_tech_largest_bomb_value = linked_techweb.largest_bomb_value //held so we can pull old before we do math
|
||||
linked_techweb.largest_bomb_value = point_gain
|
||||
|
||||
var/list/largest_values = linked_techweb.largest_values
|
||||
if(!(LARGEST_BOMB in largest_values))
|
||||
largest_values[LARGEST_BOMB] = 0
|
||||
if(point_gain > largest_values[LARGEST_BOMB])
|
||||
var/old_tech_largest_bomb_value = largest_values[LARGEST_BOMB] //held so we can pull old before we do math
|
||||
linked_techweb.largest_values[LARGEST_BOMB] = point_gain
|
||||
point_gain -= old_tech_largest_bomb_value
|
||||
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_SCI)
|
||||
if(D)
|
||||
|
||||
@@ -230,13 +230,13 @@
|
||||
|
||||
if(beaker)
|
||||
if(beaker.reagents && beaker.reagents.reagent_list.len)
|
||||
. += "\t<span class='notice'>Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.</span>\n"
|
||||
. += "<span class='notice'>Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.</span>\n"
|
||||
else
|
||||
. += "\t<span class='notice'>Attached is an empty [beaker.name].</span>\n"
|
||||
. += "<span class='notice'>Attached is an empty [beaker.name].</span>\n"
|
||||
else
|
||||
. += "\t<span class='notice'>No chemicals are attached.</span>\n"
|
||||
. += "<span class='notice'>No chemicals are attached.</span>\n"
|
||||
|
||||
. += "\t<span class='notice'>[attached ? attached : "No one"] is attached.</span>"
|
||||
. += "<span class='notice'>[attached ? attached : "No one"] is attached.</span>"
|
||||
|
||||
/obj/machinery/iv_drip/telescopic
|
||||
name = "telescopic IV drip"
|
||||
|
||||
@@ -13,6 +13,17 @@
|
||||
#define TURRET_FLAG_SHOOT_BORGS (1<<6) // checks if it can shoot cyborgs
|
||||
#define TURRET_FLAG_SHOOT_HEADS (1<<7) // checks if it can shoot at heads of staff
|
||||
|
||||
DEFINE_BITFIELD(turret_flags, list(
|
||||
"TURRET_FLAG_AUTH_WEAPONS" = TURRET_FLAG_AUTH_WEAPONS,
|
||||
"TURRET_FLAG_SHOOT_ALL" = TURRET_FLAG_SHOOT_ALL,
|
||||
"TURRET_FLAG_SHOOT_ALL_REACT" = TURRET_FLAG_SHOOT_ALL_REACT,
|
||||
"TURRET_FLAG_SHOOT_ANOMALOUS" = TURRET_FLAG_SHOOT_ANOMALOUS,
|
||||
"TURRET_FLAG_SHOOT_BORGS" = TURRET_FLAG_SHOOT_BORGS,
|
||||
"TURRET_FLAG_SHOOT_CRIMINALS" = TURRET_FLAG_SHOOT_CRIMINALS,
|
||||
"TURRET_FLAG_SHOOT_HEADS" = TURRET_FLAG_SHOOT_HEADS,
|
||||
"TURRET_FLAG_SHOOT_UNSHIELDED" = TURRET_FLAG_SHOOT_UNSHIELDED,
|
||||
))
|
||||
|
||||
/obj/machinery/porta_turret
|
||||
name = "turret"
|
||||
icon = 'icons/obj/turrets.dmi'
|
||||
|
||||
@@ -29,10 +29,12 @@
|
||||
|
||||
var/obj/effect/overlay/status_display_text/message1_overlay
|
||||
var/obj/effect/overlay/status_display_text/message2_overlay
|
||||
var/mutable_appearance/ai_vtuber_overlay
|
||||
var/current_picture = ""
|
||||
var/current_mode = SD_BLANK
|
||||
var/message1 = ""
|
||||
var/message2 = ""
|
||||
var/mob/living/silicon/ai/master
|
||||
|
||||
/obj/item/wallframe/status_display
|
||||
name = "status display frame"
|
||||
@@ -122,6 +124,10 @@
|
||||
if(overlay && message == overlay.message)
|
||||
return null
|
||||
|
||||
// if an AI is controlling, we don't update the overlay
|
||||
if(master)
|
||||
return
|
||||
|
||||
if(overlay)
|
||||
qdel(overlay)
|
||||
|
||||
@@ -147,6 +153,10 @@
|
||||
remove_messages()
|
||||
return
|
||||
|
||||
if(master)
|
||||
remove_messages()
|
||||
return
|
||||
|
||||
switch(current_mode)
|
||||
if(SD_BLANK)
|
||||
remove_messages()
|
||||
@@ -493,6 +503,42 @@
|
||||
user.emote(initial(emote.key))
|
||||
break
|
||||
|
||||
// ai vtuber moment
|
||||
/obj/machinery/status_display/AICtrlClick(mob/living/silicon/ai/user)
|
||||
if(!isAI(user) || master || (user.current && !istype(user.current, /obj/machinery/status_display))) // don't let two AIs control the same one, don't let AI control two things at once
|
||||
return
|
||||
|
||||
if(!user.client.prefs.custom_holoform_icon)
|
||||
to_chat(user, span_notice("You have no custom holoform set!"))
|
||||
return
|
||||
|
||||
// move AI to the location, set master, update overlays (removes messages)
|
||||
user.current = src
|
||||
user.eyeobj.setLoc(get_turf(src))
|
||||
icon_state = initial(icon_state)
|
||||
user.controlled_display = src
|
||||
master = user
|
||||
update_overlays()
|
||||
update_appearance()
|
||||
|
||||
// we set the avatar here
|
||||
var/icon/I = icon(user.client.prefs.custom_holoform_icon)
|
||||
I.Crop(1,16,32,32)
|
||||
ai_vtuber_overlay = mutable_appearance(I)
|
||||
ai_vtuber_overlay.blend_mode = BLEND_ADD
|
||||
ai_vtuber_overlay.pixel_y = 8
|
||||
update_overlays()
|
||||
add_overlay(ai_vtuber_overlay)
|
||||
|
||||
// tell the user how to speak
|
||||
to_chat(user, span_notice("Use :q to relay messages through the status display."))
|
||||
|
||||
// modified version of how holopads 'hear' and relay to AIs
|
||||
/obj/machinery/status_display/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods = list())
|
||||
. = ..()
|
||||
if(master && !radio_freq && master.controlled_display == src)
|
||||
master.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans, message_mods)
|
||||
|
||||
/obj/machinery/status_display/ai/process()
|
||||
if(stat & NOPOWER)
|
||||
update_appearance()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
desc = "They look bloody and gruesome."
|
||||
icon_state = "gibbl5"
|
||||
layer = LOW_OBJ_LAYER
|
||||
blend_mode = BLEND_DEFAULT
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
|
||||
mergeable_decal = FALSE
|
||||
bloodiness = 0 //This isn't supposed to be bloody.
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
desc = "It's gooey. Perhaps it's the chef's cooking?"
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "floor1"
|
||||
blend_mode = BLEND_MULTIPLY
|
||||
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
|
||||
blood_state = BLOOD_STATE_BLOOD
|
||||
bloodiness = BLOOD_AMOUNT_PER_DECAL
|
||||
@@ -33,16 +34,20 @@
|
||||
. = ..()
|
||||
if(!fixed_color)
|
||||
add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
|
||||
blend_mode = blood_DNA_to_blend()
|
||||
|
||||
/obj/effect/decal/cleanable/blood/PersistenceSave(list/data)
|
||||
. = ..()
|
||||
data["color"] = color
|
||||
data["blendmode"] = blend_mode
|
||||
|
||||
/obj/effect/decal/cleanable/blood/PersistenceLoad(list/data)
|
||||
. = ..()
|
||||
if(data["color"])
|
||||
fixed_color = TRUE
|
||||
add_atom_colour(data["color"], FIXED_COLOUR_PRIORITY)
|
||||
if(data["blendmode"])
|
||||
blend_mode = data["blendmode"]
|
||||
name = "dried blood"
|
||||
desc = "Looks like it's been here a while. Eew"
|
||||
bloodiness = 0
|
||||
@@ -82,8 +87,8 @@
|
||||
/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."
|
||||
blend_mode = BLEND_MULTIPLY
|
||||
random_icon_states = null
|
||||
beauty = -50
|
||||
persistent = TRUE
|
||||
@@ -95,6 +100,7 @@
|
||||
. = ..()
|
||||
data["dir"] = dir
|
||||
data["color"] = color
|
||||
data["blendmode"] = blend_mode
|
||||
|
||||
/obj/effect/decal/cleanable/trail_holder/PersistenceLoad(list/data)
|
||||
. = ..()
|
||||
@@ -103,11 +109,14 @@
|
||||
if(data["color"])
|
||||
fixed_color = TRUE
|
||||
add_atom_colour(data["color"], FIXED_COLOUR_PRIORITY)
|
||||
if(data["blendmode"])
|
||||
blend_mode = data["blendmode"]
|
||||
|
||||
/obj/effect/decal/cleanable/trail_holder/update_icon()
|
||||
. = ..()
|
||||
if(!fixed_color)
|
||||
add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
|
||||
blend_mode = blood_DNA_to_blend()
|
||||
|
||||
/obj/effect/cleanable/trail_holder/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/effects/fire.dmi', "fire"))
|
||||
GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons/effects/welding_effect.dmi', "welding_sparks", GASFIRE_LAYER, ABOVE_LIGHTING_PLANE))
|
||||
|
||||
GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
// if true, everyone item when created will have its name changed to be
|
||||
|
||||
@@ -601,11 +601,12 @@
|
||||
H.adjustOxyLoss(H.health - HALFWAYCRITDEATH, 0)
|
||||
else
|
||||
var/overall_damage = total_brute + total_burn + H.getToxLoss() + H.getOxyLoss()
|
||||
var/mobhealth = H.health
|
||||
H.adjustOxyLoss((mobhealth - HALFWAYCRITDEATH) * (H.getOxyLoss() / overall_damage), 0)
|
||||
H.adjustToxLoss((mobhealth - HALFWAYCRITDEATH) * (H.getToxLoss() / overall_damage), 0)
|
||||
H.adjustFireLoss((mobhealth - HALFWAYCRITDEATH) * (total_burn / overall_damage), 0)
|
||||
H.adjustBruteLoss((mobhealth - HALFWAYCRITDEATH) * (total_brute / overall_damage), 0)
|
||||
if(overall_damage)
|
||||
var/mobhealth = H.health
|
||||
H.adjustOxyLoss((mobhealth - HALFWAYCRITDEATH) * (H.getOxyLoss() / overall_damage), 0)
|
||||
H.adjustToxLoss((mobhealth - HALFWAYCRITDEATH) * (H.getToxLoss() / overall_damage), 0)
|
||||
H.adjustFireLoss((mobhealth - HALFWAYCRITDEATH) * (total_burn / overall_damage), 0)
|
||||
H.adjustBruteLoss((mobhealth - HALFWAYCRITDEATH) * (total_brute / overall_damage), 0)
|
||||
H.updatehealth() // Previous "adjust" procs don't update health, so we do it manually.
|
||||
user.visible_message("<span class='notice'>[req_defib ? "[defib]" : "[src]"] pings: Resuscitation successful.</span>")
|
||||
playsound(src, 'sound/machines/defib_success.ogg', 50, 0)
|
||||
|
||||
@@ -145,32 +145,29 @@ GENETICS SCANNER
|
||||
mob_status = "<span class='alert'><b>Deceased</b></span>"
|
||||
oxy_loss = max(rand(1, 40), oxy_loss, (300 - (tox_loss + fire_loss + brute_loss))) // Random oxygen loss
|
||||
|
||||
var/msg = "<span class='info'>*---------*\nAnalyzing results for [M]:\n\tOverall status: [mob_status]"
|
||||
var/msg = "<span class='info'>Analyzing results for [M]:\n<blockquote class='notice'>Overall status: [mob_status]"
|
||||
|
||||
// Damage descriptions
|
||||
if(brute_loss > 10)
|
||||
msg += "\n\t<span class='alert'>[brute_loss > 50 ? "Severe" : "Minor"] tissue damage detected.</span>"
|
||||
msg += "\n<span class='alert'>[brute_loss > 50 ? "Severe" : "Minor"] tissue damage detected.</span>"
|
||||
if(fire_loss > 10)
|
||||
msg += "\n\t<span class='alert'>[fire_loss > 50 ? "Severe" : "Minor"] burn damage detected.</span>"
|
||||
msg += "\n<span class='alert'>[fire_loss > 50 ? "Severe" : "Minor"] burn damage detected.</span>"
|
||||
if(oxy_loss > 10)
|
||||
msg += "\n\t<span class='info'><span class='alert'>[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected.</span>"
|
||||
msg += "\n<span class='info'><span class='alert'>[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected.</span>"
|
||||
if(tox_loss > 10)
|
||||
msg += "\n\t<span class='alert'>[tox_loss > 50 ? "Severe" : "Minor"] amount of [HAS_TRAIT(M, TRAIT_ROBOTIC_ORGANISM) ? "system corruption" : "toxin damage"] detected.</span>"
|
||||
msg += "\n<span class='alert'>[tox_loss > 50 ? "Severe" : "Minor"] amount of [HAS_TRAIT(M, TRAIT_ROBOTIC_ORGANISM) ? "system corruption" : "toxin damage"] detected.</span>"
|
||||
if(M.getStaminaLoss())
|
||||
msg += "\n\t<span class='alert'>Subject appears to be suffering from fatigue.</span>"
|
||||
msg += "\n<span class='alert'>Subject appears to be suffering from fatigue.</span>"
|
||||
if(advanced)
|
||||
msg += "\n\t<span class='info'>Fatigue Level: [M.getStaminaLoss()]%.</span>"
|
||||
msg += "\n<span class='info'>Fatigue Level: [M.getStaminaLoss()]%.</span>"
|
||||
if (M.getCloneLoss())
|
||||
msg += "\n\t<span class='alert'>Subject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage.</span>"
|
||||
msg += "\n<span class='alert'>Subject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage.</span>"
|
||||
if(advanced)
|
||||
msg += "\n\t<span class='info'>Cellular Damage Level: [M.getCloneLoss()].</span>"
|
||||
msg += "\n<span class='info'>Cellular Damage Level: [M.getCloneLoss()].</span>"
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(advanced && H.has_dna())
|
||||
msg += "\n\t<span class='info'>Genetic Stability: [H.dna.stability]%.</span>"
|
||||
|
||||
to_chat(user, msg)
|
||||
msg = ""
|
||||
msg += "\n<span class='info'>Genetic Stability: [H.dna.stability]%.</span>"
|
||||
|
||||
// Body part damage report
|
||||
var/list/dmgreport = list()
|
||||
@@ -178,7 +175,7 @@ GENETICS SCANNER
|
||||
var/mob/living/carbon/C = M
|
||||
var/list/damaged = C.get_damaged_bodyparts(1,1)
|
||||
if(length(damaged)>0 || oxy_loss>0 || tox_loss>0 || fire_loss>0)
|
||||
dmgreport += "<table style='margin-left:33px'><tr><font face='Verdana'>\
|
||||
dmgreport += "<table><tr><font face='Verdana'>\
|
||||
<td style='width: 90px;'><font color='#0000CC'>Damage:</font></td>\
|
||||
<td style='width: 55px;'><font color='red'><b>Brute</b></font></td>\
|
||||
<td style='width: 45px;'><font color='orange'><b>Burn</b></font></td>\
|
||||
@@ -196,7 +193,7 @@ GENETICS SCANNER
|
||||
<td><font color='red'>[(org.brute_dam > 0) ? "[org.brute_dam]" : "0"]</font></td>\
|
||||
<td><font color='orange'>[(org.burn_dam > 0) ? "[org.burn_dam]" : "0"]</font></td></tr>"
|
||||
dmgreport += "</table>"
|
||||
to_chat(user, dmgreport.Join())
|
||||
msg += "\n[dmgreport.Join()]"
|
||||
|
||||
|
||||
//Organ damages report
|
||||
@@ -317,7 +314,7 @@ GENETICS SCANNER
|
||||
damage_message += " <font color='red'>Minor [O.name] failure detected.</span>"
|
||||
|
||||
if(temp_message || damage_message)
|
||||
msg += "\t<b><span class='info'>[uppertext(O.name)]:</b></span> [damage_message] [temp_message]\n"
|
||||
msg += "\n<b><span class='info'>[uppertext(O.name)]:</b></span> [damage_message] [temp_message]\n"
|
||||
|
||||
|
||||
|
||||
@@ -332,24 +329,24 @@ GENETICS SCANNER
|
||||
var/has_liver = C.dna && !(NOLIVER in C.dna.species.species_traits)
|
||||
var/has_stomach = C.dna && !(NOSTOMACH in C.dna.species.species_traits)
|
||||
if(!M.getorganslot(ORGAN_SLOT_EYES))
|
||||
msg += "\t<span class='alert'><b>Subject does not have eyes.</b></span>\n"
|
||||
msg += "<span class='alert'><b>Subject does not have eyes.</b></span>\n"
|
||||
if(!M.getorganslot(ORGAN_SLOT_EARS))
|
||||
msg += "\t<span class='alert'><b>Subject does not have ears.</b></span>\n"
|
||||
msg += "<span class='alert'><b>Subject does not have ears.</b></span>\n"
|
||||
if(!M.getorganslot(ORGAN_SLOT_BRAIN))
|
||||
msg += "\t<span class='alert'><b>Subject's brain function is non-existent!</b></span>\n"
|
||||
msg += "<span class='alert'><b>Subject's brain function is non-existent!</b></span>\n"
|
||||
if(has_liver && !M.getorganslot(ORGAN_SLOT_LIVER))
|
||||
msg += "\t<span class='alert'><b>Subject's liver is missing!</b></span>\n"
|
||||
msg += "<span class='alert'><b>Subject's liver is missing!</b></span>\n"
|
||||
if(blooded && !M.getorganslot(ORGAN_SLOT_HEART))
|
||||
msg += "\t<span class='alert'><b>Subject's heart is missing!</b></span>\n"
|
||||
msg += "<span class='alert'><b>Subject's heart is missing!</b></span>\n"
|
||||
if(breathes && !M.getorganslot(ORGAN_SLOT_LUNGS))
|
||||
msg += "\t<span class='alert'><b>Subject's lungs have collapsed from trauma!</b></span>\n"
|
||||
msg += "<span class='alert'><b>Subject's lungs have collapsed from trauma!</b></span>\n"
|
||||
if(has_stomach && !M.getorganslot(ORGAN_SLOT_STOMACH))
|
||||
msg += "\t<span class='alert'><b>Subject's stomach is missing!</span>\n"
|
||||
msg += "<span class='alert'><b>Subject's stomach is missing!</span>\n"
|
||||
|
||||
|
||||
if(M.radiation)
|
||||
msg += "\t<span class='alert'>Subject is irradiated.</span>\n"
|
||||
msg += "\t<span class='info'>Radiation Level: [M.radiation] rad</span>\n"
|
||||
msg += "<span class='alert'>Subject is irradiated.</span>\n"
|
||||
msg += "<span class='info'>Radiation Level: [M.radiation] rad</span>\n"
|
||||
|
||||
|
||||
|
||||
@@ -383,11 +380,11 @@ GENETICS SCANNER
|
||||
else if (S.flying_species != initial(S.flying_species))
|
||||
mutant = TRUE
|
||||
|
||||
msg += "\t<span class='info'>Reported Species: [H.spec_trait_examine_font()][H.dna.custom_species ? H.dna.custom_species : S.name]</font></span>\n"
|
||||
msg += "\t<span class='info'>Base Species: [H.spec_trait_examine_font()][S.name]</font></span>\n"
|
||||
msg += "\n<span class='info'>Reported Species: [H.spec_trait_examine_font()][H.dna.custom_species ? H.dna.custom_species : S.name]</font></span>\n"
|
||||
msg += "<span class='info'>Base Species: [H.spec_trait_examine_font()][S.name]</font></span>\n"
|
||||
if(mutant)
|
||||
msg += "\t<span class='info'>Subject has mutations present.</span>\n"
|
||||
msg += "\t<span class='info'>Body temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)</span>\n"
|
||||
msg += "<span class='info'>Subject has mutations present.</span>\n"
|
||||
msg += "<span class='info'>Body temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)</span>\n"
|
||||
|
||||
// Time of death
|
||||
if(M.tod && (M.stat == DEAD || ((HAS_TRAIT(M, TRAIT_FAKEDEATH)) && !advanced)))
|
||||
@@ -452,14 +449,14 @@ GENETICS SCANNER
|
||||
if(cyberimp_detect)
|
||||
msg += "<span class='notice'>Detected cybernetic modifications:</span>\n"
|
||||
msg += "<span class='notice'>[cyberimp_detect]</span>\n"
|
||||
msg += "<span class='notice'>*---------*</span>"
|
||||
msg += "</blockquote>"
|
||||
to_chat(user, msg)
|
||||
SEND_SIGNAL(M, COMSIG_NANITE_SCAN, user, FALSE)
|
||||
|
||||
/proc/chemscan(mob/living/user, mob/living/M)
|
||||
if(istype(M))
|
||||
if(M.reagents)
|
||||
var/msg = "<span class='info'>*---------*\n"
|
||||
var/msg = "<blockquote class='purple'>"
|
||||
if(M.reagents.reagent_list.len)
|
||||
var/list/datum/reagent/reagents = list()
|
||||
for(var/datum/reagent/R in M.reagents.reagent_list)
|
||||
@@ -498,7 +495,7 @@ GENETICS SCANNER
|
||||
if(95 to INFINITY)
|
||||
msg += "<span class='danger'>Subject contains a extremely dangerous amount of toxic isomers.</span>\n"
|
||||
|
||||
msg += "*---------*</span>"
|
||||
msg += "</blockquote>"
|
||||
to_chat(user, msg)
|
||||
|
||||
/obj/item/healthanalyzer/verb/toggle_mode()
|
||||
@@ -529,12 +526,14 @@ GENETICS SCANNER
|
||||
|
||||
var/render_list = ""
|
||||
for(var/i in patient.get_wounded_bodyparts())
|
||||
if(render_list == "")
|
||||
render_list += "<blockquote class='warning'>"
|
||||
var/obj/item/bodypart/wounded_part = i
|
||||
render_list += "<span class='alert ml-1'><b>Warning: Physical trauma[LAZYLEN(wounded_part.wounds) > 1? "s" : ""] detected in [wounded_part.name]</b>"
|
||||
for(var/k in wounded_part.wounds)
|
||||
var/datum/wound/W = k
|
||||
render_list += "<div class='ml-2'>[W.get_scanner_description()]</div>\n"
|
||||
render_list += "</span>"
|
||||
render_list += "</blockquote>"
|
||||
|
||||
if(render_list == "")
|
||||
if(istype(scanner))
|
||||
|
||||
@@ -205,6 +205,10 @@
|
||||
if(!throw_item(target, I, user))
|
||||
break
|
||||
|
||||
if(user)
|
||||
shake_camera(user, (pressureSetting * 0.75 + 1), (pressureSetting * 0.75))
|
||||
|
||||
|
||||
/obj/item/pneumatic_cannon/proc/throw_item(turf/target, obj/item/I, mob/user)
|
||||
if(!istype(I))
|
||||
return FALSE
|
||||
|
||||
@@ -22,8 +22,8 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \
|
||||
new/datum/stack_recipe("spout flask", /obj/item/glasswork/glass_base/spouty, 20), \
|
||||
new/datum/stack_recipe("small bulb flask", /obj/item/glasswork/glass_base/flask_small, 5), \
|
||||
new/datum/stack_recipe("large bottle flask", /obj/item/glasswork/glass_base/flask_large, 15), \
|
||||
new/datum/stack_recipe("tea cup", /obj/item/glasswork/glass_base/tea_plate, 5), \
|
||||
new/datum/stack_recipe("tea plate", /obj/item/glasswork/glass_base/tea_cup, 5), \
|
||||
new/datum/stack_recipe("tea cup", /obj/item/glasswork/glass_base/tea_cup, 5), \
|
||||
new/datum/stack_recipe("tea plate", /obj/item/glasswork/glass_base/tea_plate, 5), \
|
||||
)), \
|
||||
))
|
||||
|
||||
|
||||
@@ -561,4 +561,4 @@
|
||||
singular_name = "catwalk floor tile"
|
||||
desc = "Flooring that shows its contents underneath. Engineers love it!"
|
||||
icon_state = "catwalk_tile"
|
||||
turf_type = /turf/open/floor/plating/catwalk_floor
|
||||
turf_type = /turf/open/floor/catwalk_floor
|
||||
|
||||
@@ -119,6 +119,11 @@
|
||||
dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weldingtool/use_tool(atom/target, mob/living/user, delay, amount, volume, datum/callback/extra_checks, skill_gain_mult)
|
||||
target.add_overlay(GLOB.welding_sparks)
|
||||
. = ..()
|
||||
target.cut_overlay(GLOB.welding_sparks)
|
||||
|
||||
/obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user)
|
||||
if(!istype(H))
|
||||
return ..()
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
var/obj_flags = CAN_BE_HIT
|
||||
var/set_obj_flags // ONLY FOR MAPPING: Sets flags from a string list, handled in Initialize. Usage: set_obj_flags = "EMAGGED;!CAN_BE_HIT" to set EMAGGED and clear CAN_BE_HIT.
|
||||
|
||||
var/minimap_override_color // allows this obj to set its own color on the minimap
|
||||
|
||||
var/damtype = BRUTE
|
||||
var/force = 0
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
/obj/structure/proc/do_climb(atom/movable/A)
|
||||
if(climbable)
|
||||
density = FALSE
|
||||
. = step(A,get_dir(A,src.loc))
|
||||
. = step(A, (A.loc == loc ? dir : get_dir(A,src.loc)))
|
||||
density = TRUE
|
||||
|
||||
/obj/structure/proc/climb_structure(mob/living/user)
|
||||
|
||||
@@ -156,9 +156,10 @@
|
||||
for(var/atom/movable/AM in L)
|
||||
if(AM != src && insert(AM) == -1) // limit reached
|
||||
break
|
||||
// for(var/i in reverseRange(L.GetAllContents()))
|
||||
// var/atom/movable/thing = i
|
||||
// SEND_SIGNAL(thing, COMSIG_TRY_STORAGE_HIDE_ALL)
|
||||
// todo: this should be unnecessary, storage should auto close on move wtf
|
||||
for(var/i in reverseRange(L.GetAllContents()))
|
||||
var/atom/movable/thing = i
|
||||
SEND_SIGNAL(thing, COMSIG_TRY_STORAGE_HIDE_ALL)
|
||||
|
||||
/obj/structure/closet/proc/open(mob/living/user, force = FALSE)
|
||||
if(!can_open(user, force))
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
new /obj/item/clothing/under/rank/security/officer/blueshirt/seccorp/hoscorp(src)
|
||||
new /obj/item/clothing/suit/armor/vest/leather(src)
|
||||
new /obj/item/clothing/suit/armor/hos(src)
|
||||
new /obj/item/clothing/suit/armor/hos/platecarrier(src)
|
||||
new /obj/item/clothing/under/rank/security/head_of_security/skirt(src)
|
||||
new /obj/item/clothing/under/rank/security/head_of_security/alt(src)
|
||||
new /obj/item/clothing/under/rank/security/head_of_security/alt/skirt(src)
|
||||
|
||||
+29
-1
@@ -31,14 +31,42 @@ GLOBAL_LIST_INIT(freqtospan, list(
|
||||
/atom/movable/proc/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source)
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_HEAR, args)
|
||||
|
||||
/atom/movable/proc/bark(list/hearers, distance, volume, pitch, queue_time)
|
||||
if(queue_time && vocal_current_bark != queue_time)
|
||||
return
|
||||
if(SEND_SIGNAL(src, COMSIG_MOVABLE_BARK, hearers, distance, volume, pitch))
|
||||
return //bark interception. this probably counts as some flavor of BDSM
|
||||
if(!vocal_bark)
|
||||
if(!vocal_bark_id || !set_bark(vocal_bark_id)) //just-in-time bark generation
|
||||
return
|
||||
volume = min(volume, 100)
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/mob/M in hearers)
|
||||
M.playsound_local(T, vol = volume, vary = TRUE, frequency = pitch, max_distance = distance, falloff_distance = 0, falloff_exponent = BARK_SOUND_FALLOFF_EXPONENT(distance), S = vocal_bark, distance_multiplier = 1)
|
||||
|
||||
/atom/movable/proc/can_speak()
|
||||
return 1
|
||||
|
||||
/atom/movable/proc/send_speech(message, range = 7, atom/movable/source = src, bubble_type, list/spans, datum/language/message_language = null, message_mode)
|
||||
var/rendered = compose_message(src, message_language, message, , spans, message_mode, source)
|
||||
for(var/_AM in get_hearers_in_view(range, source))
|
||||
var/list/hearers = get_hearers_in_view(range, source)
|
||||
for(var/_AM in hearers)
|
||||
var/atom/movable/AM = _AM
|
||||
AM.Hear(rendered, src, message_language, message, , spans, message_mode, source)
|
||||
if(SEND_SIGNAL(src, COMSIG_MOVABLE_QUEUE_BARK, hearers, args) || vocal_bark || vocal_bark_id)
|
||||
for(var/mob/M in hearers)
|
||||
if(!M.client)
|
||||
continue
|
||||
if(!(M.client.prefs.toggles & SOUND_BARK))
|
||||
hearers -= M
|
||||
var/barks = min(round((LAZYLEN(message) / vocal_speed)) + 1, BARK_MAX_BARKS)
|
||||
var/total_delay
|
||||
vocal_current_bark = world.time //this is juuuuust random enough to reliably be unique every time send_speech() is called, in most scenarios
|
||||
for(var/i in 1 to barks)
|
||||
if(total_delay > BARK_MAX_TIME)
|
||||
break
|
||||
addtimer(CALLBACK(src, .proc/bark, hearers, range, vocal_volume, BARK_DO_VARY(vocal_pitch, vocal_pitch_range), vocal_current_bark), total_delay)
|
||||
total_delay += rand(DS2TICKS(vocal_speed / BARK_SPEED_BASELINE), DS2TICKS(vocal_speed / BARK_SPEED_BASELINE) + DS2TICKS(vocal_speed / BARK_SPEED_BASELINE)) TICKS
|
||||
|
||||
/atom/movable/proc/compose_message(atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, face_name = FALSE, atom/movable/source)
|
||||
if(!source)
|
||||
|
||||
+11
-4
@@ -110,13 +110,20 @@ distance_multiplier - Can be used to multiply the distance at which the sound is
|
||||
*/
|
||||
|
||||
/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff_exponent = SOUND_FALLOFF_EXPONENT, channel = 0, pressure_affected = TRUE, sound/S, max_distance,
|
||||
falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = SOUND_DEFAULT_DISTANCE_MULTIPLIER, envwet = -10000, envdry = 0)
|
||||
if(!client || !can_hear())
|
||||
falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = SOUND_DEFAULT_DISTANCE_MULTIPLIER, envwet = -10000, envdry = 0, virtual_hearer)
|
||||
if(audiovisual_redirect)
|
||||
virtual_hearer = get_turf(src)
|
||||
audiovisual_redirect.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, max_distance, falloff_distance, distance_multiplier, max(0, envwet), -10000, virtual_hearer)
|
||||
//No return here, as we want to deliberately support the possibility of shenanigans in which mobs with clients can have active AV redirects to completely different players
|
||||
if(!client)
|
||||
return
|
||||
|
||||
if(!S)
|
||||
S = sound(get_sfx(soundin))
|
||||
|
||||
if(!can_hear() && !(S.status & SOUND_UPDATE)) //This is primarily to make sure sound updates still go through when a spaceman's deaf
|
||||
return
|
||||
|
||||
S.wait = 0 //No queue
|
||||
S.channel = channel || SSsounds.random_available_channel()
|
||||
S.volume = vol
|
||||
@@ -131,7 +138,7 @@ distance_multiplier - Can be used to multiply the distance at which the sound is
|
||||
S.frequency = get_rand_frequency()
|
||||
|
||||
if(isturf(turf_source))
|
||||
var/turf/T = get_turf(src)
|
||||
var/turf/T = virtual_hearer || get_turf(src)
|
||||
|
||||
//sound volume falloff with distance
|
||||
var/distance = get_dist(T, turf_source)
|
||||
@@ -173,7 +180,7 @@ distance_multiplier - Can be used to multiply the distance at which the sound is
|
||||
var/dz = turf_source.y - T.y // Hearing from infront/behind
|
||||
S.z = dz * distance_multiplier
|
||||
var/dy = (turf_source.z - T.z) * 5 * distance_multiplier // Hearing from above / below, multiplied by 5 because we assume height is further along coords.
|
||||
S.y = dy + 1
|
||||
S.y = dy + distance_multiplier
|
||||
|
||||
S.falloff = isnull(max_distance)? FALLOFF_SOUNDS : max_distance //use max_distance, else just use 1 as we are a direct sound so falloff isnt relevant.
|
||||
|
||||
|
||||
@@ -73,16 +73,26 @@
|
||||
|
||||
/turf/closed/indestructible/splashscreen
|
||||
name = "Space Station 13"
|
||||
icon = 'icons/blank_title.png'
|
||||
desc = null
|
||||
icon = 'icons/blanks/blank_title.png'
|
||||
icon_state = ""
|
||||
layer = FLY_LAYER
|
||||
plane = SPLASHSCREEN_PLANE
|
||||
bullet_bounce_sound = null
|
||||
|
||||
/turf/closed/indestructible/splashscreen/New()
|
||||
INITIALIZE_IMMEDIATE(/turf/closed/indestructible/splashscreen)
|
||||
|
||||
/turf/closed/indestructible/splashscreen/Initialize(mapload)
|
||||
. = ..()
|
||||
SStitle.splash_turf = src
|
||||
if(SStitle.icon)
|
||||
icon = SStitle.icon
|
||||
..()
|
||||
handle_generic_titlescreen_sizes()
|
||||
|
||||
///helper proc that will center the screen if the icon is changed to a generic width, to make admins have to fudge around with pixel_x less. returns null
|
||||
/turf/closed/indestructible/splashscreen/proc/handle_generic_titlescreen_sizes()
|
||||
var/icon/size_check = icon(SStitle.icon, icon_state)
|
||||
var/width = size_check.Width()
|
||||
pixel_x = (672 - width) * 0.5 //The title screen is mapped with the expectation that it's 672x480. Should probably turn the title screen size into a define some time!
|
||||
|
||||
/turf/closed/indestructible/splashscreen/vv_edit_var(var_name, var_value)
|
||||
. = ..()
|
||||
@@ -90,7 +100,13 @@
|
||||
switch(var_name)
|
||||
if(NAMEOF(src, icon))
|
||||
SStitle.icon = icon
|
||||
handle_generic_titlescreen_sizes()
|
||||
|
||||
/turf/closed/indestructible/start_area
|
||||
name = null
|
||||
desc = null
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/turf/closed/indestructible/riveted
|
||||
icon = 'icons/turf/walls/riveted.dmi'
|
||||
icon_state = "riveted"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* you can crowbar it to interact with the underneath stuff without destroying the tile...
|
||||
* unless you want to!
|
||||
*/
|
||||
/turf/open/floor/plating/catwalk_floor
|
||||
/turf/open/floor/catwalk_floor
|
||||
icon = 'icons/turf/floors/catwalk_plating.dmi'
|
||||
icon_state = "catwalk_below"
|
||||
floor_tile = /obj/item/stack/tile/catwalk
|
||||
@@ -16,29 +16,35 @@
|
||||
barefootstep = FOOTSTEP_CATWALK
|
||||
clawfootstep = FOOTSTEP_CATWALK
|
||||
heavyfootstep = FOOTSTEP_CATWALK
|
||||
intact = FALSE
|
||||
var/covered = TRUE
|
||||
|
||||
/turf/open/floor/plating/catwalk_floor/Initialize(mapload)
|
||||
/turf/open/floor/catwalk_floor/Initialize(mapload)
|
||||
. = ..()
|
||||
layer = CATWALK_LAYER
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/turf/open/floor/plating/catwalk_floor/update_overlays()
|
||||
/turf/open/floor/catwalk_floor/update_overlays()
|
||||
. = ..()
|
||||
var/static/catwalk_overlay
|
||||
var/static/image/catwalk_overlay
|
||||
if(isnull(catwalk_overlay))
|
||||
catwalk_overlay = iconstate2appearance(icon, "catwalk_above")
|
||||
catwalk_overlay = new()
|
||||
catwalk_overlay.icon = icon
|
||||
catwalk_overlay.icon_state = "catwalk_above"
|
||||
catwalk_overlay.plane = GAME_PLANE
|
||||
catwalk_overlay.layer = CATWALK_LAYER
|
||||
catwalk_overlay = catwalk_overlay.appearance
|
||||
if(covered)
|
||||
. += catwalk_overlay
|
||||
|
||||
/turf/open/floor/plating/catwalk_floor/screwdriver_act(mob/living/user, obj/item/tool)
|
||||
/turf/open/floor/catwalk_floor/screwdriver_act(mob/living/user, obj/item/tool)
|
||||
. = ..()
|
||||
covered = !covered
|
||||
user.balloon_alert(user, "[!covered ? "cover removed" : "cover added"]")
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/turf/open/floor/plating/catwalk_floor/pry_tile(obj/item/crowbar, mob/user, silent)
|
||||
/turf/open/floor/catwalk_floor/crowbar_act(mob/user, obj/item/I)
|
||||
if(covered)
|
||||
user.balloon_alert(user, "remove cover first!")
|
||||
return FALSE
|
||||
. = ..()
|
||||
return pry_tile(I, user)
|
||||
|
||||
@@ -117,6 +117,7 @@ GLOBAL_LIST(topic_status_cache)
|
||||
GLOB.world_asset_log = "[GLOB.log_directory]/asset.log"
|
||||
GLOB.world_attack_log = "[GLOB.log_directory]/attack.log"
|
||||
GLOB.world_victim_log = "[GLOB.log_directory]/victim.log"
|
||||
GLOB.world_econ_log = "[GLOB.log_directory]/econ.log"
|
||||
GLOB.world_pda_log = "[GLOB.log_directory]/pda.log"
|
||||
GLOB.world_telecomms_log = "[GLOB.log_directory]/telecomms.log"
|
||||
GLOB.world_manifest_log = "[GLOB.log_directory]/manifest.log"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user