@@ -0,0 +1 @@
|
||||
#define FORCE_MAP "_maps/layeniastation.json"
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"map_name": "Layenia Station",
|
||||
"map_path": "map_files/LayeniaStation",
|
||||
"map_file": "LayeniaStation.dmm",
|
||||
"shuttles": {
|
||||
"cargo": "cargo_box",
|
||||
"ferry": "ferry_fancy",
|
||||
"whiteship": "whiteship_box",
|
||||
"emergency": "emergency_box"
|
||||
},
|
||||
"traits":[
|
||||
{
|
||||
"Gravity":true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,30 +1,39 @@
|
||||
"a" = (/obj/machinery/door/airlock/titanium{name = "Supply Shuttle Airlock"; req_access_txt = "31"},/obj/structure/fans/tiny,/turf/open/floor/plating,/area/shuttle/supply)
|
||||
"a" = (/obj/machinery/conveyor{dir = 8; id = "QMLoad"},/obj/machinery/door/poddoor{dir = 8; id = "QMLoaddoor2"; name = "supply dock loading door"},/obj/structure/fans/tiny,/turf/open/floor/plating,/area/shuttle/supply)
|
||||
"b" = (/turf/closed/wall/mineral/titanium,/area/shuttle/supply)
|
||||
"c" = (/obj/machinery/door/airlock/titanium{name = "Supply Shuttle Airlock"; req_access_txt = "31"},/obj/docking_port/mobile/supply{dwidth = 5; width = 12},/obj/structure/fans/tiny,/turf/open/floor/plating,/area/shuttle/supply)
|
||||
"e" = (/turf/open/floor/mineral/titanium/blue,/area/shuttle/supply)
|
||||
"f" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/obj/machinery/door/poddoor{id = "QMLoaddoor2"; name = "supply dock loading door"},/turf/open/floor/plating,/area/shuttle/supply)
|
||||
"h" = (/obj/machinery/button/door{dir = 2; id = "QMLoaddoor2"; name = "Loading Doors"; pixel_x = 24; pixel_y = 8},/obj/machinery/button/door{id = "QMLoaddoor"; name = "Loading Doors"; pixel_x = 24; pixel_y = -8},/obj/machinery/light{dir = 4},/turf/open/floor/mineral/titanium/blue,/area/shuttle/supply)
|
||||
"j" = (/obj/machinery/conveyor{dir = 8; id = "QMLoad"},/obj/machinery/door/poddoor{id = "QMLoaddoor"; name = "supply dock loading door"},/turf/open/floor/plating,/area/shuttle/supply)
|
||||
"c" = (/obj/structure/fans/tiny,/obj/machinery/door/airlock/titanium{name = "Supply Shuttle Airlock"; req_access_txt = "31"},/obj/docking_port/mobile/supply{dwidth = 5; width = 12},/turf/open/floor/plating,/area/shuttle/supply)
|
||||
"e" = (/obj/effect/turf_decal/stripes/line{dir = 9},/turf/open/floor/plasteel,/area/shuttle/supply)
|
||||
"f" = (/obj/machinery/door/airlock/titanium{name = "Supply Shuttle Airlock"; req_access_txt = "31"},/obj/structure/fans/tiny,/turf/open/floor/plating,/area/shuttle/supply)
|
||||
"h" = (/obj/machinery/light{dir = 4},/obj/effect/turf_decal/stripes/line{dir = 4},/obj/machinery/button/door{id = "QMLoaddoor2"; name = "Loading Doors"; pixel_x = 24; pixel_y = 8},/obj/machinery/button/door{id = "QMLoaddoor"; name = "Loading Doors"; pixel_x = 24; pixel_y = -8},/turf/open/floor/plasteel,/area/shuttle/supply)
|
||||
"i" = (/obj/machinery/door/poddoor{dir = 8; id = "QMLoaddoor"; name = "supply dock loading door"},/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/obj/structure/fans/tiny,/turf/open/floor/plating,/area/shuttle/supply)
|
||||
"l" = (/turf/closed/wall/mineral/titanium/interior,/area/shuttle/supply)
|
||||
"q" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/shuttle/engine/heater,/turf/open/floor/plating/airless,/area/shuttle/supply)
|
||||
"q" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/shuttle/engine/heater,/obj/effect/turf_decal/stripes/line,/turf/open/floor/plating/airless,/area/shuttle/supply)
|
||||
"s" = (/turf/template_noop,/area/template_noop)
|
||||
"t" = (/obj/structure/shuttle/engine/propulsion/burst/left,/turf/open/floor/plating/airless,/area/shuttle/supply)
|
||||
"u" = (/obj/structure/shuttle/engine/propulsion,/turf/open/floor/plating/airless,/area/shuttle/supply)
|
||||
"v" = (/obj/structure/shuttle/engine/propulsion/burst/right,/turf/open/floor/plating/airless,/area/shuttle/supply)
|
||||
"w" = (/obj/machinery/light{dir = 1},/turf/open/floor/mineral/titanium/blue,/area/shuttle/supply)
|
||||
"x" = (/obj/machinery/light{dir = 8},/turf/open/floor/mineral/titanium/blue,/area/shuttle/supply)
|
||||
"t" = (/obj/structure/shuttle/engine/propulsion/burst/left,/obj/effect/turf_decal/stripes/line,/turf/open/floor/plating/airless,/area/shuttle/supply)
|
||||
"u" = (/obj/structure/shuttle/engine/propulsion,/obj/effect/turf_decal/stripes/line,/turf/open/floor/plating/airless,/area/shuttle/supply)
|
||||
"v" = (/obj/structure/shuttle/engine/propulsion/burst/right,/obj/effect/turf_decal/stripes/line,/turf/open/floor/plating/airless,/area/shuttle/supply)
|
||||
"w" = (/obj/effect/turf_decal/stripes/line{dir = 1},/obj/machinery/light{dir = 1},/turf/open/floor/plasteel,/area/shuttle/supply)
|
||||
"x" = (/obj/machinery/light{dir = 8},/obj/effect/turf_decal/stripes/line{dir = 8},/turf/open/floor/plasteel,/area/shuttle/supply)
|
||||
"y" = (/obj/effect/turf_decal/stripes/line{dir = 10},/turf/open/floor/plasteel,/area/shuttle/supply)
|
||||
"A" = (/obj/effect/turf_decal/stripes/line{dir = 1},/turf/open/floor/plasteel,/area/shuttle/supply)
|
||||
"C" = (/obj/effect/turf_decal/delivery,/turf/open/floor/plasteel,/area/shuttle/supply)
|
||||
"D" = (/obj/effect/turf_decal/stripes/line{dir = 4},/turf/open/floor/plasteel,/area/shuttle/supply)
|
||||
"F" = (/obj/effect/turf_decal/bot,/turf/open/floor/plasteel,/area/shuttle/supply)
|
||||
"K" = (/obj/effect/turf_decal/stripes/line{dir = 6},/turf/open/floor/plasteel,/area/shuttle/supply)
|
||||
"M" = (/obj/effect/turf_decal/stripes/line{dir = 8},/turf/open/floor/plasteel,/area/shuttle/supply)
|
||||
"S" = (/obj/effect/turf_decal/stripes/line{dir = 5},/turf/open/floor/plasteel,/area/shuttle/supply)
|
||||
"X" = (/obj/effect/turf_decal/stripes/line,/turf/open/floor/plasteel,/area/shuttle/supply)
|
||||
|
||||
(1,1,1) = {"
|
||||
bbbbbbb
|
||||
beeweeb
|
||||
beeeeeb
|
||||
beeeeef
|
||||
beeeeea
|
||||
bxeeehb
|
||||
beeeeec
|
||||
beeeeej
|
||||
beeeeeb
|
||||
bleeelb
|
||||
beAwASb
|
||||
bMFFFDb
|
||||
bMFFFDa
|
||||
bMFFFDf
|
||||
bxFFFhb
|
||||
bMFFFDc
|
||||
bMFFFDi
|
||||
byXXXKb
|
||||
blCCClb
|
||||
bbqqqbb
|
||||
stuuuvs
|
||||
"}
|
||||
|
||||
@@ -294,6 +294,7 @@
|
||||
#define SPEECH_LANGUAGE 5
|
||||
#define SPEECH_IGNORE_SPAM 6
|
||||
#define SPEECH_FORCED 7 */
|
||||
#define COMSIG_MOB_ANTAG_ON_GAIN "mob_antag_on_gain" //from base of /datum/antagonist/on_gain(): (antag_datum)
|
||||
|
||||
///from base of /mob/Login(): ()
|
||||
#define COMSIG_MOB_LOGIN "mob_login"
|
||||
@@ -378,6 +379,7 @@
|
||||
|
||||
///from base of mob/living/carbon/soundbang_act(): (list(intensity))
|
||||
#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang"
|
||||
#define COMSIG_CARBON_IDENTITY_TRANSFERRED_TO "carbon_id_transferred_to" //from datum/dna/transfer_identity(): (datum/dna, transfer_SE)
|
||||
///from /item/organ/proc/Insert() (/obj/item/organ/)
|
||||
#define COMSIG_CARBON_GAIN_ORGAN "carbon_gain_organ"
|
||||
///from /item/organ/proc/Remove() (/obj/item/organ/)
|
||||
@@ -566,6 +568,9 @@
|
||||
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby"
|
||||
///Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted)
|
||||
#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit"
|
||||
#define COMSIG_HUMAN_PREFS_COPIED_TO "human_prefs_copied_to" //from datum/preferences/copy_to(): (datum/preferences, icon_updates, roundstart_checks)
|
||||
#define COMSIG_HUMAN_HARDSET_DNA "human_hardset_dna" //from mob/living/carbon/human/hardset_dna(): (ui, se, newreal_name, newblood_type, datum/species, newfeatures)
|
||||
#define COMSIG_HUMAN_ON_RANDOMIZE "humman_on_randomize" //from base of proc/randomize_human()
|
||||
///Whenever EquipRanked is called, called after job is set
|
||||
#define COMSIG_JOB_RECEIVED "job_received"
|
||||
|
||||
|
||||
@@ -187,6 +187,13 @@
|
||||
#define TRAIT_NEVER_CLONE "donotclone"
|
||||
#define TRAIT_COLDBLOODED "coldblooded" // Your body is literal room temperature. Does not make you immune to the temp.
|
||||
#define TRAIT_FLIMSY "flimsy" //you have 20% less maxhealth
|
||||
|
||||
|
||||
//Hyper
|
||||
#define TRAIT_VIRILE "virile" //you have 20% more chance of impreg
|
||||
#define TRAIT_MACROPHILE "macrophile" //likes the big
|
||||
#define TRAIT_MICROPHILE "microphile" //likes the small
|
||||
|
||||
#define TRAIT_TOUGH "tough" //you have 10% more maxhealth
|
||||
#define TRAIT_AUTO_CATCH_ITEM "auto_catch_item"
|
||||
#define TRAIT_CLOWN_MENTALITY "clown_mentality" // The future is now, clownman.
|
||||
|
||||
@@ -104,17 +104,6 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
|
||||
if(!src.holder) return
|
||||
message_admins("[key_name_admin(usr)] manually reloaded mentors")
|
||||
|
||||
//Flavor Text
|
||||
/mob/living/carbon/human/verb/set_flavor()
|
||||
set name = "Set Flavor Text"
|
||||
set desc = "Sets an extended description of your character's features."
|
||||
set category = "IC"
|
||||
|
||||
var/new_flavor = input(src, "Enter your new flavor text:", "Flavor text", null) as message|null
|
||||
if(!isnull(new_flavor))
|
||||
flavor_text = sanitize(new_flavor)
|
||||
to_chat(src, "Your flavor text has been updated.")
|
||||
|
||||
//LOOC toggles
|
||||
/client/verb/listen_looc()
|
||||
set name = "Show/Hide LOOC"
|
||||
|
||||
@@ -231,6 +231,7 @@
|
||||
"ipc_screen" = snowflake_ipc_antenna_list ? pick(snowflake_ipc_antenna_list) : "None",
|
||||
"ipc_antenna" = "None",
|
||||
"flavor_text" = "",
|
||||
"silicon_flavor_text" = "",
|
||||
"ooc_text" = ""))
|
||||
|
||||
/proc/random_hair_style(gender)
|
||||
|
||||
@@ -163,6 +163,7 @@
|
||||
set waitfor = FALSE
|
||||
|
||||
to_chat(world, "<BR><BR><BR><span class='big bold'>The round has ended.</span>")
|
||||
var/botmsg = "**The Round has ended!**```Round ID: [GLOB.round_id]\nRound Time: [DisplayTimeText(world.time - SSticker.round_start_time)]\nTotal Population: [GLOB.joined_player_list.len]```"
|
||||
if(LAZYLEN(GLOB.round_end_notifiees))
|
||||
send2irc("Notice", "[GLOB.round_end_notifiees.Join(", ")] the round has ended.")
|
||||
|
||||
@@ -179,6 +180,20 @@
|
||||
var/popcount = gather_roundend_feedback()
|
||||
display_report(popcount)
|
||||
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
//Hyper bot list players
|
||||
botmsg += "\n**The Crew!** ```"
|
||||
for(var/p in GLOB.player_list)
|
||||
var/mob/living/P = p //the living crew members
|
||||
if(P)
|
||||
botmsg += "[P.real_name]"
|
||||
if(P.job)
|
||||
botmsg += " ([P.job])"
|
||||
botmsg += "\n"
|
||||
botmsg += "```"
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
// Add AntagHUD to everyone, see who was really evil the whole time!
|
||||
@@ -208,10 +223,6 @@
|
||||
if(length(CONFIG_GET(keyed_list/cross_server)))
|
||||
send_news_report()
|
||||
|
||||
//tell the nice people on discord what went on before the salt cannon happens.
|
||||
world.TgsTargetedChatBroadcast("The current round has ended. Please standby for your shift interlude Kinaris News Network's report!", FALSE)
|
||||
world.TgsTargetedChatBroadcast(send_news_report(),FALSE)
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
//These need update to actually reflect the real antagonists
|
||||
@@ -226,7 +237,6 @@
|
||||
total_antagonists[A.name] += "[key_name(A.owner)]"
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
//Now print them all into the log!
|
||||
log_game("Antagonists at round end were...")
|
||||
for(var/antag_name in total_antagonists)
|
||||
@@ -243,6 +253,7 @@
|
||||
SSblackbox.Seal()
|
||||
|
||||
sleep(50)
|
||||
world.hypermessage(botmsg)
|
||||
ready_for_reboot = TRUE
|
||||
standard_reboot()
|
||||
|
||||
|
||||
@@ -25,6 +25,12 @@
|
||||
if(SSparallax.random_layer)
|
||||
C.parallax_layers_cached += new SSparallax.random_layer
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/layer_3(null, C.view)
|
||||
if(SSmapping.config?.map_name == "Layenia Station")
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/layenia/horizon(null, C.view)
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/layenia/clouds1(null, C.view)
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/layenia/clouds2(null, C.view)
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/layenia/clouds3(null, C.view)
|
||||
|
||||
|
||||
C.parallax_layers = C.parallax_layers_cached.Copy()
|
||||
|
||||
@@ -66,24 +72,24 @@
|
||||
switch(C.prefs.parallax)
|
||||
if (PARALLAX_INSANE)
|
||||
C.parallax_throttle = FALSE
|
||||
C.parallax_layers_max = 5
|
||||
C.parallax_layers_max = 10
|
||||
return TRUE
|
||||
|
||||
if (PARALLAX_MED)
|
||||
C.parallax_throttle = PARALLAX_DELAY_MED
|
||||
C.parallax_layers_max = 3
|
||||
C.parallax_layers_max = 8
|
||||
return TRUE
|
||||
|
||||
if (PARALLAX_LOW)
|
||||
C.parallax_throttle = PARALLAX_DELAY_LOW
|
||||
C.parallax_layers_max = 1
|
||||
C.parallax_layers_max = 7
|
||||
return TRUE
|
||||
|
||||
if (PARALLAX_DISABLE)
|
||||
return FALSE
|
||||
|
||||
C.parallax_throttle = PARALLAX_DELAY_DEFAULT
|
||||
C.parallax_layers_max = 4
|
||||
C.parallax_layers_max = 10
|
||||
return TRUE
|
||||
|
||||
/datum/hud/proc/update_parallax_pref(mob/viewmob)
|
||||
@@ -320,7 +326,7 @@
|
||||
blend_mode = BLEND_OVERLAY
|
||||
absolute = TRUE //Status of seperation
|
||||
speed = 3
|
||||
layer = 30
|
||||
layer = 4
|
||||
|
||||
/obj/screen/parallax_layer/planet/update_status(mob/M)
|
||||
var/client/C = M.client
|
||||
@@ -331,3 +337,44 @@
|
||||
|
||||
/obj/screen/parallax_layer/planet/update_o()
|
||||
return //Shit wont move
|
||||
|
||||
//Layenia parallaxes
|
||||
|
||||
/obj/screen/parallax_layer/layenia
|
||||
icon_state = null
|
||||
blend_mode = BLEND_OVERLAY
|
||||
absolute = TRUE
|
||||
speed = 0.6
|
||||
layer = 5
|
||||
|
||||
/obj/screen/parallax_layer/layenia/horizon
|
||||
icon_state = "layeniahorizon"
|
||||
speed = 0.3
|
||||
absolute = FALSE
|
||||
|
||||
/obj/screen/parallax_layer/layenia/clouds1
|
||||
icon_state = "layenia1"
|
||||
speed = 0.6
|
||||
layer = 6
|
||||
|
||||
/obj/screen/parallax_layer/layenia/clouds2
|
||||
icon_state = "layenia2"
|
||||
speed = 1
|
||||
layer = 7
|
||||
|
||||
/obj/screen/parallax_layer/layenia/clouds3
|
||||
icon_state = "layenia3"
|
||||
speed = 1.4
|
||||
layer = 8
|
||||
|
||||
/obj/screen/parallax_layer/layenia/update_status(mob/M)
|
||||
var/client/C = M.client
|
||||
var/turf/posobj = get_turf(C.eye)
|
||||
if(!posobj)
|
||||
return
|
||||
invisibility = is_station_level(posobj.z) ? 0 : INVISIBILITY_ABSTRACT
|
||||
|
||||
/*
|
||||
/obj/screen/parallax_layer/tparallax1/update_status(mob/M)
|
||||
if(SSmapping.config?.map_name != "Layenia Station")
|
||||
*/
|
||||
|
||||
@@ -14,6 +14,7 @@ SUBSYSTEM_DEF(job)
|
||||
|
||||
var/overflow_role = "Assistant"
|
||||
|
||||
|
||||
/datum/controller/subsystem/job/Initialize(timeofday)
|
||||
SSmapping.HACK_LoadMapConfig()
|
||||
if(!occupations.len)
|
||||
@@ -390,7 +391,6 @@ SUBSYSTEM_DEF(job)
|
||||
var/datum/job/job = GetJob(rank)
|
||||
|
||||
H.job = rank
|
||||
equip_loadout(N, H)
|
||||
|
||||
//If we joined at roundstart we should be positioned at our workstation
|
||||
if(!joined_late)
|
||||
@@ -416,22 +416,36 @@ SUBSYSTEM_DEF(job)
|
||||
if(H.mind)
|
||||
H.mind.assigned_role = rank
|
||||
|
||||
//Job loadout, equipping, and flavortext when spawning
|
||||
if(job)
|
||||
var/new_mob = job.equip(H, null, null, joined_late)
|
||||
if(ismob(new_mob))
|
||||
var/list/handle_storage = equip_loadout(N, H) //Loadout gear
|
||||
var/new_mob = job.equip(H, null, null, joined_late) //Job gear
|
||||
|
||||
if(ismob(new_mob)) //The above doesnt return a value, but we check this anyways or else everything breaks!
|
||||
H = new_mob
|
||||
if(!joined_late)
|
||||
N.new_character = H
|
||||
else
|
||||
M = H
|
||||
|
||||
SSpersistence.antag_rep_change[M.client.ckey] += job.GetAntagRep()
|
||||
if(LAZYLEN(handle_storage)) //equip_loadout returned a list. This list is backpack contents we should store, as by now we should have a backpack and a single reference mob
|
||||
if(ishuman(H))
|
||||
var/mob/living/carbon/human/_H = H
|
||||
if(_H.back)
|
||||
for(var/atom/movable/A in handle_storage)
|
||||
if(!SEND_SIGNAL(_H.back, COMSIG_TRY_STORAGE_INSERT, A, null, TRUE, TRUE))
|
||||
A.forceMove(get_turf(H)) //Try and store into the backpack. If the backpack is full, drop it to the ground
|
||||
else //No backpack
|
||||
for(var/atom/movable/A in handle_storage)
|
||||
A.forceMove(get_turf(H))
|
||||
|
||||
//Flavortext
|
||||
var/display_rank = rank
|
||||
if(M.client && M.client.prefs && M.client.prefs.alt_titles_preferences[rank])
|
||||
display_rank = M.client.prefs.alt_titles_preferences[rank]
|
||||
|
||||
to_chat(M, "<b>You are the [display_rank].</b>")
|
||||
|
||||
var/display_rank = rank
|
||||
if(M.client && M.client.prefs && M.client.prefs.alt_titles_preferences[rank])
|
||||
display_rank = M.client.prefs.alt_titles_preferences[rank]
|
||||
to_chat(M, "<b>You are the [display_rank].</b>")
|
||||
if(job)
|
||||
to_chat(M, "<b>As the [display_rank] you answer directly to [job.supervisors]. Special circumstances may change this.</b>")
|
||||
to_chat(M, "<b>To speak on your departments radio, use the :h button. To see others, look closely at your headset.</b>")
|
||||
if(job.req_admin_notify)
|
||||
@@ -441,15 +455,15 @@ SUBSYSTEM_DEF(job)
|
||||
if(CONFIG_GET(number/minimal_access_threshold))
|
||||
to_chat(M, "<span class='notice'><B>As this station was initially staffed with a [CONFIG_GET(flag/jobs_have_minimal_access) ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.</B></span>")
|
||||
|
||||
job.after_spawn(H, M, joined_late)
|
||||
|
||||
//Account ID. ID is handled by human initialization
|
||||
if(ishuman(H))
|
||||
var/mob/living/carbon/human/wageslave = H
|
||||
to_chat(M, "<b><span class = 'big'>Your account ID is [wageslave.account_id]</span></b>")
|
||||
to_chat(M, "<b><span class = 'notice'>You do not have a pin, can set your pin at a ATM.</b>")
|
||||
H.add_memory("Your account ID is [wageslave.account_id].")
|
||||
|
||||
if(job && H)
|
||||
job.after_spawn(H, M, joined_late) // note: this happens before the mob has a key! M will always have a client, H might not.
|
||||
equip_loadout(N, H, TRUE)//CIT CHANGE - makes players spawn with in-backpack loadout items properly. A little hacky but it works
|
||||
to_chat(M, "<b><span class='big'>Your account ID is [wageslave.account_id]</span></b>")
|
||||
to_chat(M, "<b><span class='notice'>You do not have a pin, can set your pin at an ATM.</b>")
|
||||
if(H.mind)
|
||||
H.mind.memory += "Your account ID is [wageslave.account_id].<BR>"
|
||||
|
||||
return H
|
||||
|
||||
@@ -643,4 +657,4 @@ SUBSYSTEM_DEF(job)
|
||||
. |= player.mind
|
||||
|
||||
/datum/controller/subsystem/job/proc/JobDebug(message)
|
||||
log_job_debug(message)
|
||||
log_job_debug(message)
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
/datum/component/chasm/proc/is_safe()
|
||||
//if anything matching this typecache is found in the chasm, we don't drop things
|
||||
var/static/list/chasm_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile))
|
||||
var/static/list/chasm_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/lattice, /obj/structure/stone_tile))
|
||||
|
||||
var/atom/parent = src.parent
|
||||
var/list/found_safeties = typecache_filter_list(parent.contents, chasm_safeties_typecache)
|
||||
|
||||
@@ -46,6 +46,12 @@
|
||||
|
||||
//begin playsound shenanigans//
|
||||
|
||||
//for big characters, add alittle boom
|
||||
if(LM.size_multiplier > 1.5)
|
||||
var/stompsound = pick( 'sound/effects/footstep/giant1.ogg','sound/effects/footstep/giant2.ogg')
|
||||
var/giantvolume = LM.size_multiplier * 9
|
||||
playsound(T, stompsound, giantvolume)
|
||||
|
||||
//for barefooted non-clawed mobs like monkeys
|
||||
if(isbarefoot(LM))
|
||||
playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]),
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
var/insanity_effect = 0 //is the owner being punished for low mood? If so, how much?
|
||||
var/holdmyinsanityeffect = 0 //before we edit our sanity lets take a look
|
||||
var/obj/screen/mood/screen_obj
|
||||
var/lastupdate = 0
|
||||
|
||||
/datum/component/mood/Initialize()
|
||||
if(!isliving(parent))
|
||||
@@ -91,6 +92,7 @@
|
||||
mood += event.mood_change
|
||||
if(!event.hidden)
|
||||
shown_mood += event.mood_change
|
||||
|
||||
mood *= mood_modifier
|
||||
shown_mood *= mood_modifier
|
||||
|
||||
|
||||
@@ -54,11 +54,12 @@
|
||||
if(ishuman(destination))
|
||||
var/mob/living/carbon/human/H = destination
|
||||
H.give_genitals(TRUE)//This gives the body the genitals of this DNA. Used for any transformations based on DNA
|
||||
destination.flavor_text = destination.dna.features["flavor_text"] //Update the flavor_text to use new dna text
|
||||
destination.ooc_text = destination.dna.features["ooc_text"] //Update the flavor_text to use new dna text
|
||||
if(transfer_SE)
|
||||
destination.dna.mutation_index = mutation_index
|
||||
|
||||
SEND_SIGNAL(destination, COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, src, transfer_SE)
|
||||
|
||||
/datum/dna/proc/copy_dna(datum/dna/new_dna)
|
||||
new_dna.unique_enzymes = unique_enzymes
|
||||
new_dna.mutation_index = mutation_index
|
||||
@@ -356,7 +357,6 @@
|
||||
|
||||
if(newfeatures)
|
||||
dna.features = newfeatures
|
||||
flavor_text = dna.features["flavor_text"] //Update the flavor_text to use new dna text
|
||||
ooc_text = dna.features["ooc_text"] //Update the flavor_text to use new dna text
|
||||
|
||||
if(mrace)
|
||||
@@ -379,6 +379,9 @@
|
||||
dna.mutation_index = mutation_index
|
||||
domutcheck()
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_HUMAN_HARDSET_DNA, ui, newreal_name, newblood_type, mrace, newfeatures)
|
||||
// change to SEND_SIGNAL(src, COMSIG_HUMAN_HARDSET_DNA, ui, se, newreal_name, newblood_type, mrace, newfeatures) if we add structural enzymes.
|
||||
|
||||
if(mrace || newfeatures || ui)
|
||||
update_body()
|
||||
update_hair()
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
|
||||
|
||||
/datum/element/flavor_text
|
||||
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
|
||||
id_arg_index = 3
|
||||
var/flavor_name = "Flavor Text"
|
||||
var/list/texts_by_atom = list()
|
||||
var/addendum = ""
|
||||
var/always_show = FALSE
|
||||
var/max_len = MAX_FLAVOR_LEN
|
||||
var/can_edit = TRUE
|
||||
/// For preference/DNA saving/loading. Null to prevent. Prefs are only loaded from obviously if it exists in preferences.features.
|
||||
var/save_key
|
||||
/// Do not attempt to render a preview on examine. If this is on, it will display as \[flavor_name\]
|
||||
var/examine_no_preview = FALSE
|
||||
var/examineTabOutput = ""
|
||||
|
||||
/datum/element/flavor_text/Attach(datum/target, text = "", _name = "Flavor Text", _addendum, _max_len = MAX_FLAVOR_LEN, _always_show = FALSE, _edit = TRUE, _save_key, _examine_no_preview = FALSE)
|
||||
. = ..()
|
||||
|
||||
if(. == ELEMENT_INCOMPATIBLE || !isatom(target)) //no reason why this shouldn't work on atoms too.
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
|
||||
if(_max_len)
|
||||
max_len = _max_len
|
||||
texts_by_atom[target] = copytext(text, 1, max_len)
|
||||
if(_name)
|
||||
flavor_name = _name
|
||||
if(!isnull(addendum))
|
||||
addendum = _addendum
|
||||
always_show = _always_show
|
||||
can_edit = _edit
|
||||
save_key = _save_key
|
||||
examine_no_preview = _examine_no_preview
|
||||
|
||||
RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/show_flavor)
|
||||
|
||||
if(can_edit && ismob(target)) //but only mobs receive the proc/verb for the time being
|
||||
var/mob/M = target
|
||||
LAZYOR(GLOB.mobs_with_editable_flavor_text[M], src)
|
||||
M.verbs |= /mob/proc/manage_flavor_tests
|
||||
|
||||
if(save_key && ishuman(target))
|
||||
RegisterSignal(target, COMSIG_HUMAN_PREFS_COPIED_TO, .proc/update_prefs_flavor_text)
|
||||
|
||||
/datum/element/flavor_text/Detach(atom/A)
|
||||
. = ..()
|
||||
UnregisterSignal(A, list(COMSIG_PARENT_EXAMINE, COMSIG_HUMAN_PREFS_COPIED_TO))
|
||||
texts_by_atom -= A
|
||||
if(can_edit && ismob(A))
|
||||
var/mob/M = A
|
||||
LAZYREMOVE(GLOB.mobs_with_editable_flavor_text[M], src)
|
||||
if(!GLOB.mobs_with_editable_flavor_text[M])
|
||||
GLOB.mobs_with_editable_flavor_text -= M
|
||||
M.verbs -= /mob/proc/manage_flavor_tests
|
||||
|
||||
/datum/element/flavor_text/proc/show_flavor(atom/target, mob/user, list/examine_list)
|
||||
if(!always_show && isliving(target))
|
||||
var/mob/living/L = target
|
||||
var/unknown = L.get_visible_name() == "Unknown"
|
||||
if(!unknown && iscarbon(target))
|
||||
var/mob/living/carbon/C = L
|
||||
unknown = (C.wear_mask && (C.wear_mask.flags_inv & HIDEFACE)) || (C.head && (C.head.flags_inv & HIDEFACE))
|
||||
if(unknown)
|
||||
if(!("...?" in examine_list)) //can't think of anything better in case of multiple flavor texts.
|
||||
examine_list += "...?"
|
||||
return
|
||||
var/text = texts_by_atom[target]
|
||||
if(!text)
|
||||
return
|
||||
if(examine_no_preview)
|
||||
examine_list += "<span class='notice'><a href='?src=[REF(src)];show_flavor=[REF(target)]'>\[[flavor_name]\]</a></span>"
|
||||
return
|
||||
var/msg = replacetext(text, "\n", " ")
|
||||
if(length_char(msg) <= 40)
|
||||
examine_list += "<span class='notice'>[msg]</span>"
|
||||
else
|
||||
examine_list += "<span class='notice'>[copytext_char(msg, 1, 37)]... <a href='?src=[REF(src)];show_flavor=[REF(target)]'>More...</span></a>"
|
||||
|
||||
//Examine Tab stuff - Hyperstation
|
||||
examineTabOutput = "<center>"
|
||||
if(ishuman(target)) //user just returned, y'know, the user's own species. dumb.
|
||||
var/mob/living/carbon/human/L = target
|
||||
if(L.gender)
|
||||
examineTabOutput += "[icon2html('hyperstation/icons/chat/gender.dmi', world, L.gender)]"
|
||||
examineTabOutput += "[L.name] "
|
||||
examineTabOutput += "([L.dna.custom_species ? L.dna.custom_species : L.dna.species.name])"
|
||||
examineTabOutput += "</center>"
|
||||
examineTabOutput += "<br>[url_encode(msg)]"
|
||||
if(ismob(target))
|
||||
var/mob/M = target
|
||||
if(M.ooc_text)
|
||||
examineTabOutput += "<br><br><i><b>OOC</b>"
|
||||
examineTabOutput += "<br>[url_encode(M.ooc_text)]"
|
||||
user.client << output(examineTabOutput, "statbrowser:update_examine") //open the examine window
|
||||
user.client << output(null, "statbrowser:create_mobexamine") //open the examine window
|
||||
|
||||
/datum/element/flavor_text/Topic(href, href_list)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(href_list["show_flavor"])
|
||||
var/atom/target = locate(href_list["show_flavor"])
|
||||
var/text = texts_by_atom[target]
|
||||
if(text)
|
||||
usr << browse("<HTML><HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><TITLE>[target.name]</TITLE></HEAD><BODY><TT>[replacetext(texts_by_atom[target], "\n", "<BR>")]</TT></BODY></HTML>", "window=[target.name];size=500x200")
|
||||
onclose(usr, "[target.name]")
|
||||
return TRUE
|
||||
|
||||
/mob/proc/manage_flavor_tests()
|
||||
set name = "Manage Flavor Texts"
|
||||
set desc = "Used to manage your various flavor texts."
|
||||
set category = "IC"
|
||||
|
||||
var/list/L = GLOB.mobs_with_editable_flavor_text[src]
|
||||
|
||||
if(length(L) == 1)
|
||||
var/datum/element/flavor_text/F = L[1]
|
||||
F.set_flavor(src)
|
||||
return
|
||||
|
||||
var/list/choices = list()
|
||||
|
||||
for(var/i in L)
|
||||
var/datum/element/flavor_text/F = i
|
||||
choices[F.flavor_name] = F
|
||||
|
||||
var/chosen = input(src, "Which flavor text would you like to modify?") as null|anything in choices
|
||||
if(!chosen)
|
||||
return
|
||||
var/datum/element/flavor_text/F = choices[chosen]
|
||||
F.set_flavor(src)
|
||||
|
||||
/datum/element/flavor_text/proc/set_flavor(mob/user)
|
||||
if(!(user in texts_by_atom))
|
||||
return FALSE
|
||||
|
||||
var/lower_name = lowertext(flavor_name)
|
||||
var/new_text = stripped_multiline_input(user, "Set the [lower_name] displayed on 'examine'. [addendum]", flavor_name, html_decode(texts_by_atom[usr]), max_len, TRUE)
|
||||
if(!isnull(new_text) && (user in texts_by_atom))
|
||||
texts_by_atom[user] = new_text
|
||||
to_chat(src, "Your [lower_name] has been updated.")
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/element/flavor_text/proc/update_prefs_flavor_text(mob/living/carbon/human/H, datum/preferences/P, icon_updates = TRUE, roundstart_checks = TRUE)
|
||||
if(P.features.Find(save_key))
|
||||
texts_by_atom[H] = P.features[save_key]
|
||||
|
||||
//subtypes with additional hooks for DNA and preferences.
|
||||
/datum/element/flavor_text/carbon
|
||||
//list of antagonists etcetera that should have nothing to do with people's snowflakes.
|
||||
var/static/list/i_dont_even_know_who_you_are = typecacheof(list(/datum/antagonist/abductor, /datum/antagonist/ert,
|
||||
/datum/antagonist/nukeop, /datum/antagonist/wizard))
|
||||
|
||||
/datum/element/flavor_text/carbon/Attach(datum/target, text = "", _name = "Flavor Text", _addendum, _max_len = MAX_FLAVOR_LEN, _always_show = FALSE, _edit = TRUE, _save_key = "flavor_text", _examine_no_preview = FALSE)
|
||||
if(!iscarbon(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
. = ..()
|
||||
if(. == ELEMENT_INCOMPATIBLE)
|
||||
return
|
||||
RegisterSignal(target, COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, .proc/update_dna_flavor_text)
|
||||
RegisterSignal(target, COMSIG_MOB_ANTAG_ON_GAIN, .proc/on_antag_gain)
|
||||
if(ishuman(target))
|
||||
RegisterSignal(target, COMSIG_HUMAN_HARDSET_DNA, .proc/update_dna_flavor_text)
|
||||
RegisterSignal(target, COMSIG_HUMAN_ON_RANDOMIZE, .proc/unset_flavor)
|
||||
|
||||
/datum/element/flavor_text/carbon/Detach(mob/living/carbon/C)
|
||||
. = ..()
|
||||
UnregisterSignal(C, list(COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, COMSIG_MOB_ANTAG_ON_GAIN, COMSIG_HUMAN_PREFS_COPIED_TO, COMSIG_HUMAN_HARDSET_DNA, COMSIG_HUMAN_ON_RANDOMIZE))
|
||||
|
||||
/datum/element/flavor_text/carbon/proc/update_dna_flavor_text(mob/living/carbon/C)
|
||||
texts_by_atom[C] = C.dna.features[save_key]
|
||||
|
||||
/datum/element/flavor_text/carbon/set_flavor(mob/living/carbon/user)
|
||||
. = ..()
|
||||
if(. && user.dna)
|
||||
user.dna.features[save_key] = texts_by_atom[user]
|
||||
|
||||
/datum/element/flavor_text/carbon/proc/unset_flavor(mob/living/carbon/user)
|
||||
texts_by_atom[user] = ""
|
||||
|
||||
|
||||
/datum/element/flavor_text/carbon/proc/on_antag_gain(mob/living/carbon/user, datum/antagonist/antag)
|
||||
if(is_type_in_typecache(antag, i_dont_even_know_who_you_are))
|
||||
texts_by_atom[user] = ""
|
||||
if(user.dna)
|
||||
user.dna.features[save_key] = ""
|
||||
@@ -39,52 +39,49 @@
|
||||
pre_equip(H, visualsOnly)
|
||||
|
||||
//Start with uniform,suit,backpack for additional slots
|
||||
if(uniform)
|
||||
H.equip_to_slot_or_store_and_del(new uniform(H),SLOT_W_UNIFORM)
|
||||
if(suit)
|
||||
H.equip_to_slot_or_store_and_del(new suit(H),SLOT_WEAR_SUIT)
|
||||
if(back)
|
||||
H.equip_to_slot_or_del(new back(H),SLOT_BACK)
|
||||
|
||||
if(!visualsOnly) // Items in pockets or backpack don't show up on mob's icon.
|
||||
if(l_pocket)
|
||||
H.equip_to_slot_or_store_and_del(new l_pocket(H),SLOT_L_STORE)
|
||||
if(r_pocket)
|
||||
H.equip_to_slot_or_store_and_del(new r_pocket(H),SLOT_R_STORE)
|
||||
if(backpack_contents)
|
||||
if(!visualsOnly && backpack_contents) //Keep things organized when we can't equip other stuff by having this first
|
||||
for(var/path in backpack_contents)
|
||||
var/number = backpack_contents[path]
|
||||
if(!isnum(number))//Default to 1
|
||||
number = 1
|
||||
for(var/i in 1 to number)
|
||||
H.equip_to_slot_or_del(new path(H),SLOT_IN_BACKPACK)
|
||||
if(belt)
|
||||
H.equip_to_slot_or_store_and_del(new belt(H),SLOT_BELT)
|
||||
if(gloves)
|
||||
H.equip_to_slot_or_store_and_del(new gloves(H),SLOT_GLOVES)
|
||||
if(shoes)
|
||||
H.equip_to_slot_or_store_and_del(new shoes(H),SLOT_SHOES)
|
||||
if(head)
|
||||
H.equip_to_slot_or_store_and_del(new head(H),SLOT_HEAD)
|
||||
if(mask)
|
||||
H.equip_to_slot_or_store_and_del(new mask(H),SLOT_WEAR_MASK)
|
||||
if(neck)
|
||||
H.equip_to_slot_or_store_and_del(new neck(H),SLOT_NECK)
|
||||
if(ears)
|
||||
H.equip_to_slot_or_store_and_del(new ears(H),SLOT_EARS)
|
||||
if(glasses)
|
||||
H.equip_to_slot_or_store_and_del(new glasses(H),SLOT_GLASSES)
|
||||
if(id)
|
||||
H.equip_to_slot_or_store_and_del(new id(H),SLOT_WEAR_ID)
|
||||
if(suit_store)
|
||||
H.equip_to_slot_or_store_and_del(new suit_store(H),SLOT_S_STORE)
|
||||
|
||||
if(accessory)
|
||||
var/obj/item/clothing/under/U = H.w_uniform
|
||||
if(U)
|
||||
|
||||
if(uniform)
|
||||
var/obj/item/clothing/under/U = new uniform(H)
|
||||
H.equip_to_slot_or_store(U,SLOT_W_UNIFORM)
|
||||
if(accessory)
|
||||
U.attach_accessory(new accessory(H))
|
||||
else
|
||||
WARNING("Unable to equip accessory [accessory] in outfit [name]. No uniform present!")
|
||||
if(suit)
|
||||
H.equip_to_slot_or_store(new suit(H),SLOT_WEAR_SUIT)
|
||||
|
||||
if(!visualsOnly)
|
||||
if(l_pocket)
|
||||
H.equip_to_slot_or_store(new l_pocket(H),SLOT_L_STORE)
|
||||
if(r_pocket)
|
||||
H.equip_to_slot_or_store(new r_pocket(H),SLOT_R_STORE)
|
||||
if(belt)
|
||||
H.equip_to_slot_or_store(new belt(H),SLOT_BELT)
|
||||
if(gloves)
|
||||
H.equip_to_slot_or_store(new gloves(H),SLOT_GLOVES)
|
||||
if(shoes)
|
||||
H.equip_to_slot_or_store(new shoes(H),SLOT_SHOES)
|
||||
if(head)
|
||||
H.equip_to_slot_or_store(new head(H),SLOT_HEAD)
|
||||
if(mask)
|
||||
H.equip_to_slot_or_store(new mask(H),SLOT_WEAR_MASK)
|
||||
if(neck)
|
||||
H.equip_to_slot_or_store(new neck(H),SLOT_NECK)
|
||||
if(ears)
|
||||
H.equip_to_slot_or_store(new ears(H),SLOT_EARS)
|
||||
if(glasses)
|
||||
H.equip_to_slot_or_store(new glasses(H),SLOT_GLASSES)
|
||||
if(id)
|
||||
H.equip_to_slot_or_store(new id(H),SLOT_WEAR_ID)
|
||||
if(suit_store)
|
||||
H.equip_to_slot_or_store(new suit_store(H),SLOT_S_STORE)
|
||||
|
||||
if(l_hand)
|
||||
H.put_in_l_hand(new l_hand(H))
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/datum/weather/ash_storm/layenia //because fuck writing my own code
|
||||
name = "Layenia Weather"
|
||||
desc = "A subset of weather affecting Layenia"
|
||||
weather_color = "white"
|
||||
|
||||
telegraph_message = "<span class='warning'>Thundering clouds pass overhead, swept up by a steady wind.</span>"
|
||||
telegraph_duration = 300
|
||||
telegraph_overlay = "light_snow"
|
||||
|
||||
weather_message = "<span class='boldwarning'><i>Clouds storm over the station slowly...</i></span>"
|
||||
weather_duration_lower = 600
|
||||
weather_duration_upper = 8200
|
||||
weather_overlay = "snow_storm"
|
||||
|
||||
end_message = "<span class='boldannounce'>Sunlight arches over the station once more; the storm has passed.</span>"
|
||||
end_duration = 300
|
||||
end_overlay = "light_snow"
|
||||
|
||||
area_type = /area/layenia
|
||||
target_trait = ZTRAIT_STATION
|
||||
|
||||
probability = 100
|
||||
|
||||
barometer_predictable = TRUE
|
||||
|
||||
aesthetic = TRUE
|
||||
|
||||
//datum/weather/layenia/telegraph()
|
||||
|
||||
//datum/weather/layenia/start()
|
||||
|
||||
//datum/weather/layenia/wind_down()
|
||||
|
||||
//datum/weather/layenia/end()
|
||||
|
||||
//datum/weather/ash_storm/layenia/weather_act
|
||||
@@ -1380,3 +1380,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "Nothing Here"
|
||||
icon_state = "yellow"
|
||||
ambientsounds = SPOOKY
|
||||
|
||||
/area/arcade
|
||||
name = "Arcade"
|
||||
icon_state = "yellow"
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
*/
|
||||
/area/holodeck/rec_center
|
||||
name = "\improper Recreational Holodeck"
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
|
||||
/area/holodeck/rec_center/offline
|
||||
name = "Holodeck - Offline"
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
area/layenia
|
||||
name = "Layenia"
|
||||
icon_state = "mining"
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
blob_allowed = FALSE
|
||||
requires_power = TRUE
|
||||
outdoors = TRUE
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
ambientsounds = MINING
|
||||
atmos = FALSE
|
||||
flags_1 = NONE
|
||||
|
||||
area/layenia/cloudlayer
|
||||
name = "Laneya clouds"
|
||||
icon_state = "space"
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
atmos = FALSE
|
||||
|
||||
area/layenia/powered
|
||||
name = "Layenia Powered"
|
||||
icon_state = "centcom"
|
||||
requires_power = FALSE
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
noteleport = FALSE
|
||||
blob_allowed = TRUE
|
||||
flags_1 = NONE
|
||||
outdoors = FALSE
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
|
||||
atmos = FALSE
|
||||
@@ -864,14 +864,16 @@ Proc for attack log creation, because really why not
|
||||
filters += filter(arglist(arguments))
|
||||
|
||||
/atom/movable/proc/get_filter(name)
|
||||
if(filter_data && filter_data[name])
|
||||
return filters[filter_data.Find(name)]
|
||||
if(filter_data)
|
||||
if(filter_data[name])
|
||||
return filters[filter_data.Find(name)]
|
||||
|
||||
/atom/movable/proc/remove_filter(name)
|
||||
if(filter_data[name])
|
||||
filter_data -= name
|
||||
update_filters()
|
||||
return TRUE
|
||||
if(filter_data)
|
||||
if(filter_data[name])
|
||||
filter_data -= name
|
||||
update_filters()
|
||||
return TRUE
|
||||
|
||||
/atom/proc/intercept_zImpact(atom/movable/AM, levels = 1)
|
||||
. |= SEND_SIGNAL(src, COMSIG_ATOM_INTERCEPT_Z_FALL, AM, levels)
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
var/list/list_observers = list()
|
||||
|
||||
/datum/dynamic_ruleset/event/acceptable(population=0, threat=0)
|
||||
if(istype(controller, /datum/round_event_control))
|
||||
var/datum/round_event_control/R = controller
|
||||
if(R.map_blacklist.len && (SSmapping.config.map_file in R.map_blacklist)) //Apparently dynamic doesn't call a controller's canSpawnEvent :>
|
||||
return FALSE
|
||||
if(R.map_whitelist.len && !(SSmapping.config.map_file in R.map_whitelist))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/event/ready(forced = 0)
|
||||
|
||||
@@ -133,6 +133,7 @@
|
||||
|
||||
/obj/machinery/door/airlock/LateInitialize()
|
||||
. = ..()
|
||||
autorotation() //auto rotate door
|
||||
if (cyclelinkeddir)
|
||||
cyclelinkairlock()
|
||||
if(abandoned)
|
||||
@@ -159,11 +160,20 @@
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/door/airlock/proc/getrotation() //for auto rotating doors, because im sick of doing it
|
||||
for(var/turf/O in get_step(src,SOUTH))
|
||||
log_mapping("[src]: [O]")
|
||||
if(O.density)
|
||||
log_mapping("[src]: [O] is dense")
|
||||
/obj/machinery/door/airlock/proc/autorotation() //for auto rotating doors, because im sick of doing it
|
||||
var/turf/N = get_step(src, NORTH)
|
||||
var/turf/S = get_step(src, SOUTH)
|
||||
|
||||
if(istype(N, /turf/closed)) //Wall
|
||||
dir = 4
|
||||
if(istype(S, /turf/closed))
|
||||
dir = 4
|
||||
var/obj/structure/window/W = locate(/obj/structure/window, N) //Window
|
||||
if(W)
|
||||
dir = 4
|
||||
var/obj/structure/window/R = locate(/obj/structure/window, S)
|
||||
if(R)
|
||||
dir = 4
|
||||
|
||||
/obj/machinery/door/airlock/ComponentInitialize()
|
||||
. = ..()
|
||||
|
||||
@@ -350,7 +350,10 @@
|
||||
icon = 'icons/obj/doors/airlocks/external/external.dmi'
|
||||
overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi'
|
||||
note_overlay_file = 'icons/obj/doors/airlocks/external/overlays.dmi'
|
||||
color_overlay_file = 'icons/obj/doors/airlocks/external/color.dmi'
|
||||
assemblytype = /obj/structure/door_assembly/door_assembly_ext
|
||||
basecolor = "#ff0000" //red
|
||||
|
||||
|
||||
/obj/machinery/door/airlock/external/glass
|
||||
opacity = 0
|
||||
|
||||
@@ -656,3 +656,60 @@
|
||||
|
||||
if(islist(icon_states && icon_states.len))
|
||||
icon_state = pick(icon_states)
|
||||
|
||||
|
||||
/obj/structure/flora/crystal
|
||||
name = "crystal"
|
||||
desc = "You shouldnt see this!"
|
||||
gender = PLURAL //trans rights
|
||||
max_integrity = 30
|
||||
|
||||
/obj/structure/flora/crystal/small
|
||||
name = "small crystals"
|
||||
icon = 'icons/obj/flora/layeniasmall.dmi'
|
||||
light_range = 2
|
||||
light_power = 0.25
|
||||
light_color = LIGHT_COLOR_BLUE
|
||||
|
||||
//Small crystal clusters
|
||||
/obj/structure/flora/crystal/small/pile
|
||||
name = "small crystals"
|
||||
desc = "A pile of small crystals"
|
||||
icon_state = "crystals"
|
||||
|
||||
/obj/structure/flora/crystal/small/pile/Initialize()
|
||||
if(icon_state == "crystals")
|
||||
icon_state = "crystals[rand(1, 4)]"
|
||||
. = ..()
|
||||
|
||||
//Small crystal growths
|
||||
/obj/structure/flora/crystal/small/growth
|
||||
name = "small crystals"
|
||||
desc = "A growth of small crystals"
|
||||
icon_state = "crystalgrowth"
|
||||
|
||||
/obj/structure/flora/crystal/small/growth/Initialize()
|
||||
if(icon_state == "crystalgrowth")
|
||||
icon_state = "crystalgrowth[rand(1, 4)]"
|
||||
. = ..()
|
||||
|
||||
/obj/structure/flora/crystal/medium
|
||||
name = "medium crystals"
|
||||
icon = 'icons/obj/flora/layeniamedium.dmi'
|
||||
pixel_x = -16
|
||||
pixel_y = -3
|
||||
layer = ABOVE_ALL_MOB_LAYER
|
||||
light_range = 4
|
||||
light_power = 0.75
|
||||
light_color = LIGHT_COLOR_BLUE
|
||||
|
||||
//Medium crystal growths
|
||||
/obj/structure/flora/crystal/medium/growth
|
||||
name = "medium crystals"
|
||||
desc = "A growth of medium crystals"
|
||||
icon_state = "crystalgrowth"
|
||||
|
||||
/obj/structure/flora/crystal/medium/growth/Initialize()
|
||||
if(icon_state == "crystalgrowth")
|
||||
icon_state = "crystalgrowth[rand(1, 3)]"
|
||||
. = ..()
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
/turf/closed/wall,
|
||||
/obj/structure/falsewall)
|
||||
smooth = SMOOTH_MORE
|
||||
obj_flags = BLOCK_Z_FALL
|
||||
// flags = CONDUCT_1
|
||||
//planetary_atmos = TRUE
|
||||
|
||||
/obj/structure/lattice/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -74,6 +74,19 @@
|
||||
if(istype(AM))
|
||||
playsound(src,sound,50,1)
|
||||
|
||||
/turf/open/indestructible/concrete
|
||||
name = "concrete"
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "concrete"
|
||||
baseturfs = /turf/open/floor/plating/asteroid/layenia
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
planetary_atmos = TRUE
|
||||
|
||||
/turf/open/indestructible/concrete/smooth
|
||||
icon_state = "concrete2"
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
planetary_atmos = TRUE
|
||||
|
||||
/turf/open/indestructible/cobble/side
|
||||
icon_state = "cobble_side"
|
||||
|
||||
@@ -92,6 +105,27 @@
|
||||
heavyfootstep = FOOTSTEP_GENERIC_HEAVY
|
||||
tiled_dirt = FALSE
|
||||
|
||||
/turf/open/indestructible/layenia/crystal
|
||||
name = "Lattice Crystal"
|
||||
desc = "A glowing azure crystal, with strange properties to make things float."
|
||||
icon = 'icons/turf/floors/crystal_floor.dmi'
|
||||
baseturfs = /turf/open/indestructible/layenia/crystal
|
||||
slowdown = 1
|
||||
light_range = 4
|
||||
light_power = 0.5
|
||||
barefootstep = FOOTSTEP_HARD_BAREFOOT
|
||||
clawfootstep = FOOTSTEP_HARD_CLAW
|
||||
heavyfootstep = FOOTSTEP_GENERIC_HEAVY
|
||||
light_color = LIGHT_COLOR_BLUE
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
planetary_atmos = TRUE
|
||||
smooth = SMOOTH_TRUE | SMOOTH_BORDER | SMOOTH_MORE
|
||||
canSmoothWith = list(/turf/open/indestructible/layenia/crystal)
|
||||
|
||||
/turf/open/indestructible/layenia/crystal/garden
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
planetary_atmos = TRUE
|
||||
|
||||
/turf/open/indestructible/necropolis
|
||||
name = "necropolis floor"
|
||||
desc = "It's regarding you suspiciously."
|
||||
@@ -208,6 +242,13 @@
|
||||
//testing("Active turf found. Return value of compare(): [is_active]")
|
||||
excited = TRUE
|
||||
SSair.active_turfs |= src
|
||||
//Issues with air runtiming and you don't know where? Uncomment the following code.
|
||||
/*
|
||||
if(air == null)
|
||||
log_game("Bad air from [src] at [src.loc]")
|
||||
if(enemy_air == null)
|
||||
log_game("Bad air from [enemy_tile] at [enemy_tile.loc]")
|
||||
*/
|
||||
|
||||
/turf/open/proc/GetHeatCapacity()
|
||||
. = air.heat_capacity()
|
||||
|
||||
@@ -115,3 +115,25 @@
|
||||
var/turf/T = safepick(get_area_turfs(/area/fabric_of_reality))
|
||||
if(T)
|
||||
set_target(T)
|
||||
|
||||
/turf/open/chasm/cloud
|
||||
name = "clouds"
|
||||
gender = PLURAL
|
||||
desc = "Clouds as far as the eye can see... Watch your step."
|
||||
icon = 'icons/turf/space.dmi'
|
||||
icon_state = "0"
|
||||
plane = PLANE_SPACE
|
||||
tiled_dirt = FALSE
|
||||
baseturfs = /turf/open/chasm/cloud
|
||||
smooth = SMOOTH_FALSE
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
|
||||
/turf/open/chasm/cloud/Initialize()
|
||||
. = ..()
|
||||
icon_state = SPACE_ICON_STATE
|
||||
|
||||
/turf/open/chasm/cloud/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
underlay_appearance.icon = 'icons/turf/space.dmi'
|
||||
underlay_appearance.icon_state = SPACE_ICON_STATE
|
||||
underlay_appearance.plane = PLANE_SPACE
|
||||
return TRUE
|
||||
|
||||
@@ -19,13 +19,14 @@
|
||||
attachment_holes = FALSE
|
||||
var/obj/item/stack/digResult = /obj/item/stack/ore/glass/basalt
|
||||
var/dug
|
||||
var/quantity_of_available_tiles = 12 //How many sprites do you have in the DMI? Note, consider tile 0. 12 here means = 13 titles. 13 tiles is the golden standard.
|
||||
|
||||
/turf/open/floor/plating/asteroid/Initialize()
|
||||
var/proper_name = name
|
||||
. = ..()
|
||||
name = proper_name
|
||||
if(prob(floor_variance))
|
||||
icon_state = "[environment_type][rand(0,12)]"
|
||||
icon_state = "[environment_type][rand(0,quantity_of_available_tiles)]"
|
||||
|
||||
/turf/open/floor/plating/asteroid/proc/getDug()
|
||||
new digResult(src, 5)
|
||||
@@ -363,3 +364,42 @@
|
||||
/turf/open/floor/plating/asteroid/snow/atmosphere
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
planetary_atmos = FALSE
|
||||
|
||||
//Layenia stuff
|
||||
|
||||
/turf/open/floor/plating/asteroid/layenia
|
||||
gender = PLURAL //trans rights
|
||||
name = "crimson Rock"
|
||||
desc = "A cold rock, rusted scarlet in color."
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
baseturfs = /turf/open/floor/plating/asteroid/layenia
|
||||
icon_state = "layenia"
|
||||
icon_plating = "layenia"
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
slowdown = 1
|
||||
environment_type = "layenia"
|
||||
flags_1 = NONE
|
||||
planetary_atmos = TRUE
|
||||
burnt_states = null
|
||||
bullet_sizzle = TRUE
|
||||
bullet_bounce_sound = null
|
||||
digResult = /obj/item/stack/ore/glass/basalt
|
||||
floor_variance = 50 //This means 50% chance of variating from the default tile.
|
||||
quantity_of_available_tiles = 4
|
||||
//light_range = 2
|
||||
//light_power = 0.15
|
||||
//light_color = LIGHT_COLOR_WHITE
|
||||
|
||||
/turf/open/floor/plating/asteroid/layenia/Initialize()
|
||||
. = ..()
|
||||
//We no longer randomize the icon state here. That is done by the supercall in our parent, asteroid.
|
||||
set_layenia_light(src)
|
||||
|
||||
/turf/open/floor/plating/asteroid/layenia/garden
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
planetary_atmos = TRUE
|
||||
|
||||
/proc/set_layenia_light(turf/open/floor/B)
|
||||
switch(B.icon_state)
|
||||
if("layenia3", "layenia4")
|
||||
B.set_light(2, 0.6, LIGHT_COLOR_BLUE) //more light
|
||||
|
||||
@@ -240,5 +240,3 @@
|
||||
|
||||
/turf/open/floor/plating/snowed/temperatre
|
||||
temperature = 255.37
|
||||
|
||||
|
||||
|
||||
@@ -522,4 +522,16 @@
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = 1
|
||||
defer_change = 1
|
||||
|
||||
/turf/closed/mineral/layenia
|
||||
name = "Crimson rock"
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
smooth_icon = 'icons/turf/layeniarocks.dmi'
|
||||
icon_state = "layenia"
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
canSmoothWith = null
|
||||
baseturfs = /turf/open/floor/plating/asteroid/layenia
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
environment_type = "layenia"
|
||||
turf_type = /turf/open/floor/plating/asteroid/layenia
|
||||
|
||||
@@ -72,6 +72,7 @@ GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin())
|
||||
/client/proc/cmd_admin_pm_panel, /*admin-pm list*/
|
||||
/client/proc/panicbunker,
|
||||
/client/proc/addbunkerbypass,
|
||||
/client/proc/discordmessage,
|
||||
/client/proc/revokebunkerbypass,
|
||||
/client/proc/stop_sounds,
|
||||
/client/proc/debugstatpanel,
|
||||
|
||||
@@ -37,7 +37,10 @@
|
||||
H.dna.features["moth_wings"] = pick(GLOB.moth_wings_list)
|
||||
H.dna.features["moth_fluff"] = pick(GLOB.moth_fluffs_list)
|
||||
H.dna.features["deco_wings"] = pick(GLOB.deco_wings_list)
|
||||
H.dna.features["flavor_text"] = "" //Oh no.
|
||||
|
||||
SEND_SIGNAL(H, COMSIG_HUMAN_ON_RANDOMIZE)
|
||||
|
||||
H.update_body()
|
||||
H.update_hair()
|
||||
H.update_body_parts()
|
||||
H.update_body_parts()
|
||||
|
||||
@@ -72,6 +72,7 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
give_antag_moodies()
|
||||
if(is_banned(owner.current) && replace_banned)
|
||||
replace_banned_player()
|
||||
SEND_SIGNAL(owner.current, COMSIG_MOB_ANTAG_ON_GAIN, src)
|
||||
|
||||
/datum/antagonist/proc/is_banned(mob/M)
|
||||
if(!M)
|
||||
|
||||
@@ -134,6 +134,9 @@
|
||||
else
|
||||
to_chat(user, status())
|
||||
|
||||
/obj/machinery/meter/attack_ghost(mob/user)
|
||||
to_chat(user, status())
|
||||
|
||||
/obj/machinery/meter/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
@@ -141,6 +144,7 @@
|
||||
|
||||
// TURF METER - REPORTS A TILE'S AIR CONTENTS
|
||||
// why are you yelling?
|
||||
// i hope they aren't mad
|
||||
/obj/machinery/meter/turf
|
||||
|
||||
/obj/machinery/meter/turf/reattach_to_layer()
|
||||
|
||||
@@ -377,6 +377,17 @@
|
||||
air_update_turf() // Update the environment if needed.
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/attack_ghost(mob/user)
|
||||
if(user.client)
|
||||
if(IsAdminGhost(user))
|
||||
attack_ai(user)
|
||||
return FALSE
|
||||
else if(user.client.prefs.inquisitive_ghost)
|
||||
user.examinate(src)
|
||||
return FALSE
|
||||
atmosanalyzer_scan(air_contents, user, src, FALSE)
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
|
||||
@@ -181,6 +181,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
"ipc_screen" = "Sunburst",
|
||||
"ipc_antenna" = "None",
|
||||
"flavor_text" = "",
|
||||
"silicon_flavor_text" = "",
|
||||
"ooc_text" = ""
|
||||
)
|
||||
|
||||
@@ -393,6 +394,15 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "[features["flavor_text"]]"
|
||||
else
|
||||
dat += "[TextPreview(features["flavor_text"])]...<BR>"
|
||||
dat += "<h2>Silicon Flavor Text</h2>"
|
||||
dat += "<a href='?_src_=prefs;preference=silicon_flavor_text;task=input'><b>Set Silicon Examine Text</b></a><br>"
|
||||
if(length(features["silicon_flavor_text"]) <= 40)
|
||||
if(!length(features["silicon_flavor_text"]))
|
||||
dat += "\[...\]"
|
||||
else
|
||||
dat += "[features["silicon_flavor_text"]]"
|
||||
else
|
||||
dat += "[TextPreview(features["silicon_flavor_text"])]...<BR>"
|
||||
dat += "<h2>OOC Text</h2>"
|
||||
dat += "<a href='?_src_=prefs;preference=ooc_text;task=input'><b>Set OOC Text</b></a><br>"
|
||||
if(length(features["ooc_text"]) <= 40)
|
||||
@@ -1711,6 +1721,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
msg = msg
|
||||
features["flavor_text"] = msg
|
||||
|
||||
if("silicon_flavor_text")
|
||||
var/msg = stripped_multiline_input(usr, "Set the silicon flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Silicon Flavor Text", features["silicon_flavor_text"], MAX_FLAVOR_LEN, TRUE)
|
||||
if(msg)
|
||||
msg = msg
|
||||
features["silicon_flavor_text"] = msg
|
||||
|
||||
if("ooc_text")
|
||||
var/msg = stripped_multiline_input(usr, "Set the OOC text in your 'examine' verb. This should be OOC only!", "OOC Text", html_decode(features["ooc_text"]), MAX_MESSAGE_LEN, TRUE)
|
||||
if(msg)
|
||||
@@ -2754,6 +2770,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
else
|
||||
character.Digitigrade_Leg_Swap(TRUE)
|
||||
|
||||
SEND_SIGNAL(character, COMSIG_HUMAN_PREFS_COPIED_TO, src, icon_updates, roundstart_checks)
|
||||
|
||||
//speech stuff
|
||||
if(custom_tongue != "default")
|
||||
var/new_tongue = GLOB.roundstart_tongues[custom_tongue]
|
||||
|
||||
@@ -436,6 +436,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
else //We have no old flavortext, default to new
|
||||
S["feature_flavor_text"] >> features["flavor_text"]
|
||||
|
||||
S["feature_silicon_flavor_text"] >> features["silicon_flavor_text"]
|
||||
if((S["ooc_text"] != "") && (S["ooc_text"] != null) && S["ooc_text"])
|
||||
S["ooc_text"] >> features["ooc_text"]
|
||||
|
||||
@@ -513,6 +514,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
custom_speech_verb = sanitize_inlist(custom_speech_verb, GLOB.speech_verbs, "default")
|
||||
custom_tongue = sanitize_inlist(custom_tongue, GLOB.roundstart_tongues, "default")
|
||||
|
||||
features["flavor_text"] = copytext(features["flavor_text"], 1, MAX_FLAVOR_LEN)
|
||||
features["silicon_flavor_text"] = copytext(features["silicon_flavor_text"], 1, MAX_FLAVOR_LEN)
|
||||
|
||||
joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole))
|
||||
job_civilian_high = sanitize_integer(job_civilian_high, 0, 65535, initial(job_civilian_high))
|
||||
job_civilian_med = sanitize_integer(job_civilian_med, 0, 65535, initial(job_civilian_med))
|
||||
|
||||
@@ -796,6 +796,7 @@
|
||||
item_color = "greenplaidshirt"
|
||||
body_parts_covered = CHEST|GROIN|ARMS|LEGS
|
||||
can_adjust = FALSE
|
||||
fitted = NO_FEMALE_UNIFORM
|
||||
//yes
|
||||
|
||||
//Enzo_Leon patron stuff
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
max_occurrences = 1
|
||||
weight = 4
|
||||
earliest_start = 5 MINUTES
|
||||
map_blacklist = list("LayeniaStation.dmm")
|
||||
|
||||
/datum/round_event_control/aurora_caelus/canSpawnEvent(players, gamemode)
|
||||
if(!CONFIG_GET(flag/starlight))
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
min_players = 5 //increased min players from 2 to 5 to reduce chances of half the crew dying in a carp breach
|
||||
earliest_start = 10 MINUTES
|
||||
max_occurrences = 6
|
||||
map_blacklist = list("LayeniaStation.dmm")
|
||||
|
||||
/datum/round_event/carp_migration
|
||||
announceWhen = 3
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
typepath = /datum/round_event/meteor_wave/meaty
|
||||
weight = 2
|
||||
max_occurrences = 1
|
||||
map_blacklist = list("LayeniaStation.dmm")
|
||||
|
||||
/datum/round_event/meteor_wave/meaty
|
||||
wave_name = "meaty"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
min_players = 20
|
||||
max_occurrences = 3
|
||||
earliest_start = 25 MINUTES
|
||||
map_blacklist = list("LayeniaStation.dmm")
|
||||
|
||||
/datum/round_event/meteor_wave
|
||||
startWhen = 6
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
return ..()
|
||||
|
||||
/datum/round_event/pirates
|
||||
startWhen = 60 //2 minutes to answer
|
||||
startWhen = 300 //5 minutes to answer
|
||||
var/datum/comm_message/threat
|
||||
var/payoff = 0
|
||||
var/paid_off = FALSE
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
typepath = /datum/round_event/grey_tide
|
||||
max_occurrences = 2
|
||||
min_players = 5
|
||||
map_blacklist = list("LayeniaStation.dmm")
|
||||
|
||||
/datum/round_event/grey_tide
|
||||
announceWhen = 50
|
||||
@@ -67,4 +68,4 @@
|
||||
temp.prison_open()
|
||||
else if(istype(O, /obj/machinery/door_timer))
|
||||
var/obj/machinery/door_timer/temp = O
|
||||
temp.timer_end(forced = TRUE)
|
||||
temp.timer_end(forced = TRUE)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
max_occurrences = 3
|
||||
weight = 2
|
||||
min_players = 2
|
||||
map_blacklist = list("LayeniaStation.dmm")
|
||||
|
||||
|
||||
/datum/round_event/wormholes
|
||||
|
||||
@@ -540,7 +540,7 @@
|
||||
/obj/item/reagent_containers/food/drinks/soda_cans/monkey_energy
|
||||
name = "Monkey Energy"
|
||||
desc = "Unleash the ape!"
|
||||
icon_state = "monkey_energy"
|
||||
icon_state = "menergy"
|
||||
list_reagents = list(/datum/reagent/consumable/monkey_energy = 50)
|
||||
foodtype = SUGAR | JUNKFOOD
|
||||
price = 3
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
/obj/machinery/gibber/RefreshParts()
|
||||
var/gib_time = 40
|
||||
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
|
||||
meat_produced += B.rating
|
||||
meat_produced += 1.6 * B.rating
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
gib_time -= 5 * M.rating
|
||||
gibtime = gib_time
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
GLOBAL_LIST_EMPTY(monkey_recyclers)
|
||||
|
||||
/obj/machinery/monkey_recycler
|
||||
name = "monkey recycler"
|
||||
desc = "A machine used for recycling dead monkeys into monkey cubes. It currently produces 1 cube for every 5 monkeys inserted." // except it literally never does
|
||||
desc = "A machine used for recycling dead monkeys into monkey cubes. You can use a multitool to link it to a xenobiology console. It currently produces 0.2 cubes for every monkey inserted."
|
||||
icon = 'icons/obj/kitchen.dmi'
|
||||
icon_state = "grinder"
|
||||
layer = BELOW_OBJ_LAYER
|
||||
@@ -9,20 +11,29 @@
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 50
|
||||
circuit = /obj/item/circuitboard/machine/monkey_recycler
|
||||
var/grinded = 0
|
||||
var/required_grind = 5
|
||||
var/cube_production = 1
|
||||
var/stored_matter = 0
|
||||
var/cube_production = 0.2
|
||||
var/list/connected = list() //Xenobio consoles
|
||||
|
||||
/obj/machinery/monkey_recycler/Initialize(mapload)
|
||||
. = ..()
|
||||
GLOB.monkey_recyclers += src
|
||||
|
||||
/obj/machinery/monkey_recycler/RefreshParts()
|
||||
var/req_grind = 5
|
||||
var/cubes_made = 1
|
||||
/obj/machinery/monkey_recycler/Destroy()
|
||||
if(src in GLOB.monkey_recyclers)
|
||||
GLOB.monkey_recyclers -= src
|
||||
for(var/obj/machinery/computer/camera_advanced/xenobio/C in connected)
|
||||
var/obj/machinery/computer/camera_advanced/xenobio/console = C
|
||||
console.connected_recycler = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/monkey_recycler/RefreshParts() //Ranges from 0.2 to 0.8 per monkey recycled
|
||||
cube_production = 0
|
||||
for(var/obj/item/stock_parts/manipulator/B in component_parts)
|
||||
req_grind -= B.rating
|
||||
cube_production += B.rating * 0.1
|
||||
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
|
||||
cubes_made = M.rating
|
||||
cube_production = cubes_made
|
||||
required_grind = req_grind
|
||||
src.desc = "A machine used for recycling dead monkeys into monkey cubes. It currently produces [cubes_made] cube(s) for every [required_grind] monkey(s) inserted."
|
||||
cube_production += M.rating * 0.1
|
||||
desc = "A machine used for recycling dead monkeys into monkey cubes. You can use a multitool to link it to a xenobiology console. It currently produces [cube_production] cubes for every monkey inserted."
|
||||
|
||||
/obj/machinery/monkey_recycler/attackby(obj/item/O, mob/user, params)
|
||||
if(default_deconstruction_screwdriver(user, "grinder_open", "grinder", O))
|
||||
@@ -64,17 +75,23 @@
|
||||
var/offset = prob(50) ? -2 : 2
|
||||
animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking
|
||||
use_power(500)
|
||||
grinded++
|
||||
stored_matter += cube_production
|
||||
addtimer(VARSET_CALLBACK(src, pixel_x, initial(pixel_x)))
|
||||
addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, user, "<span class='notice'>The machine now has [grinded] monkey\s worth of material stored.</span>"))
|
||||
addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, user, "<span class='notice'>The machine now has [stored_matter] monkey\s worth of material stored.</span>"))
|
||||
|
||||
/obj/machinery/monkey_recycler/interact(mob/user)
|
||||
if(grinded >= required_grind)
|
||||
to_chat(user, "<span class='notice'>The machine hisses loudly as it condenses the grinded monkey meat. After a moment, it dispenses a brand new monkey cube.</span>")
|
||||
if(stored_matter >= 1)
|
||||
to_chat(user, "<span class='notice'>The machine hisses loudly as it condenses the ground monkey meat. After a moment, it dispenses a brand new monkey cube.</span>")
|
||||
playsound(src.loc, 'sound/machines/hiss.ogg', 50, 1)
|
||||
grinded -= required_grind
|
||||
for(var/i = 0, i < cube_production, i++)
|
||||
new /obj/item/reagent_containers/food/snacks/monkeycube(src.loc)
|
||||
to_chat(user, "<span class='notice'>The machine's display flashes that it has [grinded] monkeys worth of material left.</span>")
|
||||
for(var/i in 1 to max(stored_matter, 1))
|
||||
new /obj/item/reagent_containers/food/snacks/monkeycube(loc)
|
||||
stored_matter--
|
||||
to_chat(user, "<span class='notice'>The machine's display flashes that it has [stored_matter] monkeys worth of material left.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='danger'>The machine needs at least [required_grind] monkey(s) worth of material to produce a monkey cube. It only has [grinded].</span>")
|
||||
to_chat(user, "<span class='danger'>The machine needs at least 1 monkey worth of material to produce a monkey cube. It currently has [stored_matter].</span>")
|
||||
|
||||
/obj/machinery/monkey_recycler/multitool_act(mob/living/user, obj/item/multitool/I)
|
||||
if(istype(I))
|
||||
to_chat(user, "<span class='notice'>You log [src] in the multitool's buffer.</span>")
|
||||
I.buffer = src
|
||||
return TRUE
|
||||
|
||||
@@ -368,7 +368,7 @@
|
||||
C.reagents.add_reagent(/datum/reagent/fermi/eigenstate, 30)
|
||||
if(5)
|
||||
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"A new familiar for me, and you'll see it's thee!\"</span>")
|
||||
C.reagents.add_reagent("secretcatchem", 30)
|
||||
C.reagents.add_reagent(/datum/reagent/fermi/secretcatchem, 30)
|
||||
if(6)
|
||||
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"While you may not be a ghost, for this sheet you'll always be it's host.\"</span>")
|
||||
var/mob/living/carbon/human/H = C
|
||||
|
||||
@@ -29,13 +29,13 @@
|
||||
distill_reagent = /datum/reagent/saltpetre
|
||||
|
||||
|
||||
// Laughin' Peas
|
||||
// Laughing Peas
|
||||
/obj/item/seeds/peas/laugh
|
||||
name = "pack of laughin' peas"
|
||||
desc = "These seeds give off a very soft purple glow.. they should grow into Laughin' Peas."
|
||||
name = "pack of laughing peas"
|
||||
desc = "These seeds give off a very soft purple glow.. they should grow into Laughing Peas."
|
||||
icon_state = "seed-laughpeas"
|
||||
species = "laughpeas"
|
||||
plantname = "Laughin' Peas"
|
||||
plantname = "Laughing Peas"
|
||||
product = /obj/item/reagent_containers/food/snacks/grown/laugh
|
||||
maturation = 7
|
||||
potency = 10
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/laugh
|
||||
seed = /obj/item/seeds/peas/laugh
|
||||
name = "pod of laughin' peas"
|
||||
name = "pod of laughing peas"
|
||||
desc = "Ridens Cicer, guaranteed to improve your mood dramatically upon consumption!"
|
||||
icon_state = "laughpeas"
|
||||
filling_color = "#ee7bee"
|
||||
|
||||
@@ -29,13 +29,22 @@ Captain
|
||||
/datum/job/captain/get_access()
|
||||
return get_all_accesses()
|
||||
|
||||
/datum/job/captain/announce(mob/living/carbon/human/H)
|
||||
..()
|
||||
var/displayed_rank = H.client.prefs.alt_titles_preferences[title]
|
||||
if(!displayed_rank)
|
||||
displayed_rank = "Captain"
|
||||
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, .proc/minor_announce, "[displayed_rank] [H.nameless ? "" : "[H.real_name] "]on deck!"))
|
||||
/datum/job/captain/announce(mob/living/carbon/human/H, tried=FALSE)
|
||||
if(!H)
|
||||
return
|
||||
if(!H.client && !tried) //Roundstart mobs don't have clients when announce() gets called
|
||||
SSticker.OnRoundstart(CALLBACK(src, .proc/announce, H, TRUE)) //So we try again...
|
||||
return
|
||||
if(tried && !H.client) //We don't want to endlessly call ourselves when we don't have a client
|
||||
throw EXCEPTION("[H.nameless ? "Captain" : "Captain [H.real_name]"] ([H.x],[H.y],[H.z]) has no client.")
|
||||
return
|
||||
|
||||
var/displayed_rank = H.client.prefs.alt_titles_preferences[title]
|
||||
if(!displayed_rank) //Default to Captain
|
||||
displayed_rank = "Captain"
|
||||
|
||||
minor_announce("[displayed_rank] [H.nameless ? "" : "[H.real_name] "]on deck!")
|
||||
..()
|
||||
|
||||
/datum/outfit/job/captain
|
||||
name = "Captain"
|
||||
|
||||
@@ -18,7 +18,7 @@ Clown
|
||||
minimal_access = list(ACCESS_THEATRE)
|
||||
|
||||
/datum/job/clown/after_spawn(mob/living/carbon/human/H, mob/M)
|
||||
. = ..()
|
||||
..()
|
||||
H.apply_pref_name("clown", M.client)
|
||||
|
||||
/datum/outfit/job/clown
|
||||
@@ -83,6 +83,7 @@ Mime
|
||||
minimal_access = list(ACCESS_THEATRE)
|
||||
|
||||
/datum/job/mime/after_spawn(mob/living/carbon/human/H, mob/M)
|
||||
..()
|
||||
H.apply_pref_name("mime", M.client)
|
||||
|
||||
/datum/outfit/job/mime
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
//Only override this proc
|
||||
//H is usually a human unless an /equip override transformed it
|
||||
/datum/job/proc/after_spawn(mob/living/H, mob/M, latejoin = FALSE)
|
||||
//do actions on H but send messages to M as the key may not have been transferred_yet
|
||||
//do actions on H but send messages to M as the key may not have been transferred yet
|
||||
if(mind_traits)
|
||||
for(var/t in mind_traits)
|
||||
ADD_TRAIT(H.mind, t, JOB_TRAIT)
|
||||
|
||||
@@ -21,7 +21,7 @@ AI
|
||||
. = H.AIize(latejoin)
|
||||
|
||||
/datum/job/ai/after_spawn(mob/H, mob/M, latejoin)
|
||||
. = ..()
|
||||
..()
|
||||
if(latejoin)
|
||||
var/obj/structure/AIcore/latejoin_inactive/lateJoinCore
|
||||
for(var/obj/structure/AIcore/latejoin_inactive/P in GLOB.latejoin_ai_cores)
|
||||
|
||||
@@ -64,6 +64,14 @@
|
||||
name = "asteroid snow baseturf editor"
|
||||
baseturf = /turf/open/floor/plating/asteroid/snow
|
||||
|
||||
/obj/effect/baseturf_helper/asteroid/layenia
|
||||
name = "layenia baseturf editor"
|
||||
baseturf = /turf/open/floor/plating/asteroid/layenia
|
||||
|
||||
/obj/effect/baseturf_helper/cloud
|
||||
name = "cloud baseturf editor"
|
||||
baseturf = /turf/open/chasm/cloud
|
||||
|
||||
/obj/effect/baseturf_helper/beach/sand
|
||||
name = "beach sand baseturf editor"
|
||||
baseturf = /turf/open/floor/plating/beach/sand
|
||||
|
||||
@@ -597,7 +597,7 @@
|
||||
if (H.custom_body_size) //Do they have it set?
|
||||
H.resize(H.custom_body_size * 0.01)
|
||||
if (H.breedable == TRUE)
|
||||
H.impregchance = 30
|
||||
H.impregchance = 25
|
||||
. = H
|
||||
new_character = .
|
||||
if(transfer_after)
|
||||
|
||||
@@ -17,3 +17,8 @@
|
||||
name = "Round + Light"
|
||||
icon_state = "roundlight"
|
||||
|
||||
/datum/sprite_accessory/snouts/gator
|
||||
name = "Gator"
|
||||
icon_state = "gator"
|
||||
color_src = MATRIXED
|
||||
|
||||
|
||||
@@ -11,14 +11,20 @@
|
||||
toggle_combat_mode(TRUE, TRUE)
|
||||
|
||||
. = ..()
|
||||
|
||||
|
||||
for(var/T in get_traumas())
|
||||
var/datum/brain_trauma/BT = T
|
||||
BT.on_death()
|
||||
|
||||
|
||||
if(SSticker.mode)
|
||||
SSticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now
|
||||
|
||||
//watching someone die is traumatic
|
||||
for(var/mob/living/carbon/human/H in oview(5, src))
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "death", /datum/mood_event/deathsaw)
|
||||
if(prob(10)) //10% chance to pump adrenaline into their body
|
||||
H.jitteriness += 5
|
||||
|
||||
/mob/living/carbon/gib(no_brain, no_organs, no_bodyparts)
|
||||
var/atom/Tsec = drop_location()
|
||||
for(var/mob/M in src)
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
var/t_is = p_are()
|
||||
var/obscure_name
|
||||
var/dispSize = round(12*size_multiplier) // gets the character's sprite size percent and converts it to the nearest half foot
|
||||
var/output = ""
|
||||
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
@@ -24,25 +23,13 @@
|
||||
if (vassDesc != "")
|
||||
. += vassDesc
|
||||
|
||||
output = "<center>"
|
||||
var/list/obscured = check_obscured_slots()
|
||||
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
|
||||
|
||||
if(ishuman(src)) //user just returned, y'know, the user's own species. dumb.
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(gender)
|
||||
output += "[icon2html('hyperstation/icons/chat/gender.dmi', world, gender)]"
|
||||
|
||||
output += "<b>[src.name]</b>"
|
||||
var/datum/species/pref_species = H.dna.species
|
||||
if(get_visible_name() == "Unknown") // same as flavor text, but hey it works.
|
||||
. += "You can't make out what species they are."
|
||||
else if(skipface)
|
||||
. += "You can't make out what species they are."
|
||||
else
|
||||
. += "[t_He] [t_is] a [H.dna.custom_species ? H.dna.custom_species : pref_species.name]!"
|
||||
output += "([H.dna.custom_species ? H.dna.custom_species : pref_species.name])"
|
||||
output += "</center>"
|
||||
|
||||
if(skipface || get_visible_name() == "Unknown")
|
||||
. += "You can't make out what species they are."
|
||||
else
|
||||
. += "[t_He] [t_is] a [dna.custom_species ? dna.custom_species : dna.species.name]!"
|
||||
|
||||
//uniform
|
||||
if(w_uniform && !(SLOT_W_UNIFORM in obscured))
|
||||
@@ -416,30 +403,9 @@
|
||||
else if(isobserver(user) && traitstring)
|
||||
. += "<span class='info'><b>Traits:</b> [traitstring]</span>"
|
||||
|
||||
|
||||
if(print_flavor_text())
|
||||
output += "<br><b>General</b>"
|
||||
if(get_visible_name() == "Unknown") //Are we sure we know who this is? Don't show flavor text unless we can recognize them. Prevents certain metagaming with impersonation.
|
||||
. += "...?"
|
||||
output += "<br>...?"
|
||||
else if(skipface) //Sometimes we're not unknown, but impersonating someone in a hardsuit, let's not reveal our flavor text then either.
|
||||
. += "...?"
|
||||
output += "<br>...?"
|
||||
else
|
||||
. += "[print_flavor_text()]"
|
||||
output += "<br>[url_encode(flavor_text)]"
|
||||
if(ooc_text)
|
||||
output += "<br><br><i><b>OOC</b>"
|
||||
output += "<br>[url_encode(ooc_text)]"
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, msg)
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) //This also handles flavor texts now
|
||||
. += "*---------*</span>"
|
||||
|
||||
//stat panel
|
||||
if(ishuman(src))
|
||||
user.client << output(output, "statbrowser:update_examine") //open the examine window
|
||||
user.client << output(null, "statbrowser:create_mobexamine") //open the examine window
|
||||
|
||||
/mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects!
|
||||
var/list/dat = list()
|
||||
if(!pronoun_replacement)
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
if(!CONFIG_GET(flag/disable_human_mood))
|
||||
AddComponent(/datum/component/mood)
|
||||
AddElement(/datum/element/mob_holder/micro, "micro")
|
||||
AddElement(/datum/element/flavor_text/carbon, "", "Flavor Text", "", MAX_FLAVOR_LEN, FALSE, TRUE, "flavor_text")
|
||||
AddElement(/datum/element/flavor_text, "", "Temporary Flavor Text", "This should be used only for things pertaining to the current round!")
|
||||
|
||||
/mob/living/carbon/human/Destroy()
|
||||
QDEL_NULL(physiology)
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
//H13 custom body size and impregnation
|
||||
var/custom_body_size = 100
|
||||
var/breedable = 0
|
||||
var/impregchance = 0
|
||||
var/impregchance = 30
|
||||
//h13 noncon settings
|
||||
var/Noncon = 0
|
||||
var/ERP = 0
|
||||
|
||||
@@ -437,11 +437,11 @@
|
||||
|
||||
var/obj/item/reagent_containers/spray/cyborg_drying/CD = locate(/obj/item/reagent_containers/spray/cyborg_drying) in basic_modules
|
||||
if(CD)
|
||||
CD.reagents.add_reagent("drying_agent", 5 * coeff)
|
||||
CD.reagents.add_reagent(/datum/reagent/drying_agent, 5 * coeff)
|
||||
|
||||
var/obj/item/reagent_containers/spray/cyborg_lube/CL = locate(/obj/item/reagent_containers/spray/cyborg_lube) in emag_modules
|
||||
if(CL)
|
||||
CL.reagents.add_reagent("lube", 2 * coeff)
|
||||
CL.reagents.add_reagent(/datum/reagent/lube, 2 * coeff)
|
||||
|
||||
/obj/item/robot_module/clown
|
||||
name = "Clown"
|
||||
|
||||
@@ -55,6 +55,11 @@
|
||||
diag_hud_set_status()
|
||||
diag_hud_set_health()
|
||||
|
||||
/mob/living/silicon/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/flavor_text, "", "Silicon Flavor Text", "", MAX_FLAVOR_LEN, FALSE, TRUE, "silicon_flavor_text")
|
||||
AddElement(/datum/element/flavor_text, "", "Temporary Flavor Text", "This should be used only for things pertaining to the current round!")
|
||||
|
||||
/mob/living/silicon/med_hud_set_health()
|
||||
return //we use a different hud
|
||||
|
||||
|
||||
@@ -316,9 +316,9 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0)
|
||||
to_chat(H, "<span class='userdanger'>WHAT THE FUCK IS THAT?!</span>")
|
||||
to_chat(H, "<i>.KNOH !nuf hcum os si uoy htiw gniyalP .KNOH KNOH KNOH</i>")
|
||||
H.playsound_local(src,'sound/hallucinations/im_here1.ogg', 25)
|
||||
H.reagents.add_reagent("mindbreaker", 3)
|
||||
H.reagents.add_reagent("laughter", 5)
|
||||
H.reagents.add_reagent("mercury", 3)
|
||||
H.reagents.add_reagent(/datum/reagent/toxin/mindbreaker, 3)
|
||||
H.reagents.add_reagent(/datum/reagent/consumable/laughter, 5)
|
||||
H.reagents.add_reagent(/datum/reagent/mercury, 3)
|
||||
Appear()
|
||||
manifested = FALSE
|
||||
addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Manifest), 2)
|
||||
|
||||
@@ -240,10 +240,11 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
|
||||
return FALSE
|
||||
if(!W.mob_can_equip(src, null, slot, disable_warning, bypass_equip_delay_self))
|
||||
if(store && istype(src, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = src
|
||||
var/obj/item/storage/backpack/BP = H.back
|
||||
if(BP)
|
||||
return SEND_SIGNAL(BP, COMSIG_TRY_STORAGE_INSERT, W, null, TRUE, TRUE)
|
||||
equip_to_slot(W, SLOT_IN_BACKPACK, FALSE)
|
||||
return TRUE
|
||||
else if(store && !qdel_on_fail)
|
||||
W.forceMove(get_turf(src))
|
||||
|
||||
if(qdel_on_fail)
|
||||
qdel(W)
|
||||
else if(!disable_warning)
|
||||
@@ -524,13 +525,6 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
|
||||
unset_machine()
|
||||
src << browse(null, t1)
|
||||
|
||||
if(href_list["flavor_more"])
|
||||
usr << browse(text("<HTML><HEAD><TITLE>[]</TITLE></HEAD><BODY><TT>[]</TT></BODY></HTML>", name, replacetext(flavor_text, "\n", "<BR>")), text("window=[];size=500x200", name))
|
||||
onclose(usr, "[name]")
|
||||
|
||||
if(href_list["flavor_change"])
|
||||
update_flavor_text()
|
||||
|
||||
if(href_list["refresh"])
|
||||
if(machine && in_range(src, usr))
|
||||
show_inv(machine)
|
||||
|
||||
@@ -129,9 +129,7 @@
|
||||
///Whether the mob is updating glide size when movespeed updates or not
|
||||
var/updating_glide_size = TRUE
|
||||
|
||||
var/flavor_text = ""
|
||||
var/ooc_text = ""
|
||||
var/flavor_text_2 = "" //version of the above that only lasts for the current round.
|
||||
|
||||
///////TYPING INDICATORS///////
|
||||
/// Set to true if we want to show typing indicators.
|
||||
|
||||
@@ -2,31 +2,6 @@
|
||||
////////////////////SUBTLE COMMAND////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
/mob/proc/update_flavor_text()
|
||||
set src in usr
|
||||
if(usr != src)
|
||||
to_chat(usr, "No.")
|
||||
var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. IC only!", "Flavor Text", html_decode(flavor_text), MAX_MESSAGE_LEN, TRUE)
|
||||
|
||||
if(msg)
|
||||
flavor_text = html_encode(msg)
|
||||
|
||||
flavor_text = msg
|
||||
|
||||
/mob/proc/warn_flavor_changed()
|
||||
if(flavor_text && flavor_text != "") // don't spam people that don't use it!
|
||||
to_chat(src, "<h2 class='alert'>OOC Warning:</h2>")
|
||||
to_chat(src, "<span class='alert'>Your flavor text is likely out of date! <a href='?src=[REF(src)];flavor_change=1'>Change</a></span>")
|
||||
|
||||
/mob/proc/print_flavor_text()
|
||||
if(flavor_text && flavor_text != "")
|
||||
// We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown.
|
||||
var/msg = html_decode(replacetext(flavor_text, "\n", " "))
|
||||
if(length_char(msg) <= 40)
|
||||
return "<span class='notice'>[html_encode(msg)]</span>"
|
||||
else
|
||||
return "<span class='notice'>[html_encode(copytext_char(msg, 1, 37))]... <a href='?src=[REF(src)];flavor_more=1'>More...</span></a>"
|
||||
|
||||
/mob/proc/get_top_level_mob()
|
||||
if(istype(src.loc,/mob)&&src.loc!=src)
|
||||
var/mob/M=src.loc
|
||||
|
||||
@@ -171,7 +171,7 @@
|
||||
|
||||
/turf/open/pool/attackby(obj/item/W, mob/living/user)
|
||||
if(istype(W, /obj/item/mop) && filled)
|
||||
W.reagents.add_reagent("water", 5)
|
||||
W.reagents.add_reagent(/datum/reagent/water, 5)
|
||||
to_chat(user, "<span class='notice'>You wet [W] in [src].</span>")
|
||||
playsound(src, 'sound/effects/slosh.ogg', 25, TRUE)
|
||||
else
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
var/grumping = 0 // is the engine currently doing grumpy things
|
||||
var/list/grump_prefix = list("an upsetting", "an unsettling",
|
||||
"a scary", "a loud", "a sassy", "a grouchy", "a grumpy",
|
||||
"an awful", "a horrible", "a despicable", "a pretty rad", "a godawful")
|
||||
var/list/grump_suffix = list("noise", "racket", "ruckus", "sound", "clatter", "fracas", "hubbub")
|
||||
"an awful", "a horrible", "a despicable", "a pretty rad", "a godawful, a wocky")
|
||||
var/list/grump_suffix = list("noise", "racket", "ruckus", "sound", "clatter", "fracas", "hubbub, slush")
|
||||
var/sound_engine1 = 'sound/machines/tractor_running.ogg'
|
||||
var/sound_engine2 = 'sound/machines/engine_highpower.ogg'
|
||||
var/sound_tractorrev = 'sound/machines/tractorrev.ogg'
|
||||
|
||||
@@ -337,70 +337,6 @@
|
||||
construction_time = 600
|
||||
category = list("Durand")
|
||||
|
||||
//H.O.N.K
|
||||
/datum/design/honk_chassis
|
||||
name = "Exosuit Chassis (\"H.O.N.K\")"
|
||||
id = "honk_chassis"
|
||||
build_type = MECHFAB
|
||||
build_path = /obj/item/mecha_parts/chassis/honker
|
||||
materials = list(MAT_METAL=20000)
|
||||
construction_time = 100
|
||||
category = list("H.O.N.K")
|
||||
|
||||
/datum/design/honk_torso
|
||||
name = "Exosuit Torso (\"H.O.N.K\")"
|
||||
id = "honk_torso"
|
||||
build_type = MECHFAB
|
||||
build_path = /obj/item/mecha_parts/part/honker_torso
|
||||
materials = list(MAT_METAL=20000,MAT_GLASS=10000,MAT_BANANIUM=10000)
|
||||
construction_time = 300
|
||||
category = list("H.O.N.K")
|
||||
|
||||
/datum/design/honk_head
|
||||
name = "Exosuit Head (\"H.O.N.K\")"
|
||||
id = "honk_head"
|
||||
build_type = MECHFAB
|
||||
build_path = /obj/item/mecha_parts/part/honker_head
|
||||
materials = list(MAT_METAL=10000,MAT_GLASS=5000,MAT_BANANIUM=5000)
|
||||
construction_time = 200
|
||||
category = list("H.O.N.K")
|
||||
|
||||
/datum/design/honk_left_arm
|
||||
name = "Exosuit Left Arm (\"H.O.N.K\")"
|
||||
id = "honk_left_arm"
|
||||
build_type = MECHFAB
|
||||
build_path = /obj/item/mecha_parts/part/honker_left_arm
|
||||
materials = list(MAT_METAL=15000,MAT_BANANIUM=5000)
|
||||
construction_time = 200
|
||||
category = list("H.O.N.K")
|
||||
|
||||
/datum/design/honk_right_arm
|
||||
name = "Exosuit Right Arm (\"H.O.N.K\")"
|
||||
id = "honk_right_arm"
|
||||
build_type = MECHFAB
|
||||
build_path = /obj/item/mecha_parts/part/honker_right_arm
|
||||
materials = list(MAT_METAL=15000,MAT_BANANIUM=5000)
|
||||
construction_time = 200
|
||||
category = list("H.O.N.K")
|
||||
|
||||
/datum/design/honk_left_leg
|
||||
name = "Exosuit Left Leg (\"H.O.N.K\")"
|
||||
id = "honk_left_leg"
|
||||
build_type = MECHFAB
|
||||
build_path =/obj/item/mecha_parts/part/honker_left_leg
|
||||
materials = list(MAT_METAL=20000,MAT_BANANIUM=5000)
|
||||
construction_time = 200
|
||||
category = list("H.O.N.K")
|
||||
|
||||
/datum/design/honk_right_leg
|
||||
name = "Exosuit Right Leg (\"H.O.N.K\")"
|
||||
id = "honk_right_leg"
|
||||
build_type = MECHFAB
|
||||
build_path = /obj/item/mecha_parts/part/honker_right_leg
|
||||
materials = list(MAT_METAL=20000,MAT_BANANIUM=5000)
|
||||
construction_time = 200
|
||||
category = list("H.O.N.K")
|
||||
|
||||
|
||||
//Phazon
|
||||
/datum/design/phazon_chassis
|
||||
|
||||
@@ -464,16 +464,6 @@
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000)
|
||||
export_price = 5000
|
||||
|
||||
/////////////////////////Clown tech/////////////////////////
|
||||
/datum/techweb_node/clown
|
||||
id = "clown"
|
||||
display_name = "Clown Technology"
|
||||
description = "Honk?!"
|
||||
prereq_ids = list("base")
|
||||
design_ids = list("air_horn", "honker_main", "honker_peri", "honker_targ", "honk_chassis", "honk_head", "honk_torso", "honk_left_arm", "honk_right_arm",
|
||||
"honk_left_leg", "honk_right_leg", "mech_banana_mortar", "mech_mousetrap_mortar", "mech_honker", "mech_punching_face", "implant_trombone", "borg_transform_clown")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
export_price = 5000
|
||||
|
||||
////////////////////////Computer tech////////////////////////
|
||||
/datum/techweb_node/comptech
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//Xenobio control console
|
||||
/mob/camera/aiEye/remote/xenobio
|
||||
visible_icon = 1
|
||||
visible_icon = TRUE
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "camera_target"
|
||||
var/allowed_area = null
|
||||
@@ -22,15 +22,11 @@
|
||||
desc = "A computer used for remotely handling slimes."
|
||||
networks = list("ss13")
|
||||
circuit = /obj/item/circuitboard/computer/xenobiology
|
||||
var/datum/action/innate/slime_place/slime_place_action
|
||||
var/datum/action/innate/slime_pick_up/slime_up_action
|
||||
var/datum/action/innate/feed_slime/feed_slime_action
|
||||
var/datum/action/innate/monkey_recycle/monkey_recycle_action
|
||||
var/datum/action/innate/slime_scan/scan_action
|
||||
var/datum/action/innate/feed_potion/potion_action
|
||||
var/datum/action/innate/hotkey_help/hotkey_help
|
||||
|
||||
var/datum/component/redirect/listener
|
||||
|
||||
var/obj/machinery/monkey_recycler/connected_recycler
|
||||
var/list/stored_slimes
|
||||
var/obj/item/slimepotion/slime/current_potion
|
||||
var/max_slimes = 5
|
||||
@@ -43,14 +39,13 @@
|
||||
|
||||
/obj/machinery/computer/camera_advanced/xenobio/Initialize()
|
||||
. = ..()
|
||||
slime_place_action = new
|
||||
slime_up_action = new
|
||||
feed_slime_action = new
|
||||
monkey_recycle_action = new
|
||||
scan_action = new
|
||||
potion_action = new
|
||||
hotkey_help = new
|
||||
stored_slimes = list()
|
||||
listener = AddComponent(/datum/component/redirect, list(COMSIG_ATOM_CONTENTS_DEL = CALLBACK(src, .proc/on_contents_del)))
|
||||
for(var/obj/machinery/monkey_recycler/recycler in GLOB.monkey_recyclers)
|
||||
if(get_area(src) == get_area(recycler))
|
||||
connected_recycler = recycler
|
||||
connected_recycler.connected += src
|
||||
|
||||
/obj/machinery/computer/camera_advanced/xenobio/Destroy()
|
||||
stored_slimes = null
|
||||
@@ -61,45 +56,56 @@
|
||||
S.forceMove(drop_location())
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/camera_advanced/xenobio/examine(mob/user)
|
||||
. = ..()
|
||||
var/thing = "It has "
|
||||
if((upgradetier & XENOBIO_UPGRADE_SLIMEADV))
|
||||
thing += "an advanced slime upgrade disk "
|
||||
if((upgradetier & XENOBIO_UPGRADE_MONKEYS))
|
||||
thing += "and a monkey upgrade disk "
|
||||
else if((upgradetier & XENOBIO_UPGRADE_SLIMEBASIC))
|
||||
thing += "a basic slime upgrade disk "
|
||||
if((upgradetier & XENOBIO_UPGRADE_MONKEYS))
|
||||
thing += "and a monkey upgrade disk "
|
||||
else if((upgradetier & XENOBIO_UPGRADE_MONKEYS))
|
||||
thing += "a monkey upgrade disk "
|
||||
else
|
||||
thing += "no upgrades installed."
|
||||
. += thing
|
||||
return
|
||||
thing += "installed."
|
||||
. += thing
|
||||
|
||||
/obj/machinery/computer/camera_advanced/xenobio/CreateEye()
|
||||
eyeobj = new /mob/camera/aiEye/remote/xenobio(get_turf(src))
|
||||
eyeobj.origin = src
|
||||
eyeobj.visible_icon = 1
|
||||
eyeobj.visible_icon = TRUE
|
||||
eyeobj.icon = 'icons/obj/abductor.dmi'
|
||||
eyeobj.icon_state = "camera_target"
|
||||
|
||||
/obj/machinery/computer/camera_advanced/xenobio/GrantActions(mob/living/user)
|
||||
..()
|
||||
|
||||
if(slime_up_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC
|
||||
slime_up_action.target = src
|
||||
slime_up_action.Grant(user)
|
||||
actions += slime_up_action
|
||||
if(hotkey_help)
|
||||
hotkey_help.target = src
|
||||
hotkey_help.Grant(user)
|
||||
actions += hotkey_help
|
||||
|
||||
if(slime_place_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC
|
||||
slime_place_action.target = src
|
||||
slime_place_action.Grant(user)
|
||||
actions += slime_place_action
|
||||
RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL, .proc/XenoSlimeClickCtrl)
|
||||
RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT, .proc/XenoSlimeClickAlt)
|
||||
RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT, .proc/XenoSlimeClickShift)
|
||||
RegisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT, .proc/XenoTurfClickShift)
|
||||
RegisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL, .proc/XenoTurfClickCtrl)
|
||||
RegisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL, .proc/XenoMonkeyClickCtrl)
|
||||
|
||||
if(feed_slime_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
|
||||
feed_slime_action.target = src
|
||||
feed_slime_action.Grant(user)
|
||||
actions += feed_slime_action
|
||||
|
||||
if(monkey_recycle_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
|
||||
monkey_recycle_action.target = src
|
||||
monkey_recycle_action.Grant(user)
|
||||
actions += monkey_recycle_action
|
||||
|
||||
if(scan_action)
|
||||
scan_action.target = src
|
||||
scan_action.Grant(user)
|
||||
actions += scan_action
|
||||
|
||||
if(potion_action && (upgradetier & XENOBIO_UPGRADE_SLIMEADV)) // CIT CHANGE - makes giving slimes potions via console require XENOBIO_UPGRADE_SLIMEADV
|
||||
potion_action.target = src
|
||||
potion_action.Grant(user)
|
||||
actions += potion_action
|
||||
/obj/machinery/computer/camera_advanced/xenobio/remove_eye_control(mob/living/user)
|
||||
UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL)
|
||||
UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT)
|
||||
UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT)
|
||||
UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT)
|
||||
UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL)
|
||||
UnregisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL)
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/camera_advanced/xenobio/proc/on_contents_del(atom/deleted)
|
||||
if(current_potion == deleted)
|
||||
@@ -134,135 +140,161 @@
|
||||
current_potion = O
|
||||
to_chat(user, "<span class='notice'>You load [O] in the console's potion slot[replaced ? ", replacing the one that was there before" : ""].</span>")
|
||||
return
|
||||
else if(istype(O, /obj/item/multitool))
|
||||
var/obj/item/multitool/M = O
|
||||
if(istype(M.buffer))
|
||||
to_chat(user, "<span class='notice'>You link [src] with [M.buffer] in [M] buffer.</span>")
|
||||
connected_recycler = M.buffer
|
||||
connected_recycler += src
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[M] has no buffer.</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
/datum/action/innate/slime_place
|
||||
name = "Place Slimes"
|
||||
/datum/action/innate/hotkey_help
|
||||
name = "Hotkey Help"
|
||||
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
|
||||
button_icon_state = "slime_down"
|
||||
button_icon_state = "hotkey_help"
|
||||
|
||||
/datum/action/innate/slime_place/Activate()
|
||||
/datum/action/innate/hotkey_help/Activate()
|
||||
if(!target || !isliving(owner))
|
||||
return
|
||||
var/mob/living/C = owner
|
||||
var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
|
||||
var/obj/machinery/computer/camera_advanced/xenobio/X = target
|
||||
to_chat(owner, "<b>Click shortcuts:</b>")
|
||||
to_chat(owner, "Shift-click a slime to pick it up, or the floor to drop all held slimes.")
|
||||
to_chat(owner, "Ctrl-click a slime to scan it.")
|
||||
to_chat(owner, "Alt-click a slime to feed it a potion.")
|
||||
to_chat(owner, "Ctrl-click on a dead monkey to recycle it, or the floor to place a new monkey.")
|
||||
|
||||
if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
|
||||
for(var/mob/living/simple_animal/slime/S in X.stored_slimes)
|
||||
S.forceMove(remote_eye.loc)
|
||||
//
|
||||
// Alternate clicks for slime, monkey and open turf if using a xenobio console
|
||||
|
||||
//Picks up slime
|
||||
/mob/living/simple_animal/slime/ShiftClick(mob/user)
|
||||
SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_SHIFT, src)
|
||||
..()
|
||||
|
||||
//Place slimes
|
||||
/turf/open/ShiftClick(mob/user)
|
||||
SEND_SIGNAL(user, COMSIG_XENO_TURF_CLICK_SHIFT, src)
|
||||
..()
|
||||
|
||||
//Place monkey
|
||||
/turf/open/CtrlClick(mob/user)
|
||||
SEND_SIGNAL(user, COMSIG_XENO_TURF_CLICK_CTRL, src)
|
||||
..()
|
||||
|
||||
//Pick up monkey
|
||||
/mob/living/carbon/monkey/CtrlClick(mob/user)
|
||||
SEND_SIGNAL(user, COMSIG_XENO_MONKEY_CLICK_CTRL, src)
|
||||
..()
|
||||
|
||||
// Scans slime
|
||||
/mob/living/simple_animal/slime/CtrlClick(mob/user)
|
||||
SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_CTRL, src)
|
||||
..()
|
||||
|
||||
//Feeds a potion to slime
|
||||
/mob/living/simple_animal/slime/AltClick(mob/user)
|
||||
SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_ALT, src)
|
||||
..()
|
||||
|
||||
//Picks up slime
|
||||
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickShift(mob/living/user, mob/living/simple_animal/slime/S)
|
||||
if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC))
|
||||
return
|
||||
if(!GLOB.cameranet.checkTurfVis(S.loc))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
return
|
||||
var/area/mobarea = get_area(S.loc)
|
||||
var/mob/camera/aiEye/remote/xenobio/X = eyeobj
|
||||
if(mobarea.name == X.allowed_area || mobarea.xenobiology_compatible)
|
||||
if(stored_slimes.len >= max_slimes)
|
||||
to_chat(user, "<span class='warning'>Slime storage is full.</span>")
|
||||
return
|
||||
if(S.ckey)
|
||||
to_chat(user, "<span class='warning'>The slime wiggled free!</span>")
|
||||
return
|
||||
if(S.buckled)
|
||||
S.Feedstop(silent = TRUE)
|
||||
S.visible_message("[S] vanishes in a flash of light!")
|
||||
S.forceMove(src)
|
||||
stored_slimes += S
|
||||
|
||||
//Place slimes
|
||||
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickShift(mob/living/user, turf/open/T)
|
||||
if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC))
|
||||
return
|
||||
if(!GLOB.cameranet.checkTurfVis(T))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
return
|
||||
var/area/turfarea = get_area(T)
|
||||
var/mob/camera/aiEye/remote/xenobio/X = eyeobj
|
||||
if(turfarea.name == X.allowed_area || turfarea.xenobiology_compatible)
|
||||
for(var/mob/living/simple_animal/slime/S in stored_slimes)
|
||||
S.forceMove(T)
|
||||
S.visible_message("[S] warps in!")
|
||||
X.stored_slimes -= S
|
||||
else
|
||||
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
|
||||
stored_slimes -= S
|
||||
|
||||
/datum/action/innate/slime_pick_up
|
||||
name = "Pick up Slime"
|
||||
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
|
||||
button_icon_state = "slime_up"
|
||||
|
||||
/datum/action/innate/slime_pick_up/Activate()
|
||||
if(!target || !isliving(owner))
|
||||
//Place monkey
|
||||
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickCtrl(mob/living/user, turf/open/T)
|
||||
if(!(upgradetier & XENOBIO_UPGRADE_MONKEYS))
|
||||
return
|
||||
var/mob/living/C = owner
|
||||
var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
|
||||
var/obj/machinery/computer/camera_advanced/xenobio/X = target
|
||||
|
||||
if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
|
||||
for(var/mob/living/simple_animal/slime/S in remote_eye.loc)
|
||||
if(X.stored_slimes.len >= X.max_slimes)
|
||||
break
|
||||
if(!S.ckey)
|
||||
if(S.buckled)
|
||||
S.Feedstop(silent = TRUE)
|
||||
S.visible_message("[S] vanishes in a flash of light!")
|
||||
S.forceMove(X)
|
||||
X.stored_slimes += S
|
||||
else
|
||||
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
|
||||
/datum/action/innate/feed_slime
|
||||
name = "Feed Slimes"
|
||||
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
|
||||
button_icon_state = "monkey_down"
|
||||
|
||||
/datum/action/innate/feed_slime/Activate()
|
||||
if(!target || !isliving(owner))
|
||||
if(!GLOB.cameranet.checkTurfVis(T))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
return
|
||||
var/mob/living/C = owner
|
||||
var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
|
||||
var/obj/machinery/computer/camera_advanced/xenobio/X = target
|
||||
var/area/turfarea = get_area(T)
|
||||
var/mob/camera/aiEye/remote/xenobio/X = eyeobj
|
||||
if(turfarea.name == X.allowed_area || turfarea.xenobiology_compatible)
|
||||
if(monkeys >= 1)
|
||||
var/mob/living/carbon/monkey/food = new/mob/living/carbon/monkey(T, TRUE, user)
|
||||
if(!QDELETED(food))
|
||||
food.LAssailant = user
|
||||
monkeys = round(monkeys-1, 0.1)
|
||||
to_chat(user, "[src] now has [monkeys] monkeys stored.")
|
||||
|
||||
if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
|
||||
if(X.monkeys >= 1)
|
||||
var/mob/living/carbon/monkey/food = new /mob/living/carbon/monkey(remote_eye.loc, TRUE, owner)
|
||||
if (!QDELETED(food))
|
||||
food.LAssailant = C
|
||||
X.monkeys --
|
||||
to_chat(owner, "[X] now has [X.monkeys] monkeys left.")
|
||||
else
|
||||
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
|
||||
/datum/action/innate/monkey_recycle
|
||||
name = "Recycle Monkeys"
|
||||
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
|
||||
button_icon_state = "monkey_up"
|
||||
|
||||
/datum/action/innate/monkey_recycle/Activate()
|
||||
if(!target || !isliving(owner))
|
||||
//Pick up monkey
|
||||
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoMonkeyClickCtrl(mob/living/user, mob/living/carbon/monkey/M)
|
||||
if(!(upgradetier & XENOBIO_UPGRADE_MONKEYS))
|
||||
return
|
||||
var/mob/living/C = owner
|
||||
var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
|
||||
var/obj/machinery/computer/camera_advanced/xenobio/X = target
|
||||
|
||||
if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
|
||||
for(var/mob/living/carbon/monkey/M in remote_eye.loc)
|
||||
if(M.stat)
|
||||
M.visible_message("[M] vanishes as [M.p_theyre()] reclaimed for recycling!")
|
||||
X.monkeys = round(X.monkeys + 0.2,0.1)
|
||||
qdel(M)
|
||||
else
|
||||
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
/datum/action/innate/slime_scan
|
||||
name = "Scan Slime"
|
||||
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
|
||||
button_icon_state = "slime_scan"
|
||||
|
||||
/datum/action/innate/slime_scan/Activate()
|
||||
if(!target || !isliving(owner))
|
||||
if(!connected_recycler)
|
||||
to_chat(user, "<span class='notice'>There is no connected monkey recycler. You can connect one with a multitool.</span>")
|
||||
return
|
||||
var/mob/living/C = owner
|
||||
var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
|
||||
|
||||
if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
|
||||
for(var/mob/living/simple_animal/slime/S in remote_eye.loc)
|
||||
slime_scan(S, C)
|
||||
else
|
||||
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
/datum/action/innate/feed_potion
|
||||
name = "Apply Potion"
|
||||
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
|
||||
button_icon_state = "slime_potion"
|
||||
|
||||
/datum/action/innate/feed_potion/Activate()
|
||||
if(!target || !isliving(owner))
|
||||
if(!GLOB.cameranet.checkTurfVis(M.loc))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
return
|
||||
var/area/mobarea = get_area(M.loc)
|
||||
var/mob/camera/aiEye/remote/xenobio/X = eyeobj
|
||||
if(mobarea.name == X.allowed_area || mobarea.xenobiology_compatible)
|
||||
if(!M.stat)
|
||||
return
|
||||
M.visible_message("[M] vanishes as [M.p_theyre()] reclaimed for recycling!")
|
||||
connected_recycler.use_power(500)
|
||||
monkeys += connected_recycler.cube_production
|
||||
to_chat(user, "[src] now has [monkeys] monkeys available.")
|
||||
qdel(M)
|
||||
|
||||
var/mob/living/C = owner
|
||||
var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
|
||||
var/obj/machinery/computer/camera_advanced/xenobio/X = target
|
||||
|
||||
if(QDELETED(X.current_potion))
|
||||
to_chat(owner, "<span class='notice'>No potion loaded.</span>")
|
||||
// Scans slime
|
||||
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickCtrl(mob/living/user, mob/living/simple_animal/slime/S)
|
||||
if(!GLOB.cameranet.checkTurfVis(S.loc))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
return
|
||||
var/area/mobarea = get_area(S.loc)
|
||||
var/mob/camera/aiEye/remote/xenobio/X = eyeobj
|
||||
if(mobarea.name == X.allowed_area || mobarea.xenobiology_compatible)
|
||||
slime_scan(S, user)
|
||||
|
||||
if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
|
||||
for(var/mob/living/simple_animal/slime/S in remote_eye.loc)
|
||||
X.current_potion.attack(S, C)
|
||||
break
|
||||
else
|
||||
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
|
||||
//Feeds a potion to slime
|
||||
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickAlt(mob/living/user, mob/living/simple_animal/slime/S)
|
||||
if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC))
|
||||
return
|
||||
if(!GLOB.cameranet.checkTurfVis(S.loc))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
return
|
||||
var/area/mobarea = get_area(S.loc)
|
||||
if(QDELETED(current_potion))
|
||||
to_chat(user, "<span class='warning'>No potion loaded.</span>")
|
||||
return
|
||||
var/mob/camera/aiEye/remote/xenobio/X = eyeobj
|
||||
if(mobarea.name == X.allowed_area || mobarea.xenobiology_compatible)
|
||||
current_potion.attack(S, user)
|
||||
|
||||
@@ -11,4 +11,9 @@
|
||||
/datum/mood_event/kiss
|
||||
description = "<span class='nicegreen'>Someone kissed me, I feel happy!</span>\n"
|
||||
mood_change = 2
|
||||
timeout = 3 MINUTES
|
||||
timeout = 3 MINUTES
|
||||
|
||||
/datum/mood_event/deathsaw
|
||||
description = "<span class='boldwarning'>I saw someone die!</span>\n"
|
||||
mood_change = -8
|
||||
timeout = 20 MINUTES //takes a long time to get over
|
||||
@@ -47,3 +47,38 @@
|
||||
M.nutrition = rand(NUTRITION_LEVEL_FAT + NUTRITION_LEVEL_START_MIN, NUTRITION_LEVEL_FAT + NUTRITION_LEVEL_START_MAX)
|
||||
M.overeatduration = 100
|
||||
ADD_TRAIT(M, TRAIT_FAT, OBESITY)
|
||||
|
||||
/datum/quirk/virile
|
||||
name = "Virile"
|
||||
desc = "Either through higher quality sperms, more of them, or just being more horny, your impregnation chance will increase by 20-30%."
|
||||
value = 0
|
||||
medical_record_text = "Patient has a higher sperm count."
|
||||
mob_trait = TRAIT_VIRILE
|
||||
gain_text = "<span class='notice'>You feel more potent."
|
||||
lose_text = "<span class='notice'>You feel less potent."
|
||||
var/ichange = 0
|
||||
|
||||
/datum/quirk/virile/add()
|
||||
ichange = rand(20,30)
|
||||
quirk_holder.impregchance += ichange
|
||||
|
||||
/datum/quirk/virile/remove()
|
||||
if(quirk_holder)
|
||||
quirk_holder.impregchance -= ichange
|
||||
|
||||
|
||||
/datum/quirk/macrophile
|
||||
name = "Macrophile"
|
||||
desc = "You are attracted to larger people, and being stepped on by them."
|
||||
value = 0
|
||||
mob_trait = TRAIT_MACROPHILE
|
||||
gain_text = "<span class='notice'>You feel attracted to people larger than you."
|
||||
lose_text = "<span class='notice'>You feel less attracted to people larger than you."
|
||||
|
||||
/datum/quirk/microphile
|
||||
name = "Microphile"
|
||||
desc = "You are attracted to smaller people, and stepping on them."
|
||||
value = 0
|
||||
mob_trait = TRAIT_MICROPHILE
|
||||
gain_text = "<span class='notice'>You feel attracted to people smaller than you."
|
||||
lose_text = "<span class='notice'>You feel less attracted to people smaller than you."
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
//ported from virgo
|
||||
|
||||
/obj/structure/railing
|
||||
name = "railing"
|
||||
desc = "A railing to stop people from falling"
|
||||
|
||||
icon = 'hyperstation/icons/obj/railings.dmi'
|
||||
var/icon_modifier = "grey_"
|
||||
icon_state = "grey_railing0"
|
||||
|
||||
density = TRUE
|
||||
layer = 4
|
||||
anchored = TRUE
|
||||
flags_1 = ON_BORDER_1
|
||||
max_integrity = 250
|
||||
var/heat_resistance = 800
|
||||
|
||||
resistance_flags = ACID_PROOF
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
|
||||
CanAtmosPass = ATMOS_PASS_PROC
|
||||
var/real_explosion_block //ignore this, just use explosion_block
|
||||
var/breaksound = "shatter"
|
||||
var/hitsound = 'sound/effects/Glasshit.ogg'
|
||||
rad_insulation = RAD_VERY_LIGHT_INSULATION
|
||||
rad_flags = RAD_PROTECT_CONTENTS
|
||||
var/check = 0
|
||||
|
||||
|
||||
/obj/structure/railing/CanPass(atom/movable/mover, turf/target)
|
||||
if(istype(mover) && (mover.pass_flags & PASSGLASS))
|
||||
return 1
|
||||
if(get_dir(loc, target) == dir)
|
||||
return !density
|
||||
return 1
|
||||
|
||||
/obj/structure/railing/CheckExit(atom/movable/O, turf/target)
|
||||
if(istype(O) && (O.pass_flags & PASSGLASS))
|
||||
return 1
|
||||
if(get_dir(O.loc, target) == dir)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/structure/railing/Initialize()
|
||||
. = ..()
|
||||
if(src.anchored)
|
||||
update_icon(0)
|
||||
|
||||
/obj/structure/railing/proc/NeighborsCheck(var/UpdateNeighbors = 1)
|
||||
check = 0
|
||||
//if (!anchored) return
|
||||
var/Rturn = turn(src.dir, -90)
|
||||
var/Lturn = turn(src.dir, 90)
|
||||
|
||||
for(var/obj/structure/railing/R in src.loc)
|
||||
if ((R.dir == Lturn) && R.anchored)
|
||||
check |= 32
|
||||
if (UpdateNeighbors)
|
||||
R.update_icon(0)
|
||||
if ((R.dir == Rturn) && R.anchored)
|
||||
check |= 2
|
||||
if (UpdateNeighbors)
|
||||
R.update_icon(0)
|
||||
|
||||
for (var/obj/structure/railing/R in get_step(src, Lturn))
|
||||
if ((R.dir == src.dir) && R.anchored)
|
||||
check |= 16
|
||||
if (UpdateNeighbors)
|
||||
R.update_icon(0)
|
||||
for (var/obj/structure/railing/R in get_step(src, Rturn))
|
||||
if ((R.dir == src.dir) && R.anchored)
|
||||
check |= 1
|
||||
if (UpdateNeighbors)
|
||||
R.update_icon(0)
|
||||
|
||||
for (var/obj/structure/railing/R in get_step(src, (Lturn + src.dir)))
|
||||
if ((R.dir == Rturn) && R.anchored)
|
||||
check |= 64
|
||||
if (UpdateNeighbors)
|
||||
R.update_icon(0)
|
||||
for (var/obj/structure/railing/R in get_step(src, (Rturn + src.dir)))
|
||||
if ((R.dir == Lturn) && R.anchored)
|
||||
check |= 4
|
||||
if (UpdateNeighbors)
|
||||
R.update_icon(0)
|
||||
|
||||
/obj/structure/railing/update_icon(var/UpdateNeighgors = 1)
|
||||
NeighborsCheck(UpdateNeighgors)
|
||||
overlays.Cut()
|
||||
if (!check || !anchored)//|| !anchored
|
||||
icon_state = "[icon_modifier]railing0"
|
||||
else
|
||||
icon_state = "[icon_modifier]railing1"
|
||||
if (check & 32)
|
||||
overlays += image ('hyperstation/icons/obj/railings.dmi', src, "[icon_modifier]corneroverlay")
|
||||
if ((check & 16) || !(check & 32) || (check & 64))
|
||||
overlays += image ('hyperstation/icons/obj/railings.dmi', src, "[icon_modifier]frontoverlay_l")
|
||||
if (!(check & 2) || (check & 1) || (check & 4))
|
||||
overlays += image ('hyperstation/icons/obj/railings.dmi', src, "[icon_modifier]frontoverlay_r")
|
||||
if(check & 4)
|
||||
switch (src.dir)
|
||||
if (NORTH)
|
||||
overlays += image ('hyperstation/icons/obj/railings.dmi', src, "[icon_modifier]mcorneroverlay", pixel_x = 32)
|
||||
if (SOUTH)
|
||||
overlays += image ('hyperstation/icons/obj/railings.dmi', src, "[icon_modifier]mcorneroverlay", pixel_x = -32)
|
||||
if (EAST)
|
||||
overlays += image ('hyperstation/icons/obj/railings.dmi', src, "[icon_modifier]mcorneroverlay", pixel_y = -32)
|
||||
if (WEST)
|
||||
overlays += image ('hyperstation/icons/obj/railings.dmi', src, "[icon_modifier]mcorneroverlay", pixel_y = 32)
|
||||
@@ -0,0 +1,16 @@
|
||||
//not the most effient bot in the world, but it does its job.
|
||||
|
||||
/client/proc/discordmessage(input as message)
|
||||
set category = "Special Verbs"
|
||||
set name = "Hyperbot Message"
|
||||
set desc = "Makes the local bot say something in general chat on discord."
|
||||
|
||||
if(input)
|
||||
world.hypermessage(input)
|
||||
message_admins("[key_name_admin(usr)] has made the Hyperbot post '[input]' in General.")
|
||||
|
||||
/world/proc/hypermessage(message)
|
||||
fdel("Hyperbot/message.txt") //cleaning up old message
|
||||
if(message)
|
||||
var botmsg = "![message]"
|
||||
text2file(botmsg,"Hyperbot/message.txt") //the bot on local reads a new text file and sends it to the discord.
|
||||
@@ -0,0 +1,56 @@
|
||||
/mob/living/dancercaptain
|
||||
name = "Captain Beats"
|
||||
desc = "A captain cursed to dance for all eternity!"
|
||||
icon = 'hyperstation/icons/mobs/dancer/captain.dmi'
|
||||
icon_state = "idle"
|
||||
var/danceaction = 1
|
||||
var/lastaction = 0 //when the last action was!
|
||||
var/actiontime = 4
|
||||
var/list/dancefloor_turfs
|
||||
var/list/dancefloor_turfs_types
|
||||
var/dancefloor_exists = FALSE
|
||||
|
||||
/mob/living/dancercaptain/Move(atom/newloc, direct)
|
||||
|
||||
if(!danceaction)
|
||||
if(!(world.time > lastaction))
|
||||
return // no move for you!
|
||||
|
||||
animate(src, pixel_x, pixel_y = pixel_y + 10, time = 0.7, 0)
|
||||
. = ..()
|
||||
danceaction = 0 //you did your move
|
||||
lastaction = world.time+actiontime //next action time
|
||||
sleep(1)
|
||||
animate(src, pixel_x, pixel_y = pixel_y - 10, time = 0.7, 0)
|
||||
sleep(1)
|
||||
|
||||
LAZYINITLIST(dancefloor_turfs)
|
||||
LAZYINITLIST(dancefloor_turfs_types)
|
||||
|
||||
if(dancefloor_exists) //remove the old one!
|
||||
dancefloor_exists = FALSE
|
||||
for(var/i in 1 to dancefloor_turfs.len)
|
||||
var/turf/T = dancefloor_turfs[i]
|
||||
T.ChangeTurf(dancefloor_turfs_types[i])
|
||||
var/list/funky_turfs = RANGE_TURFS(2, src)
|
||||
|
||||
|
||||
dancefloor_exists = TRUE
|
||||
var/i = 1
|
||||
dancefloor_turfs.len = funky_turfs.len
|
||||
dancefloor_turfs_types.len = funky_turfs.len
|
||||
for(var/t in funky_turfs)
|
||||
if(!(istype(t, /turf/closed))) //dont change walls
|
||||
var/turf/T = t
|
||||
dancefloor_turfs[i] = T
|
||||
dancefloor_turfs_types[i] = T.type
|
||||
T.ChangeTurf((i % 2 == 0) ? /turf/open/floor/light/colour_cycle/dancefloor_a : /turf/open/floor/light/colour_cycle/dancefloor_b)
|
||||
i++
|
||||
|
||||
|
||||
/mob/living/dancercaptain/Initialize()
|
||||
. = ..()
|
||||
|
||||
lastaction = round(world.time) //round to the nearest second! to keep in beat!
|
||||
|
||||
/mob/living/dancercaptain/proc/mtimer()
|
||||
@@ -32,10 +32,14 @@
|
||||
if(user.pulling)
|
||||
dat += "<a href='byond://?src=[REF(src)];kiss=1'>Kiss [user.pulling]</A>"
|
||||
dat += "(Kiss a partner, or object.)<BR>"
|
||||
else
|
||||
dat += "<span class='linkOff'>Kiss</span></A>"
|
||||
dat += "(Requires a partner)<BR>"
|
||||
|
||||
|
||||
if(user.pulling)
|
||||
dat += "<a href='byond://?src=[REF(src)];climaxover=1'>Climax over [user.pulling]</A>" //you can cum on objects if you really want...
|
||||
dat += "(Orgasm over a person or object.)<BR>"
|
||||
|
||||
if(isliving(user.pulling))
|
||||
if(iscarbon(user.pulling))
|
||||
dat += "<a href='byond://?src=[REF(src)];climaxwith=1'>Climax with [user.pulling]</A>"
|
||||
@@ -43,8 +47,13 @@
|
||||
|
||||
var/mob/living/carbon/human/H = user.pulling
|
||||
if(H.breedable && P && H)
|
||||
dat += "<a href='byond://?src=[REF(src)];impreg=1'>Impregnate [user.pulling]</A>"
|
||||
dat += "(Climax inside another person, knocking them up.)<BR>"
|
||||
dat += "<a href='byond://?src=[REF(src)];impreg=1'>Impregnate [U.pulling] ([clamp(U.impregchance,0,100)]%)</A>"
|
||||
dat += "(Climax inside another person, and attempt to knock them up.)<BR>"
|
||||
else
|
||||
dat += "<span class='linkOff'>Climax over</span></A>"
|
||||
dat += "(Requires a partner)<BR>"
|
||||
dat += "<span class='linkOff'>Climax with</span></A>"
|
||||
dat += "(Requires a partner)<BR>"
|
||||
|
||||
//old code needs to be cleaned
|
||||
if(P)
|
||||
@@ -308,8 +317,6 @@ obj/screen/arousal/proc/kiss()
|
||||
src.visible_message("<span class='notice'>[src] is about to kiss [L]!</span>", \
|
||||
"<span class='notice'>You're attempting to kiss [L]!</span>", \
|
||||
"<span class='notice'>You're attempting to kiss with something!</span>")
|
||||
if(!do_mob(src, L, 2 SECONDS)) //I think two seconds is enough time to pull away if its unwanted.
|
||||
return
|
||||
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "kissed", /datum/mood_event/kiss) //how cute, affection is nice.
|
||||
//Well done you kissed it/them!
|
||||
src.visible_message("<span class='notice'>[src] kisses [L]!</span>", \
|
||||
|
||||
@@ -7,6 +7,5 @@
|
||||
metabolization_rate = 1 * REAGENTS_METABOLISM
|
||||
taste_description = "sweetness"
|
||||
|
||||
/datum/reagent/consumable/alienhoney/on_mob_life(mob/living/carbon/M) //can still be eaten/drank, but will provide no benefits like normal honey. Still good for a food sauce.
|
||||
M.reagents.add_reagent(/datum/reagent/consumable/sugar,2) //metabolisms in the system as sugar.
|
||||
/datum/reagent/consumable/alienhoney/on_mob_life(mob/living/carbon/M)
|
||||
..()
|
||||
@@ -44,7 +44,7 @@ mob/living/get_effective_size()
|
||||
if(size_multiplier == previous_size)
|
||||
return 1
|
||||
src.update_transform() //WORK DAMN YOU
|
||||
src.update_mobsize()
|
||||
src.update_mobsize()
|
||||
//Going to change the health and speed values too
|
||||
src.remove_movespeed_modifier(MOVESPEED_ID_SIZE)
|
||||
src.add_movespeed_modifier(MOVESPEED_ID_SIZE, multiplicative_slowdown = (abs(size_multiplier - 1) * 0.8 ))
|
||||
@@ -67,7 +67,7 @@ mob/living/get_effective_size()
|
||||
|
||||
if(tmob.pulledby == H)
|
||||
return 0
|
||||
|
||||
|
||||
//Micro is on a table.
|
||||
var/turf/steppyspot = tmob.loc
|
||||
for(var/thing in steppyspot.contents)
|
||||
@@ -91,6 +91,7 @@ mob/living/get_effective_size()
|
||||
tmob.visible_message("<span class='notice'>[src] carefully slithers around [tmob].</span>", "<span class='notice'>[src]'s huge tail slithers besides you.</span>")
|
||||
else
|
||||
tmob.visible_message("<span class='notice'>[src] carefully steps over [tmob].</span>", "<span class='notice'>[src] steps over you carefully.</span>")
|
||||
|
||||
return 1
|
||||
|
||||
//Smaller person stepping under a larger person
|
||||
@@ -133,7 +134,20 @@ mob/living/get_effective_size()
|
||||
tmob.visible_message("<span class='danger'>[src] carefully rolls their tail over [tmob]!</span>", "<span class='danger'>[src]'s huge tail rolls over you!</span>")
|
||||
else
|
||||
tmob.visible_message("<span class='danger'>[src] carefully steps on [tmob]!</span>", "<span class='danger'>[src] steps onto you with force!</span>")
|
||||
return 1
|
||||
|
||||
//horny traits
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_MICROPHILE))
|
||||
src.adjustArousalLoss(8)
|
||||
if (src.getArousalLoss() >= 100 && ishuman(tmob) && tmob.has_dna())
|
||||
src.mob_climax(forced_climax=TRUE)
|
||||
|
||||
if(HAS_TRAIT(tmob, TRAIT_MACROPHILE))
|
||||
tmob.adjustArousalLoss(10)
|
||||
if (tmob.getArousalLoss() >= 100 && ishuman(tmob) && tmob.has_dna())
|
||||
tmob.mob_climax(forced_climax=TRUE)
|
||||
|
||||
return 1
|
||||
|
||||
if(H.a_intent == "harm" && H.canmove && !H.buckled)
|
||||
now_pushing = 0
|
||||
@@ -149,6 +163,19 @@ mob/living/get_effective_size()
|
||||
tmob.visible_message("<span class='danger'>[src] mows down [tmob] under their tail!</span>", "<span class='userdanger'>[src] plows their tail over you mercilessly!</span>")
|
||||
else
|
||||
tmob.visible_message("<span class='danger'>[src] slams their foot down on [tmob], crushing them!</span>", "<span class='userdanger'>[src] crushes you under their foot!</span>")
|
||||
|
||||
//horny traits
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_MICROPHILE))
|
||||
src.adjustArousalLoss((get_effective_size()/tmob.get_effective_size()*3))
|
||||
if (src.getArousalLoss() >= 100 && ishuman(tmob) && tmob.has_dna())
|
||||
src.mob_climax(forced_climax=TRUE)
|
||||
|
||||
if(HAS_TRAIT(tmob, TRAIT_MACROPHILE))
|
||||
tmob.adjustArousalLoss((get_effective_size()/tmob.get_effective_size()*3))
|
||||
if (tmob.getArousalLoss() >= 100 && ishuman(tmob) && tmob.has_dna())
|
||||
tmob.mob_climax(forced_climax=TRUE)
|
||||
|
||||
return 1
|
||||
|
||||
if(H.a_intent == "grab" && H.canmove && !H.buckled)
|
||||
@@ -215,7 +242,7 @@ mob/living/get_effective_size()
|
||||
mob_size = 2 //the default human size
|
||||
if(size_multiplier > 1)
|
||||
mob_size = 3
|
||||
|
||||
|
||||
//Proc for instantly grabbing valid size difference. Code optimizations soon(TM)
|
||||
/*
|
||||
/mob/living/proc/sizeinteractioncheck(var/mob/living/tmob)
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
|
||||
if (C.getArousalLoss() >= 100 && ishuman(C) && C.has_dna())
|
||||
var/mob/living/carbon/human/O = C
|
||||
O.mob_climax_partner(P, M, TRUE, FALSE, FALSE, TRUE) //climax with their partner remotely!
|
||||
O.mob_climax_partner(P, M, FALSE, FALSE, FALSE, TRUE) //climax with their partner remotely!
|
||||
return
|
||||
..()
|
||||
|
||||
@@ -189,6 +189,9 @@
|
||||
if(H.dna.species.name == "Slimeperson") // slime nerd
|
||||
sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_slime")
|
||||
|
||||
if(H.dna.species.name == "Avian") // bird nerd
|
||||
sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_avian")
|
||||
|
||||
sleeve.color = "#" + H.dna.features["mcolor"]
|
||||
add_overlay(sleeve)
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
item_state = "highheels"
|
||||
icon = 'hyperstation/icons/obj/clothing/shoes.dmi'
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/feet.dmi'
|
||||
mutantrace_variation = NO_MUTANTRACE_VARIATION
|
||||
|
||||
|
||||
/obj/item/clothing/shoes/highheels/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -124,6 +124,14 @@
|
||||
icon_state = "commissar_beret"
|
||||
item_state = "commissar_beret"
|
||||
|
||||
/obj/item/clothing/under/touchinfuzzy
|
||||
name = "provocative jumpsuit"
|
||||
desc = "A form fitting jumpsuit with a golden trim zipper! Smells faintly of succubus milk."
|
||||
icon_state = "touchinfuzzyuni"
|
||||
item_state = "touchinfuzzyuni"
|
||||
body_parts_covered = CHEST|GROIN|ARMS|LEGS
|
||||
fitted = NO_FEMALE_UNIFORM
|
||||
|
||||
/obj/item/toy/sword/chloesabre
|
||||
name = "Fleet Commander's Sabre"
|
||||
desc = "An elegant weapon, similar in design to the Captain's Sabre, but with a syndicate twist."
|
||||
@@ -143,4 +151,50 @@
|
||||
return mutable_appearance('icons/obj/custom.dmi', "darksheath-darksabre")
|
||||
|
||||
/obj/item/toy/sword/chloesabre/get_worn_belt_overlay(icon_file)
|
||||
return mutable_appearance(icon_file, "darksheath-darksabre")
|
||||
return mutable_appearance(icon_file, "darksheath-darksabre")
|
||||
|
||||
/obj/item/mialasscale
|
||||
name = "Miala's Scale"
|
||||
desc = "A bright, and familiar, cyan scale from an equally familiar snake being."
|
||||
icon = 'hyperstation/icons/obj/rewards.dmi'
|
||||
icon_state = "m_scale"
|
||||
item_state = "m_scale"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/bong/kiseru
|
||||
name = "black lacquered kiseru"
|
||||
desc = "it is a black lacquered kiseru with a ornate silver head and mouthpiece, you can feel it's old age as you hold it"
|
||||
icon = 'hyperstation/icons/obj/rewards.dmi'
|
||||
icon_state = null
|
||||
item_state = null
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
light_color = "#FFCC66"
|
||||
icon_off = "pipe"
|
||||
icon_on = "pipe_lit"
|
||||
|
||||
/obj/item/clothing/suit/hooded/occultrobes
|
||||
name = "Occult Robes"
|
||||
desc = "I didn't even know they made these in XXS..."
|
||||
icon_state = "coatwinter"
|
||||
item_state = "coatwinter"
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
cold_protection = CHEST|GROIN|ARMS
|
||||
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter)
|
||||
|
||||
/obj/item/clothing/suit/hooded/occultrobes
|
||||
name = "occult robes"
|
||||
desc = "I didn't even know they made these in XXS..."
|
||||
icon_state = "occultrobes"
|
||||
hoodtype = /obj/item/clothing/head/hooded/occultrobeshood
|
||||
mutantrace_variation = NO_MUTANTRACE_VARIATION
|
||||
|
||||
/obj/item/clothing/head/hooded/occultrobeshood
|
||||
name = "occult hood"
|
||||
icon_state = "occultrobeshood"
|
||||
body_parts_covered = HEAD
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
|
||||
flags_inv = HIDEHAIR
|
||||
mutantrace_variation = NO_MUTANTRACE_VARIATION
|
||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 605 B After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 554 KiB After Width: | Height: | Size: 691 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 212 KiB After Width: | Height: | Size: 213 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 427 KiB After Width: | Height: | Size: 429 KiB |
|
Before Width: | Height: | Size: 372 KiB After Width: | Height: | Size: 374 KiB |