mirror of
https://github.com/KabKebab/GS13.git
synced 2026-07-12 00:20:55 +01:00
Update with master
This commit is contained in:
@@ -426,7 +426,7 @@
|
||||
"}
|
||||
if(GLOB.master_mode == "secret")
|
||||
dat += "<A href='?src=[REF(src)];[HrefToken()];f_secret=1'>(Force Secret Mode)</A><br>"
|
||||
|
||||
|
||||
if(GLOB.master_mode == "dynamic")
|
||||
if(SSticker.current_state <= GAME_STATE_PREGAME)
|
||||
dat += "<A href='?src=[REF(src)];[HrefToken()];f_dynamic_roundstart=1'>(Force Roundstart Rulesets)</A><br>"
|
||||
@@ -710,20 +710,44 @@
|
||||
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
var/turf/T = get_turf(usr)
|
||||
|
||||
var/chosen = pick_closest_path(object)
|
||||
if(!chosen)
|
||||
return
|
||||
if(ispath(chosen, /turf))
|
||||
var/turf/T = get_turf(usr.loc)
|
||||
T.ChangeTurf(chosen)
|
||||
else
|
||||
var/atom/A = new chosen(usr.loc)
|
||||
var/atom/A = new chosen(T)
|
||||
A.flags_1 |= ADMIN_SPAWNED_1
|
||||
|
||||
log_admin("[key_name(usr)] spawned [chosen] at [AREACOORD(usr)]")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Spawn Atom") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/datum/admins/proc/podspawn_atom(object as text)
|
||||
set category = "Debug"
|
||||
set desc = "(atom path) Spawn an atom via supply drop"
|
||||
set name = "Podspawn"
|
||||
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
var/chosen = pick_closest_path(object)
|
||||
if(!chosen)
|
||||
return
|
||||
var/turf/T = get_turf(usr)
|
||||
|
||||
if(ispath(chosen, /turf))
|
||||
T.ChangeTurf(chosen)
|
||||
else
|
||||
var/obj/structure/closet/supplypod/centcompod/pod = new()
|
||||
var/atom/A = new chosen(pod)
|
||||
A.flags_1 |= ADMIN_SPAWNED_1
|
||||
new /obj/effect/abstract/DPtarget(T, pod)
|
||||
|
||||
log_admin("[key_name(usr)] pod-spawned [chosen] at [AREACOORD(usr)]")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Podspawn Atom") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/datum/admins/proc/spawn_cargo(object as text)
|
||||
set category = "Debug"
|
||||
set desc = "(atom path) Spawn a cargo crate"
|
||||
@@ -963,6 +987,7 @@
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Ghost Drag Control")
|
||||
|
||||
tomob.ckey = frommob.ckey
|
||||
tomob.client?.init_verbs()
|
||||
qdel(frommob)
|
||||
|
||||
return 1
|
||||
@@ -1011,3 +1036,4 @@
|
||||
log_admin("Man up global: [key_name(usr)] told everybody to man up")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] told everybody to man up.</span>")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Man Up Global")
|
||||
|
||||
|
||||
@@ -72,8 +72,10 @@ 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,
|
||||
/client/proc/hide_verbs, /*hides all our adminverbs*/
|
||||
/client/proc/hide_most_verbs, /*hides all our hideable adminverbs*/
|
||||
/datum/admins/proc/open_borgopanel
|
||||
@@ -107,11 +109,12 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list(
|
||||
/client/proc/smite,
|
||||
/client/proc/spawn_floor_cluwne, // Yogs
|
||||
/client/proc/spawn_random_floor_cluwne,
|
||||
/client/proc/spawn_twitch_plays_clowncar,
|
||||
/client/proc/admin_away,
|
||||
/client/proc/roll_dices //CIT CHANGE - Adds dice verb
|
||||
))
|
||||
GLOBAL_PROTECT(admin_verbs_spawn)
|
||||
GLOBAL_LIST_INIT(admin_verbs_spawn, list(/datum/admins/proc/spawn_atom, /datum/admins/proc/spawn_cargo, /datum/admins/proc/spawn_objasmob, /client/proc/respawn_character))
|
||||
GLOBAL_LIST_INIT(admin_verbs_spawn, list(/datum/admins/proc/spawn_atom, /datum/admins/proc/podspawn_atom, /datum/admins/proc/spawn_cargo, /datum/admins/proc/spawn_objasmob, /client/proc/respawn_character))
|
||||
GLOBAL_PROTECT(admin_verbs_server)
|
||||
GLOBAL_LIST_INIT(admin_verbs_server, world.AVerbsServer())
|
||||
/world/proc/AVerbsServer()
|
||||
@@ -255,36 +258,36 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
|
||||
control_freak = CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS
|
||||
|
||||
var/rights = holder.rank.rights
|
||||
verbs += GLOB.admin_verbs_default
|
||||
add_verb(src, GLOB.admin_verbs_default)
|
||||
if(rights & R_BUILDMODE)
|
||||
verbs += /client/proc/togglebuildmodeself
|
||||
add_verb(src, /client/proc/togglebuildmodeself)
|
||||
if(rights & R_ADMIN)
|
||||
verbs += GLOB.admin_verbs_admin
|
||||
add_verb(src, GLOB.admin_verbs_admin)
|
||||
if(rights & R_BAN)
|
||||
verbs += GLOB.admin_verbs_ban
|
||||
add_verb(src, GLOB.admin_verbs_ban)
|
||||
if(rights & R_FUN)
|
||||
verbs += GLOB.admin_verbs_fun
|
||||
add_verb(src, GLOB.admin_verbs_fun)
|
||||
if(rights & R_SERVER)
|
||||
verbs += GLOB.admin_verbs_server
|
||||
add_verb(src, GLOB.admin_verbs_server)
|
||||
if(rights & R_DEBUG)
|
||||
verbs += GLOB.admin_verbs_debug
|
||||
add_verb(src, GLOB.admin_verbs_debug)
|
||||
if(rights & R_POSSESS)
|
||||
verbs += GLOB.admin_verbs_possess
|
||||
add_verb(src, GLOB.admin_verbs_possess)
|
||||
if(rights & R_PERMISSIONS)
|
||||
verbs += GLOB.admin_verbs_permissions
|
||||
add_verb(src, GLOB.admin_verbs_permissions)
|
||||
if(rights & R_STEALTH)
|
||||
verbs += /client/proc/stealth
|
||||
add_verb(src, /client/proc/stealth)
|
||||
if(rights & R_ADMIN)
|
||||
verbs += GLOB.admin_verbs_poll
|
||||
add_verb(src, GLOB.admin_verbs_poll)
|
||||
if(rights & R_SOUNDS)
|
||||
verbs += GLOB.admin_verbs_sounds
|
||||
add_verb(src, GLOB.admin_verbs_sounds)
|
||||
if(CONFIG_GET(string/invoke_youtubedl))
|
||||
verbs += /client/proc/play_web_sound
|
||||
add_verb(src, /client/proc/play_web_sound)
|
||||
if(rights & R_SPAWN)
|
||||
verbs += GLOB.admin_verbs_spawn
|
||||
add_verb(src, GLOB.admin_verbs_spawn)
|
||||
|
||||
/client/proc/remove_admin_verbs()
|
||||
verbs.Remove(
|
||||
remove_verb(src, list(
|
||||
GLOB.admin_verbs_default,
|
||||
/client/proc/togglebuildmodeself,
|
||||
GLOB.admin_verbs_admin,
|
||||
@@ -303,14 +306,14 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
|
||||
GLOB.admin_verbs_debug_mapping,
|
||||
/client/proc/disable_debug_verbs,
|
||||
/client/proc/readmin
|
||||
)
|
||||
))
|
||||
|
||||
/client/proc/hide_most_verbs()//Allows you to keep some functionality while hiding some verbs
|
||||
set name = "Adminverbs - Hide Most"
|
||||
set category = "Admin"
|
||||
|
||||
verbs.Remove(/client/proc/hide_most_verbs, GLOB.admin_verbs_hideable)
|
||||
verbs += /client/proc/show_verbs
|
||||
add_verb(src, /client/proc/show_verbs)
|
||||
|
||||
to_chat(src, "<span class='interface'>Most of your adminverbs have been hidden.</span>")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Hide Most Adminverbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
@@ -321,7 +324,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
|
||||
set category = "Admin"
|
||||
|
||||
remove_admin_verbs()
|
||||
verbs += /client/proc/show_verbs
|
||||
add_verb(src, /client/proc/show_verbs)
|
||||
|
||||
to_chat(src, "<span class='interface'>Almost all of your adminverbs have been hidden.</span>")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Hide All Adminverbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
@@ -331,7 +334,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
|
||||
set name = "Adminverbs - Show"
|
||||
set category = "Admin"
|
||||
|
||||
verbs -= /client/proc/show_verbs
|
||||
remove_verb(src, /client/proc/show_verbs)
|
||||
add_admin_verbs()
|
||||
|
||||
to_chat(src, "<span class='interface'>All of your adminverbs are now visible.</span>")
|
||||
@@ -364,6 +367,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
|
||||
message_admins("[key_name_admin(usr)] admin ghosted.")
|
||||
var/mob/body = mob
|
||||
body.ghostize(1)
|
||||
init_verbs()
|
||||
if(body && !body.key)
|
||||
body.key = "@[key]" //Haaaaaaaack. But the people have spoken. If it breaks; blame adminbus
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Admin Ghost") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
@@ -716,3 +720,10 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
|
||||
|
||||
log_admin("[key_name(usr)] has [AI_Interact ? "activated" : "deactivated"] Admin AI Interact")
|
||||
message_admins("[key_name_admin(usr)] has [AI_Interact ? "activated" : "deactivated"] their AI interaction")
|
||||
|
||||
|
||||
/client/proc/debugstatpanel()
|
||||
set name = "Debug Stat Panel"
|
||||
set category = "Debug"
|
||||
|
||||
src << output("", "statbrowser:create_debug")
|
||||
@@ -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()
|
||||
|
||||
@@ -93,7 +93,7 @@ GLOBAL_PROTECT(href_token)
|
||||
var/client/C
|
||||
if ((C = owner) || (C = GLOB.directory[target]))
|
||||
disassociate()
|
||||
C.verbs += /client/proc/readmin
|
||||
add_verb(C, /client/proc/readmin)
|
||||
|
||||
/datum/admins/proc/associate(client/C)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
@@ -113,7 +113,8 @@ GLOBAL_PROTECT(href_token)
|
||||
owner = C
|
||||
owner.holder = src
|
||||
owner.add_admin_verbs() //TODO <--- todo what? the proc clearly exists and works since its the backbone to our entire admin system
|
||||
owner.verbs -= /client/proc/readmin
|
||||
remove_verb(owner, /client/proc/readmin)
|
||||
owner.init_verbs() //re-initialize the verb list
|
||||
GLOB.admins |= C
|
||||
|
||||
/datum/admins/proc/disassociate()
|
||||
@@ -125,6 +126,7 @@ GLOBAL_PROTECT(href_token)
|
||||
if(owner)
|
||||
GLOB.admins -= owner
|
||||
owner.remove_admin_verbs()
|
||||
owner.init_verbs()
|
||||
owner.holder = null
|
||||
owner = null
|
||||
|
||||
|
||||
@@ -2399,7 +2399,7 @@
|
||||
|
||||
var/atom/target //Where the object will be spawned
|
||||
var/where = href_list["object_where"]
|
||||
if (!( where in list("onfloor","inhand","inmarked") ))
|
||||
if (!( where in list("onfloor","frompod","inhand","inmarked") ))
|
||||
where = "onfloor"
|
||||
|
||||
|
||||
@@ -2410,7 +2410,7 @@
|
||||
where = "onfloor"
|
||||
target = usr
|
||||
|
||||
if("onfloor")
|
||||
if("onfloor", "frompod")
|
||||
switch(href_list["offset_type"])
|
||||
if ("absolute")
|
||||
target = locate(0 + X,0 + Y,0 + Z)
|
||||
@@ -2426,7 +2426,10 @@
|
||||
else
|
||||
target = marked_datum
|
||||
|
||||
var/obj/structure/closet/supplypod/centcompod/pod
|
||||
if(target)
|
||||
if(where == "frompod")
|
||||
pod = new()
|
||||
for (var/path in paths)
|
||||
for (var/i = 0; i < number; i++)
|
||||
if(path in typesof(/turf))
|
||||
@@ -2435,7 +2438,11 @@
|
||||
if(N && obj_name)
|
||||
N.name = obj_name
|
||||
else
|
||||
var/atom/O = new path(target)
|
||||
var/atom/O
|
||||
if(where == "frompod")
|
||||
O = new path(pod)
|
||||
else
|
||||
O = new path(target)
|
||||
if(!QDELETED(O))
|
||||
O.flags_1 |= ADMIN_SPAWNED_1
|
||||
if(obj_dir)
|
||||
@@ -2455,6 +2462,8 @@
|
||||
R.module.add_module(I, TRUE, TRUE)
|
||||
R.activate_module(I)
|
||||
|
||||
if(pod)
|
||||
new /obj/effect/abstract/DPtarget(target, pod)
|
||||
|
||||
if (number == 1)
|
||||
log_admin("[key_name(usr)] created a [english_list(paths)]")
|
||||
@@ -2981,3 +2990,4 @@
|
||||
else
|
||||
to_chat(usr, "<span class='danger'>Failed to establish database connection. The changes will last only for the current round.</span>")
|
||||
to_chat(usr, "<span class='adminnotice'>Mentor removed.</span>")
|
||||
|
||||
|
||||
@@ -393,11 +393,14 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
|
||||
delete_click = new(null, "INITIALIZING", src)
|
||||
if(!action_click)
|
||||
action_click = new(null, "INITIALIZNG", src)
|
||||
stat("[id] ", delete_click.update("DELETE QUERY | STATE : [text_state()] | ALL/ELIG/FIN \
|
||||
|
||||
var/list/L = list()
|
||||
L[++L.len] = list("[id] ", "[delete_click.update("DELETE QUERY | STATE : [text_state()] | ALL/ELIG/FIN \
|
||||
[islist(obj_count_all)? length(obj_count_all) : (isnull(obj_count_all)? "0" : obj_count_all)]/\
|
||||
[islist(obj_count_eligible)? length(obj_count_eligible) : (isnull(obj_count_eligible)? "0" : obj_count_eligible)]/\
|
||||
[islist(obj_count_finished)? length(obj_count_finished) : (isnull(obj_count_finished)? "0" : obj_count_finished)] - [get_query_text()]"))
|
||||
stat(" ", action_click.update("[SDQL2_IS_RUNNING? "HALT" : "RUN"]"))
|
||||
[islist(obj_count_finished)? length(obj_count_finished) : (isnull(obj_count_finished)? "0" : obj_count_finished)] - [get_query_text()]")]", REF(delete_click))
|
||||
L[++L.len] = list(" ", "[action_click.update("[SDQL2_IS_RUNNING? "HALT" : "RUN"]")]", REF(action_click))
|
||||
return L
|
||||
|
||||
/datum/SDQL2_query/proc/delete_click()
|
||||
admin_del(usr)
|
||||
@@ -1161,10 +1164,18 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
|
||||
return istype(thing, /datum) || istype(thing, /client)
|
||||
|
||||
/obj/effect/statclick/SDQL2_delete/Click()
|
||||
if(!usr.client?.holder)
|
||||
message_admins("[key_name_admin(usr)] non-holder clicked on a statclick! ([src])")
|
||||
log_game("[key_name(usr)] non-holder clicked on a statclick! ([src])")
|
||||
return
|
||||
var/datum/SDQL2_query/Q = target
|
||||
Q.delete_click()
|
||||
|
||||
/obj/effect/statclick/SDQL2_action/Click()
|
||||
if(!usr.client?.holder)
|
||||
message_admins("[key_name_admin(usr)] non-holder clicked on a statclick! ([src])")
|
||||
log_game("[key_name(usr)] non-holder clicked on a statclick! ([src])")
|
||||
return
|
||||
var/datum/SDQL2_query/Q = target
|
||||
Q.action_click()
|
||||
|
||||
@@ -1172,4 +1183,13 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
|
||||
name = "VIEW VARIABLES"
|
||||
|
||||
/obj/effect/statclick/SDQL2_VV_all/Click()
|
||||
if(!usr.client?.holder)
|
||||
message_admins("[key_name_admin(usr)] non-holder clicked on a statclick! ([src])")
|
||||
log_game("[key_name(usr)] non-holder clicked on a statclick! ([src])")
|
||||
return
|
||||
usr.client.debug_variables(GLOB.sdql2_queries)
|
||||
|
||||
if(!usr.client?.holder)
|
||||
message_admins("[key_name_admin(usr)] non-holder clicked on a statclick! ([src])")
|
||||
log_game("[key_name(usr)] non-holder clicked on a statclick! ([src])")
|
||||
return
|
||||
@@ -89,18 +89,23 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
|
||||
//Tickets statpanel
|
||||
/datum/admin_help_tickets/proc/stat_entry()
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
var/list/L = list()
|
||||
var/num_disconnected = 0
|
||||
stat("Active Tickets:", astatclick.update("[active_tickets.len]"))
|
||||
L[++L.len] = list("Active Tickets:", "[astatclick.update("[active_tickets.len]")]", null, REF(astatclick))
|
||||
astatclick.update("[active_tickets.len]")
|
||||
for(var/I in active_tickets)
|
||||
var/datum/admin_help/AH = I
|
||||
if(AH.initiator)
|
||||
stat("#[AH.id]. [AH.initiator_key_name]:", AH.statclick.update())
|
||||
L[++L.len] = list("#[AH.id]. [AH.initiator_key_name]:", "[AH.statclick.update()]", REF(AH))
|
||||
else
|
||||
++num_disconnected
|
||||
if(num_disconnected)
|
||||
stat("Disconnected:", astatclick.update("[num_disconnected]"))
|
||||
stat("Closed Tickets:", cstatclick.update("[closed_tickets.len]"))
|
||||
stat("Resolved Tickets:", rstatclick.update("[resolved_tickets.len]"))
|
||||
L[++L.len] = list("Disconnected:", "[astatclick.update("[num_disconnected]")]", null, REF(astatclick))
|
||||
L[++L.len] = list("Closed Tickets:", "[cstatclick.update("[closed_tickets.len]")]", null, REF(cstatclick))
|
||||
L[++L.len] = list("Resolved Tickets:", "[rstatclick.update("[resolved_tickets.len]")]", null, REF(rstatclick))
|
||||
return L
|
||||
|
||||
//Reassociate still open ticket if one exists
|
||||
/datum/admin_help_tickets/proc/ClientLogin(client/C)
|
||||
@@ -137,6 +142,13 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
/obj/effect/statclick/ticket_list/Click()
|
||||
GLOB.ahelp_tickets.BrowseTickets(current_state)
|
||||
|
||||
|
||||
//called by admin topic
|
||||
/obj/effect/statclick/ticket_list/proc/Action()
|
||||
Click()
|
||||
|
||||
|
||||
|
||||
//
|
||||
//TICKET DATUM
|
||||
//
|
||||
@@ -221,7 +233,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
|
||||
//Removes the ahelp verb and returns it after 30 seconds
|
||||
/datum/admin_help/proc/TimeoutVerb()
|
||||
initiator.verbs -= /client/verb/adminhelp
|
||||
remove_verb(initiator, /client/verb/adminhelp)
|
||||
initiator.adminhelptimerid = addtimer(CALLBACK(initiator, /client/proc/giveadminhelpverb), 300, TIMER_STOPPABLE) //30 seconds cooldown of admin helps
|
||||
|
||||
//private
|
||||
@@ -492,7 +504,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
//
|
||||
|
||||
/client/proc/giveadminhelpverb()
|
||||
src.verbs |= /client/verb/adminhelp
|
||||
add_verb(src, /client/verb/adminhelp)
|
||||
deltimer(adminhelptimerid)
|
||||
adminhelptimerid = 0
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
msg = keywords_lookup(msg)
|
||||
msg = "<span class='adminsay'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> [ADMIN_FLW(mob)]: <span class='message linkify'>[msg]</span></span>"
|
||||
to_chat(GLOB.admins, msg)
|
||||
|
||||
SEND_SOUND(GLOB.admins, sound('sound/effects/asay.ogg'))
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Asay") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/get_admin_say()
|
||||
|
||||
@@ -199,7 +199,7 @@
|
||||
borg.notify_ai(DISCONNECT)
|
||||
if(borg.shell)
|
||||
borg.undeploy()
|
||||
borg.connected_ai = newai
|
||||
borg.set_connected_ai(newai)
|
||||
borg.notify_ai(TRUE)
|
||||
message_admins("[key_name_admin(user)] slaved [ADMIN_LOOKUPFLW(borg)] to the AI [ADMIN_LOOKUPFLW(newai)].")
|
||||
log_admin("[key_name(user)] slaved [key_name(borg)] to the AI [key_name(newai)].")
|
||||
@@ -207,7 +207,7 @@
|
||||
borg.notify_ai(DISCONNECT)
|
||||
if(borg.shell)
|
||||
borg.undeploy()
|
||||
borg.connected_ai = null
|
||||
borg.set_connected_ai(null)
|
||||
message_admins("[key_name_admin(user)] freed [ADMIN_LOOKUPFLW(borg)] from being slaved to an AI.")
|
||||
log_admin("[key_name(user)] freed [key_name(borg)] from being slaved to an AI.")
|
||||
if (borg.lawupdate)
|
||||
|
||||
@@ -493,6 +493,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
|
||||
log_admin("[key_name(usr)] assumed direct control of [M].")
|
||||
var/mob/adminmob = src.mob
|
||||
M.ckey = src.ckey
|
||||
init_verbs()
|
||||
if( isobserver(adminmob) )
|
||||
qdel(adminmob)
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Assume Direct Control") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -205,15 +205,15 @@ GLOBAL_LIST_EMPTY(dirty_vars)
|
||||
set name = "Debug verbs - Enable"
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
verbs -= /client/proc/enable_debug_verbs
|
||||
verbs.Add(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping)
|
||||
remove_verb(src, /client/proc/enable_debug_verbs)
|
||||
add_verb(src, list(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping))
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Enable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/disable_debug_verbs()
|
||||
set category = "Debug"
|
||||
set name = "Debug verbs - Disable"
|
||||
verbs.Remove(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping)
|
||||
verbs += /client/proc/enable_debug_verbs
|
||||
remove_verb(src, list(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping))
|
||||
add_verb(src, /client/proc/enable_debug_verbs)
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Disable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/count_objects_on_z_level()
|
||||
|
||||
@@ -48,6 +48,6 @@
|
||||
set desc = "Give this guy possess/release verbs"
|
||||
set category = "Debug"
|
||||
set name = "Give Possessing Verbs"
|
||||
M.verbs += /proc/possess
|
||||
M.verbs += /proc/release
|
||||
add_verb(M, /proc/possess)
|
||||
add_verb(M, /proc/release)
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Give Possessing Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -1247,26 +1247,34 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
var/obj/item/reagent_containers/food/snacks/store/bread/plain/funnyBread = new(get_turf(target))
|
||||
target.forceMove(funnyBread)
|
||||
|
||||
/client/proc/bookify(atom/movable/target)
|
||||
var/obj/item/reagent_containers/food/snacks/store/book/funnyBook = new(get_turf(target))
|
||||
target.forceMove(funnyBook)
|
||||
funnyBook.name = "Book of " + target.name
|
||||
|
||||
/client/proc/smite(mob/living/carbon/human/target as mob)
|
||||
set name = "Smite"
|
||||
set category = "Fun"
|
||||
if(!check_rights(R_ADMIN) || !check_rights(R_FUN))
|
||||
return
|
||||
|
||||
var/list/punishment_list = list(ADMIN_PUNISHMENT_PIE,
|
||||
ADMIN_PUNISHMENT_FIREBALL,
|
||||
ADMIN_PUNISHMENT_CLUWNE,
|
||||
ADMIN_PUNISHMENT_LIGHTNING,
|
||||
ADMIN_PUNISHMENT_BRAINDAMAGE,
|
||||
ADMIN_PUNISHMENT_BSA,
|
||||
ADMIN_PUNISHMENT_GIB,
|
||||
ADMIN_PUNISHMENT_SUPPLYPOD,
|
||||
ADMIN_PUNISHMENT_MAZING,
|
||||
ADMIN_PUNISHMENT_ROD,
|
||||
var/list/punishment_list = list(ADMIN_PUNISHMENT_PIE,
|
||||
ADMIN_PUNISHMENT_FIREBALL,
|
||||
ADMIN_PUNISHMENT_ROLEPLAY,
|
||||
ADMIN_PUNISHMENT_CLUWNE,
|
||||
ADMIN_PUNISHMENT_LIGHTNING,
|
||||
ADMIN_PUNISHMENT_BRAINDAMAGE,
|
||||
ADMIN_PUNISHMENT_BSA,
|
||||
ADMIN_PUNISHMENT_GIB,
|
||||
ADMIN_PUNISHMENT_SUPPLYPOD_QUICK,
|
||||
ADMIN_PUNISHMENT_SUPPLYPOD,
|
||||
ADMIN_PUNISHMENT_MAZING,
|
||||
ADMIN_PUNISHMENT_ROD,
|
||||
ADMIN_PUNISHMENT_TABLETIDESTATIONWIDE,
|
||||
ADMIN_PUNISHMENT_FAKEBWOINK,
|
||||
ADMIN_PUNISHMENT_NUGGET,
|
||||
ADMIN_PUNISHMENT_BREADIFY)
|
||||
ADMIN_PUNISHMENT_BREADIFY,
|
||||
ADMIN_PUNISHMENT_BOOKIFY)
|
||||
|
||||
var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
|
||||
|
||||
@@ -1304,6 +1312,22 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
var/turf/startT = spaceDebrisStartLoc(startside, T.z)
|
||||
var/turf/endT = spaceDebrisFinishLoc(startside, T.z)
|
||||
new /obj/effect/immovablerod(startT, endT,target)
|
||||
if(ADMIN_PUNISHMENT_SUPPLYPOD_QUICK)
|
||||
var/target_path = input(usr,"Enter typepath of an atom you'd like to send with the pod (type \"empty\" to send an empty pod):" ,"Typepath","/obj/item/reagent_containers/food/snacks/grown/harebell") as null|text
|
||||
var/obj/structure/closet/supplypod/centcompod/pod = new()
|
||||
pod.damage = 40
|
||||
pod.explosionSize = list(0,0,0,2)
|
||||
pod.effectStun = TRUE
|
||||
if (isnull(target_path)) //The user pressed "Cancel"
|
||||
return
|
||||
if (target_path != "empty")//if you didn't type empty, we want to load the pod with a delivery
|
||||
var/delivery = text2path(target_path)
|
||||
if(!ispath(delivery))
|
||||
delivery = pick_closest_path(target_path)
|
||||
if(!delivery)
|
||||
alert("ERROR: Incorrect / improper path given.")
|
||||
new delivery(pod)
|
||||
new /obj/effect/abstract/DPtarget(get_turf(target), pod)
|
||||
if(ADMIN_PUNISHMENT_SUPPLYPOD)
|
||||
var/datum/centcom_podlauncher/plaunch = new(usr)
|
||||
if(!holder)
|
||||
@@ -1316,6 +1340,8 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
plaunch.temp_pod.explosionSize = list(0,0,0,2)
|
||||
plaunch.temp_pod.effectStun = TRUE
|
||||
plaunch.ui_interact(usr)
|
||||
return //We return here because punish_log() is handled by the centcom_podlauncher datum
|
||||
|
||||
if(ADMIN_PUNISHMENT_MAZING)
|
||||
if(!puzzle_imprison(target))
|
||||
to_chat(usr,"<span class='warning'>Imprisonment failed!</span>")
|
||||
@@ -1336,6 +1362,9 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
sleep(1)
|
||||
if(ADMIN_PUNISHMENT_FAKEBWOINK)
|
||||
SEND_SOUND(target, 'sound/effects/adminhelp.ogg')
|
||||
if(ADMIN_PUNISHMENT_ROLEPLAY)
|
||||
SEND_SOUND(target, 'sound/effects/roleplay.ogg')
|
||||
to_chat(target, "<span class='warning big'>Please roleplay appropriately.</span>")
|
||||
if(ADMIN_PUNISHMENT_NUGGET)
|
||||
if (!iscarbon(target))
|
||||
return
|
||||
@@ -1356,13 +1385,22 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
target.transformation_animation(bread_appearance, time = BREADIFY_TIME, transform_overlay=transform_scanline, reset_after=TRUE)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/breadify, target), BREADIFY_TIME)
|
||||
#undef BREADIFY_TIME
|
||||
if(ADMIN_PUNISHMENT_BOOKIFY)
|
||||
#define BOOKIFY_TIME (2 SECONDS)
|
||||
var/mutable_appearance/book_appearance = mutable_appearance('icons/obj/library.dmi', "book")
|
||||
var/mutable_appearance/transform_scanline = mutable_appearance('icons/effects/effects.dmi', "transform_effect")
|
||||
target.transformation_animation(book_appearance, time = BOOKIFY_TIME, transform_overlay=transform_scanline, reset_after=TRUE)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/bookify, target), BOOKIFY_TIME)
|
||||
playsound(target, 'hyperstation/sound/misc/bookify.ogg', 60, 1)
|
||||
#undef BOOKIFY_TIME
|
||||
|
||||
punish_log(target, punishment)
|
||||
|
||||
var/msg = "[key_name_admin(usr)] punished [key_name_admin(target)] with [punishment]."
|
||||
/client/proc/punish_log(var/whom, var/punishment)
|
||||
var/msg = "[key_name_admin(usr)] punished [key_name_admin(whom)] with [punishment]."
|
||||
message_admins(msg)
|
||||
admin_ticket_log(target, msg)
|
||||
log_admin("[key_name(usr)] punished [key_name(target)] with [punishment].")
|
||||
|
||||
admin_ticket_log(whom, msg)
|
||||
log_admin("[key_name(usr)] punished [key_name(whom)] with [punishment].")
|
||||
|
||||
/client/proc/trigger_centcom_recall()
|
||||
if(!check_rights(R_ADMIN))
|
||||
@@ -1432,3 +1470,4 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
else
|
||||
message_admins("[key_name_admin(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name_admin(C)]")
|
||||
log_admin("[key_name(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name(C)]")
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/client/proc/spawn_floor_cluwne()
|
||||
set category = "Fun"
|
||||
set name = "Unleash Targeted Floor Cluwne"
|
||||
set desc = "Pick a specific target. Be warned: spawning more than one may cause issues!"
|
||||
var/target
|
||||
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
target = input("Any specific target in mind? Please note only live, non cluwned, human targets are valid.", "Target", target) as null|anything in GLOB.player_list
|
||||
if(target && ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/mob/living/simple_animal/hostile/floor_cluwne/FC = new /mob/living/simple_animal/hostile/floor_cluwne(H.loc)
|
||||
FC.forced = TRUE
|
||||
FC.Acquire_Victim(H)
|
||||
FC.target = H
|
||||
FC.current_victim = H
|
||||
log_admin("[key_name(usr)] spawned floor cluwne.")
|
||||
message_admins("[key_name(usr)] spawned floor cluwne.")
|
||||
deadchat_broadcast("<span class='deadsay'><b>Floor Cluwne</b> has just been spawned!</span>")
|
||||
|
||||
/client/proc/spawn_random_floor_cluwne()
|
||||
set category = "Fun"
|
||||
set name = "Unleash Random Floor Cluwne"
|
||||
set desc = "Goes after a random player in your Z level. Be warned: spawning more than one may cause issues!"
|
||||
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(usr)
|
||||
new /mob/living/simple_animal/hostile/floor_cluwne(T)
|
||||
log_admin("[key_name(usr)] spawned a random target floor cluwne.")
|
||||
message_admins("[key_name(usr)] spawned a random target floor cluwne.")
|
||||
@@ -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)
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
health = maxHealth
|
||||
name = "blob zombie"
|
||||
desc = "A shambling corpse animated by the blob."
|
||||
mob_biotypes += MOB_HUMANOID
|
||||
mob_biotypes |= MOB_HUMANOID
|
||||
melee_damage_lower += 8
|
||||
melee_damage_upper += 11
|
||||
movement_type = GROUND
|
||||
|
||||
@@ -223,19 +223,16 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
/mob/camera/blob/blob_act(obj/structure/blob/B)
|
||||
return
|
||||
|
||||
/mob/camera/blob/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
if(blob_core)
|
||||
stat(null, "Core Health: [blob_core.obj_integrity]")
|
||||
stat(null, "Power Stored: [blob_points]/[max_blob_points]")
|
||||
stat(null, "Blobs to Win: [blobs_legit.len]/[blobwincount]")
|
||||
if(free_chem_rerolls)
|
||||
stat(null, "You have [free_chem_rerolls] Free Chemical Reroll\s Remaining")
|
||||
if(!placed)
|
||||
if(manualplace_min_time)
|
||||
stat(null, "Time Before Manual Placement: [max(round((manualplace_min_time - world.time)*0.1, 0.1), 0)]")
|
||||
stat(null, "Time Before Automatic Placement: [max(round((autoplace_max_time - world.time)*0.1, 0.1), 0)]")
|
||||
/mob/camera/blob/get_status_tab_items()
|
||||
. = ..()
|
||||
if(blob_core)
|
||||
. += "Core Health: [blob_core.obj_integrity]"
|
||||
. += "Power Stored: [blob_points]/[max_blob_points]"
|
||||
. += "Blobs to Win: [blobs_legit.len]/[blobwincount]"
|
||||
if(!placed)
|
||||
if(manualplace_min_time)
|
||||
. += "Time Before Manual Placement: [max(round((manualplace_min_time - world.time)*0.1, 0.1), 0)]"
|
||||
. += "Time Before Automatic Placement: [max(round((autoplace_max_time - world.time)*0.1, 0.1), 0)]"
|
||||
|
||||
/mob/camera/blob/Move(NewLoc, Dir = 0)
|
||||
if(placed)
|
||||
|
||||
@@ -60,6 +60,8 @@
|
||||
|
||||
if(user.nutrition < NUTRITION_LEVEL_WELL_FED)
|
||||
user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED)
|
||||
if(user.thirst < THIRST_LEVEL_QUENCHED)
|
||||
user.thirst = min((user.thirst + target.thirst), THIRST_LEVEL_QUENCHED)
|
||||
|
||||
if(target.mind)//if the victim has got a mind
|
||||
// Absorb a lizard, speak Draconic.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
name = "clockwork marauder"
|
||||
desc = "The stalwart apparition of a soldier, blazing with crimson flames. It's armed with a gladius and shield."
|
||||
icon_state = "clockwork_marauder"
|
||||
mob_biotypes = list(MOB_INORGANIC, MOB_HUMANOID)
|
||||
mob_biotypes = MOB_INORGANIC|MOB_HUMANOID
|
||||
health = 120
|
||||
maxHealth = 120
|
||||
force_threshold = 8
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "imp"
|
||||
icon_living = "imp"
|
||||
mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
|
||||
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
|
||||
speed = 1
|
||||
a_intent = INTENT_HARM
|
||||
stop_automated_movement = 1
|
||||
|
||||
@@ -76,7 +76,7 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
|
||||
resistance += initial(S.resistance)
|
||||
stage_speed += initial(S.stage_speed)
|
||||
transmittable += initial(S.transmittable)
|
||||
threshold_block += initial(S.threshold_desc)
|
||||
threshold_block += initial(S.threshold_desc)
|
||||
stat_block = "Resistance: [resistance]<br>Stealth: [stealth]<br>Stage Speed: [stage_speed]<br>Transmissibility: [transmittable]<br><br>"
|
||||
if(symptoms.len == 1) //lazy boy's dream
|
||||
name = initial(S.name)
|
||||
@@ -194,8 +194,6 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
|
||||
/datum/disease_ability/action/sneeze
|
||||
name = "Voluntary Sneezing"
|
||||
actions = list(/datum/action/cooldown/disease_sneeze)
|
||||
cost = 2
|
||||
required_total_points = 3
|
||||
short_desc = "Force the host you are following to sneeze, spreading your infection to those in front of them."
|
||||
long_desc = "Force the host you are following to sneeze with extra force, spreading your infection to any victims in a 4 meter cone in front of your host.<br>Cooldown: 20 seconds"
|
||||
|
||||
@@ -232,8 +230,6 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
|
||||
/datum/disease_ability/action/infect
|
||||
name = "Secrete Infection"
|
||||
actions = list(/datum/action/cooldown/disease_infect)
|
||||
cost = 2
|
||||
required_total_points = 3
|
||||
short_desc = "Cause all objects your host is touching to become infectious for a limited time, spreading your infection to anyone who touches them."
|
||||
long_desc = "Cause the host you are following to excrete an infective substance from their pores, causing all objects touching their skin to transmit your infection to anyone who touches them for the next 30 seconds. This includes the floor, if they are not wearing shoes, and any items they are holding, if they are not wearing gloves.<br>Cooldown: 40 seconds"
|
||||
|
||||
@@ -274,22 +270,19 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
|
||||
//healing costs more so you have to techswitch from naughty disease otherwise we'd have friendly disease for easy greentext (no fun!)
|
||||
|
||||
/datum/disease_ability/symptom/mild
|
||||
cost = 2
|
||||
required_total_points = 4
|
||||
category = "Symptom (Weak)"
|
||||
|
||||
/datum/disease_ability/symptom/medium
|
||||
cost = 4
|
||||
required_total_points = 8
|
||||
category = "Symptom"
|
||||
|
||||
/datum/disease_ability/symptom/medium/heal
|
||||
cost = 5
|
||||
required_total_points = 5
|
||||
category = "Symptom (+)"
|
||||
|
||||
/datum/disease_ability/symptom/powerful
|
||||
cost = 4
|
||||
required_total_points = 16
|
||||
required_total_points = 10
|
||||
category = "Symptom (Strong)"
|
||||
|
||||
/datum/disease_ability/symptom/powerful/heal
|
||||
|
||||
@@ -84,17 +84,16 @@ the new instance inside the host to be updated to the template's stats.
|
||||
to_chat(src, "<span class='warning'>You have [DisplayTimeText(freemove_end - world.time)] to select your first host. Click on a human to select your host.</span>")
|
||||
|
||||
|
||||
/mob/camera/disease/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
if(freemove)
|
||||
stat("Host Selection Time: [round((freemove_end - world.time)/10)]s")
|
||||
else
|
||||
stat("Adaptation Points: [points]/[total_points]")
|
||||
stat("Hosts: [disease_instances.len]")
|
||||
var/adapt_ready = next_adaptation_time - world.time
|
||||
if(adapt_ready > 0)
|
||||
stat("Adaptation Ready: [round(adapt_ready/10, 0.1)]s")
|
||||
/mob/camera/disease/get_status_tab_items()
|
||||
|
||||
if(freemove)
|
||||
. += "Host Selection Time: [round((freemove_end - world.time)/10)]s"
|
||||
else
|
||||
. += "Adaptation Points: [points]/[total_points]"
|
||||
. += "Hosts: [disease_instances.len]"
|
||||
var/adapt_ready = next_adaptation_time - world.time
|
||||
if(adapt_ready > 0)
|
||||
. += "Adaptation Ready: [round(adapt_ready/10, 0.1)]s"
|
||||
|
||||
|
||||
/mob/camera/disease/examine(mob/user)
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
#define LIGHTSTOBREAK_MINIMUM 25
|
||||
#define LIGHTSTOBREAK_MAXIMUM 75
|
||||
#define LIGHTSTOBREAK_THRESHOLD 50
|
||||
#define LIGHTSTOBREAK_MAX_CHANCE 50
|
||||
#define LIGHTSTOBREAK_AREA_MIN 1
|
||||
#define LIGHTSTOBREAK_AREA_MAX 2
|
||||
|
||||
/datum/antagonist/nightmare
|
||||
name = "Nightmare"
|
||||
show_in_antagpanel = FALSE
|
||||
show_name_in_check_antagonists = TRUE
|
||||
show_name_in_check_antagonists = TRUE
|
||||
|
||||
/datum/antagonist/nightmare/on_gain()
|
||||
owner.objectives += forge_objective()
|
||||
owner.objectives += new /datum/objective/survive
|
||||
|
||||
/datum/antagonist/nightmare/proc/forge_objective()
|
||||
var/datum/objective/break_lights/O = new
|
||||
O.mode = prob(50) ? TRUE : FALSE
|
||||
antag_memory = "<b>Objectives:<br>1.</b> [O.apply_rules()]<br><b>2.</b> Stay alive until the end."
|
||||
return O
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/datum/objective/break_lights
|
||||
var/mode = FALSE //If true, break all lights in determined area
|
||||
var/list/area_targets = list() //Which areas we have to keep lights broken
|
||||
target_amount = LIGHTSTOBREAK_AREA_MIN
|
||||
var/lightsbroken = 0
|
||||
|
||||
var/safe_areas = list(
|
||||
/area/space,
|
||||
/area/maintenance/solars,
|
||||
/area/maintenance/central, //HOP/Conference room APC
|
||||
/area/ai_monitored,
|
||||
/area/shuttle,
|
||||
/area/engine/engine_smes,
|
||||
/area/security/prison, //If you get unlucky, you'll have to break the lights in armory
|
||||
/area/security/execution)
|
||||
|
||||
/datum/objective/break_lights/proc/apply_rules()
|
||||
if(mode)
|
||||
var/list/valid_areas = list()
|
||||
for(var/obj/machinery/power/apc/C in GLOB.apcs_list)
|
||||
if(C.cell && is_station_level(C.z))
|
||||
var/is_safearea = 1
|
||||
for(var/A in safe_areas)
|
||||
if(istype(C.area, A))
|
||||
is_safearea = 0
|
||||
break
|
||||
if(is_safearea)
|
||||
valid_areas += C.area
|
||||
var/I = rand(LIGHTSTOBREAK_AREA_MIN, LIGHTSTOBREAK_AREA_MAX)
|
||||
for(var/N in 1 to I)
|
||||
var/area2add = pick(valid_areas)
|
||||
if(!locate(area2add) in area_targets)
|
||||
area_targets += area2add
|
||||
else
|
||||
target_amount = rand(LIGHTSTOBREAK_MINIMUM, LIGHTSTOBREAK_MAXIMUM)
|
||||
if(prob(LIGHTSTOBREAK_MAX_CHANCE))
|
||||
if(target_amount > LIGHTSTOBREAK_THRESHOLD)
|
||||
target_amount = LIGHTSTOBREAK_MAXIMUM
|
||||
else if(target_amount > LIGHTSTOBREAK_THRESHOLD)
|
||||
target_amount = LIGHTSTOBREAK_THRESHOLD
|
||||
explanation_text = update_explanation_text()
|
||||
return explanation_text
|
||||
|
||||
/datum/objective/break_lights/update_explanation_text()
|
||||
..()
|
||||
if(mode)
|
||||
if(!area_targets.len)
|
||||
return "Uh oh! Something broke! Report this."
|
||||
. += "There must not be any light sources in the "
|
||||
if(area_targets.len == 1)
|
||||
var/area/A = area_targets[1]
|
||||
. += "[A.name]"
|
||||
else if(area_targets.len == 2)
|
||||
var/area/A = area_targets[1]
|
||||
var/area/B = area_targets[2]
|
||||
. += "[A.name] and [B.name]"
|
||||
else //Won't get here because of define values, but during development you can get here. leaving this here for future purposes
|
||||
var/i = 1
|
||||
for(var/area/A in area_targets)
|
||||
if(i != area_targets.len) . += "[A.name], "
|
||||
else . += "and [A.name]"
|
||||
|
||||
. += " before the end."
|
||||
else
|
||||
. += "Break at least [target_amount] lights with your light eater."
|
||||
|
||||
/datum/objective/break_lights/check_completion()
|
||||
if(completed)
|
||||
return TRUE //An attempt to stop this from being called twice
|
||||
if(!mode)
|
||||
if(lightsbroken >= target_amount)
|
||||
completed = TRUE
|
||||
else
|
||||
var/list/valid_turfs = list()
|
||||
for(var/area/target in area_targets)
|
||||
var/list/cached_area = get_area_turfs(target.type)
|
||||
for(var/turf/A in cached_area)
|
||||
if(!is_station_level(A.z))
|
||||
continue
|
||||
valid_turfs += A
|
||||
for(var/turf/T in valid_turfs)
|
||||
for(var/atom/C in T.contents)
|
||||
/*if(!C?.visibility) //Doesn't compile, add this another time
|
||||
continue*/
|
||||
if(C.light_range > 0)
|
||||
if(C.light_power <= SHADOW_SPECIES_LIGHT_THRESHOLD*2) //Give some leniency for not destroying that unbreakable requests console
|
||||
completed = TRUE
|
||||
else
|
||||
completed = FALSE
|
||||
break
|
||||
if(!completed)
|
||||
break
|
||||
|
||||
return completed
|
||||
|
||||
/datum/objective/break_lights/area
|
||||
mode = TRUE
|
||||
|
||||
|
||||
#undef LIGHTSTOBREAK_MINIMUM
|
||||
#undef LIGHTSTOBREAK_MAXIMUM
|
||||
#undef LIGHTSTOBREAK_THRESHOLD
|
||||
#undef LIGHTSTOBREAK_MAX_CHANCE
|
||||
#undef LIGHTSTOBREAK_AREA_MIN
|
||||
#undef LIGHTSTOBREAK_AREA_MAX
|
||||
@@ -381,6 +381,7 @@
|
||||
playsound(src, 'sound/machines/nuke/confirm_beep.ogg', 50, FALSE)
|
||||
set_active()
|
||||
update_ui_mode()
|
||||
. = TRUE
|
||||
else
|
||||
playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE)
|
||||
if("anchor")
|
||||
@@ -608,6 +609,8 @@ This is here to make the tiles around the station mininuke change when it's arme
|
||||
lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi'
|
||||
icon_state = "datadisk0"
|
||||
drop_sound = 'sound/items/handling/disk_drop.ogg'
|
||||
pickup_sound = 'sound/items/handling/disk_pickup.ogg'
|
||||
|
||||
/obj/item/disk/nuclear
|
||||
name = "nuclear authentication disk"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
var/icon_stun = "revenant_stun"
|
||||
var/icon_drain = "revenant_draining"
|
||||
var/stasis = FALSE
|
||||
mob_biotypes = list(MOB_SPIRIT)
|
||||
mob_biotypes = MOB_SPIRIT
|
||||
incorporeal_move = INCORPOREAL_MOVE_JAUNT
|
||||
invisibility = INVISIBILITY_REVENANT
|
||||
health = INFINITY //Revenants don't use health, they use essence instead
|
||||
@@ -124,12 +124,12 @@
|
||||
update_health_hud()
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/revenant/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
stat(null, "Current essence: [essence]/[essence_regen_cap]E")
|
||||
stat(null, "Stolen essence: [essence_accumulated]E")
|
||||
stat(null, "Stolen perfect souls: [perfectsouls]")
|
||||
|
||||
/mob/living/simple_animal/revenant/get_status_tab_items()
|
||||
. = ..()
|
||||
. += "Current essence: [essence]/[essence_regen_cap]E"
|
||||
. += "Stolen essence: [essence_accumulated]E"
|
||||
. += "Stolen perfect souls: [perfectsouls]"
|
||||
|
||||
/mob/living/simple_animal/revenant/update_health_hud()
|
||||
if(hud_used)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "daemon"
|
||||
icon_living = "daemon"
|
||||
mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
|
||||
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
|
||||
speed = 1
|
||||
a_intent = INTENT_HARM
|
||||
stop_automated_movement = 1
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
speak_emote = list("tones")
|
||||
initial_language_holder = /datum/language_holder/swarmer
|
||||
bubble_icon = "swarmer"
|
||||
mob_biotypes = list(MOB_ROBOTIC)
|
||||
mob_biotypes = MOB_ROBOTIC
|
||||
health = 40
|
||||
maxHealth = 40
|
||||
status_flags = CANPUSH
|
||||
@@ -107,7 +107,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/swarmer/Initialize()
|
||||
. = ..()
|
||||
verbs -= /mob/living/verb/pulled
|
||||
remove_verb(src, /mob/living/verb/pulled)
|
||||
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
|
||||
diag_hud.add_to_hud(src)
|
||||
|
||||
@@ -123,10 +123,9 @@
|
||||
holder.pixel_y = I.Height() - world.icon_size
|
||||
holder.icon_state = "hudstat"
|
||||
|
||||
/mob/living/simple_animal/hostile/swarmer/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
stat("Resources:",resources)
|
||||
/mob/living/simple_animal/hostile/swarmer/get_status_tab_items()
|
||||
. = ..()
|
||||
. += "Resources: [resources]"
|
||||
|
||||
/mob/living/simple_animal/hostile/swarmer/emp_act()
|
||||
. = ..()
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
var/wizard_name_second = pick(GLOB.wizard_second)
|
||||
var/randomname = "[wizard_name_first] [wizard_name_second]"
|
||||
var/mob/living/wiz_mob = owner.current
|
||||
var/newname = reject_bad_name(stripped_input(wiz_mob, "You are the [name]. Would you like to change your name to something else?", "Name change", randomname, MAX_NAME_LEN))
|
||||
var/newname = reject_bad_name(stripped_input(wiz_mob, "You are the [name]. Would you like to change your name to something else?", "Name change", randomname, MAX_NAME_LEN), TRUE)
|
||||
|
||||
if (!newname)
|
||||
newname = randomname
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
//used for mapping and for breathing while in walls (because that's a thing that needs to be accounted for...)
|
||||
//string parsed by /datum/gas/proc/copy_from_turf
|
||||
var/initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
|
||||
var/initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
//approximation of MOLES_O2STANDARD and MOLES_N2STANDARD pending byond allowing constant expressions to be embedded in constant strings
|
||||
// If someone will place 0 of some gas there, SHIT WILL BREAK. Do not do that.
|
||||
|
||||
|
||||
@@ -338,8 +338,9 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
|
||||
if(!length(cached_gases))
|
||||
return
|
||||
var/list/reactions = list()
|
||||
for(var/I in cached_gases)
|
||||
reactions += SSair.gas_reactions[I]
|
||||
for(var/datum/gas_reaction/G in SSair.gas_reactions)
|
||||
if(cached_gases[G.major_gas])
|
||||
reactions += G
|
||||
if(!length(reactions))
|
||||
return
|
||||
reaction_results = new
|
||||
|
||||
@@ -184,7 +184,18 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g
|
||||
name = "Miasma"
|
||||
gas_overlay = "miasma"
|
||||
moles_visible = MOLES_GAS_VISIBLE * 60
|
||||
rarity = 250
|
||||
rarity = 150
|
||||
|
||||
|
||||
/datum/gas/pheromone
|
||||
id = "pheromone"
|
||||
specific_heat = 0.00001
|
||||
fusion_power = 30
|
||||
name = "Pheromones"
|
||||
gas_overlay = "pheromone"
|
||||
moles_visible = MOLES_GAS_VISIBLE * 10
|
||||
rarity = 30
|
||||
|
||||
|
||||
/obj/effect/overlay/gas
|
||||
icon = 'icons/effects/atmospherics.dmi'
|
||||
@@ -192,6 +203,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g
|
||||
anchored = TRUE // should only appear in vis_contents, but to be safe
|
||||
layer = FLY_LAYER
|
||||
appearance_flags = TILE_BOUND
|
||||
vis_flags = NONE
|
||||
|
||||
/obj/effect/overlay/gas/New(state, alph)
|
||||
. = ..()
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
/proc/init_gas_reactions()
|
||||
. = list()
|
||||
for(var/type in subtypesof(/datum/gas))
|
||||
.[type] = list()
|
||||
|
||||
for(var/r in subtypesof(/datum/gas_reaction))
|
||||
var/datum/gas_reaction/reaction = r
|
||||
@@ -16,27 +14,19 @@
|
||||
var/datum/gas/req_gas = req
|
||||
if (!reaction_key || initial(reaction_key.rarity) > initial(req_gas.rarity))
|
||||
reaction_key = req_gas
|
||||
.[reaction_key] += list(reaction)
|
||||
sortTim(., /proc/cmp_gas_reactions, TRUE)
|
||||
reaction.major_gas = reaction_key
|
||||
. += reaction
|
||||
sortTim(., /proc/cmp_gas_reaction)
|
||||
|
||||
/proc/cmp_gas_reactions(list/datum/gas_reaction/a, list/datum/gas_reaction/b) // compares lists of reactions by the maximum priority contained within the list
|
||||
if (!length(a) || !length(b))
|
||||
return length(b) - length(a)
|
||||
var/maxa
|
||||
var/maxb
|
||||
for (var/datum/gas_reaction/R in a)
|
||||
if (R.priority > maxa)
|
||||
maxa = R.priority
|
||||
for (var/datum/gas_reaction/R in b)
|
||||
if (R.priority > maxb)
|
||||
maxb = R.priority
|
||||
return maxb - maxa
|
||||
/proc/cmp_gas_reaction(datum/gas_reaction/a, datum/gas_reaction/b) // compares lists of reactions by the maximum priority contained within the list
|
||||
return b.priority - a.priority
|
||||
|
||||
/datum/gas_reaction
|
||||
//regarding the requirements lists: the minimum or maximum requirements must be non-zero.
|
||||
//when in doubt, use MINIMUM_MOLE_COUNT.
|
||||
var/list/min_requirements
|
||||
var/list/max_requirements
|
||||
var/major_gas //the highest rarity gas used in the reaction.
|
||||
var/exclude = FALSE //do it this way to allow for addition/removal of reactions midmatch in the future
|
||||
var/priority = 100 //lower numbers are checked/react later than higher numbers. if two reactions have the same priority they may happen in either order
|
||||
var/name = "reaction"
|
||||
|
||||
@@ -96,6 +96,7 @@
|
||||
/datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000),
|
||||
/datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10),
|
||||
/datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5),
|
||||
/datum/gas/pheromone = new/datum/tlv/(-1, -1, 2, 5),
|
||||
/datum/gas/plasma = new/datum/tlv/dangerous,
|
||||
/datum/gas/nitrous_oxide = new/datum/tlv/dangerous,
|
||||
/datum/gas/bz = new/datum/tlv/dangerous,
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
if(!panel_open)
|
||||
return
|
||||
anchored = !anchored
|
||||
move_resist = anchored? INFINITY : 100
|
||||
I.play_tool_sound(src)
|
||||
if(generator)
|
||||
disconnectFromGenerator()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
//liquid plasma!!!!!!//
|
||||
|
||||
/turf/open/floor/plasteel/dark/snowdin
|
||||
initial_gas_mix = "o2=22;n2=82;TEMP=180"
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
planetary_atmos = 1
|
||||
temperature = 180
|
||||
|
||||
@@ -323,7 +323,7 @@
|
||||
|
||||
/obj/item/paper/fluff/awaymissions/snowdin/secnotice
|
||||
name = "Security Notice"
|
||||
info = {"YOu have been assigned to this Arctic Post with intention of protecting Nanotrasen assets and ensuring vital information is kept secure while the stationed crew obeys protocol. The picked
|
||||
info = {"You have been assigned to this Arctic Post with intention of protecting Nanotrasen assets and ensuring vital information is kept secure while the stationed crew obeys protocol. The picked
|
||||
staff for this post have been pre-screened with no prior incidients on record, but incase of an issue you have been given a single holding cell and instructions to contact Central to terminate the
|
||||
offending crewmember."}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
if("Immortality")
|
||||
to_chat(user, "<B>Your wish is granted, but at a terrible cost...</B>")
|
||||
to_chat(user, "The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart.")
|
||||
user.verbs += /mob/living/carbon/proc/immortality
|
||||
add_verb(user, /mob/living/carbon/proc/immortality)
|
||||
user.set_species(/datum/species/shadow)
|
||||
if("To Kill")
|
||||
to_chat(user, "<B>Your wish is granted, but at a terrible cost...</B>")
|
||||
|
||||
@@ -215,3 +215,24 @@
|
||||
description = "Commander Jackson is looking for a fine addition to her exotic weapons collection. She will reward you handsomely for either a Cat or Liz o' Nine Tails."
|
||||
reward = 4000
|
||||
wanted_types = list(/obj/item/melee/chainofcommand/tailwhip)
|
||||
|
||||
/datum/bounty/item/assistant/shadow_wood_chair
|
||||
name = "Shadow Wood Chairs"
|
||||
description = "Commander Mat is unhappy with his chair. He claims it hurts his back. Ship some shadow wood chairs to humor him."
|
||||
reward = 1000
|
||||
required_count = 5
|
||||
wanted_types = list(/obj/structure/chair/shadoww)
|
||||
|
||||
/datum/bounty/item/assistant/mushroom_chair
|
||||
name = "Mushroom Chairs"
|
||||
description = "Commander Rat is unhappy with his chair. He claims it hurts his back. Ship some mushroom chairs to humor him."
|
||||
reward = 1500
|
||||
required_count = 5
|
||||
wanted_types = list(/obj/structure/chair/gmushroom)
|
||||
|
||||
/datum/bounty/item/assistant/plaswood_chair
|
||||
name = "Plaswood Chairs"
|
||||
description = "Commander Cat is unhappy with his chair. He claims it hurts his back. Ship some plaswood chairs to humor him."
|
||||
reward = 2250
|
||||
required_count = 5
|
||||
wanted_types = list(/obj/structure/chair/plaswood)
|
||||
|
||||
@@ -63,3 +63,24 @@
|
||||
reward = 1000
|
||||
required_count = 1
|
||||
wanted_types = list(/obj/item/seeds/lavaland/cactus)
|
||||
|
||||
datum/bounty/item/mining/plaswood
|
||||
name = "Plaswood Planks"
|
||||
description = "Central Command's carpentry department needs more exotic wood, send us some plaswood planks!"
|
||||
reward = 5500
|
||||
required_count = 100
|
||||
wanted_types = list(/obj/item/stack/sheet/mineral/plaswood)
|
||||
|
||||
datum/bounty/item/mining/gmushroom
|
||||
name = "Mushroom Planks"
|
||||
description = "Central Command's carpentry department needs more exotic 'wood', send us some mushroom planks!"
|
||||
reward = 1100
|
||||
required_count = 100
|
||||
wanted_types = list(/obj/item/stack/sheet/mineral/gmushroom)
|
||||
|
||||
datum/bounty/item/mining/shadoww
|
||||
name = "Shadow Planks"
|
||||
description = "Central Command's carpentry department needs more exotic wood, send us some shadow planks!"
|
||||
reward = 900
|
||||
required_count = 100
|
||||
wanted_types = list(/obj/item/stack/sheet/mineral/shadoww)
|
||||
@@ -19,7 +19,7 @@
|
||||
//Variables declared to change how items in the launch bay are picked and launched. (Almost) all of these are changed in the ui_act proc
|
||||
//Some effect groups are choices, while other are booleans. This is because some effects can stack, while others dont (ex: you can stack explosion and quiet, but you cant stack ordered launch and random launch)
|
||||
/datum/centcom_podlauncher
|
||||
var/static/list/ignored_atoms = typecacheof(list(null, /mob/dead, /obj/effect/landmark, /obj/docking_port, /atom/movable/lighting_object, /obj/effect/particle_effect/sparks, /obj/effect/DPtarget, /obj/effect/supplypod_selector ))
|
||||
var/static/list/ignored_atoms = typecacheof(list(null, /mob/dead, /obj/effect/landmark, /obj/docking_port, /atom/movable/lighting_object, /obj/effect/particle_effect/sparks, /obj/effect/abstract/DPtarget, /obj/effect/supplypod_selector ))
|
||||
var/turf/oldTurf //Keeps track of where the user was at if they use the "teleport to centcom" button, so they can go back
|
||||
var/client/holder //client of whoever is using this datum
|
||||
var/area/bay //What bay we're using to launch shit from.
|
||||
@@ -29,9 +29,10 @@
|
||||
var/damageChoice = 0 //Determines if we do no damage (0), custom amnt of damage (1), or gib + 5000dmg (2)
|
||||
var/launcherActivated = FALSE //check if we've entered "launch mode" (when we click a pod is launched). Used for updating mouse cursor
|
||||
var/effectBurst = FALSE //Effect that launches 5 at once in a 3x3 area centered on the target
|
||||
var/effectAnnounce = TRUE
|
||||
var/numTurfs = 0 //Counts the number of turfs with things we can launch in the chosen bay (in the centcom map)
|
||||
var/launchCounter = 1 //Used with the "Ordered" launch mode (launchChoice = 1) to see what item is launched
|
||||
var/specificTarget //Do we want to target a specific mob instead of where we click? Also used for smiting
|
||||
var/atom/specificTarget //Do we want to target a specific mob instead of where we click? Also used for smiting
|
||||
var/list/orderedArea = list() //Contains an ordered list of turfs in an area (filled in the createOrderedArea() proc), read top-left to bottom-right. Used for the "ordered" launch mode (launchChoice = 1)
|
||||
var/list/acceptableTurfs = list() //Contians a list of turfs (in the "bay" area on centcom) that have items that can be launched. Taken from orderedArea
|
||||
var/list/launchList = list() //Contains whatever is going to be put in the supplypod and fired. Taken from acceptableTurfs
|
||||
@@ -66,12 +67,14 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
data["launchChoice"] = launchChoice //Launch turfs all at once (0), ordered (1), or randomly(1)
|
||||
data["explosionChoice"] = explosionChoice //An explosion that occurs when landing. Can be no explosion (0), custom explosion (1), or maxcap (2)
|
||||
data["damageChoice"] = damageChoice //Damage that occurs to any mob under the pod when it lands. Can be no damage (0), custom damage (1), or gib+5000dmg (2)
|
||||
data["fallDuration"] = temp_pod.fallDuration //How long the pod's falling animation lasts
|
||||
data["landingDelay"] = temp_pod.landingDelay //How long the pod takes to land after launching
|
||||
data["openingDelay"] = temp_pod.openingDelay //How long the pod takes to open after landing
|
||||
data["departureDelay"] = temp_pod.departureDelay //How long the pod takes to leave after opening (if bluespace=true, it deletes. if reversing=true, it flies back to centcom)
|
||||
data["styleChoice"] = temp_pod.style //Style is a variable that keeps track of what the pod is supposed to look like. It acts as an index to the POD_STYLES list in cargo.dm defines to get the proper icon/name/desc for the pod.
|
||||
data["effectStun"] = temp_pod.effectStun //If true, stuns anyone under the pod when it launches until it lands, forcing them to get hit by the pod. Devilish!
|
||||
data["effectLimb"] = temp_pod.effectLimb //If true, pops off a limb (if applicable) from anyone caught under the pod when it lands
|
||||
data["effectOrgans"] = temp_pod.effectOrgans //If true, yeets the organs out of any bodies caught under the pod when it lands
|
||||
data["effectBluespace"] = temp_pod.bluespace //If true, the pod deletes (in a shower of sparks) after landing
|
||||
data["effectStealth"] = temp_pod.effectStealth //If true, a target icon isnt displayed on the turf where the pod will land
|
||||
data["effectQuiet"] = temp_pod.effectQuiet //The female sniper. If true, the pod makes no noise (including related explosions, opening sounds, etc)
|
||||
@@ -81,12 +84,14 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
data["effectReverse"] = temp_pod.reversing //If true, the pod will not send any items. Instead, after opening, it will close again (picking up items/mobs) and fly back to centcom
|
||||
data["effectTarget"] = specificTarget //Launches the pod at the turf of a specific mob target, rather than wherever the user clicked. Useful for smites
|
||||
data["effectName"] = temp_pod.adminNamed //Determines whether or not the pod has been named by an admin. If true, the pod's name will not get overridden when the style of the pod changes (changing the style of the pod normally also changes the name+desc)
|
||||
data["effectAnnounce"] = effectAnnounce
|
||||
data["giveLauncher"] = launcherActivated //If true, the user is in launch mode, and whenever they click a pod will be launched (either at their mouse position or at a specific target)
|
||||
data["numObjects"] = numTurfs //Counts the number of turfs that contain a launchable object in the centcom supplypod bay
|
||||
data["fallingSound"] = temp_pod.fallingSound != initial(temp_pod.fallingSound)//Admin sound to play as the pod falls
|
||||
data["landingSound"] = temp_pod.landingSound //Admin sound to play when the pod lands
|
||||
data["openingSound"] = temp_pod.openingSound //Admin sound to play when the pod opens
|
||||
data["leavingSound"] = temp_pod.leavingSound //Admin sound to play when the pod leaves
|
||||
data["soundVolume"] = temp_pod.soundVolume != 50 //Admin sound to play when the pod leaves
|
||||
data["soundVolume"] = temp_pod.soundVolume != initial(temp_pod.soundVolume) //Admin sound to play when the pod leaves
|
||||
return data
|
||||
|
||||
/datum/centcom_podlauncher/ui_act(action, params)
|
||||
@@ -227,6 +232,9 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if("effectLimb") //Toggle: Anyone carbon mob under the pod loses a limb when it lands
|
||||
temp_pod.effectLimb = !temp_pod.effectLimb
|
||||
. = TRUE
|
||||
if("effectOrgans") //Toggle: Any carbon mob under the pod loses every limb and organ
|
||||
temp_pod.effectOrgans = !temp_pod.effectOrgans
|
||||
. = TRUE
|
||||
if("effectBluespace") //Toggle: Deletes the pod after landing
|
||||
temp_pod.bluespace = !temp_pod.bluespace
|
||||
. = TRUE
|
||||
@@ -245,6 +253,9 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if("effectBurst") //Toggle: Launch 5 pods (with a very slight delay between) in a 3x3 area centered around the target
|
||||
effectBurst = !effectBurst
|
||||
. = TRUE
|
||||
if("effectAnnounce") //Toggle: Sends a ghost announcement.
|
||||
effectAnnounce = !effectAnnounce
|
||||
. = TRUE
|
||||
if("effectReverse") //Toggle: Don't send any items. Instead, after landing, close (taking any objects inside) and go back to the centcom bay it came from
|
||||
temp_pod.reversing = !temp_pod.reversing
|
||||
. = TRUE
|
||||
@@ -261,11 +272,23 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
. = TRUE
|
||||
|
||||
////////////////////////////TIMER DELAYS//////////////////
|
||||
if("fallDuration") //Change the falling animation duration
|
||||
if (temp_pod.fallDuration != initial(temp_pod.fallDuration)) //If the fall duration has already been changed when we push the "change value" button, then set it to default
|
||||
temp_pod.fallDuration = initial(temp_pod.fallDuration)
|
||||
return
|
||||
var/timeInput = input("Enter the duration of the pod's falling animation, in seconds", "Delay Time", initial(temp_pod.fallDuration) * 0.1) as null|num
|
||||
if (isnull(timeInput))
|
||||
return
|
||||
if (!isnum(timeInput)) //Sanitize input, if it doesnt check out, error and set to default
|
||||
alert(usr, "That wasnt a number! Value set to default ([initial(temp_pod.fallDuration)*0.1]) instead.")
|
||||
timeInput = initial(temp_pod.fallDuration)
|
||||
temp_pod.fallDuration = 10 * timeInput
|
||||
. = TRUE
|
||||
if("landingDelay") //Change the time it takes the pod to land, after firing
|
||||
if (temp_pod.landingDelay != initial(temp_pod.landingDelay)) //If the landing delay has already been changed when we push the "change value" button, then set it to default
|
||||
temp_pod.landingDelay = initial(temp_pod.landingDelay)
|
||||
return
|
||||
var/timeInput = input("Delay Time", "Enter the time it takes for the pod to land, in seconds", 0.5) as null|num
|
||||
var/timeInput = input("Enter the time it takes for the pod to land, in seconds", "Delay Time", initial(temp_pod.landingDelay) * 0.1) as null|num
|
||||
if (isnull(timeInput))
|
||||
return
|
||||
if (!isnum(timeInput)) //Sanitize input, if it doesnt check out, error and set to default
|
||||
@@ -277,7 +300,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if (temp_pod.openingDelay != initial(temp_pod.openingDelay)) //If the opening delay has already been changed when we push the "change value" button, then set it to default
|
||||
temp_pod.openingDelay = initial(temp_pod.openingDelay)
|
||||
return
|
||||
var/timeInput = input("Delay Time", "Enter the time it takes for the pod to open after landing, in seconds", 3) as null|num
|
||||
var/timeInput = input("Enter the time it takes for the pod to open after landing, in seconds", "Delay Time", initial(temp_pod.openingDelay) * 0.1) as null|num
|
||||
if (isnull(timeInput))
|
||||
return
|
||||
if (!isnum(timeInput)) //Sanitize input
|
||||
@@ -289,7 +312,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if (temp_pod.departureDelay != initial(temp_pod.departureDelay)) //If the departure delay has already been changed when we push the "change value" button, then set it to default
|
||||
temp_pod.departureDelay = initial(temp_pod.departureDelay)
|
||||
return
|
||||
var/timeInput = input("Delay Time", "Enter the time it takes for the pod to leave after opening, in seconds", 3) as null|num
|
||||
var/timeInput = input("Enter the time it takes for the pod to leave after opening, in seconds", "Delay Time", initial(temp_pod.departureDelay) * 0.1) as null|num
|
||||
if (isnull(timeInput))
|
||||
return
|
||||
if (!isnum(timeInput))
|
||||
@@ -299,31 +322,57 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
. = TRUE
|
||||
|
||||
////////////////////////////ADMIN SOUNDS//////////////////
|
||||
if("fallingSound") //Admin sound from a local file that plays when the pod falls
|
||||
if ((temp_pod.fallingSound) != initial(temp_pod.fallingSound))
|
||||
temp_pod.fallingSound = initial(temp_pod.fallingSound)
|
||||
temp_pod.fallingSoundLength = initial(temp_pod.fallingSoundLength)
|
||||
return
|
||||
var/soundInput = input(holder, "Please pick a sound file to play when the pod lands! NOTICE: Take a note of exactly how long the sound is.", "Pick a Sound File") as null|sound
|
||||
if (isnull(soundInput))
|
||||
return
|
||||
var/timeInput = input(holder, "What is the exact length of the sound file, in seconds. This number will be used to line the sound up so that it finishes right as the pod lands!", "Pick a Sound File", 0.3) as null|num
|
||||
if (isnull(timeInput))
|
||||
return
|
||||
if (!isnum(timeInput))
|
||||
alert(usr, "That wasnt a number! Value set to default ([initial(temp_pod.fallingSoundLength)*0.1]) instead.")
|
||||
temp_pod.fallingSound = soundInput
|
||||
temp_pod.fallingSoundLength = 10 * timeInput
|
||||
. = TRUE
|
||||
if("landingSound") //Admin sound from a local file that plays when the pod lands
|
||||
if (!isnull(temp_pod.landingSound))
|
||||
temp_pod.landingSound = null
|
||||
return
|
||||
temp_pod.landingSound = input(holder, "Please pick a sound file to play when the pod lands! I reccomend a nice \"oh shit, i'm sorry\", incase you hit someone with the pod.", "Pick a Sound File") as null|sound
|
||||
var/soundInput = input(holder, "Please pick a sound file to play when the pod lands! I reccomend a nice \"oh shit, i'm sorry\", incase you hit someone with the pod.", "Pick a Sound File") as null|sound
|
||||
if (isnull(soundInput))
|
||||
return
|
||||
temp_pod.landingSound = soundInput
|
||||
. = TRUE
|
||||
if("openingSound") //Admin sound from a local file that plays when the pod opens
|
||||
if (!isnull(temp_pod.openingSound))
|
||||
temp_pod.openingSound = null
|
||||
return
|
||||
temp_pod.openingSound = input(holder, "Please pick a sound file to play when the pod opens! I reccomend a stock sound effect of kids cheering at a party, incase your pod is full of fun exciting stuff!", "Pick a Sound File") as null|sound
|
||||
var/soundInput = input(holder, "Please pick a sound file to play when the pod opens! I reccomend a stock sound effect of kids cheering at a party, incase your pod is full of fun exciting stuff!", "Pick a Sound File") as null|sound
|
||||
if (isnull(soundInput))
|
||||
return
|
||||
temp_pod.openingSound = soundInput
|
||||
. = TRUE
|
||||
if("leavingSound") //Admin sound from a local file that plays when the pod leaves
|
||||
if (!isnull(temp_pod.leavingSound))
|
||||
temp_pod.leavingSound = null
|
||||
return
|
||||
temp_pod.leavingSound = input(holder, "Please pick a sound file to play when the pod leaves! I reccomend a nice slide whistle sound, especially if you're using the reverse pod effect.", "Pick a Sound File") as null|sound
|
||||
var/soundInput = input(holder, "Please pick a sound file to play when the pod leaves! I reccomend a nice slide whistle sound, especially if you're using the reverse pod effect.", "Pick a Sound File") as null|sound
|
||||
if (isnull(soundInput))
|
||||
return
|
||||
temp_pod.leavingSound = soundInput
|
||||
. = TRUE
|
||||
if("soundVolume") //Admin sound from a local file that plays when the pod leaves
|
||||
if (temp_pod.soundVolume != 50)
|
||||
temp_pod.soundVolume = 50
|
||||
if (temp_pod.soundVolume != initial(temp_pod.soundVolume))
|
||||
temp_pod.soundVolume = initial(temp_pod.soundVolume)
|
||||
return
|
||||
temp_pod.soundVolume = input(holder, "Please pick a volume. Default is between 1 and 100 with 50 being average, but pick whatever. I'm a notification, not a cop. If you still cant hear your sound, consider turning on the Quiet effect. It will silence all pod sounds except for the custom admin ones set by the previous three buttons.", "Pick Admin Sound Volume") as null|num
|
||||
if (isnull(temp_pod.soundVolume))
|
||||
temp_pod.soundVolume = 50
|
||||
var/soundInput = input(holder, "Please pick a volume. Default is between 1 and 100 with 80 being average, but pick whatever. I'm a notification, not a cop. If you still cant hear your sound, consider turning on the Quiet effect. It will silence all pod sounds except for the custom admin ones set by the previous three buttons.", "Pick Admin Sound Volume") as null|num
|
||||
if (isnull(soundInput))
|
||||
return
|
||||
temp_pod.soundVolume = soundInput
|
||||
. = TRUE
|
||||
////////////////////////////STYLE CHANGES//////////////////
|
||||
//Style is a value that is used to keep track of what the pod is supposed to look like. It can be used with the POD_STYLES list (in cargo.dm defines)
|
||||
@@ -364,6 +413,9 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if("styleGondola")
|
||||
temp_pod.setStyle(STYLE_GONDOLA)
|
||||
. = TRUE
|
||||
if("styleSeeThrough")
|
||||
temp_pod.setStyle(STYLE_SEETHROUGH)
|
||||
. = TRUE
|
||||
if("refresh") //Refresh the Pod bay. User should press this if they spawn something new in the centcom bay. Automatically called whenever the user launches a pod
|
||||
refreshBay()
|
||||
. = TRUE
|
||||
@@ -403,12 +455,17 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if(left_click) //When we left click:
|
||||
preLaunch() //Fill the acceptableTurfs list from the orderedArea list. Then, fill up the launchList list with items from the acceptableTurfs list based on the manner of launch (ordered, random, etc)
|
||||
if (!isnull(specificTarget))
|
||||
target = get_turf(specificTarget) //if we have a specific mob target, then always launch the pod at the turf of the mob
|
||||
target = get_turf(specificTarget) //if we have a specific target, then always launch the pod at the turf of the target
|
||||
else if (target)
|
||||
target = get_turf(target) //Make sure we're aiming at a turf rather than an item or effect or something
|
||||
else
|
||||
return //if target is null and we don't have a specific target, cancel
|
||||
|
||||
if (effectAnnounce)
|
||||
deadchat_broadcast("<span class='deadsay'>A special package is being launched at the station!</span>", turf_target = target)
|
||||
var/list/bouttaDie = list()
|
||||
for (var/mob/living/M in target)
|
||||
bouttaDie.Add(M)
|
||||
supplypod_punish_log(bouttaDie)
|
||||
if (!effectBurst) //If we're not using burst mode, just launch normally.
|
||||
launch(target)
|
||||
else
|
||||
@@ -422,7 +479,6 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
else
|
||||
launch(target) //If we couldn't locate an adjacent turf, just launch at the normal target
|
||||
sleep(rand()*2) //looks cooler than them all appearing at once. Gives the impression of burst fire.
|
||||
log_admin("Centcom Supplypod Launch: [key_name(user)] launched a supplypod in [AREACOORD(target)]")
|
||||
|
||||
/datum/centcom_podlauncher/proc/refreshBay() //Called whenever the bay is switched, as well as wheneber a pod is launched
|
||||
orderedArea = createOrderedArea(bay) //Create an ordered list full of turfs form the bay
|
||||
@@ -486,11 +542,11 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if (launchClone) //We arent launching the actual items from the bay, rather we are creating clones and launching those
|
||||
for (var/atom/movable/O in launchList)
|
||||
DuplicateObject(O).forceMove(toLaunch) //Duplicate each atom/movable in launchList and forceMove them into the supplypod
|
||||
new /obj/effect/DPtarget(A, toLaunch) //Create the DPTarget, which will eventually forceMove the temp_pod to it's location
|
||||
else
|
||||
new /obj/effect/abstract/DPtarget(A, toLaunch) //Create the DPTarget, which will eventually forceMove the temp_pod to it's location
|
||||
else
|
||||
for (var/atom/movable/O in launchList) //If we aren't cloning the objects, just go through the launchList
|
||||
O.forceMove(toLaunch) //and forceMove any atom/moveable into the supplypod
|
||||
new /obj/effect/DPtarget(A, toLaunch) //Then, create the DPTarget effect, which will eventually forceMove the temp_pod to it's location
|
||||
new /obj/effect/abstract/DPtarget(A, toLaunch) //Then, create the DPTarget effect, which will eventually forceMove the temp_pod to it's location
|
||||
if (launchClone)
|
||||
launchCounter++ //We only need to increment launchCounter if we are cloning objects.
|
||||
//If we aren't cloning objects, taking and removing the first item each time from the acceptableTurfs list will inherently iterate through the list in order
|
||||
@@ -508,4 +564,26 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
updateCursor(FALSE) //Make sure our moues cursor resets to default. False means we are not in launch mode
|
||||
qdel(temp_pod) //Delete the temp_pod
|
||||
qdel(selector) //Delete the selector effect
|
||||
. = ..()
|
||||
. = ..()
|
||||
|
||||
/datum/centcom_podlauncher/proc/supplypod_punish_log(var/list/whoDyin)
|
||||
var/podString = effectBurst ? "5 pods" : "a pod"
|
||||
var/whomString = ""
|
||||
if (LAZYLEN(whoDyin))
|
||||
for (var/mob/living/M in whoDyin)
|
||||
whomString += "[key_name(M)], "
|
||||
|
||||
var/delayString = temp_pod.landingDelay == initial(temp_pod.landingDelay) ? "" : " Delay=[temp_pod.landingDelay*0.1]s"
|
||||
var/damageString = temp_pod.damage == 0 ? "" : " Dmg=[temp_pod.damage]"
|
||||
var/explosionString = ""
|
||||
var/explosion_sum = temp_pod.explosionSize[1] + temp_pod.explosionSize[2] + temp_pod.explosionSize[3] + temp_pod.explosionSize[4]
|
||||
if (explosion_sum != 0)
|
||||
explosionString = " Boom=|"
|
||||
for (var/X in temp_pod.explosionSize)
|
||||
explosionString += "[X]|"
|
||||
|
||||
var/msg = "launched [podString][whomString].[delayString][damageString][explosionString]]"
|
||||
message_admins("[key_name_admin(usr)] [msg] in [AREACOORD(specificTarget)].")
|
||||
if (!isemptylist(whoDyin))
|
||||
for (var/mob/living/M in whoDyin)
|
||||
admin_ticket_log(M, "[key_name_admin(usr)] [msg]")
|
||||
|
||||
@@ -183,7 +183,7 @@
|
||||
LZ = pick(empty_turfs)
|
||||
if (SO.pack.cost <= SSshuttle.points && LZ)//we need to call the cost check again because of the CHECK_TICK call
|
||||
SSshuttle.points -= SO.pack.cost
|
||||
new /obj/effect/DPtarget(LZ, podType, SO)
|
||||
new /obj/effect/abstract/DPtarget(LZ, podType, SO)
|
||||
. = TRUE
|
||||
update_icon()
|
||||
else
|
||||
@@ -200,7 +200,8 @@
|
||||
for(var/i in 1 to MAX_EMAG_ROCKETS)
|
||||
var/LZ = pick(empty_turfs)
|
||||
LAZYREMOVE(empty_turfs, LZ)
|
||||
new /obj/effect/DPtarget(LZ, podType, SO)
|
||||
new /obj/effect/abstract/DPtarget(LZ, podType, SO)
|
||||
. = TRUE
|
||||
update_icon()
|
||||
CHECK_TICK
|
||||
|
||||
|
||||
@@ -39,15 +39,22 @@
|
||||
set name = "Release Contents"
|
||||
set category = "Gondola"
|
||||
set desc = "Release any contents stored within your vast belly."
|
||||
linked_pod.open(src, manual = TRUE)
|
||||
linked_pod.open(src, forced = TRUE)
|
||||
|
||||
/mob/living/simple_animal/pet/gondola/gondolapod/examine(mob/user)
|
||||
..()
|
||||
if (contents.len)
|
||||
to_chat(user, "<span class='notice'>It looks like it hasn't made its delivery yet.</b><span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>It looks like it has already made its delivery.</b><span>")
|
||||
|
||||
/mob/living/simple_animal/pet/gondola/gondolapod/verb/check()
|
||||
set name = "Count Contents"
|
||||
set category = "Gondola"
|
||||
set desc = "Take a deep look inside youself, and count up what's inside"
|
||||
var/total = contents.len
|
||||
if (total)
|
||||
to_chat(src, "<span class='notice'>You detect [total] object[total > 1 ? "s" : ""] within your incredibly vast belly.</span>")
|
||||
if (total)
|
||||
to_chat(src, "<span class='notice'>You detect [total] object\s within your incredibly vast belly.</span>")
|
||||
else
|
||||
to_chat(src, "<span class='notice'>A closer look inside yourself reveals... nothing.</span>")
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
var/access_any = FALSE //Do we care about access?
|
||||
var/list/contains = null //What items are in the crate
|
||||
var/crate_name = "crate" //The crate that comes with each order
|
||||
var/crate_desc = "" //Crate's description
|
||||
var/desc = ""//no desc by default
|
||||
var/crate_type = /obj/structure/closet/crate //what kind of crate - Locked crates needed for access locked crates
|
||||
var/dangerous = FALSE // Should we message admins?
|
||||
@@ -19,6 +20,8 @@
|
||||
/datum/supply_pack/proc/generate(atom/A)
|
||||
var/obj/structure/closet/crate/C = new crate_type(A)
|
||||
C.name = crate_name
|
||||
if(crate_desc)
|
||||
C.desc = crate_desc
|
||||
if(access)
|
||||
C.req_access = list(access)
|
||||
if(access_any)
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
crate_name = "swat crate"
|
||||
|
||||
/datum/supply_pack/security/armory/swattasers //Lesser AEG tbh
|
||||
name = "SWAT tatical tasers Crate"
|
||||
name = "SWAT tactical tasers Crate"
|
||||
desc = "Contains two tactical energy gun, these guns are able to tase, disable and lethal as well as hold a seclight. Requires Armory access to open."
|
||||
cost = 7000
|
||||
contains = list(/obj/item/gun/energy/e_gun/stun,
|
||||
|
||||
@@ -289,6 +289,30 @@
|
||||
crate_name = "wizard costume crate"
|
||||
crate_type = /obj/structure/closet/crate/wooden
|
||||
|
||||
/datum/supply_pack/costumes_toys/magicka
|
||||
name = "Proper Wizard Costume Crate"
|
||||
desc = "Up to four crewmates take on a grand adventure to save their world from certain doom using the robes in this crate!"
|
||||
cost = 7000
|
||||
contraband = TRUE
|
||||
contains = list(/obj/item/staff,
|
||||
/obj/item/staff,
|
||||
/obj/item/staff,
|
||||
/obj/item/staff,
|
||||
/obj/item/clothing/shoes/sandal,
|
||||
/obj/item/clothing/shoes/sandal,
|
||||
/obj/item/clothing/shoes/sandal,
|
||||
/obj/item/clothing/shoes/sandal,
|
||||
/obj/item/clothing/suit/notwizrobe,
|
||||
/obj/item/clothing/head/notwizard,
|
||||
/obj/item/clothing/suit/notwizrobe/red,
|
||||
/obj/item/clothing/head/notwizard/red,
|
||||
/obj/item/clothing/suit/notwizrobe/yellow,
|
||||
/obj/item/clothing/head/notwizard/yellow,
|
||||
/obj/item/clothing/suit/notwizrobe/black,
|
||||
/obj/item/clothing/head/notwizard/black)
|
||||
crate_name = "proper wizard costume crate"
|
||||
crate_type = /obj/structure/closet/crate/wooden
|
||||
|
||||
/datum/supply_pack/costumes_toys/randomised/fill(obj/structure/closet/crate/C)
|
||||
var/list/L = contains.Copy()
|
||||
for(var/i in 1 to num_contained)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
/datum/supply_pack/emergency/vehicle
|
||||
name = "Biker Gang Kit" //TUNNEL SNAKES OWN THIS TOWN
|
||||
desc = "TUNNEL SNAKES OWN THIS TOWN. Contains an unbranded All Terrain Vehicle, and a complete gang outfit -- consists of black gloves, a menacing skull bandanna, and a SWEET leather overcoat!"
|
||||
cost = 2500
|
||||
cost = 7500
|
||||
contraband = TRUE
|
||||
contains = list(/obj/vehicle/ridden/atv,
|
||||
/obj/item/key,
|
||||
|
||||
@@ -169,12 +169,22 @@
|
||||
crate_name = "tesla generator crate"
|
||||
|
||||
/datum/supply_pack/engine/teg
|
||||
name = "Thermoelectric Generator"
|
||||
desc = "Contains your very own Thermoelectric Generator. Time to turn cargo into a blazing hellfire, perhaps?"
|
||||
cost = 4000
|
||||
contains = list(/obj/machinery/power/generator)
|
||||
name = "Thermoelectric Generator Assembly"
|
||||
desc = "Contains your very own Thermoelectric Generator Assembly. Time to turn cargo into a blazing hellfire, perhaps?"
|
||||
cost = 3000
|
||||
contains = list(/obj/item/paper/teg,
|
||||
/obj/item/circuitboard/machine/generator,
|
||||
/obj/item/circuitboard/machine/circulator,
|
||||
/obj/item/circuitboard/machine/circulator,
|
||||
/obj/item/stack/cable_coil,
|
||||
/obj/item/stack/sheet/metal/twenty)
|
||||
crate_name = "thermoelectric generator crate"
|
||||
|
||||
/obj/item/paper/teg
|
||||
info = "*The seemingly useful notes have been scribbled over with red and black crayon. Hmm.*"
|
||||
name = "TEG Instructions"
|
||||
color = "red"
|
||||
|
||||
/datum/supply_pack/engine/energy_harvester
|
||||
name = "Energy Harvesting Module"
|
||||
desc = "A Device which upon connection to a node, will harvest the energy and send it to engineerless stations in return for credits, derived from a syndicate powersink model."
|
||||
|
||||
@@ -91,15 +91,11 @@
|
||||
crate_name = "insulated gloves crate"
|
||||
crate_type = /obj/structure/closet/crate/engineering/electrical
|
||||
|
||||
/obj/item/stock_parts/cell/inducer_supply
|
||||
maxcharge = 5000
|
||||
charge = 5000
|
||||
|
||||
/datum/supply_pack/engineering/inducers
|
||||
name = "NT-75 Electromagnetic Power Inducers Crate"
|
||||
desc = "No rechargers? No problem, with the NT-75 EPI, you can recharge any standard cell-based equipment anytime, anywhere. Contains two Inducers."
|
||||
cost = 2300
|
||||
contains = list(/obj/item/inducer/sci {cell_type = /obj/item/stock_parts/cell/inducer_supply; opened = 0}, /obj/item/inducer/sci {cell_type = /obj/item/stock_parts/cell/inducer_supply; opened = 0}) //FALSE doesn't work in modified type paths apparently.
|
||||
contains = list(/obj/item/inducer/sci/supply, /obj/item/inducer/sci/supply)
|
||||
crate_name = "inducer crate"
|
||||
crate_type = /obj/structure/closet/crate/engineering/electrical
|
||||
|
||||
@@ -133,17 +129,6 @@
|
||||
crate_name = "power tools crate"
|
||||
crate_type = /obj/structure/closet/crate/secure/engineering
|
||||
|
||||
/datum/supply_pack/engineering/siezedpower
|
||||
name = "Seized Power Cell Crate"
|
||||
desc = "We took the means of power! Contains three high-voltage plus power cells."
|
||||
cost = 1300
|
||||
contraband = TRUE
|
||||
contains = list(/obj/item/stock_parts/cell/high/plus,
|
||||
/obj/item/stock_parts/cell/high/plus,
|
||||
/obj/item/stock_parts/cell/high/plus)
|
||||
crate_name = "seized crate"
|
||||
crate_type = /obj/structure/closet/crate/engineering/electrical
|
||||
|
||||
/datum/supply_pack/engineering/shuttle_engine
|
||||
name = "Shuttle Engine Crate"
|
||||
desc = "Through advanced bluespace-shenanigans, our engineers have managed to fit an entire shuttle engine into one tiny little crate. Requires CE access to open."
|
||||
@@ -153,22 +138,6 @@
|
||||
crate_name = "shuttle engine crate"
|
||||
crate_type = /obj/structure/closet/crate/secure/engineering
|
||||
|
||||
/datum/supply_pack/engineering/seizedproduction
|
||||
name = "The Means of Production"
|
||||
desc = "We will win for we have took over the production! Contains five metal sheets, five wire, three matter bins, one manipulator and one sheet of glass."
|
||||
cost = 1500
|
||||
contraband = TRUE
|
||||
contains = list(/obj/item/stock_parts/cell/high/plus,
|
||||
/obj/item/circuitboard/machine/autolathe,
|
||||
/obj/item/stack/cable_coil/random/five,
|
||||
/obj/item/stack/sheet/metal/five,
|
||||
/obj/item/stock_parts/matter_bin,
|
||||
/obj/item/stock_parts/matter_bin,
|
||||
/obj/item/stock_parts/matter_bin,
|
||||
/obj/item/stock_parts/manipulator,
|
||||
/obj/item/stack/sheet/glass,)
|
||||
crate_name = "seized crate"
|
||||
|
||||
/datum/supply_pack/engineering/tools
|
||||
name = "Toolbox Crate"
|
||||
desc = "Any robust spaceman is never far from their trusty toolbox. Contains three electrical toolboxes and three mechanical toolboxes."
|
||||
|
||||
@@ -30,6 +30,13 @@
|
||||
contains = list(/obj/item/stack/sheet/metal/fifty)
|
||||
crate_name = "metal sheets crate"
|
||||
|
||||
/datum/supply_pack/materials/gmushroom50
|
||||
name = "50 Mushroom Planks"
|
||||
desc = "Looks like wood AND is fire proof? Of course you need fifty mushroom planks!"
|
||||
cost = 1700
|
||||
contains = list(/obj/item/stack/sheet/mineral/gmushroom/fifty)
|
||||
crate_name = "mushroom planks crate"
|
||||
|
||||
/datum/supply_pack/materials/plasteel20
|
||||
name = "20 Plasteel Sheets"
|
||||
desc = "Reinforce the station's integrity with twenty plasteel sheets!"
|
||||
@@ -51,6 +58,13 @@
|
||||
contains = list(/obj/item/stack/sheet/plastic/fifty)
|
||||
crate_name = "plastic sheets crate"
|
||||
|
||||
/datum/supply_pack/materials/plaswood50
|
||||
name = "50 Plaswood Planks"
|
||||
desc = "Who need metal when you can have fifty plaswood planks?"
|
||||
cost = 9000
|
||||
contains = list(/obj/item/stack/sheet/mineral/plaswood/fifty)
|
||||
crate_name = "Plaswood crate"
|
||||
|
||||
/datum/supply_pack/materials/sandstone30
|
||||
name = "30 Sandstone Blocks"
|
||||
desc = "Neither sandy nor stoney, these thirty blocks will still get the job done."
|
||||
@@ -58,6 +72,13 @@
|
||||
contains = list(/obj/item/stack/sheet/mineral/sandstone/thirty)
|
||||
crate_name = "sandstone blocks crate"
|
||||
|
||||
/datum/supply_pack/materials/shadoww50
|
||||
name = "50 Shadow Wood Planks"
|
||||
desc = "Time to bring the dark side with fifty shadow wooden planks!"
|
||||
cost = 1450
|
||||
contains = list(/obj/item/stack/sheet/mineral/shadoww/fifty)
|
||||
crate_name = "Shadown wood planks crate"
|
||||
|
||||
/datum/supply_pack/materials/wood50
|
||||
name = "50 Wood Planks"
|
||||
desc = "Turn cargo's boring metal groundwork into beautiful panelled flooring and much more with fifty wooden planks!"
|
||||
@@ -68,13 +89,25 @@
|
||||
/datum/supply_pack/organic/rawcotton
|
||||
name = "Raw Cotton Crate"
|
||||
desc = "Plushies have been on the down in the market, and now due to a flood of raw cotton the price of it is so cheap, its a steal! Contains 40 raw cotton sheets."
|
||||
cost = 800 // 100 net cost, 20 x 20 = 400. 300 proffit if turned into cloth sheets or more if turned to silk then 10 x 200 = 2000
|
||||
cost = 800 // 100 net cost, 20 x 20 = 400. 300 profit if turned into cloth sheets or more if turned to silk then 10 x 200 = 2000
|
||||
contains = list(/obj/item/stack/sheet/cotton/thirty,
|
||||
/obj/item/stack/sheet/cotton/ten
|
||||
)
|
||||
crate_name = "cotton crate"
|
||||
crate_type = /obj/structure/closet/crate/hydroponics
|
||||
|
||||
/datum/supply_pack/organic/rawcotton/bulk
|
||||
name = "Bulk Raw Cotton Crate"
|
||||
desc = "Plushies are more down in the market than ever before; bulk cotton now for use! Contains 100 raw cotton sheets."
|
||||
cost = 1700 //Same math as before, but since it's bulk, you get a 100 credit discount to encourage bulk buys. Welcome to space Costco.
|
||||
contains = list(/obj/item/stack/sheet/cotton/thirty,
|
||||
/obj/item/stack/sheet/cotton/thirty,
|
||||
/obj/item/stack/sheet/cotton/thirty,
|
||||
/obj/item/stack/sheet/cotton/ten
|
||||
)
|
||||
crate_name = "bulk cotton crate"
|
||||
crate_type = /obj/structure/closet/crate/hydroponics
|
||||
|
||||
/datum/supply_pack/organic/rawlumber
|
||||
name = "Raw Lumber Crate"
|
||||
desc = "Raw logs from towercaps. Contains fifty logs."
|
||||
|
||||
@@ -40,9 +40,10 @@
|
||||
|
||||
/datum/supply_pack/medical/bloodpacks
|
||||
name = "Blood Pack Variety Crate"
|
||||
desc = "Contains ten different blood packs for reintroducing blood to patients."
|
||||
desc = "Contains nine different blood packs for reintroducing blood to patients, plus two universal synthetic blood packs."
|
||||
cost = 3000
|
||||
contains = list(/obj/item/reagent_containers/blood/random,
|
||||
contains = list(/obj/item/reagent_containers/blood/synthetics,
|
||||
/obj/item/reagent_containers/blood/synthetics,
|
||||
/obj/item/reagent_containers/blood/random,
|
||||
/obj/item/reagent_containers/blood/APlus,
|
||||
/obj/item/reagent_containers/blood/AMinus,
|
||||
@@ -56,18 +57,6 @@
|
||||
crate_name = "blood freezer"
|
||||
crate_type = /obj/structure/closet/crate/freezer
|
||||
|
||||
/datum/supply_pack/medical/bloodpackssynth
|
||||
name = "Synthetics Blood Pack Crate"
|
||||
desc = "Contains five synthetics blood packs for reintroducing blood to patients."
|
||||
cost = 3000
|
||||
contains = list(/obj/item/reagent_containers/blood/synthetics,
|
||||
/obj/item/reagent_containers/blood/synthetics,
|
||||
/obj/item/reagent_containers/blood/synthetics,
|
||||
/obj/item/reagent_containers/blood/synthetics,
|
||||
/obj/item/reagent_containers/blood/synthetics)
|
||||
crate_name = "blood freezer"
|
||||
crate_type = /obj/structure/closet/crate/freezer
|
||||
|
||||
/datum/supply_pack/medical/defibs
|
||||
name = "Defibrillator Crate"
|
||||
desc = "Contains two defibrillators for bringing the recently deceased back to life."
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
contains = list(/obj/item/pen/fountain/captain)
|
||||
crate_name = "captain pen"
|
||||
crate_type = /obj/structure/closet/crate/secure/weapon //It is a combat pen
|
||||
|
||||
|
||||
/datum/supply_pack/misc/dueling_stam
|
||||
name = "Dueling Pistols"
|
||||
desc = "Resolve all your quarrels with some nonlethal fun."
|
||||
@@ -267,7 +267,7 @@
|
||||
|
||||
/datum/supply_pack/misc/lewd
|
||||
name = "Lewd Crate" // OwO
|
||||
desc = "Psss want to have a good time with your sluts? Well I got what you want! Maid clothing, dildos, collars and more!"
|
||||
desc = "Psst, want to have a good time with your sluts? Well I got what you want! Maid clothing, dildos, collars and more!"
|
||||
cost = 5000
|
||||
contraband = TRUE
|
||||
contains = list(/obj/item/dildo/custom,
|
||||
@@ -301,7 +301,7 @@
|
||||
/datum/supply_pack/misc/religious_supplies
|
||||
name = "Religious Supplies Crate"
|
||||
desc = "Keep your local chaplain happy and well-supplied, lest they call down judgement upon your cargo bay. Contains two bottles of holywater, bibles, chaplain robes, and burial garmets."
|
||||
cost = 4000 // it costs so much because the Space Church is ran by Space Jews
|
||||
cost = 4000
|
||||
contains = list(/obj/item/reagent_containers/food/drinks/bottle/holywater,
|
||||
/obj/item/reagent_containers/food/drinks/bottle/holywater,
|
||||
/obj/item/storage/book/bible/booze,
|
||||
@@ -311,19 +311,6 @@
|
||||
)
|
||||
crate_name = "religious supplies crate"
|
||||
|
||||
/datum/supply_pack/misc/randomised/promiscuous
|
||||
name = "Promiscuous Organs"
|
||||
desc = "Do YOU want to have more genital? Well we have just the thing for you~. This crate has two autosurgeon, that will let you have a new sex, organ to impress that hot stud and or chick."
|
||||
cost = 4000 //Only get 2!
|
||||
contraband = TRUE
|
||||
var/num_contained = 2
|
||||
contains = list(/obj/item/autosurgeon/penis,
|
||||
/obj/item/autosurgeon/testicles,
|
||||
/obj/item/autosurgeon/vagina,
|
||||
/obj/item/autosurgeon/breasts,
|
||||
/obj/item/autosurgeon/womb)
|
||||
crate_name = "promiscuous organs"
|
||||
|
||||
/datum/supply_pack/misc/shower
|
||||
name = "Shower Supplies"
|
||||
desc = "Everyone needs a bit of R&R. Make sure you get can get yours by ordering this crate filled with towels, rubber duckies, and some soap!"
|
||||
@@ -363,6 +350,19 @@
|
||||
/obj/item/toner)
|
||||
crate_name = "toner crate"
|
||||
|
||||
/datum/supply_pack/misc/wedding
|
||||
name = "Wedding Crate"
|
||||
desc = "Almost everything you need to host a wedding! Don't forget a ring!"
|
||||
cost = 1500
|
||||
contains = list(/obj/item/clothing/under/wedding_dress,
|
||||
/obj/item/clothing/under/tuxedo,
|
||||
/obj/item/storage/belt/cummerbund,
|
||||
/obj/item/bouquet,
|
||||
/obj/item/bouquet/sunflower,
|
||||
/obj/item/bouquet/poppy,
|
||||
/obj/item/reagent_containers/food/drinks/bottle/champagne)
|
||||
crate_name = "wedding crate"
|
||||
|
||||
/datum/supply_pack/misc/diamondring
|
||||
name = "Diamond Ring"
|
||||
desc = "Show them your love is like a diamond: unbreakable and forever lasting. Shipped straight from child slave cartels in the space african mines."
|
||||
@@ -379,3 +379,53 @@
|
||||
/obj/item/storage/fancy/ringbox/silver
|
||||
)
|
||||
crate_name = "jewelry crate"
|
||||
|
||||
/datum/supply_pack/misc/carpet_exotic
|
||||
name = "Exotic Carpet Crate"
|
||||
desc = "Exotic carpets straight from Space Russia, for all your decorating needs. Contains 100 tiles each of 10 different flooring patterns."
|
||||
cost = 7000
|
||||
contains = list(/obj/item/stack/tile/carpet/blue/fifty,
|
||||
/obj/item/stack/tile/carpet/blue/fifty,
|
||||
/obj/item/stack/tile/carpet/cyan/fifty,
|
||||
/obj/item/stack/tile/carpet/cyan/fifty,
|
||||
/obj/item/stack/tile/carpet/green/fifty,
|
||||
/obj/item/stack/tile/carpet/green/fifty,
|
||||
/obj/item/stack/tile/carpet/orange/fifty,
|
||||
/obj/item/stack/tile/carpet/orange/fifty,
|
||||
/obj/item/stack/tile/carpet/purple/fifty,
|
||||
/obj/item/stack/tile/carpet/purple/fifty,
|
||||
/obj/item/stack/tile/carpet/red/fifty,
|
||||
/obj/item/stack/tile/carpet/red/fifty,
|
||||
/obj/item/stack/tile/carpet/royalblue/fifty,
|
||||
/obj/item/stack/tile/carpet/royalblue/fifty,
|
||||
/obj/item/stack/tile/carpet/royalblack/fifty,
|
||||
/obj/item/stack/tile/carpet/royalblack/fifty,
|
||||
/obj/item/stack/tile/carpet/blackred/fifty,
|
||||
/obj/item/stack/tile/carpet/blackred/fifty,
|
||||
/obj/item/stack/tile/carpet/monochrome/fifty,
|
||||
/obj/item/stack/tile/carpet/monochrome/fifty)
|
||||
crate_name = "exotic carpet crate"
|
||||
|
||||
/datum/supply_pack/misc/carpentry
|
||||
name = "Carpentry Crate"
|
||||
desc = "Make money at cargo by learning some carpentry and making custom furniture."
|
||||
cost = 1000
|
||||
contains = list(/obj/item/carpentry/handsaw,
|
||||
/obj/item/carpentry/hammer,
|
||||
/obj/item/carpentry/glue,
|
||||
/obj/item/carpentry/borer,
|
||||
/obj/item/carpentry/sandpaper)
|
||||
crate_name = "carpentry crate"
|
||||
|
||||
|
||||
/datum/supply_pack/misc/prospacillin //size changing should be hard to achieve; so enjoy the price tag.
|
||||
name = "Prospacillin Bottle"
|
||||
desc = "An extremely expensive solution of growth serum known as Prospacillin. Effects are permanent upon consumption, and growth is slow."
|
||||
cost = 100000
|
||||
contains = list(/obj/item/reagent_containers/food/drinks/prospacillin)
|
||||
|
||||
/datum/supply_pack/misc/diminicillin //size changing should be hard to achieve; so enjoy the price tag.
|
||||
name = "Diminicillin Bottle"
|
||||
desc = "An extremely expensive solution of shrinking serum known as Diminicillin. Effects are permanent upon consumption, and shrinking is slow."
|
||||
cost = 100000
|
||||
contains = list(/obj/item/reagent_containers/food/drinks/diminicillin)
|
||||
|
||||
@@ -196,9 +196,185 @@
|
||||
/obj/item/reagent_containers/food/snacks/grown/strawberry)
|
||||
crate_name = "fruit crate"
|
||||
|
||||
|
||||
//ALIEN-ESQUE SEEDS CRATE
|
||||
/datum/supply_pack/organic/rareseeds
|
||||
name = "Galactic Seeds Crate"
|
||||
desc = "Explore the vastness of space, now condensed into a single crate! Contains at least 4 seeds from random regions of space."
|
||||
cost = 9500 //See fill proc. I know this costs a lot
|
||||
contains = list()
|
||||
crate_name = "galactic seeds crate"
|
||||
crate_desc = "A rectangular steel crate."
|
||||
crate_type = /obj/structure/closet/crate/hydroponics
|
||||
|
||||
/datum/supply_pack/organic/rareseeds/fill(obj/structure/closet/crate/C)
|
||||
. = ..()
|
||||
var/iteration = 0
|
||||
var/common_seeds = list(
|
||||
/obj/item/seeds/wheat,
|
||||
/obj/item/seeds/wheat/oat,
|
||||
/obj/item/seeds/peas,
|
||||
/obj/item/seeds/tea,
|
||||
/obj/item/seeds/coffee,
|
||||
/obj/item/seeds/poppy,
|
||||
/obj/item/seeds/sunflower,
|
||||
/obj/item/seeds/grass,
|
||||
/obj/item/seeds/glowshroom,
|
||||
/obj/item/seeds/cotton,
|
||||
/obj/item/seeds/reishi,
|
||||
/obj/item/seeds/kudzu, //For some sort of realism that kudzu generally grows everywhere, have it a common seed
|
||||
/obj/item/seeds/starthistle)
|
||||
var/uncommon_seeds = list(
|
||||
/obj/item/seeds/chanterelle/jupitercup,
|
||||
/obj/item/seeds/sunflower/moonflower,
|
||||
/obj/item/seeds/bee_balm,
|
||||
/obj/item/seeds/random,
|
||||
/obj/item/seeds/tea/astra,
|
||||
/obj/item/seeds/peas/laugh,
|
||||
/obj/item/seeds/galaxythistle,
|
||||
/obj/item/seeds/coconut,
|
||||
/obj/item/seeds/ambrosia/deus,
|
||||
/obj/item/seeds/aloe,
|
||||
/obj/item/seeds/cannabis/rainbow,
|
||||
/obj/item/seeds/cannabis/ultimate,
|
||||
/obj/item/seeds/angel,
|
||||
/obj/item/seeds/liberty,
|
||||
/obj/item/seeds/plump/walkingmushroom,
|
||||
/obj/item/seeds/chanterelle,
|
||||
/obj/item/seeds/glowshroom/shadowshroom)
|
||||
var/xenoarch_seeds = list(
|
||||
/obj/item/seeds/amauri,
|
||||
/obj/item/seeds/gelthi,
|
||||
/obj/item/seeds/jurlmah,
|
||||
/obj/item/seeds/nofruit,
|
||||
/obj/item/seeds/shand,
|
||||
/obj/item/seeds/surik,
|
||||
/obj/item/seeds/telriis,
|
||||
/obj/item/seeds/thaadra,
|
||||
/obj/item/seeds/vale,
|
||||
/obj/item/seeds/vaporsac)
|
||||
var/lavaland_seeds = list(
|
||||
/obj/item/seeds/lavaland/polypore,
|
||||
/obj/item/seeds/lavaland/porcini,
|
||||
/obj/item/seeds/lavaland/inocybe,
|
||||
/obj/item/seeds/lavaland/ember,
|
||||
/obj/item/seeds/lavaland/cactus)
|
||||
while((prob(68) || iteration <= 4) && iteration <= 15)
|
||||
iteration++
|
||||
var/obj/item/seeds/chosen_seed = null
|
||||
var/obj/item/seeds/cache = null
|
||||
switch(iteration)
|
||||
if(1 to 3)
|
||||
chosen_seed = pick(common_seeds)
|
||||
if(4)
|
||||
if(prob(25))
|
||||
chosen_seed = pick(lavaland_seeds)
|
||||
else
|
||||
chosen_seed = pick(common_seeds)
|
||||
if(5)
|
||||
if(prob(40))
|
||||
chosen_seed = pick(lavaland_seeds)
|
||||
else
|
||||
chosen_seed = pick(common_seeds)
|
||||
if(6)
|
||||
if(prob(70))
|
||||
chosen_seed = pick(common_seeds)
|
||||
else
|
||||
chosen_seed = pick(uncommon_seeds)
|
||||
if(7)
|
||||
if(prob(3))
|
||||
chosen_seed = pick(xenoarch_seeds)
|
||||
else if(prob(40))
|
||||
chosen_seed = pick(common_seeds)
|
||||
else
|
||||
chosen_seed = pick(uncommon_seeds)
|
||||
if(8 to 10)
|
||||
if(prob(8))
|
||||
chosen_seed = pick(xenoarch_seeds)
|
||||
else
|
||||
chosen_seed = pick(uncommon_seeds)
|
||||
if(11 to INFINITY)
|
||||
if(prob(15))
|
||||
chosen_seed = pick(xenoarch_seeds)
|
||||
else if (prob(50))
|
||||
chosen_seed = pick(uncommon_seeds)
|
||||
else
|
||||
chosen_seed = pick(lavaland_seeds)
|
||||
|
||||
new chosen_seed(C)
|
||||
cache = chosen_seed
|
||||
//Make it actually seem like it's from another galaxy with all this stuff
|
||||
if(prob(23) && !istype(chosen_seed, /obj/item/seeds/starthistle))
|
||||
chosen_seed.rarity += 1
|
||||
|
||||
var/mutated = FALSE
|
||||
for(var/datum/plant_gene/G in cache.genes)
|
||||
if(locate(G) in chosen_seed.genes && prob(60))
|
||||
if(prob(50))
|
||||
chosen_seed.unset_mutability(G, PLANT_GENE_EXTRACTABLE)
|
||||
chosen_seed.rarity += 5
|
||||
else if(prob(70))
|
||||
chosen_seed.unset_mutability(G, PLANT_GENE_REMOVABLE)
|
||||
chosen_seed.rarity += 5
|
||||
else if(!istype(G, /datum/plant_gene/core))
|
||||
chosen_seed.forbiddengenes += G.type //Has the slim chance to make this plant unable to produce anything it started out with
|
||||
chosen_seed.genes -= locate(G) in chosen_seed.genes //Sanity check
|
||||
chosen_seed.rarity += 10
|
||||
|
||||
if(prob(65)) //To make this seem even more otherworldly
|
||||
//Our own version of add_random_reagents
|
||||
var/random_amount = round(rand(0, 25), 5) * 0.01
|
||||
if(random_amount <= 0) random_amount = 0.02
|
||||
var/datum/plant_gene/reagent/R = new(get_random_reagent_id(), random_amount)
|
||||
|
||||
if(R.can_add(chosen_seed))
|
||||
chosen_seed.genes += R
|
||||
chosen_seed.rarity += 5
|
||||
else
|
||||
qdel(R)
|
||||
chosen_seed.reagents_from_genes()
|
||||
|
||||
if(prob(3)) //This is insanely rare, but we will use different grow sprites. Probably will fuck something up
|
||||
var/obj/item/seeds/S = pick(subtypesof(/obj/item/seeds))
|
||||
if(prob(85))
|
||||
chosen_seed.plantname = "[pick("Alien", "Supernatural", "Artificial", "Modified")] [S.plantname]"
|
||||
chosen_seed.rarity += 20*(!mutated)
|
||||
else
|
||||
chosen_seed.plantname = S.plantname
|
||||
chosen_seed.growing_icon = S.growing_icon
|
||||
chosen_seed.species = S.species
|
||||
chosen_seed.icon_grow = S.icon_grow
|
||||
chosen_seed.icon_harvest = S.icon_harvest
|
||||
chosen_seed.icon_dead = S.icon_dead
|
||||
chosen_seed.rarity += 35*(!mutated) //woah nelly
|
||||
mutated = TRUE
|
||||
|
||||
else if(prob(70)) //Add basic reagents from grounded sheets, but only small amounts
|
||||
var/A = rand(1, 5)
|
||||
var/chosen_reagent
|
||||
switch(A)
|
||||
if(1)
|
||||
chosen_reagent = /datum/reagent/toxin/plasma
|
||||
if(2)
|
||||
chosen_reagent = /datum/reagent/uranium
|
||||
if(3)
|
||||
chosen_reagent = /datum/reagent/iron
|
||||
if(4)
|
||||
chosen_reagent = /datum/reagent/gold
|
||||
if(5)
|
||||
chosen_reagent = /datum/reagent/cellulose
|
||||
var/datum/plant_gene/reagent/R = new(chosen_reagent, A*0.02)
|
||||
if(R.can_add(chosen_seed))
|
||||
chosen_seed.genes += R
|
||||
chosen_seed.rarity += 5
|
||||
else
|
||||
qdel(R)
|
||||
chosen_seed.reagents_from_genes()
|
||||
//All in a while() loop! Very efficient I know
|
||||
|
||||
/datum/supply_pack/organic/grill
|
||||
name = "Grilling Starter Kit"
|
||||
desc = "Hey dad I'm Hungry. Hi Hungry I'm THE NEW GRILLING STARTER KIT ONLY 5000 BUX GET NOW! Contains a cooking grill and five fuel coal sheets."
|
||||
desc = "Hey dad, I'm Hungry. Hi Hungry I'm THE NEW GRILLING STARTER KIT ONLY 5000 BUX GET NOW! Contains a cooking grill and five fuel coal sheets."
|
||||
cost = 3000
|
||||
crate_type = /obj/structure/closet/crate
|
||||
contains = list(/obj/item/stack/sheet/mineral/coal/five,
|
||||
@@ -277,11 +453,9 @@
|
||||
|
||||
/datum/supply_pack/organic/hydroponics
|
||||
name = "Hydroponics Crate"
|
||||
desc = "Supplies for growing a great garden! Contains two bottles of ammonia, two Plant-B-Gone spray bottles, a hatchet, cultivator, plant analyzer, as well as a pair of leather gloves and a botanist's apron."
|
||||
desc = "Supplies for growing a great garden! Contains two bottles of ammonia, a hatchet, cultivator, plant analyzer, as well as a pair of leather gloves and a botanist's apron."
|
||||
cost = 1750
|
||||
contains = list(/obj/item/reagent_containers/spray/plantbgone,
|
||||
/obj/item/reagent_containers/spray/plantbgone,
|
||||
/obj/item/reagent_containers/glass/bottle/ammonia,
|
||||
contains = list(/obj/item/reagent_containers/glass/bottle/ammonia,
|
||||
/obj/item/reagent_containers/glass/bottle/ammonia,
|
||||
/obj/item/hatchet,
|
||||
/obj/item/cultivator,
|
||||
@@ -326,6 +500,33 @@
|
||||
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass)
|
||||
crate_name = "kitchen cutlery deluxe set"
|
||||
|
||||
/datum/supply_pack/organic/hydroponics/maintgarden
|
||||
name = "Maintenance Garden Crate"
|
||||
desc = "Set up your own tiny paradise with do-it-yourself botany kit. Contains sandstone for dirt plots, pest spray, ammonia, a portable seed generator, basic botanical tools, and some seeds to start off with."
|
||||
cost = 2700
|
||||
contains = list(/obj/item/storage/bag/plants/portaseeder,
|
||||
/obj/item/reagent_containers/spray/pestspray,
|
||||
/obj/item/stack/sheet/mineral/sandstone/twelve,
|
||||
/obj/item/reagent_containers/glass/bucket,
|
||||
/obj/item/reagent_containers/glass/bottle/ammonia,
|
||||
/obj/item/reagent_containers/glass/bottle/ammonia,
|
||||
/obj/item/hatchet,
|
||||
/obj/item/cultivator,
|
||||
/obj/item/plant_analyzer,
|
||||
/obj/item/clothing/gloves/botanic_leather,
|
||||
/obj/item/clothing/suit/apron,
|
||||
/obj/item/flashlight,
|
||||
/obj/item/seeds/carrot,
|
||||
/obj/item/seeds/carrot,
|
||||
/obj/item/seeds/tower,
|
||||
/obj/item/seeds/tower,
|
||||
/obj/item/seeds/watermelon,
|
||||
/obj/item/seeds/watermelon,
|
||||
/obj/item/seeds/grass,
|
||||
/obj/item/seeds/grass)
|
||||
crate_name = "maint garden crate"
|
||||
crate_type = /obj/structure/closet/crate/hydroponics
|
||||
|
||||
/datum/supply_pack/organic/mre
|
||||
name = "MRE supply kit (emergency rations)"
|
||||
desc = "The lights are out. Oxygen's running low. You've run out of food except space weevils. Don't let this be you! Order our NT branded MRE kits today! This pack contains 5 MRE packs with a randomized menu and an oxygen tank."
|
||||
@@ -386,8 +587,8 @@
|
||||
|
||||
/datum/supply_pack/organic/seeds
|
||||
name = "Seeds Crate"
|
||||
desc = "Big things have small beginnings. Contains thirteen different seeds."
|
||||
cost = 1250
|
||||
desc = "Big things have small beginnings. Contains fourteen different seeds."
|
||||
cost = 1300
|
||||
contains = list(/obj/item/seeds/chili,
|
||||
/obj/item/seeds/berry,
|
||||
/obj/item/seeds/corn,
|
||||
@@ -398,7 +599,8 @@
|
||||
/obj/item/seeds/wheat/rice,
|
||||
/obj/item/seeds/carrot,
|
||||
/obj/item/seeds/sunflower,
|
||||
/obj/item/seeds/chanter,
|
||||
/obj/item/seeds/rose,
|
||||
/obj/item/seeds/chanterelle,
|
||||
/obj/item/seeds/potato,
|
||||
/obj/item/seeds/sugarcane)
|
||||
crate_name = "seeds crate"
|
||||
|
||||
@@ -47,32 +47,6 @@
|
||||
/obj/item/stack/packageWrap)
|
||||
crate_name = "cargo supplies crate"
|
||||
|
||||
/datum/supply_pack/service/carpet_exotic
|
||||
name = "Exotic Carpet Crate"
|
||||
desc = "Exotic carpets straight from Space Russia, for all your decorating needs. Contains 100 tiles each of 10 different flooring patterns."
|
||||
cost = 7000
|
||||
contains = list(/obj/item/stack/tile/carpet/blue/fifty,
|
||||
/obj/item/stack/tile/carpet/blue/fifty,
|
||||
/obj/item/stack/tile/carpet/cyan/fifty,
|
||||
/obj/item/stack/tile/carpet/cyan/fifty,
|
||||
/obj/item/stack/tile/carpet/green/fifty,
|
||||
/obj/item/stack/tile/carpet/green/fifty,
|
||||
/obj/item/stack/tile/carpet/orange/fifty,
|
||||
/obj/item/stack/tile/carpet/orange/fifty,
|
||||
/obj/item/stack/tile/carpet/purple/fifty,
|
||||
/obj/item/stack/tile/carpet/purple/fifty,
|
||||
/obj/item/stack/tile/carpet/red/fifty,
|
||||
/obj/item/stack/tile/carpet/red/fifty,
|
||||
/obj/item/stack/tile/carpet/royalblue/fifty,
|
||||
/obj/item/stack/tile/carpet/royalblue/fifty,
|
||||
/obj/item/stack/tile/carpet/royalblack/fifty,
|
||||
/obj/item/stack/tile/carpet/royalblack/fifty,
|
||||
/obj/item/stack/tile/carpet/blackred/fifty,
|
||||
/obj/item/stack/tile/carpet/blackred/fifty,
|
||||
/obj/item/stack/tile/carpet/monochrome/fifty,
|
||||
/obj/item/stack/tile/carpet/monochrome/fifty)
|
||||
crate_name = "exotic carpet crate"
|
||||
|
||||
/datum/supply_pack/service/food_cart
|
||||
name = "Food Cart Crate"
|
||||
desc = "Want to sell food on the go? Cook lost their cart? Well we just so happen to have a few carts to spare!"
|
||||
@@ -252,23 +226,39 @@
|
||||
|
||||
/datum/supply_pack/service/carpet
|
||||
name = "Premium Carpet Crate"
|
||||
desc = "Plasteel floor tiles getting on your nerves? These stacks of extra soft carpet will tie any room together. Contains the classics."
|
||||
desc = "Plasteel floor tiles getting on your nerves? These stacks of extra soft carpet will tie any room together. Contains one of each pattern: classic, black, black-red and monochrome."
|
||||
cost = 1000
|
||||
contains = list(/obj/item/stack/tile/carpet/fifty,
|
||||
/obj/item/stack/tile/carpet/fifty,
|
||||
/obj/item/stack/tile/carpet/blackred/fifty,
|
||||
/obj/item/stack/tile/carpet/black/fifty,
|
||||
/obj/item/stack/tile/carpet/black/fifty)
|
||||
/obj/item/stack/tile/carpet/monochrome/fifty)
|
||||
crate_name = "premium carpet crate"
|
||||
|
||||
/datum/supply_pack/service/carpet2
|
||||
name = "Premium Carpet Crate #2"
|
||||
desc = "Plasteel floor tiles getting on your nerves? These stacks of extra soft carpet will tie any room together. Contains red, and monochrome"
|
||||
cost = 1000
|
||||
contains = list(/obj/item/stack/tile/carpet/blackred/fifty,
|
||||
/datum/supply_pack/service/carpet_exotic
|
||||
name = "Exotic Carpet Crate"
|
||||
desc = "Exotic carpets straight from Space Russia, for all your decorating needs. Contains 100 tiles each of 10 different flooring patterns."
|
||||
cost = 7000
|
||||
contains = list(/obj/item/stack/tile/carpet/blue/fifty,
|
||||
/obj/item/stack/tile/carpet/blue/fifty,
|
||||
/obj/item/stack/tile/carpet/cyan/fifty,
|
||||
/obj/item/stack/tile/carpet/cyan/fifty,
|
||||
/obj/item/stack/tile/carpet/green/fifty,
|
||||
/obj/item/stack/tile/carpet/green/fifty,
|
||||
/obj/item/stack/tile/carpet/orange/fifty,
|
||||
/obj/item/stack/tile/carpet/orange/fifty,
|
||||
/obj/item/stack/tile/carpet/purple/fifty,
|
||||
/obj/item/stack/tile/carpet/purple/fifty,
|
||||
/obj/item/stack/tile/carpet/red/fifty,
|
||||
/obj/item/stack/tile/carpet/red/fifty,
|
||||
/obj/item/stack/tile/carpet/royalblue/fifty,
|
||||
/obj/item/stack/tile/carpet/royalblue/fifty,
|
||||
/obj/item/stack/tile/carpet/royalblack/fifty,
|
||||
/obj/item/stack/tile/carpet/royalblack/fifty,
|
||||
/obj/item/stack/tile/carpet/blackred/fifty,
|
||||
/obj/item/stack/tile/carpet/blackred/fifty,
|
||||
/obj/item/stack/tile/carpet/monochrome/fifty,
|
||||
/obj/item/stack/tile/carpet/monochrome/fifty)
|
||||
crate_name = "premium carpet crate #2"
|
||||
crate_name = "exotic carpet crate"
|
||||
|
||||
/datum/supply_pack/service/lightbulbs
|
||||
name = "Replacement Lights"
|
||||
@@ -324,6 +314,14 @@
|
||||
crate_name = "games supply crate"
|
||||
crate_type = /obj/structure/closet/crate
|
||||
|
||||
/datum/supply_pack/service/vending/hydrovendors
|
||||
name = "Hydroponics Supply Crate"
|
||||
desc = "Arn't you glad you dont have to do it the natural way? Contains a megaseed and nutrimax vending machine refill."
|
||||
cost = 5000
|
||||
contains = list(/obj/item/vending_refill/hydroseeds,
|
||||
/obj/item/vending_refill/hydronutrients)
|
||||
crate_name = "hydroponics supply crate"
|
||||
|
||||
/datum/supply_pack/service/vending/snack
|
||||
name = "Snack Supply Crate"
|
||||
desc = "One vending machine refill of cavity-bringin' goodness! The number one dentist recommended order!"
|
||||
|
||||
@@ -15,15 +15,17 @@
|
||||
armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 80)
|
||||
anchored = TRUE //So it cant slide around after landing
|
||||
anchorable = FALSE
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
|
||||
//*****NOTE*****: Many of these comments are similarly described in centcom_podlauncher.dm. If you change them here, please consider doing so in the centcom podlauncher code as well!
|
||||
var/adminNamed = FALSE //Determines whether or not the pod has been named by an admin. If true, the pod's name will not get overridden when the style of the pod changes (changing the style of the pod normally also changes the name+desc)
|
||||
var/bluespace = FALSE //If true, the pod deletes (in a shower of sparks) after landing
|
||||
var/landingDelay = 30 //How long the pod takes to land after launching
|
||||
var/openingDelay = 30 //How long the pod takes to open after landing
|
||||
var/departureDelay = 30 //How long the pod takes to leave after opening (if bluespace=true, it deletes. if reversing=true, it flies back to centcom)
|
||||
var/departureDelay = 30 //How long the pod takes to leave after opening. If bluespace = TRUE, it deletes. If reversing = TRUE, it flies back to centcom.
|
||||
var/damage = 0 //Damage that occurs to any mob under the pod when it lands.
|
||||
var/effectStun = FALSE //If true, stuns anyone under the pod when it launches until it lands, forcing them to get hit by the pod. Devilish!
|
||||
var/effectLimb = FALSE //If true, pops off a limb (if applicable) from anyone caught under the pod when it lands
|
||||
var/effectOrgans = FALSE //If true, yeets out every limb and organ from anyone caught under the pod when it lands
|
||||
var/effectGib = FALSE //If true, anyone under the pod will be gibbed when it lands
|
||||
var/effectStealth = FALSE //If true, a target icon isnt displayed on the turf where the pod will land
|
||||
var/effectQuiet = FALSE //The female sniper. If true, the pod makes no noise (including related explosions, opening sounds, etc)
|
||||
@@ -31,10 +33,13 @@
|
||||
var/effectCircle = FALSE //If true, allows the pod to come in at any angle. Bit of a weird feature but whatever its here
|
||||
var/style = STYLE_STANDARD //Style is a variable that keeps track of what the pod is supposed to look like. It acts as an index to the POD_STYLES list in cargo.dm defines to get the proper icon/name/desc for the pod.
|
||||
var/reversing = FALSE //If true, the pod will not send any items. Instead, after opening, it will close again (picking up items/mobs) and fly back to centcom
|
||||
var/fallDuration = 4
|
||||
var/fallingSoundLength = 11
|
||||
var/fallingSound = 'sound/weapons/mortar_long_whistle.ogg'//Admin sound to play before the pod lands
|
||||
var/landingSound //Admin sound to play when the pod lands
|
||||
var/openingSound //Admin sound to play when the pod opens
|
||||
var/leavingSound //Admin sound to play when the pod leaves
|
||||
var/soundVolume = 50 //Volume to play sounds at. Ignores the cap
|
||||
var/soundVolume = 80 //Volume to play sounds at. Ignores the cap
|
||||
var/bay //Used specifically for the centcom_podlauncher datum. Holds the current bay the user is launching objects from. Bays are specific rooms on the centcom map.
|
||||
var/list/explosionSize = list(0,0,2,3)
|
||||
|
||||
@@ -48,16 +53,18 @@
|
||||
style = STYLE_CENTCOM
|
||||
bluespace = TRUE
|
||||
explosionSize = list(0,0,0,0)
|
||||
landingDelay = 5 //Very speedy!
|
||||
landingDelay = 20 //Very speedy!
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
/obj/structure/closet/supplypod/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
setStyle(style, TRUE) //Upon initialization, give the supplypod an iconstate, name, and description based on the "style" variable. This system is important for the centcom_podlauncher to function correctly
|
||||
|
||||
/obj/structure/closet/supplypod/update_icon()
|
||||
cut_overlays()
|
||||
if (style != STYLE_INVISIBLE) //If we're invisible, we dont bother adding any overlays
|
||||
if (style == STYLE_SEETHROUGH || style == STYLE_INVISIBLE) //If we're invisible, we dont bother adding any overlays
|
||||
return
|
||||
else
|
||||
if (opened)
|
||||
add_overlay("[icon_state]_open")
|
||||
else
|
||||
@@ -75,7 +82,7 @@
|
||||
update_icon()
|
||||
|
||||
/obj/structure/closet/supplypod/tool_interact(obj/item/W, mob/user)
|
||||
if (bluespace) //We dont want to worry about interacting with bluespace pods, as they are due to delete themselves soon anyways.
|
||||
if(bluespace) //We dont want to worry about interacting with bluespace pods, as they are due to delete themselves soon anyways.
|
||||
return FALSE
|
||||
else
|
||||
..()
|
||||
@@ -86,9 +93,6 @@
|
||||
/obj/structure/closet/supplypod/contents_explosion() //Supplypods also protect their contents from the harmful effects of fucking exploding.
|
||||
return
|
||||
|
||||
/obj/structure/closet/supplypod/prevent_content_explosion() //Useful for preventing epicenter explosions from damaging contents
|
||||
return TRUE
|
||||
|
||||
/obj/structure/closet/supplypod/toggle(mob/living/user) //Supplypods shouldn't be able to be manually opened under any circumstances, as the open() proc generates supply order datums
|
||||
return
|
||||
|
||||
@@ -101,17 +105,33 @@
|
||||
if (effectLimb && iscarbon(M)) //If effectLimb is true (which means we pop limbs off when we hit people):
|
||||
var/mob/living/carbon/CM = M
|
||||
for (var/obj/item/bodypart/bodypart in CM.bodyparts) //Look at the bodyparts in our poor mob beneath our pod as it lands
|
||||
if(bodypart.body_part != HEAD && bodypart.body_zone != CHEST)//we dont want to kill him, just teach em a lesson!
|
||||
if(bodypart.body_part != HEAD && bodypart.body_part != CHEST)//we dont want to kill him, just teach em a lesson!
|
||||
if (bodypart.dismemberable)
|
||||
bodypart.dismember() //Using the power of flextape i've sawed this man's limb in half!
|
||||
break
|
||||
if (effectOrgans && iscarbon(M)) //effectOrgans means remove every organ in our mob
|
||||
var/mob/living/carbon/CM = M
|
||||
for(var/X in CM.internal_organs)
|
||||
var/destination = get_edge_target_turf(T, pick(GLOB.alldirs)) //Pick a random direction to toss them in
|
||||
var/obj/item/organ/O = X
|
||||
O.Remove(CM) //Note that this isn't the same proc as for lists
|
||||
O.forceMove(T) //Move the organ outta the body
|
||||
O.throw_at(destination, 2, 3) //Thow the organ at a random tile 3 spots away
|
||||
sleep(1)
|
||||
for (var/obj/item/bodypart/bodypart in CM.bodyparts) //Look at the bodyparts in our poor mob beneath our pod as it lands
|
||||
var/destination = get_edge_target_turf(T, pick(GLOB.alldirs))
|
||||
if (bodypart.dismemberable)
|
||||
bodypart.dismember() //Using the power of flextape i've sawed this man's bodypart in half!
|
||||
bodypart.throw_at(destination, 2, 3)
|
||||
sleep(1)
|
||||
|
||||
if (effectGib) //effectGib is on, that means whatever's underneath us better be fucking oof'd on
|
||||
M.adjustBruteLoss(5000) //THATS A LOT OF DAMAGE (called just in case gib() doesnt work on em)
|
||||
M.gib() //After adjusting the fuck outta that brute loss we finish the job with some satisfying gibs
|
||||
M.adjustBruteLoss(damage)
|
||||
|
||||
|
||||
if (B[1] || B[2] || B[3] || B[4]) //If the explosion list isn't all zeroes, call an explosion
|
||||
else
|
||||
M.adjustBruteLoss(damage)
|
||||
var/explosion_sum = B[1] + B[2] + B[3] + B[4]
|
||||
if (explosion_sum != 0) //If the explosion list isn't all zeroes, call an explosion
|
||||
explosion(get_turf(src), B[1], B[2], B[3], flame_range = B[4], silent = effectQuiet, ignorecap = istype(src, /obj/structure/closet/supplypod/centcompod)) //less advanced equipment than bluespace pod, so larger explosion when landing
|
||||
else if (!effectQuiet) //If our explosion list IS all zeroes, we still make a nice explosion sound (unless the effectQuiet var is true)
|
||||
playsound(src, "explosion", landingSound ? 15 : 80, 1)
|
||||
@@ -128,22 +148,31 @@
|
||||
|
||||
/obj/structure/closet/supplypod/open(atom/movable/holder, var/broken = FALSE, var/forced = FALSE) //The holder var represents an atom whose contents we will be working with
|
||||
var/turf/T = get_turf(holder) //Get the turf of whoever's contents we're talking about
|
||||
if (!holder)
|
||||
return
|
||||
if(opened)
|
||||
return
|
||||
opened = TRUE //This is to ensure we don't open something that has already been opened
|
||||
var/mob/M
|
||||
if (istype(holder, /mob)) //Allows mobs to assume the role of the holder, meaning we look at the mob's contents rather than the supplypod's contents. Typically by this point the supplypod's contents have already been moved over to the mob's contents
|
||||
M = holder
|
||||
if (M.key && !forced && !broken) //If we are player controlled, then we shouldnt open unless the opening is manual, or if it is due to being destroyed (represented by the "broken" parameter)
|
||||
return
|
||||
opened = TRUE //This is to ensure we don't open something that has already been opened
|
||||
if (openingSound)
|
||||
playsound(get_turf(holder), openingSound, soundVolume, 0, 0)
|
||||
playsound(get_turf(holder), openingSound, soundVolume, 0, 0) //Special admin sound to play
|
||||
INVOKE_ASYNC(holder, .proc/setOpened) //Use the INVOKE_ASYNC proc to call setOpened() on whatever the holder may be, without giving the atom/movable base class a setOpened() proc definition
|
||||
if (style == STYLE_SEETHROUGH)
|
||||
update_icon()
|
||||
for (var/atom/movable/O in holder.contents) //Go through the contents of the holder
|
||||
O.forceMove(T) //move everything from the contents of the holder to the turf of the holder
|
||||
if (!effectQuiet) //If we aren't being quiet, play an open sound
|
||||
if (!effectQuiet && !openingSound && style != STYLE_SEETHROUGH) //If we aren't being quiet, play the default pod open sound
|
||||
playsound(get_turf(holder), open_sound, 15, 1, -3)
|
||||
if (broken) //If the pod is opening because it's been destroyed, we end here
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/depart, holder), departureDelay) //Finish up the pod's duties after a certain amount of time
|
||||
if (style == STYLE_SEETHROUGH)
|
||||
depart(src)
|
||||
else
|
||||
addtimer(CALLBACK(src, .proc/depart, holder), departureDelay) //Finish up the pod's duties after a certain amount of time
|
||||
|
||||
/obj/structure/closet/supplypod/proc/depart(atom/movable/holder)
|
||||
if (leavingSound)
|
||||
@@ -151,7 +180,7 @@
|
||||
if (reversing) //If we're reversing, we call the close proc. This sends the pod back up to centcom
|
||||
close(holder)
|
||||
else if (bluespace) //If we're a bluespace pod, then delete ourselves (along with our holder, if a seperate holder exists)
|
||||
if (style != STYLE_INVISIBLE)
|
||||
if (!effectQuiet && style != STYLE_INVISIBLE && style != STYLE_SEETHROUGH)
|
||||
do_sparks(5, TRUE, holder) //Create some sparks right before closing
|
||||
qdel(src) //Delete ourselves and the holder
|
||||
if (holder != src)
|
||||
@@ -164,13 +193,14 @@
|
||||
if (ismob(O) && !isliving(O)) //We dont want to take ghosts with us
|
||||
continue
|
||||
O.forceMove(holder) //Put objects inside before we close
|
||||
var/obj/effect/temp_visual/risingPod = new /obj/effect/temp_visual/DPfall(get_turf(holder), src) //Make a nice animation of flying back up
|
||||
var/obj/effect/temp_visual/risingPod = new /obj/effect/abstract/DPfall(get_turf(holder), src) //Make a nice animation of flying back up
|
||||
risingPod.pixel_z = 0 //The initial value of risingPod's pixel_z is 200 because it normally comes down from a high spot
|
||||
holder.forceMove(bay) //Move the pod back to centcom, where it belongs
|
||||
animate(risingPod, pixel_z = 200, time = 10, easing = LINEAR_EASING) //Animate our rising pod
|
||||
QDEL_IN(risingPod, 10)
|
||||
reversing = FALSE //Now that we're done reversing, we set this to false (otherwise we would get stuck in an infinite loop of calling the close proc at the bottom of open() )
|
||||
bluespace = TRUE //Make it so that the pod doesn't stay in centcom forever
|
||||
open(holder, forced = TRUE)
|
||||
return
|
||||
|
||||
/obj/structure/closet/supplypod/proc/setOpened() //Proc exists here, as well as in any atom that can assume the role of a "holder" of a supplypod. Check the open() proc for more details
|
||||
update_icon()
|
||||
@@ -179,12 +209,11 @@
|
||||
update_icon()
|
||||
|
||||
/obj/structure/closet/supplypod/Destroy()
|
||||
if (!opened) //If we havent opened yet, we're opening because we've been destroyed. Lets dump our contents by opening up
|
||||
open(src, broken = TRUE)
|
||||
return ..()
|
||||
open(src, broken = TRUE) //Lets dump our contents by opening up
|
||||
. = ..()
|
||||
|
||||
//------------------------------------FALLING SUPPLY POD-------------------------------------//
|
||||
/obj/effect/temp_visual/DPfall //Falling pod
|
||||
/obj/effect/abstract/DPfall //Falling pod
|
||||
name = ""
|
||||
icon = 'icons/obj/supplypods.dmi'
|
||||
pixel_x = -16
|
||||
@@ -192,17 +221,22 @@
|
||||
pixel_z = 200
|
||||
desc = "Get out of the way!"
|
||||
layer = FLY_LAYER//that wasnt flying, that was falling with style!
|
||||
randomdir = FALSE
|
||||
icon_state = ""
|
||||
|
||||
/obj/effect/temp_visual/DPfall/Initialize(dropLocation, obj/structure/closet/supplypod/pod)
|
||||
if (pod.style != STYLE_INVISIBLE) //Check to ensure the pod isn't invisible
|
||||
/obj/effect/abstract/DPfall/Initialize(dropLocation, obj/structure/closet/supplypod/pod)
|
||||
if (pod.style == STYLE_SEETHROUGH)
|
||||
pixel_x = -16
|
||||
pixel_y = 0
|
||||
for (var/atom/movable/O in pod.contents)
|
||||
var/icon/I = getFlatIcon(O) //im so sorry
|
||||
add_overlay(I)
|
||||
else if (pod.style != STYLE_INVISIBLE) //Check to ensure the pod isn't invisible
|
||||
icon_state = "[pod.icon_state]_falling"
|
||||
name = pod.name
|
||||
. = ..()
|
||||
|
||||
//------------------------------------TEMPORARY_VISUAL-------------------------------------//
|
||||
/obj/effect/DPtarget //This is the object that forceMoves the supplypod to it's location
|
||||
/obj/effect/abstract/DPtarget //This is the object that forceMoves the supplypod to it's location
|
||||
name = "Landing Zone Indicator"
|
||||
desc = "A holographic projection designating the landing zone of something. It's probably best to stand back."
|
||||
icon = 'icons/mob/actions/actions_items.dmi'
|
||||
@@ -212,45 +246,60 @@
|
||||
var/obj/effect/temp_visual/fallingPod //Temporary "falling pod" that we animate
|
||||
var/obj/structure/closet/supplypod/pod //The supplyPod that will be landing ontop of this target
|
||||
|
||||
/obj/effect/ex_act()
|
||||
return
|
||||
|
||||
/obj/effect/DPtarget/Initialize(mapload, podParam, var/datum/supply_order/SO = null)
|
||||
/obj/effect/abstract/DPtarget/Initialize(mapload, podParam, single_order = null)
|
||||
. = ..()
|
||||
if (ispath(podParam)) //We can pass either a path for a pod (as expressconsoles do), or a reference to an instantiated pod (as the centcom_podlauncher does)
|
||||
podParam = new podParam() //If its just a path, instantiate it
|
||||
pod = podParam
|
||||
if (SO)
|
||||
SO.generate(pod)
|
||||
for (var/mob/living/M in podParam) //If there are any mobs in the supplypod, we want to forceMove them into the target. This is so that they can see where they are about to land, AND so that they don't get sent to the nullspace error room (as the pod is currently in nullspace)
|
||||
if (single_order)
|
||||
if (istype(single_order, /datum/supply_order))
|
||||
var/datum/supply_order/SO = single_order
|
||||
SO.generate(pod)
|
||||
else if (istype(single_order, /atom/movable))
|
||||
var/atom/movable/O = single_order
|
||||
O.forceMove(pod)
|
||||
for (var/mob/living/M in pod) //If there are any mobs in the supplypod, we want to forceMove them into the target. This is so that they can see where they are about to land, AND so that they don't get sent to the nullspace error room (as the pod is currently in nullspace)
|
||||
M.forceMove(src)
|
||||
if(pod.effectStun) //If effectStun is true, stun any mobs caught on this target until the pod gets a chance to hit them
|
||||
for (var/mob/living/M in get_turf(src))
|
||||
M.Stun(pod.landingDelay+10, ignore_canstun = TRUE)//you aint goin nowhere, kid.
|
||||
if (pod.effectStealth) //If effectStealth is true we want to be invisible
|
||||
alpha = 255
|
||||
icon_state = ""
|
||||
if (pod.fallDuration == initial(pod.fallDuration) && pod.landingDelay + pod.fallDuration < pod.fallingSoundLength)
|
||||
pod.fallingSoundLength = 3 //The default falling sound is a little long, so if the landing time is shorter than the default falling sound, use a special, shorter default falling sound
|
||||
pod.fallingSound = 'sound/weapons/mortar_whistle.ogg'
|
||||
var/soundStartTime = pod.landingDelay - pod.fallingSoundLength + pod.fallDuration
|
||||
if (soundStartTime < 0)
|
||||
soundStartTime = 1
|
||||
if (!pod.effectQuiet)
|
||||
addtimer(CALLBACK(src, .proc/playFallingSound), soundStartTime)
|
||||
addtimer(CALLBACK(src, .proc/beginLaunch, pod.effectCircle), pod.landingDelay)
|
||||
|
||||
/obj/effect/DPtarget/proc/beginLaunch(effectCircle) //Begin the animation for the pod falling. The effectCircle param determines whether the pod gets to come in from any descent angle
|
||||
fallingPod = new /obj/effect/temp_visual/DPfall(drop_location(), pod)
|
||||
/obj/effect/abstract/DPtarget/proc/playFallingSound()
|
||||
playsound(src, pod.fallingSound, pod.soundVolume, 1, 6)
|
||||
|
||||
/obj/effect/abstract/DPtarget/proc/beginLaunch(effectCircle) //Begin the animation for the pod falling. The effectCircle param determines whether the pod gets to come in from any descent angle
|
||||
fallingPod = new /obj/effect/abstract/DPfall(drop_location(), pod)
|
||||
var/matrix/M = matrix(fallingPod.transform) //Create a new matrix that we can rotate
|
||||
var/angle = effectCircle ? rand(0,360) : rand(70,110) //The angle that we can come in from
|
||||
fallingPod.pixel_x = cos(angle)*200 //Use some ADVANCED MATHEMATICS to set the animated pod's position to somewhere on the edge of a circle with the center being the target
|
||||
fallingPod.pixel_z = sin(angle)*200
|
||||
fallingPod.pixel_x = cos(angle)*400 //Use some ADVANCED MATHEMATICS to set the animated pod's position to somewhere on the edge of a circle with the center being the target
|
||||
fallingPod.pixel_z = sin(angle)*400
|
||||
var/rotation = Get_Pixel_Angle(fallingPod.pixel_z, fallingPod.pixel_x) //CUSTOM HOMEBREWED proc that is just arctan with extra steps
|
||||
M.Turn(rotation) //Turn our matrix accordingly
|
||||
fallingPod.transform = M //Transform the animated pod according to the matrix
|
||||
M = matrix(pod.transform) //Make another matrix based on the pod
|
||||
M.Turn(rotation) //Turn the matrix
|
||||
pod.transform = M //Turn the actual pod (Won't be visible until endLaunch() proc tho)
|
||||
animate(fallingPod, pixel_z = 0, pixel_x = -16, time = 3, , easing = LINEAR_EASING) //Make the pod fall! At an angle!
|
||||
addtimer(CALLBACK(src, .proc/endLaunch), 3, TIMER_CLIENT_TIME) //Go onto the last step after a very short falling animation
|
||||
animate(fallingPod, pixel_z = 0, pixel_x = -16, time = pod.fallDuration, , easing = LINEAR_EASING) //Make the pod fall! At an angle!
|
||||
addtimer(CALLBACK(src, .proc/endLaunch), pod.fallDuration, TIMER_CLIENT_TIME) //Go onto the last step after a very short falling animation
|
||||
|
||||
/obj/effect/DPtarget/proc/endLaunch()
|
||||
/obj/effect/abstract/DPtarget/proc/endLaunch()
|
||||
pod.update_icon()
|
||||
pod.forceMove(drop_location()) //The fallingPod animation is over, now's a good time to forceMove the actual pod into position
|
||||
QDEL_NULL(fallingPod) //Delete the falling pod effect, because at this point its animation is over. We dont use temp_visual because we want to manually delete it as soon as the pod appears
|
||||
for (var/mob/living/M in src) //Remember earlier (initialization) when we moved mobs into the DPTarget so they wouldnt get lost in nullspace? Time to get them out
|
||||
M.forceMove(pod)
|
||||
pod.preOpen() //Begin supplypod open procedures. Here effects like explosions, damage, and other dangerous (and potentially admin-caused, if the centcom_podlauncher datum was used) memes will take place
|
||||
QDEL_NULL(fallingPod) //The fallingPod's (the animated effect, not the actual pod) purpose is complete. It can rest easy now
|
||||
qdel(src) //ditto
|
||||
|
||||
//------------------------------------UPGRADES-------------------------------------//
|
||||
@@ -261,3 +310,4 @@
|
||||
icon_state = "cargodisk"
|
||||
item_state = "card-id"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
//BLACK MAGIC THINGS//
|
||||
//////////////////////
|
||||
parent_type = /datum
|
||||
|
||||
|
||||
/// hides the byond verb panel as we use our own custom version
|
||||
show_verb_panel = FALSE
|
||||
////////////////
|
||||
//ADMIN THINGS//
|
||||
////////////////
|
||||
@@ -24,6 +28,12 @@
|
||||
var/move_delay = 0
|
||||
var/area = null
|
||||
|
||||
|
||||
|
||||
/// list of tabs containing spells and abilities
|
||||
var/list/spell_tabs = list()
|
||||
/// list of tabs containing verbs
|
||||
var/list/verb_tabs = list()
|
||||
///////////////
|
||||
//SOUND STUFF//
|
||||
///////////////
|
||||
|
||||
@@ -197,7 +197,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
|
||||
debug_tools_allowed = TRUE
|
||||
//END CITADEL EDIT
|
||||
else if(GLOB.deadmins[ckey])
|
||||
verbs += /client/proc/readmin
|
||||
add_verb(src, /client/proc/readmin)
|
||||
connecting_admin = TRUE
|
||||
if(CONFIG_GET(flag/autoadmin))
|
||||
if(!GLOB.admin_datums[ckey])
|
||||
@@ -240,10 +240,10 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
|
||||
|
||||
prefs.last_ip = address //these are gonna be used for banning
|
||||
prefs.last_id = computer_id //these are gonna be used for banning
|
||||
fps = 40
|
||||
fps = prefs.clientfps
|
||||
|
||||
if(fexists(roundend_report_file()))
|
||||
verbs += /client/proc/show_previous_roundend_report
|
||||
add_verb(src, /client/proc/show_previous_roundend_report)
|
||||
|
||||
var/full_version = "[byond_version].[byond_build ? byond_build : "xxx"]"
|
||||
log_access("Login: [key_name(src)] from [address ? address : "localhost"]-[computer_id] || BYOND v[full_version]")
|
||||
@@ -304,6 +304,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
|
||||
set_macros()
|
||||
|
||||
chatOutput.start() // Starts the chat
|
||||
src << browse(file('html/statbrowser.html'), "window=statbrowser") //starts stats tab
|
||||
|
||||
if(alert_mob_dupe_login)
|
||||
spawn()
|
||||
@@ -798,9 +799,9 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
|
||||
|
||||
/client/proc/add_verbs_from_config()
|
||||
if(CONFIG_GET(flag/see_own_notes))
|
||||
verbs += /client/proc/self_notes
|
||||
add_verb(src, /client/proc/self_notes)
|
||||
if(CONFIG_GET(flag/use_exp_tracking))
|
||||
verbs += /client/proc/self_playtime
|
||||
add_verb(src, /client/proc/self_playtime)
|
||||
|
||||
|
||||
#undef UPLOAD_LIMIT
|
||||
@@ -865,6 +866,31 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
|
||||
y = CLAMP(y+change, min,max)
|
||||
change_view("[x]x[y]")
|
||||
|
||||
/// compiles a full list of verbs and sends it to the browser
|
||||
/client/proc/init_verbs()
|
||||
if(IsAdminAdvancedProcCall())
|
||||
return
|
||||
var/list/verblist = list()
|
||||
|
||||
var/list/verbstoprocess = verbs.Copy()
|
||||
if(mob)
|
||||
verbstoprocess += mob.verbs
|
||||
for(var/AM in mob.contents)
|
||||
var/atom/movable/thing = AM
|
||||
verbstoprocess += thing.verbs
|
||||
verb_tabs.Cut()
|
||||
for(var/thing in verbstoprocess)
|
||||
var/procpath/verb_to_init = thing
|
||||
if(!verb_to_init)
|
||||
continue
|
||||
if(verb_to_init.hidden)
|
||||
continue
|
||||
if(!istext(verb_to_init.category))
|
||||
continue
|
||||
verb_tabs |= verb_to_init.category
|
||||
verblist[++verblist.len] = list(verb_to_init.category, verb_to_init.name)
|
||||
src << output("[url_encode(json_encode(verb_tabs))];[url_encode(json_encode(verblist))]", "statbrowser:init_verbs")
|
||||
|
||||
/client/proc/change_view(new_size)
|
||||
if (isnull(new_size))
|
||||
CRASH("change_view called without argument.")
|
||||
|
||||
@@ -37,6 +37,7 @@ Thanks to spacemaniac and mcdonald for help with the JS side of this.
|
||||
winset(src, "say", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
|
||||
winset(src, "asset_cache_browser", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
|
||||
winset(src, "tooltip", "background-color = [COLOR_WHITEMODE_BACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
|
||||
src << output(null, "statbrowser:set_light_theme")
|
||||
|
||||
/client/proc/force_dark_theme() //Inversely, if theyre using white theme and want to swap to the superior dark theme, let's get WINSET() ing
|
||||
//Main windows
|
||||
@@ -62,4 +63,5 @@ Thanks to spacemaniac and mcdonald for help with the JS side of this.
|
||||
//Etc.
|
||||
winset(src, "say", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
|
||||
winset(src, "asset_cache_browser", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
|
||||
winset(src, "tooltip", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
|
||||
winset(src, "tooltip", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
|
||||
src << output(null, "statbrowser:set_dark_theme")
|
||||
+249
-112
@@ -46,6 +46,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/buttons_locked = FALSE
|
||||
var/hotkeys = FALSE
|
||||
var/chat_on_map = TRUE
|
||||
var/autocorrect = TRUE
|
||||
var/radiosounds = TRUE
|
||||
var/max_chat_length = CHAT_MESSAGE_MAX_LENGTH
|
||||
var/see_chat_non_mob = TRUE
|
||||
@@ -68,6 +69,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/pda_skin = PDA_SKIN_ALT
|
||||
|
||||
var/list/alt_titles_preferences = list()
|
||||
var/static/preview_job_outfit = TRUE //shouldn't be something that's saved, but this is a preference option
|
||||
|
||||
var/uses_glasses_colour = 0
|
||||
|
||||
@@ -96,7 +98,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
//H13
|
||||
var/body_size = 100 //Body Size in percent
|
||||
var/can_get_preg = 0 //Body Size in percent
|
||||
var/can_get_preg = 0 //if they can get preggers
|
||||
|
||||
|
||||
var/datum/species/pref_species = new /datum/species/human() //Mutant race
|
||||
var/list/features = list("mcolor" = "FFF",
|
||||
@@ -134,6 +137,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
"cock_color" = "fff",
|
||||
"has_sheath" = FALSE,
|
||||
"sheath_color" = "fff",
|
||||
"has_belly" = FALSE,
|
||||
"hide_belly" = FALSE,
|
||||
"belly_color" = "fff",
|
||||
"has_balls" = FALSE,
|
||||
"balls_internal" = FALSE,
|
||||
"balls_color" = "fff",
|
||||
@@ -174,7 +180,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
"womb_fluid" = /datum/reagent/consumable/femcum,
|
||||
"ipc_screen" = "Sunburst",
|
||||
"ipc_antenna" = "None",
|
||||
"flavor_text" = ""
|
||||
"flavor_text" = "",
|
||||
"silicon_flavor_text" = "",
|
||||
"ooc_text" = ""
|
||||
)
|
||||
|
||||
/// Security record note section
|
||||
@@ -191,6 +199,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/custom_species = null
|
||||
|
||||
var/list/all_quirks = list()
|
||||
var/compressed_quirks = FALSE //Hyperstation edit: Use a smaller font for the quirks list
|
||||
var/old_view = FALSE //Hyperstation edit: toggle for sorting by category
|
||||
|
||||
//Jobs, uses bitflags
|
||||
var/job_civilian_high = 0
|
||||
@@ -240,6 +250,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/list/bgstate_options = list("000", "midgrey", "hiro", "FFF", "white", "steel", "techmaint", "dark", "plating", "reinforced")
|
||||
|
||||
var/show_mismatched_markings = FALSE //determines whether or not the markings lists should show markings that don't match the currently selected species. Intentionally left unsaved.
|
||||
var/hide_ckey = FALSE //pref for hiding if your ckey shows round-end or not
|
||||
|
||||
/datum/preferences/New(client/C)
|
||||
parent = C
|
||||
@@ -283,6 +294,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<a href='?_src_=prefs;preference=tab;tab=2' [current_tab == 2 ? "class='linkOn'" : ""]>Character Appearance</a>"
|
||||
dat += "<a href='?_src_=prefs;preference=tab;tab=3' [current_tab == 3 ? "class='linkOn'" : ""]>Loadout</a>"
|
||||
dat += "<a href='?_src_=prefs;preference=tab;tab=1' [current_tab == 1 ? "class='linkOn'" : ""]>Game Preferences</a>"
|
||||
dat += "<a href='?_src_=prefs;preference=tab;tab=4' [current_tab == 4 ? "class='linkOn'" : ""]>Antagonist Preferences</a>"
|
||||
|
||||
if(!path)
|
||||
dat += "<div class='notice'>Please create an account to save your preferences</div>"
|
||||
@@ -295,26 +307,26 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
dat += "<HR>"
|
||||
|
||||
switch(current_tab)
|
||||
if (0) // Character Settings#
|
||||
if(path)
|
||||
var/savefile/S = new /savefile(path)
|
||||
if(S)
|
||||
dat += "<center>"
|
||||
var/name
|
||||
var/unspaced_slots = 0
|
||||
for(var/i=1, i<=max_save_slots, i++)
|
||||
unspaced_slots++
|
||||
if(unspaced_slots > 4)
|
||||
dat += "<br>"
|
||||
unspaced_slots = 0
|
||||
S.cd = "/character[i]"
|
||||
S["real_name"] >> name
|
||||
if(!name)
|
||||
name = "+"
|
||||
dat += "<a style='white-space:nowrap;' href='?_src_=prefs;preference=changeslot;num=[i];' [i == default_slot ? "class='linkOn'" : ""]>[name]</a> "
|
||||
dat += "</center>"
|
||||
if(path) //Show list of characters
|
||||
var/savefile/S = new /savefile(path)
|
||||
if(S)
|
||||
dat += "<center>"
|
||||
var/name
|
||||
var/unspaced_slots = 0
|
||||
for(var/i=1, i<=max_save_slots, i++)
|
||||
unspaced_slots++
|
||||
if(unspaced_slots > 4)
|
||||
dat += "<br>"
|
||||
unspaced_slots = 0
|
||||
S.cd = "/character[i]"
|
||||
S["real_name"] >> name
|
||||
if(!name)
|
||||
name = "+"
|
||||
dat += "<a style='white-space:nowrap;' href='?_src_=prefs;preference=changeslot;num=[i];' [i == default_slot ? "class='linkOn'" : ""]>[name]</a> "
|
||||
dat += "</center>"
|
||||
|
||||
switch(current_tab)
|
||||
if (0) // Character Settings
|
||||
dat += "<center><h2>Occupation Choices</h2>"
|
||||
dat += "<a href='?_src_=prefs;preference=job;task=menu'>Set Occupation Preferences</a><br></center>"
|
||||
if(CONFIG_GET(flag/roundstart_traits))
|
||||
@@ -368,31 +380,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "[medical_records]"
|
||||
else
|
||||
dat += "[TextPreview(medical_records)]...<BR>"
|
||||
dat += "<br><a href='?_src_=prefs;preference=hide_ckey;task=input'><b>Hide ckey: [hide_ckey ? "Enabled" : "Disabled"]</b></a><br>"
|
||||
dat += "</tr></table>"
|
||||
|
||||
//Character Appearance
|
||||
if(2)
|
||||
if(path)
|
||||
var/savefile/S = new /savefile(path)
|
||||
if(S)
|
||||
dat += "<center>"
|
||||
var/name
|
||||
var/unspaced_slots = 0
|
||||
for(var/i=1, i<=max_save_slots, i++)
|
||||
unspaced_slots++
|
||||
if(unspaced_slots > 4)
|
||||
dat += "<br>"
|
||||
unspaced_slots = 0
|
||||
S.cd = "/character[i]"
|
||||
S["real_name"] >> name
|
||||
if(!name)
|
||||
name = "+"
|
||||
dat += "<a style='white-space:nowrap;' href='?_src_=prefs;preference=changeslot;num=[i];' [i == default_slot ? "class='linkOn'" : ""]>[name]</a> "
|
||||
dat += "</center>"
|
||||
|
||||
update_preview_icon()
|
||||
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
|
||||
dat += "<h2>Flavor Text</h2>"
|
||||
dat += "<h2>General Examine Text</h2>"
|
||||
dat += "<a href='?_src_=prefs;preference=flavor_text;task=input'><b>Set Examine Text</b></a><br>"
|
||||
if(length(features["flavor_text"]) <= 40)
|
||||
if(!length(features["flavor_text"]))
|
||||
@@ -401,6 +396,25 @@ 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)
|
||||
if(!length(features["ooc_text"]))
|
||||
dat += "\[...\]"
|
||||
else
|
||||
dat += "[features["ooc_text"]]"
|
||||
else
|
||||
dat += "[TextPreview(features["ooc_text"])]...<BR>"
|
||||
|
||||
dat += "<h2>Body</h2>"
|
||||
dat += "<b>Gender:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=gender'>[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]</a><BR>"
|
||||
dat += "<b>Species:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=species;task=input'>[pref_species.id]</a><BR>"
|
||||
@@ -838,6 +852,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=balls_fluid;task=input'>Semen</a>"
|
||||
if(/datum/reagent/consumable/femcum)
|
||||
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=balls_fluid;task=input'>Femcum</a>"
|
||||
if(/datum/reagent/consumable/alienhoney)
|
||||
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=balls_fluid;task=input'>Honey</a>"
|
||||
else
|
||||
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=balls_fluid;task=input'>Nothing?</a>"
|
||||
//This else is a safeguard for errors, and if it happened, they wouldn't be able to change this pref,
|
||||
@@ -881,10 +897,23 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_fluid;task=input'>Semen</a>"
|
||||
if(/datum/reagent/consumable/femcum)
|
||||
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_fluid;task=input'>Femcum</a>"
|
||||
if(/datum/reagent/consumable/alienhoney)
|
||||
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_fluid;task=input'>Honey</a>"
|
||||
else
|
||||
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_fluid;task=input'>Nothing?</a>"
|
||||
//This else is a safeguard for errors, and if it happened, they wouldn't be able to change this pref,
|
||||
//DO NOT REMOVE IT UNLESS YOU HAVE A GOOD IDEA
|
||||
dat += APPEARANCE_CATEGORY_COLUMN
|
||||
dat += "<h3>Belly</h3>"
|
||||
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_belly'>[features["has_belly"] == TRUE ? "Yes" : "No"]</a>"
|
||||
if(features["has_belly"])
|
||||
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
||||
dat += "<b>Color:</b></a><BR>"
|
||||
dat += "<span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'> </span>(Skin tone overriding)<br>"
|
||||
else
|
||||
dat += "<b>Color:</b></a><BR>"
|
||||
dat += "<span style='border: 1px solid #161616; background-color: #[features["belly_color"]];'> </span> <a href='?_src_=prefs;preference=belly_color;task=input'>Change</a><br>"
|
||||
dat += "<b>Hide on Round-Start:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=hide_belly'>[features["hide_belly"] == 1 ? "Yes" : "No"]</a>"
|
||||
|
||||
dat += "</td>"
|
||||
dat += "</td>"
|
||||
@@ -900,6 +929,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<b>Chat Bubbles message char limit:</b> <a href='?_src_=prefs;preference=max_chat_length;task=input'>[max_chat_length]</a><br>"
|
||||
dat += "<b>Chat Bubbles for non-mobs:</b> <a href='?_src_=prefs;preference=see_chat_non_mob'>[see_chat_non_mob ? "Enabled" : "Disabled"]</a><br>"
|
||||
dat += "<br>"
|
||||
dat += "<b>Autocorrect:</b> <a href='?_src_=prefs;preference=autocorrect'>[(autocorrect) ? "On" : "Off"]</a><br>"
|
||||
dat += "<b>Radio Sounds:</b> <a href='?_src_=prefs;preference=radiosounds'>[radiosounds ? "Enabled" : "Disabled"]</a><br>"
|
||||
dat += "<br>"
|
||||
dat += "<b>Action Buttons:</b> <a href='?_src_=prefs;preference=action_buttons'>[(buttons_locked) ? "Locked In Place" : "Unlocked"]</a><br>"
|
||||
@@ -958,7 +988,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
if(jobban_isbanned(user, ROLE_SYNDICATE))
|
||||
dat += "<font color=red><b>You are banned from antagonist roles.</b></font>"
|
||||
src.be_special = list()
|
||||
be_special = list()
|
||||
|
||||
|
||||
for (var/i in GLOB.hyper_special_roles)
|
||||
@@ -1037,40 +1067,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
p_map += " (No longer exists)"
|
||||
if(CONFIG_GET(flag/allow_map_voting))
|
||||
dat += "<b>Preferred Map:</b> <a href='?_src_=prefs;preference=preferred_map;task=input'>[p_map]</a><br>"
|
||||
|
||||
dat += "</td><td width='300px' height='300px' valign='top'>"
|
||||
|
||||
dat += "<h2>Special Role Settings</h2>"
|
||||
|
||||
if(jobban_isbanned(user, ROLE_SYNDICATE))
|
||||
dat += "<font color=red><b>You are banned from antagonist roles.</b></font>"
|
||||
src.be_special = list()
|
||||
|
||||
|
||||
for (var/i in GLOB.special_roles)
|
||||
if(jobban_isbanned(user, i))
|
||||
dat += "<b>Be [capitalize(i)]:</b> <a href='?_src_=prefs;jobbancheck=[i]'>BANNED</a><br>"
|
||||
else
|
||||
var/days_remaining = null
|
||||
if(ispath(GLOB.special_roles[i]) && CONFIG_GET(flag/use_age_restriction_for_jobs)) //If it's a game mode antag, check if the player meets the minimum age
|
||||
var/mode_path = GLOB.special_roles[i]
|
||||
var/datum/game_mode/temp_mode = new mode_path
|
||||
days_remaining = temp_mode.get_remaining_days(user.client)
|
||||
|
||||
if(days_remaining)
|
||||
dat += "<b>Be [capitalize(i)]:</b> <font color=red> \[IN [days_remaining] DAYS]</font><br>"
|
||||
else
|
||||
dat += "<b>Be [capitalize(i)]:</b> <a href='?_src_=prefs;preference=be_special;be_special_type=[i]'>[(i in be_special) ? "Enabled" : "Disabled"]</a><br>"
|
||||
dat += "<b>Midround Antagonist:</b> <a href='?_src_=prefs;preference=allow_midround_antag'>[(toggles & MIDROUND_ANTAG) ? "Enabled" : "Disabled"]</a><br>"
|
||||
|
||||
dat += "<br>"
|
||||
|
||||
if(3)
|
||||
if(3) //Item Loadout
|
||||
if(!gear_tab)
|
||||
gear_tab = GLOB.loadout_items[1]
|
||||
dat += "<table align='center' width='100%'>"
|
||||
dat += "<tr><td colspan=4><center><b><font color='[gear_points == 0 ? "#E62100" : "#CCDDFF"]'>[gear_points]</font> loadout points remaining.</b> \[<a href='?_src_=prefs;preference=gear;clear_loadout=1'>Clear Loadout</a>\]</center></td></tr>"
|
||||
dat += "<tr><td colspan=4><center>You can only choose one item per category, unless it's an item that spawns in your backpack or hands.</center></td></tr>"
|
||||
dat += "<tr><td colspan=4><center><b><font color='[gear_points == 0 ? "#E62100" : "#CCDDFF"]'>[gear_points]</font> loadout points remaining.</b> \[<a href='?_src_=prefs;preference=gear;clear_loadout=1'>Clear Loadout</a>\] \[<a href='?_src_=prefs;preference=gear;toggle_outfit_visibility=1'>[preview_job_outfit ? "Enable" : "Disable"] Job Outfit Preview</a>\]</center></td></tr>"
|
||||
dat += "<tr><td colspan=4><center>You can only choose two items per category, unless it's an item that spawns in your backpack or hands.</center></td></tr>"
|
||||
dat += "<tr><td colspan=4><center><b>"
|
||||
var/firstcat = TRUE
|
||||
for(var/i in GLOB.loadout_items)
|
||||
@@ -1121,6 +1125,36 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "</td><td><font size=2><i>[gear.description]</i></font></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
if(4) //Antag Preferences
|
||||
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
|
||||
dat += "<h1>Special Role Settings</h1>"
|
||||
if(jobban_isbanned(user, ROLE_SYNDICATE))
|
||||
dat += "<font color=red><h3><b>You are banned from antagonist roles.</b></h3></font>"
|
||||
be_special = list()
|
||||
|
||||
for (var/i in GLOB.special_roles)
|
||||
if(jobban_isbanned(user, i))
|
||||
dat += "<b>Be [capitalize(i)]:</b> <a href='?_src_=prefs;jobbancheck=[i]'>BANNED</a><br>"
|
||||
else
|
||||
var/days_remaining = null
|
||||
if(ispath(GLOB.special_roles[i]) && CONFIG_GET(flag/use_age_restriction_for_jobs)) //If it's a game mode antag, check if the player meets the minimum age
|
||||
var/mode_path = GLOB.special_roles[i]
|
||||
var/datum/game_mode/temp_mode = new mode_path
|
||||
days_remaining = temp_mode.get_remaining_days(user.client)
|
||||
|
||||
if(days_remaining)
|
||||
dat += "<b>Be [capitalize(i)]:</b> <font color=red> \[IN [days_remaining] DAYS]</font><br>"
|
||||
else
|
||||
dat += "<b>Be [capitalize(i)]:</b> <a href='?_src_=prefs;preference=be_special;be_special_type=[i]'>[(i in be_special) ? "Enabled" : "Disabled"]</a><br>"
|
||||
dat += "<b>Midround Antagonist:</b> <a href='?_src_=prefs;preference=allow_midround_antag'>[(toggles & MIDROUND_ANTAG) ? "Enabled" : "Disabled"]</a><br>"
|
||||
dat += "</td><td width='340px' height='300px' valign='top'>"
|
||||
dat += "<h1>Sync Settings</h1>"
|
||||
dat += "<b>Sync</b> antag prefs. with all characters: <a href='?_src_=prefs;preference=sync_antag_with_chars'>[(toggles & ANTAG_SYNC_WITH_CHARS) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Copy</b> and save antag prefs. to all characters: <a href='?_src_=prefs;preference=copy_antag_to_chars'>Copy</a><br>"
|
||||
dat += "<b>Reset</b> antag prefs. for this character: <a href='?_src_=prefs;preference=reset_antag'>Reset</a><br>"
|
||||
dat += "</td></tr></table>"
|
||||
|
||||
|
||||
dat += "<hr><center>"
|
||||
|
||||
if(!IsGuestKey(user.key))
|
||||
@@ -1409,7 +1443,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
to_chat(user, "<span class='danger'>The quirk subsystem is still initializing! Try again in a minute.</span>")
|
||||
return
|
||||
|
||||
var/list/dat = list()
|
||||
var/dat = ""
|
||||
if(!SSquirks.quirks.len)
|
||||
dat += "The quirk subsystem hasn't finished initializing, please hold..."
|
||||
dat += "<center><a href='?_src_=prefs;preference=trait;task=close'>Done</a></center><br>"
|
||||
@@ -1418,50 +1452,76 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<center><b>Choose quirk setup</b></center><br>"
|
||||
dat += "<div align='center'>Left-click to add or remove quirks. You need negative quirks to have positive ones.<br>\
|
||||
Quirks are applied at roundstart and cannot normally be removed.</div>"
|
||||
dat += "<center><a href='?_src_=prefs;preference=trait;task=close'>Done</a></center>"
|
||||
dat += "<center><a href='?_src_=prefs;preference=trait;task=close'>Done</a><br>\
|
||||
<a href='?_src_=prefs;preference=trait;task=trait_small_text'>[compressed_quirks ? "Normal View" : "Small View"]</a> \
|
||||
<a href='?_src_=prefs;preference=trait;task=old_view'>[old_view ? "Current View" : "Old View"]</a> </center>" //Hyper edit
|
||||
dat += "<hr>"
|
||||
dat += "<center><b>Current quirks:</b> [all_quirks.len ? all_quirks.Join(", ") : "None"]</center>"
|
||||
dat += "<center>[GetPositiveQuirkCount()] / [MAX_QUIRKS] max positive quirks<br>\
|
||||
<b>Quirk balance remaining:</b> [GetQuirkBalance()]</center><br>"
|
||||
for(var/V in SSquirks.quirks)
|
||||
var/datum/quirk/T = SSquirks.quirks[V]
|
||||
var/quirk_name = initial(T.name)
|
||||
var/has_quirk
|
||||
var/quirk_cost = initial(T.value) * -1
|
||||
var/lock_reason = "This trait is unavailable."
|
||||
var/quirk_conflict = FALSE
|
||||
for(var/_V in all_quirks)
|
||||
if(_V == quirk_name)
|
||||
has_quirk = TRUE
|
||||
if(initial(T.mood_quirk) && CONFIG_GET(flag/disable_human_mood))
|
||||
lock_reason = "Mood is disabled."
|
||||
quirk_conflict = TRUE
|
||||
if(has_quirk)
|
||||
if(quirk_conflict)
|
||||
all_quirks -= quirk_name
|
||||
has_quirk = FALSE
|
||||
var/list/hacky = SSquirks.quirk_categories
|
||||
if(old_view)
|
||||
hacky = list(1) //Hyperstation edit; super hacky, but it works
|
||||
|
||||
//Hyperstation Edit: Categorize quirks
|
||||
for(var/_cat in hacky)
|
||||
var/list/L = SSquirks.quirks_sorted[_cat]
|
||||
if(!old_view)
|
||||
if(compressed_quirks)
|
||||
dat += "<p style='color:white;margin-bottom:1px;margin-top:6px'><u>[_cat]</u></p>"
|
||||
else
|
||||
quirk_cost *= -1 //invert it back, since we'd be regaining this amount
|
||||
if(quirk_cost > 0)
|
||||
quirk_cost = "+[quirk_cost]"
|
||||
var/font_color = "#AAAAFF"
|
||||
if(initial(T.value) != 0)
|
||||
font_color = initial(T.value) > 0 ? "#AAFFAA" : "#FFAAAA"
|
||||
if(quirk_conflict)
|
||||
dat += "<font color='[font_color]'>[quirk_name]</font> - [initial(T.desc)] \
|
||||
<font color='red'><b>LOCKED: [lock_reason]</b></font><br>"
|
||||
dat += "<p style='color:white;font-size:12px;margin-bottom:2px;margin-top:4px'><u>[_cat]</u></p>"
|
||||
else
|
||||
L = SSquirks.quirks
|
||||
|
||||
for(var/T in L)
|
||||
//End Hyperstation Edit
|
||||
var/datum/quirk/Q = SSquirks.quirks[T]
|
||||
var/quirk_name = initial(Q.name)
|
||||
var/has_quirk
|
||||
var/quirk_cost = initial(Q.value) * -1
|
||||
var/lock_reason = "This trait is unavailable."
|
||||
var/quirk_conflict = FALSE
|
||||
for(var/_V in all_quirks)
|
||||
if(_V == quirk_name)
|
||||
has_quirk = TRUE
|
||||
break
|
||||
if(initial(Q.mood_quirk) && CONFIG_GET(flag/disable_human_mood))
|
||||
lock_reason = "Mood is disabled."
|
||||
quirk_conflict = TRUE
|
||||
if(has_quirk)
|
||||
dat += "<a href='?_src_=prefs;preference=trait;task=update;trait=[quirk_name]'>[has_quirk ? "Remove" : "Take"] ([quirk_cost] pts.)</a> \
|
||||
<b><font color='[font_color]'>[quirk_name]</font></b> - [initial(T.desc)]<br>"
|
||||
else
|
||||
dat += "<a href='?_src_=prefs;preference=trait;task=update;trait=[quirk_name]'>[has_quirk ? "Remove" : "Take"] ([quirk_cost] pts.)</a> \
|
||||
<font color='[font_color]'>[quirk_name]</font> - [initial(T.desc)]<br>"
|
||||
if(quirk_conflict)
|
||||
all_quirks -= quirk_name
|
||||
has_quirk = FALSE
|
||||
else
|
||||
quirk_cost *= -1 //invert it back, since we'd be regaining this amount
|
||||
if(quirk_cost > 0)
|
||||
quirk_cost = "+[quirk_cost]"
|
||||
var/font_color = "#AAAAFF"
|
||||
if(initial(Q.value) != 0)
|
||||
font_color = initial(Q.value) > 0 ? "#AAFFAA" : "#FFAAAA"
|
||||
|
||||
if(compressed_quirks) //Hyperstation Edit: smol text
|
||||
if(quirk_conflict)
|
||||
dat += "<a><font size='1' color='red'>([quirk_cost]) [quirk_name])</font></a>"
|
||||
else
|
||||
dat += "[has_quirk ? "<b><u>" : ""]<a href='?_src_=prefs;preference=trait;task=update;trait=[quirk_name]'><font size='1' color='[font_color]'>([quirk_cost]) [quirk_name]</font></a>[has_quirk ? "</u></b>" : ""]"
|
||||
else //if(old_view)
|
||||
if(quirk_conflict)
|
||||
dat += "<font color='[font_color]'>[quirk_name]</font> - \
|
||||
<font color='red'><b>LOCKED: [lock_reason]</b></font>"
|
||||
else
|
||||
dat += "<a href='?_src_=prefs;preference=trait;task=update;trait=[quirk_name]'>[has_quirk ? "Remove" : "Take"] ([quirk_cost] pts.)</a> \
|
||||
[has_quirk ? "<b>" : ""]<font color='[font_color]'>[quirk_name]</font>[has_quirk ? "</b>": ""] - [initial(Q.desc)]"
|
||||
dat += "<br>"
|
||||
|
||||
dat += "<br>"
|
||||
|
||||
dat += "<br><center><a href='?_src_=prefs;preference=trait;task=reset'>Reset Quirks</a></center>"
|
||||
|
||||
var/datum/browser/popup = new(user, "mob_occupation", "<div align='center'>Quirk Preferences</div>", 900, 600) //no reason not to reuse the occupation window, as it's cleaner that way
|
||||
popup.set_window_options("can_close=0")
|
||||
popup.set_content(dat.Join())
|
||||
popup.set_content(dat)
|
||||
popup.open(FALSE)
|
||||
|
||||
/datum/preferences/proc/GetQuirkBalance()
|
||||
@@ -1550,8 +1610,16 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
else if(href_list["preference"] == "trait")
|
||||
switch(href_list["task"])
|
||||
if("trait_small_text")
|
||||
compressed_quirks = !compressed_quirks
|
||||
SetQuirks(user)
|
||||
if("old_view")
|
||||
old_view = !old_view
|
||||
SetQuirks(user)
|
||||
if("close")
|
||||
user << browse(null, "window=mob_occupation")
|
||||
compressed_quirks = FALSE
|
||||
//Intentional for old_view to not be reset here. But we don't save the varx
|
||||
ShowChoices(user)
|
||||
if("update")
|
||||
var/quirk = href_list["trait"]
|
||||
@@ -1662,7 +1730,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("name")
|
||||
var/new_name = input(user, "Choose your character's name:", "Character Preference") as text|null
|
||||
if(new_name)
|
||||
new_name = reject_bad_name(new_name)
|
||||
new_name = reject_bad_name(new_name, TRUE)
|
||||
if(new_name)
|
||||
real_name = new_name
|
||||
else
|
||||
@@ -1684,11 +1752,29 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
medical_records = rec
|
||||
|
||||
if("flavor_text")
|
||||
var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", html_decode(features["flavor_text"]), MAX_MESSAGE_LEN, TRUE)
|
||||
var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This should be IC, and description people can deduce at a quick glance.", "Flavor Text", html_decode(features["flavor_text"]), MAX_MESSAGE_LEN, TRUE)
|
||||
if(msg)
|
||||
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)
|
||||
msg = msg
|
||||
features["ooc_text"] = msg
|
||||
|
||||
|
||||
if("hide_ckey")
|
||||
hide_ckey = !hide_ckey
|
||||
if(user)
|
||||
user.mind?.hide_ckey = hide_ckey
|
||||
|
||||
if("hair")
|
||||
var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference","#"+hair_color) as color|null
|
||||
if(new_hair)
|
||||
@@ -2159,6 +2245,17 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
else
|
||||
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
if("belly_color")
|
||||
var/new_bellycolor = input(user, "Belly Color:", "Character Preference") as color|null
|
||||
if(new_bellycolor)
|
||||
var/temp_hsv = RGBtoHSV(new_bellycolor)
|
||||
if(new_bellycolor == "#000000")
|
||||
features["belly_color"] = pref_species.default_color
|
||||
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
||||
features["belly_color"] = sanitize_hexcolor(new_bellycolor)
|
||||
else
|
||||
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
if("balls_shape")
|
||||
var/new_shape
|
||||
new_shape = input(user, "Testicle Type:", "Character Preference") as null|anything in GLOB.balls_shapes_list
|
||||
@@ -2177,6 +2274,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
features["balls_fluid"] = /datum/reagent/consumable/semen
|
||||
if("Femcum")
|
||||
features["balls_fluid"] = /datum/reagent/consumable/femcum
|
||||
if("Honey")
|
||||
features["balls_fluid"] = /datum/reagent/consumable/alienhoney
|
||||
|
||||
if("egg_size")
|
||||
var/new_size
|
||||
@@ -2211,13 +2310,15 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
new_shape = input(user, "Breast Fluid", "Character Preference") as null|anything in GLOB.genital_fluids_list
|
||||
switch(new_shape)
|
||||
if("Milk")
|
||||
features["balls_fluid"] = /datum/reagent/consumable/milk
|
||||
features["breasts_fluid"] = /datum/reagent/consumable/milk
|
||||
if("Water")
|
||||
features["balls_fluid"] = /datum/reagent/water
|
||||
features["breasts_fluid"] = /datum/reagent/water
|
||||
if("Semen")
|
||||
features["balls_fluid"] = /datum/reagent/consumable/semen
|
||||
features["breasts_fluid"] = /datum/reagent/consumable/semen
|
||||
if("Femcum")
|
||||
features["balls_fluid"] = /datum/reagent/consumable/femcum
|
||||
features["breasts_fluid"] = /datum/reagent/consumable/femcum
|
||||
if("Honey")
|
||||
features["breasts_fluid"] = /datum/reagent/consumable/alienhoney
|
||||
|
||||
if("breasts_color")
|
||||
var/new_breasts_color = input(user, "Breast Color:", "Character Preference") as color|null
|
||||
@@ -2360,6 +2461,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
features["has_cock"] = !features["has_cock"]
|
||||
if(features["has_cock"] == FALSE)
|
||||
features["has_balls"] = FALSE
|
||||
if("has_belly")
|
||||
features["has_belly"] = !features["has_belly"]
|
||||
if(features["has_belly"] == FALSE)
|
||||
features["hide_belly"] = FALSE
|
||||
if("hide_belly")
|
||||
features["hide_belly"] = !features["hide_belly"]
|
||||
if("has_balls")
|
||||
features["has_balls"] = !features["has_balls"]
|
||||
if("has_ovi")
|
||||
@@ -2433,6 +2540,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
buttons_locked = !buttons_locked
|
||||
if("chat_on_map")
|
||||
chat_on_map = !chat_on_map
|
||||
if("autocorrect")
|
||||
autocorrect = !autocorrect
|
||||
if("radiosounds")
|
||||
radiosounds = !radiosounds
|
||||
if("see_chat_non_mob")
|
||||
@@ -2453,9 +2562,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("be_special")
|
||||
var/be_special_type = href_list["be_special_type"]
|
||||
if(be_special_type in be_special)
|
||||
be_special -= be_special_type
|
||||
be_special -= list(be_special_type)
|
||||
else
|
||||
be_special += be_special_type
|
||||
be_special += list(be_special_type)
|
||||
|
||||
if("name")
|
||||
be_random_name = !be_random_name
|
||||
@@ -2494,6 +2603,30 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("allow_midround_antag")
|
||||
toggles ^= MIDROUND_ANTAG
|
||||
|
||||
if("sync_antag_with_chars")
|
||||
toggles ^= ANTAG_SYNC_WITH_CHARS
|
||||
if(!(toggles & ANTAG_SYNC_WITH_CHARS) && path)
|
||||
var/savefile/S = new /savefile(path)
|
||||
if(S)
|
||||
S["special_roles"] >> be_special
|
||||
|
||||
if("copy_antag_to_chars")
|
||||
if(path)
|
||||
var/savefile/S = new /savefile(path)
|
||||
if(S)
|
||||
var/initial_cd = S.cd
|
||||
for(var/i=1, i<=max_save_slots, i++)
|
||||
S.cd = "/character[i]"
|
||||
if(S["real_name"])
|
||||
WRITE_FILE(S["special_roles"], be_special)
|
||||
S.cd = initial_cd
|
||||
to_chat(parent, "<span class='notice'>Successfully copied antagonist preferences to all characters.</span>")
|
||||
else
|
||||
to_chat(parent, "<span class='notice'>Could not write to file.</span>")
|
||||
|
||||
if("reset_antag")
|
||||
be_special = list()
|
||||
|
||||
if("parallaxup")
|
||||
parallax = WRAP(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1)
|
||||
if (parent && parent.mob && parent.mob.hud_used)
|
||||
@@ -2580,6 +2713,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(gear_points >= initial(G.cost))
|
||||
LAZYADD(chosen_gear, G.type)
|
||||
gear_points -= initial(G.cost)
|
||||
if(href_list["toggle_outfit_visibility"])
|
||||
preview_job_outfit = !preview_job_outfit
|
||||
|
||||
ShowChoices(user)
|
||||
return 1
|
||||
@@ -2671,6 +2806,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]
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// You do not need to raise this if you are adding new values that have sane defaults.
|
||||
// Only raise this value when changing the meaning/format/name/layout of an existing value
|
||||
// where you would want the updater procs below to run
|
||||
#define SAVEFILE_VERSION_MAX 22
|
||||
#define SAVEFILE_VERSION_MAX 23
|
||||
|
||||
/*
|
||||
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
|
||||
@@ -44,6 +44,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
/datum/preferences/proc/update_preferences(current_version, savefile/S)
|
||||
if(current_version < 21)
|
||||
clientfps = 60
|
||||
if(current_version < 23)
|
||||
S["be_special"] >> be_special
|
||||
return
|
||||
|
||||
/datum/preferences/proc/update_character(current_version, savefile/S)
|
||||
@@ -56,6 +58,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
features["balls_fluid"] = /datum/reagent/consumable/semen
|
||||
if(features["breasts_fluid"])
|
||||
features["breasts_fluid"] = /datum/reagent/consumable/milk
|
||||
if(current_version < 23)
|
||||
if(be_special)
|
||||
WRITE_FILE(S["special_roles"], be_special)
|
||||
|
||||
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
|
||||
if(!ckey)
|
||||
@@ -91,7 +96,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["tgui_lock"] >> tgui_lock
|
||||
S["buttons_locked"] >> buttons_locked
|
||||
S["windowflash"] >> windowflashing
|
||||
S["be_special"] >> be_special
|
||||
|
||||
|
||||
S["default_slot"] >> default_slot
|
||||
@@ -108,6 +112,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["uses_glasses_colour"]>> uses_glasses_colour
|
||||
S["clientfps"] >> clientfps
|
||||
S["chat_on_map"] >> chat_on_map
|
||||
S["autocorrect"] >> autocorrect
|
||||
S["radiosounds"] >> radiosounds
|
||||
S["max_chat_length"] >> max_chat_length
|
||||
S["see_chat_non_mob"] >> see_chat_non_mob
|
||||
@@ -146,6 +151,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
|
||||
UI_style = sanitize_inlist(UI_style, GLOB.available_ui_styles, GLOB.available_ui_styles[1])
|
||||
hotkeys = sanitize_integer(hotkeys, 0, 1, initial(hotkeys))
|
||||
autocorrect = sanitize_integer(autocorrect, 0, 1, initial(autocorrect))
|
||||
chat_on_map = sanitize_integer(chat_on_map, 0, 1, initial(chat_on_map))
|
||||
radiosounds = sanitize_integer(radiosounds, 0, 1, initial(radiosounds))
|
||||
max_chat_length = sanitize_integer(max_chat_length, 1, CHAT_MESSAGE_MAX_LENGTH, initial(max_chat_length))
|
||||
@@ -159,7 +165,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
clientfps = sanitize_integer(clientfps, 0, 1000, 0)
|
||||
if (clientfps == 0) clientfps = world.fps*2
|
||||
body_size = sanitize_integer(body_size, 90, 110, 0)
|
||||
can_get_preg = sanitize_integer(body_size, 0, 1, 0)
|
||||
can_get_preg = sanitize_integer(can_get_preg, 0, 1, 0)
|
||||
parallax = sanitize_integer(parallax, PARALLAX_INSANE, PARALLAX_DISABLE, null)
|
||||
ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion))
|
||||
auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport))
|
||||
@@ -212,7 +218,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["tgui_lock"], tgui_lock)
|
||||
WRITE_FILE(S["buttons_locked"], buttons_locked)
|
||||
WRITE_FILE(S["windowflash"], windowflashing)
|
||||
WRITE_FILE(S["be_special"], be_special)
|
||||
WRITE_FILE(S["default_slot"], default_slot)
|
||||
WRITE_FILE(S["toggles"], toggles)
|
||||
WRITE_FILE(S["chat_toggles"], chat_toggles)
|
||||
@@ -337,7 +342,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["feature_human_ears"] >> features["ears"]
|
||||
S["feature_deco_wings"] >> features["deco_wings"]
|
||||
|
||||
|
||||
S["hide_ckey"] >> hide_ckey //saved per-character
|
||||
|
||||
|
||||
//Custom names
|
||||
@@ -360,6 +365,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["job_engsec_med"] >> job_engsec_med
|
||||
S["job_engsec_low"] >> job_engsec_low
|
||||
|
||||
//Antags
|
||||
if(!(toggles & ANTAG_SYNC_WITH_CHARS))
|
||||
S["special_roles"] >> be_special
|
||||
|
||||
//Quirks
|
||||
S["all_quirks"] >> all_quirks
|
||||
|
||||
@@ -411,10 +420,15 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
//womb features
|
||||
S["feature_has_womb"] >> features["has_womb"]
|
||||
S["feature_can_get_preg"] >> features["can_get_preg"] //hyperstation 13
|
||||
//balls features
|
||||
S["feature_has_belly"] >> features["has_belly"]
|
||||
S["feature_belly_color"] >> features["belly_color"]
|
||||
S["feature_hide_belly"] >> features["hide_belly"]
|
||||
|
||||
//flavor text
|
||||
//Let's make our players NOT cry desperately as we wipe their savefiles of their special snowflake texts:
|
||||
if((S["flavor_text"] != "") && (S["flavor_text"] != null) && S["flavor_text"]) //If old text isn't null and isn't "" but still exists.
|
||||
S["flavor_text"] >> features["flavor_text"] //Load old flavortext as current dna-based flavortext
|
||||
S["flavor_text"] >> features["flavor_text"] //Load old flavortext as current dna-based flavortext
|
||||
|
||||
WRITE_FILE(S["feature_flavor_text"], features["flavor_text"]) //Save it in our new type of flavor-text
|
||||
WRITE_FILE(S["flavor_text"] , "") //Remove old flavortext, completing the cut-and-paste into the new format.
|
||||
@@ -422,6 +436,15 @@ 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"]
|
||||
|
||||
WRITE_FILE(S["feature_ooc_text"], features["ooc_text"]) //Save it in our new type of flavor-text
|
||||
WRITE_FILE(S["ooc_text"], "") //Remove old flavortext, completing the cut-and-paste into the new format.
|
||||
|
||||
else
|
||||
S["feature_ooc_text"] >> features["ooc_text"]
|
||||
|
||||
//try to fix any outdated data if necessary
|
||||
if(needs_update >= 0)
|
||||
@@ -429,7 +452,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
|
||||
//Sanitize
|
||||
|
||||
real_name = reject_bad_name(real_name)
|
||||
real_name = reject_bad_name(real_name, TRUE)
|
||||
gender = sanitize_gender(gender, TRUE, TRUE)
|
||||
if(!real_name)
|
||||
real_name = random_unique_name(gender)
|
||||
@@ -491,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))
|
||||
@@ -578,20 +604,24 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["prefered_security_department"] , prefered_security_department)
|
||||
|
||||
//Jobs
|
||||
WRITE_FILE(S["joblessrole"] , joblessrole)
|
||||
WRITE_FILE(S["joblessrole"] , joblessrole)
|
||||
WRITE_FILE(S["job_civilian_high"] , job_civilian_high)
|
||||
WRITE_FILE(S["job_civilian_med"] , job_civilian_med)
|
||||
WRITE_FILE(S["job_civilian_low"] , job_civilian_low)
|
||||
WRITE_FILE(S["job_medsci_high"] , job_medsci_high)
|
||||
WRITE_FILE(S["job_medsci_high"] , job_medsci_high)
|
||||
WRITE_FILE(S["job_medsci_med"] , job_medsci_med)
|
||||
WRITE_FILE(S["job_medsci_low"] , job_medsci_low)
|
||||
WRITE_FILE(S["job_engsec_high"] , job_engsec_high)
|
||||
WRITE_FILE(S["job_engsec_high"] , job_engsec_high)
|
||||
WRITE_FILE(S["job_engsec_med"] , job_engsec_med)
|
||||
WRITE_FILE(S["job_engsec_low"] , job_engsec_low)
|
||||
//Record Flavor Text
|
||||
WRITE_FILE(S["security_records"] , security_records)
|
||||
WRITE_FILE(S["medical_records"] , medical_records)
|
||||
//Quirks
|
||||
WRITE_FILE(S["security_records"] , security_records)
|
||||
WRITE_FILE(S["medical_records"] , medical_records)
|
||||
|
||||
//Misc.
|
||||
if(!(toggles & ANTAG_SYNC_WITH_CHARS))
|
||||
WRITE_FILE(S["special_roles"] , be_special) //Preferences don't load every character change
|
||||
WRITE_FILE(S["hide_ckey"] , hide_ckey)
|
||||
WRITE_FILE(S["all_quirks"] , all_quirks)
|
||||
|
||||
cit_character_pref_save(S)
|
||||
|
||||
@@ -366,3 +366,10 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8")
|
||||
|
||||
pct += delta
|
||||
winset(src, "mainwindow.split", "splitter=[pct]")
|
||||
|
||||
|
||||
/client/verb/fix_stat_panel()
|
||||
set name = "Fix Stat Panel"
|
||||
set hidden = TRUE
|
||||
|
||||
init_verbs()
|
||||
@@ -47,7 +47,6 @@
|
||||
//Add a "exclude" string to do the opposite, making it only only species listed that can't wear it.
|
||||
//You append this to clothing objects.
|
||||
//Hyper change// - Variables for HS13 checks
|
||||
var/roomy = 0 //0 For false
|
||||
|
||||
|
||||
/obj/item/clothing/Initialize()
|
||||
@@ -95,6 +94,7 @@
|
||||
to_chat(user, "<span class='notice'>You fix the damage on [src] with [C].</span>")
|
||||
return 1
|
||||
//Hyper Change//
|
||||
/*
|
||||
if(istype(W, /obj/item/bluespace_thread))
|
||||
var/obj/item/bluespace_thread/B = W
|
||||
if ((istype(src, /obj/item/clothing/under) || istype(src, /obj/item/clothing/suit)) && roomy != 1) //Make sure the thread is used on an item that could be ripped off in the first place
|
||||
@@ -106,6 +106,7 @@
|
||||
qdel(B)
|
||||
else
|
||||
user.show_message("<span class='notice'>You probably don't need any more room in that.</span>", 1)
|
||||
*/ //Long live roomy = TRUE
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/Destroy()
|
||||
|
||||
@@ -72,6 +72,12 @@
|
||||
desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting conditions. This one has prescription lens fitted in."
|
||||
vision_correction = 1
|
||||
|
||||
/obj/item/clothing/glasses/meson/eyepatch
|
||||
name = "meson scanner eyepatch"
|
||||
desc = "An eyepatch with a built-in meson scanner."
|
||||
icon_state = "mesonpatch"
|
||||
item_state = "mesonpatch"
|
||||
|
||||
/obj/item/clothing/glasses/meson/night
|
||||
name = "night vision meson scanner"
|
||||
desc = "An optical meson scanner fitted with an amplified visible light spectrum overlay, providing greater visual clarity in darkness."
|
||||
@@ -108,6 +114,12 @@
|
||||
if(slot == SLOT_GLASSES)
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/glasses/science/eyepatch
|
||||
name = "science eyepatch"
|
||||
desc = "An eyepatch with an analyser for scanning items and reagents."
|
||||
icon_state = "scipatch"
|
||||
item_state = "scipatch"
|
||||
|
||||
/obj/item/clothing/glasses/night
|
||||
name = "night vision goggles"
|
||||
desc = "You can totally see in the dark now!"
|
||||
@@ -122,6 +134,12 @@
|
||||
desc = "NVGs but for those with nearsightedness."
|
||||
vision_correction = 1
|
||||
|
||||
/obj/item/clothing/glasses/night/eyepatch
|
||||
name = "night vision eyepatch"
|
||||
desc = "An eyepatch with night vision technology!"
|
||||
icon_state = "nightpatch"
|
||||
item_state = "nightpatch"
|
||||
|
||||
/obj/item/clothing/glasses/science/suicide_act(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user] is tightening \the [src]'s straps around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return OXYLOSS
|
||||
|
||||
@@ -37,21 +37,23 @@
|
||||
hud_type = DATA_HUD_MEDICAL_ADVANCED
|
||||
glass_colour_type = /datum/client_colour/glass_colour/lightblue
|
||||
|
||||
/obj/item/clothing/glasses/hud/health/eyepatch
|
||||
name = "health scanner HUD eyepatch"
|
||||
desc = "A heads-up display, in an eyepatch, that scans the humans in view and provides accurate data about their health status."
|
||||
icon_state = "medpatch"
|
||||
item_state = "medpatch"
|
||||
|
||||
/obj/item/clothing/glasses/hud/health/prescription
|
||||
name = "prescription health scanner HUD"
|
||||
desc = "A heads-up display, made with a prescription lens, that scans the humans in view and provides accurate data about their health status."
|
||||
icon_state = "healthhud"
|
||||
hud_type = DATA_HUD_MEDICAL_ADVANCED
|
||||
vision_correction = 1
|
||||
glass_colour_type = /datum/client_colour/glass_colour/lightblue
|
||||
|
||||
/obj/item/clothing/glasses/hud/health/gar
|
||||
name = "gar health scanner HUD"
|
||||
desc = "When you're scared, that's all the more reason to move forward!"
|
||||
icon_state = "garh"
|
||||
item_state = "garh"
|
||||
hud_type = DATA_HUD_MEDICAL_ADVANCED
|
||||
glass_colour_type = /datum/client_colour/glass_colour/lightblue
|
||||
force = 10
|
||||
throwforce = 10
|
||||
throw_speed = 4
|
||||
@@ -84,13 +86,17 @@
|
||||
hud_type = DATA_HUD_DIAGNOSTIC_BASIC
|
||||
glass_colour_type = /datum/client_colour/glass_colour/lightorange
|
||||
|
||||
/obj/item/clothing/glasses/hud/diagnostic/eyepatch
|
||||
name = "diagnostic HUD eyepatch"
|
||||
desc = "A heads-up display, in an eyepatch, capable of analyzing the integrity and status of robotics and exosuits."
|
||||
icon_state = "diapatch"
|
||||
item_state = "diapatch"
|
||||
|
||||
/obj/item/clothing/glasses/hud/diagnostic/prescription
|
||||
name = "prescription diagnostic HUD"
|
||||
desc = "A heads-up display capable of analyzing the integrity and status of robotics and exosuits. This one has a prescription lens."
|
||||
icon_state = "diagnostichud"
|
||||
hud_type = DATA_HUD_DIAGNOSTIC_BASIC
|
||||
vision_correction = 1
|
||||
glass_colour_type = /datum/client_colour/glass_colour/lightorange
|
||||
|
||||
/obj/item/clothing/glasses/hud/diagnostic/night
|
||||
name = "night vision diagnostic HUD"
|
||||
@@ -112,9 +118,7 @@
|
||||
name = "prescription security HUD"
|
||||
desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status and security records. This one has a prescription lens so you can see the banana peal that slipped you."
|
||||
icon_state = "securityhud"
|
||||
hud_type = DATA_HUD_SECURITY_ADVANCED
|
||||
vision_correction = 1
|
||||
glass_colour_type = /datum/client_colour/glass_colour/red
|
||||
|
||||
/obj/item/clothing/glasses/hud/security/chameleon
|
||||
name = "chameleon security HUD"
|
||||
@@ -141,7 +145,7 @@
|
||||
|
||||
|
||||
/obj/item/clothing/glasses/hud/security/sunglasses/eyepatch
|
||||
name = "eyepatch HUD"
|
||||
name = "Security eyepatch HUD"
|
||||
desc = "A heads-up display that connects directly to the optical nerve of the user, replacing the need for that useless eyeball."
|
||||
icon_state = "hudpatch"
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
item_color="yellow"
|
||||
resistance_flags = NONE
|
||||
var/can_be_cut = 1
|
||||
price = 10
|
||||
|
||||
/obj/item/clothing/gloves/color/fyellow //Cheap Chinese Crap
|
||||
desc = "These gloves are cheap knockoffs of the coveted ones - no way this can end badly."
|
||||
@@ -19,6 +20,7 @@
|
||||
item_color="yellow"
|
||||
resistance_flags = NONE
|
||||
var/can_be_cut = 1
|
||||
price = 5
|
||||
|
||||
/obj/item/clothing/gloves/color/fyellow/New()
|
||||
..()
|
||||
@@ -113,6 +115,7 @@
|
||||
siemens_coefficient = 0
|
||||
permeability_coefficient = 0.05
|
||||
resistance_flags = NONE
|
||||
price = 12
|
||||
|
||||
/obj/item/clothing/gloves/color/rainbow
|
||||
name = "rainbow gloves"
|
||||
|
||||
@@ -40,6 +40,37 @@
|
||||
muzzle_var = NORMAL_STYLE
|
||||
|
||||
H.update_inv_head()
|
||||
|
||||
///Special throw_impact for hats to frisbee hats at people to place them on their heads.
|
||||
/obj/item/clothing/head/throw_impact(atom/hit_atom, datum/thrownthing/thrownthing)
|
||||
. = ..()
|
||||
///if the thrown object's target zone isn't the head
|
||||
if(thrownthing.target_zone != BODY_ZONE_HEAD)
|
||||
return
|
||||
///ignore any hats with downsides when worn
|
||||
if(clothing_flags & IGNORE_HAT_TOSS)
|
||||
return
|
||||
///if the hat happens to be capable of holding contents and has something in it. mostly to prevent super cheesy stuff like stuffing a mini-bomb in a hat and throwing it
|
||||
if(LAZYLEN(contents))
|
||||
return
|
||||
if(iscarbon(hit_atom))
|
||||
var/mob/living/carbon/H = hit_atom
|
||||
if(istype(H.head, /obj/item))
|
||||
var/obj/item/WH = H.head
|
||||
H.visible_message("<span class='warning'>[src] bounces off [H]'s [WH.name]!", "<span class='warning'>[src] bounces off your [WH.name], falling to the floor.</span>")
|
||||
return
|
||||
if(H.equip_to_slot_if_possible(src, SLOT_HEAD, FALSE, TRUE))
|
||||
H.visible_message("<span class='notice'>[src] lands neatly on [H]'s head!", "<span class='notice'>[src] lands perfectly onto your head!</span>")
|
||||
return
|
||||
if(iscyborg(hit_atom))
|
||||
var/mob/living/silicon/robot/R = hit_atom
|
||||
///hats in the borg's blacklist bounce off
|
||||
if(!is_type_in_typecache(src, R.equippable_hats) || R.hat_offset == INFINITY)
|
||||
R.visible_message("<span class='warning'>[src] bounces off [R]!", "<span class='warning'>[src] bounces off you, falling to the floor.</span>")
|
||||
return
|
||||
else
|
||||
R.visible_message("<span class='notice'>[src] lands neatly on top of [R].", "<span class='notice'>[src] lands perfectly on top of you.</span>")
|
||||
R.place_on_head(src) //hats aren't designed to snugly fit borg heads or w/e so they'll always manage to knock eachother off
|
||||
|
||||
/obj/item/clothing/head/worn_overlays(isinhands = FALSE)
|
||||
. = list()
|
||||
|
||||
@@ -158,4 +158,4 @@
|
||||
/obj/item/clothing/head/hardhat/weldhat/dblue
|
||||
icon_state = "hardhat0_dblue"
|
||||
item_state = "hardhat0_dblue"
|
||||
item_color = "dblue"
|
||||
item_color = "dblue"
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
resistance_flags = NONE
|
||||
flags_cover = HEADCOVERSEYES
|
||||
flags_inv = HIDEHAIR
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/helmet
|
||||
|
||||
/obj/item/clothing/head/helmet/ComponentInitialize()
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
strip_delay = 10
|
||||
equip_delay_other = 10
|
||||
dynamic_hair_suffix = ""
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/chefhat
|
||||
dog_fashion = /datum/dog_fashion/head/chef
|
||||
|
||||
/obj/item/clothing/head/chefhat/suicide_act(mob/user)
|
||||
@@ -24,6 +25,12 @@
|
||||
playsound(user, 'sound/machines/ding.ogg', 50, 1)
|
||||
return(FIRELOSS)
|
||||
|
||||
/obj/item/clothing/head/chefhat/relaymove(mob/user, direction)
|
||||
if(!istype(user, /mob/living/simple_animal/mouse) || !isliving(loc) || !prob(20))
|
||||
return
|
||||
var/mob/living/L = loc
|
||||
step_towards(L, get_step(L, direction))
|
||||
|
||||
//Captain
|
||||
/obj/item/clothing/head/caphat
|
||||
name = "captain's hat"
|
||||
@@ -253,6 +260,7 @@
|
||||
name = "security's bitch beret"
|
||||
desc = "A softer beret with the word 'BITCH' embroidered on it in pink thread."
|
||||
icon_state = "bitchberet"
|
||||
price = 5
|
||||
|
||||
//Curator
|
||||
/obj/item/clothing/head/fedora/curator
|
||||
|
||||
@@ -321,6 +321,39 @@
|
||||
icon_state = "christmashatg"
|
||||
item_state = "christmashatg"
|
||||
|
||||
|
||||
/obj/item/clothing/head/cowboyhat
|
||||
name = "cowboy hat"
|
||||
desc = "A standard brown cowboy hat, yeehaw."
|
||||
icon_state = "cowboyhat"
|
||||
item_state = "cowboyhat"
|
||||
|
||||
/obj/item/clothing/head/cowboyhat/black
|
||||
name = "black cowboy hat"
|
||||
desc = "A a black cowboy hat, perfect for any outlaw"
|
||||
icon_state = "cowboyhat_black"
|
||||
item_state = "cowboyhat_black"
|
||||
|
||||
/obj/item/clothing/head/cowboyhat/white
|
||||
name = "white cowboy hat"
|
||||
desc = "A white cowboy hat, perfect for your every day rancher"
|
||||
icon_state = "cowboyhat_white"
|
||||
item_state = "cowboyhat_white"
|
||||
|
||||
/obj/item/clothing/head/cowboyhat/pink
|
||||
name = "pink cowboy hat"
|
||||
desc = "A pink cowboy? more like cowgirl hat, just don't be a buckle bunny."
|
||||
icon_state = "cowboyhat_pink"
|
||||
item_state = "cowboyhat_pink"
|
||||
|
||||
/obj/item/clothing/head/cowboyhat/sec
|
||||
name = "security cowboy hat"
|
||||
desc = "A security cowboy hat, perfect for any true lawman"
|
||||
icon_state = "cowboyhat_sec"
|
||||
item_state = "cowboyhat_sec"
|
||||
armor = list("melee" = 40, "bullet" = 30, "laser" = 30,"energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
|
||||
|
||||
|
||||
/obj/item/clothing/head/pharaoh
|
||||
name = "pharaoh hat"
|
||||
desc = "Walk like an Egyptian."
|
||||
|
||||
@@ -238,6 +238,7 @@
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = -5,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = -5, "fire" = 0, "acid" = 0)
|
||||
equip_delay_other = 140
|
||||
var/datum/brain_trauma/mild/phobia/paranoia
|
||||
clothing_flags = IGNORE_HAT_TOSS
|
||||
|
||||
/obj/item/clothing/head/foilhat/equipped(mob/living/carbon/human/user, slot)
|
||||
..()
|
||||
|
||||
@@ -94,32 +94,6 @@
|
||||
icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi'
|
||||
alternate_worn_icon = 'modular_citadel/icons/mob/citadel/head.dmi'
|
||||
|
||||
|
||||
/obj/item/clothing/head/stalhelm
|
||||
name = "Stalhelm"
|
||||
desc = "Ein Helm, um die Nazi-Interesse an fremden Raumstationen zu sichern."
|
||||
icon_state = "stalhelm"
|
||||
item_state = "stalhelm"
|
||||
icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi'
|
||||
alternate_worn_icon = 'modular_citadel/icons/mob/citadel/head.dmi'
|
||||
|
||||
/obj/item/clothing/head/panzer
|
||||
name = "Panzer Cap"
|
||||
desc = "Command any mech in style."
|
||||
icon_state = "panzercap"
|
||||
item_state = "panzercap"
|
||||
icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi'
|
||||
alternate_worn_icon = 'modular_citadel/icons/mob/citadel/head.dmi'
|
||||
|
||||
/obj/item/clothing/head/naziofficer
|
||||
name = "Officer Cap"
|
||||
desc = "Style is all that matters."
|
||||
icon_state = "officercap"
|
||||
item_state = "officercap"
|
||||
icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi'
|
||||
alternate_worn_icon = 'modular_citadel/icons/mob/citadel/head.dmi'
|
||||
|
||||
|
||||
/obj/item/clothing/head/russobluecamohat
|
||||
name = "russian blue camo beret"
|
||||
desc = "A symbol of discipline, honor, and lots and lots of removal of some type of skewered food."
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
item_state = "sluthailer"
|
||||
aggressiveness = 0 //can't have your pets being mean!
|
||||
actions_types = list(/datum/action/item_action/halt)
|
||||
price = 5
|
||||
|
||||
/obj/item/clothing/mask/gas/sechailer/slut/attack_hand(mob/user)
|
||||
if(iscarbon(user))
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
var/obj/item/organ/heart/heart = M.getorganslot(ORGAN_SLOT_HEART)
|
||||
var/obj/item/organ/lungs/lungs = M.getorganslot(ORGAN_SLOT_LUNGS)
|
||||
|
||||
|
||||
|
||||
if (!do_mob(user,M,60)) // Stethoscope should take a moment to listen
|
||||
return // FAIL
|
||||
@@ -302,3 +302,4 @@
|
||||
icon = 'icons/obj/clothing/neck.dmi'
|
||||
icon_state = "bling"
|
||||
item_color = "bling"
|
||||
price = 30
|
||||
@@ -137,6 +137,7 @@
|
||||
desc = "A pair of knee-high jackboots, complete with heels. All style, all the time."
|
||||
icon_state = "jackboots-tall"
|
||||
item_state = "jackboots-tall"
|
||||
price = 5
|
||||
|
||||
/obj/item/clothing/shoes/jackboots/fast
|
||||
slowdown = -1
|
||||
@@ -371,6 +372,11 @@
|
||||
lightCycle = 0
|
||||
active = FALSE
|
||||
|
||||
/obj/item/clothing/shoes/footwraps
|
||||
name = "cloth footwraps"
|
||||
desc = "A roll of treated canvas used for wrapping claws or paws."
|
||||
icon_state = "foot_wraps"
|
||||
|
||||
/obj/item/clothing/shoes/wraps
|
||||
name = "gilded leg wraps"
|
||||
desc = "Ankle coverings. These ones have a golden design."
|
||||
@@ -392,6 +398,16 @@
|
||||
desc = "Ankle coverings. Hang ten, brother."
|
||||
icon_state = "bluecuffs"
|
||||
|
||||
/obj/item/clothing/shoes/cowboyboots
|
||||
name = "cowboy boots"
|
||||
desc = "A standard pair of brown cowboy boots."
|
||||
icon_state = "cowboyboots"
|
||||
|
||||
/obj/item/clothing/shoes/cowboyboots/black
|
||||
name = "black cowboy boots"
|
||||
desc = "A pair of black cowboy boots, pretty easy to scuff up."
|
||||
icon_state = "cowboyboots_black"
|
||||
|
||||
/obj/item/clothing/shoes/winterboots/christmasbootsr
|
||||
name = "red christmas boots"
|
||||
desc = "A pair of fluffy red christmas boots!"
|
||||
|
||||
@@ -103,8 +103,6 @@
|
||||
actions_types = list(/datum/action/item_action/toggle_helmet)
|
||||
var/helmettype = /obj/item/clothing/head/helmet/space/hardsuit
|
||||
var/obj/item/tank/jetpack/suit/jetpack = null
|
||||
roomy = TRUE
|
||||
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/Initialize()
|
||||
if(jetpack && ispath(jetpack))
|
||||
|
||||
@@ -1,25 +1,5 @@
|
||||
|
||||
//VG Ports
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/nazi
|
||||
name = "nazi hardhelmet"
|
||||
desc = "This is the face of das vaterland's top elite. Gas or energy are your only escapes."
|
||||
item_state = "hardsuit0-nazi"
|
||||
icon_state = "hardsuit0-nazi"
|
||||
armor = list(melee = 40, bullet = 30, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 20)
|
||||
item_color = "nazi"
|
||||
icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi'
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/nazi
|
||||
name = "nazi hardsuit"
|
||||
desc = "The attire of a true krieger. All shall fall, and only das vaterland will remain."
|
||||
item_state = "hardsuit-nazi"
|
||||
icon_state = "hardsuit-nazi"
|
||||
slowdown = 1
|
||||
armor = list(melee = 40, bullet = 30, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 20)
|
||||
allowed = list(/obj/item/gun,/obj/item/flashlight,/obj/item/tank,/obj/item/melee/)
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/nazi
|
||||
icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi'
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/soviet
|
||||
name = "soviet hardhelmet"
|
||||
desc = "Crafted with the pride of the proletariat. The vengeful gaze of the visor roots out all fascists and capitalists."
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
var/togglename = null
|
||||
var/suittoggled = FALSE
|
||||
|
||||
drop_sound = 'sound/items/handling/cloth_drop.ogg'
|
||||
pickup_sound = 'sound/items/handling/cloth_pickup.ogg'
|
||||
var/adjusted = NORMAL_STYLE
|
||||
mutantrace_variation = MUTANTRACE_VARIATION
|
||||
var/tauric = FALSE //Citadel Add for tauric hardsuits
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
max_integrity = 250
|
||||
resistance_flags = NONE
|
||||
armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
|
||||
roomy = TRUE
|
||||
|
||||
/obj/item/clothing/suit/armor/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -169,6 +169,7 @@
|
||||
cold_protection = CHEST|LEGS|ARMS
|
||||
heat_protection = CHEST|LEGS|ARMS
|
||||
mutantrace_variation = NO_MUTANTRACE_VARIATION //you don't need it
|
||||
price = 5
|
||||
|
||||
//Surgeon
|
||||
/obj/item/clothing/suit/apron/surgical
|
||||
|
||||
@@ -590,7 +590,6 @@
|
||||
item_state = "coatcentcom"
|
||||
armor = list("melee" = 40, "bullet" = 45, "laser" = 45, "energy" = 35, "bomb" = 40, "bio" = 25, "rad" = 25, "fire" = 35, "acid" = 50)
|
||||
hoodtype = /obj/item/clothing/head/hooded/winterhood/centcom
|
||||
roomy = TRUE
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/centcom/Initialize()
|
||||
. = ..()
|
||||
@@ -599,7 +598,6 @@
|
||||
/obj/item/clothing/head/hooded/winterhood/centcom
|
||||
icon_state = "winterhood_centcom"
|
||||
armor = list("melee" = 40, "bullet" = 45, "laser" = 45, "energy" = 35, "bomb" = 40, "bio" = 25, "rad" = 25, "fire" = 35, "acid" = 50)
|
||||
roomy = TRUE
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/captain
|
||||
name = "captain's winter coat"
|
||||
@@ -637,6 +635,7 @@
|
||||
icon_state = "coatsecuritypink"
|
||||
item_state = "coatsecuritypink"
|
||||
hoodtype = /obj/item/clothing/head/hooded/winterhood/security/pink
|
||||
price = 5
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/security/Initialize()
|
||||
. = ..()
|
||||
@@ -956,3 +955,20 @@
|
||||
|
||||
/obj/item/clothing/head/hooded/winterhood/durathread
|
||||
icon_state = "winterhood_durathread"
|
||||
|
||||
//Enzo_Leon Patron stuff
|
||||
/obj/item/clothing/suit/toggle/enzojacket
|
||||
name = "Altevain Colony-Ship Command Jacket"
|
||||
desc = "A comfortable form fitting jacket that has a little cheese emblem on the chest."
|
||||
icon_state = "enzojacket"
|
||||
item_state = "enzojacket"
|
||||
body_parts_covered = CHEST|ARMS
|
||||
//End
|
||||
|
||||
//Might get moved later since I have no clue where to put this stuff for now - Luke_vale
|
||||
/obj/item/clothing/suit/toggle/labcoat/formallab
|
||||
name = "winter labcoat"
|
||||
desc = "A stark white labcoat, thicker and kitted out with extra fluff to keep you warm even on the coldest of mad sceinctist nights."
|
||||
icon_state = "labcoat_formal"
|
||||
item_state = "labcoat_formal"
|
||||
body_parts_covered = CHEST|ARMS
|
||||
|
||||
@@ -226,3 +226,63 @@
|
||||
W.current_charges += 8
|
||||
to_chat(user, "<span class='notice'>You charge \the [W]. It can now absorb [W.current_charges] hits.</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/head/notwizard
|
||||
name = "wizard hat"
|
||||
desc = "Strange-looking hat-wear that most certainly belongs to an aspiring magic user."
|
||||
icon_state = "wizard"
|
||||
gas_transfer_coefficient = 1
|
||||
permeability_coefficient = 1
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
strip_delay = 50
|
||||
equip_delay_other = 50
|
||||
resistance_flags = FLAMMABLE
|
||||
dog_fashion = /datum/dog_fashion/head/blue_wizard
|
||||
|
||||
/obj/item/clothing/head/notwizard/red
|
||||
name = "red wizard hat"
|
||||
desc = "Strange-looking red hat-wear that most certainly belongs to an aspiring magic user."
|
||||
icon_state = "redwizard"
|
||||
dog_fashion = /datum/dog_fashion/head/red_wizard
|
||||
|
||||
/obj/item/clothing/head/notwizard/yellow
|
||||
name = "yellow wizard hat"
|
||||
desc = "Strange-looking yellow hat-wear that most certainly belongs to an aspiring magic user."
|
||||
icon_state = "yellowwizard"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/notwizard/black
|
||||
name = "black wizard hat"
|
||||
desc = "Strange-looking black hat-wear that most certainly belongs to an aspiring skeleton. Way cooler than magic." //skeleton gang 4lyfe
|
||||
icon_state = "blackwizard"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/suit/notwizrobe
|
||||
name = "wizard robe"
|
||||
desc = "A decent looking robe that seems to radiate imagination."
|
||||
icon_state = "wizard"
|
||||
item_state = "wizrobe"
|
||||
gas_transfer_coefficient = 1
|
||||
permeability_coefficient = 1
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
strip_delay = 50
|
||||
equip_delay_other = 50
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/clothing/suit/notwizrobe/red
|
||||
name = "red wizard robe"
|
||||
desc = "A decent looking red robe that seems to radiate imagination."
|
||||
icon_state = "redwizard"
|
||||
item_state = "redwizrobe"
|
||||
|
||||
/obj/item/clothing/suit/notwizrobe/yellow
|
||||
name = "yellow wizard robe"
|
||||
desc = "A decent looking yellow robe that seems to radiate imagination."
|
||||
icon_state = "yellowwizard"
|
||||
item_state = "yellowwizrobe"
|
||||
|
||||
/obj/item/clothing/suit/notwizrobe/black
|
||||
name = "black wizard robe"
|
||||
desc = "An unnerving black robe that radiates death and decay."
|
||||
icon_state = "blackwizard"
|
||||
item_state = "blackwizrobe"
|
||||
@@ -16,6 +16,10 @@
|
||||
var/obj/item/clothing/accessory/attached_accessory
|
||||
var/mutable_appearance/accessory_overlay
|
||||
mutantrace_variation = MUTANTRACE_VARIATION //Are there special sprites for specific situations? Don't use this unless you need to.
|
||||
equip_sound = 'sound/items/equip/jumpsuit_equip.ogg'
|
||||
|
||||
drop_sound = 'sound/items/handling/cloth_drop.ogg'
|
||||
pickup_sound = 'sound/items/handling/cloth_pickup.ogg'
|
||||
|
||||
/obj/item/clothing/under/worn_overlays(isinhands = FALSE)
|
||||
. = list()
|
||||
@@ -156,4 +160,4 @@
|
||||
if(SENSOR_COORDS)
|
||||
. += "Its vital tracker and tracking beacon appear to be enabled."
|
||||
if(attached_accessory)
|
||||
. += "\A [attached_accessory] is attached to it."
|
||||
. += "\A [attached_accessory] is attached to it."
|
||||
|
||||
@@ -381,6 +381,7 @@
|
||||
item_state = "b_suit"
|
||||
item_color = "galaxy_blue"
|
||||
can_adjust = FALSE
|
||||
price = 10
|
||||
|
||||
/obj/item/clothing/under/lawyer/galaxy_red
|
||||
name = "\improper Pulsar Gonne"
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
icon_state = "rsecuritypink"
|
||||
item_state = "r_suit"
|
||||
item_color = "rsecuritypink"
|
||||
price = 3
|
||||
/obj/item/clothing/under/rank/security/skirt
|
||||
name = "security jumpskirt"
|
||||
desc = "A \"tactical\" security jumpsuit with the legs replaced by a skirt."
|
||||
@@ -46,6 +47,7 @@
|
||||
item_state = "secslutskirt"
|
||||
item_color = null //i dont understand what item_color even is, apparently setting it to null means it won't change color in a washing machine?
|
||||
mutantrace_variation = NO_MUTANTRACE_VARIATION //look at the first two comments in vg_under.dm
|
||||
price = 3
|
||||
/obj/item/clothing/under/rank/security/skirt/slut/pink
|
||||
desc = "A \"\"\"tactical\"\"\" security jumpsuit with the legs replaced by a skirt. No matter how you adjust it, it always feels a little too small. This one seems to have an experimental color scheme."
|
||||
icon_state = "secslutskirtpink"
|
||||
@@ -59,6 +61,7 @@
|
||||
can_adjust = FALSE
|
||||
body_parts_covered = CHEST|GROIN
|
||||
mutantrace_variation = NO_MUTANTRACE_VARIATION
|
||||
price = 5
|
||||
|
||||
|
||||
/obj/item/clothing/under/rank/warden
|
||||
|
||||
@@ -119,14 +119,12 @@
|
||||
item_state = "g_suit"
|
||||
item_color = "officer"
|
||||
alt_covers_chest = TRUE
|
||||
roomy = TRUE
|
||||
/obj/item/clothing/under/rank/centcom_commander
|
||||
desc = "It's a jumpsuit worn by CentCom's highest-tier Commanders, adorned with a golden K and a star. signifying work under Kinaris."
|
||||
name = "\improper CentCom Commander's jumpsuit"
|
||||
icon_state = "centcom"
|
||||
item_state = "dg_suit"
|
||||
item_color = "centcom"
|
||||
roomy = TRUE
|
||||
/obj/item/clothing/under/rank/centcom_officer/skirt
|
||||
name = "\improper CentCom Officer's jumpskirt"
|
||||
desc = "It's a jumpskirt worn by CentCom's officials, adorned with a golden K and a star, signifying work under Kinaris."
|
||||
@@ -136,7 +134,6 @@
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
roomy = TRUE
|
||||
/obj/item/clothing/under/space
|
||||
name = "\improper NASA jumpsuit"
|
||||
desc = "It has a NASA logo on it and is made of space-proofed materials."
|
||||
@@ -169,7 +166,6 @@
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
|
||||
can_adjust = FALSE
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
roomy = TRUE
|
||||
/obj/item/clothing/under/owl
|
||||
name = "owl uniform"
|
||||
desc = "A soft brown jumpsuit made of synthetic feathers and strong conviction."
|
||||
@@ -790,3 +786,43 @@
|
||||
can_adjust = FALSE
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
mutantrace_variation = NO_MUTANTRACE_VARIATION
|
||||
|
||||
//Chemlight the dumb dog was here
|
||||
/obj/item/clothing/under/greenplaidshirt
|
||||
name = "plaid green shirt"
|
||||
desc = "A pair of khaki pants and a green shirt with a plaid open button shirt, looks roomy on the inside..."
|
||||
icon_state = "greenplaidshirt"
|
||||
item_state = "greenplaidshirt"
|
||||
item_color = "greenplaidshirt"
|
||||
body_parts_covered = CHEST|GROIN|ARMS|LEGS
|
||||
can_adjust = FALSE
|
||||
fitted = NO_FEMALE_UNIFORM
|
||||
//yes
|
||||
|
||||
//Enzo_Leon patron stuff
|
||||
/obj/item/clothing/under/enzoshirt
|
||||
name = "Altevain Standard-Issue Uniform"
|
||||
desc = "A soft, and light uniform with blue-space threading to help with Altevain proportions."
|
||||
icon_state = "enzoshirt"
|
||||
item_state = "enzoshirt"
|
||||
item_color = "enzoshirt"
|
||||
body_parts_covered = CHEST|GROIN|ARMS|LEGS
|
||||
//End
|
||||
|
||||
/obj/item/clothing/under/wedding_dress
|
||||
name = "wedding dress"
|
||||
desc = "A luxurious gown for once-in-a-lifetime occasions."
|
||||
icon_state = "wedding_dress"
|
||||
item_state = "wedding_dress"
|
||||
body_parts_covered = CHEST|GROIN|LEGS
|
||||
flags_cover = HIDESHOES
|
||||
mutantrace_variation = NO_MUTANTRACE_VARIATION
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/tuxedo
|
||||
name = "tuxedo"
|
||||
desc = "A formal black tuxedo. It exudes classiness."
|
||||
icon_state = "tuxedo"
|
||||
item_state = "tuxedo"
|
||||
mutantrace_variation = NO_MUTANTRACE_VARIATION //temporary
|
||||
can_adjust = FALSE
|
||||
|
||||
@@ -21,19 +21,19 @@
|
||||
|
||||
/obj/item/clothing/under/syndicate/tacticool
|
||||
name = "tacticool turtleneck"
|
||||
desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-."
|
||||
icon_state = "tactifool"
|
||||
desc = "A robust looking turtleneck designed to fit tightly against the body while still being comfortable."
|
||||
icon_state = "syndicate"
|
||||
item_state = "bl_suit"
|
||||
item_color = "tactifool"
|
||||
item_color = "syndicate"
|
||||
has_sensor = HAS_SENSORS
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
|
||||
|
||||
/obj/item/clothing/under/syndicate/tacticool/skirt
|
||||
name = "tacticool skirtleneck"
|
||||
desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-."
|
||||
icon_state = "tactifool_skirt"
|
||||
desc = "A robust looking skirtleneck designed to fit tightly against the body while still being comfortable."
|
||||
icon_state = "syndicate_skirt"
|
||||
item_state = "bl_suit"
|
||||
item_color = "tactifool_skirt"
|
||||
item_color = "syndicate_skirt"
|
||||
has_sensor = HAS_SENSORS
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
CAT_PRIMAL,
|
||||
CAT_FOOD,
|
||||
CAT_CLOTHING)
|
||||
//CAT_CARPENTRY
|
||||
var/list/subcategories = list(
|
||||
list( //Weapon subcategories
|
||||
CAT_WEAPON,
|
||||
@@ -110,6 +111,10 @@
|
||||
for(var/datum/reagent/A in RC.reagents.reagent_list)
|
||||
.["other"][A.type] += A.volume
|
||||
.["other"][I.type] += 1
|
||||
if(istype(I, /obj/item/reagent_containers/food/snacks/grown) && !.["color"]) //First we find has priority
|
||||
var/obj/item/reagent_containers/food/snacks/grown/G = I
|
||||
if(G.modified_colors)
|
||||
.["color"] = G.color
|
||||
|
||||
/datum/personal_crafting/proc/check_tools(mob/user, datum/crafting_recipe/R, list/contents)
|
||||
if(!R.tools.len)
|
||||
@@ -145,6 +150,9 @@
|
||||
/datum/personal_crafting/proc/construct_item(mob/user, datum/crafting_recipe/R)
|
||||
var/list/contents = get_surroundings(user)
|
||||
var/send_feedback = 1
|
||||
var/cached_color = null
|
||||
if(contents["color"]) //From plants
|
||||
cached_color = contents["color"]
|
||||
if(check_contents(R, contents))
|
||||
if(check_tools(user, R, contents))
|
||||
if(do_after(user, R.time, target = user))
|
||||
@@ -156,6 +164,7 @@
|
||||
var/list/parts = del_reqs(R, user)
|
||||
var/atom/movable/I = new R.result (get_turf(user.loc))
|
||||
I.CheckParts(parts, R)
|
||||
I.color = cached_color
|
||||
if(send_feedback)
|
||||
SSblackbox.record_feedback("tally", "object_crafted", 1, I.type)
|
||||
return 0
|
||||
@@ -439,4 +448,4 @@
|
||||
/datum/mind/proc/teach_crafting_recipe(R)
|
||||
if(!learned_recipes)
|
||||
learned_recipes = list()
|
||||
learned_recipes |= R
|
||||
learned_recipes |= R
|
||||
|
||||
@@ -43,6 +43,24 @@
|
||||
/obj/item/stack/cable_coil = 5)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/hudeyesec
|
||||
name = "Security HUD eyepatch"
|
||||
result = /obj/item/clothing/glasses/hud/security/sunglasses/eyepatch
|
||||
time = 20
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
reqs = list(/obj/item/clothing/glasses/hud/security/sunglasses = 1,
|
||||
/obj/item/clothing/glasses/eyepatch = 1,
|
||||
/obj/item/stack/cable_coil = 5)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/hudeyesecremoval
|
||||
name = "Security HUD removal (Eyepatch)"
|
||||
result = /obj/item/clothing/glasses/hud/security/sunglasses
|
||||
time = 20
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
reqs = list(/obj/item/clothing/glasses/hud/security/sunglasses/eyepatch = 1)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/hudsunsecremoval
|
||||
name = "Security HUD removal"
|
||||
result = /obj/item/clothing/glasses/sunglasses
|
||||
@@ -61,6 +79,16 @@
|
||||
/obj/item/stack/cable_coil = 5)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/hudeyemed
|
||||
name = "Medical HUD eyepatch"
|
||||
result = /obj/item/clothing/glasses/hud/health/eyepatch
|
||||
time = 20
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
reqs = list(/obj/item/clothing/glasses/hud/health = 1,
|
||||
/obj/item/clothing/glasses/eyepatch = 1,
|
||||
/obj/item/stack/cable_coil = 5)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/hudsunmedremoval
|
||||
name = "Medical HUD removal"
|
||||
result = /obj/item/clothing/glasses/sunglasses
|
||||
@@ -69,6 +97,86 @@
|
||||
reqs = list(/obj/item/clothing/glasses/hud/health/sunglasses = 1)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/hudeyemedremoval
|
||||
name = "Medical HUD removal (Eyepatch)"
|
||||
result = /obj/item/clothing/glasses/eyepatch
|
||||
time = 20
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
reqs = list(/obj/item/clothing/glasses/hud/health/eyepatch = 1)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/hudeyedia
|
||||
name = "Diagnostic HUD eyepatch"
|
||||
result = /obj/item/clothing/glasses/hud/diagnostic/eyepatch
|
||||
time = 20
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
reqs = list(/obj/item/clothing/glasses/hud/diagnostic = 1,
|
||||
/obj/item/clothing/glasses/eyepatch = 1,
|
||||
/obj/item/stack/cable_coil = 5)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/hudeyediaremoval
|
||||
name = "Diagnostic HUD removal"
|
||||
result = /obj/item/clothing/glasses/eyepatch
|
||||
time = 20
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
reqs = list(/obj/item/clothing/glasses/hud/diagnostic/eyepatch = 1)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/hudeyesci
|
||||
name = "Science eyepatch"
|
||||
result = /obj/item/clothing/glasses/science/eyepatch
|
||||
time = 20
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
reqs = list(/obj/item/clothing/glasses/science = 1,
|
||||
/obj/item/clothing/glasses/eyepatch = 1,
|
||||
/obj/item/stack/cable_coil = 5)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/hudeyesciremoval
|
||||
name = "Science eyepatch removal"
|
||||
result = /obj/item/clothing/glasses/eyepatch
|
||||
time = 20
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
reqs = list(/obj/item/clothing/glasses/science/eyepatch = 1)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/hudeyemeson
|
||||
name = "Meson eyepatch"
|
||||
result = /obj/item/clothing/glasses/meson/eyepatch
|
||||
time = 20
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
reqs = list(/obj/item/clothing/glasses/meson = 1,
|
||||
/obj/item/clothing/glasses/eyepatch = 1,
|
||||
/obj/item/stack/cable_coil = 5)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/hudeyemesonremoval
|
||||
name = "Meson eyepatch removal"
|
||||
result = /obj/item/clothing/glasses/eyepatch
|
||||
time = 20
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
reqs = list(/obj/item/clothing/glasses/meson/eyepatch = 1)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/hudeyenv
|
||||
name = "Night Vision eyepatch"
|
||||
result = /obj/item/clothing/glasses/night/eyepatch
|
||||
time = 20
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
reqs = list(/obj/item/clothing/glasses/night = 1,
|
||||
/obj/item/clothing/glasses/eyepatch = 1,
|
||||
/obj/item/stack/cable_coil = 5)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/hudeyenvremoval
|
||||
name = "Night Vision eyepatch removal"
|
||||
result = /obj/item/clothing/glasses/eyepatch
|
||||
time = 20
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
reqs = list(/obj/item/clothing/glasses/night/eyepatch = 1)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/beergoggles
|
||||
name = "Beer Goggles"
|
||||
result = /obj/item/clothing/glasses/sunglasses/reagent
|
||||
@@ -185,3 +293,11 @@
|
||||
time = 60
|
||||
always_availible = TRUE
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/garlic_necklace
|
||||
name = "Garlic Necklace"
|
||||
result = /obj/item/clothing/neck/garlic_necklace
|
||||
reqs = list(/obj/item/reagent_containers/food/snacks/grown/garlic = 15,
|
||||
/obj/item/stack/cable_coil = 10)
|
||||
time = 100 //Takes a while to put all the garlics on the coil and knot it.
|
||||
category = CAT_CLOTHING
|
||||
|
||||
@@ -373,3 +373,30 @@
|
||||
time = 100
|
||||
category = CAT_MISC
|
||||
always_availible = FALSE // Disabled til learned
|
||||
|
||||
//Bouquets <3
|
||||
/datum/crafting_recipe/mixedbouquet
|
||||
name = "Mixed bouquet"
|
||||
result = /obj/item/bouquet
|
||||
reqs = list(/obj/item/reagent_containers/food/snacks/grown/poppy/lily =2,
|
||||
/obj/item/grown/sunflower = 2,
|
||||
/obj/item/reagent_containers/food/snacks/grown/poppy/geranium = 2)
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/sunbouquet
|
||||
name = "Sunflower bouquet"
|
||||
result = /obj/item/bouquet/sunflower
|
||||
reqs = list(/obj/item/grown/sunflower = 6)
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/poppybouquet
|
||||
name = "Poppy bouquet"
|
||||
result = /obj/item/bouquet/poppy
|
||||
reqs = list (/obj/item/reagent_containers/food/snacks/grown/poppy = 6)
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/rosebouquet
|
||||
name = "Rose bouquet"
|
||||
result = /obj/item/bouquet/rose
|
||||
reqs = list(/obj/item/grown/rose = 6)
|
||||
category = CAT_MISC
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
var/list/gamemode_blacklist = list() // Event won't happen in these gamemodes
|
||||
var/list/gamemode_whitelist = list() // Event will happen ONLY in these gamemodes if not empty
|
||||
var/list/map_blacklist = list() //Event won't run if this contains the current station map. Must be contain something like "BoxStation.dmm". Capitalization matters.
|
||||
var/list/map_whitelist = list() //Same as above, except only for these maps
|
||||
|
||||
var/triggering //admin cancellation
|
||||
|
||||
@@ -50,6 +52,10 @@
|
||||
return FALSE
|
||||
if(gamemode_whitelist.len && !(gamemode in gamemode_whitelist))
|
||||
return FALSE
|
||||
if(map_blacklist.len && (SSmapping.config.map_file in map_blacklist)) //HYPER EDIT: certain maps will get special events
|
||||
return FALSE
|
||||
if(map_whitelist.len && !(SSmapping.config.map_file in map_whitelist))
|
||||
return FALSE
|
||||
if(holidayID && (!SSevents.holidays || !SSevents.holidays[holidayID]))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -10,16 +10,8 @@
|
||||
|
||||
|
||||
/datum/round_event/anomaly/anomaly_bluespace/announce(fake)
|
||||
if(prob(90))
|
||||
priority_announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
else
|
||||
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
|
||||
for(var/obj/machinery/computer/communications/C in GLOB.machines)
|
||||
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
|
||||
var/obj/item/paper/P = new(C.loc)
|
||||
P.name = "Unstable bluespace anomaly"
|
||||
P.info = "Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name]."
|
||||
P.update_icon()
|
||||
priority_announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
|
||||
|
||||
/datum/round_event/anomaly/anomaly_bluespace/start()
|
||||
var/turf/T = safepick(get_area_turfs(impact_area))
|
||||
|
||||
@@ -11,16 +11,7 @@
|
||||
announceWhen = 3
|
||||
|
||||
/datum/round_event/anomaly/anomaly_flux/announce(fake)
|
||||
if(prob(90))
|
||||
priority_announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
else
|
||||
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
|
||||
for(var/obj/machinery/computer/communications/C in GLOB.machines)
|
||||
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
|
||||
var/obj/item/paper/P = new(C.loc)
|
||||
P.name = "Localized hyper-energetic flux wave"
|
||||
P.info = "Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name]."
|
||||
P.update_icon()
|
||||
priority_announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
|
||||
/datum/round_event/anomaly/anomaly_flux/start()
|
||||
var/turf/T = safepick(get_area_turfs(impact_area))
|
||||
|
||||
@@ -9,16 +9,7 @@
|
||||
announceWhen = 20
|
||||
|
||||
/datum/round_event/anomaly/anomaly_grav/announce(fake)
|
||||
if(prob(90))
|
||||
priority_announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
else
|
||||
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
|
||||
for(var/obj/machinery/computer/communications/C in GLOB.machines)
|
||||
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
|
||||
var/obj/item/paper/P = new(C.loc)
|
||||
P.name = "Gravitational anomaly"
|
||||
P.info = "Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name]."
|
||||
P.update_icon()
|
||||
priority_announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
|
||||
/datum/round_event/anomaly/anomaly_grav/start()
|
||||
var/turf/T = safepick(get_area_turfs(impact_area))
|
||||
|
||||
@@ -9,16 +9,7 @@
|
||||
announceWhen = 10
|
||||
|
||||
/datum/round_event/anomaly/anomaly_pyro/announce(fake)
|
||||
if(prob(90))
|
||||
priority_announce("Pyroclastic anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
else
|
||||
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
|
||||
for(var/obj/machinery/computer/communications/C in GLOB.machines)
|
||||
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
|
||||
var/obj/item/paper/P = new(C.loc)
|
||||
P.name = "Pyroclastic anomaly"
|
||||
P.info = "Pyroclastic anomaly detected on long range scanners. Expected location: [impact_area.name]."
|
||||
P.update_icon()
|
||||
priority_announce("Pyroclastic anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
|
||||
/datum/round_event/anomaly/anomaly_pyro/start()
|
||||
var/turf/T = safepick(get_area_turfs(impact_area))
|
||||
|
||||
@@ -11,16 +11,7 @@
|
||||
announceWhen = 3
|
||||
|
||||
/datum/round_event/anomaly/anomaly_vortex/announce(fake)
|
||||
if(prob(90))
|
||||
priority_announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert")
|
||||
else
|
||||
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
|
||||
for(var/obj/machinery/computer/communications/C in GLOB.machines)
|
||||
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
|
||||
var/obj/item/paper/P = new(C.loc)
|
||||
P.name = "Vortex anomaly"
|
||||
P.info = "Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]."
|
||||
P.update_icon()
|
||||
priority_announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert")
|
||||
|
||||
/datum/round_event/anomaly/anomaly_vortex/start()
|
||||
var/turf/T = safepick(get_area_turfs(impact_area))
|
||||
|
||||
@@ -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))
|
||||
@@ -12,10 +13,11 @@
|
||||
|
||||
/datum/round_event/aurora_caelus
|
||||
announceWhen = 1
|
||||
startWhen = 9
|
||||
startWhen = 8 //Delayed with sleep()
|
||||
endWhen = 50
|
||||
var/list/aurora_colors = list("#ffd980", "#eaff80", "#eaff80", "#ffd980", "#eaff80", "#A2FFC7", "#9400D3", "#FFC0CB")
|
||||
var/aurora_progress = 0 //this cycles from 1 to 8, slowly changing colors from gentle green to gentle blue
|
||||
var/list/applicable_areas = list()
|
||||
|
||||
/datum/round_event/aurora_caelus/announce()
|
||||
priority_announce("[station_name()]: A harmless cloud of ions is approaching your station, and will exhaust their energy battering the hull. Kinaris Command has approved a short break for all employees to relax and observe this very rare event. During this time, starlight will be bright but gentle, shifting between quiet green and blue colors. We will also play quiet music for you to enjoy and relax. Any staff who would like to view these lights for themselves may proceed to the area nearest to them with viewing ports to open space. We hope you enjoy the lights.",
|
||||
@@ -24,39 +26,68 @@
|
||||
for(var/V in GLOB.player_list)
|
||||
var/mob/M = V
|
||||
if((M.client.prefs.toggles & SOUND_MIDI) && is_station_level(M.z))
|
||||
M.playsound_local(M, 'sound/ambience/aurora_caelus_new.ogg', 40, FALSE, pressure_affected = FALSE) //ogg is "The Fire is Gone" by Heaven Pierce Her, used in the videogame ULTRAKILL. All respects and credits to the equivalent artists who worked on it.
|
||||
M.playsound_local(M, pick('sound/ambience/aurora_caelus_new.ogg','sound/ambience/aurora_caelus.ogg'), 40, FALSE, pressure_affected = FALSE) //ogg is "The Fire is Gone" by Heaven Pierce Her, used in the videogame ULTRAKILL. All respects and credits to the equivalent artists who worked on it.
|
||||
start_checking()
|
||||
|
||||
/datum/round_event/aurora_caelus/proc/start_checking()
|
||||
var/list/turfs_to_check = list()
|
||||
var/x = 1
|
||||
var/y = 1
|
||||
while(TRUE)
|
||||
turfs_to_check += locate(x,y,2) //If the station z-level ever gets changed, change this too. I couldn't find if there's an easy way to get it
|
||||
x++
|
||||
if(x > 255)
|
||||
x = 0
|
||||
y++
|
||||
if(y > 255)
|
||||
break
|
||||
if(!turfs_to_check)
|
||||
CRASH("Aurora Caelus called, but there's no space!")
|
||||
var/tlen = turfs_to_check.len
|
||||
var/i = 0
|
||||
while(i < tlen)
|
||||
i++
|
||||
var/turf/T = turfs_to_check[i]
|
||||
if(!istype(T, /turf/open/space))
|
||||
continue
|
||||
if(i%2500 == 0)
|
||||
sleep(1) //try to spread the lag around a bit
|
||||
var/sure = (!istype(get_step(T, NORTH)?.loc, /area/space)||\
|
||||
!istype(get_step(T, NORTHEAST)?.loc, /area/space)||\
|
||||
!istype(get_step(T, EAST)?.loc, /area/space)||\
|
||||
!istype(get_step(T, SOUTHEAST)?.loc, /area/space)||\
|
||||
!istype(get_step(T, SOUTH)?.loc, /area/space)||\
|
||||
!istype(get_step(T, SOUTHWEST)?.loc, /area/space)||\
|
||||
!istype(get_step(T, WEST)?.loc, /area/space)||\
|
||||
!istype(get_step(T, NORTHWEST)?.loc, /area/space)) //Better than using range()
|
||||
if(sure)
|
||||
applicable_areas += T
|
||||
|
||||
/datum/round_event/aurora_caelus/start()
|
||||
for(var/area in GLOB.sortedAreas)
|
||||
var/area/A = area
|
||||
if(initial(A.dynamic_lighting) == DYNAMIC_LIGHTING_IFSTARLIGHT)
|
||||
for(var/turf/open/space/S in A)
|
||||
S.set_light(S.light_range * 6, S.light_power * 1)
|
||||
for(var/turf/S in applicable_areas)
|
||||
S.set_light(6, 0.8, l_color = aurora_colors[1])
|
||||
|
||||
/datum/round_event/aurora_caelus/tick()
|
||||
if(activeFor % 5 == 0)
|
||||
aurora_progress++
|
||||
if(aurora_progress > LAZYLEN(aurora_colors))
|
||||
aurora_progress = 1
|
||||
var/aurora_color = aurora_colors[aurora_progress]
|
||||
for(var/area in GLOB.sortedAreas)
|
||||
var/area/A = area
|
||||
if(initial(A.dynamic_lighting) == DYNAMIC_LIGHTING_IFSTARLIGHT)
|
||||
for(var/turf/open/space/S in A)
|
||||
S.set_light(l_color = aurora_color)
|
||||
for(var/turf/S in applicable_areas)
|
||||
S.set_light(l_color = aurora_color)
|
||||
|
||||
/datum/round_event/aurora_caelus/end()
|
||||
for(var/area in GLOB.sortedAreas)
|
||||
var/area/A = area
|
||||
if(initial(A.dynamic_lighting) == DYNAMIC_LIGHTING_IFSTARLIGHT)
|
||||
for(var/turf/open/space/S in A)
|
||||
fade_to_black(S)
|
||||
priority_announce("The aurora caelus event is now ending. Starlight conditions will slowly return to normal. When this has concluded, please return to your workplace and continue work as normal. Have a pleasant shift, [station_name()], and thank you for watching with us.",
|
||||
sound = 'sound/misc/notice2.ogg',
|
||||
sender_override = "Kinaris Meteorology Division")
|
||||
sound = 'sound/misc/notice2.ogg',
|
||||
sender_override = "Kinaris Meteorology Division")
|
||||
for(var/S in applicable_areas)
|
||||
fade_to_black(S)
|
||||
|
||||
/datum/round_event/aurora_caelus/proc/fade_to_black(turf/open/space/S)
|
||||
set waitfor = FALSE
|
||||
var/new_light = initial(S.light_range)
|
||||
while(S.light_range > new_light)
|
||||
S.set_light(S.light_range - 0.2)
|
||||
sleep(30)
|
||||
S.set_light(new_light, initial(S.light_power), initial(S.light_color))
|
||||
var/i = 0.8
|
||||
while(i>0)
|
||||
S.set_light(l_power=i)
|
||||
sleep(10)
|
||||
i -= 0.05 //16 seconds
|
||||
S.set_light(initial(S.light_range), initial(S.light_power), initial(S.light_color))
|
||||
|
||||
@@ -35,16 +35,8 @@
|
||||
source = initial(example.name)
|
||||
else if(originMachine)
|
||||
source = originMachine.name
|
||||
if(prob(50))
|
||||
priority_announce("Rampant brand intelligence has been detected aboard [station_name()]. Please stand by. The origin is believed to be \a [source].", "Machine Learning Alert")
|
||||
else
|
||||
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
|
||||
for(var/obj/machinery/computer/communications/C in GLOB.machines)
|
||||
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
|
||||
var/obj/item/paper/P = new(C.loc)
|
||||
P.name = "Rampant brand intelligence"
|
||||
P.info = "Rampant brand intelligence has been detected aboard [station_name()]. Please stand by. The origin is believed to be \a [source]."
|
||||
P.update_icon()
|
||||
priority_announce("Rampant brand intelligence has been detected aboard [station_name()]. Please stand by. The origin is believed to be \a [source].", "Machine Learning Alert")
|
||||
|
||||
/datum/round_event/brand_intelligence/start()
|
||||
for(var/obj/machinery/vending/V in GLOB.machines)
|
||||
if(!is_station_level(V.z))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user