Merge branch 'master' into sizecode

This commit is contained in:
Dahlular
2020-04-17 08:07:37 -06:00
218 changed files with 4187 additions and 70480 deletions
+8 -8
View File
@@ -4,15 +4,15 @@
#define COLOR_INPUT_ENABLED "#D3B5B5"
#define COLOR_DARKMODE_INFO_BUTTONS_BG "#40628A"
#define COLOR_DARKMODE_ISSUE_BUTTON_BG "#ce4242"
#define COLOR_DARKMODE_BACKGROUND "#202020"
#define COLOR_DARKMODE_DARKBACKGROUND "#171717"
#define COLOR_DARKMODE_TEXT "#f0f0f0"
#define COLOR_DARKMODE_ISSUE_BUTTON_BG "#A92C2C"
#define COLOR_DARKMODE_BACKGROUND "#272727"
#define COLOR_DARKMODE_DARKBACKGROUND "#242424"
#define COLOR_DARKMODE_TEXT "#E0E0E0"
#define COLOR_WHITEMODE_INFO_BUTTONS_BG "#90b3dd"
#define COLOR_WHITEMODE_ISSUE_BUTTON_BG "#ef7f7f"
#define COLOR_WHITEMODE_BACKGROUND "#eeeeee"
#define COLOR_WHITEMODE_DARKBACKGROUND "#dddddd"
#define COLOR_WHITEMODE_INFO_BUTTONS_BG "#90B3DD"
#define COLOR_WHITEMODE_ISSUE_BUTTON_BG "##EF7F7F"
#define COLOR_WHITEMODE_BACKGROUND "#F0F0F0"
#define COLOR_WHITEMODE_DARKBACKGROUND "#E6E6E6"
#define COLOR_WHITEMODE_TEXT "#000000"
#define COLOR_FLOORTILE_GRAY "#8D8B8B"
+2
View File
@@ -227,6 +227,8 @@
//Mood
#define COMSIG_ADD_MOOD_EVENT "add_mood" //Called when you send a mood event from anywhere in the code.
#define COMSIG_CLEAR_MOOD_EVENT "clear_mood" //Called when you clear a mood event from anywhere in the code.
#define COMSIG_INCREASE_SANITY "decrease_sanity" //Called when you want to increase sanity from anywhere in the code.
#define COMSIG_DECREASE_SANITY "increase_sanity" //Same as above but to decrease sanity instead.
//NTnet
#define COMSIG_COMPONENT_NTNET_RECEIVE "ntnet_receive" //called on an object by its NTNET connection component on receive. (sending_id(number), sending_netname(text), data(datum/netdata))
+1 -1
View File
@@ -56,7 +56,7 @@
#define isgolem(A) (is_species(A, /datum/species/golem))
#define islizard(A) (is_species(A, /datum/species/lizard))
#define isplasmaman(A) (is_species(A, /datum/species/plasmaman))
#define ispodperson(A) (is_species(A, /datum/species/podperson))
#define ispodperson(A) (is_species(A, /datum/species/pod))
#define isflyperson(A) (is_species(A, /datum/species/fly))
#define isjellyperson(A) (is_species(A, /datum/species/jelly))
#define isslimeperson(A) (is_species(A, /datum/species/jelly/slime))
+3
View File
@@ -496,3 +496,6 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define VOMIT_TOXIC 1
#define VOMIT_PURPLE 2
//Misc text define. Does 4 spaces. Used as a makeshift tabulator.
#define FOURSPACES "    "
+2
View File
@@ -117,6 +117,8 @@
#define BIOWARE_GENERIC "generic"
#define BIOWARE_NERVES "nerves"
#define BIOWARE_CIRCULATION "circulation"
#define BIOWARE_LIGAMENTS "ligaments"
#define BIOWARE_DISSECTION "dissected"
//Health hud screws for carbon mobs
#define SCREWYHUD_NONE 0
+14
View File
@@ -34,3 +34,17 @@
#define DEL_REAGENT 1 // reagent deleted (fully cleared)
#define ADD_REAGENT 2 // reagent added
#define REM_REAGENT 3 // reagent removed (may still exist)
//reagent bitflags, used for altering how they works
#define REAGENT_DEAD_PROCESS (1<<0) //calls on_mob_dead() if present in a dead body
#define REAGENT_DONOTSPLIT (1<<1) //Do not split the chem at all during processing
#define REAGENT_ONLYINVERSE (1<<2) //Only invert chem, no splitting
#define REAGENT_ONMOBMERGE (1<<3) //Call on_mob_life proc when reagents are merging.
#define REAGENT_INVISIBLE (1<<4) //Doesn't appear on handheld health analyzers.
#define REAGENT_FORCEONNEW (1<<5) //Forces a on_new() call without a data overhead
#define REAGENT_SNEAKYNAME (1<<6) //When inverted, the inverted chem uses the name of the original chem
#define REAGENT_SPLITRETAINVOL (1<<7) //Retains initial volume of chem when splitting
//Chemical reaction flags, for determining reaction specialties
#define REACTION_CLEAR_IMPURE (1<<0) //Convert into impure/pure on reaction completion
#define REACTION_CLEAR_INVERSE (1<<1) //Convert into inverse on reaction completion when purity is low enough
+4 -2
View File
@@ -83,7 +83,8 @@
#define INIT_ORDER_SHUTTLE -21
#define INIT_ORDER_MINOR_MAPPING -40
#define INIT_ORDER_PATH -50
#define INIT_ORDER_PERSISTENCE -100
#define INIT_ORDER_PERSISTENCE -95
#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
// Subsystem fire priority, from lowest to highest priority
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
@@ -97,7 +98,7 @@
#define FIRE_PRIORITY_GARBAGE 15
#define FIRE_PRIORITY_WET_FLOORS 20
#define FIRE_PRIORITY_AIR 20
#define FIRE_PRIORITY_NPC 20
#define FIRE_PRIORITY_NPC 80
#define FIRE_PRIORITY_PROCESS 25
#define FIRE_PRIORITY_THROWING 25
#define FIRE_PRIORITY_SPACEDRIFT 30
@@ -114,6 +115,7 @@
#define FIRE_PRIORITY_MOBS 100
#define FIRE_PRIORITY_TGUI 110
#define FIRE_PRIORITY_TICKER 200
#define FIRE_PRIORITY_CHAT 400
#define FIRE_PRIORITY_OVERLAYS 500
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
+2
View File
@@ -95,6 +95,8 @@
#define TRAIT_NOHUNGER "no_hunger"
#define TRAIT_EASYDISMEMBER "easy_dismember"
#define TRAIT_LIMBATTACHMENT "limb_attach"
#define TRAIT_NOLIMBDISABLE "no_limb_disable"
#define TRAIT_EASYLIMBDISABLE "easy_limb_disable"
#define TRAIT_TOXINLOVER "toxinlover"
#define TRAIT_NOBREATH "no_breath"
#define TRAIT_ANTIMAGIC "anti_magic"
+11 -11
View File
@@ -280,34 +280,34 @@
if(GLOB.round_id)
var/statspage = CONFIG_GET(string/roundstatsurl)
var/info = statspage ? "<a href='?action=openLink&link=[url_encode(statspage)][GLOB.round_id]'>[GLOB.round_id]</a>" : GLOB.round_id
parts += "[GLOB.TAB]Round ID: <b>[info]</b>"
parts += "[FOURSPACES]Round ID: <b>[info]</b>"
var/list/voting_results = SSvote.stored_gamemode_votes
if(length(voting_results))
parts += "[GLOB.TAB]Voting: "
parts += "[FOURSPACES]Voting: "
var/total_score = 0
for(var/choice in voting_results)
var/score = voting_results[choice]
total_score += score
parts += "[GLOB.TAB][GLOB.TAB][choice]: [score]"
parts += "[FOURSPACES][FOURSPACES][choice]: [score]"
parts += "[GLOB.TAB]Shift Duration: <B>[DisplayTimeText(world.time - SSticker.round_start_time)]</B>"
parts += "[GLOB.TAB]Station Integrity: <B>[mode.station_was_nuked ? "<span class='redtext'>Destroyed</span>" : "[popcount["station_integrity"]]%"]</B>"
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>"
var/total_players = GLOB.joined_player_list.len
if(total_players)
parts+= "[GLOB.TAB]Total Population: <B>[total_players]</B>"
parts+= "[FOURSPACES]Total Population: <B>[total_players]</B>"
if(station_evacuated)
parts += "<BR>[GLOB.TAB]Evacuation Rate: <B>[popcount[POPCOUNT_ESCAPEES]] ([PERCENT(popcount[POPCOUNT_ESCAPEES]/total_players)]%)</B>"
parts += "[GLOB.TAB](on emergency shuttle): <B>[popcount[POPCOUNT_SHUTTLE_ESCAPEES]] ([PERCENT(popcount[POPCOUNT_SHUTTLE_ESCAPEES]/total_players)]%)</B>"
parts += "[GLOB.TAB]Survival Rate: <B>[popcount[POPCOUNT_SURVIVORS]] ([PERCENT(popcount[POPCOUNT_SURVIVORS]/total_players)]%)</B>"
parts += "<BR>[FOURSPACES]Evacuation Rate: <B>[popcount[POPCOUNT_ESCAPEES]] ([PERCENT(popcount[POPCOUNT_ESCAPEES]/total_players)]%)</B>"
parts += "[FOURSPACES](on emergency shuttle): <B>[popcount[POPCOUNT_SHUTTLE_ESCAPEES]] ([PERCENT(popcount[POPCOUNT_SHUTTLE_ESCAPEES]/total_players)]%)</B>"
parts += "[FOURSPACES]Survival Rate: <B>[popcount[POPCOUNT_SURVIVORS]] ([PERCENT(popcount[POPCOUNT_SURVIVORS]/total_players)]%)</B>"
if(SSblackbox.first_death)
var/list/ded = SSblackbox.first_death
if(ded.len)
parts += "[GLOB.TAB]First Death: <b>[ded["name"]], [ded["role"]], at [ded["area"]]. Damage taken: [ded["damage"]].[ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : ""]</b>"
parts += "[FOURSPACES]First Death: <b>[ded["name"]], [ded["role"]], at [ded["area"]]. Damage taken: [ded["damage"]].[ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : ""]</b>"
//ignore this comment, it fixes the broken sytax parsing caused by the " above
else
parts += "[GLOB.TAB]<i>Nobody died this shift!</i>"
parts += "[FOURSPACES]<i>Nobody died this shift!</i>"
return parts.Join("<br>")
/client/proc/roundend_report_file()
+19 -4
View File
@@ -171,12 +171,27 @@ GLOBAL_LIST_INIT(bitfields, list(
"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
),
"clear_conversion" = list(
"REACTION_CLEAR_IMPURE" = REACTION_CLEAR_IMPURE,
"REACTION_CLEAR_INVERSE" = REACTION_CLEAR_INVERSE
),
"organ_flags" = list(
"ORGAN_SYNTHETIC" = ORGAN_SYNTHETIC,
@@ -185,5 +200,5 @@ GLOBAL_LIST_INIT(bitfields, list(
"ORGAN_EXTERNAL" = ORGAN_EXTERNAL,
"ORGAN_VITAL" = ORGAN_VITAL,
"ORGAN_NO_SPOIL" = ORGAN_NO_SPOIL
),
))
),
))
+4
View File
@@ -13,6 +13,8 @@
#define POLL_IGNORE_GOLEM "golem"
#define POLL_IGNORE_SWARMER "swarmer"
#define POLL_IGNORE_DRONE "drone"
#define POLL_IGNORE_DEMON "demon"
#define POLL_IGNORE_WIZARD "wizard"
GLOBAL_LIST_INIT(poll_ignore_desc, list(
POLL_IGNORE_SENTIENCE_POTION = "Sentience potion",
@@ -28,6 +30,8 @@ GLOBAL_LIST_INIT(poll_ignore_desc, list(
POLL_IGNORE_GOLEM = "Golems",
POLL_IGNORE_SWARMER = "Swarmer shells",
POLL_IGNORE_DRONE = "Drone shells",
POLL_IGNORE_DEMON = "Demons",
POLL_IGNORE_WIZARD = "Wizards",
))
GLOBAL_LIST_INIT(poll_ignore, init_poll_ignore())
-2
View File
@@ -6,8 +6,6 @@ GLOBAL_VAR_INIT(timezoneOffset, 0) // The difference betwen midnight (of the hos
// However it'd be ok to use for accessing attack logs and such too, which are even laggier.
GLOBAL_VAR_INIT(fileaccess_timer, 0)
GLOBAL_VAR_INIT(TAB, "&nbsp;&nbsp;&nbsp;&nbsp;")
GLOBAL_DATUM_INIT(data_core, /datum/datacore, new)
GLOBAL_VAR_INIT(CELLRATE, 0.002) // conversion ratio between a watt-tick and kilojoule
+67
View File
@@ -0,0 +1,67 @@
SUBSYSTEM_DEF(chat)
name = "Chat"
flags = SS_TICKER|SS_NO_INIT
wait = 1
priority = FIRE_PRIORITY_CHAT
init_order = INIT_ORDER_CHAT
var/list/payload = list()
/datum/controller/subsystem/chat/fire()
for(var/i in payload)
var/client/C = i
C << output(payload[C], "browseroutput:output")
payload -= C
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/chat/proc/queue(target, message, handle_whitespace = TRUE)
if(!target || !message)
return
if(!istext(message))
stack_trace("to_chat called with invalid input type")
return
if(target == world)
target = GLOB.clients
//Some macros remain in the string even after parsing and fuck up the eventual output
message = replacetext(message, "\improper", "")
message = replacetext(message, "\proper", "")
if(handle_whitespace)
message = replacetext(message, "\n", "<br>")
message = replacetext(message, "\t", "[FOURSPACES][FOURSPACES]")
message += "<br>"
//url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript.
//Do the double-encoding here to save nanoseconds
var/twiceEncoded = url_encode(url_encode(message))
if(islist(target))
for(var/I in target)
var/client/C = CLIENT_FROM_VAR(I) //Grab us a client if possible
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
continue
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
C.chatOutput.messageQueue += message
continue
payload[C] += twiceEncoded
else
var/client/C = CLIENT_FROM_VAR(target) //Grab us a client if possible
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
return
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
C.chatOutput.messageQueue += message
return
payload[C] += twiceEncoded
+1 -1
View File
@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(npcpool)
name = "NPC Pool"
flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
flags = SS_KEEP_TIMING | SS_NO_INIT
priority = FIRE_PRIORITY_NPC
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
+17 -13
View File
@@ -21,6 +21,8 @@
RegisterSignal(parent, COMSIG_ADD_MOOD_EVENT, .proc/add_event)
RegisterSignal(parent, COMSIG_CLEAR_MOOD_EVENT, .proc/clear_event)
RegisterSignal(parent, COMSIG_INCREASE_SANITY, .proc/IncreaseSanity)
RegisterSignal(parent, COMSIG_DECREASE_SANITY, .proc/DecreaseSanity)
RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, .proc/modify_hud)
var/mob/living/owner = parent
@@ -129,23 +131,23 @@
switch(mood_level)
if(1)
DecreaseSanity(0.2)
DecreaseSanity(src, 0.2)
if(2)
DecreaseSanity(0.125, SANITY_CRAZY)
DecreaseSanity(src, 0.125, SANITY_CRAZY)
if(3)
DecreaseSanity(0.075, SANITY_UNSTABLE)
DecreaseSanity(src, 0.075, SANITY_UNSTABLE)
if(4)
DecreaseSanity(0.025, SANITY_DISTURBED)
DecreaseSanity(src, 0.025, SANITY_DISTURBED)
if(5)
IncreaseSanity(0.1)
IncreaseSanity(src, 0.1)
if(6)
IncreaseSanity(0.15)
IncreaseSanity(src, 0.15)
if(7)
IncreaseSanity(0.20)
IncreaseSanity(src, 0.20)
if(8)
IncreaseSanity(0.25, SANITY_GREAT)
IncreaseSanity(src, 0.25, SANITY_GREAT)
if(9)
IncreaseSanity(0.4, SANITY_GREAT)
IncreaseSanity(src, 0.4, SANITY_GREAT)
if(insanity_effect != holdmyinsanityeffect)
if(insanity_effect > holdmyinsanityeffect)
@@ -218,9 +220,9 @@
master.crit_threshold = (master.crit_threshold - insanity_effect) + newval
insanity_effect = newval
/datum/component/mood/proc/DecreaseSanity(amount, minimum = SANITY_INSANE)
/datum/component/mood/proc/DecreaseSanity(datum/source, amount, minimum = SANITY_INSANE)
if(sanity < minimum) //This might make KevinZ stop fucking pinging me.
IncreaseSanity(0.5)
IncreaseSanity(src, 0.5)
else
sanity = max(minimum, sanity - amount)
if(sanity < SANITY_UNSTABLE)
@@ -229,13 +231,13 @@
else
insanity_effect = (MINOR_INSANITY_PEN)
/datum/component/mood/proc/IncreaseSanity(amount, maximum = SANITY_NEUTRAL)
/datum/component/mood/proc/IncreaseSanity(datum/source, amount, maximum = SANITY_NEUTRAL)
// Disturbed stops you from getting any more sane - I'm just gonna bung this in here
var/mob/living/owner = parent
if(HAS_TRAIT(owner, TRAIT_UNSTABLE))
return
if(sanity > maximum)
DecreaseSanity(0.5) //Removes some sanity to go back to our current limit.
DecreaseSanity(src, 0.5) //Removes some sanity to go back to our current limit.
else
sanity = min(maximum, sanity + amount)
if(sanity > SANITY_CRAZY)
@@ -262,6 +264,8 @@
if(the_event.timeout)
addtimer(CALLBACK(src, .proc/clear_event, null, category), the_event.timeout, TIMER_UNIQUE|TIMER_OVERRIDE)
return the_event
/datum/component/mood/proc/clear_event(datum/source, category)
var/datum/mood_event/event = mood_events[category]
if(!event)
+23 -24
View File
@@ -18,6 +18,7 @@
var/ride_check_rider_incapacitated = FALSE
var/ride_check_rider_restrained = FALSE
var/ride_check_ridden_incapacitated = FALSE
var/list/offhands = list() // keyed list containing all the current riding offsets associated by mob
/datum/component/riding/Initialize()
if(!ismovableatom(parent))
@@ -299,36 +300,34 @@
M.throw_at(target, 14, 5, AM)
M.Knockdown(60)
/datum/component/riding/proc/equip_buckle_inhands(mob/living/carbon/human/user, amount_required = 1, riding_target_override = null)
var/atom/movable/AM = parent
var/amount_equipped = 0
/datum/component/riding/proc/equip_buckle_inhands(mob/living/carbon/human/user, amount_required = 1, mob/living/riding_target_override)
var/list/equipped
var/mob/living/L = riding_target_override ? riding_target_override : user
for(var/amount_needed = amount_required, amount_needed > 0, amount_needed--)
var/obj/item/riding_offhand/inhand = new /obj/item/riding_offhand(user)
if(!riding_target_override)
inhand.rider = user
else
inhand.rider = riding_target_override
inhand.parent = AM
if(user.put_in_hands(inhand, TRUE))
amount_equipped++
else
var/obj/item/riding_offhand/inhand = new
inhand.rider = L
inhand.parent = parent
if(!user.put_in_hands(inhand, TRUE))
qdel(inhand) // it isn't going to be added to offhands anyway
break
LAZYADD(equipped, inhand)
var/amount_equipped = LAZYLEN(equipped)
if(amount_equipped)
LAZYADD(offhands[L], equipped)
if(amount_equipped >= amount_required)
return TRUE
else
unequip_buckle_inhands(user)
return FALSE
unequip_buckle_inhands(L)
return FALSE
/datum/component/riding/proc/unequip_buckle_inhands(mob/living/carbon/user)
var/atom/movable/AM = parent
for(var/obj/item/riding_offhand/O in user.contents)
if(O.parent != AM)
CRASH("RIDING OFFHAND ON WRONG MOB")
continue
if(O.selfdeleting)
continue
else
qdel(O)
for(var/a in offhands[user])
LAZYREMOVE(offhands[user], a)
if(a) //edge cases null entries
var/obj/item/riding_offhand/O = a
if(O.parent != parent)
CRASH("RIDING OFFHAND ON WRONG MOB")
else if(!O.selfdeleting)
qdel(O)
return TRUE
/obj/item/riding_offhand
+1 -1
View File
@@ -61,7 +61,7 @@
teamsize = 1
opendoors = FALSE
enforce_human = FALSE
roles = /datum/antagonist/greybois
roles = list(/datum/antagonist/greybois)
leader_role = /datum/antagonist/greybois/greygod
rename_team = "Emergency Assistants"
polldesc = "an Emergency Assistant"
@@ -169,3 +169,10 @@
/datum/mood_event/sad_empath/add_effects(mob/sadtarget)
description = "<span class='warning'>[sadtarget.name] seems upset...</span>\n"
/datum/mood_event/revenant_blight
description = "<span class='umbra'>Just give up, honk...</span>\n"
mood_change = -5
/datum/mood_event/revenant_blight/add_effects()
description = "<span class='umbra'>Just give up, [pick("no one will miss you", "there is nothing you can do to help", "even a clown would be more useful than you", "does it even matter in the end?")]...</span>\n"
+1 -1
View File
@@ -316,4 +316,4 @@
id = "advancedlab"
suffix = "advancedlab.dmm"
name = "Abductor Replication Lab"
description = "Some scientists tried and almost succeeded to recreate abductor tools. Somewhat slower and a bit less modern than their originals, these tools are the best you can get if you aren't an alien."
description = "Some scientists tried and almost succeeded to recreate abductor tools. Somewhat slower and a bit less modern than their originals, these tools are the best you can get if you aren't an alien."
+8 -5
View File
@@ -426,19 +426,20 @@
else
new /obj/effect/temp_visual/bleed(get_turf(owner))
/mob/living/proc/apply_necropolis_curse(set_curse)
/mob/living/proc/apply_necropolis_curse(set_curse, duration = 10 MINUTES)
var/datum/status_effect/necropolis_curse/C = has_status_effect(STATUS_EFFECT_NECROPOLIS_CURSE)
if(!set_curse)
set_curse = pick(CURSE_BLINDING, CURSE_SPAWNING, CURSE_WASTING, CURSE_GRASPING)
if(QDELETED(C))
apply_status_effect(STATUS_EFFECT_NECROPOLIS_CURSE, set_curse)
apply_status_effect(STATUS_EFFECT_NECROPOLIS_CURSE, set_curse, duration)
else
C.apply_curse(set_curse)
C.duration += 3000 //additional curses add 5 minutes
C.duration += duration * 0.5 //additional curses add half their duration
/datum/status_effect/necropolis_curse
id = "necrocurse"
duration = 6000 //you're cursed for 10 minutes have fun
duration = 10 MINUTES //you're cursed for 10 minutes have fun
tick_interval = 50
alert_type = null
var/curse_flags = NONE
@@ -446,7 +447,9 @@
var/effect_cooldown = 100
var/obj/effect/temp_visual/curse/wasting_effect = new
/datum/status_effect/necropolis_curse/on_creation(mob/living/new_owner, set_curse)
/datum/status_effect/necropolis_curse/on_creation(mob/living/new_owner, set_curse, _duration)
if(_duration)
duration = _duration
. = ..()
if(.)
apply_curse(set_curse)
+30
View File
@@ -203,3 +203,33 @@
/datum/quirk/bloodpressure/remove()
var/mob/living/M = quirk_holder
M.blood_ratio = 1
/datum/quirk/draconicspeaker
name = "Draconic speaker"
desc = "Due to your time spent around lizards, you can speak Draconic!"
value = 1
gain_text = "<span class='notice'>You feel sensitive to hissing noises and your tongue curls comfortably.</span>"
lose_text = "<span class='notice'>You forget how to speak Draconic!</span>"
/datum/quirk/draconicspeaker/add()
var/mob/living/M = quirk_holder
M.grant_language(/datum/language/draconic)
/datum/quirk/draconicspeaker/remove()
var/mob/living/M = quirk_holder
M.remove_language(/datum/language/draconic)
/datum/quirk/slimespeaker
name = "Slime speaker"
desc = "Due to your time spent around slimes, you can speak Slimespeak!"
value = 1
gain_text = "<span class='notice'>You feel sensitive to blorbling noises, and your throat produces melodic sounds.</span>"
lose_text = "<span class='notice'>You forget how to speak Slimespeak!</span>"
/datum/quirk/slimespeaker/add()
var/mob/living/M = quirk_holder
M.grant_language(/datum/language/slime)
/datum/quirk/slimespeaker/remove()
var/mob/living/M = quirk_holder
M.remove_language(/datum/language/slime)
+1 -1
View File
@@ -471,4 +471,4 @@
// Abductor Replication Lab
/area/ruin/space/has_grav/powered/advancedlab
name = "Abductor Replication Lab"
icon_state = "yellow"
icon_state = "yellow"
+2 -2
View File
@@ -124,12 +124,12 @@
L[avoid_assoc_duplicate_keys(A.name, areaindex)] = R
for(var/obj/item/implant/tracking/I in GLOB.tracked_implants)
if(!I.imp_in || !isliving(I.loc))
if(!I.imp_in || !I.allow_teleport || !isliving(I.imp_in))
continue
else
var/mob/living/M = I.loc
if(M.stat == DEAD)
if(M.timeofdeath + 6000 < world.time)
if(M.timeofdeath + I.lifespan_postmortem < world.time)
continue
if(is_eligible(I))
L[avoid_assoc_duplicate_keys(M.real_name, areaindex)] = I
+2 -1
View File
@@ -210,13 +210,13 @@
add_fingerprint(user)
/obj/machinery/suit_storage_unit/proc/cook()
var/mob/living/mob_occupant = occupant
if(uv_cycles)
uv_cycles--
uv = TRUE
locked = TRUE
update_icon()
if(occupant)
var/mob/living/mob_occupant = occupant
if(uv_super)
mob_occupant.adjustFireLoss(rand(20, 36))
else
@@ -245,6 +245,7 @@
visible_message("<span class='notice'>[src]'s door slides open. The glowing yellow lights dim to a gentle green.</span>")
else
visible_message("<span class='warning'>[src]'s door slides open, barraging you with the nauseating smell of charred flesh.</span>")
mob_occupant.radiation = 0
playsound(src, 'sound/machines/airlockclose.ogg', 25, 1)
for(var/obj/item/I in src) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRONG)
+40 -8
View File
@@ -1,3 +1,7 @@
GLOBAL_VAR_INIT(singularity_counter, 0)
#define METEOR_DISASTER_MODIFIER 0.5
////////////////////////////////////////
//Singularity beacon
////////////////////////////////////////
@@ -14,38 +18,58 @@
verb_say = "states"
var/cooldown = 0
var/active = 0
var/active = FALSE
var/meteor_buff = FALSE
var/icontype = "beacon"
/obj/machinery/power/singularity_beacon/proc/Activate(mob/user = null)
if(active)
return FALSE
if(surplus() < 1500)
if(user)
to_chat(user, "<span class='notice'>The connected wire doesn't have enough current.</span>")
return
return FALSE
if(is_station_level(z))
increment_meteor_waves()
for(var/obj/singularity/singulo in GLOB.singularities)
if(singulo.z == z)
singulo.target = src
icon_state = "[icontype]1"
active = 1
active = TRUE
if(user)
to_chat(user, "<span class='notice'>You activate the beacon.</span>")
return TRUE
/obj/machinery/power/singularity_beacon/proc/Deactivate(mob/user = null)
/obj/machinery/power/singularity_beacon/proc/Deactivate(mob/user)
if(!active)
return FALSE
for(var/obj/singularity/singulo in GLOB.singularities)
if(singulo.target == src)
singulo.target = null
icon_state = "[icontype]0"
active = 0
active = FALSE
if(user)
to_chat(user, "<span class='notice'>You deactivate the beacon.</span>")
if(meteor_buff)
decrement_meteor_waves()
return TRUE
/obj/machinery/power/singularity_beacon/proc/increment_meteor_waves()
meteor_buff = TRUE
GLOB.singularity_counter++
for(var/datum/round_event_control/meteor_wave/W in SSevents.control)
W.weight += round(initial(W.weight) * METEOR_DISASTER_MODIFIER)
/obj/machinery/power/singularity_beacon/proc/decrement_meteor_waves()
meteor_buff = FALSE
GLOB.singularity_counter--
for(var/datum/round_event_control/meteor_wave/W in SSevents.control)
W.weight -= round(initial(W.weight) * METEOR_DISASTER_MODIFIER)
/obj/machinery/power/singularity_beacon/attack_ai(mob/user)
return
/obj/machinery/power/singularity_beacon/attack_hand(mob/user)
. = ..()
if(.)
@@ -86,6 +110,12 @@
if(!active)
return
var/is_on_station = is_station_level(z)
if(meteor_buff && !is_on_station)
decrement_meteor_waves()
else if(!meteor_buff && is_on_station)
increment_meteor_waves()
if(surplus() >= 1500)
add_load(1500)
if(cooldown <= world.time)
@@ -133,3 +163,5 @@
/obj/item/sbeacondrop/clownbomb
desc = "A label on it reads: <i>Warning: Activating this device will send a silly explosive to your location</i>."
droptype = /obj/machinery/syndicatebomb/badmin/clown
#undef METEOR_DISASTER_MODIFIER
+21
View File
@@ -160,6 +160,7 @@ RLD
var/mode = 1
var/ranged = FALSE
var/computer_dir = 1
var/airlock_dir = 1
var/airlock_type = /obj/machinery/door/airlock
var/airlock_glass = FALSE // So the floor's rcd_act knows how much ammo to use
var/window_type = /obj/structure/window/fulltile
@@ -281,6 +282,22 @@ RLD
return FALSE
return TRUE
/obj/item/construction/rcd/proc/change_airlock_direction(mob/user)
if(!user)
return
var/list/airlock_dirs = list(
"North/South" = image(icon = 'icons/mob/radial.dmi', icon_state = "airlocknorthsouth"),
"East/West" = image(icon = 'icons/mob/radial.dmi', icon_state = "airlockeastwest")
)
var/airlockdirs = show_radial_menu(user, src, airlock_dirs, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
if(!check_menu(user))
return
switch(airlockdirs)
if("North/South")
airlock_dir = 1
if("East/West")
airlock_dir = 4
/obj/item/construction/rcd/proc/change_computer_dir(mob/user)
if(!user)
return
@@ -486,6 +503,7 @@ RLD
if(mode == RCD_AIRLOCK)
choices += list(
"Change Access" = image(icon = 'icons/mob/radial.dmi', icon_state = "access"),
"Change Direction" = image(icon = 'icons/mob/radial.dmi', icon_state = "airlockrotation"),
"Change Airlock Type" = image(icon = 'icons/mob/radial.dmi', icon_state = "airlocktype")
)
else if(mode == RCD_WINDOWGRILLE)
@@ -513,6 +531,9 @@ RLD
if("Change Access")
change_airlock_access(user)
return
if("Change Direction")
change_airlock_direction(user)
return
if("Change Airlock Type")
change_airlock_setting(user)
return
+15 -1
View File
@@ -453,7 +453,7 @@ GENE SCANNER
if(M.reagents.reagent_list.len)
var/list/datum/reagent/reagents = list()
for(var/datum/reagent/R in M.reagents.reagent_list)
if(R.invisible)
if(R.chemical_flags & REAGENT_INVISIBLE)
continue
reagents += R
@@ -475,6 +475,20 @@ GENE SCANNER
msg += "*---------*</span>"
to_chat(user, msg)
if(M.reagents.has_reagent("fermiTox"))
var/datum/reagent/fermiTox = M.reagents.has_reagent("fermiTox")
switch(fermiTox.volume)
if(5 to 10)
msg += "<span class='notice'>Subject contains a low amount of toxic isomers.</span>\n"
if(10 to 25)
msg += "<span class='danger'>Subject contains toxic isomers.</span>\n"
if(25 to 50)
msg += "<span class='danger'>Subject contains a substantial amount of toxic isomers.</span>\n"
if(50 to 95)
msg += "<span class='danger'>Subject contains a high amount of toxic isomers.</span>\n"
if(95 to INFINITY)
msg += "<span class='danger'>Subject contains a extremely dangerous amount of toxic isomers.</span>\n"
/obj/item/healthanalyzer/verb/toggle_mode()
set name = "Switch Verbosity"
set category = "Object"
+2
View File
@@ -1,5 +1,6 @@
/obj/item/restraints
breakouttime = 600
var/demoralize_criminals = TRUE // checked on carbon/carbon.dm to decide wheter to apply the handcuffed negative moodlet or not.
/obj/item/restraints/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] is strangling [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -220,6 +221,7 @@
name = "fake handcuffs"
desc = "Fake handcuffs meant for gag purposes."
breakouttime = 10 //Deciseconds = 1s
demoralize_criminals = FALSE
/obj/item/restraints/handcuffs/fake/kinky
name = "kinky handcuffs"
+2 -2
View File
@@ -249,7 +249,7 @@
return
var/obj/item/nullrod/holy_weapon
var/list/holy_weapons_list = typesof(/obj/item/nullrod) + list(
/obj/item/melee/transforming/energy/sword/cx/chaplain
/obj/item/twohanded/dualsaber/hypereutactic/chaplain
)
var/list/display_names = list()
for(var/V in holy_weapons_list)
@@ -710,7 +710,7 @@
righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
w_class = WEIGHT_CLASS_NORMAL
attack_verb = list("bashes", "smacks", "whacks")
/obj/item/nullrod/hypertool
icon = 'icons/obj/device.dmi'
icon_state = "hypertool"
@@ -1,7 +1,19 @@
/obj/item/implant/tracking
name = "tracking implant"
desc = "Track with this."
activated = 0
activated = FALSE
var/lifespan_postmortem = 10 MINUTES //for how many deciseconds after user death will the implant work?
var/allow_teleport = TRUE //will people implanted with this act as teleporter beacons?
/obj/item/implant/tracking/c38
name = "TRAC implant"
desc = "A smaller tracking implant that supplies power for only a few minutes."
var/lifespan = 5 MINUTES //how many deciseconds does the implant last?
allow_teleport = FALSE
/obj/item/implant/tracking/c38/Initialize()
. = ..()
QDEL_IN(src, lifespan)
/obj/item/implant/tracking/New()
..()
@@ -21,7 +33,7 @@
var/dat = {"<b>Implant Specifications:</b><BR>
<b>Name:</b> Tracking Beacon<BR>
<b>Life:</b> 10 minutes after death of host<BR>
<b>Important Notes:</b> None<BR>
<b>Important Notes:</b> Implant also works as a teleporter beacon.<BR>
<HR>
<b>Implant Details:</b> <BR>
<b>Function:</b> Continuously transmits low power signal. Useful for tracking.<BR>
+13 -9
View File
@@ -75,15 +75,14 @@
temp += "<B>Implant Signals:</B><BR>"
for (var/obj/item/implant/tracking/W in GLOB.tracked_implants)
if (!W.imp_in || !isliving(W.loc))
if (!isliving(W.imp_in))
continue
else
var/mob/living/M = W.loc
if (M.stat == DEAD)
if (M.timeofdeath + 6000 < world.time)
continue
var/mob/living/M = W.imp_in
if (M.stat == DEAD)
if (M.timeofdeath + W.lifespan_postmortem < world.time)
continue
var/turf/tr = get_turf(W)
var/turf/tr = get_turf(M)
if (tr.z == sr.z && tr)
var/direct = max(abs(tr.x - sr.x), abs(tr.y - sr.y))
if (direct < 20)
@@ -188,8 +187,13 @@
user.show_message("<span class='notice'>\The [src] is recharging!</span>")
return
var/atom/T = L[t1]
var/implantcheckmate = FALSE
if(isliving(T))
var/mob/living/M = T
if(!locate(/obj/item/implant/tracking) in M.implants) //The user was too slow and let the target mob's tracking implant expire or get removed.
implantcheckmate = TRUE
var/area/A = get_area(T)
if(A.noteleport)
if(A.noteleport || implantcheckmate)
to_chat(user, "<span class='notice'>\The [src] is malfunctioning.</span>")
return
current_location = get_turf(user) //Recheck.
@@ -233,4 +237,4 @@
itemUser.visible_message("<span class='suicide'>The portal snaps closed taking [user]'s head with it!</span>")
else
itemUser.visible_message("<span class='suicide'>[user] looks even further depressed as they realize they do not have a head...and suddenly dies of shame!</span>")
return (BRUTELOSS)
return (BRUTELOSS)
+1 -1
View File
@@ -232,7 +232,7 @@
. = ..()
if(!sliver)
return
if(ismovableatom(O) && O != sliver)
if(proximity && ismovableatom(O) && O != sliver)
Consume(O, user)
/obj/item/hemostat/supermatter/throw_impact(atom/hit_atom) // no instakill supermatter javelins
+10
View File
@@ -304,6 +304,16 @@
icon = "meow_mix"
desc = "No, we don't serve catnip, officer!"
/datum/barsign/goose
name = "The Loose Goose"
icon = "goose"
desc = "Drink till you puke and/or break the laws of reality!"
/datum/barsign/the_hive
name = "The Hive"
icon = "thehive"
desc = "Comb in for some sweet drinks! Not known for serving any sappy drink."
/datum/barsign/hiddensigns
hidden = TRUE
@@ -22,7 +22,9 @@
if(opened || move_delay || user.stat || user.IsStun() || user.IsKnockdown() || user.IsUnconscious() || !isturf(loc) || !has_gravity(loc))
return
move_delay = TRUE
if(step(src, direction))
var/oldloc = loc
step(src, direction)
if(oldloc != loc)
addtimer(CALLBACK(src, .proc/ResetMoveDelay), (use_mob_movespeed ? user.movement_delay() : CONFIG_GET(number/movedelay/walk_delay)) * move_speed_multiplier)
else
ResetMoveDelay()
@@ -561,7 +561,7 @@
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
mob_name = "a space pirate"
mob_species = /datum/species/skeleton/pirate
mob_species = /datum/species/skeleton/space
outfit = /datum/outfit/pirate/space
roundstart = FALSE
death = FALSE
+89 -32
View File
@@ -28,6 +28,8 @@
rad_insulation = RAD_VERY_LIGHT_INSULATION
rad_flags = RAD_PROTECT_CONTENTS
/obj/structure/window/examine(mob/user)
..()
if(reinf)
@@ -471,11 +473,12 @@
/turf/closed/wall/rust,
/turf/closed/wall/r_wall/rust,
/turf/closed/wall/clockwork,
/turf/closed/indestructible/riveted/,
/turf/closed/indestructible/riveted/uranium,
/obj/structure/window/fulltile,
/obj/structure/window/reinforced/fulltile,
/obj/structure/window/reinforced/tinted/fulltile,
/obj/structure/window/plasma/fulltile,
/obj/structure/window/plasma/reinforced/fulltile,
/obj/machinery/door,
/obj/machinery/door/airlock/,
/obj/machinery/door/airlock/mining,
/obj/machinery/door/airlock/mining/glass,
@@ -503,7 +506,10 @@
/obj/machinery/door/window/northright,
/obj/machinery/door/airlock/external,
/obj/machinery/door/airlock,
/obj/machinery/door)
/obj/machinery/door/airlock/hatch,
/obj/machinery/door/airlock/engineering/glass/critical,
/obj/machinery/door/airlock/atmos,
/obj/machinery/door/airlock/highsecurity,)
// canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile, /obj/structure/window/reinforced/tinted/fulltile, /obj/structure/window/plasma/fulltile, /obj/structure/window/plasma/reinforced/fulltile)
glass_amount = 2
@@ -529,11 +535,9 @@
/turf/closed/wall/rust,
/turf/closed/wall/r_wall/rust,
/turf/closed/wall/clockwork,
/obj/structure/window/fulltile,
/obj/structure/window/reinforced/fulltile,
/obj/structure/window/reinforced/tinted/fulltile,
/obj/structure/window/plasma/fulltile,
/obj/structure/window/plasma/reinforced/fulltile,
/obj/machinery/door,
/obj/machinery/door/airlock/,
/obj/machinery/door/airlock/mining,
/obj/machinery/door/airlock/mining/glass,
@@ -561,7 +565,13 @@
/obj/machinery/door/window/northright,
/obj/machinery/door/airlock/external,
/obj/machinery/door/airlock,
/obj/machinery/door)
/obj/machinery/door/airlock/hatch,
/obj/machinery/door/airlock/engineering/glass/critical,
/obj/machinery/door/airlock/atmos,
/obj/machinery/door/airlock/highsecurity,
/turf/closed/indestructible/,
/turf/closed/indestructible/riveted,
/turf/closed/indestructible/fakeglass)
glass_amount = 2
/obj/structure/window/plasma/fulltile/unanchored
@@ -577,31 +587,12 @@
smooth = SMOOTH_TRUE
glass_amount = 2
/obj/structure/window/plasma/reinforced/fulltile/unanchored
anchored = FALSE
/obj/structure/window/reinforced/fulltile
icon = 'icons/obj/smooth_structures/reinforced_window.dmi'
icon_state = "r_window"
dir = FULLTILE_WINDOW_DIR
max_integrity = 100
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
smooth = SMOOTH_TRUE
canSmoothWith = list(
/turf/closed/wall,
/turf/closed/wall/r_wall,
/obj/structure/falsewall,
/obj/structure/falsewall/brass,
/obj/structure/falsewall/reinforced,
/turf/closed/wall/rust,
/turf/closed/wall/r_wall/rust,
/turf/closed/wall/clockwork,
/obj/structure/window/fulltile,
/obj/structure/window/reinforced/fulltile,
/obj/structure/window/reinforced/tinted/fulltile,
/obj/structure/window/plasma/fulltile,
/obj/structure/window/plasma/reinforced/fulltile,
/obj/machinery/door,
/obj/machinery/door/airlock/,
/obj/machinery/door/airlock/mining,
/obj/machinery/door/airlock/mining/glass,
@@ -629,7 +620,70 @@
/obj/machinery/door/window/northright,
/obj/machinery/door/airlock/external,
/obj/machinery/door/airlock,
/obj/machinery/door)
/obj/machinery/door/airlock/hatch,
/obj/machinery/door/airlock/engineering/glass/critical,
/obj/machinery/door/airlock/atmos,
/obj/machinery/door/airlock/highsecurity
)
/obj/structure/window/plasma/reinforced/fulltile/unanchored
anchored = FALSE
/obj/structure/window/reinforced/fulltile
icon = 'icons/obj/smooth_structures/reinforced_window.dmi'
icon_state = "r_window"
dir = FULLTILE_WINDOW_DIR
max_integrity = 100
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
smooth = SMOOTH_TRUE
canSmoothWith = list(
/turf/closed/wall,
/turf/closed/wall/r_wall,
/obj/structure/falsewall,
/obj/structure/falsewall/brass,
/obj/structure/falsewall/reinforced,
/turf/closed/wall/rust,
/turf/closed/wall/r_wall/rust,
/turf/closed/wall/clockwork,
/turf/closed/indestructible/riveted/,
/turf/closed/indestructible/riveted/uranium,
/obj/structure/window/fulltile,
/obj/structure/window/reinforced/fulltile,
/obj/structure/window/reinforced/tinted/fulltile,
/obj/machinery/door,
/obj/machinery/door/airlock/,
/obj/machinery/door/airlock/mining,
/obj/machinery/door/airlock/mining/glass,
/obj/machinery/door/airlock/medical,
/obj/machinery/door/airlock/medical/glass,
/obj/machinery/door/airlock/public,
/obj/machinery/door/airlock/public/glass,
/obj/machinery/door/airlock/research,
/obj/machinery/door/airlock/research/glass,
/obj/machinery/door/airlock/maintenance,
/obj/machinery/door/airlock/maintenance/glass,
/obj/machinery/door/airlock/command/,
/obj/machinery/door/airlock/command/glass,
/obj/machinery/door/airlock/engineering,
/obj/machinery/door/airlock/engineering/glass,
/obj/machinery/door/airlock/engineering/abandoned,
/obj/machinery/door/airlock/security,
/obj/machinery/door/airlock/security/glass,
/obj/machinery/door/airlock/maintenance/abandoned,
/obj/machinery/door/poddoor/shutters/preopen,
/obj/machinery/door/poddoor/shutters,
/obj/machinery/door/window/eastright,
/obj/machinery/door/window/eastleft,
/obj/machinery/door/window/northleft,
/obj/machinery/door/window/northright,
/obj/machinery/door/airlock/external,
/obj/machinery/door/airlock,
/obj/machinery/door/airlock/hatch,
/obj/machinery/door/airlock/engineering/glass/critical,
/obj/machinery/door/airlock/atmos,
/obj/machinery/door/airlock/highsecurity,)
level = 3
glass_amount = 2
@@ -654,11 +708,12 @@
/turf/closed/wall/rust,
/turf/closed/wall/r_wall/rust,
/turf/closed/wall/clockwork,
/turf/closed/indestructible/riveted/,
/turf/closed/indestructible/riveted/uranium,
/obj/structure/window/fulltile,
/obj/structure/window/reinforced/fulltile,
/obj/structure/window/reinforced/tinted/fulltile,
/obj/structure/window/plasma/fulltile,
/obj/structure/window/plasma/reinforced/fulltile,
/obj/machinery/door,
/obj/machinery/door/airlock/,
/obj/machinery/door/airlock/mining,
/obj/machinery/door/airlock/mining/glass,
@@ -686,8 +741,10 @@
/obj/machinery/door/window/northright,
/obj/machinery/door/airlock/external,
/obj/machinery/door/airlock,
/obj/machinery/door)
/obj/machinery/door/airlock/hatch,
/obj/machinery/door/airlock/engineering/glass/critical,
/obj/machinery/door/airlock/atmos,
/obj/machinery/door/airlock/highsecurity,)
//Old code left of reference
//canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile, /obj/structure/window/reinforced/tinted/fulltile, /obj/structure/window/plasma/fulltile, /obj/structure/window/plasma/reinforced/fulltile)
level = 3
+2
View File
@@ -182,6 +182,8 @@
soundin = pick('sound/voice/beepsky/god.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/beepsky/secureday.ogg', 'sound/voice/beepsky/radio.ogg', 'sound/voice/beepsky/insult.ogg', 'sound/voice/beepsky/creep.ogg')
if("honkbot_e")
soundin = pick('sound/items/bikehorn.ogg', 'sound/items/AirHorn2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/items/AirHorn.ogg', 'sound/effects/reee.ogg', 'sound/items/WEEOO1.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/beepsky/creep.ogg','sound/magic/Fireball.ogg' ,'sound/effects/pray.ogg', 'sound/voice/hiss1.ogg','sound/machines/buzz-sigh.ogg', 'sound/machines/ping.ogg', 'sound/weapons/flashbang.ogg', 'sound/weapons/bladeslice.ogg')
if("goose")
soundin = pick('sound/creatures/goose1.ogg', 'sound/creatures/goose2.ogg', 'sound/creatures/goose3.ogg', 'sound/creatures/goose4.ogg')
//START OF CIT CHANGES - adds random vore sounds
if ("struggle_sound")
soundin = pick( 'sound/vore/pred/struggle_01.ogg','sound/vore/pred/struggle_02.ogg','sound/vore/pred/struggle_03.ogg',
+148
View File
@@ -86,9 +86,108 @@
smooth = SMOOTH_TRUE
explosion_block = INFINITY
canSmoothWith = list(
/turf/closed/wall,
/turf/closed/wall/r_wall,
/obj/structure/falsewall,
/obj/structure/falsewall/brass,
/obj/structure/falsewall/reinforced,
/turf/closed/wall/rust,
/turf/closed/wall/r_wall/rust,
/turf/closed/wall/clockwork,
/turf/closed/indestructible/riveted/,
/turf/closed/indestructible/riveted/uranium,
/obj/structure/window/fulltile,
/obj/structure/window/reinforced/fulltile,
/obj/structure/window/reinforced/tinted/fulltile,
/obj/structure/window/plasma/fulltile,
/obj/structure/window/plasma/reinforced/fulltile,
/obj/machinery/door,
/obj/machinery/door/airlock/,
/obj/machinery/door/airlock/mining,
/obj/machinery/door/airlock/mining/glass,
/obj/machinery/door/airlock/medical,
/obj/machinery/door/airlock/medical/glass,
/obj/machinery/door/airlock/public,
/obj/machinery/door/airlock/public/glass,
/obj/machinery/door/airlock/research,
/obj/machinery/door/airlock/research/glass,
/obj/machinery/door/airlock/maintenance,
/obj/machinery/door/airlock/maintenance/glass,
/obj/machinery/door/airlock/command/,
/obj/machinery/door/airlock/command/glass,
/obj/machinery/door/airlock/engineering,
/obj/machinery/door/airlock/engineering/glass,
/obj/machinery/door/airlock/engineering/abandoned,
/obj/machinery/door/airlock/security,
/obj/machinery/door/airlock/security/glass,
/obj/machinery/door/airlock/maintenance/abandoned,
/obj/machinery/door/poddoor/shutters/preopen,
/obj/machinery/door/poddoor/shutters,
/obj/machinery/door/window/eastright,
/obj/machinery/door/window/eastleft,
/obj/machinery/door/window/northleft,
/obj/machinery/door/window/northright,
/obj/machinery/door/airlock/external,
/obj/machinery/door/airlock,
/obj/machinery/door/airlock/hatch,
/obj/machinery/door/airlock/engineering/glass/critical,
/obj/machinery/door/airlock/atmos,
/obj/machinery/door/airlock/highsecurity,
/obj/machinery/door/airlock/centcom)
/turf/closed/indestructible/riveted/uranium
icon = 'icons/turf/walls/uranium_wall.dmi'
icon_state = "uranium"
canSmoothWith = list(
/turf/closed/wall,
/turf/closed/wall/r_wall,
/obj/structure/falsewall,
/obj/structure/falsewall/brass,
/obj/structure/falsewall/reinforced,
/turf/closed/wall/rust,
/turf/closed/wall/r_wall/rust,
/turf/closed/wall/clockwork,
/turf/closed/indestructible/riveted/,
/turf/closed/indestructible/riveted/uranium,
/obj/structure/window/fulltile,
/obj/structure/window/reinforced/fulltile,
/obj/structure/window/reinforced/tinted/fulltile,
/obj/structure/window/plasma/fulltile,
/obj/structure/window/plasma/reinforced/fulltile,
/obj/machinery/door,
/obj/machinery/door/airlock/,
/obj/machinery/door/airlock/mining,
/obj/machinery/door/airlock/mining/glass,
/obj/machinery/door/airlock/medical,
/obj/machinery/door/airlock/medical/glass,
/obj/machinery/door/airlock/public,
/obj/machinery/door/airlock/public/glass,
/obj/machinery/door/airlock/research,
/obj/machinery/door/airlock/research/glass,
/obj/machinery/door/airlock/maintenance,
/obj/machinery/door/airlock/maintenance/glass,
/obj/machinery/door/airlock/command/,
/obj/machinery/door/airlock/command/glass,
/obj/machinery/door/airlock/engineering,
/obj/machinery/door/airlock/engineering/glass,
/obj/machinery/door/airlock/engineering/abandoned,
/obj/machinery/door/airlock/security,
/obj/machinery/door/airlock/security/glass,
/obj/machinery/door/airlock/maintenance/abandoned,
/obj/machinery/door/poddoor/shutters/preopen,
/obj/machinery/door/poddoor/shutters,
/obj/machinery/door/window/eastright,
/obj/machinery/door/window/eastleft,
/obj/machinery/door/window/northleft,
/obj/machinery/door/window/northright,
/obj/machinery/door/airlock/external,
/obj/machinery/door/airlock,
/obj/machinery/door/airlock/hatch,
/obj/machinery/door/airlock/engineering/glass/critical,
/obj/machinery/door/airlock/atmos,
/obj/machinery/door/airlock/highsecurity,
/obj/machinery/door/airlock/centcom)
/turf/closed/indestructible/abductor
icon_state = "alien1"
@@ -102,6 +201,55 @@
opacity = 0
smooth = SMOOTH_TRUE
icon = 'icons/obj/smooth_structures/reinforced_window.dmi'
canSmoothWith = list(
/turf/closed/wall,
/turf/closed/wall/r_wall,
/obj/structure/falsewall,
/obj/structure/falsewall/brass,
/obj/structure/falsewall/reinforced,
/turf/closed/wall/rust,
/turf/closed/wall/r_wall/rust,
/turf/closed/wall/clockwork,
/turf/closed/indestructible/riveted/,
/turf/closed/indestructible/riveted/uranium,
/obj/structure/window/fulltile,
/obj/structure/window/reinforced/fulltile,
/obj/structure/window/reinforced/tinted/fulltile,
/obj/structure/window/plasma/fulltile,
/obj/structure/window/plasma/reinforced/fulltile,
/obj/machinery/door,
/obj/machinery/door/airlock/,
/obj/machinery/door/airlock/mining,
/obj/machinery/door/airlock/mining/glass,
/obj/machinery/door/airlock/medical,
/obj/machinery/door/airlock/medical/glass,
/obj/machinery/door/airlock/public,
/obj/machinery/door/airlock/public/glass,
/obj/machinery/door/airlock/research,
/obj/machinery/door/airlock/research/glass,
/obj/machinery/door/airlock/maintenance,
/obj/machinery/door/airlock/maintenance/glass,
/obj/machinery/door/airlock/command/,
/obj/machinery/door/airlock/command/glass,
/obj/machinery/door/airlock/engineering,
/obj/machinery/door/airlock/engineering/glass,
/obj/machinery/door/airlock/engineering/abandoned,
/obj/machinery/door/airlock/security,
/obj/machinery/door/airlock/security/glass,
/obj/machinery/door/airlock/maintenance/abandoned,
/obj/machinery/door/poddoor/shutters/preopen,
/obj/machinery/door/poddoor/shutters,
/obj/machinery/door/window/eastright,
/obj/machinery/door/window/eastleft,
/obj/machinery/door/window/northleft,
/obj/machinery/door/window/northright,
/obj/machinery/door/airlock/external,
/obj/machinery/door/airlock,
/obj/machinery/door/airlock/hatch,
/obj/machinery/door/airlock/engineering/glass/critical,
/obj/machinery/door/airlock/atmos,
/obj/machinery/door/airlock/highsecurity,
/obj/machinery/door/airlock/centcom)
/turf/closed/indestructible/fakeglass/Initialize()
. = ..()
+1 -1
View File
@@ -253,7 +253,7 @@
return FALSE
to_chat(user, "<span class='notice'>You build an airlock.</span>")
var/obj/machinery/door/airlock/A = new the_rcd.airlock_type(src)
A.setDir(the_rcd.airlock_dir)
A.electronics = new/obj/item/electronics/airlock(A)
if(the_rcd.conf_access)
@@ -192,7 +192,7 @@
explosion_block = 3
flags_1 = CAN_BE_DIRTY_1 | CHECK_RICOCHET_1
sheet_type = /obj/item/stack/sheet/mineral/titanium
smooth = SMOOTH_MORE|SMOOTH_DIAGONAL
smooth = SMOOTH_MORE
canSmoothWith = list(/turf/closed/wall/mineral/titanium, /obj/machinery/door/airlock/shuttle, /obj/machinery/door/airlock, /obj/structure/window/shuttle, /obj/structure/shuttle/engine/heater, /obj/structure/falsewall/titanium)
/turf/closed/wall/mineral/titanium/nodiagonal
+7 -1
View File
@@ -27,11 +27,14 @@
/turf/closed/wall/rust,
/turf/closed/wall/r_wall/rust,
/turf/closed/wall/clockwork,
/turf/closed/indestructible/riveted/,
/turf/closed/indestructible/riveted/uranium,
/obj/structure/window/fulltile,
/obj/structure/window/reinforced/fulltile,
/obj/structure/window/reinforced/tinted/fulltile,
/obj/structure/window/plasma/fulltile,
/obj/structure/window/plasma/reinforced/fulltile,
/obj/machinery/door,
/obj/machinery/door/airlock/,
/obj/machinery/door/airlock/mining,
/obj/machinery/door/airlock/mining/glass,
@@ -59,7 +62,10 @@
/obj/machinery/door/window/northright,
/obj/machinery/door/airlock/external,
/obj/machinery/door/airlock,
/obj/machinery/door)
/obj/machinery/door/airlock/hatch,
/obj/machinery/door/airlock/engineering/glass/critical,
/obj/machinery/door/airlock/atmos,
/obj/machinery/door/airlock/highsecurity)
smooth = SMOOTH_TRUE
+8 -3
View File
@@ -452,16 +452,21 @@
/turf/AllowDrop()
return TRUE
/turf/proc/add_vomit_floor(mob/living/carbon/M, toxvomit = NONE)
/turf/proc/add_vomit_floor(mob/living/M, toxvomit = NONE)
var/obj/effect/decal/cleanable/vomit/V = new /obj/effect/decal/cleanable/vomit(src, M.get_static_viruses())
// If the vomit combined, apply toxicity and reagents to the old vomit
//if the vomit combined, apply toxicity and reagents to the old vomit
if (QDELETED(V))
V = locate() in src
// Make toxins and blazaam vomit look different
if(toxvomit == VOMIT_PURPLE)
V.icon_state = "vomitpurp_[pick(1,4)]"
else if(toxvomit == VOMIT_TOXIC)
else if (toxvomit == VOMIT_TOXIC)
V.icon_state = "vomittox_[pick(1,4)]"
if (iscarbon(M))
var/mob/living/carbon/C = M
if(C.reagents)
clear_reagents_to_vomit_pool(C,V)
/proc/clear_reagents_to_vomit_pool(mob/living/carbon/M, obj/effect/decal/cleanable/vomit/V)
M.reagents.trans_to(V, M.reagents.total_volume / 10)
+3 -3
View File
@@ -413,9 +413,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
dat += "CLOSED"
else
dat += "UNKNOWN"
dat += "</b>[GLOB.TAB][TicketHref("Refresh", ref_src)][GLOB.TAB][TicketHref("Re-Title", ref_src, "retitle")]"
dat += "</b>[FOURSPACES][TicketHref("Refresh", ref_src)][FOURSPACES][TicketHref("Re-Title", ref_src, "retitle")]"
if(state != AHELP_ACTIVE)
dat += "[GLOB.TAB][TicketHref("Reopen", ref_src, "reopen")]"
dat += "[FOURSPACES][TicketHref("Reopen", ref_src, "reopen")]"
dat += "<br><br>Opened at: [GAMETIMESTAMP("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)"
if(closed_at)
dat += "<br>Closed at: [GAMETIMESTAMP("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)"
@@ -423,7 +423,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
if(initiator)
dat += "<b>Actions:</b> [FullMonty(ref_src)]<br>"
else
dat += "<b>DISCONNECTED</b>[GLOB.TAB][ClosureLinks(ref_src)]<br>"
dat += "<b>DISCONNECTED</b>[FOURSPACES][ClosureLinks(ref_src)]<br>"
dat += "<br><b>Log:</b><br><br>"
for(var/I in _interactions)
dat += "[I]<br>"
@@ -56,7 +56,7 @@
if(used)
to_chat(H, "You already used this contract!")
return
var/list/candidates = pollCandidatesForMob("Do you want to play as a wizard's [href_list["school"]] apprentice?", ROLE_WIZARD, null, ROLE_WIZARD, 150, src)
var/list/candidates = pollCandidatesForMob("Do you want to play as a wizard's [href_list["school"]] apprentice?", ROLE_WIZARD, null, ROLE_WIZARD, 150, src, ignore_category = POLL_IGNORE_WIZARD)
if(LAZYLEN(candidates))
if(QDELETED(src))
return
@@ -235,7 +235,7 @@
return
if(used)
return
var/list/candidates = pollCandidatesForMob("Do you want to play as a [initial(demon_type.name)]?", ROLE_ALIEN, null, ROLE_ALIEN, 50, src)
var/list/candidates = pollCandidatesForMob("Do you want to play as a [initial(demon_type.name)]?", ROLE_ALIEN, null, ROLE_ALIEN, 50, src, ignore_category = POLL_IGNORE_DEMON)
if(LAZYLEN(candidates))
if(used || QDELETED(src))
return
@@ -1,5 +1,5 @@
/datum/surgery/organ_extraction
name = "experimental dissection"
name = "experimental organ replacement"
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/incise, /datum/surgery_step/extract_organ, /datum/surgery_step/gland_insert)
possible_locs = list(BODY_ZONE_CHEST)
ignore_clothes = 1
+10 -5
View File
@@ -644,6 +644,11 @@
desc = "A spell that will absorb blood from anything you touch.<br>Touching cultists and constructs can heal them.<br><b>Clicking the hand will potentially let you focus the spell into something stronger.</b>"
color = "#7D1717"
/obj/item/melee/blood_magic/manipulator/examine(mob/user)
. = ..()
if(iscultist(user))
to_chat(user, "<span class='cultitalic'>The [name] currently has <b>[uses]</b> blood charges left.</span>")
/obj/item/melee/blood_magic/manipulator/afterattack(atom/target, mob/living/carbon/human/user, proximity)
if(proximity)
if(ishuman(target))
@@ -678,9 +683,9 @@
if(ratio>1)
ratio = 1
uses -= round(overall_damage)
H.visible_message("<span class='warning'>[H] is fully healed by [H==user ? "[H.p_their()]":"[H]'s"]'s blood magic!</span>")
H.visible_message("<span class='warning'>[H] is fully healed by [H==user ? "[H.p_their()]":"[user]'s"] blood magic!</span>")
else
H.visible_message("<span class='warning'>[H] is partially healed by [H==user ? "[H.p_their()]":"[H]'s"] blood magic.</span>")
H.visible_message("<span class='warning'>[H] is partially healed by [H==user ? "[H.p_their()]":"[user]'s"] blood magic.</span>")
uses = 0
ratio *= -1
H.adjustOxyLoss((overall_damage*ratio) * (H.getOxyLoss() / overall_damage), 0)
@@ -762,7 +767,7 @@
switch(choice)
if("Blood Spear (150)")
if(uses < 150)
to_chat(user, "<span class='cultitalic'>You need 200 charges to perform this rite.</span>")
to_chat(user, "<span class='cultitalic'>You need 150 charges to perform this rite.</span>")
else
uses -= 150
var/turf/T = get_turf(user)
@@ -778,7 +783,7 @@
"<span class='cultitalic'>A [rite.name] materializes at your feet.</span>")
if("Blood Bolt Barrage (300)")
if(uses < 300)
to_chat(user, "<span class='cultitalic'>You need 400 charges to perform this rite.</span>")
to_chat(user, "<span class='cultitalic'>You need 300 charges to perform this rite.</span>")
else
var/obj/rite = new /obj/item/gun/ballistic/shotgun/boltaction/enchanted/arcane_barrage/blood()
uses -= 300
@@ -790,7 +795,7 @@
qdel(rite)
if("Blood Beam (500)")
if(uses < 500)
to_chat(user, "<span class='cultitalic'>You need 600 charges to perform this rite.</span>")
to_chat(user, "<span class='cultitalic'>You need 500 charges to perform this rite.</span>")
else
var/obj/rite = new /obj/item/blood_beam()
uses -= 500
@@ -666,6 +666,7 @@
righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi'
slot_flags = 0
force = 17
force_unwielded = 17
force_wielded = 24
throwforce = 40
throw_speed = 2
+6 -42
View File
@@ -185,9 +185,6 @@ structure_check() searches for nearby cultist structures required for the invoca
color = RUNE_COLOR_OFFER
req_cultists = 1
rune_in_use = FALSE
var/mob/living/currentconversionman
var/conversiontimeout
var/conversionresult
/obj/effect/rune/convert/do_invoke_glow()
return
@@ -236,34 +233,14 @@ structure_check() searches for nearby cultist structures required for the invoca
/obj/effect/rune/convert/proc/do_convert(mob/living/convertee, list/invokers)
if(invokers.len < 2)
for(var/M in invokers)
to_chat(M, "<span class='danger'>You need at least two invokers to convert [convertee]!</span>")
to_chat(M, "<span class='warning'>You need at least two invokers to convert [convertee]!</span>")
log_game("Offer rune failed - tried conversion with one invoker")
return 0
if(convertee.anti_magic_check(TRUE, TRUE))
if(convertee.anti_magic_check(TRUE, TRUE, FALSE, 0)) //Not chargecost because it can be spammed
for(var/M in invokers)
to_chat(M, "<span class='warning'>Something is shielding [convertee]'s mind!</span>")
log_game("Offer rune failed - convertee had anti-magic")
return 0
to_chat(convertee, "<span class='cult italic'><b>The world goes red. All at once you are aware of an evil, eldritch truth taking roots into your mind.\n\
<a href='?src=\ref[src];signmeup=1'>Click here to become a follower of Nar'sie</a></b>, or suffer a fate worse than death.</span>")
INVOKE_ASYNC(src, .proc/optinalert, convertee)
currentconversionman = convertee
conversiontimeout = world.time + (14 SECONDS)
convertee.Stun(140)
ADD_TRAIT(convertee, TRAIT_MUTE, "conversionrune")
flash_color(convertee, list("#960000", "#960000", "#960000", rgb(0,0,0)), 50)
conversionresult = FALSE
while(world.time < conversiontimeout && convertee && !conversionresult)
stoplag(1)
currentconversionman = null
if(!convertee)
return FALSE
REMOVE_TRAIT(convertee, TRAIT_MUTE, "conversionrune")
if(get_turf(convertee) != get_turf(src))
return FALSE
if(!conversionresult)
do_sacrifice(convertee, invokers, TRUE)
return FALSE
var/brutedamage = convertee.getBruteLoss()
var/burndamage = convertee.getFireLoss()
if(brutedamage || burndamage)
@@ -275,6 +252,8 @@ structure_check() searches for nearby cultist structures required for the invoca
SSticker.mode.add_cultist(convertee.mind, 1)
new /obj/item/melee/cultblade/dagger(get_turf(src))
convertee.mind.special_role = ROLE_CULTIST
to_chat(convertee, "<span class='cult italic'><b>Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \
and something evil takes root.</b></span>")
to_chat(convertee, "<span class='cult italic'><b>Assist your new compatriots in their dark dealings. Your goal is theirs, and theirs is yours. You serve the Geometer above all else. Bring it back.\
</b></span>")
if(ishuman(convertee))
@@ -284,18 +263,7 @@ structure_check() searches for nearby cultist structures required for the invoca
H.cultslurring = 0
return 1
/obj/effect/rune/convert/proc/optinalert(mob/living/convertee)
var/alert = alert(convertee, "Will you embrace the Geometer of Blood or perish in futile resistance?", "Choose your own fate", "Join the Blood Cult", "Suffer a horrible demise")
if(alert == "Join the Blood Cult")
signmeup(convertee)
/obj/effect/rune/convert/proc/signmeup(mob/living/convertee)
if(currentconversionman == usr)
conversionresult = TRUE
else
to_chat(usr, "<span class='cult italic'>Your fate has already been set in stone.</span>")
/obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers, force_a_sac)
/obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers)
var/mob/living/first_invoker = invokers[1]
if(!first_invoker)
return FALSE
@@ -305,7 +273,7 @@ structure_check() searches for nearby cultist structures required for the invoca
var/big_sac = FALSE
if(!force_a_sac && (((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || C.cult_team.is_sacrifice_target(sacrificial.mind)) && invokers.len < 3)
if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || C.cult_team.is_sacrifice_target(sacrificial.mind)) && invokers.len < 3)
for(var/M in invokers)
to_chat(M, "<span class='cult italic'>[sacrificial] is too greatly linked to the world! You need three acolytes!</span>")
log_game("Offer rune failed - not enough acolytes and target is living or sac target")
@@ -345,10 +313,6 @@ structure_check() searches for nearby cultist structures required for the invoca
sacrificial.gib()
return TRUE
/obj/effect/rune/convert/Topic(href, href_list)
if(href_list["signmeup"])
signmeup(usr)
/obj/effect/rune/empower
cultist_name = "Empower"
cultist_desc = "allows cultists to prepare greater amounts of blood magic at far less of a cost."
+4 -4
View File
@@ -539,10 +539,10 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
var/list/parts = list()
parts += "The devil's true name is: [truename]"
parts += "The devil's bans were:"
parts += "[GLOB.TAB][GLOB.lawlorify[LORE][ban]]"
parts += "[GLOB.TAB][GLOB.lawlorify[LORE][bane]]"
parts += "[GLOB.TAB][GLOB.lawlorify[LORE][obligation]]"
parts += "[GLOB.TAB][GLOB.lawlorify[LORE][banish]]"
parts += "[FOURSPACES][GLOB.lawlorify[LORE][ban]]"
parts += "[FOURSPACES][GLOB.lawlorify[LORE][bane]]"
parts += "[FOURSPACES][GLOB.lawlorify[LORE][obligation]]"
parts += "[FOURSPACES][GLOB.lawlorify[LORE][banish]]"
return parts.Join("<br>")
/datum/antagonist/devil/roundend_report()
@@ -1,7 +1,8 @@
#define CHALLENGE_TELECRYSTALS 280
#define PLAYER_SCALING 1.5
#define CHALLENGE_TIME_LIMIT 3000
#define CHALLENGE_MIN_PLAYERS 50
#define CHALLENGE_PLAYERS_TARGET 50 //target players population. anything below is a malus to the challenge tc bonus.
#define TELECRYSTALS_MALUS_SCALING 1 //the higher the value, the bigger the malus.
#define CHALLENGE_SHUTTLE_DELAY 15000 // 25 minutes, so the ops have at least 5 minutes before the shuttle is callable.
GLOBAL_LIST_EMPTY(jam_on_wardec)
@@ -62,12 +63,15 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
for(var/obj/machinery/computer/camera_advanced/shuttle_docker/D in GLOB.jam_on_wardec)
D.jammed = TRUE
GLOB.war_declared = TRUE
var/list/nukeops = get_antag_minds(/datum/antagonist/nukeop)
var/actual_players = GLOB.joined_player_list.len - nukeops.len
var/tc_malus = 0
if(actual_players < CHALLENGE_PLAYERS_TARGET)
tc_malus = FLOOR((CHALLENGE_TELECRYSTALS - actual_players * INVERSE(CHALLENGE_PLAYERS_TARGET)) * TELECRYSTALS_MALUS_SCALING, 1)
new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS + CEILING(PLAYER_SCALING * actual_players, 1))
new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS - tc_malus + CEILING(PLAYER_SCALING * actual_players, 1))
CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY))
SSblackbox.record_feedback("amount", "nuclear_challenge_mode", 1)
@@ -79,11 +83,6 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
to_chat(user, "You are already in the process of declaring war! Make your mind up.")
return FALSE
var/list/nukeops = get_antag_minds(/datum/antagonist/nukeop)
var/actual_players = GLOB.joined_player_list.len - nukeops.len
if(actual_players < CHALLENGE_MIN_PLAYERS)
to_chat(user, "The enemy crew is too small to be worth declaring war on.")
return FALSE
if(!user.onSyndieBase())
to_chat(user, "You have to be at your base to use this.")
return FALSE
@@ -102,5 +101,6 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
#undef CHALLENGE_TELECRYSTALS
#undef CHALLENGE_TIME_LIMIT
#undef CHALLENGE_MIN_PLAYERS
#undef CHALLENGE_PLAYERS_TARGET
#undef TELECRYSTALS_MALUS_SCALING
#undef CHALLENGE_SHUTTLE_DELAY
@@ -11,9 +11,9 @@
viable_mobtypes = list(/mob/living/carbon/human)
disease_flags = CURABLE
permeability_mod = 1
severity = DISEASE_SEVERITY_HARMFUL
var/stagedamage = 0 //Highest stage reached.
severity = DISEASE_SEVERITY_DANGEROUS
var/finalstage = 0 //Because we're spawning off the cure in the final stage, we need to check if we've done the final stage's effects.
var/datum/mood_event/revenant_blight/depression
/datum/disease/revblight/cure()
if(affected_mob)
@@ -21,12 +21,13 @@
if(affected_mob.dna && affected_mob.dna.species)
affected_mob.dna.species.handle_mutant_bodyparts(affected_mob)
affected_mob.dna.species.handle_hair(affected_mob)
to_chat(affected_mob, "<span class='notice'>You feel better.</span>")
SEND_SIGNAL(affected_mob, COMSIG_CLEAR_MOOD_EVENT, "rev_blight")
..()
/datum/disease/revblight/stage_act()
if(!finalstage)
if(affected_mob.lying && prob(stage*6))
if(affected_mob.lying && prob(stage*4))
to_chat(affected_mob, "<span class='notice'>You feel better.</span>")
cure()
return
if(prob(stage*3))
@@ -34,10 +35,6 @@
affected_mob.confused += 8
affected_mob.adjustStaminaLoss(8)
new /obj/effect/temp_visual/revenant(affected_mob.loc)
if(stagedamage < stage)
stagedamage++
affected_mob.adjustToxLoss(stage*2) //should, normally, do about 30 toxin damage.
new /obj/effect/temp_visual/revenant(affected_mob.loc)
if(prob(45))
affected_mob.adjustStaminaLoss(stage)
..() //So we don't increase a stage before applying the stage damage.
@@ -46,9 +43,13 @@
if(prob(5))
affected_mob.emote("pale")
if(3)
if(!depression)
depression = SEND_SIGNAL(affected_mob, COMSIG_ADD_MOOD_EVENT, "rev_blight", /datum/mood_event/revenant_blight)
SEND_SIGNAL(affected_mob, COMSIG_DECREASE_SANITY, 0.12, SANITY_CRAZY)
if(prob(10))
affected_mob.emote(pick("pale","shiver"))
if(4)
SEND_SIGNAL(affected_mob, COMSIG_DECREASE_SANITY, 0.18, SANITY_CRAZY)
if(prob(15))
affected_mob.emote(pick("pale","shiver","cries"))
if(5)
@@ -56,12 +57,18 @@
finalstage = TRUE
to_chat(affected_mob, "<span class='revenbignotice'>You feel like [pick("nothing's worth it anymore", "nobody ever needed your help", "nothing you did mattered", "everything you tried to do was worthless")].</span>")
affected_mob.adjustStaminaLoss(45)
new /obj/effect/temp_visual/revenant(affected_mob.loc)
if(affected_mob.dna && affected_mob.dna.species)
if(affected_mob.dna?.species)
affected_mob.dna.species.handle_mutant_bodyparts(affected_mob,"#1d2953")
affected_mob.dna.species.handle_hair(affected_mob,"#1d2953")
affected_mob.visible_message("<span class='warning'>[affected_mob] looks terrifyingly gaunt...</span>", "<span class='revennotice'>You suddenly feel like your skin is <i>wrong</i>...</span>")
affected_mob.add_atom_colour("#1d2953", TEMPORARY_COLOUR_PRIORITY)
addtimer(CALLBACK(src, .proc/cure), 100)
else
return
new /obj/effect/temp_visual/revenant(affected_mob.loc)
addtimer(CALLBACK(src, .proc/curses), 150)
/datum/disease/revblight/proc/curses()
if(QDELETED(affected_mob))
return
affected_mob.playsound_local(affected_mob, 'sound/effects/curse5.ogg', 40, 1, -1)
to_chat(affected_mob, "<span class='revendanger'>You sense the terrific curse of a vengeful ghost befall upon you...</span>")
affected_mob.apply_necropolis_curse(null, 7 MINUTES) //Once the blight has done its course without being cured beforehand, it will cast a necrocurse to compensate how underpowered it's.
cure()
@@ -198,7 +198,7 @@
to_chat(user, "<span class='warning'>This artifact can only affect three undead at a time!</span>")
return
M.set_species(/datum/species/skeleton, icon_update=0)
M.set_species(/datum/species/skeleton/space, icon_update=0)
M.revive(full_heal = 1, admin_revive = 1)
spooky_scaries |= M
to_chat(M, "<span class='userdanger'>You have been revived by </span><B>[user.real_name]!</B>")
+2
View File
@@ -571,6 +571,8 @@ GLOBAL_LIST_EMPTY(asset_datums)
"fontawesome-webfont.woff" = 'tgui/assets/fonts/fontawesome-webfont.woff',
"font-awesome.css" = 'code/modules/goonchat/browserassets/css/font-awesome.css',
"browserOutput.css" = 'code/modules/goonchat/browserassets/css/browserOutput.css',
"browserOutput_dark.css" = 'code/modules/goonchat/browserassets/css/browserOutput_dark.css',
"browserOutput_light.css" = 'code/modules/goonchat/browserassets/css/browserOutput_light.css'
)
/datum/asset/spritesheet/goonchat
+8 -20
View File
@@ -16,7 +16,7 @@ Thanks to spacemaniac and mcdonald for help with the JS side of this.
//Main windows
winset(src, "infowindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
winset(src, "info", "background-color = [COLOR_WHITEMODE_BACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
winset(src, "browseroutput", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];text-color = [COLOR_WHITEMODE_TEXT]")
winset(src, "browseroutput", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
winset(src, "outputwindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
winset(src, "mainwindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND]")
winset(src, "split", "background-color = [COLOR_WHITEMODE_BACKGROUND]")
@@ -30,7 +30,9 @@ Thanks to spacemaniac and mcdonald for help with the JS side of this.
//Status and verb tabs
winset(src, "output", "background-color = [COLOR_WHITEMODE_BACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
winset(src, "statwindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
winset(src, "stat", "background-color = [COLOR_WHITEMODE_BACKGROUND];tab-background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT];tab-text-color = [COLOR_WHITEMODE_TEXT];prefix-color = [COLOR_WHITEMODE_TEXT];suffix-color = [COLOR_WHITEMODE_TEXT]")
winset(src, "stat", "background-color = [COLOR_WHITEMODE_BACKGROUND];tab-background-color = [COLOR_WHITEMODE_DARKBACKGROUND];\
text-color = [COLOR_WHITEMODE_TEXT];tab-text-color = [COLOR_WHITEMODE_TEXT];\
prefix-color = [COLOR_WHITEMODE_TEXT];suffix-color = [COLOR_WHITEMODE_TEXT]")
//Etc.
winset(src, "say", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
winset(src, "asset_cache_browser", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
@@ -54,24 +56,10 @@ Thanks to spacemaniac and mcdonald for help with the JS side of this.
//Status and verb tabs
winset(src, "output", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
winset(src, "statwindow", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
winset(src, "stat", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];tab-background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT];tab-text-color = [COLOR_DARKMODE_TEXT];prefix-color = [COLOR_DARKMODE_TEXT];suffix-color = [COLOR_DARKMODE_TEXT]")
winset(src, "stat", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];tab-background-color = [COLOR_DARKMODE_BACKGROUND];\
text-color = [COLOR_DARKMODE_TEXT];tab-text-color = [COLOR_DARKMODE_TEXT];\
prefix-color = [COLOR_DARKMODE_TEXT];suffix-color = [COLOR_DARKMODE_TEXT]")
//Etc.
winset(src, "say", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
winset(src, "asset_cache_browser", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
winset(src, "tooltip", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
/datum/asset/simple/goonchat
verify = FALSE
assets = list(
"json2.min.js" = 'code/modules/goonchat/browserassets/js/json2.min.js',
"errorHandler.js" = 'code/modules/goonchat/browserassets/js/errorHandler.js',
"browserOutput.js" = 'code/modules/goonchat/browserassets/js/browserOutput.js',
"fontawesome-webfont.eot" = 'tgui/assets/fonts/fontawesome-webfont.eot',
"fontawesome-webfont.svg" = 'tgui/assets/fonts/fontawesome-webfont.svg',
"fontawesome-webfont.ttf" = 'tgui/assets/fonts/fontawesome-webfont.ttf',
"fontawesome-webfont.woff" = 'tgui/assets/fonts/fontawesome-webfont.woff',
"font-awesome.css" = 'code/modules/goonchat/browserassets/css/font-awesome.css',
"browserOutput.css" = 'code/modules/goonchat/browserassets/css/browserOutput.css',
"browserOutput_white.css" = 'code/modules/goonchat/browserassets/css/browserOutput_white.css',
)
winset(src, "tooltip", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
+9 -2
View File
@@ -777,6 +777,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<b>Testicles Color:</b></a><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["balls_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=balls_color;task=input'>Change</a><br>"
dat += "<b>Testicles showing:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=balls_shape;task=input'>[features["balls_shape"]]</a>"
dat += "<b>Produces:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=balls_fluid;task=input'>[features["balls_fluid"]]</a>"
dat += APPEARANCE_CATEGORY_COLUMN
dat += "<h3>Vagina</h3>"
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_vag'>[features["has_vag"] == TRUE ? "Yes" : "No"]</a>"
@@ -807,7 +808,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<b>Lactates:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_producing'>[features["breasts_producing"] == TRUE ? "Yes" : "No"]</a>"
if(features["breasts_producing"] == TRUE)
dat += "<b>Produces:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_fluid;task=input'>[features["breasts_fluid"]]</a>"
dat += "</td>"
dat += "</td>"
dat += "</tr></table>"
@@ -1996,6 +1997,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(new_shape)
features["balls_shape"] = new_shape
if("balls_fluid")
var/new_shape
new_shape = input(user, "Balls Fluid", "Character Preference") as null|anything in GLOB.genital_fluids_list
if(new_shape)
features["balls_fluid"] = new_shape
if("egg_size")
var/new_size
var/list/egg_sizes = list(1,2,3)
@@ -2023,7 +2030,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
new_shape = input(user, "Breast Shape", "Character Preference") as null|anything in GLOB.breasts_shapes_list
if(new_shape)
features["breasts_shape"] = new_shape
if("breasts_fluid")
var/new_shape
new_shape = input(user, "Breast Fluid", "Character Preference") as null|anything in GLOB.genital_fluids_list
+1
View File
@@ -1,3 +1,4 @@
GLOBAL_VAR_INIT(LOOC_COLOR, null)//If this is null, use the CSS for OOC. Otherwise, use a custom colour.
GLOBAL_VAR_INIT(normal_looc_colour, "#6699CC")
+5 -4
View File
@@ -14,19 +14,20 @@
icon_state = "DS-magboots0"
magboot_state = "DS-magboots"
icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi'
alternate_worn_icon = 'modular_citadel/icons/mob/citadel/head.dmi'
alternate_worn_icon = 'icons/mob/feet.dmi'
slowdown_active = SHOES_SLOWDOWN
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
mutantrace_variation = NO_MUTANTRACE_VARIATION
mutantrace_variation = MUTANTRACE_VARIATION
/obj/item/clothing/shoes/magboots/atmos
desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle. These are painted in the colors of an atmospheric technician."
name = "atmospherics magboots"
icon_state = "atmosmagboots0"
icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi'
alternate_worn_icon = 'modular_citadel/icons/mob/citadel/head.dmi'
alternate_worn_icon = 'icons/mob/feet.dmi'
magboot_state = "atmosmagboots"
resistance_flags = FIRE_PROOF
mutantrace_variation = NO_MUTANTRACE_VARIATION
mutantrace_variation = MUTANTRACE_VARIATION
/obj/item/clothing/shoes/simonshoes
name = "Simon's Shoes"
+9 -1
View File
@@ -1,5 +1,8 @@
// Normal strength
#define SINGULO_BEACON_DISTURBANCE 0.2 //singularity beacon also improve the odds of meteor waves and speed them up a little.
#define SINGULO_BEACON_MAX_DISTURBANCE 0.6 //maximum cap due to how meteor waves can be potentially round ending.
/datum/round_event_control/meteor_wave
name = "Meteor Wave: Normal"
typepath = /datum/round_event/meteor_wave
@@ -18,6 +21,8 @@
/datum/round_event/meteor_wave/setup()
announceWhen = 1
startWhen = rand(300, 600) //Yeah for SOME REASON this is measured in seconds and not deciseconds???
if(GLOB.singularity_counter)
startWhen *= 1 - min(GLOB.singularity_counter * SINGULO_BEACON_DISTURBANCE, SINGULO_BEACON_MAX_DISTURBANCE)
endWhen = startWhen + 60
@@ -52,7 +57,7 @@
kill()
/datum/round_event/meteor_wave/announce(fake)
priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round(startWhen/60)] minutes.", "Meteor Alert", 'sound/ai/meteors.ogg')
priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round(startWhen/60)] minutes.[GLOB.singularity_counter ? " Warning: Anomalous gravity pulse detected, Syndicate technology interference likely." : ""]", "Meteor Alert", 'sound/ai/meteors.ogg')
/datum/round_event/meteor_wave/tick()
if(ISMULTIPLE(activeFor, 3))
@@ -79,3 +84,6 @@
/datum/round_event/meteor_wave/catastrophic
wave_name = "catastrophic"
#undef SINGULO_BEACON_DISTURBANCE
#undef SINGULO_BEACON_MAX_DISTURBANCE
+3 -1
View File
@@ -771,7 +771,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
..()
var/turf/source = random_far_turf()
if(!sound_type)
sound_type = pick("airlock","airlock pry","console","explosion","far explosion","mech","glass","alarm","beepsky","mech","wall decon","door hack")
sound_type = pick("airlock","airlock pry","console","flash","explosion","far explosion","mech","glass","alarm","beepsky","mech","wall decon","door hack")
feedback_details += "Type: [sound_type]"
//Strange audio
switch(sound_type)
@@ -788,6 +788,8 @@ GLOBAL_LIST_INIT(hallucination_list, list(
target.playsound_local(source,'sound/effects/explosion1.ogg', 50, 1)
else
target.playsound_local(source, 'sound/effects/explosion2.ogg', 50, 1)
if("flash")
target.playsound_local(source, 'sound/weapons/flash.ogg', 50, 1)
if("far explosion")
target.playsound_local(source, 'sound/effects/explosionfar.ogg', 50, 1)
if("glass")
@@ -410,7 +410,9 @@
FermiChem = TRUE//If the chemical uses the Fermichem reaction mechanics
FermiExplode = FALSE //If the chemical explodes in a special way
PurityMin = 0 //The minimum purity something has to be above, otherwise it explodes.
clear_conversion = REACTION_CLEAR_INVERSE
/*
/datum/chemical_reaction/neurotoxin/FermiFinish(datum/reagents/holder, var/atom/my_atom)
var/datum/reagent/consumable/ethanol/neurotoxin/Nt = locate(/datum/reagent/consumable/ethanol/neurotoxin) in my_atom.reagents.reagent_list
if(Nt)
@@ -418,6 +420,7 @@
if(Nt.purity < 0.5)
holder.remove_reagent(src.id, cached_volume)
holder.add_reagent("neurosmash", cached_volume)
*/
/datum/chemical_reaction/snowwhite
name = "Snow White"
+14 -48
View File
@@ -5,17 +5,9 @@ For the main html chat area
//Precaching a bunch of shit
GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of icons for the browser output
//Should match the value set in the browser js
#define MAX_COOKIE_LENGTH 5
//On client, created on login
/datum/chatOutput
var/client/owner //client ref
// How many times client data has been checked
var/total_checks = 0
// When to next clear the client data checks counter
var/next_time_to_clear = 0
var/loaded = FALSE // Has the client loaded the browser output area?
var/list/messageQueue //If they haven't loaded chat, this is where messages will go until they do
var/cookieSent = FALSE // Has the client sent a cookie for analysis
@@ -90,11 +82,13 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
if("setMusicVolume")
data = setMusicVolume(arglist(params))
if("swaptodarkmode")
swaptodarkmode()
if("colorPresetPost") //User just swapped color presets in their goonchat preferences. Do we do anything else?
switch(href_list["preset"])
if("light")
owner.force_white_theme()
if("dark" || "normal")
owner.force_dark_theme()
if("swaptolightmode")
swaptolightmode()
if(data)
ehjax_send(data = data)
@@ -156,19 +150,6 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
//Called by client, sent data to investigate (cookie history so far)
/datum/chatOutput/proc/analyzeClientData(cookie = "")
//Spam check
if(world.time > next_time_to_clear)
next_time_to_clear = world.time + (3 SECONDS)
total_checks = 0
total_checks += 1
if(total_checks > SPAM_TRIGGER_AUTOMUTE)
message_admins("[key_name(owner)] kicked for goonchat topic spam")
qdel(owner)
return
if(!cookie)
return
@@ -177,24 +158,13 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
if (connData && islist(connData) && connData.len > 0 && connData["connData"])
connectionHistory = connData["connData"] //lol fuck
var/list/found = new()
if(connectionHistory.len > MAX_COOKIE_LENGTH)
message_admins("[key_name(src.owner)] was kicked for an invalid ban cookie)")
qdel(owner)
return
for(var/i in connectionHistory.len to 1 step -1)
if(QDELETED(owner))
//he got cleaned up before we were done
return
var/list/row = src.connectionHistory[i]
if (!row || row.len < 3 || (!row["ckey"] || !row["compid"] || !row["ip"])) //Passed malformed history object
return
if (world.IsBanned(row["ckey"], row["ip"], row["compid"], real_bans_only=TRUE))
found = row
break
CHECK_TICK
//Uh oh this fucker has a history of playing on a banned account!!
if (found.len > 0)
@@ -213,8 +183,8 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
log_world("\[[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]\] Client: [(src.owner.key ? src.owner.key : src.owner)] triggered JS error: [error]")
//Global chat procs
/proc/to_chat(target, message, handle_whitespace=TRUE)
if(!target)
/proc/to_chat_immediate(target, message, handle_whitespace=TRUE)
if(!target || !message)
return
//Ok so I did my best but I accept that some calls to this will be for shit like sound and images
@@ -236,7 +206,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
message = replacetext(message, "\proper", "")
if(handle_whitespace)
message = replacetext(message, "\n", "<br>")
message = replacetext(message, "\t", "[GLOB.TAB][GLOB.TAB]")
message = replacetext(message, "\t", "[FOURSPACES][FOURSPACES]")
if(islist(target))
// Do the double-encoding outside the loop to save nanoseconds
@@ -279,12 +249,8 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
// url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript.
C << output(url_encode(url_encode(message)), "browseroutput:output")
/datum/chatOutput/proc/swaptolightmode() //Dark mode light mode stuff. Yell at KMC if this breaks! (See darkmode.dm for documentation)
owner.force_white_theme()
/datum/chatOutput/proc/swaptodarkmode()
owner.force_dark_theme()
#undef MAX_COOKIE_LENGTH
/proc/to_chat(target, message, handle_whitespace = TRUE)
if(Master.current_runlevel == RUNLEVEL_INIT || !SSchat?.initialized)
to_chat_immediate(target, message, handle_whitespace)
return
SSchat.queue(target, message, handle_whitespace)
@@ -7,20 +7,16 @@ html, body {
padding: 0;
margin: 0;
height: 100%;
color: #f0f0f0;
color: #000000;
}
body {
background: #171717;
background: #E0E0E0; /*CIT CHANGE - darkens chatbox a lil*/
font-family: Verdana, sans-serif;
font-size: 9pt;
font-color: #f0f0f0;
line-height: 1.2;
overflow-x: hidden;
overflow-y: scroll;
word-wrap: break-word;
scrollbar-face-color:#1A1A1A;
scrollbar-track-color:#171717;
scrollbar-highlight-color:#171717;
word-wrap: break-word;
}
em {
@@ -60,9 +56,9 @@ img.icon {
border-radius: 10px;
}
a {color: #397ea5;}
a.visited {color: #7c00e6;}
a:visited {color: #7c00e6;}
a {color: #0000ff;}
a.visited {color: #ff00ff;}
a:visited {color: #ff00ff;}
a.popt {text-decoration: none;}
/*****************************************
@@ -93,21 +89,21 @@ a.popt {text-decoration: none;}
bottom: 0;
right: 0;
padding: 8px;
background: #202020;
background: #d0d0d0;
text-decoration: none;
font-variant: small-caps;
font-size: 1.1em;
font-weight: bold;
color: #a4bad6;
color: #333;
}
#newMessages:hover {background: #171717;}
#newMessages:hover {background: #ccc;}
#newMessages i {vertical-align: middle; padding-left: 3px;}
#ping {
position: fixed;
top: 0;
right: 115px;
width: 45px;
background: #202020;
background: #d0d0d0;
height: 30px;
padding: 8px 0 2px 0;
}
@@ -124,19 +120,19 @@ a.popt {text-decoration: none;}
right: 0;
}
#userBar .subCell {
background: #202020;
background: #d0d0d0;
height: 30px;
padding: 5px 0;
display: block;
color: #a4bad6;
color: #333;
text-decoration: none;
line-height: 28px;
border-top: 1px solid #171717;
border-top: 1px solid #b4b4b4;
}
#userBar .subCell:hover {background: #202020;}
#userBar .subCell:hover {background: #ccc;}
#userBar .toggle {
width: 40px;
background: #202020;
background: #ccc;
border-top: 0;
float: right;
text-align: center;
@@ -172,7 +168,7 @@ a.popt {text-decoration: none;}
position: fixed;
top: 50%;
left: 50%;
background: #ddd;
background: #d0d0d0;
}
.popup .close {
position: absolute;
@@ -189,7 +185,7 @@ a.popt {text-decoration: none;}
.popup .close:hover {background: #999;}
.popup .head {
background: #999;
color: #ddd;
color: #d0d0d0;
padding: 0 10px;
height: 30px;
line-height: 30px;
@@ -200,7 +196,7 @@ a.popt {text-decoration: none;}
}
.popup input {border: 1px solid #999; background: #fff; margin: 0; padding: 5px; outline: none; color: #333;}
.popup input[type=text]:hover, .popup input[type=text]:active, .popup input[type=text]:focus {border-color: green;}
.popup input[type=submit] {padding: 5px 10px; background: #999; color: #ddd; text-transform: uppercase; font-size: 0.9em; font-weight: bold;}
.popup input[type=submit] {padding: 5px 10px; background: #999; color: #d0d0d0; text-transform: uppercase; font-size: 0.9em; font-weight: bold;}
.popup input[type=submit]:hover, .popup input[type=submit]:focus, .popup input[type=submit]:active {background: #aaa; cursor: pointer;}
.changeFont {padding: 10px;}
@@ -214,7 +210,7 @@ a.popt {text-decoration: none;}
/* ADMIN CONTEXT MENU */
.contextMenu {
background-color: #ddd;
background-color: #d0d0d0;
position: fixed;
margin: 2px;
width: 150px;
@@ -246,9 +242,9 @@ a.popt {text-decoration: none;}
******************************************/
/* MOTD */
.motd {color: #a4bad6; font-family: Verdana, sans-serif;}
.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #a4bad6; text-decoration: underline;}
.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #a4bad6;}
.motd {color: #638500; font-family: Verdana, sans-serif;}
.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #638500; text-decoration: underline;}
.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #638500;}
/* ADD HERE FOR BOLD */
.bold, .name, .prefix, .ooc, .looc, .adminooc, .admin, .medal, .yell {font-weight: bold;}
@@ -259,91 +255,91 @@ a.popt {text-decoration: none;}
/* OUTPUT COLORS */
.highlight {background: yellow;}
h1, h2, h3, h4, h5, h6 {color: #a4bad6;font-family: Georgia, Verdana, sans-serif;}
h1.alert, h2.alert {color: #a4bad6;}
h1, h2, h3, h4, h5, h6 {color: #0000ff;font-family: Georgia, Verdana, sans-serif;}
h1.alert, h2.alert {color: #000000;}
em {font-style: normal; font-weight: bold;}
.ooc {color: #cca300; font-weight: bold;}
.looc {color: #d8b555; font-weight: bold;}
.antagooc {color: #ce254f; font-weight: bold;}
.ooc {color: #002eb8; font-weight: bold;}
.looc {color: #6699CC; font-weight: bold;}
.antagooc {color: #b8002e; font-weight: bold;}
.adminobserverooc {color: #0099cc; font-weight: bold;}
.adminooc {color: #3d5bc3; font-weight: bold;}
.adminooc {color: #700038; font-weight: bold;}
.adminsay {color: #ff4500; font-weight: bold;}
.admin {color: #5975da; font-weight: bold;}
.adminsay {color: #FF4500}
.admin {color: #386aff; font-weight: bold;}
.name { font-weight: bold;}
.say {}
.deadsay {color: #e2c1ff;}
.deadsay {color: #5c00e6;}
.binarysay {color: #20c20e; background-color: #000000; display: block;}
.binarysay a {color: #00ff00;}
.binarysay a:active, .binarysay a:visited {color: #88ff88;}
.radio {color: #1ecc43;}
.sciradio {color: #c68cfa;}
.comradio {color: #5177ff;}
.secradio {color: #dd3535;}
.medradio {color: #57b8f0;}
.engradio {color: #f37746;}
.suppradio {color: #b88646;}
.servradio {color: #6ca729;}
.syndradio {color: #8f4a4b;}
.centcomradio {color: #2681a5;}
.aiprivradio {color: #d65d95;}
.redteamradio {color: #ff4444;}
.blueteamradio {color: #3434fd;}
.radio {color: #008000;}
.sciradio {color: #993399;}
.comradio {color: #948f02;}
.secradio {color: #a30000;}
.medradio {color: #337296;}
.engradio {color: #fb5613;}
.suppradio {color: #a8732b;}
.servradio {color: #6eaa2c;}
.syndradio {color: #6d3f40;}
.centcomradio {color: #686868;}
.aiprivradio {color: #ff00ff;}
.redteamradio {color: #ff0000;}
.blueteamradio {color: #0000ff;}
.yell { font-weight: bold;}
.alert {color: #d82020;}
h1.alert, h2.alert {color: #99aab5;}
.alert {color: #ff0000;}
h1.alert, h2.alert {color: #000000;}
.emote { font-style: italic;}
.selecteddna {color: #ffffff; background-color: #001B1B}
.attack {color: #e01c1c;}
.disarm {color: #b42525;}
.passive {color: #a00f0f;}
.attack {color: #ff0000;}
.disarm {color: #990000;}
.passive {color: #660000;}
.userdanger {color: #c51e1e; font-weight: bold; font-size: 24px;}
.danger {color: #c51e1e;}
.warning {color: #c51e1e; font-style: italic;}
.userdanger {color: #ff0000; font-weight: bold; font-size: 24px;}
.danger {color: #ff0000;}
.warning {color: #ff0000; font-style: italic;}
.alertwarning {color: #FF0000; font-weight: bold}
.boldwarning {color: #c51e1e; font-style: italic; font-weight: bold}
.announce {color: #c51e1e; font-weight: bold;}
.boldannounce {color: #c51e1e; font-weight: bold;}
.greenannounce {color: #059223; font-weight: bold;}
.boldwarning {color: #ff0000; font-style: italic; font-weight: bold}
.announce {color: #228b22; font-weight: bold;}
.boldannounce {color: #ff0000; font-weight: bold;}
.greenannounce {color: #00ff00; font-weight: bold;}
.rose {color: #ff5050;}
.info {color: #6685f5;}
.notice {color: #6685f5;}
.boldnotice {color: #6685f5; font-weight: bold;}
.adminnotice {color: #6685f5;}
.info {color: #0000CC;}
.notice {color: #000099;}
.boldnotice {color: #000099; font-weight: bold;}
.adminnotice {color: #0000ff;}
.adminhelp {color: #ff0000; font-weight: bold;}
.unconscious {color: #a4bad6; font-weight: bold;}
.unconscious {color: #0000ff; font-weight: bold;}}
.suicide {color: #ff5050; font-style: italic;}
.red {color: #FF0000}
.pink {color: #ff70c1;}
.blue {color: #215cff}
.green {color: #059223;}
.nicegreen {color: #059223;}
.green {color: #03ff39;}
.red {color: #FF0000;}
.pink {color: #FF69Bf;}
.blue {color: #0000FF;}
.nicegreen {color: #14a833;}
.userlove {color: #ff42a6; font-style: italic; font-weight: bold; text-shadow: 0 0 6px #82365e;}
.love {color: #ff4591; font-style: italic; text-shadow: 0 0 6px #994449;}
.shadowling {color: #8e8a99;}
.cult {color: #aa1c1c;}
.shadowling {color: #3b2769;}
.cult {color: #960000;}
.cultitalic {color: #aa1c1c; font-style: italic;}
.cultbold {color: #aa1c1c; font-style: italic; font-weight: bold;}
.cultboldtalic {color: #aa1c1c; font-weight: bold; font-size: 24px;}
.cultitalic {color: #960000; font-style: italic;}
.cultbold {color: #960000; font-style: italic; font-weight: bold;}
.cultboldtalic {color: #960000; font-weight: bold; font-size: 24px;}
.cultlarge {color: #aa1c1c; font-weight: bold; font-size: 24px;}
.narsie {color: #aa1c1c; font-weight: bold; font-size: 120px;}
.narsiesmall {color: #aa1c1c; font-weight: bold; font-size: 48px;}
.cultlarge {color: #960000; font-weight: bold; font-size: 24px;}
.narsie {color: #960000; font-weight: bold; font-size: 120px;}
.narsiesmall {color: #960000; font-weight: bold; font-size: 48px;}
.colossus {color: #7F282A; font-size: 40px;}
.hierophant {color: #b441ee; font-weight: bold; font-style: italic;}
.hierophant_warning {color: #c56bf1; font-style: italic;}
.purple {color: #9956d3;}
.holoparasite {color: #88809c;}
.hierophant {color: #660099; font-weight: bold; font-style: italic;}
.hierophant_warning {color: #660099; font-style: italic;}
.purple {color: #5e2d79;}
.holoparasite {color: #35333a;}
.revennotice {color: #1d2953;}
.revenboldnotice {color: #1d2953; font-weight: bold;}
@@ -351,11 +347,11 @@ h1.alert, h2.alert {color: #99aab5;}
.revenminor {color: #823abb}
.revenwarning {color: #760fbb; font-style: italic;}
.revendanger {color: #760fbb; font-weight: bold; font-size: 24px;}
.umbra {color: #7c00e6;}
.umbra_emphasis {color: #7c00e6; font-weight: bold; font-style: italic;}
.umbra_large {color: #7c00e6; font-size: 24px; font-weight: bold; font-style: italic;}
.umbra {color: #5000A0;}
.umbra_emphasis {color: #5000A0; font-weight: bold; font-style: italic;}
.umbra_large {color: #5000A0; font-size: 24px; font-weight: bold; font-style: italic;}
.deconversion_message {color: #a947ff; font-size: 24px; font-style: italic;}
.deconversion_message {color: #5000A0; font-size: 24px; font-style: italic;}
.brass {color: #BE8700;}
.heavy_brass {color: #BE8700; font-weight: bold; font-style: italic;}
@@ -380,17 +376,17 @@ h1.alert, h2.alert {color: #99aab5;}
.neovgre {color: #6E001A; font-weight: bold; font-style: italic;}
.neovgre_small {color: #6E001A;}
.newscaster {color: #c05d5d;}
.ghostalert {color: #6600ff; font-style: italic; font-weight: bold;}
.newscaster {color: #800000;}
.ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;}
.alien {color: #855d85;}
.noticealien {color: #059223;}
.alertalien {color: #059223; font-weight: bold;}
.changeling {color: #059223; font-style: italic;}
.alien {color: #543354;}
.noticealien {color: #00c000;}
.alertalien {color: #00c000; font-weight: bold;}
.changeling {color: #800080; font-style: italic;}
.spider {color: #8800ff;}
.spider {color: #4d004d;}
.interface {color: #750e75;}
.interface {color: #330033;}
.sans {font-family: "Comic Sans MS", cursive, sans-serif;}
.papyrus {font-family: "Papyrus", cursive, sans-serif;}
@@ -401,9 +397,9 @@ h1.alert, h2.alert {color: #99aab5;}
.big {font-size: 24px;}
.reallybig {font-size: 32px;}
.extremelybig {font-size: 40px;}
.greentext {color: #059223; font-size: 24px;}
.redtext {color: #c51e1e; font-size: 24px;}
.clown {color: #ff70c1; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;}
.greentext {color: #00FF00; font-size: 24px;}
.redtext {color: #FF0000; font-size: 24px;}
.clown {color: #FF69Bf; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;}
.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;}
.velvet {color: #660015; font-weight: bold; animation: velvet 5000ms infinite;}
@keyframes velvet {
@@ -435,20 +431,20 @@ h1.alert, h2.alert {color: #99aab5;}
.memo {color: #638500; text-align: center;}
.memoedit {text-align: center; font-size: 16px;}
.abductor {color: #c204c2; font-style: italic;}
.mind_control {color: #df3da9; font-size: 3; font-weight: bold; font-style: italic;}
.abductor {color: #800080; font-style: italic;}
.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;}
.slime {color: #00CED1;}
.drone {color: #848482;}
.monkey {color: #975032;}
.swarmer {color: #2C75FF;}
.resonate {color: #298F85;}
.monkeyhive {color: #a56408;}
.monkeylead {color: #af6805; font-size: 2;}
.monkeyhive {color: #774704;}
.monkeylead {color: #774704; font-size: 2;}
.connectionClosed, .fatalError {background: red; color: white; padding: 5px;}
.connectionClosed.restored {background: green;}
.internal.boldnshit {color: #3d5bc3; font-weight: bold;}
.internal.boldnshit {color: #000099; font-weight: bold;}
/* HELPER CLASSES */
.text-normal {font-weight: normal; font-style: normal;}
@@ -0,0 +1,159 @@
html, body {color: #E0E0E0;}
body {
background: #171717;
font-color: #E0E0E0;
scrollbar-face-color:#1A1A1A;
scrollbar-track-color:#171717;
scrollbar-highlight-color:#171717;
}
a {color: #397ea5;}
a.visited {color: #7c00e6;}
a:visited {color: #7c00e6;}
#newMessages {
background: #242424;
color: #E0E0E0;
}
#newMessages:hover {background: #272727;}
#ping {background: #272727;}
#userBar .subCell {
background: #272727;
color: #E0E0E0;
border-top: 1px solid #171717;
}
#userBar .subCell:hover {background: #272727;}
#userBar .toggle {background: #272727;}
/* MOTD */
.motd {color: #E0E0E0; font-family: Verdana, sans-serif;}
.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #E0E0E0; text-decoration: underline;}
.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #E0E0E0;}
h1, h2, h3, h4, h5, h6 {color: #E0E0E0;font-family: Georgia, Verdana, sans-serif;}
h1.alert, h2.alert {color: #E0E0E0;}
.ooc {color: #cca300; font-weight: bold;}
.looc {color: #d8b555; font-weight: bold;}
.antagooc {color: #ce254f; font-weight: bold;}
.adminobserverooc {color: #0099cc; font-weight: bold;}
.adminooc {color: #3d5bc3; font-weight: bold;}
.admin {color: #5975da; font-weight: bold;}
.deadsay {color: #e2c1ff;}
.radio {color: #1ecc43;}
.sciradio {color: #c68cfa;}
.comradio {color: #5177ff;}
.secradio {color: #dd3535;}
.medradio {color: #57b8f0;}
.engradio {color: #f37746;}
.suppradio {color: #b88646;}
.servradio {color: #6ca729;}
.syndradio {color: #8f4a4b;}
.centcomradio {color: #2681a5;}
.aiprivradio {color: #d65d95;}
.redteamradio {color: #ff4444;}
.blueteamradio {color: #3434fd;}
.alert {color: #d82020;}
h1.alert, h2.alert {color: #99aab5;}
.attack {color: #e01c1c;}
.disarm {color: #b42525;}
.passive {color: #a00f0f;}
.userdanger {color: #c51e1e; font-weight: bold; font-size: 24px;}
.danger {color: #c51e1e;}
.warning {color: #c51e1e; font-style: italic;}
.alertwarning {color: #c51e1e; font-weight: bold}
.boldwarning {color: #c51e1e; font-style: italic; font-weight: bold}
.announce {color: #c51e1e; font-weight: bold;}
.boldannounce {color: #c51e1e; font-weight: bold;}
.greenannounce {color: #059223; font-weight: bold;}
.info {color: #6685f5;}
.notice {color: #6685f5;}
.boldnotice {color: #6685f5; font-weight: bold;}
.adminnotice {color: #6685f5;}
.adminhelp {color: #ff0000; font-weight: bold;}
.unconscious {color: #E0E0E0; font-weight: bold;}
.red {color: #FF0000}
.pink {color: #ff70c1;}
.blue {color: #215cff}
.green {color: #059223;}
.nicegreen {color: #059223;}
.userlove {color: #ff42a6; font-style: italic; font-weight: bold; text-shadow: 0 0 6px #82365e;}
.love {color: #ff4591; font-style: italic; text-shadow: 0 0 6px #994449;}
.shadowling {color: #8e8a99;}
.cult {color: #aa1c1c;}
.cultitalic {color: #aa1c1c; font-style: italic;}
.cultbold {color: #aa1c1c; font-style: italic; font-weight: bold;}
.cultboldtalic {color: #aa1c1c; font-weight: bold; font-size: 24px;}
.cultlarge {color: #aa1c1c; font-weight: bold; font-size: 24px;}
.narsie {color: #aa1c1c; font-weight: bold; font-size: 120px;}
.narsiesmall {color: #aa1c1c; font-weight: bold; font-size: 48px;}
.hierophant {color: #b441ee; font-weight: bold; font-style: italic;}
.hierophant_warning {color: #c56bf1; font-style: italic;}
.purple {color: #9956d3;}
.holoparasite {color: #88809c;}
.revennotice {color: #3645aa;}
.revenboldnotice {color: #3645aa; font-weight: bold;}
.revenbignotice {color: #3645aa; font-weight: bold; font-size: 24px;}
.revenminor {color: #823ddd}
.revenwarning {color: #8911d9; font-style: italic;}
.revendanger {color: #8911d9; font-weight: bold; font-size: 24px;}
.umbra {color: #7c00e6;}
.umbra_emphasis {color: #7c00e6; font-weight: bold; font-style: italic;}
.umbra_large {color: #7c00e6; font-size: 24px; font-weight: bold; font-style: italic;}
.deconversion_message {color: #a947ff; font-size: 24px; font-style: italic;}
.alloy {color: #545b64;}
.heavy_alloy {color: #545b64; font-weight: bold; font-style: italic;}
.nezbere_large {color: #545b64; font-size: 24px; font-weight: bold; font-style: italic;}
.nezbere {color: #545b64; font-weight: bold; font-style: italic;}
.nezbere_small {color: #545b64;}
.inathneq_large {color: #1d7dc7; font-size: 24px; font-weight: bold; font-style: italic;}
.inathneq {color: #1d7dc7; font-weight: bold; font-style: italic;}
.inathneq_small {color: #1d7dc7;}
.neovgre_large {color: #7c0622; font-size: 24px; font-weight: bold; font-style: italic;}
.neovgre {color: #7c0622; font-weight: bold; font-style: italic;}
.neovgre_small {color: #7c0622;}
.newscaster {color: #c05d5d;}
.ghostalert {color: #6600ff; font-style: italic; font-weight: bold;}
.alien {color: #855d85;}
.noticealien {color: #059223;}
.alertalien {color: #059223; font-weight: bold;}
.changeling {color: #059223; font-style: italic;}
.spider {color: #8800ff;}
.interface {color: #750e75;}
.greentext {color: #059223; font-size: 24px;}
.redtext {color: #c51e1e; font-size: 24px;}
.clown {color: #ff70c1; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;}
.velvet {color: #660015; font-weight: bold; animation: velvet 5000ms infinite;}
@keyframes velvet {
0% { color: #890020; }
40% { color: #c51e1e; }
50% { color: #FF8888; }
60% { color: #c51e1e; }
100% { color: #890020; }
}
.abductor {color: #c204c2; font-style: italic;}
.mind_control {color: #df3da9; font-size: 3; font-weight: bold; font-style: italic;}
.drone {color: #979795;}
.monkeyhive {color: #a56408;}
.monkeylead {color: #af6805; font-size: 2;}
.internal.boldnshit {color: #3d5bc3; font-weight: bold;}
@@ -1,236 +1,18 @@
/*****************************************
*
* GLOBAL STYLES
*
******************************************/
html, body {
padding: 0;
margin: 0;
height: 100%;
color: #000000;
}
body {
background: #eeeeee;
font-family: Verdana, sans-serif;
font-size: 9pt;
line-height: 1.2;
overflow-x: hidden;
overflow-y: scroll;
word-wrap: break-word;
}
body {background: #F1F1F1;}
em {
font-style: normal;
font-weight: bold;
}
#newMessages {background: #ddd;}
#ping {background: #ddd;}
img {
margin: 0;
padding: 0;
line-height: 1;
-ms-interpolation-mode: nearest-neighbor;
image-rendering: pixelated;
}
img.icon {
height: 1em;
min-height: 16px;
width: auto;
vertical-align: bottom;
}
.r:before { /* "repeated" badge class for combined messages */
content: 'x';
}
.r {
display: inline-block;
min-width: 0.5em;
font-size: 0.7em;
padding: 0.2em 0.3em;
line-height: 1;
color: white;
text-align: center;
white-space: nowrap;
vertical-align: middle;
background-color: crimson;
border-radius: 10px;
}
a {color: #0000ff;}
a.visited {color: #ff00ff;}
a:visited {color: #ff00ff;}
a.popt {text-decoration: none;}
/*****************************************
*
* OUTPUT NOT RELATED TO ACTUAL MESSAGES
*
******************************************/
#loading {
position: fixed;
width: 300px;
height: 150px;
text-align: center;
left: 50%;
top: 50%;
margin: -75px 0 0 -150px;
}
#loading i {display: block; padding-bottom: 3px;}
#messages {
font-size: 13px;
padding: 3px;
margin: 0;
word-wrap: break-word;
}
#newMessages {
position: fixed;
display: block;
bottom: 0;
right: 0;
padding: 8px;
background: #ddd;
text-decoration: none;
font-variant: small-caps;
font-size: 1.1em;
font-weight: bold;
color: #333;
}
#newMessages:hover {background: #ccc;}
#newMessages i {vertical-align: middle; padding-left: 3px;}
#ping {
position: fixed;
top: 0;
right: 115px;
width: 45px;
background: #ddd;
height: 30px;
padding: 8px 0 2px 0;
}
#ping i {display: block; text-align: center;}
#ping .ms {
display: block;
text-align: center;
font-size: 8pt;
padding-top: 2px;
}
#userBar {
position: fixed;
top: 0;
right: 0;
}
#userBar .subCell {
background: #ddd;
height: 30px;
padding: 5px 0;
display: block;
color: #333;
text-decoration: none;
line-height: 28px;
border-top: 1px solid #b4b4b4;
}
#userBar .subCell:hover {background: #ccc;}
#userBar .toggle {
width: 40px;
background: #ccc;
border-top: 0;
float: right;
text-align: center;
}
#userBar .sub {clear: both; display: none; width: 160px;}
#userBar .sub.scroll {overflow-y: scroll;}
#userBar .sub.subCell {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;}
#userBar .sub span {
display: block;
line-height: 30px;
float: left;
}
#userBar .sub i {
display: block;
padding: 0 5px;
font-size: 1.1em;
width: 22px;
text-align: center;
line-height: 30px;
float: right;
}
#userBar .sub input {
position: absolute;
padding: 7px 5px;
width: 121px;
line-height: 30px;
float: left;
}
#userBar .topCell {border-top: 0;}
#userBar .subCell {background: #ddd;}
/* POPUPS */
.popup {
position: fixed;
top: 50%;
left: 50%;
background: #ddd;
}
.popup .close {
position: absolute;
background: #aaa;
top: 0;
right: 0;
color: #333;
text-decoration: none;
z-index: 2;
padding: 0 10px;
height: 30px;
line-height: 30px;
}
.popup .close:hover {background: #999;}
.popup .head {
background: #999;
color: #ddd;
padding: 0 10px;
height: 30px;
line-height: 30px;
text-transform: uppercase;
font-size: 0.9em;
font-weight: bold;
border-bottom: 2px solid green;
}
.popup input {border: 1px solid #999; background: #fff; margin: 0; padding: 5px; outline: none; color: #333;}
.popup input[type=text]:hover, .popup input[type=text]:active, .popup input[type=text]:focus {border-color: green;}
.popup input[type=submit] {padding: 5px 10px; background: #999; color: #ddd; text-transform: uppercase; font-size: 0.9em; font-weight: bold;}
.popup input[type=submit]:hover, .popup input[type=submit]:focus, .popup input[type=submit]:active {background: #aaa; cursor: pointer;}
.changeFont {padding: 10px;}
.changeFont a {display: block; text-decoration: none; padding: 3px; color: #333;}
.changeFont a:hover {background: #ccc;}
.highlightPopup {padding: 10px; text-align: center;}
.highlightPopup input[type=text] {display: block; width: 215px; text-align: left; margin-top: 5px;}
.highlightPopup input.highlightColor {background-color: #FFFF00;}
.highlightPopup input.highlightTermSubmit {margin-top: 5px;}
.popup {background: #ddd;}
.popup .head {color: #ddd;}
.popup input[type=submit] {color: #ddd;}
/* ADMIN CONTEXT MENU */
.contextMenu {
background-color: #ddd;
position: fixed;
margin: 2px;
width: 150px;
}
.contextMenu a {
display: block;
padding: 2px 5px;
text-decoration: none;
color: #333;
}
.contextMenu {background-color: #ddd;}
.contextMenu a:hover {
background-color: #ccc;
}
/* ADMIN FILTER MESSAGES MENU */
.filterMessages {padding: 5px;}
.filterMessages div {padding: 2px 0;}
.filterMessages input {}
.filterMessages label {}
.icon-stack {height: 1em; line-height: 1em; width: 1em; vertical-align: middle; margin-top: -2px;}
@@ -266,8 +48,8 @@ em {font-style: normal; font-weight: bold;}
.adminobserverooc {color: #0099cc; font-weight: bold;}
.adminooc {color: #700038; font-weight: bold;}
.adminsay {color: #ff4500; font-weight: bold;}
.admin {color: #4473ff; font-weight: bold;}
.adminsay {color: #FF4500}
.admin {color: #386aff; font-weight: bold;}
.name { font-weight: bold;}
@@ -305,7 +87,7 @@ h1.alert, h2.alert {color: #000000;}
.userdanger {color: #ff0000; font-weight: bold; font-size: 24px;}
.danger {color: #ff0000;}
.warning {color: #ff0000; font-style: italic;}
.alertwarning {color: #FF0000; font-weight: bold}
.alertwarning {color: #FF0000; font-weight: bold}
.boldwarning {color: #ff0000; font-style: italic; font-weight: bold}
.announce {color: #228b22; font-weight: bold;}
.boldannounce {color: #ff0000; font-weight: bold;}
@@ -318,10 +100,10 @@ h1.alert, h2.alert {color: #000000;}
.adminhelp {color: #ff0000; font-weight: bold;}
.unconscious {color: #0000ff; font-weight: bold;}
.suicide {color: #ff5050; font-style: italic;}
.green {color: #03ff39;}
.red {color: #FF0000}
.green {color: #03ff39;}
.red {color: #FF0000;}
.pink {color: #FF69Bf;}
.blue {color: #0000FF}
.blue {color: #0000FF;}
.nicegreen {color: #14a833;}
.userlove {color: #FF1493; font-style: italic; font-weight: bold; text-shadow: 0 0 6px #ff6dbc;}
.love {color: #ff006a; font-style: italic; text-shadow: 0 0 6px #ff6d6d;}
@@ -330,7 +112,7 @@ h1.alert, h2.alert {color: #000000;}
.cultitalic {color: #960000; font-style: italic;}
.cultbold {color: #960000; font-style: italic; font-weight: bold;}
.cultboldtalic {color: #960000; font-weight: bold; font-size: 24px;}
.cultboldtalic {color: #960000; font-weight: bold; font-size: 24px;}
.cultlarge {color: #960000; font-weight: bold; font-size: 24px;}
.narsie {color: #960000; font-weight: bold; font-size: 120px;}
@@ -401,13 +183,38 @@ h1.alert, h2.alert {color: #000000;}
.redtext {color: #FF0000; font-size: 24px;}
.clown {color: #FF69Bf; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;}
.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;}
.velvet {color: #660015; font-weight: bold; animation: velvet 5000ms infinite;}
@keyframes velvet {
0% { color: #400020; }
40% { color: #FF0000; }
50% { color: #FF8888; }
60% { color: #FF0000; }
100% { color: #400020; }
}
.hypnophrase {color: #202020; font-weight: bold; animation: hypnocolor 1500ms infinite;}
@keyframes hypnocolor {
0% { color: #202020; }
25% { color: #4b02ac; }
50% { color: #9f41f1; }
75% { color: #541c9c; }
100% { color: #7adbf3; }
}
.phobia {color: #dd0000; font-weight: bold; animation: phobia 750ms infinite;}
@keyframes phobia {
0% { color: #f75a5a; }
50% { color: #dd0000; }
100% { color: #f75a5a; }
}
.icon {height: 1em; width: auto;}
.memo {color: #638500; text-align: center;}
.memoedit {text-align: center; font-size: 16px;}
.abductor {color: #800080; font-style: italic;}
.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;}
.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;}
.slime {color: #00CED1;}
.drone {color: #848482;}
.monkey {color: #975032;}
@@ -419,9 +226,8 @@ h1.alert, h2.alert {color: #000000;}
.connectionClosed, .fatalError {background: red; color: white; padding: 5px;}
.connectionClosed.restored {background: green;}
.internal.boldnshit {color: blue; font-weight: bold;}
.internal.boldnshit {color: #000099; font-weight: bold;}
/* HELPER CLASSES */
.text-normal {font-weight: normal; font-style: normal;}
.hidden {display: none; visibility: hidden;}
@@ -5,8 +5,9 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="font-awesome.css" />
<link id="sheetofstyles" rel="stylesheet" type="text/css" href="browserOutput_white.css" />
<link rel="stylesheet" type="text/css" href="browserOutput.css" />
<link rel="stylesheet" type="text/css" href="spritesheet_chat.css" />
<link rel="stylesheet" type="text/css" id="colorPresetLink"/>
<script type="text/javascript" src="errorHandler.js"></script>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="json2.min.js"></script>
@@ -29,7 +30,7 @@
<span class="ms" id="pingMs">--ms</span>
</div>
<div id="darkmodething">
<a href="#" class="subCell toggle" id="darkmodetoggle" title="Darkmode"><i class="icon-adjust"></i></a>
<a href="#" class="subCell toggle" id="changeColorPreset" title="Change color preset"><i class="icon-eye-open"></i></a>
</div>
<div id="audio">
<a href="#" class="subCell toggle" id="toggleAudio" title="Audio"><i class="icon-volume-up"></i></a>
@@ -35,7 +35,7 @@ var opts = {
'wasd': false, //Is the user in wasd mode?
'priorChatHeight': 0, //Thing for height-resizing detection
'restarting': false, //Is the round restarting?
'darkmode':false, //Are we using darkmode? If not WHY ARE YOU LIVING IN 2009???
'colorPreset': 0, // index in the color presets list.
//Options menu
'selectedSubLoop': null, //Contains the interval loop for closing the selected sub menu
@@ -73,6 +73,14 @@ var opts = {
};
// Array of names for chat display color presets.
// If not set to normal, a CSS file `browserOutput_${name}.css` will be added to the head.
var colorPresets = [
'normal',
'light',
'dark'
]
function clamp(val, min, max) {
return Math.max(min, Math.min(val, max))
}
@@ -96,6 +104,12 @@ if (typeof String.prototype.trim !== 'function') {
};
}
function updateColorPreset() {
var el = $("#colorPresetLink")[0];
el.href = "browserOutput_"+colorPresets[opts.colorPreset]+".css";
runByond('?_src_=chat&proc=colorPresetPost&preset='+colorPresets[opts.colorPreset]);
}
// Linkify the contents of a node, within its parent.
function linkify(parent, insertBefore, text) {
var start = 0;
@@ -395,19 +409,6 @@ function toHex(n) {
return "0123456789ABCDEF".charAt((n-n%16)/16) + "0123456789ABCDEF".charAt(n%16);
}
function swap() { //Swap to darkmode
if (opts.darkmode){
document.getElementById("sheetofstyles").href = "browserOutput_white.css";
opts.darkmode = false;
runByond('?_src_=chat&proc=swaptolightmode');
} else {
document.getElementById("sheetofstyles").href = "browserOutput.css";
opts.darkmode = true;
runByond('?_src_=chat&proc=swaptodarkmode');
}
setCookie('darkmode', (opts.darkmode ? 'true' : 'false'), 365);
}
function handleClientData(ckey, ip, compid) {
//byond sends player info to here
var currentData = {'ckey': ckey, 'ip': ip, 'compid': compid};
@@ -615,7 +616,7 @@ $(function() {
'shighlightColor': getCookie('highlightcolor'),
'smusicVolume': getCookie('musicVolume'),
'smessagecombining': getCookie('messagecombining'),
'sdarkmode': getCookie('darkmode'),
'scolorPreset': getCookie('colorpreset'),
};
if (savedConfig.sfontSize) {
@@ -626,9 +627,6 @@ $(function() {
$("body").css('line-height', savedConfig.slineHeight);
internalOutput('<span class="internal boldnshit">Loaded line height setting of: '+savedConfig.slineHeight+'</span>', 'internal');
}
if(savedConfig.sdarkmode == 'true'){
swap();
}
if (savedConfig.spingDisabled) {
if (savedConfig.spingDisabled == 'true') {
opts.pingDisabled = true;
@@ -654,6 +652,13 @@ $(function() {
opts.highlightColor = savedConfig.shighlightColor;
internalOutput('<span class="internal boldnshit">Loaded highlight color of: '+savedConfig.shighlightColor+'</span>', 'internal');
}
if (savedConfig.scolorPreset) {
opts.colorPreset = Number(savedConfig.scolorPreset);
updateColorPreset();
internalOutput('<span class="internal boldnshit">Loaded color preset of: '+colorPresets[opts.colorPreset]+'</span>', 'internal');
}
if (savedConfig.smusicVolume) {
var newVolume = clamp(savedConfig.smusicVolume, 0, 100);
$('#adminMusic').prop('volume', newVolume / 100);
@@ -839,9 +844,6 @@ $(function() {
$('#toggleOptions').click(function(e) {
handleToggleClick($subOptions, $(this));
});
$('#darkmodetoggle').click(function(e) {
swap();
});
$('#toggleAudio').click(function(e) {
handleToggleClick($subAudio, $(this));
});
@@ -913,7 +915,7 @@ $(function() {
$.ajax({
type: 'GET',
url: 'browserOutput_white.css',
url: 'browserOutput.css',
success: function(styleData) {
var blob = new Blob(['<head><title>Chat Log</title><style>', styleData, '</style></head><body>', $messages.html(), '</body>']);
@@ -991,7 +993,14 @@ $(function() {
$messages.empty();
opts.messageCount = 0;
});
$('#changeColorPreset').click(function() {
opts.colorPreset = (opts.colorPreset+1) % colorPresets.length;
updateColorPreset();
setCookie('colorpreset', opts.colorPreset, 365);
internalOutput('<span class="internal boldnshit">Changed color preset to: '+colorPresets[opts.colorPreset]);
});
$('#musicVolumeSpan').hover(function() {
$('#musicVolumeText').addClass('hidden');
$('#musicVolume').removeClass('hidden');
@@ -261,7 +261,7 @@
desc = "A wing ripped from a watcher. Suitable as a trophy for a kinetic crusher."
icon_state = "watcher_wing"
denied_type = /obj/item/crusher_trophy/watcher_wing
bonus_value = 50
bonus_value = 30
/obj/item/crusher_trophy/watcher_wing/effect_desc()
return "mark detonation to prevent certain creatures from using certain attacks for <b>[bonus_value*0.1]</b> second\s"
@@ -442,4 +442,4 @@
new /obj/effect/temp_visual/hierophant/wall/crusher(otherT, user)
/obj/effect/temp_visual/hierophant/wall/crusher
duration = 75
duration = 55
@@ -43,13 +43,668 @@
/datum/sprite_accessory/tails_animated/human/none
name = "None"
icon_state = "none"
/*
/datum/sprite_accessory/tails/lizard/axolotl
name = "Axolotl"
icon_state = "axolotl"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/lizard/axolotl
name = "Axolotl"
icon_state = "axolotl"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/body_markings/guilmon
name = "Guilmon"
icon_state = "guilmon"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/markings_notmammals.dmi'
/datum/sprite_accessory/tails/lizard/guilmon
name = "Guilmon"
icon_state = "guilmon"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/lizard/guilmon
name = "Guilmon"
icon_state = "guilmon"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/******************************************
************** Human Tails ****************
*******************************************/
/datum/sprite_accessory/tails/human/none
name = "None"
icon_state = "none"
/datum/sprite_accessory/tails_animated/human/none
name = "None"
icon_state = "none"
/datum/sprite_accessory/tails/human/ailurus
name = "Red Panda"
icon_state = "wah"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails_animated/human/ailurus
name = "Red Panda"
icon_state = "wah"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails/human/axolotl
name = "Axolotl"
icon_state = "axolotl"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails_animated/human/axolotl
name = "Axolotl"
icon_state = "axolotl"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails/human/bee
name = "Bee"
icon_state = "bee"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails_animated/human/bee
name = "Bee"
icon_state = "bee"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails/human/cat
name = "Cat"
icon_state = "cat"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = HAIR
/datum/sprite_accessory/tails_animated/human/cat
name = "Cat"
icon_state = "cat"
color_src = HAIR*/
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = HAIR
/datum/sprite_accessory/tails/human/catbig
name = "Cat, Big"
icon_state = "catbig"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails_animated/human/catbig
name = "Cat, Big"
icon_state = "catbig"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails/human/cow
name = "Cow"
icon_state = "cow"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails_animated/human/cow
name = "Cow"
icon_state = "cow"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails/human/corvid
name = "Corvid"
icon_state = "crow"
/datum/sprite_accessory/tails_animated/human/corvid
name = "Corvid"
icon_state = "crow"
/datum/sprite_accessory/tails/human/eevee
name = "Eevee"
icon_state = "eevee"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails_animated/human/eevee
name = "Eevee"
icon_state = "eevee"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails/human/fennec
name = "Fennec"
icon_state = "fennec"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails_animated/human/fennec
name = "Fennec"
icon_state = "fennec"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails/human/fish
name = "Fish"
icon_state = "fish"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails_animated/human/fish
name = "Fish"
icon_state = "fish"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails/human/fox
name = "Fox"
icon_state = "fox"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails_animated/human/fox
name = "Fox"
icon_state = "fox"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails/human/horse
name = "Horse"
icon_state = "horse"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = HAIR
/datum/sprite_accessory/tails_animated/human/horse
name = "Horse"
icon_state = "horse"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = HAIR
/datum/sprite_accessory/tails/human/husky
name = "Husky"
icon_state = "husky"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails_animated/human/husky
name = "Husky"
icon_state = "husky"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails/human/insect
name = "Insect"
icon_state = "insect"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails_animated/human/insect
name = "insect"
icon_state = "insect"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/tails/human/kitsune
name = "Kitsune"
icon_state = "kitsune"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/human/kitsune
name = "Kitsune"
icon_state = "kitsune"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails/human/murid
name = "Murid"
icon_state = "murid"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/human/murid
name = "Murid"
icon_state = "murid"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails/human/otie
name = "Otusian"
icon_state = "otie"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/human/otie
name = "Otusian"
icon_state = "otie"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails/orca
name = "Orca"
icon_state = "orca"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/orca
name = "Orca"
icon_state = "orca"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails/human/pede
name = "Scolipede"
icon_state = "pede"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/human/pede
name = "Scolipede"
icon_state = "pede"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails/human/rabbit
name = "Rabbit"
icon_state = "rabbit"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/human/rabbit
name = "Rabbit"
icon_state = "rabbit"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails/human/sergal
name = "Sergal"
icon_state = "sergal"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/human/sergal
name = "Sergal"
icon_state = "sergal"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails/human/skunk
name = "skunk"
icon_state = "skunk"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/human/skunk
name = "skunk"
icon_state = "skunk"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails/human/shark
name = "Shark"
icon_state = "shark"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/human/shark
name = "Shark"
icon_state = "shark"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails/human/datashark
name = "datashark"
icon_state = "datashark"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/human/datashark
name = "datashark"
icon_state = "datashark"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails/human/straighttail
name = "Straight Tail"
icon_state = "straighttail"
/datum/sprite_accessory/tails_animated/human/straighttail
name = "Straight Tail"
icon_state = "straighttail"
/datum/sprite_accessory/tails/human/squirrel
name = "Squirrel"
icon_state = "squirrel"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/human/squirrel
name = "Squirrel"
icon_state = "squirrel"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails/human/tentacle
name = "Tentacle"
icon_state = "tentacle"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/human/tentacle
name = "Tentacle"
icon_state = "tentacle"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails/human/tiger
name = "Tiger"
icon_state = "tiger"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/human/tiger
name = "Tiger"
icon_state = "tiger"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails/human/wolf
name = "Wolf"
icon_state = "wolf"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/human/wolf
name = "Wolf"
icon_state = "wolf"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/******************************************
************** Furry Tails ****************
*******************************************/
/datum/sprite_accessory/mam_tails
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/mam_tails/none
name = "None"
icon_state = "none"
/datum/sprite_accessory/mam_tails_animated
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/mam_tails_animated/none
name = "None"
icon_state = "none"
color_src = MATRIXED
/datum/sprite_accessory/mam_tails/ailurus
name = "Red Panda"
icon_state = "wah"
extra = TRUE
/datum/sprite_accessory/mam_tails_animated/ailurus
name = "Red Panda"
icon_state = "wah"
extra = TRUE
/datum/sprite_accessory/mam_tails/axolotl
name = "Axolotl"
icon_state = "axolotl"
/datum/sprite_accessory/mam_tails_animated/axolotl
name = "Axolotl"
icon_state = "axolotl"
/datum/sprite_accessory/mam_tails/bee
name = "Bee"
icon_state = "bee"
/datum/sprite_accessory/mam_tails_animated/bee
name = "Bee"
icon_state = "bee"
/datum/sprite_accessory/mam_tails/cat
name = "Cat"
icon_state = "cat"
color_src = HAIR
/datum/sprite_accessory/mam_tails_animated/cat
name = "Cat"
icon_state = "cat"
color_src = HAIR
/datum/sprite_accessory/mam_tails/catbig
name = "Cat, Big"
icon_state = "catbig"
/datum/sprite_accessory/mam_tails_animated/catbig
name = "Cat, Big"
icon_state = "catbig"
/datum/sprite_accessory/mam_tails/corvid
name = "Corvid"
icon_state = "crow"
/datum/sprite_accessory/mam_tails_animated/corvid
name = "Corvid"
icon_state = "crow"
/datum/sprite_accessory/mam_tail/cow
name = "Cow"
icon_state = "cow"
/datum/sprite_accessory/mam_tails_animated/cow
name = "Cow"
icon_state = "cow"
/datum/sprite_accessory/mam_tails/eevee
name = "Eevee"
icon_state = "eevee"
/datum/sprite_accessory/mam_tails_animated/eevee
name = "Eevee"
icon_state = "eevee"
/datum/sprite_accessory/mam_tails/fennec
name = "Fennec"
icon_state = "fennec"
/datum/sprite_accessory/mam_tails_animated/fennec
name = "Fennec"
icon_state = "fennec"
/datum/sprite_accessory/mam_tails/human/fish
name = "Fish"
icon_state = "fish"
/datum/sprite_accessory/mam_tails_animated/human/fish
name = "Fish"
icon_state = "fish"
/datum/sprite_accessory/mam_tails/fox
name = "Fox"
icon_state = "fox"
/datum/sprite_accessory/mam_tails_animated/fox
name = "Fox"
icon_state = "fox"
/datum/sprite_accessory/mam_tails/hawk
name = "Hawk"
icon_state = "hawk"
/datum/sprite_accessory/mam_tails_animated/hawk
name = "Hawk"
icon_state = "hawk"
/datum/sprite_accessory/mam_tails/horse
name = "Horse"
icon_state = "horse"
color_src = HAIR
/datum/sprite_accessory/mam_tails_animated/horse
name = "Horse"
icon_state = "horse"
color_src = HAIR
/datum/sprite_accessory/mam_tails/husky
name = "Husky"
icon_state = "husky"
/datum/sprite_accessory/mam_tails_animated/husky
name = "Husky"
icon_state = "husky"
datum/sprite_accessory/mam_tails/insect
name = "Insect"
icon_state = "insect"
/datum/sprite_accessory/mam_tails_animated/insect
name = "Insect"
icon_state = "insect"
/datum/sprite_accessory/mam_tails/kangaroo
name = "kangaroo"
icon_state = "kangaroo"
/datum/sprite_accessory/mam_tails_animated/kangaroo
name = "kangaroo"
icon_state = "kangaroo"
/datum/sprite_accessory/mam_tails/kitsune
name = "Kitsune"
icon_state = "kitsune"
/datum/sprite_accessory/mam_tails_animated/kitsune
name = "Kitsune"
icon_state = "kitsune"
/datum/sprite_accessory/mam_tails/lab
name = "Lab"
icon_state = "lab"
/datum/sprite_accessory/mam_tails_animated/lab
name = "Lab"
icon_state = "lab"
/datum/sprite_accessory/mam_tails/murid
name = "Murid"
icon_state = "murid"
/datum/sprite_accessory/mam_tails_animated/murid
name = "Murid"
icon_state = "murid"
/datum/sprite_accessory/mam_tails/otie
name = "Otusian"
icon_state = "otie"
/datum/sprite_accessory/mam_tails_animated/otie
name = "Otusian"
icon_state = "otie"
/datum/sprite_accessory/mam_tails/orca
name = "Orca"
icon_state = "orca"
/datum/sprite_accessory/mam_tails_animated/orca
name = "Orca"
icon_state = "orca"
/datum/sprite_accessory/mam_tails/pede
name = "Scolipede"
icon_state = "pede"
/datum/sprite_accessory/mam_tails_animated/pede
name = "Scolipede"
icon_state = "pede"
/datum/sprite_accessory/mam_tails/rabbit
name = "Rabbit"
icon_state = "rabbit"
/datum/sprite_accessory/mam_tails_animated/rabbit
name = "Rabbit"
icon_state = "rabbit"
/datum/sprite_accessory/mam_tails/sergal
name = "Sergal"
icon_state = "sergal"
/datum/sprite_accessory/mam_tails_animated/sergal
name = "Sergal"
icon_state = "sergal"
/datum/sprite_accessory/mam_tails/skunk
name = "Skunk"
icon_state = "skunk"
/datum/sprite_accessory/mam_tails_animated/skunk
name = "Skunk"
icon_state = "skunk"
/datum/sprite_accessory/mam_tails/shark
name = "Shark"
icon_state = "shark"
/datum/sprite_accessory/mam_tails_animated/shark
name = "Shark"
icon_state = "shark"
/datum/sprite_accessory/mam_tails/shepherd
name = "Shepherd"
icon_state = "shepherd"
/datum/sprite_accessory/mam_tails_animated/shepherd
name = "Shepherd"
icon_state = "shepherd"
/datum/sprite_accessory/mam_tails/straighttail
name = "Straight Tail"
icon_state = "straighttail"
/datum/sprite_accessory/mam_tails_animated/straighttail
name = "Straight Tail"
icon_state = "straighttail"
/datum/sprite_accessory/mam_tails/squirrel
name = "Squirrel"
icon_state = "squirrel"
/datum/sprite_accessory/mam_tails_animated/squirrel
name = "Squirrel"
icon_state = "squirrel"
/datum/sprite_accessory/mam_tails/tentacle
name = "Tentacle"
icon_state = "tentacle"
/datum/sprite_accessory/mam_tails_animated/tentacle
name = "Tentacle"
icon_state = "tentacle"
/datum/sprite_accessory/mam_tails/tiger
name = "Tiger"
icon_state = "tiger"
/datum/sprite_accessory/mam_tails_animated/tiger
name = "Tiger"
icon_state = "tiger"
/datum/sprite_accessory/mam_tails/wolf
name = "Wolf"
icon_state = "wolf"
/datum/sprite_accessory/mam_tails_animated/wolf
name = "Wolf"
icon_state = "wolf"
+8 -3
View File
@@ -286,9 +286,13 @@
if(restrained())
changeNext_move(CLICK_CD_BREAKOUT)
last_special = world.time + CLICK_CD_BREAKOUT
var/buckle_cd = 600
if(handcuffed)
var/obj/item/restraints/O = src.get_item_by_slot(SLOT_HANDCUFFED)
buckle_cd = O.breakouttime
visible_message("<span class='warning'>[src] attempts to unbuckle [p_them()]self!</span>", \
"<span class='notice'>You attempt to unbuckle yourself... (This will take around one minute and you need to stay still.)</span>")
if(do_after(src, 600, 0, target = src))
"<span class='notice'>You attempt to unbuckle yourself... (This will take around [round(buckle_cd/600,1)] minute\s, and you need to stay still.)</span>")
if(do_after(src, buckle_cd, 0, target = src))
if(!buckled)
return
buckled.user_unbuckle_mob(src,src)
@@ -824,7 +828,8 @@
drop_all_held_items()
stop_pulling()
throw_alert("handcuffed", /obj/screen/alert/restrained/handcuffed, new_master = src.handcuffed)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "handcuffed", /datum/mood_event/handcuffed)
if(handcuffed.demoralize_criminals)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "handcuffed", /datum/mood_event/handcuffed)
else
clear_alert("handcuffed")
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "handcuffed")
+11 -5
View File
@@ -854,9 +854,15 @@
.["Copy outfit"] = "?_src_=vars;[HrefToken()];copyoutfit=[REF(src)]"
/mob/living/carbon/human/MouseDrop_T(mob/living/target, mob/living/user)
//If they dragged themselves and we're currently aggressively grabbing them try to piggyback
if(user == target && can_piggyback(target) && pulling == target && (HAS_TRAIT(src, TRAIT_PACIFISM) || grab_state >= GRAB_AGGRESSIVE) && stat == CONSCIOUS)
buckle_mob(target,TRUE,TRUE)
if(pulling == target && grab_state >= GRAB_AGGRESSIVE && stat == CONSCIOUS)
//If they dragged themselves and we're currently aggressively grabbing them try to piggyback
if(user == target && can_piggyback(target))
piggyback(target)
return
//If you dragged them to you and you're aggressively grabbing try to fireman carry them
else if(user != target)
fireman_carry(target)
return
. = ..()
/mob/living/carbon/human/proc/piggyback_instant(mob/living/M)
@@ -1068,6 +1074,6 @@
/mob/living/carbon/human/species/zombie/krokodil_addict
race = /datum/species/krokodil_addict
//define holder_type on nibbas we wanna commit scoop to
//define holder_type on nerds we wanna commit scoop to
/mob/living/carbon/human
var/holder_type = /obj/item/clothing/head/mob_holder/micro
var/holder_type = /obj/item/clothing/head/mob_holder/micro
@@ -16,5 +16,5 @@
blacklisted = 1
use_skintones = 0
species_traits = list(NOBLOOD,EYECOLOR,NOGENITALS)
inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER)
inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOLIMBDISABLE,TRAIT_NOHUNGER)
sexes = 0
@@ -3,7 +3,7 @@
name = "Spooky Scary Skeleton"
id = "skeleton"
say_mod = "rattles"
blacklisted = 1
blacklisted = 0
sexes = 0
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
species_traits = list(NOBLOOD,NOGENITALS,NOAROUSAL)
@@ -12,13 +12,18 @@
mutanttongue = /obj/item/organ/tongue/bone
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
disliked_food = NONE
liked_food = GROSS | MEAT | RAW
liked_food = GROSS | MEAT | RAW | DAIRY
/datum/species/skeleton/check_roundstart_eligible()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
return TRUE
return ..()
/datum/species/skeleton/pirate
name = "Space Queen's Skeleton"
/datum/species/skeleton/space
name = "Spooky Spacey Skeleton"
id = "spaceskeleton"
blacklisted = 1
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
/datum/species/skeleton/pirate/check_roundstart_eligible()
return FALSE
@@ -12,7 +12,7 @@
damage_overlay_type = "synth"
limbs_id = "synth"
var/list/initial_species_traits = list(NOTRANSSTING) //for getting these values back for assume_disguise()
var/list/initial_inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER,TRAIT_NOBREATH)
var/list/initial_inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER,TRAIT_NOLIMBDISABLE,TRAIT_NOBREATH)
var/disguise_fail_health = 75 //When their health gets to this level their synthflesh partially falls off
var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged
@@ -16,7 +16,12 @@
disliked_food = NONE
liked_food = GROSS | MEAT | RAW
/datum/species/zombie/check_roundstart_eligible()
/datum/species/zombie/notspaceproof
id = "notspaceproofzombie"
blacklisted = 0
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH,TRAIT_NODEATH,TRAIT_FAKEDEATH)
/datum/species/zombie/notspaceproof/check_roundstart_eligible()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
return TRUE
return ..()
@@ -47,7 +52,7 @@
/datum/species/zombie/infectious/spec_life(mob/living/carbon/C)
. = ..()
C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW
//Zombies never actually die, they just fall down until they regenerate enough to rise back up.
//They must be restrained, beheaded or gibbed to stop being a threat.
if(regen_cooldown < world.time)
@@ -58,7 +63,7 @@
C.adjustToxLoss(-heal_amt)
if(!C.InCritical() && prob(4))
playsound(C, pick(spooks), 50, TRUE, 10)
//Congrats you somehow died so hard you stopped being a zombie
/datum/species/zombie/infectious/spec_death(mob/living/carbon/C)
. = ..()
@@ -123,15 +123,16 @@ There are several things that need to be remembered:
if(U.adjusted == ALT_STYLE)
t_color = "[t_color]_d"
if(U.mutantrace_variation)
if(U.suit_style == DIGITIGRADE_SUIT_STYLE)
U.alternate_worn_icon = 'modular_citadel/icons/mob/uniform_digi.dmi'
if(U.adjusted == ALT_STYLE)
t_color = "[t_color]_d_l"
else if(U.adjusted == NORMAL_STYLE)
t_color = "[t_color]_l"
else
U.alternate_worn_icon = null
if(!U.force_alternate_icon)
if(U.mutantrace_variation)
if(U.suit_style == DIGITIGRADE_SUIT_STYLE)
U.alternate_worn_icon = 'modular_citadel/icons/mob/uniform_digi.dmi'
if(U.adjusted == ALT_STYLE)
t_color = "[t_color]_d_l"
else if(U.adjusted == NORMAL_STYLE)
t_color = "[t_color]_l"
else
U.alternate_worn_icon = null
var/mutable_appearance/uniform_overlay
+7
View File
@@ -35,6 +35,7 @@
*/
if(stat == DEAD)
stop_sound_channel(CHANNEL_HEARTBEAT)
handle_death()
rot()
//Updates the number of stored chemicals for powers
@@ -43,6 +44,12 @@
if(stat != DEAD)
return 1
//Procs called while dead
/mob/living/carbon/proc/handle_death()
for(var/datum/reagent/R in reagents.reagent_list)
if(R.chemical_flags & REAGENT_DEAD_PROCESS)
R.on_mob_dead(src)
///////////////
// BREATHING //
///////////////
@@ -44,7 +44,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
var/reset = 0 //if the summoner has reset the guardian already
var/cooldown = 0
var/mob/living/carbon/summoner
var/range = 10 //how far from the user the spirit can be
var/range = 13 //how far from the user the spirit can be
var/toggle_button_type = /obj/screen/guardian/ToggleMode/Inactive //what sort of toggle button the hud uses
var/datum/guardianname/namedatum = new/datum/guardianname()
var/playstyle_string = "<span class='holoparasite bold'>You are a standard Guardian. You shouldn't exist!</span>"
@@ -1,7 +1,5 @@
//Assassin
/mob/living/simple_animal/hostile/guardian/assassin
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "slashes"
attack_sound = 'sound/weapons/bladeslice.ogg'
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
@@ -12,7 +10,7 @@
toggle_button_type = /obj/screen/guardian/ToggleMode/Assassin
var/toggle = FALSE
var/stealthcooldown = 160
var/stealthcooldown = 100
var/obj/screen/alert/canstealthalert
var/obj/screen/alert/instealthalert
@@ -1,13 +1,10 @@
//Charger
/mob/living/simple_animal/hostile/guardian/charger
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1 //technically
ranged_message = "charges"
ranged_cooldown_time = 40
speed = -1
damage_coeff = list(BRUTE = 0.6, BURN = 0.6, TOX = 0.6, CLONE = 0.6, STAMINA = 0, OXY = 0.6)
playstyle_string = "<span class='holoparasite'>As a <b>charger</b> type you do medium damage, have medium damage resistance, move very fast, and can charge at a location, damaging any target hit and forcing them to drop any items they are holding.</span>"
ranged_cooldown_time = 20
damage_coeff = list(BRUTE = 0, BURN = 0.5, TOX = 0.5, CLONE = 0.5, STAMINA = 0, OXY = 0.5)
playstyle_string = "<span class='holoparasite'>As a <b>charger</b> type you do medium damage, take half damage, immunity to brute damage, move very fast, and can charge at a location, damaging any target hit and forcing them to drop any items they are holding.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Hunter, an alien master of rapid assault.</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Charge modules loaded. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! Caught one! It's a charger carp, that likes running at people. But it doesn't have any legs...</span>"
@@ -3,7 +3,7 @@
melee_damage_lower = 10
melee_damage_upper = 10
damage_coeff = list(BRUTE = 0.75, BURN = 0.75, TOX = 0.75, CLONE = 0.75, STAMINA = 0, OXY = 0.75)
playstyle_string = "<span class='holoparasite'>As a <b>dextrous</b> type you can hold items, store an item within yourself, and have medium damage resistance, but do low damage on attacks. Recalling and leashing will force you to drop unstored items!</span>"
playstyle_string = "<span class='holoparasite'>As a <b>dextrous</b> type you can hold items, store an item within yourself, and take half damage, but do low damage on attacks. Recalling and leashing will force you to drop unstored items!</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Drone, a dextrous master of construction and repair.</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Dextrous combat modules loaded. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! You caught one! It can hold stuff in its fins, sort of.</span>"
@@ -1,10 +1,7 @@
//Bomb
/mob/living/simple_animal/hostile/guardian/bomb
melee_damage_lower = 15
melee_damage_upper = 15
damage_coeff = list(BRUTE = 0.6, BURN = 0.6, TOX = 0.6, CLONE = 0.6, STAMINA = 0, OXY = 0.6)
range = 13
playstyle_string = "<span class='holoparasite'>As an <b>explosive</b> type, you have moderate close combat abilities, may explosively teleport targets on attack, and are capable of converting nearby items and objects into disguised bombs via alt click.</span>"
playstyle_string = "<span class='holoparasite'>As an <b>explosive</b> type, you have moderate close combat abilities, take half damage, may explosively teleport targets on attack, and are capable of converting nearby items and objects into disguised bombs via alt click.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Scientist, master of explosive death.</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Explosive modules active. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! Caught one! It's an explosive carp! Boom goes the fishy.</span>"
@@ -1,13 +1,13 @@
//Fire
/mob/living/simple_animal/hostile/guardian/fire
a_intent = INTENT_HELP
melee_damage_lower = 7
melee_damage_upper = 7
melee_damage_lower = 10
melee_damage_upper = 10
attack_sound = 'sound/items/welder.ogg'
attacktext = "ignites"
damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
range = 7
playstyle_string = "<span class='holoparasite'>As a <b>chaos</b> type, you have only light damage resistance, but will ignite any enemy you bump into. In addition, your melee attacks will cause human targets to see everyone as you.</span>"
melee_damage_type = BURN
damage_coeff = list(BRUTE = 0.7, BURN = 0, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
playstyle_string = "<span class='holoparasite'>As a <b>chaos</b> type, you take 30% damage reduction to all but burn, which you are immune to. You will ignite any enemy you bump into. in addition, your melee attacks will cause human targets to see everyone as you.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Wizard, bringer of endless chaos!</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Crowd control modules activated. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! You caught one! OH GOD, EVERYTHING'S ON FIRE. Except you and the fish.</span>"
@@ -38,6 +38,6 @@
/mob/living/simple_animal/hostile/guardian/fire/proc/collision_ignite(AM as mob|obj)
if(isliving(AM))
var/mob/living/M = AM
if(!hasmatchingsummoner(M) && M != summoner && M.fire_stacks < 7)
M.fire_stacks = 7
if(!hasmatchingsummoner(M) && M != summoner && M.fire_stacks < 10)
M.fire_stacks = 10
M.IgniteMob()
@@ -4,14 +4,13 @@
layer = LYING_MOB_LAYER
/mob/living/simple_animal/hostile/guardian/beam
melee_damage_lower = 7
melee_damage_upper = 7
melee_damage_lower = 10
melee_damage_upper = 10
attacktext = "shocks"
melee_damage_type = BURN
attack_sound = 'sound/machines/defib_zap.ogg'
damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
range = 7
playstyle_string = "<span class='holoparasite'>As a <b>lightning</b> type, you will apply lightning chains to targets on attack and have a lightning chain to your summoner. Lightning chains will shock anyone near them.</span>"
playstyle_string = "<span class='holoparasite'>As a <b>lightning</b> type, you have 30% damage reduction, apply lightning chains to targets on attack and have a lightning chain to your summoner. Lightning chains will shock anyone near them.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Tesla, a shocking, lethal source of power.</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Lightning modules active. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! Caught one! It's a lightning carp! Everyone else goes zap zap.</span>"
@@ -31,7 +30,7 @@
var/datum/beam/C = pick(enemychains)
qdel(C)
enemychains -= C
enemychains += Beam(target, "lightning[rand(1,12)]", time=70, maxdistance=7, beam_type=/obj/effect/ebeam/chain)
enemychains += Beam(target, "lightning[rand(1,12)]", time=70, maxdistance=13, beam_type=/obj/effect/ebeam/chain)
/mob/living/simple_animal/hostile/guardian/beam/Destroy()
removechains()
@@ -1,7 +1,5 @@
//Protector
/mob/living/simple_animal/hostile/guardian/protector
melee_damage_lower = 15
melee_damage_upper = 15
range = 15 //worse for it due to how it leashes
damage_coeff = list(BRUTE = 0.4, BURN = 0.4, TOX = 0.4, CLONE = 0.4, STAMINA = 0, OXY = 0.4)
playstyle_string = "<span class='holoparasite'>As a <b>protector</b> type you cause your summoner to leash to you instead of you leashing to them and have two modes; Combat Mode, where you do and take medium damage, and Protection Mode, where you do and take almost no damage, but move slightly slower.</span>"
@@ -33,9 +31,9 @@
cooldown = world.time + 10
if(toggle)
cut_overlays()
melee_damage_lower = initial(melee_damage_lower)
melee_damage_upper = initial(melee_damage_upper)
speed = initial(speed)
melee_damage_lower = 15
melee_damage_upper = 15
speed = 0
damage_coeff = list(BRUTE = 0.4, BURN = 0.4, TOX = 0.4, CLONE = 0.4, STAMINA = 0, OXY = 0.4)
to_chat(src, "<span class='danger'><B>You switch to combat mode.</span></B>")
toggle = FALSE
@@ -44,8 +42,8 @@
if(namedatum)
shield_overlay.color = namedatum.colour
add_overlay(shield_overlay)
melee_damage_lower = 2
melee_damage_upper = 2
melee_damage_lower = 5
melee_damage_upper = 5
speed = 1
damage_coeff = list(BRUTE = 0.05, BURN = 0.05, TOX = 0.05, CLONE = 0.05, STAMINA = 0, OXY = 0.05) //damage? what's damage?
to_chat(src, "<span class='danger'><B>You switch to protection mode.</span></B>")
@@ -16,8 +16,7 @@
ranged_cooldown_time = 1 //fast!
projectilesound = 'sound/effects/hit_on_shattered_glass.ogg'
ranged = 1
range = 13
playstyle_string = "<span class='holoparasite'>As a <b>ranged</b> type, you have only light damage resistance, but are capable of spraying shards of crystal at incredibly high speed. You can also deploy surveillance snares to monitor enemy movement. Finally, you can switch to scout mode, in which you can't attack, but can move without limit.</span>"
playstyle_string = "<span class='holoparasite'>As a <b>ranged</b> type, you have 10% damage reduction, but are capable of spraying shards of crystal at incredibly high speed. You can also deploy surveillance snares to monitor enemy movement. Finally, you can switch to scout mode, in which you can't attack, but can move without limit.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Sentinel, an alien master of ranged combat.</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Ranged combat modules active. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! Caught one, it's a ranged carp. This fishy can watch people pee in the ocean.</span>"
@@ -36,7 +35,7 @@
obj_damage = initial(obj_damage)
environment_smash = initial(environment_smash)
alpha = 255
range = initial(range)
range = 13
to_chat(src, "<span class='danger'><B>You switch to combat mode.</span></B>")
toggle = FALSE
else
@@ -3,9 +3,9 @@
melee_damage_lower = 20
melee_damage_upper = 20
obj_damage = 80
next_move_modifier = 0.8 //attacks 20% faster
next_move_modifier = 0.5 //attacks 50% faster
environment_smash = ENVIRONMENT_SMASH_WALLS
playstyle_string = "<span class='holoparasite'>As a <b>standard</b> type you have no special abilities, but have a high damage resistance and a powerful attack capable of smashing through walls.</span>"
playstyle_string = "<span class='holoparasite'>As a <b>standard</b> type you have no special abilities, but take half damage and have powerful attack capable of smashing through walls.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Assistant, faceless and generic, but never to be underestimated.</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Standard combat modules loaded. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! You caught one! It's really boring and standard. Better punch some walls to ease the tension.</span>"
@@ -2,11 +2,8 @@
/mob/living/simple_animal/hostile/guardian/healer
a_intent = INTENT_HARM
friendly = "heals"
speed = 0
damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
melee_damage_lower = 15
melee_damage_upper = 15
playstyle_string = "<span class='holoparasite'>As a <b>support</b> type, you may toggle your basic attacks to a healing mode. In addition, Alt-Clicking on an adjacent object or mob will warp them to your bluespace beacon after a short delay.</span>"
playstyle_string = "<span class='holoparasite'>As a <b>support</b> type, you have 30% damage reduction and may toggle your basic attacks to a healing mode. In addition, Alt-Clicking on an adjacent object or mob will warp them to your bluespace beacon after a short delay.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the CMO, a potent force of life... and death.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! You caught a support carp. It's a kleptocarp!</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Support modules active. Holoparasite swarm online.</span>"
@@ -0,0 +1,173 @@
#define GOOSE_SATIATED 50
/mob/living/simple_animal/hostile/retaliate/goose
name = "goose"
desc = "It's loose"
icon_state = "goose" // sprites by cogwerks from goonstation, used with permission
icon_living = "goose"
icon_dead = "goose_dead"
mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
speak_chance = 0
turns_per_move = 5
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat = 2)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
emote_taunt = list("hisses")
taunt_chance = 30
speed = 0
maxHealth = 25
health = 25
harm_intent_damage = 5
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = "pecks"
attack_sound = "goose"
speak_emote = list("honks")
faction = list("neutral")
attack_same = TRUE
gold_core_spawnable = HOSTILE_SPAWN
var/random_retaliate = TRUE
var/icon_vomit_start = "vomit_start"
var/icon_vomit = "vomit"
var/icon_vomit_end = "vomit_end"
/mob/living/simple_animal/hostile/retaliate/goose/handle_automated_movement()
. = ..()
if(prob(5) && random_retaliate == TRUE)
Retaliate()
/mob/living/simple_animal/hostile/retaliate/goose/vomit
name = "Birdboat"
real_name = "Birdboat"
desc = "It's a sick-looking goose, probably ate too much maintenance trash. Best not to move it around too much."
gender = MALE
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
gold_core_spawnable = NO_SPAWN
random_retaliate = FALSE
var/vomiting = FALSE
var/vomitCoefficient = 1
var/vomitTimeBonus = 0
var/datum/action/cooldown/vomit/goosevomit
/mob/living/simple_animal/hostile/retaliate/goose/vomit/cargo
name = "Sickly Goose"
real_name = "Sickly Goose"
/mob/living/simple_animal/hostile/retaliate/goose/vomit/Initialize()
. = ..()
goosevomit = new
goosevomit.Grant(src)
/mob/living/simple_animal/hostile/retaliate/goose/vomit/Destroy()
QDEL_NULL(goosevomit)
return ..()
/mob/living/simple_animal/hostile/retaliate/goose/vomit/examine(user)
. = ..()
. += "<span class='notice'>Somehow, it still looks hungry.</span>"
/mob/living/simple_animal/hostile/retaliate/goose/vomit/attacked_by(obj/item/O, mob/user)
. = ..()
feed(O)
/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/feed(obj/item/O)
var/obj/item/reagent_containers/food/tasty = O
if(!istype(O))
return
if (contents.len > GOOSE_SATIATED)
visible_message("<span class='notice'>[src] looks too full to eat \the [tasty]!</span>")
return
if (tasty.foodtype & GROSS)
visible_message("<span class='notice'>[src] hungrily gobbles up \the [tasty]!</span>")
tasty.forceMove(src)
playsound(src,'sound/items/eatfood.ogg', 70, 1)
vomitCoefficient += 3
vomitTimeBonus += 2
else
visible_message("<span class='notice'>[src] refuses to eat \the [tasty].</span>")
/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/vomit()
var/turf/T = get_turf(src)
var/obj/item/reagent_containers/food/consumed = locate() in contents //Barf out a single food item from our guts
if (prob(50) && consumed)
barf_food(consumed)
else
playsound(T, 'sound/effects/splat.ogg', 50, 1)
T.add_vomit_floor(src)
/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/barf_food(var/atom/A, var/hard = FALSE)
if(!istype(A, /obj/item/reagent_containers/food))
return
var/turf/currentTurf = get_turf(src)
var/obj/item/reagent_containers/food/consumed = A
consumed.forceMove(currentTurf)
var/destination = get_edge_target_turf(currentTurf, pick(GLOB.alldirs)) //Pick a random direction to toss them in
var/throwRange = hard ? rand(2,8) : 1
consumed.safe_throw_at(destination, throwRange, 2) //Thow the food at a random tile 1 spot away
sleep(2)
if (QDELETED(src) || QDELETED(consumed))
return
currentTurf = get_turf(consumed)
currentTurf.add_vomit_floor(src)
playsound(currentTurf, 'sound/effects/splat.ogg', 50, 1)
/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/vomit_prestart(duration)
flick("vomit_start",src)
addtimer(CALLBACK(src, .proc/vomit_start, duration), 13) //13 is the length of the vomit_start animation in gooseloose.dmi
/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/vomit_start(duration)
vomiting = TRUE
icon_state = "vomit"
vomit()
addtimer(CALLBACK(src, .proc/vomit_preend), duration)
/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/vomit_preend()
for (var/obj/item/consumed in contents) //Get rid of any food left in the poor thing
barf_food(consumed, TRUE)
sleep(1)
if (QDELETED(src))
return
vomit_end()
/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/vomit_end()
flick("vomit_end",src)
vomiting = FALSE
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/retaliate/goose/vomit/Moved(oldLoc, dir)
. = ..()
if(vomiting)
vomit() // its supposed to keep vomiting if you move
return
var/turf/currentTurf = get_turf(src)
while (currentTurf == get_turf(src))
var/obj/item/reagent_containers/food/tasty = locate() in currentTurf
if (tasty)
feed(tasty)
stoplag(20)
if(prob(vomitCoefficient * 0.2))
vomit_prestart(vomitTimeBonus + 25)
vomitCoefficient = 1
vomitTimeBonus = 0
/datum/action/cooldown/vomit
name = "Vomit"
check_flags = AB_CHECK_CONSCIOUS
button_icon_state = "vomit"
icon_icon = 'icons/mob/animal.dmi'
cooldown_time = 250
/datum/action/cooldown/vomit/Trigger()
if(!..())
return FALSE
if(!istype(owner, /mob/living/simple_animal/hostile/retaliate/goose/vomit))
return FALSE
var/mob/living/simple_animal/hostile/retaliate/goose/vomit/vomit = owner
if(!vomit.vomiting)
vomit.vomit_prestart(vomit.vomitTimeBonus + 25)
vomit.vomitCoefficient = 1
vomit.vomitTimeBonus = 0
return TRUE
@@ -125,6 +125,8 @@ Difficulty: Very Hard
if(H.mind)
if(H.mind.martial_art && prob(H.mind.martial_art.deflection_chance))
. = TRUE
if (is_species(H, /datum/species/golem/sand))
. = TRUE
/mob/living/simple_animal/hostile/megafauna/colossus/proc/alternating_dir_shots()
dir_shots(GLOB.diagonals)
+3
View File
@@ -67,6 +67,9 @@
/obj/structure/filingcabinet/ui_interact(mob/user)
. = ..()
if(isobserver(user))
return
if(contents.len <= 0)
to_chat(user, "<span class='notice'>[src] is empty.</span>")
return
+2 -4
View File
@@ -267,7 +267,7 @@
to_chat(user, "<span class='brass'>There is an integration cog installed!</span>")
to_chat(user, "<span class='notice'>Alt-Click the APC to [ locked ? "unlock" : "lock"] the interface.</span>")
if(issilicon(user))
to_chat(user, "<span class='notice'>Ctrl-Click the APC to switch the breaker [ operating ? "off" : "on"].</span>")
@@ -793,7 +793,7 @@
if(damage_flag == "melee" && damage_amount < damage_deflection)
return 0
. = ..()
/obj/machinery/power/apc/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(!(stat & BROKEN))
@@ -846,8 +846,6 @@
if(!ui)
ui = new(user, src, ui_key, "apc", name, 535, 515, master_ui, state)
ui.open()
if(ui)
ui.set_autoupdate(state = (failure_timer ? 1 : 0))
/obj/machinery/power/apc/ui_data(mob/user)
var/list/data = list(
@@ -329,6 +329,12 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
if(power)
soundloop.volume = min(40, (round(power/100)/50)+1) // 5 +1 volume per 20 power. 2500 power is max
if(isclosedturf(T))
var/turf/did_it_melt = T.Melt()
if(!isclosedturf(did_it_melt)) //In case some joker finds way to place these on indestructible walls
visible_message("<span class='warning'>[src] melts through [T]!</span>")
return
//Ok, get the air from the turf
var/datum/gas_mixture/env = T.return_air()
@@ -1,3 +1,9 @@
// lato
/obj/item/ammo_casing/latob
name = "Lato-class bullet casing"
desc = "A Lato-class bullet casing. Signiature with lotus engravings."
projectile_type = /obj/item/projectile/bullet/latob
// 10mm (Stechkin)
/obj/item/ammo_casing/c10mm
@@ -6,6 +6,11 @@
caliber = "357"
projectile_type = /obj/item/projectile/bullet/a357
/obj/item/ammo_casing/a357/ap
name = ".357 armor-piercing bullet casing"
desc = "A .357 armor-piercing bullet casing."
projectile_type = /obj/item/projectile/bullet/a357/ap
// 7.62x38mmR (Nagant Revolver)
/obj/item/ammo_casing/n762
@@ -20,9 +25,26 @@
name = ".38 rubber bullet casing"
desc = "A .38 rubber bullet casing."
caliber = "38"
projectile_type = /obj/item/projectile/bullet/c38
projectile_type = /obj/item/projectile/bullet/c38/rubber
/obj/item/ammo_casing/c38/lethal
name = ".38 bullet casing"
desc = "A .38 bullet casing"
projectile_type = /obj/item/projectile/bullet/c38lethal
projectile_type = /obj/item/projectile/bullet/c38
/obj/item/ammo_casing/c38/trac
name = ".38 TRAC bullet casing"
desc = "A .38 \"TRAC\" bullet casing."
projectile_type = /obj/item/projectile/bullet/c38/trac
/obj/item/ammo_casing/c38/hotshot
name = ".38 Hot Shot bullet casing"
desc = "A .38 Hot Shot bullet casing."
caliber = "38"
projectile_type = /obj/item/projectile/bullet/c38/hotshot
/obj/item/ammo_casing/c38/iceblox
name = ".38 Iceblox bullet casing"
desc = "A .38 Iceblox bullet casing."
caliber = "38"
projectile_type = /obj/item/projectile/bullet/c38/iceblox
@@ -26,3 +26,10 @@
caliber = "40mm"
icon_state = "40mmHE"
projectile_type = /obj/item/projectile/bullet/a40mm
// bratonmag (Braton)
/obj/item/ammo_casing/bratonmag
name = "Braton-class bullet casing"
desc = "A signiature shell from a Braton, lined with engravings."
caliber = "bratonb"
projectile_type = /obj/item/projectile/bullet/bratonb
@@ -3,18 +3,39 @@
desc = "Designed to quickly reload revolvers."
icon_state = "357"
ammo_type = /obj/item/ammo_casing/a357
caliber = "357"
max_ammo = 7
multiple_sprites = 1
/obj/item/ammo_box/a357/ap
name = "speed loader (.357 AP)"
ammo_type = /obj/item/ammo_casing/a357/ap
/obj/item/ammo_box/c38
name = "speed loader (.38 rubber)"
desc = "Designed to quickly reload revolvers."
icon_state = "38"
caliber = "38"
ammo_type = /obj/item/ammo_casing/c38
max_ammo = 6
multiple_sprites = 1
materials = list(MAT_METAL = 20000)
/obj/item/ammo_box/c38/trac
name = "speed loader (.38 TRAC)"
desc = "Designed to quickly reload revolvers. TRAC bullets embed a tracking implant within the target's body."
ammo_type = /obj/item/ammo_casing/c38/trac
/obj/item/ammo_box/c38/hotshot
name = "speed loader (.38 Hot Shot)"
desc = "Designed to quickly reload revolvers. Hot Shot bullets contain an incendiary payload."
ammo_type = /obj/item/ammo_casing/c38/hotshot
/obj/item/ammo_box/c38/iceblox
name = "speed loader (.38 Iceblox)"
desc = "Designed to quickly reload revolvers. Iceblox bullets contain a cryogenic payload."
ammo_type = /obj/item/ammo_casing/c38/iceblox
/obj/item/ammo_box/c38/lethal
name = "speed loader (.38)"
ammo_type = /obj/item/ammo_casing/c38/lethal
@@ -1,3 +1,11 @@
//Lato Ammo
/obj/item/ammo_box/magazine/latomag
name = "pistol magazine (lato)"
desc = "A magazine fitted for lato-class weapons. A lotus decal is inscribed on the backside."
icon_state = "latomag"
ammo_type = /obj/item/ammo_casing/latob
max_ammo = 15
/obj/item/ammo_box/magazine/m10mm
name = "pistol magazine (10mm)"
desc = "A gun magazine."
@@ -19,3 +19,11 @@
caliber = "a556"
max_ammo = 30
multiple_sprites = 2
//braton
/obj/item/ammo_box/magazine/bratonmag
name = "toploader magazine (braton)"
icon_state = "bratonmag"
ammo_type = /obj/item/ammo_casing/bratonmag
caliber = "bratonb"
max_ammo = 60
@@ -208,6 +208,21 @@
update_icon()
return
//WARFRAME WEAPONS INSERT
/obj/item/gun/ballistic/automatic/braton
name = "\improper Braton"
desc = "An unusual weapon in design; sporting a high firing rate and capacity, but low damage. There is a lotus decal on the underside of the barrel."
icon_state = "braton"
item_state = "braton"
w_class = WEIGHT_CLASS_HUGE
slot_flags = 0
mag_type = /obj/item/ammo_box/magazine/bratonmag
fire_sound = 'sound/weapons/gunshot_braton.ogg'
can_suppress = FALSE
burst_size = 5
fire_delay = 1
//ENDS HERE
/obj/item/gun/ballistic/automatic/tommygun
name = "\improper Thompson SMG"
desc = "Based on the classic 'Chicago Typewriter'."
@@ -21,6 +21,20 @@
var/obj/item/suppressor/S = new(src)
install_suppressor(S)
//WARFRAME WEAPONS INSERT
/obj/item/gun/ballistic/automatic/pistol/lato
name = "\improper Lato"
desc = "A strange sidearm, sporting low damage but a high firing rate and capacity. There is a lotus decal on the barrel."
icon_state = "lato"
item_state = "lato"
w_class = WEIGHT_CLASS_NORMAL
mag_type = /obj/item/ammo_box/magazine/latomag
can_suppress = FALSE
fire_sound = 'sound/weapons/gunshot_lato.ogg'
fire_delay = 0
//ENDS HERE
/obj/item/gun/ballistic/automatic/pistol/m1911
name = "\improper M1911"
desc = "A classic .45 handgun with a small magazine capacity."

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