Merge branch 'master' into upstream-merge-37423

This commit is contained in:
LetterJay
2018-05-16 12:17:57 -05:00
committed by GitHub
220 changed files with 5462 additions and 3984 deletions
+1 -1
View File
@@ -39,7 +39,7 @@
return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.")
if (CONFIG_GET(flag/panic_bunker) && SSdbcore.Connect())
log_access("Failed Login: [key] - Guests not allowed during panic bunker")
return list("reason"="guest", "desc"="\nReason: You must first join the Discord to verify your account before joining this server. Please ping an admin once you've joined and read the rules. https://discord.gg/E6SQuhz")
return list("reason"="guest", "desc"="\nReason: You must first sign into your BYOND account or join the Discord to verify your account before joining this server. Please ping an admin once you've joined and read the rules. https://discord.gg/E6SQuhz")
//Population Cap Checking
var/extreme_popcap = CONFIG_GET(number/extreme_popcap)
+1 -1
View File
@@ -95,7 +95,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Jump To Key") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/Getmob(mob/M in GLOB.mob_list)
/client/proc/Getmob(mob/M in GLOB.mob_list - GLOB.dummy_mob_list)
set category = "Admin"
set name = "Get Mob"
set desc = "Mob to teleport"
+1 -1
View File
@@ -27,7 +27,7 @@
if(isnewplayer(M))
continue
if (M.stat == DEAD || (M.client && M.client.holder && (M.client.prefs.chat_toggles & CHAT_DEAD))) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above
M.show_message(rendered, 2)
to_chat(M, rendered)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Dsay") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -151,6 +151,7 @@
desc = "You get the feeling that you shouldn't be standing here."
clockwork_desc = "A sigil that will soon erupt and smite any unenlightened nearby."
icon = 'icons/effects/96x96.dmi'
icon_state = ""
pixel_x = -32
pixel_y = -32
layer = BELOW_MOB_LAYER
+4 -10
View File
@@ -33,10 +33,8 @@
desc = "A sword humming with unholy energy. It glows with a dim red light."
icon_state = "cultblade"
item_state = "cultblade"
lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi'
righthand_file = 'icons/mob/inhands/64x64_righthand.dmi'
inhand_x_dimension = 64
inhand_y_dimension = 64
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
flags_1 = CONDUCT_1
sharpness = IS_SHARP
w_class = WEIGHT_CLASS_BULKY
@@ -73,8 +71,6 @@
if(!iscultist(user))
if(!is_servant_of_ratvar(user))
to_chat(user, "<span class='cultlarge'>\"I wouldn't advise that.\"</span>")
to_chat(user, "<span class='warning'>An overwhelming sense of nausea overpowers you!</span>")
user.Dizzy(120)
else
to_chat(user, "<span class='cultlarge'>\"One of Ratvar's toys is trying to play with things [user.p_they()] shouldn't. Cute.\"</span>")
to_chat(user, "<span class='userdanger'>A horrible force yanks at your arm!</span>")
@@ -138,10 +134,7 @@
if(!iscultist(user))
if(!is_servant_of_ratvar(user))
to_chat(user, "<span class='cultlarge'>\"I wouldn't advise that.\"</span>")
to_chat(user, "<span class='warning'>An overwhelming sense of nausea overpowers you!</span>")
user.Dizzy(80)
user.dropItemToGround(src, TRUE)
user.Knockdown(30)
force = 5
return
else
to_chat(user, "<span class='cultlarge'>\"One of Ratvar's toys is trying to play with things [user.p_they()] shouldn't. Cute.\"</span>")
@@ -151,6 +144,7 @@
user.dropItemToGround(src, TRUE)
user.Knockdown(50)
return
force = initial(force)
jaunt.Grant(user, src)
linked_action.Grant(user, src)
user.update_icons()
+2 -1
View File
@@ -144,7 +144,8 @@ This file contains the cult dagger and rune list code
if(locate(/obj/effect/rune) in T)
to_chat(user, "<span class='cult'>There is already a rune here.</span>")
return FALSE
if(!is_station_level(T.z) && !is_mining_level(T.z))
var/area/A = get_area(T)
if((!is_station_level(T.z) && !is_mining_level(T.z)) || (A && !A.blob_allowed))
to_chat(user, "<span class='warning'>The veil is not weak enough here.</span>")
return FALSE
return TRUE
+5
View File
@@ -708,6 +708,11 @@ structure_check() searches for nearby cultist structures required for the invoca
fail_invoke()
log_game("Summon Cultist rune failed - target died")
return
if(cultist_to_summon.pulledby || cultist_to_summon.buckled)
to_chat(user, "<span class='cult italic'>[cultist_to_summon] is being held in place!</span>")
fail_invoke()
log_game("Summon Cultist rune failed - target restrained")
return
if(!iscultist(cultist_to_summon))
to_chat(user, "<span class='cult italic'>[cultist_to_summon] is not a follower of the Geometer!</span>")
fail_invoke()
+1 -1
View File
@@ -190,7 +190,7 @@
return ..()
/mob/living/simple_animal/hostile/morph/AttackingTarget()
if(!melee_damage_disguised)
if(morphed && !melee_damage_disguised)
to_chat(src, "<span class='warning'>You can not attack while disguised!</span>")
return
if(isliving(target)) //Eat Corpses to regen health
@@ -66,7 +66,7 @@
name = "pile of viscera"
desc = "A repulsive pile of guts and gore."
gender = NEUTER
random_icon_states = list("innards")
icon_state = "innards"
/mob/living/simple_animal/slaughter/phasein()
. = ..()
+4 -4
View File
@@ -493,10 +493,10 @@
D.pixel_z = target.pixel_z
if(do_mob(src, target, 100))
to_chat(src, "<span class='info'>Dismantling complete.</span>")
var/obj/item/stack/sheet/metal/M = new /obj/item/stack/sheet/metal(target.loc)
M.amount = 5
var/atom/Tsec = target.drop_location()
new /obj/item/stack/sheet/metal(Tsec, 5)
for(var/obj/item/I in target.component_parts)
I.forceMove(M.drop_location())
I.forceMove(Tsec)
var/obj/effect/temp_visual/swarmer/disintegration/N = new /obj/effect/temp_visual/swarmer/disintegration(get_turf(target))
N.pixel_x = target.pixel_x
N.pixel_y = target.pixel_y
@@ -505,7 +505,7 @@
if(istype(target, /obj/machinery/computer))
var/obj/machinery/computer/C = target
if(C.circuit)
C.circuit.forceMove(M.drop_location())
C.circuit.forceMove(Tsec)
qdel(target)
@@ -33,7 +33,6 @@
..()
if(!iscultist(user) && !iswizard(user) && !usability)
to_chat(user, "<span class='danger'>An overwhelming feeling of dread comes over you as you pick up the soulstone. It would be wise to be rid of this quickly.</span>")
user.Dizzy(120)
/obj/item/soulstone/examine(mob/user)
..()
+2 -1
View File
@@ -111,7 +111,7 @@ Code:
var/obj/item/assembly/signaler/signaler2 = W
if(secured && signaler2.secured)
code = signaler2.code
frequency = signaler2.frequency
set_frequency(signaler2.frequency)
to_chat(user, "You transfer the frequency and code of \the [signaler2.name] to \the [name]")
..()
@@ -186,6 +186,7 @@ Code:
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
var/anomaly_type = /obj/effect/anomaly
/obj/item/assembly/signaler/anomaly/receive_signal(datum/signal/signal)
if(!signal)
@@ -34,8 +34,10 @@ Iconnery
var/turf/T = loc
if(level == 2 || !T.intact)
showpipe = TRUE
plane = GAME_PLANE
else
showpipe = FALSE
plane = FLOOR_PLANE
if(!showpipe)
return //no need to update the pipes if they aren't showing
+1 -1
View File
@@ -101,7 +101,7 @@
export_types = list(/obj/machinery/iv_drip)
/datum/export/large/barrier
cost = 325
cost = 100
unit_name = "security barrier"
export_types = list(/obj/item/grenade/barrier, /obj/structure/barricade/security)
+3 -2
View File
@@ -1649,8 +1649,9 @@
. = ..()
if(prob(50))
var/mob/living/simple_animal/pet/dog/corgi/D = locate() in .
qdel(D)
new /mob/living/simple_animal/pet/dog/corgi/Lisa(.)
if(D.gender == FEMALE)
qdel(D)
new /mob/living/simple_animal/pet/dog/corgi/Lisa(.)
/datum/supply_pack/critter/cow
name = "Cow Crate"
+243 -62
View File
@@ -157,12 +157,14 @@ GLOBAL_LIST_EMPTY(asset_datums)
//get an assetdatum or make a new one
/proc/get_asset_datum(var/type)
if (!(type in GLOB.asset_datums))
return new type()
return GLOB.asset_datums[type]
return GLOB.asset_datums[type] || new type()
/datum/asset
var/_abstract = /datum/asset
/datum/asset/New()
GLOB.asset_datums[type] = src
register()
/datum/asset/proc/register()
return
@@ -170,20 +172,173 @@ GLOBAL_LIST_EMPTY(asset_datums)
/datum/asset/proc/send(client)
return
//If you don't need anything complicated.
/datum/asset/simple
_abstract = /datum/asset/simple
var/assets = list()
var/verify = FALSE
/datum/asset/simple/register()
for(var/asset_name in assets)
register_asset(asset_name, assets[asset_name])
/datum/asset/simple/send(client)
send_asset_list(client,assets,verify)
// For registering or sending multiple others at once
/datum/asset/group
_abstract = /datum/asset/group
var/list/children
/datum/asset/group/register()
for(var/type in children)
get_asset_datum(type)
/datum/asset/group/send(client/C)
for(var/type in children)
var/datum/asset/A = get_asset_datum(type)
A.send(C)
// spritesheet implementation - coalesces various icons into a single .png file
// and uses CSS to select icons out of that file - saves on transferring some
// 1400-odd individual PNG files
#define SPR_SIZE 1
#define SPR_IDX 2
#define SPRSZ_COUNT 1
#define SPRSZ_ICON 2
#define SPRSZ_STRIPPED 3
/datum/asset/spritesheet
_abstract = /datum/asset/spritesheet
var/name
var/list/sizes = list() // "32x32" -> list(10, icon/normal, icon/stripped)
var/list/sprites = list() // "foo_bar" -> list("32x32", 5)
var/verify = FALSE
/datum/asset/spritesheet/register()
if (!name)
CRASH("spritesheet [type] cannot register without a name")
ensure_stripped()
var/res_name = "spritesheet_[name].css"
var/fname = "data/spritesheets/[res_name]"
call("rust_g", "file_write")(generate_css(), fname)
register_asset(res_name, file(fname))
for(var/size_id in sizes)
var/size = sizes[size_id]
register_asset("[name]_[size_id].png", size[SPRSZ_STRIPPED])
/datum/asset/spritesheet/send(client/C)
if (!name)
return
var/all = list("spritesheet_[name].css")
for(var/size_id in sizes)
all += "[name]_[size_id].png"
send_asset_list(C, all, verify)
/datum/asset/spritesheet/proc/ensure_stripped(sizes_to_strip = sizes)
for(var/size_id in sizes_to_strip)
var/size = sizes[size_id]
if (size[SPRSZ_STRIPPED])
continue
// save flattened version
var/fname = "data/spritesheets/[name]_[size_id].png"
fcopy(size[SPRSZ_ICON], fname)
var/error = call("rust_g", "dmi_strip_metadata")(fname)
if(length(error))
stack_trace("Failed to strip [name]_[size_id].png: [error]")
size[SPRSZ_STRIPPED] = icon(fname)
/datum/asset/spritesheet/proc/generate_css()
var/list/out = list()
for (var/size_id in sizes)
var/size = sizes[size_id]
var/icon/tiny = size[SPRSZ_ICON]
out += ".[name][size_id]{display:inline-block;width:[tiny.Width()]px;height:[tiny.Height()]px;background:url('[name]_[size_id].png') no-repeat;}"
for (var/sprite_id in sprites)
var/sprite = sprites[sprite_id]
var/size_id = sprite[SPR_SIZE]
var/idx = sprite[SPR_IDX]
var/size = sizes[size_id]
var/icon/tiny = size[SPRSZ_ICON]
var/icon/big = size[SPRSZ_STRIPPED]
var/per_line = big.Width() / tiny.Width()
var/x = (idx % per_line) * tiny.Width()
var/y = round(idx / per_line) * tiny.Height()
out += ".[name][size_id].[sprite_id]{background-position:-[x]px -[y]px;}"
return out.Join("\n")
/datum/asset/spritesheet/proc/Insert(sprite_name, icon/I, icon_state="", dir=SOUTH, frame=1, moving=FALSE)
I = icon(I, icon_state=icon_state, dir=dir, frame=frame, moving=moving)
if (!I || !length(icon_states(I))) // that direction or state doesn't exist
return
var/size_id = "[I.Width()]x[I.Height()]"
var/size = sizes[size_id]
if (sprites[sprite_name])
CRASH("duplicate sprite \"[sprite_name]\" in sheet [name] ([type])")
if (size)
var/position = size[SPRSZ_COUNT]++
var/icon/sheet = size[SPRSZ_ICON]
size[SPRSZ_STRIPPED] = null
sheet.Insert(I, icon_state=sprite_name)
sprites[sprite_name] = list(size_id, position)
else
sizes[size_id] = size = list(1, I, null)
sprites[sprite_name] = list(size_id, 0)
/datum/asset/spritesheet/proc/InsertAll(prefix, icon/I, list/directions)
if (length(prefix))
prefix = "[prefix]-"
if (!directions)
directions = list(SOUTH)
for (var/icon_state_name in icon_states(I))
for (var/direction in directions)
var/prefix2 = (directions.len > 1) ? "[dir2text(direction)]-" : ""
Insert("[prefix][prefix2][icon_state_name]", I, icon_state=icon_state_name, dir=direction)
/datum/asset/spritesheet/proc/css_tag()
return {"<link rel="stylesheet" href="spritesheet_[name].css" />"}
/datum/asset/spritesheet/proc/icon_tag(sprite_name)
var/sprite = sprites[sprite_name]
if (!sprite)
return null
var/size_id = sprite[SPR_SIZE]
return {"<span class="[name][size_id] [sprite_name]"></span>"}
#undef SPR_SIZE
#undef SPR_IDX
#undef SPRSZ_COUNT
#undef SPRSZ_ICON
#undef SPRSZ_STRIPPED
/datum/asset/spritesheet/simple
_abstract = /datum/asset/spritesheet/simple
var/list/assets
/datum/asset/spritesheet/simple/register()
for (var/key in assets)
Insert(key, assets[key])
..()
//Generates assets based on iconstates of a single icon
/datum/asset/simple/icon_states
_abstract = /datum/asset/simple/icon_states
var/icon
var/list/directions = list(SOUTH)
var/frame = 1
@@ -209,6 +364,7 @@ GLOBAL_LIST_EMPTY(asset_datums)
register_asset(asset_name, asset)
/datum/asset/simple/icon_states/multiple_icons
_abstract = /datum/asset/simple/icon_states/multiple_icons
var/list/icons
/datum/asset/simple/icon_states/multiple_icons/register()
@@ -260,50 +416,52 @@ GLOBAL_LIST_EMPTY(asset_datums)
"smmon_6.gif" = 'icons/program_icons/smmon_6.gif'
)
/datum/asset/simple/pda
/datum/asset/spritesheet/simple/pda
name = "pda"
assets = list(
"pda_atmos.png" = 'icons/pda_icons/pda_atmos.png',
"pda_back.png" = 'icons/pda_icons/pda_back.png',
"pda_bell.png" = 'icons/pda_icons/pda_bell.png',
"pda_blank.png" = 'icons/pda_icons/pda_blank.png',
"pda_boom.png" = 'icons/pda_icons/pda_boom.png',
"pda_bucket.png" = 'icons/pda_icons/pda_bucket.png',
"pda_medbot.png" = 'icons/pda_icons/pda_medbot.png',
"pda_floorbot.png" = 'icons/pda_icons/pda_floorbot.png',
"pda_cleanbot.png" = 'icons/pda_icons/pda_cleanbot.png',
"pda_crate.png" = 'icons/pda_icons/pda_crate.png',
"pda_cuffs.png" = 'icons/pda_icons/pda_cuffs.png',
"pda_eject.png" = 'icons/pda_icons/pda_eject.png',
"pda_flashlight.png" = 'icons/pda_icons/pda_flashlight.png',
"pda_honk.png" = 'icons/pda_icons/pda_honk.png',
"pda_mail.png" = 'icons/pda_icons/pda_mail.png',
"pda_medical.png" = 'icons/pda_icons/pda_medical.png',
"pda_menu.png" = 'icons/pda_icons/pda_menu.png',
"pda_mule.png" = 'icons/pda_icons/pda_mule.png',
"pda_notes.png" = 'icons/pda_icons/pda_notes.png',
"pda_power.png" = 'icons/pda_icons/pda_power.png',
"pda_rdoor.png" = 'icons/pda_icons/pda_rdoor.png',
"pda_reagent.png" = 'icons/pda_icons/pda_reagent.png',
"pda_refresh.png" = 'icons/pda_icons/pda_refresh.png',
"pda_scanner.png" = 'icons/pda_icons/pda_scanner.png',
"pda_signaler.png" = 'icons/pda_icons/pda_signaler.png',
"pda_status.png" = 'icons/pda_icons/pda_status.png',
"pda_dronephone.png" = 'icons/pda_icons/pda_dronephone.png'
"atmos" = 'icons/pda_icons/pda_atmos.png',
"back" = 'icons/pda_icons/pda_back.png',
"bell" = 'icons/pda_icons/pda_bell.png',
"blank" = 'icons/pda_icons/pda_blank.png',
"boom" = 'icons/pda_icons/pda_boom.png',
"bucket" = 'icons/pda_icons/pda_bucket.png',
"medbot" = 'icons/pda_icons/pda_medbot.png',
"floorbot" = 'icons/pda_icons/pda_floorbot.png',
"cleanbot" = 'icons/pda_icons/pda_cleanbot.png',
"crate" = 'icons/pda_icons/pda_crate.png',
"cuffs" = 'icons/pda_icons/pda_cuffs.png',
"eject" = 'icons/pda_icons/pda_eject.png',
"flashlight" = 'icons/pda_icons/pda_flashlight.png',
"honk" = 'icons/pda_icons/pda_honk.png',
"mail" = 'icons/pda_icons/pda_mail.png',
"medical" = 'icons/pda_icons/pda_medical.png',
"menu" = 'icons/pda_icons/pda_menu.png',
"mule" = 'icons/pda_icons/pda_mule.png',
"notes" = 'icons/pda_icons/pda_notes.png',
"power" = 'icons/pda_icons/pda_power.png',
"rdoor" = 'icons/pda_icons/pda_rdoor.png',
"reagent" = 'icons/pda_icons/pda_reagent.png',
"refresh" = 'icons/pda_icons/pda_refresh.png',
"scanner" = 'icons/pda_icons/pda_scanner.png',
"signaler" = 'icons/pda_icons/pda_signaler.png',
"status" = 'icons/pda_icons/pda_status.png',
"dronephone" = 'icons/pda_icons/pda_dronephone.png'
)
/datum/asset/simple/paper
/datum/asset/spritesheet/simple/paper
name = "paper"
assets = list(
"large_stamp-clown.png" = 'icons/stamp_icons/large_stamp-clown.png',
"large_stamp-deny.png" = 'icons/stamp_icons/large_stamp-deny.png',
"large_stamp-ok.png" = 'icons/stamp_icons/large_stamp-ok.png',
"large_stamp-hop.png" = 'icons/stamp_icons/large_stamp-hop.png',
"large_stamp-cmo.png" = 'icons/stamp_icons/large_stamp-cmo.png',
"large_stamp-ce.png" = 'icons/stamp_icons/large_stamp-ce.png',
"large_stamp-hos.png" = 'icons/stamp_icons/large_stamp-hos.png',
"large_stamp-rd.png" = 'icons/stamp_icons/large_stamp-rd.png',
"large_stamp-cap.png" = 'icons/stamp_icons/large_stamp-cap.png',
"large_stamp-qm.png" = 'icons/stamp_icons/large_stamp-qm.png',
"large_stamp-law.png" = 'icons/stamp_icons/large_stamp-law.png'
"stamp-clown" = 'icons/stamp_icons/large_stamp-clown.png',
"stamp-deny" = 'icons/stamp_icons/large_stamp-deny.png',
"stamp-ok" = 'icons/stamp_icons/large_stamp-ok.png',
"stamp-hop" = 'icons/stamp_icons/large_stamp-hop.png',
"stamp-cmo" = 'icons/stamp_icons/large_stamp-cmo.png',
"stamp-ce" = 'icons/stamp_icons/large_stamp-ce.png',
"stamp-hos" = 'icons/stamp_icons/large_stamp-hos.png',
"stamp-rd" = 'icons/stamp_icons/large_stamp-rd.png',
"stamp-cap" = 'icons/stamp_icons/large_stamp-cap.png',
"stamp-qm" = 'icons/stamp_icons/large_stamp-qm.png',
"stamp-law" = 'icons/stamp_icons/large_stamp-law.png'
)
/datum/asset/simple/IRV
@@ -335,10 +493,22 @@ GLOBAL_LIST_EMPTY(asset_datums)
"changelog.css" = 'html/changelog.css'
)
/datum/asset/simple/goonchat
/datum/asset/group/goonchat
children = list(
/datum/asset/simple/jquery,
/datum/asset/simple/goonchat,
/datum/asset/spritesheet/goonchat
)
/datum/asset/simple/jquery
verify = FALSE
assets = list(
"jquery.min.js" = 'code/modules/goonchat/browserassets/js/jquery.min.js',
)
/datum/asset/simple/goonchat
verify = FALSE
assets = list(
"json2.min.js" = 'code/modules/goonchat/browserassets/js/json2.min.js',
"errorHandler.js" = 'code/modules/goonchat/browserassets/js/errorHandler.js',
"browserOutput.js" = 'code/modules/goonchat/browserassets/js/browserOutput.js',
@@ -350,6 +520,24 @@ GLOBAL_LIST_EMPTY(asset_datums)
"browserOutput.css" = 'code/modules/goonchat/browserassets/css/browserOutput.css',
)
/datum/asset/spritesheet/goonchat
name = "chat"
/datum/asset/spritesheet/goonchat/register()
InsertAll("emoji", 'icons/emoji.dmi')
// pre-loading all lanugage icons also helps to avoid meta
InsertAll("language", 'icons/misc/language.dmi')
// catch languages which are pulling icons from another file
for(var/path in typesof(/datum/language))
var/datum/language/L = path
var/icon = initial(L.icon)
if (icon != 'icons/misc/language.dmi')
var/icon_state = initial(L.icon_state)
Insert("language-[icon_state]", icon, icon_state=icon_state)
..()
/datum/asset/simple/permissions
assets = list(
"padlock.png" = 'html/padlock.png'
@@ -362,26 +550,19 @@ GLOBAL_LIST_EMPTY(asset_datums)
var/datum/language/L = new path ()
L.get_icon()
/datum/asset/simple/icon_states/emojis
icon = 'icons/emoji.dmi'
generic_icon_names = TRUE
/datum/asset/spritesheet/pipes
name = "pipes"
/datum/asset/simple/icon_states/multiple_icons/pipes
icons = list('icons/obj/atmospherics/pipes/pipe_item.dmi', 'icons/obj/atmospherics/pipes/disposal.dmi', 'icons/obj/atmospherics/pipes/transit_tube.dmi')
prefix = "pipe"
/datum/asset/simple/icon_states/multiple_icons/pipes/New()
directions = GLOB.alldirs
/datum/asset/spritesheet/pipes/register()
for (var/each in list('icons/obj/atmospherics/pipes/pipe_item.dmi', 'icons/obj/atmospherics/pipes/disposal.dmi', 'icons/obj/atmospherics/pipes/transit_tube.dmi'))
InsertAll("", each, GLOB.alldirs)
..()
/datum/asset/simple/icon_states/multiple_icons/pipes/register()
..()
var/meter = icon('icons/obj/atmospherics/pipes/simple.dmi', "meterX", SOUTH, frame, movement_states)
if(meter)
register_asset(sanitize_filename("[prefix].south.meterX.png"), fcopy_rsc(meter))
// Representative icons for each research design
/datum/asset/simple/research_designs/register()
/datum/asset/spritesheet/research_designs
name = "design"
/datum/asset/spritesheet/research_designs/register()
for (var/path in subtypesof(/datum/design))
var/datum/design/D = path
@@ -401,7 +582,6 @@ GLOBAL_LIST_EMPTY(asset_datums)
if (machine)
item = machine
var/icon_file = initial(item.icon)
var/all_states = icon_states(icon_file)
var/icon/I = icon(icon_file, initial(item.icon_state), SOUTH)
// computers (and snowflakes) get their screen and keyboard sprites
@@ -409,10 +589,11 @@ GLOBAL_LIST_EMPTY(asset_datums)
var/obj/machinery/computer/C = item
var/screen = initial(C.icon_screen)
var/keyboard = initial(C.icon_keyboard)
var/all_states = icon_states(icon_file)
if (screen && (screen in all_states))
I.Blend(icon(icon_file, screen, SOUTH), ICON_OVERLAY)
if (keyboard && (keyboard in all_states))
I.Blend(icon(icon_file, keyboard, SOUTH), ICON_OVERLAY)
assets["design_[initial(D.id)].png"] = I
Insert(initial(D.id), I)
return ..()
+4 -4
View File
@@ -92,7 +92,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
if (citadel_client_procs(href_list))
return
// CITADEL End
switch(href_list["_src_"])
if("holder")
hsrc = holder
@@ -403,9 +403,9 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
var/datum/verbs/menu/menuitem = GLOB.menulist[thing]
if (menuitem)
menuitem.Load_checked(src)
hook_vr("client_new",list(src)) // CIT CHANGE - hook for client/New() changes
Master.UpdateTickRate()
//////////////
@@ -484,7 +484,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
if (CONFIG_GET(flag/panic_bunker) && !holder && !GLOB.deadmins[ckey])
log_access("Failed Login: [key] - New account attempting to connect during panic bunker")
message_admins("<span class='adminnotice'>Failed Login: [key] - New account attempting to connect during panic bunker</span>")
to_chat(src, "Sorry but the server is currently not accepting connections from never before seen players.")
to_chat(src, "You must first join the Discord to verify your account before joining this server. Please ping an admin once you've joined and read the rules. https://discord.gg/E6SQuhz") //CIT CHANGE - makes the panic bunker disconnect message point to the discord
var/list/connectiontopic_a = params2list(connectiontopic)
var/list/panic_addr = CONFIG_GET(string/panic_server_address)
if(panic_addr && !connectiontopic_a["redirect"])
+91 -85
View File
@@ -83,12 +83,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
//Mob preview
var/icon/preview_icon = null
//Trait list
var/list/positive_traits = list()
var/list/negative_traits = list()
var/list/neutral_traits = list()
var/list/all_traits = list()
var/list/character_traits = list()
//Quirk list
var/list/positive_quirks = list()
var/list/negative_quirks = list()
var/list/neutral_quirks = list()
var/list/all_quirks = list()
var/list/character_quirks = list()
//Jobs, uses bitflags
var/job_civilian_high = 0
@@ -120,6 +120,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/parallax
var/ambientocclusion = TRUE
var/uplink_spawn_loc = UPLINK_PDA
var/list/exp = list()
@@ -193,9 +195,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
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))
dat += "<center><h2>Trait Setup</h2>"
dat += "<a href='?_src_=prefs;preference=trait;task=menu'>Configure Traits</a><br></center>"
dat += "<center><b>Current traits:</b> [all_traits.len ? all_traits.Join(", ") : "None"]</center>"
dat += "<center><h2>Quirk Setup</h2>"
dat += "<a href='?_src_=prefs;preference=trait;task=menu'>Configure Quirks</a><br></center>"
dat += "<center><b>Current quirks:</b> [all_quirks.len ? all_quirks.Join(", ") : "None"]</center>"
dat += "<h2>Identity</h2>"
dat += "<table width='100%'><tr><td width='75%' valign='top'>"
if(jobban_isbanned(user, "appearance"))
@@ -490,6 +492,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "High"
dat += "</a><br>"
dat += "<b>Ambient Occlusion:</b> <a href='?_src_=prefs;preference=ambientocclusion'>[ambientocclusion ? "Enabled" : "Disabled"]</a><br>"
dat += "</td><td width='300px' height='300px' valign='top'>"
dat += "<h2>Special Role Settings</h2>"
@@ -855,72 +859,72 @@ GLOBAL_LIST_EMPTY(preferences_datums)
return job_engsec_low
return 0
/datum/preferences/proc/SetTraits(mob/user)
if(!SStraits)
to_chat(user, "<span class='danger'>The trait subsystem is still initializing! Try again in a minute.</span>")
/datum/preferences/proc/SetQuirks(mob/user)
if(!SSquirks)
to_chat(user, "<span class='danger'>The quirk subsystem is still initializing! Try again in a minute.</span>")
return
var/list/dat = list()
if(!SStraits.traits.len)
dat += "The trait subsystem hasn't finished initializing, please hold..."
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>"
else
dat += "<center><b>Choose trait setup</b></center><br>"
dat += "<div align='center'>Left-click to add or remove traits. You need one negative trait for every positive trait.<br>\
Traits are applied at roundstart and cannot normally be removed.</div>"
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 += "<hr>"
dat += "<center><b>Current traits:</b> [all_traits.len ? all_traits.Join(", ") : "None"]</center>"
dat += "<center>[all_traits.len] / [MAX_TRAITS] max traits<br>\
<b>Trait balance remaining:</b> [GetTraitBalance()]</center><br>"
for(var/V in SStraits.traits)
var/datum/trait/T = SStraits.traits[V]
var/trait_name = initial(T.name)
var/has_trait
var/trait_cost = initial(T.value) * -1
dat += "<center><b>Current quirks:</b> [all_quirks.len ? all_quirks.Join(", ") : "None"]</center>"
dat += "<center>[positive_quirks.len] / [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/trait_conflict = FALSE
for(var/_V in all_traits)
if(_V == trait_name)
has_trait = TRUE
if(initial(T.mood_trait) && CONFIG_GET(flag/disable_human_mood))
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."
trait_conflict = TRUE
if(has_trait)
if(trait_conflict)
all_traits -= trait_name
has_trait = FALSE
quirk_conflict = TRUE
if(has_quirk)
if(quirk_conflict)
all_quirks -= quirk_name
has_quirk = FALSE
else
trait_cost *= -1 //invert it back, since we'd be regaining this amount
if(trait_cost > 0)
trait_cost = "+[trait_cost]"
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(trait_conflict)
dat += "<font color='[font_color]'>[trait_name]</font> - [initial(T.desc)] \
if(quirk_conflict)
dat += "<font color='[font_color]'>[quirk_name]</font> - [initial(T.desc)] \
<font color='red'><b>LOCKED: [lock_reason]</b></font><br>"
else
if(has_trait)
dat += "<b><font color='[font_color]'>[trait_name]</font></b> - [initial(T.desc)] \
<a href='?_src_=prefs;preference=trait;task=update;trait=[trait_name]'>[has_trait ? "Lose" : "Take"] ([trait_cost] pts.)</a><br>"
if(has_quirk)
dat += "<b><font color='[font_color]'>[quirk_name]</font></b> - [initial(T.desc)] \
<a href='?_src_=prefs;preference=trait;task=update;trait=[quirk_name]'>[has_quirk ? "Lose" : "Take"] ([quirk_cost] pts.)</a><br>"
else
dat += "<font color='[font_color]'>[trait_name]</font> - [initial(T.desc)] \
<a href='?_src_=prefs;preference=trait;task=update;trait=[trait_name]'>[has_trait ? "Lose" : "Take"] ([trait_cost] pts.)</a><br>"
dat += "<font color='[font_color]'>[quirk_name]</font> - [initial(T.desc)] \
<a href='?_src_=prefs;preference=trait;task=update;trait=[quirk_name]'>[has_quirk ? "Lose" : "Take"] ([quirk_cost] pts.)</a><br>"
dat += "<br><center><a href='?_src_=prefs;preference=trait;task=reset'>Reset Traits</a></center>"
user << browse(null, "window=preferences")
var/datum/browser/popup = new(user, "mob_occupation", "<div align='center'>Trait Preferences</div>", 900, 600) //no reason not to reuse the occupation window, as it's cleaner that way
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.open(0)
return
/datum/preferences/proc/GetTraitBalance()
/datum/preferences/proc/GetQuirkBalance()
var/bal = 0
for(var/V in all_traits)
var/datum/trait/T = SStraits.traits[V]
for(var/V in all_quirks)
var/datum/quirk/T = SSquirks.quirks[V]
bal -= initial(T.value)
return bal
@@ -977,55 +981,49 @@ GLOBAL_LIST_EMPTY(preferences_datums)
user << browse(null, "window=mob_occupation")
ShowChoices(user)
if("update")
var/trait = href_list["trait"]
if(!SStraits.traits[trait])
var/quirk = href_list["trait"]
if(!SSquirks.quirks[quirk])
return
var/value = SStraits.trait_points[trait]
var/value = SSquirks.quirk_points[quirk]
if(value == 0)
if(trait in neutral_traits)
neutral_traits -= trait
all_traits -= trait
if(quirk in neutral_quirks)
neutral_quirks -= quirk
all_quirks -= quirk
else
if(all_traits.len >= MAX_TRAITS)
to_chat(user, "<span class='warning'>You can't have more than [MAX_TRAITS] traits!</span>")
return
neutral_traits += trait
all_traits += trait
neutral_quirks += quirk
all_quirks += quirk
else
var/balance = GetTraitBalance()
if(trait in positive_traits)
positive_traits -= trait
all_traits -= trait
else if(trait in negative_traits)
var/balance = GetQuirkBalance()
if(quirk in positive_quirks)
positive_quirks -= quirk
all_quirks -= quirk
else if(quirk in negative_quirks)
if(balance + value < 0)
to_chat(user, "<span class='warning'>Refunding this would cause you to go below your balance!</span>")
return
negative_traits -= trait
all_traits -= trait
negative_quirks -= quirk
all_quirks -= quirk
else if(value > 0)
if(all_traits.len >= MAX_TRAITS)
to_chat(user, "<span class='warning'>You can't have more than [MAX_TRAITS] traits!</span>")
if(positive_quirks.len >= MAX_QUIRKS)
to_chat(user, "<span class='warning'>You can't have more than [MAX_QUIRKS] positive quirks!</span>")
return
if(balance - value < 0)
to_chat(user, "<span class='warning'>You don't have enough balance to gain this trait!</span>")
to_chat(user, "<span class='warning'>You don't have enough balance to gain this quirk!</span>")
return
positive_traits += trait
all_traits += trait
positive_quirks += quirk
all_quirks += quirk
else
if(all_traits.len >= MAX_TRAITS)
to_chat(user, "<span class='warning'>You can't have more than [MAX_TRAITS] traits!</span>")
return
negative_traits += trait
all_traits += trait
SetTraits(user)
negative_quirks += quirk
all_quirks += quirk
SetQuirks(user)
if("reset")
all_traits = list()
positive_traits = list()
negative_traits = list()
neutral_traits = list()
SetTraits(user)
all_quirks = list()
positive_quirks = list()
negative_quirks = list()
neutral_quirks = list()
SetQuirks(user)
else
SetTraits(user)
SetQuirks(user)
return TRUE
switch(href_list["task"])
@@ -1535,6 +1533,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
cit_toggles ^= DIGESTION_NOISES
//END CITADEL EDIT
if("ambientocclusion")
ambientocclusion = !ambientocclusion
if(parent && parent.screen && parent.screen.len)
var/obj/screen/plane_master/game_world/PM = locate(/obj/screen/plane_master/game_world) in parent.screen
PM.filters -= AMBIENT_OCCLUSION
if(ambientocclusion)
PM.filters += AMBIENT_OCCLUSION
if("save")
save_preferences()
save_character()
@@ -1642,4 +1648,4 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(icon_updates)
character.update_body()
character.update_hair()
character.update_body_parts()
character.update_body_parts()
+17 -14
View File
@@ -130,6 +130,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["uses_glasses_colour"]>> uses_glasses_colour
S["clientfps"] >> clientfps
S["parallax"] >> parallax
S["ambientocclusion"] >> ambientocclusion
S["menuoptions"] >> menuoptions
S["enable_tips"] >> enable_tips
S["tip_delay"] >> tip_delay
@@ -160,6 +161,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
toggles = sanitize_integer(toggles, 0, 65535, initial(toggles))
clientfps = sanitize_integer(clientfps, 0, 1000, 0)
parallax = sanitize_integer(parallax, PARALLAX_INSANE, PARALLAX_DISABLE, null)
ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion))
ghost_form = sanitize_inlist(ghost_form, GLOB.ghost_forms, initial(ghost_form))
ghost_orbit = sanitize_inlist(ghost_orbit, GLOB.ghost_orbits, initial(ghost_orbit))
ghost_accs = sanitize_inlist(ghost_accs, GLOB.ghost_accs_options, GHOST_ACCS_DEFAULT_OPTION)
@@ -210,6 +212,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["uses_glasses_colour"], uses_glasses_colour)
WRITE_FILE(S["clientfps"], clientfps)
WRITE_FILE(S["parallax"], parallax)
WRITE_FILE(S["ambientocclusion"], ambientocclusion)
WRITE_FILE(S["menuoptions"], menuoptions)
WRITE_FILE(S["enable_tips"], enable_tips)
WRITE_FILE(S["tip_delay"], tip_delay)
@@ -310,11 +313,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["job_engsec_med"] >> job_engsec_med
S["job_engsec_low"] >> job_engsec_low
//Traits
S["all_traits"] >> all_traits
S["positive_traits"] >> positive_traits
S["negative_traits"] >> negative_traits
S["neutral_traits"] >> neutral_traits
//Quirks
S["all_quirks"] >> all_quirks
S["positive_quirks"] >> positive_quirks
S["negative_quirks"] >> negative_quirks
S["neutral_quirks"] >> neutral_quirks
//Citadel code
S["feature_genitals_use_skintone"] >> features["genitals_use_skintone"]
@@ -421,10 +424,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
job_engsec_med = sanitize_integer(job_engsec_med, 0, 65535, initial(job_engsec_med))
job_engsec_low = sanitize_integer(job_engsec_low, 0, 65535, initial(job_engsec_low))
all_traits = SANITIZE_LIST(all_traits)
positive_traits = SANITIZE_LIST(positive_traits)
negative_traits = SANITIZE_LIST(negative_traits)
neutral_traits = SANITIZE_LIST(neutral_traits)
all_quirks = SANITIZE_LIST(all_quirks)
positive_quirks = SANITIZE_LIST(positive_quirks)
negative_quirks = SANITIZE_LIST(negative_quirks)
neutral_quirks = SANITIZE_LIST(neutral_quirks)
cit_character_pref_load(S)
@@ -491,11 +494,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["job_engsec_med"] , job_engsec_med)
WRITE_FILE(S["job_engsec_low"] , job_engsec_low)
//Traits
WRITE_FILE(S["all_traits"] , all_traits)
WRITE_FILE(S["positive_traits"] , positive_traits)
WRITE_FILE(S["negative_traits"] , negative_traits)
WRITE_FILE(S["neutral_traits"] , neutral_traits)
//Quirks
WRITE_FILE(S["all_quirks"] , all_quirks)
WRITE_FILE(S["positive_quirks"] , positive_quirks)
WRITE_FILE(S["negative_quirks"] , negative_quirks)
WRITE_FILE(S["neutral_quirks"] , neutral_quirks)
cit_character_pref_save(S)
+8 -6
View File
@@ -81,12 +81,14 @@
/obj/item/clothing/equipped(mob/user, slot)
..()
if (!istype(user))
return
if(slot_flags & slotdefine2slotbit(slot)) //Was equipped to a valid slot for this item?
for(var/variable in user_vars_to_edit)
if(variable in user.vars)
user_vars_remembered[variable] = user.vars[variable]
user.vars[variable] = user_vars_to_edit[variable]
if (LAZYLEN(user_vars_to_edit))
for(var/variable in user_vars_to_edit)
if(variable in user.vars)
LAZYSET(user_vars_remembered, variable, user.vars[variable])
user.vv_edit_var(variable, user_vars_to_edit[variable])
/obj/item/clothing/examine(mob/user)
..()
@@ -285,4 +287,4 @@ BLIND // can't see anything
Shreds.desc = "The sad remains of what used to be [name]."
deconstruct(FALSE)
else
..()
..()
@@ -365,6 +365,7 @@
scan_reagents = 1
flags_1 = NODROP_1
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
resistance_flags = LAVA_PROOF | FIRE_PROOF
/obj/item/clothing/glasses/godeye/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, src) && W != src && W.loc == user)
@@ -93,7 +93,7 @@
MA.alpha = 180
MA.maptext = "[strength]k"
MA.color = "#64C864"
MA.layer = AREA_LAYER
MA.layer = FLY_LAYER
pic.appearance = MA
flick_overlay(pic, list(user.client), 8)
+8
View File
@@ -158,12 +158,20 @@
strip_delay = 100
dog_fashion = null
/obj/item/clothing/head/helmet/roman/fake
desc = "An ancient helmet made of plastic and leather."
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
/obj/item/clothing/head/helmet/roman/legionaire
name = "roman legionaire helmet"
desc = "An ancient helmet made of bronze and leather. Has a red crest on top of it."
icon_state = "roman_c"
item_state = "roman_c"
/obj/item/clothing/head/helmet/roman/legionaire/fake
desc = "An ancient helmet made of plastic and leather. Has a red crest on top of it."
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
/obj/item/clothing/head/helmet/gladiator
name = "gladiator helmet"
desc = "Ave, Imperator, morituri te salutant."
+24 -1
View File
@@ -321,4 +321,27 @@
name = "headress of Nemes"
desc = "Lavish space tomb not included."
icon_state = "nemes_headdress"
icon_state = "nemes_headdress"
icon_state = "nemes_headdress"
/obj/item/clothing/head/frenchberet
name = "french beret"
desc = "A quality beret, infused with the aroma of chain-smoking, wine-swilling Parisians. You feel less inclined to engage military conflict, for some reason."
icon_state = "beretblack"
/obj/item/clothing/head/frenchberet/speechModification(M)
if(copytext(M, 1, 2) != "*")
M = " [M]"
var/list/french_words = strings("french_replacement.json", "french")
for(var/key in french_words)
var/value = french_words[key]
if(islist(value))
value = pick(value)
M = replacetextEx(M, " [uppertext(key)]", " [uppertext(value)]")
M = replacetextEx(M, " [capitalize(key)]", " [capitalize(value)]")
M = replacetextEx(M, " [key]", " [value]")
if(prob(3))
M += pick(" Honh honh honh!"," Honh!"," Zut Alors!")
return trim(M)
+1 -1
View File
@@ -47,7 +47,7 @@
/obj/item/clothing/mask/fakemoustache/italian/speechModification(M)
if(copytext(M, 1, 2) != "*")
M = " [M]"
var/list/italian_words = strings("word_replacement.json", "italian")
var/list/italian_words = strings("italian_replacement.json", "italian")
for(var/key in italian_words)
var/value = italian_words[key]
+10 -1
View File
@@ -126,7 +126,7 @@
if(user.transferItemToLoc(I, src))
jetpack = I
to_chat(user, "<span class='notice'>You successfully install the jetpack into [src].</span>")
return
else if(istype(I, /obj/item/screwdriver))
if(!jetpack)
to_chat(user, "<span class='warning'>[src] has no jetpack installed.</span>")
@@ -139,6 +139,8 @@
jetpack.forceMove(drop_location())
jetpack = null
to_chat(user, "<span class='notice'>You successfully remove the jetpack from [src].</span>")
return
return ..()
/obj/item/clothing/suit/space/hardsuit/equipped(mob/user, slot)
@@ -237,6 +239,9 @@
brightness_on = 7
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator)
/obj/item/clothing/head/helmet/space/hardsuit/mining/Initialize()
. = ..()
AddComponent(/datum/component/armor_plate)
/obj/item/clothing/suit/space/hardsuit/mining
icon_state = "hardsuit-mining"
@@ -250,6 +255,10 @@
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/mining
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
/obj/item/clothing/suit/space/hardsuit/mining/Initialize()
. = ..()
AddComponent(/datum/component/armor_plate)
//Syndicate hardsuit
/obj/item/clothing/head/helmet/space/hardsuit/syndi
name = "blood-red hardsuit helmet"
-180
View File
@@ -165,186 +165,6 @@
. = ..()
allowed = GLOB.detective_vest_allowed
//Reactive armor
/obj/item/clothing/suit/armor/reactive
name = "reactive armor"
desc = "Doesn't seem to do much for some reason."
var/active = 0
var/reactivearmor_cooldown_duration = 0 //cooldown specific to reactive armor
var/reactivearmor_cooldown = 0
icon_state = "reactiveoff"
item_state = "reactiveoff"
blood_overlay_type = "armor"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
actions_types = list(/datum/action/item_action/toggle)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
hit_reaction_chance = 50
/obj/item/clothing/suit/armor/reactive/attack_self(mob/user)
src.active = !( src.active )
if (src.active)
to_chat(user, "<span class='notice'>[src] is now active.</span>")
src.icon_state = "reactive"
src.item_state = "reactive"
else
to_chat(user, "<span class='notice'>[src] is now inactive.</span>")
src.icon_state = "reactiveoff"
src.item_state = "reactiveoff"
src.add_fingerprint(user)
return
/obj/item/clothing/suit/armor/reactive/emp_act(severity)
active = 0
src.icon_state = "reactiveoff"
src.item_state = "reactiveoff"
reactivearmor_cooldown = world.time + 200
..()
//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!)
/obj/item/clothing/suit/armor/reactive/teleport
name = "reactive teleport armor"
desc = "Someone separated our Research Director from his own head!"
var/tele_range = 6
var/rad_amount= 15
reactivearmor_cooldown_duration = 100
/obj/item/clothing/suit/armor/reactive/teleport/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
var/mob/living/carbon/human/H = owner
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive teleport system is still recharging! It fails to teleport [H]!</span>")
return
owner.visible_message("<span class='danger'>The reactive teleport system flings [H] clear of [attack_text], shutting itself off in the process!</span>")
var/list/turfs = new/list()
for(var/turf/T in orange(tele_range, H))
if(T.density)
continue
if(T.x>world.maxx-tele_range || T.x<tele_range)
continue
if(T.y>world.maxy-tele_range || T.y<tele_range)
continue
turfs += T
if(!turfs.len)
turfs += pick(/turf in orange(tele_range, H))
var/turf/picked = pick(turfs)
if(!isturf(picked))
return
H.forceMove(picked)
H.rad_act(rad_amount)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return 0
/obj/item/clothing/suit/armor/reactive/fire
name = "reactive incendiary armor"
desc = "An experimental suit of armor with a reactive sensor array rigged to a flame emitter. For the stylish pyromaniac."
/obj/item/clothing/suit/armor/reactive/fire/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive incendiary armor on [owner] activates, but fails to send out flames as it is still recharging its flame jets!</span>")
return
owner.visible_message("<span class='danger'>[src] blocks [attack_text], sending out jets of flame!</span>")
for(var/mob/living/carbon/C in range(6, owner))
if(C != owner)
C.fire_stacks += 8
C.IgniteMob()
owner.fire_stacks = -20
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return 0
/obj/item/clothing/suit/armor/reactive/stealth
name = "reactive stealth armor"
desc = "An experimental suit of armor that renders the wearer invisible on detection of imminent harm, and creates a decoy that runs away from the owner. You can't fight what you can't see."
/obj/item/clothing/suit/armor/reactive/stealth/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive stealth system on [owner] activates, but is still recharging its holographic emitters!</span>")
return
var/mob/living/simple_animal/hostile/illusion/escape/E = new(owner.loc)
E.Copy_Parent(owner, 50)
E.GiveTarget(owner) //so it starts running right away
E.Goto(owner, E.move_to_delay, E.minimum_distance)
owner.alpha = 0
owner.visible_message("<span class='danger'>[owner] is hit by [attack_text] in the chest!</span>") //We pretend to be hit, since blocking it would stop the message otherwise
spawn(40)
owner.alpha = initial(owner.alpha)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
/obj/item/clothing/suit/armor/reactive/tesla
name = "reactive tesla armor"
desc = "An experimental suit of armor with sensitive detectors hooked up to a huge capacitor grid, with emitters strutting out of it. Zap."
siemens_coefficient = -1
var/tesla_power = 25000
var/tesla_range = 20
var/tesla_boom = FALSE
var/tesla_stun = FALSE
/obj/item/clothing/suit/armor/reactive/tesla/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread
sparks.set_up(1, 1, src)
sparks.start()
owner.visible_message("<span class='danger'>The tesla capacitors on [owner]'s reactive tesla armor are still recharging! The armor merely emits some sparks.</span>")
return
owner.visible_message("<span class='danger'>[src] blocks [attack_text], sending out arcs of lightning!</span>")
tesla_zap(owner,tesla_range,tesla_power,tesla_boom, tesla_stun)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
/obj/item/clothing/suit/armor/reactive/table
name = "reactive table armor"
desc = "If you can't beat the memes, embrace them."
var/tele_range = 10
/obj/item/clothing/suit/armor/reactive/table/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
var/mob/living/carbon/human/H = owner
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive table armor's fabricators are still on cooldown!</span>")
return
owner.visible_message("<span class='danger'>The reactive teleport system flings [H] clear of [attack_text] and slams them into a fabricated table!</span>")
owner.visible_message("<font color='red' size='3'>[H] GOES ON THE TABLE!!!</font>")
owner.Knockdown(40)
var/list/turfs = new/list()
for(var/turf/T in orange(tele_range, H))
if(T.density)
continue
if(T.x>world.maxx-tele_range || T.x<tele_range)
continue
if(T.y>world.maxy-tele_range || T.y<tele_range)
continue
turfs += T
if(!turfs.len)
turfs += pick(/turf in orange(tele_range, H))
var/turf/picked = pick(turfs)
if(!isturf(picked))
return
H.forceMove(picked)
new /obj/structure/table(get_turf(owner))
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return 0
/obj/item/clothing/suit/armor/reactive/table/emp_act()
return
//All of the armor below is mostly unused
/obj/item/clothing/suit/armor/centcom
@@ -0,0 +1,235 @@
/obj/item/reactive_armour_shell
name = "reactive armour shell"
desc = "An experimental suit of armour, awaiting installation of an anomaly core."
icon_state = "reactiveoff"
icon = 'icons/obj/clothing/suits.dmi'
w_class = WEIGHT_CLASS_BULKY
/obj/item/reactive_armour_shell/attackby(obj/item/I, mob/user, params)
..()
var/static/list/anomaly_armour_types = list(
/obj/effect/anomaly/grav = /obj/item/clothing/suit/armor/reactive/repulse,
/obj/effect/anomaly/flux = /obj/item/clothing/suit/armor/reactive/tesla,
/obj/effect/anomaly/bluespace = /obj/item/clothing/suit/armor/reactive/teleport,
/obj/effect/anomaly/pyro = /obj/item/clothing/suit/armor/reactive/fire)
if(istype(I, /obj/item/assembly/signaler/anomaly))
var/obj/item/assembly/signaler/anomaly/A = I
var/armour_path = anomaly_armour_types[A.anomaly_type]
if(!armour_path)
armour_path = /obj/item/clothing/suit/armor/reactive/stealth //Lets not cheat the player if an anomaly type doesnt have its own armour coded
to_chat(user, "You insert [A] into the chest plate, and the armour gently hums to life.")
new armour_path(get_turf(src))
qdel(src)
qdel(A)
//Reactive armor
/obj/item/clothing/suit/armor/reactive
name = "reactive armor"
desc = "Doesn't seem to do much for some reason."
var/active = 0
var/reactivearmor_cooldown_duration = 0 //cooldown specific to reactive armor
var/reactivearmor_cooldown = 0
icon_state = "reactiveoff"
item_state = "reactiveoff"
blood_overlay_type = "armor"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
actions_types = list(/datum/action/item_action/toggle)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
hit_reaction_chance = 50
/obj/item/clothing/suit/armor/reactive/attack_self(mob/user)
active = !(active)
if(active)
to_chat(user, "<span class='notice'>[src] is now active.</span>")
icon_state = "reactive"
item_state = "reactive"
else
to_chat(user, "<span class='notice'>[src] is now inactive.</span>")
icon_state = "reactiveoff"
item_state = "reactiveoff"
add_fingerprint(user)
return
/obj/item/clothing/suit/armor/reactive/emp_act(severity)
active = 0
icon_state = "reactiveoff"
item_state = "reactiveoff"
reactivearmor_cooldown = world.time + 200
..()
//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!)
/obj/item/clothing/suit/armor/reactive/teleport
name = "reactive teleport armor"
desc = "Someone separated our Research Director from his own head!"
var/tele_range = 6
var/rad_amount= 15
reactivearmor_cooldown_duration = 100
/obj/item/clothing/suit/armor/reactive/teleport/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
var/mob/living/carbon/human/H = owner
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive teleport system is still recharging! It fails to teleport [H]!</span>")
return
owner.visible_message("<span class='danger'>The reactive teleport system flings [H] clear of [attack_text], shutting itself off in the process!</span>")
var/list/turfs = new/list()
for(var/turf/T in orange(tele_range, H))
if(T.density)
continue
if(T.x>world.maxx-tele_range || T.x<tele_range)
continue
if(T.y>world.maxy-tele_range || T.y<tele_range)
continue
turfs += T
if(!turfs.len)
turfs += pick(/turf in orange(tele_range, H))
var/turf/picked = pick(turfs)
if(!isturf(picked))
return
H.forceMove(picked)
H.rad_act(rad_amount)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return 0
//Fire
/obj/item/clothing/suit/armor/reactive/fire
name = "reactive incendiary armor"
desc = "An experimental suit of armor with a reactive sensor array rigged to a flame emitter. For the stylish pyromaniac."
/obj/item/clothing/suit/armor/reactive/fire/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive incendiary armor on [owner] activates, but fails to send out flames as it is still recharging its flame jets!</span>")
return
owner.visible_message("<span class='danger'>[src] blocks [attack_text], sending out jets of flame!</span>")
for(var/mob/living/carbon/C in range(6, owner))
if(C != owner)
C.fire_stacks += 8
C.IgniteMob()
owner.fire_stacks = -20
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return 0
//Stealth
/obj/item/clothing/suit/armor/reactive/stealth
name = "reactive stealth armor"
desc = "An experimental suit of armor that renders the wearer invisible on detection of imminent harm, and creates a decoy that runs away from the owner. You can't fight what you can't see."
/obj/item/clothing/suit/armor/reactive/stealth/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive stealth system on [owner] activates, but is still recharging its holographic emitters!</span>")
return
var/mob/living/simple_animal/hostile/illusion/escape/E = new(owner.loc)
E.Copy_Parent(owner, 50)
E.GiveTarget(owner) //so it starts running right away
E.Goto(owner, E.move_to_delay, E.minimum_distance)
owner.alpha = 0
owner.visible_message("<span class='danger'>[owner] is hit by [attack_text] in the chest!</span>") //We pretend to be hit, since blocking it would stop the message otherwise
spawn(40)
owner.alpha = initial(owner.alpha)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
//Tesla
/obj/item/clothing/suit/armor/reactive/tesla
name = "reactive tesla armor"
desc = "An experimental suit of armor with sensitive detectors hooked up to a huge capacitor grid, with emitters strutting out of it. Zap."
siemens_coefficient = -1
var/tesla_power = 25000
var/tesla_range = 20
var/tesla_boom = FALSE
var/tesla_stun = FALSE
/obj/item/clothing/suit/armor/reactive/tesla/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread
sparks.set_up(1, 1, src)
sparks.start()
owner.visible_message("<span class='danger'>The tesla capacitors on [owner]'s reactive tesla armor are still recharging! The armor merely emits some sparks.</span>")
return
owner.visible_message("<span class='danger'>[src] blocks [attack_text], sending out arcs of lightning!</span>")
tesla_zap(owner,tesla_range,tesla_power,tesla_boom, tesla_stun)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
//Repulse
/obj/item/clothing/suit/armor/reactive/repulse
name = "reactive repulse armor"
desc = "An experimental suit of armor that violently throws back attackers."
/obj/item/clothing/suit/armor/reactive/repulse/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The repulse generator is still recharging!</span>")
return 0
owner.visible_message("<span class='danger'>[src] blocks [attack_text], converting the attack into a wave of force!</span>")
var/turf/T = get_turf(owner)
var/list/thrown_items = list()
for(var/atom/movable/A in range(T, 7))
if(A == owner || A.anchored || thrown_items[A])
continue
var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(A, src)))
A.throw_at(throwtarget,10,1)
thrown_items[A] = A
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
/obj/item/clothing/suit/armor/reactive/table
name = "reactive table armor"
desc = "If you can't beat the memes, embrace them."
var/tele_range = 10
/obj/item/clothing/suit/armor/reactive/table/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
var/mob/living/carbon/human/H = owner
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive table armor's fabricators are still on cooldown!</span>")
return
owner.visible_message("<span class='danger'>The reactive teleport system flings [H] clear of [attack_text] and slams them into a fabricated table!</span>")
owner.visible_message("<font color='red' size='3'>[H] GOES ON THE TABLE!!!</font>")
owner.Knockdown(40)
var/list/turfs = new/list()
for(var/turf/T in orange(tele_range, H))
if(T.density)
continue
if(T.x>world.maxx-tele_range || T.x<tele_range)
continue
if(T.y>world.maxy-tele_range || T.y<tele_range)
continue
turfs += T
if(!turfs.len)
turfs += pick(/turf in orange(tele_range, H))
var/turf/picked = pick(turfs)
if(!isturf(picked))
return
H.forceMove(picked)
new /obj/structure/table(get_turf(owner))
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return 0
/obj/item/clothing/suit/armor/reactive/table/emp_act()
return
@@ -28,6 +28,14 @@
item_state = "gy_suit"
item_color = "security"
/obj/item/clothing/under/rank/security/skirt
name = "security jumpskirt"
desc = "A \"tactical\" security jumpsuit with the legs replaced by a skirt."
icon_state = "secskirt"
item_state = "r_suit"
item_color = "secskirt"
can_adjust = FALSE //you know now that i think of it if you adjust the skirt and the sprite disappears isn't that just like flashing everyone
/obj/item/clothing/under/rank/warden
name = "security suit"
+4 -2
View File
@@ -15,8 +15,10 @@
search = findtext(text, ":", pos+1)
if(search)
emoji = lowertext(copytext(text, pos+1, search))
if(emoji in emojis)
parsed += icon2html('icons/emoji.dmi', world, emoji)
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/goonchat)
var/tag = sheet.icon_tag("emoji-[emoji]")
if(tag)
parsed += tag
pos = search + 1
else
parsed += copytext(text, pos, search)
@@ -344,6 +344,15 @@
list_reagents = list("limejuice" = 100)
foodtype = FRUIT
/obj/item/reagent_containers/food/drinks/bottle/menthol
name = "menthol"
desc = "Tastes naturally minty, and imparts a very mild numbing sensation."
icon_state = "mentholbox"
item_state = "carton"
lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi'
isGlass = FALSE
list_reagents = list("menthol" = 100)
////////////////////////// MOLOTOV ///////////////////////
/obj/item/reagent_containers/food/drinks/bottle/molotov
@@ -158,7 +158,7 @@
desc = "A timeless classic."
ingredients_placement = INGREDIENTS_STACKPLUSTOP
icon = 'icons/obj/food/burgerbread.dmi'
icon_state = "bun"
icon_state = "custburg"
foodtype = GRAIN
@@ -299,8 +299,7 @@
qdel(S)
return TRUE
for(var/obj/item/stack/sheet/wetleather/WL in src)
var/obj/item/stack/sheet/leather/L = new(drop_location())
L.amount = WL.amount
new /obj/item/stack/sheet/leather(drop_location(), WL.amount)
qdel(WL)
return TRUE
return FALSE
@@ -623,4 +623,42 @@
id = "crevice_spike"
results = list("crevice_spike" = 6)
required_reagents = list("limejuice" = 2, "capsaicin" = 4) //2 powdered delta (sour), 4 flanergide (spicy)
mix_message = "The mixture stings your eyes as it settles."
mix_message = "The mixture stings your eyes as it settles."
/datum/chemical_reaction/sake
name = "sake"
id = "sake"
results = list("sake" = 10)
required_reagents = list("rice" = 10)
required_catalysts = list("enzyme" = 5)
mix_message = "The rice grains ferment into a clear, sweet-smelling liquid."
/datum/chemical_reaction/alexander
name = "Alexander"
id = "alexander"
results = list("alexander" = 3)
required_reagents = list("cognac" = 1, "creme_de_cacao" = 1, "cream" = 1)
/datum/chemical_reaction/sidecar
name = "Sidecar"
id = "sidecar"
results = list("sidecar" = 4)
required_reagents = list("cognac" = 2, "triple_sec" = 1, "lemonjuice" = 1)
/datum/chemical_reaction/between_the_sheets
name = "Between the Sheets"
id = "between_the_sheets"
results = list("between_the_sheets" = 5)
required_reagents = list("rum" = 1, "sidecar" = 4)
/datum/chemical_reaction/kamikaze
name = "Kamikaze"
id = "kamikaze"
results = list("kamikaze" = 3)
required_reagents = list("vodka" = 1, "triple_sec" = 1, "limejuice" = 1)
/datum/chemical_reaction/mojito
name = "Mojito"
id = "mojito"
results = list("mojito" = 5)
required_reagents = list("rum" = 1, "sugar" = 1, "limejuice" = 1, "sodawater" = 1, "menthol" = 1)
+1 -2
View File
@@ -46,8 +46,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
if(!owner)
return
var/datum/asset/stuff = get_asset_datum(/datum/asset/simple/goonchat)
stuff.register()
var/datum/asset/stuff = get_asset_datum(/datum/asset/group/goonchat)
stuff.send(owner)
owner << browse(file('code/modules/goonchat/browserassets/html/browserOutput.html'), "window=browseroutput")
@@ -6,6 +6,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="font-awesome.css" />
<link rel="stylesheet" type="text/css" href="browserOutput.css" />
<link rel="stylesheet" type="text/css" href="spritesheet_chat.css" />
<script type="text/javascript" src="errorHandler.js"></script>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="json2.min.js"></script>
+9 -1
View File
@@ -70,6 +70,7 @@
begin_month = DECEMBER
end_day = 2
end_month = JANUARY
drone_hat = /obj/item/clothing/head/festive
/datum/holiday/new_year/getStationPrefix()
return pick("Party","New","Hangover","Resolution")
@@ -78,6 +79,7 @@
name = "Groundhog Day"
begin_day = 2
begin_month = FEBRUARY
drone_hat = /obj/item/clothing/head/helmet/space/chronos
/datum/holiday/valentines
name = VALENTINES
@@ -92,6 +94,7 @@
name = "Birthday of Space Station 13"
begin_day = 16
begin_month = FEBRUARY
drone_hat = /obj/item/clothing/head/festive
/datum/holiday/birthday/greet()
var/game_age = text2num(time2text(world.timeofday, "YY")) - 3
@@ -202,6 +205,7 @@
name = "UFO Day"
begin_day = 2
begin_month = JULY
drone_hat = /obj/item/clothing/mask/facehugger/dead
/datum/holiday/UFO/getStationPrefix() //Is such a thing even possible?
return pick("Ayy","Truth","Tsoukalos","Mulder") //Yes it is!
@@ -272,11 +276,13 @@
name = "Smiling Day"
begin_day = 7
begin_month = OCTOBER
drone_hat = /obj/item/clothing/head/papersack/smiley
/datum/holiday/boss
name = "Boss' Day"
begin_day = 16
begin_month = OCTOBER
drone_hat = /obj/item/clothing/head/that
/datum/holiday/halloween
name = HALLOWEEN
@@ -305,6 +311,7 @@
name = "Flowers Day"
begin_day = 19
begin_month = NOVEMBER
drone_hat = /obj/item/reagent_containers/food/snacks/grown/moonflower
/datum/holiday/hello
name = "Saying-'Hello' Day"
@@ -312,7 +319,7 @@
begin_month = NOVEMBER
/datum/holiday/hello/greet()
return "[pick(list("Aloha", "Bonjour", "Hello", "Hi", "Greetings", "Salutations", "Bienvenidos", "Hola", "Howdy"))]! " + ..()
return "[pick(list("Aloha", "Bonjour", "Hello", "Hi", "Greetings", "Salutations", "Bienvenidos", "Hola", "Howdy", "Ni hao", "Guten Tag", "Konnichiwa", "G'day cunt"))]! " + ..()
/datum/holiday/human_rights
name = "Human-Rights Day"
@@ -323,6 +330,7 @@
name = "Monkey Day"
begin_day = 14
begin_month = DECEMBER
drone_hat = /obj/item/clothing/mask/gas/monkeymask
/datum/holiday/thanksgiving
name = "Thanksgiving in the United States"
+1 -2
View File
@@ -262,8 +262,7 @@
if(!check_cost(D.materials, amount))
return FALSE
var/obj/item/stack/product = new D.build_path(loc)
product.amount = amount
new D.build_path(drop_location(), amount)
for(var/R in D.make_reagents)
beaker.reagents.add_reagent(R, D.make_reagents[R]*amount)
else
+26 -20
View File
@@ -85,14 +85,15 @@
interact(user)
return
else if(istype(I, /obj/item/disk/plantgene))
if(disk)
to_chat(user, "<span class='warning'>A data disk is already loaded into the machine!</span>")
else
if(!user.transferItemToLoc(I, src))
return
disk = I
to_chat(user, "<span class='notice'>You add [I] to the machine.</span>")
interact(user)
if (operation)
to_chat(user, "<span class='notice'>Please complete current operation.</span>")
return
eject_disk()
if(!user.transferItemToLoc(I, src))
return
disk = I
to_chat(user, "<span class='notice'>You add [I] to the machine.</span>")
interact(user)
else
..()
@@ -266,18 +267,13 @@
to_chat(usr, "<span class='notice'>You add [I] to the machine.</span>")
update_icon()
else if(href_list["eject_disk"] && !operation)
if (disk)
disk.forceMove(drop_location())
disk.verb_pickup()
disk = null
update_genes()
else
var/obj/item/I = usr.get_active_held_item()
if(istype(I, /obj/item/disk/plantgene))
if(!usr.transferItemToLoc(I, src))
return
disk = I
to_chat(usr, "<span class='notice'>You add [I] to the machine.</span>")
var/obj/item/I = usr.get_active_held_item()
eject_disk()
if(istype(I, /obj/item/disk/plantgene))
if(!usr.transferItemToLoc(I, src))
return
disk = I
to_chat(usr, "<span class='notice'>You add [I] to the machine.</span>")
else if(href_list["op"] == "insert" && disk && disk.gene && seed)
if(!operation) // Wait for confirmation
operation = "insert"
@@ -365,6 +361,16 @@
update_genes()
update_icon()
/obj/machinery/plantgenes/proc/eject_disk()
if (disk && !operation)
if(Adjacent(usr) && !issilicon(usr))
if (!usr.put_in_hands(disk))
disk.forceMove(drop_location())
else
disk.forceMove(drop_location())
disk = null
update_genes()
/obj/machinery/plantgenes/proc/update_genes()
core_genes = list()
reagent_genes = list()
+1 -12
View File
@@ -36,19 +36,8 @@
continue
grassAmt += 1 + round(G.seed.potency * tile_coefficient)
qdel(G)
var/obj/item/stack/tile/GT = new stacktype(user.loc)
while(grassAmt > GT.max_amount)
GT.amount = GT.max_amount
grassAmt -= GT.max_amount
GT = new stacktype(user.loc)
GT.amount = grassAmt
for(var/obj/item/stack/tile/T in user.loc)
if((T.type == stacktype) && (T.amount < T.max_amount))
GT.merge(T)
if(GT.amount <= 0)
break
new stacktype(user.drop_location(), grassAmt)
qdel(src)
return
// Carpet
/obj/item/seeds/grass/carpet
+3 -3
View File
@@ -22,7 +22,7 @@
var/blood_type = null
var/list/features = null
var/factions = null
var/list/traits = null
var/list/quirks = null
var/contains_sample = 0
/obj/item/seeds/replicapod/Initialize()
@@ -42,7 +42,7 @@
blood_type = B.data["blood_type"]
features = B.data["features"]
factions = B.data["factions"]
factions = B.data["traits"]
factions = B.data["quirks"]
contains_sample = TRUE
visible_message("<span class='notice'>The [src] is injected with a fresh blood sample.</span>")
else
@@ -114,7 +114,7 @@
podman.faction |= factions
if(!features["mcolor"])
features["mcolor"] = "#59CE00"
for(var/V in traits)
for(var/V in quirks)
new V(podman)
podman.hardset_dna(null,null,podman.real_name,blood_type, new /datum/species/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman
podman.set_cloned_appearance()
@@ -142,21 +142,18 @@
/obj/item/integrated_circuit/converter/concatenator
name = "concatenator"
desc = "This joins many strings together to get one big string."
desc = "This can join up to 8 strings together to get one big string."
complexity = 4
inputs = list(
"A" = IC_PINTYPE_STRING,
"B" = IC_PINTYPE_STRING,
"C" = IC_PINTYPE_STRING,
"D" = IC_PINTYPE_STRING,
"E" = IC_PINTYPE_STRING,
"F" = IC_PINTYPE_STRING,
"G" = IC_PINTYPE_STRING,
"H" = IC_PINTYPE_STRING
)
inputs = list()
outputs = list("result" = IC_PINTYPE_STRING)
activators = list("concatenate" = IC_PINTYPE_PULSE_IN, "on concatenated" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
var/number_of_pins = 8
/obj/item/integrated_circuit/converter/concatenator/Initialize()
for(var/i = 1 to number_of_pins)
inputs["input [i]"] = IC_PINTYPE_STRING
. = ..()
/obj/item/integrated_circuit/converter/concatenator/do_work()
var/result = null
@@ -169,6 +166,18 @@
push_data()
activate_pin(2)
/obj/item/integrated_circuit/converter/concatenator/small
name = "small concatenator"
desc = "This can join up to 4 strings together to get one big string."
complexity = 2
number_of_pins = 4
/obj/item/integrated_circuit/converter/concatenator/large
name = "large concatenator"
desc = "This can join up to 16 strings together to get one very big string."
complexity = 6
number_of_pins = 16
/obj/item/integrated_circuit/converter/separator
name = "separator"
desc = "This splits as single string into two at the relative split point."
@@ -203,6 +212,32 @@
activate_pin(2)
/obj/item/integrated_circuit/converter/indexer
name = "indexer"
desc = "This circuit takes a string and an index value, then returns the character found at in the string at the given index."
extended_desc = "Make sure the index is not longer or shorter than the string length. If you don't, the circuit will return empty."
icon_state = "split"
complexity = 4
inputs = list(
"string to index" = IC_PINTYPE_STRING,
"index" = IC_PINTYPE_NUMBER,
)
outputs = list(
"found character" = IC_PINTYPE_STRING
)
activators = list("index" = IC_PINTYPE_PULSE_IN, "on indexed" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/indexer/do_work()
var/strin = get_pin_data(IC_INPUT, 1)
var/ind = get_pin_data(IC_INPUT, 2)
if(ind > 0 && ind <= length(strin))
set_pin_data(IC_OUTPUT, 1, strin[ind])
else
set_pin_data(IC_OUTPUT, 1, "")
push_data()
activate_pin(2)
/obj/item/integrated_circuit/converter/findstring
name = "find text"
desc = "This gives position of sample in the string. Or returns 0."
@@ -216,14 +251,38 @@
outputs = list(
"position" = IC_PINTYPE_NUMBER
)
activators = list("search" = IC_PINTYPE_PULSE_IN, "after search" = IC_PINTYPE_PULSE_OUT)
activators = list("search" = IC_PINTYPE_PULSE_IN, "after search" = IC_PINTYPE_PULSE_OUT, "found" = IC_PINTYPE_PULSE_OUT, "not found" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/findstring/do_work()
var/position = findtext(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2))
set_pin_data(IC_OUTPUT, 1, findtext(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2)) )
set_pin_data(IC_OUTPUT, 1, position)
push_data()
activate_pin(2)
if(position)
activate_pin(3)
else
activate_pin(4)
/obj/item/integrated_circuit/converter/stringlength
name = "get length"
desc = "This circuit will return the number of characters in a string."
complexity = 1
inputs = list(
"string" = IC_PINTYPE_STRING
)
outputs = list(
"length" = IC_PINTYPE_NUMBER
)
activators = list("get length" = IC_PINTYPE_PULSE_IN, "on acquisition" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/stringlength/do_work()
set_pin_data(IC_OUTPUT, 1, length(get_pin_data(IC_INPUT, 1)))
push_data()
activate_pin(2)
@@ -232,7 +291,8 @@
name = "string exploder"
desc = "This splits a single string into a list of strings."
extended_desc = "This circuit splits a given string into a list of strings based on the string and given delimiter. \
For example, 'eat this burger' will be converted to list('eat','this','burger')."
For example, 'eat this burger' will be converted to list('eat','this','burger'). Leave the delimiter null to get a list \
of every individual character."
icon_state = "split"
complexity = 4
inputs = list(
@@ -248,7 +308,10 @@
/obj/item/integrated_circuit/converter/exploders/do_work()
var/strin = get_pin_data(IC_INPUT, 1)
var/delimiter = get_pin_data(IC_INPUT, 2)
set_pin_data(IC_OUTPUT, 1, splittext(strin, delimiter))
if(delimiter == null)
set_pin_data(IC_OUTPUT, 1, string2charlist(strin))
else
set_pin_data(IC_OUTPUT, 1, splittext(strin, delimiter))
push_data()
activate_pin(2)
+8 -3
View File
@@ -226,9 +226,14 @@ GLOBAL_PROTECT(exp_to_update)
if(!rolefound)
play_records["Unknown"] += minutes
else
play_records[EXP_TYPE_GHOST] += minutes
if(announce_changes)
to_chat(src,"<span class='notice'>You got: [minutes] Ghost EXP!</span>")
if(holder && !holder.deadmined)
play_records[EXP_TYPE_ADMIN] += minutes
if(announce_changes)
to_chat(src,"<span class='notice'>You got: [minutes] Admin EXP!</span>")
else
play_records[EXP_TYPE_GHOST] += minutes
if(announce_changes)
to_chat(src,"<span class='notice'>You got: [minutes] Ghost EXP!</span>")
else if(isobserver(mob))
play_records[EXP_TYPE_GHOST] += minutes
if(announce_changes)
+1 -1
View File
@@ -91,7 +91,7 @@ Mime
uniform = /obj/item/clothing/under/rank/mime
mask = /obj/item/clothing/mask/gas/mime
gloves = /obj/item/clothing/gloves/color/white
head = /obj/item/clothing/head/beret
head = /obj/item/clothing/head/frenchberet
suit = /obj/item/clothing/suit/suspenders
backpack_contents = list(/obj/item/reagent_containers/food/drinks/bottle/bottleofnothing=1)
+2 -1
View File
@@ -35,7 +35,8 @@
return TRUE
/datum/language/proc/get_icon()
return "[icon2html(icon, world, icon_state)]"
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/goonchat)
return sheet.icon_tag("language-[icon_state]")
/datum/language/proc/get_random_name(gender, name_count=2, syllable_count=4, syllable_divisor=2)
if(!syllables || !syllables.len)
@@ -25,6 +25,14 @@
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
resistance_flags = FIRE_PROOF
/obj/item/clothing/suit/hooded/explorer/Initialize()
. = ..()
AddComponent(/datum/component/armor_plate)
/obj/item/clothing/head/hooded/explorer/Initialize()
. = ..()
AddComponent(/datum/component/armor_plate)
/obj/item/clothing/mask/gas/explorer
name = "explorer gas mask"
desc = "A military-grade gas mask that can be connected to an air supply."
+1 -35
View File
@@ -9,38 +9,4 @@
novariants = FALSE
flags_1 = NOBLUDGEON_1
w_class = WEIGHT_CLASS_NORMAL
layer = MOB_LAYER
var/static/list/goliath_platable_armor_typecache = typecacheof(list(
/obj/item/clothing/head/helmet/space/hardsuit/mining,
/obj/item/clothing/suit/space/hardsuit/mining,
/obj/item/clothing/head/hooded/explorer,
/obj/item/clothing/suit/hooded/explorer))
/obj/item/stack/sheet/animalhide/goliath_hide/afterattack(atom/target, mob/user, proximity_flag)
if(!proximity_flag)
return
if(is_type_in_typecache(target, goliath_platable_armor_typecache))
var/obj/item/clothing/C = target
if(C.armor.melee < 60)
C.armor = C.armor.setRating(melee = min(C.armor.melee + 10, 60))
to_chat(user, "<span class='info'>You strengthen [target], improving its resistance against melee attacks.</span>")
use(1)
else
to_chat(user, "<span class='warning'>You can't improve [C] any further!</span>")
else if(istype(target, /obj/mecha/working/ripley))
var/obj/mecha/working/ripley/D = target
if(D.hides < 3)
D.hides++
D.armor = D.armor.setRating(\
melee = min(D.armor.melee + 10, 70),\
bullet = min(D.armor.bullet + 5, 50),\
laser = min(D.armor.laser + 5, 50))
to_chat(user, "<span class='info'>You strengthen [target], improving its resistance against melee attacks.</span>")
D.update_icon()
if(D.hides == 3)
D.desc = "Autonomous Power Loader Unit. It's wearing a fearsome carapace entirely composed of goliath hide plates - its pilot must be an experienced monster hunter."
else
D.desc = "Autonomous Power Loader Unit. Its armour is enhanced with some goliath hide plates."
use(1)
else
to_chat(user, "<span class='warning'>You can't improve [D] any further!</span>")
layer = MOB_LAYER
+5 -6
View File
@@ -303,13 +303,12 @@
desired = input("How many sheets?", "How many sheets would you like to smelt?", 1) as null|num
var/amount = round(min(desired,50,smelt_amount))
materials.use_amount(alloy.materials, amount)
var/output = new alloy.build_path(src)
if(istype(output, /obj/item/stack/sheet))
var/obj/item/stack/sheet/produced_alloy = output
produced_alloy.amount = amount
unload_mineral(produced_alloy)
var/output
if(ispath(alloy.build_path, /obj/item/stack/sheet))
output = new alloy.build_path(src, amount)
else
unload_mineral(output)
output = new alloy.build_path(src)
unload_mineral(output)
else
to_chat(usr, "<span class='warning'>Required access not found.</span>")
return TRUE
+3 -6
View File
@@ -44,8 +44,7 @@
if(!(text2path(href_list["release"]) in machine.stack_list))
return //someone tried to spawn materials by spoofing hrefs
var/obj/item/stack/sheet/inp = machine.stack_list[text2path(href_list["release"])]
var/obj/item/stack/sheet/out = new inp.type()
out.amount = inp.amount
var/obj/item/stack/sheet/out = new inp.type(null, inp.amount)
inp.amount = 0
machine.unload_mineral(out)
@@ -81,14 +80,12 @@
/obj/machinery/mineral/stacking_machine/proc/process_sheet(obj/item/stack/sheet/inp)
if(!(inp.type in stack_list)) //It's the first of this sheet added
var/obj/item/stack/sheet/s = new inp.type(src,0)
s.amount = 0
var/obj/item/stack/sheet/s = new inp.type(src, 0)
stack_list[inp.type] = s
var/obj/item/stack/sheet/storage = stack_list[inp.type]
storage.amount += inp.amount //Stack the sheets
qdel(inp) //Let the old sheet garbage collect
while(storage.amount > stack_amt) //Get rid of excessive stackage
var/obj/item/stack/sheet/out = new inp.type()
out.amount = stack_amt
var/obj/item/stack/sheet/out = new inp.type(null, stack_amt)
unload_mineral(out)
storage.amount -= stack_amt
@@ -400,7 +400,7 @@
SSticker.mode.make_antag_chance(humanc)
if(humanc && CONFIG_GET(flag/roundstart_traits))
SStraits.AssignTraits(humanc, humanc.client, TRUE)
SSquirks.AssignQuirks(humanc, humanc.client, TRUE)
log_manifest(character.mind.key,character.mind,character,latejoin = TRUE)
@@ -592,6 +592,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/list/possessible = list()
for(var/mob/living/L in GLOB.alive_mob_list)
if(istype(L,/mob/living/carbon/human/dummy) || !get_turf(L)) //Haha no.
continue
if(!(L in GLOB.player_list) && !L.mind)
possessible += L
+4 -1
View File
@@ -326,7 +326,10 @@
I.plane = initial(I.plane)
I.appearance_flags &= ~NO_CLIENT_COLOR
if(!no_move && !(I.flags_1 & DROPDEL_1)) //item may be moved/qdel'd immedietely, don't bother moving it
I.forceMove(newloc)
if (isnull(newloc))
I.moveToNullspace()
else
I.forceMove(newloc)
I.dropped(src)
return TRUE
+4 -4
View File
@@ -193,10 +193,10 @@
blood_data["real_name"] = real_name
blood_data["features"] = dna.features
blood_data["factions"] = faction
blood_data["traits"] = list()
for(var/V in roundstart_traits)
var/datum/trait/T = V
blood_data["traits"] += T.type
blood_data["quirks"] = list()
for(var/V in roundstart_quirks)
var/datum/quirk/T = V
blood_data["quirks"] += T.type
return blood_data
//get the id of the substance this mob use as blood.
@@ -19,6 +19,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
//Inefficient pooling/caching way.
GLOBAL_LIST_EMPTY(human_dummy_list)
GLOBAL_LIST_EMPTY(dummy_mob_list)
/proc/generate_or_wait_for_human_dummy(slotkey)
if(!slotkey)
@@ -31,6 +32,7 @@ GLOBAL_LIST_EMPTY(human_dummy_list)
if(QDELETED(D))
D = new
GLOB.human_dummy_list[slotkey] = D
GLOB.dummy_mob_list += D
D.in_use = TRUE
return D
@@ -733,8 +733,8 @@
if(0 to NUTRITION_LEVEL_STARVING)
to_chat(src, "<span class='danger'>You're starving!</span>")
if(roundstart_traits.len)
to_chat(src, "<span class='notice'>You have these traits: [get_trait_string()].</span>")
if(roundstart_quirks.len)
to_chat(src, "<span class='notice'>You have these quirks: [get_trait_string()].</span>")
else
if(wear_suit)
wear_suit.add_fingerprint(M)
+2 -1
View File
@@ -13,7 +13,8 @@
message = T.TongueSpeech(message)
if(wear_mask)
message = wear_mask.speechModification(message)
if(head)
message = head.speechModification(message)
return message
/mob/living/carbon/can_speak_vocal(message)
+13 -10
View File
@@ -407,16 +407,14 @@
*/
//Recursive function to find everything a mob is holding. Really shitty proc tbh.
/mob/living/get_contents()
. = list()
. |= list(src)
for(var/obj/o in .)
var/list/newlist = list()
o.SendSignal(COMSIG_TRY_STORAGE_RETURN_INVENTORY, newlist)
. |= newlist
for(var/obj/item/clothing/under/U in .)
. |= U.contents
for(var/obj/item/folder/F in .)
. |= F.contents
var/list/ret = list()
ret |= contents //add our contents
for(var/i in ret.Copy()) //iterate storage objects
var/atom/A = i
A.SendSignal(COMSIG_TRY_STORAGE_RETURN_INVENTORY, ret)
for(var/obj/item/folder/F in ret.Copy()) //very snowflakey-ly iterate folders
ret |= F.contents
return ret
// Living mobs use can_inject() to make sure that the mob is not syringe-proof in general.
/mob/living/proc/can_inject()
@@ -494,6 +492,11 @@
ExtinguishMob()
fire_stacks = 0
update_canmove()
GET_COMPONENT(mood, /datum/component/mood)
if (mood)
QDEL_LIST(mood.mood_events)
mood.sanity = SANITY_GREAT
mood.update_mood()
//proc called by revive(), to check if we can actually ressuscitate the mob (we don't want to revive him and have him instantly die again)
+1 -2
View File
@@ -317,8 +317,7 @@
return shock_damage
/mob/living/emp_act(severity)
var/list/L = src.get_contents()
for(var/obj/O in L)
for(var/obj/O in contents)
O.emp_act(severity)
..()
+1 -1
View File
@@ -34,7 +34,7 @@
var/list/status_traits = list()
var/list/roundstart_traits = list()
var/list/roundstart_quirks = list()
var/list/surgeries = list() //a list of surgery datums. generally empty, they're added when the player wants them.
@@ -831,7 +831,7 @@
set_module = /obj/item/robot_module/janitor
/mob/living/silicon/robot/modules/syndicate
icon_state = "syndie_bloodhound"
icon_state = "synd_sec"
faction = list(ROLE_SYNDICATE)
bubble_icon = "syndibot"
req_access = list(ACCESS_SYNDICATE)
@@ -859,7 +859,7 @@
return
/mob/living/silicon/robot/modules/syndicate/medical
icon_state = "syndi-medi"
icon_state = "synd_medical"
playstyle_string = "<span class='big bold'>You are a Syndicate medical cyborg!</span><br>\
<b>You are armed with powerful medical tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \
Your hypospray will produce Restorative Nanites, a wonder-drug that will heal most types of bodily damages, including clone and brain damage. It also produces morphine for offense. \
@@ -1,7 +1,7 @@
/obj/item/robot_module
name = "Default"
icon = 'icons/obj/module.dmi'
icon_state = "std_module"
icon_state = "std_mod"
w_class = WEIGHT_CLASS_GIGANTIC
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
@@ -164,12 +164,7 @@
update_controls()
/mob/living/simple_animal/bot/floorbot/proc/empty_tiles()
var/atom/Tsec = drop_location()
while(specialtiles > initial(tiletype.max_amount))
new tiletype(Tsec,initial(tiletype.max_amount))
specialtiles -= initial(tiletype.max_amount)
new tiletype(Tsec,specialtiles)
new tiletype(drop_location(), specialtiles)
specialtiles = 0
tiletype = null
@@ -378,8 +373,7 @@
if(prob(50))
drop_part(robot_arm, Tsec)
var/obj/item/stack/tile/plasteel/T = new (Tsec)
T.amount = 1
new /obj/item/stack/tile/plasteel(Tsec, 1)
do_sparks(3, TRUE, src)
..()
@@ -2,7 +2,7 @@
name = "\improper honkbot"
desc = "A little robot. It looks happy with its bike horn."
icon = 'icons/mob/aibots.dmi'
icon_state = "honkbot"
icon_state = "honkbot1"
density = FALSE
anchored = FALSE
health = 25
@@ -27,6 +27,7 @@
attacktext = "pummels"
attack_sound = 'sound/weapons/punch1.ogg'
dextrous = TRUE
held_items = list(null, null)
possible_a_intents = list(INTENT_HELP, INTENT_GRAB, INTENT_DISARM, INTENT_HARM)
faction = list("jungle")
robust_searching = TRUE
@@ -9,7 +9,7 @@
icon_dead = "Fugu_dead"
icon_gib = "syndicate_gib"
mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
mouse_opacity = MOUSE_OPACITY_OPAQUE
mouse_opacity = MOUSE_OPACITY_ICON
move_to_delay = 5
friendly = "floats near"
speak_emote = list("puffs")
+8 -8
View File
@@ -146,12 +146,12 @@
else
status_traits[trait] |= list(source)
/mob/living/proc/add_trait_datum(trait, spawn_effects) //separate proc due to the way these ones are handled
if(has_trait(trait))
/mob/living/proc/add_quirk(quirk, spawn_effects) //separate proc due to the way these ones are handled
if(has_trait(quirk))
return
if(!SStraits || !SStraits.traits[trait])
if(!SSquirks || !SSquirks.quirks[quirk])
return
var/datum/trait/T = SStraits.traits[trait]
var/datum/quirk/T = SSquirks.quirks[quirk]
new T (src, spawn_effects)
return TRUE
@@ -180,8 +180,8 @@
if(!LAZYLEN(status_traits[trait]))
status_traits -= trait
/mob/living/proc/remove_trait_datum(trait)
var/datum/trait/T = roundstart_traits[trait]
/mob/living/proc/remove_quirk(quirk)
var/datum/quirk/T = roundstart_quirks[quirk]
if(T)
qdel(T)
return TRUE
@@ -201,8 +201,8 @@
else if(LAZYLEN(status_traits[trait]))
return TRUE
/mob/living/proc/has_trait_datum(trait)
return roundstart_traits[trait]
/mob/living/proc/has_quirk(quirk)
return roundstart_quirks[quirk]
/mob/living/proc/remove_all_traits()
status_traits = list()
+1 -1
View File
@@ -70,7 +70,7 @@
message = src.say_quote(message, get_spans())
var/rendered = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <span class='name'>[name]</span>[alt_name] <span class='message'>[message]</span></span>"
log_message("DEAD: [message]", INDIVIDUAL_SAY_LOG)
deadchat_broadcast(rendered, follow_target = src, speaker_key = K)
/mob/proc/check_emote(message)
+5 -2
View File
@@ -66,7 +66,7 @@
..()
to_chat(user, "<span class='notice'>Alt-click to fold it.</span>")
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/paper)
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/paper)
assets.send(user)
if(in_range(user, src) || isobserver(user))
@@ -300,7 +300,10 @@
if(!in_range(src, user))
return
stamps += "<img src=large_[P.icon_state].png>"
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/paper)
if (isnull(stamps))
stamps = sheet.css_tag()
stamps += sheet.icon_tag(P.icon_state)
var/mutable_appearance/stampoverlay = mutable_appearance('icons/obj/bureaucracy.dmi', "paper_[P.icon_state]")
stampoverlay.pixel_x = rand(-2, 2)
stampoverlay.pixel_y = rand(-3, 2)
+2 -7
View File
@@ -111,13 +111,8 @@
/obj/machinery/power/port_gen/pacman/DropFuel()
if(sheets)
var/fail_safe = FALSE
while(sheets > 0 && fail_safe < 100)
fail_safe += 1
var/obj/item/stack/sheet/S = new sheet_path(loc)
var/amount = min(sheets, S.max_amount)
S.amount = amount
sheets -= amount
new sheet_path(drop_location(), sheets)
sheets = 0
/obj/machinery/power/port_gen/pacman/UseFuel()
var/needed_sheets = 1 / (time_per_sheet * consumption / power_output)
+4 -4
View File
@@ -191,12 +191,12 @@
// Give back the glass type we were supplied with
/obj/item/solar_assembly/proc/give_glass(device_broken)
var/atom/Tsec = drop_location()
if(device_broken)
new /obj/item/shard(loc)
new /obj/item/shard(loc)
new /obj/item/shard(Tsec)
new /obj/item/shard(Tsec)
else if(glass_type)
var/obj/item/stack/sheet/S = new glass_type(loc)
S.amount = 2
new glass_type(Tsec, 2)
glass_type = null
@@ -1,8 +1,8 @@
/obj/item/ammo_box/magazine/m12g
name = "shotgun magazine (12g taser slugs)"
name = "shotgun magazine (12g buckshot slugs)"
desc = "A drum magazine."
icon_state = "m12gs"
ammo_type = /obj/item/ammo_casing/shotgun/stunslug
icon_state = "m12gb"
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
caliber = "shotgun"
max_ammo = 8
@@ -10,14 +10,14 @@
..()
icon_state = "[initial(icon_state)]-[CEILING(ammo_count(0)/8, 1)*8]"
/obj/item/ammo_box/magazine/m12g/buckshot
name = "shotgun magazine (12g buckshot slugs)"
icon_state = "m12gb"
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
/obj/item/ammo_box/magazine/m12g/stun
name = "shotgun magazine (12g taser slugs)"
icon_state = "m12gs"
ammo_type = /obj/item/ammo_casing/shotgun/stunslug
/obj/item/ammo_box/magazine/m12g/slug
name = "shotgun magazine (12g slugs)"
icon_state = "m12gb"
icon_state = "m12gb" //this may need an unique sprite
ammo_type = /obj/item/ammo_casing/shotgun
/obj/item/ammo_box/magazine/m12g/dragon
@@ -40,7 +40,6 @@
to_chat(user, "<span class='warning'>You need a free hand to hold the gun!</span>")
return
update_icon()
gun.forceMove(user)
user.update_inv_back()
else
to_chat(user, "<span class='warning'>You are already holding the gun!</span>")
@@ -436,7 +436,7 @@
/obj/item/projectile/beam/beam_rifle
name = "particle beam"
icon = ""
icon = null
hitsound = 'sound/effects/explosion3.ogg'
damage = 0 //Handled manually.
damage_type = BURN
@@ -4,7 +4,7 @@
/obj/item/projectile/curse_hand
name = "curse hand"
icon_state = "cursehand"
icon_state = "cursehand0"
hitsound = 'sound/effects/curse4.ogg'
layer = LARGE_MOB_LAYER
damage_type = BURN
@@ -19,10 +19,7 @@
/obj/item/projectile/curse_hand/Initialize(mapload)
. = ..()
handedness = prob(50)
update_icon()
/obj/item/projectile/curse_hand/update_icon()
icon_state = "[icon_state][handedness]"
icon_state = "cursehand[handedness]"
/obj/item/projectile/curse_hand/fire(setAngle)
if(starting)
@@ -433,7 +433,8 @@ obj/machinery/chem_dispenser/proc/work_animation()
"orangejuice",
"limejuice",
"tomatojuice",
"lemonjuice"
"lemonjuice",
"menthol"
)
emagged_reagents = list(
"thirteenloko",
@@ -465,7 +466,8 @@ obj/machinery/chem_dispenser/proc/work_animation()
"hcider",
"creme_de_menthe",
"creme_de_cacao",
"triple_sec"
"triple_sec",
"sake"
)
emagged_reagents = list(
"ethanol",
@@ -499,3 +501,17 @@ obj/machinery/chem_dispenser/proc/work_animation()
"ammonia",
"ash",
"diethylamine")
/obj/machinery/chem_dispenser/fullupgrade //fully upgraded stock parts
/obj/machinery/chem_dispenser/fullupgrade/Initialize()
. = ..()
component_parts = list()
component_parts += new /obj/item/circuitboard/machine/chem_dispenser(null)
component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null)
component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null)
component_parts += new /obj/item/stock_parts/capacitor/quadratic(null)
component_parts += new /obj/item/stock_parts/manipulator/femto(null)
component_parts += new /obj/item/stack/sheet/glass(null)
component_parts += new /obj/item/stock_parts/cell/bluespace(null)
RefreshParts()
@@ -0,0 +1,85 @@
/obj/machinery/chem_dispenser/chem_synthesizer //formerly SCP-294 made by mrty, but now only for testing purposes
name = "\improper debug chemical synthesizer"
desc = "If you see this, yell at adminbus."
icon = 'icons/obj/chemical.dmi'
icon_state = "dispenser"
amount = 10
resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | LAVA_PROOF
working_state = null
nopower_state = null
flags_1 = NODECONSTRUCT_1
var/static/list/shortcuts = list(
"meth" = "methamphetamine",
"tricord" = "tricordrazine"
)
var/mutable_appearance/top_overlay
/obj/machinery/chem_dispenser/chem_synthesizer/Initialize()
. = ..()
GLOB.poi_list += src
top_overlay = mutable_appearance(icon, "disp_beaker", layer = ABOVE_ALL_MOB_LAYER)
update_icon()
/obj/machinery/chem_dispenser/chem_synthesizer/update_icon()
cut_overlays()
add_overlay(top_overlay)
/obj/machinery/chem_dispenser/chem_synthesizer/Destroy()
. = ..()
GLOB.poi_list -= src
QDEL_NULL(top_overlay)
/obj/machinery/chem_dispenser/chem_synthesizer/display_beaker()
return
/obj/machinery/chem_dispenser/chem_synthesizer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "chem_synthesizer", name, 390, 315, master_ui, state)
ui.open()
/obj/machinery/chem_dispenser/chem_synthesizer/ui_act(action, params)
if(..())
return
update_icon()
switch(action)
if("ejectBeaker")
if(beaker)
beaker.forceMove(drop_location())
if(Adjacent(usr) && !issilicon(usr))
usr.put_in_hands(beaker)
beaker = null
. = TRUE
if("input")
var/input_reagent = replacetext(lowertext(input("Enter the name of any liquid", "Input") as text), " ", "") //95% of the time, the reagent id is a lowercase/no spaces version of the name
if(shortcuts[input_reagent])
input_reagent = shortcuts[input_reagent]
else
input_reagent = find_reagent(input_reagent)
if(!input_reagent || !GLOB.chemical_reagents_list[input_reagent])
say("OUT OF RANGE")
return
else
if(!beaker)
return
else if(!beaker.reagents && !QDELETED(beaker))
beaker.create_reagents(beaker.volume)
beaker.reagents.add_reagent(input_reagent, amount)
if("makecup")
if(beaker)
return
beaker = new /obj/item/reagent_containers/glass/beaker/bluespace(src)
visible_message("<span class='notice'>[src] dispenses a bluespace beaker.</span>")
/obj/machinery/chem_dispenser/chem_synthesizer/proc/find_reagent(input)
. = FALSE
if(GLOB.chemical_reagents_list[input]) //prefer IDs!
var/datum/reagent/R = GLOB.chemical_reagents_list[input]
if(R.can_synth_debug)
return input
else
for(var/X in GLOB.chemical_reagents_list)
var/datum/reagent/R = GLOB.chemical_reagents_list[X]
if(R.can_synth_debug && input == replacetext(lowertext(R.name), " ", ""))
return X
+2 -1
View File
@@ -20,7 +20,8 @@
var/current_cycle = 0
var/volume = 0
var/color = "#000000" // rgb: 0, 0, 0
var/can_synth = TRUE
var/can_synth = TRUE // can this reagent be synthesized? (for example: odysseus syringe gun)
var/can_synth_debug = TRUE // can this reagent be synthesized by the debug chem synthesizer?
var/metabolization_rate = REAGENTS_METABOLISM //how fast the reagent is metabolized by the mob
var/overrides_metab = 0
var/overdose_threshold = 0
@@ -1546,4 +1546,70 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "It'll either knock the drunkenness out of you or knock you out cold. Both, probably."
/datum/reagent/consumable/ethanol/crevice_spike/on_mob_add(mob/living/L) //damage only applies when drink first enters system and won't again until drink metabolizes out
L.adjustBruteLoss(3 * min(5,volume)) //minimum 3 brute damage on ingestion to limit non-drink means of injury - a full 5 unit gulp of the drink trucks you for the full 15
L.adjustBruteLoss(3 * min(5,volume)) //minimum 3 brute damage on ingestion to limit non-drink means of injury - a full 5 unit gulp of the drink trucks you for the full 15
/datum/reagent/consumable/ethanol/sake
name = "Sake"
id = "sake"
description = "A sweet rice wine of questionable legality and extreme potency."
color = "#DDDDDD"
boozepwr = 70
taste_description = "sweet rice wine"
glass_icon_state = "sakecup"
glass_name = "cup of sake"
glass_desc = "A traditional cup of sake."
/datum/reagent/consumable/ethanol/alexander
name = "Alexander"
id = "alexander"
description = "A creamy, indulgent delight that is stronger than it seems."
color = "#F5E9D3"
boozepwr = 80
taste_description = "bitter, creamy cacao"
glass_icon_state = "alexander"
glass_name = "Alexander"
glass_desc = "A creamy, indulgent delight that is stronger than it seems."
/datum/reagent/consumable/ethanol/sidecar
name = "Sidecar"
id = "sidecar"
description = "The one ride youll gladly give up the wheel for."
color = "#FFC55B"
boozepwr = 80
taste_description = "delicious freedom"
glass_icon_state = "sidecar"
glass_name = "Sidecar"
glass_desc = "The one ride youll gladly give up the wheel for."
/datum/reagent/consumable/ethanol/between_the_sheets
name = "Between the Sheets"
id = "between_the_sheets"
description = "A provocatively named classic."
color = "#F4C35A"
boozepwr = 80
taste_description = "seduction"
glass_icon_state = "between_the_sheets"
glass_name = "Between the Sheets"
glass_desc = "A provocatively named classic."
/datum/reagent/consumable/ethanol/kamikaze
name = "Kamikaze"
id = "kamikaze"
description = "Divinely windy."
color = "#EEF191"
boozepwr = 60
taste_description = "divine windiness"
glass_icon_state = "kamikaze"
glass_name = "Kamikaze"
glass_desc = "Divinely windy."
/datum/reagent/consumable/ethanol/mojito
name = "Mojito"
id = "mojito"
description = "A drink that looks as refreshing as it tastes."
color = "#DFFAD9"
boozepwr = 30
taste_description = "refreshing mint"
glass_icon_state = "mojito"
glass_name = "Mojito"
glass_desc = "A drink that looks as refreshing as it tastes."
@@ -721,3 +721,13 @@
description = "Milk for cool kids."
color = "#7D4E29"
taste_description = "chocolate milk"
/datum/reagent/consumable/menthol
name = "Menthol"
id = "menthol"
description = "Tastes naturally minty, and imparts a very mild numbing sensation."
color = "#80AF9C"
taste_description = "mint"
glass_icon_state = "glass_green"
glass_name = "glass of menthol"
glass_desc = "Tastes naturally minty, and imparts a very mild numbing sensation."
@@ -57,15 +57,6 @@
..()
. = 1
/datum/reagent/drug/menthol
name = "Menthol"
id = "menthol"
description = "Tastes naturally minty, and imparts a very mild numbing sensation."
taste_description = "mint"
reagent_state = LIQUID
color = "#80AF9C"
trippy = FALSE
/datum/reagent/drug/crank
name = "Crank"
id = "crank"
@@ -171,8 +171,7 @@
else if(istype(O, /obj/item/stack/sheet/hairlesshide))
var/obj/item/stack/sheet/hairlesshide/HH = O
var/obj/item/stack/sheet/wetleather/WL = new(get_turf(HH))
WL.amount = HH.amount
new /obj/item/stack/sheet/wetleather(get_turf(HH), HH.amount)
qdel(HH)
/*
@@ -728,7 +728,7 @@
/datum/reagent/toxin/rotatium/on_mob_life(mob/living/M)
if(M.hud_used)
if(current_cycle >= 20 && current_cycle%20 == 0)
var/list/screens = list(M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"])
var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"])
var/rotation = min(round(current_cycle/20), 89) // By this point the player is probably puking and quitting anyway
for(var/whole_screen in screens)
animate(whole_screen, transform = matrix(rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING, loop = -1)
@@ -737,7 +737,7 @@
/datum/reagent/toxin/rotatium/on_mob_delete(mob/living/M)
if(M && M.hud_used)
var/list/screens = list(M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"])
var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"])
for(var/whole_screen in screens)
animate(whole_screen, transform = matrix(), time = 5, easing = QUAD_EASING)
..()
@@ -755,7 +755,7 @@
/datum/reagent/toxin/skewium/on_mob_life(mob/living/M)
if(M.hud_used)
if(current_cycle >= 5 && current_cycle % 3 == 0)
var/list/screens = list(M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"])
var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"])
var/matrix/skew = matrix()
var/intensity = 8
skew.set_skew(rand(-intensity,intensity), rand(-intensity,intensity))
@@ -772,7 +772,7 @@
/datum/reagent/toxin/skewium/on_mob_delete(mob/living/M)
if(M && M.hud_used)
var/list/screens = list(M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"])
var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"])
for(var/whole_screen in screens)
animate(whole_screen, transform = matrix(), time = 5, easing = QUAD_EASING)
..()
+3 -2
View File
@@ -51,8 +51,9 @@ other types of metals and chemistry for reagents).
return ..()
/datum/design/proc/icon_html(client/user)
send_asset(user, "design_[id].png", FALSE)
return "<img class='icon' src=\"design_[id].png\">"
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/research_designs)
sheet.send(user)
return sheet.icon_tag(id)
////////////////////////////////////////
//Disks for transporting design datums//
@@ -126,42 +126,47 @@
/datum/design/apc_board
name = "APC Module"
id = "power control"
build_type = AUTOLATHE
build_type = AUTOLATHE | PROTOLATHE
materials = list(MAT_METAL = 100, MAT_GLASS = 100)
build_path = /obj/item/electronics/apc
category = list("initial", "Electronics")
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
/datum/design/airlock_board
name = "Airlock Electronics"
id = "airlock_board"
build_type = AUTOLATHE
build_type = AUTOLATHE | PROTOLATHE
materials = list(MAT_METAL = 50, MAT_GLASS = 50)
build_path = /obj/item/electronics/airlock
category = list("initial", "Electronics")
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
/datum/design/firelock_board
name = "Firelock Circuitry"
id = "firelock_board"
build_type = AUTOLATHE
build_type = AUTOLATHE | PROTOLATHE
materials = list(MAT_METAL = 50, MAT_GLASS = 50)
build_path = /obj/item/electronics/firelock
category = list("initial", "Electronics")
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
/datum/design/airalarm_electronics
name = "Air Alarm Electronics"
id = "airalarm_electronics"
build_type = AUTOLATHE
build_type = AUTOLATHE | PROTOLATHE
materials = list(MAT_METAL = 50, MAT_GLASS = 50)
build_path = /obj/item/electronics/airalarm
category = list("initial", "Electronics")
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
/datum/design/firealarm_electronics
name = "Fire Alarm Electronics"
id = "firealarm_electronics"
build_type = AUTOLATHE
build_type = AUTOLATHE | PROTOLATHE
materials = list(MAT_METAL = 50, MAT_GLASS = 50)
build_path = /obj/item/electronics/firealarm
category = list("initial", "Electronics")
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
/datum/design/camera
name = "Camera"
@@ -354,3 +354,17 @@
build_path = /obj/item/weldingtool/experimental
category = list("Equipment")
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING
/////////////////////////////////////////
////////////Armour//////////////
/////////////////////////////////////////
/datum/design/reactive_armour
name = "Reactive Armour Shell"
desc = "An experimental suit of armour capable of utilizing an implanted anomaly core to protect the user."
id = "reactive_armour"
build_type = PROTOLATHE
materials = list(MAT_METAL = 10000, MAT_DIAMOND = 5000, MAT_URANIUM = 8000, MAT_SILVER = 4500, MAT_GOLD = 5000)
build_path = /obj/item/reactive_armour_shell
category = list("Equipment")
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING
@@ -21,15 +21,23 @@
name = "Plasma + Glass alloy"
id = "plasmaglass"
build_type = SMELTER
materials = list(MAT_PLASMA = MINERAL_MATERIAL_AMOUNT, MAT_GLASS = MINERAL_MATERIAL_AMOUNT)
materials = list(MAT_PLASMA = MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS = MINERAL_MATERIAL_AMOUNT)
build_path = /obj/item/stack/sheet/plasmaglass
category = list("initial")
/datum/design/plasmarglass_alloy
name = "Plasma + Metal + Glass alloy"
id = "plasmareinforcedglass"
build_type = SMELTER
materials = list(MAT_PLASMA = MINERAL_MATERIAL_AMOUNT * 0.5, MAT_METAL = MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS = MINERAL_MATERIAL_AMOUNT)
build_path = /obj/item/stack/sheet/plasmarglass
category = list("initial")
/datum/design/titaniumglass_alloy
name = "Titanium + Glass alloy"
id = "titaniumglass"
build_type = SMELTER
materials = list(MAT_TITANIUM = MINERAL_MATERIAL_AMOUNT, MAT_GLASS = MINERAL_MATERIAL_AMOUNT)
materials = list(MAT_TITANIUM = MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS = MINERAL_MATERIAL_AMOUNT)
build_path = /obj/item/stack/sheet/titaniumglass
category = list("initial")
@@ -37,7 +45,7 @@
name = "Plasma + Titanium + Glass alloy"
id = "plastitaniumglass"
build_type = SMELTER
materials = list(MAT_PLASMA = MINERAL_MATERIAL_AMOUNT, MAT_TITANIUM = MINERAL_MATERIAL_AMOUNT, MAT_GLASS = MINERAL_MATERIAL_AMOUNT)
materials = list(MAT_PLASMA = MINERAL_MATERIAL_AMOUNT * 0.5, MAT_TITANIUM = MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS = MINERAL_MATERIAL_AMOUNT)
build_path = /obj/item/stack/sheet/plastitaniumglass
category = list("initial")
+2
View File
@@ -217,6 +217,8 @@ doesn't have toxins access.
/obj/machinery/computer/rdconsole/proc/ui_header()
var/list/l = list()
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/research_designs)
l += "[sheet.css_tag()][RDSCREEN_NOBREAK]"
l += "<div class='statusDisplay'><b>[stored_research.organization] Research and Development Network</b>"
l += "Available points: [round(stored_research.research_points)] (+[round(stored_research.last_bitcoins * 60)] / minute)"
l += "Security protocols: [obj_flags & EMAGGED ? "<font color='red'>Disabled</font>" : "<font color='green'>Enabled</font>"]"
+10 -2
View File
@@ -93,7 +93,7 @@
description = "A refresher course on modern engineering technology."
prereq_ids = list("base")
design_ids = list("solarcontrol", "recharger", "powermonitor", "rped", "pacman", "adv_capacitor", "adv_scanning", "emitter", "high_cell", "adv_matter_bin",
"atmosalerts", "atmos_control", "recycler", "autolathe", "high_micro_laser", "nano_mani", "mesons", "thermomachine", "rad_collector", "tesla_coil", "grounding_rod", "apc_control", "cell_charger")
"atmosalerts", "atmos_control", "recycler", "autolathe", "high_micro_laser", "nano_mani", "mesons", "thermomachine", "rad_collector", "tesla_coil", "grounding_rod", "apc_control", "cell_charger", "power control", "airlock_board", "firelock_board", "airalarm_electronics", "firealarm_electronics")
research_cost = 7500
export_price = 5000
@@ -106,6 +106,15 @@
research_cost = 2500
export_price = 5000
/datum/techweb_node/anomaly
id = "anomaly_research"
display_name = "Anomaly Research"
description = "Unlock the potential of the mysterious anomalies that appear on station."
prereq_ids = list("adv_engi", "practical_bluespace")
design_ids = list("reactive_armour")
research_cost = 2500
export_price = 5000
/datum/techweb_node/high_efficiency
id = "high_efficiency"
display_name = "High Efficiency Parts"
@@ -153,7 +162,6 @@
research_cost = 5000
export_price = 5000
/datum/techweb_node/bluespace_power
id = "bluespace_power"
display_name = "Bluespace Power Technology"
@@ -448,8 +448,7 @@ datum/status_effect/stabilized/blue/on_remove()
else if(istype(O, /obj/item/stack/sheet/hairlesshide))
to_chat(owner, "<span class='warning'>[linked_extract] kept your hands wet! It wets [O]!</span>")
var/obj/item/stack/sheet/hairlesshide/HH = O
var/obj/item/stack/sheet/wetleather/WL = new(get_turf(HH))
WL.amount = HH.amount
new /obj/item/stack/sheet/wetleather(get_turf(HH), HH.amount)
qdel(HH)
..()
@@ -66,10 +66,8 @@ Charged extracts:
colour = "metal"
/obj/item/slimecross/charged/metal/do_effect(mob/user)
var/obj/item/stack/sheet/metal/M = new(get_turf(user))
M.amount = 25
var/obj/item/stack/sheet/plasteel/P = new(get_turf(user))
P.amount = 10
new /obj/item/stack/sheet/metal(get_turf(user), 25)
new /obj/item/stack/sheet/plasteel(get_turf(user), 10)
user.visible_message("<span class='notice'>[src] grows into a plethora of metals!</span>")
..()
@@ -85,8 +83,7 @@ Charged extracts:
colour = "dark purple"
/obj/item/slimecross/charged/darkpurple/do_effect(mob/user)
var/obj/item/stack/sheet/mineral/plasma/M = new(get_turf(user))
M.amount = 10
new /obj/item/stack/sheet/mineral/plasma(get_turf(user), 10)
user.visible_message("<span class='notice'>[src] produces a large amount of plasma!</span>")
..()
@@ -113,8 +110,7 @@ Charged extracts:
colour = "bluespace"
/obj/item/slimecross/charged/bluespace/do_effect(mob/user)
var/obj/item/stack/sheet/bluespace_crystal/M = new(get_turf(user))
M.amount = 10
new /obj/item/stack/sheet/bluespace_crystal(get_turf(user), 10)
user.visible_message("<span class='notice'>[src] produces several sheets of polycrystal!</span>")
..()
@@ -138,8 +134,7 @@ Charged extracts:
colour = "pyrite"
/obj/item/slimecross/charged/pyrite/do_effect(mob/user)
var/obj/item/stack/sheet/mineral/bananium/M = new(get_turf(user))
M.amount = 10
new /obj/item/stack/sheet/mineral/bananium(get_turf(user), 10)
user.visible_message("<span class='warning'>[src] solidifies with a horrifying banana stench!</span>")
..()
@@ -75,12 +75,7 @@ Industrial extracts:
/obj/item/slimecross/industrial/metal
colour = "metal"
plasmarequired = 3
itempath = /obj/item/stack/sheet/metal
/obj/item/slimecross/industrial/metal/do_after_spawn(obj/item/spawned)
var/obj/item/stack/sheet/metal/M = spawned
if(istype(M))
M.amount = 10
itempath = /obj/item/stack/sheet/metal/ten
/obj/item/slimecross/industrial/yellow
colour = "yellow"
+24 -30
View File
@@ -144,7 +144,6 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
var/smoke_spread = 0 //1 - harmless, 2 - harmful
var/smoke_amt = 0 //cropped at 10
var/critfailchance = 0
var/centcom_cancast = 1 //Whether or not the spell should be allowed on z2
action_icon = 'icons/mob/actions/actions_spells.dmi'
@@ -153,7 +152,6 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
base_action = /datum/action/spell_action/spell
/obj/effect/proc_holder/spell/proc/cast_check(skipcharge = 0,mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell
if(player_lock)
if(!user.mind || !(src in user.mind.spell_list) && !(src in user.mob_spell_list))
to_chat(user, "<span class='warning'>You shouldn't have this spell! Something's wrong.</span>")
@@ -168,15 +166,8 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
return 0
if(!skipcharge)
switch(charge_type)
if("recharge")
if(charge_counter < charge_max)
to_chat(user, still_recharging_msg)
return 0
if("charges")
if(!charge_counter)
to_chat(user, "<span class='notice'>[name] has no charges left.</span>")
return 0
if(!charge_check(user))
return 0
if(user.stat && !stat_allowed)
to_chat(user, "<span class='notice'>Not when you're incapacitated.</span>")
@@ -236,6 +227,20 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
action.UpdateButtonIcon()
return 1
/obj/effect/proc_holder/spell/proc/charge_check(mob/user, silent = FALSE)
switch(charge_type)
if("recharge")
if(charge_counter < charge_max)
if(!silent)
to_chat(user, still_recharging_msg)
return FALSE
if("charges")
if(!charge_counter)
if(!silent)
to_chat(user, "<span class='notice'>[name] has no charges left.</span>")
return FALSE
return TRUE
/obj/effect/proc_holder/spell/proc/invocation(mob/user = usr) //spelling the spell out and setting it on recharge/reducing charges amount
switch(invocation_type)
if("shout")
@@ -297,10 +302,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
recharging = TRUE
if(sound)
playMagSound()
if(prob(critfailchance))
critfail(targets)
else
cast(targets,user=user)
cast(targets,user=user)
after_cast(targets)
if(action)
action.UpdateButtonIcon()
@@ -349,9 +351,6 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
/obj/effect/proc_holder/spell/proc/cast(list/targets,mob/user = usr)
return
/obj/effect/proc_holder/spell/proc/critfail(list/targets)
return
/obj/effect/proc_holder/spell/proc/revert_cast(mob/user = usr) //resets recharge or readds a charge
switch(charge_type)
if("recharge")
@@ -500,25 +499,20 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
/obj/effect/proc_holder/spell/proc/can_cast(mob/user = usr)
if(((!user.mind) || !(src in user.mind.spell_list)) && !(src in user.mob_spell_list))
return 0
return FALSE
switch(charge_type)
if("recharge")
if(charge_counter < charge_max)
return 0
if("charges")
if(!charge_counter)
return 0
if(!charge_check(user,TRUE))
return FALSE
if(user.stat && !stat_allowed)
return 0
return FALSE
if(!ishuman(user))
if(clothes_req || human_req)
return 0
return FALSE
if(nonabstract_req && (isbrain(user) || ispAI(user)))
return 0
return 1
return FALSE
return TRUE
/obj/effect/proc_holder/spell/self //Targets only the caster. Good for buffs and heals, but probably not wise for fireballs (although they usually fireball themselves anyway, honke)
range = -1 //Duh
+5 -8
View File
@@ -13,10 +13,7 @@
throwforce = 0
throw_range = 0
throw_speed = 0
/obj/item/melee/touch_attack/Initialize()
attached_spell = loc
. = ..()
var/charges = 1
/obj/item/melee/touch_attack/attack(mob/target, mob/living/carbon/user)
if(!iscarbon(user)) //Look ma, no hands
@@ -29,13 +26,13 @@
/obj/item/melee/touch_attack/afterattack(atom/target, mob/user, proximity)
user.say(catchphrase)
playsound(get_turf(user), on_use_sound,50,1)
if(attached_spell)
attached_spell.attached_hand = null
qdel(src)
charges--
if(charges <= 0)
qdel(src)
/obj/item/melee/touch_attack/Destroy()
if(attached_spell)
attached_spell.attached_hand = null
attached_spell.on_hand_destroy(src)
return ..()
/obj/item/melee/touch_attack/disintegrate
@@ -1,37 +1,46 @@
/obj/effect/proc_holder/spell/targeted/touch
var/hand_path = "/obj/item/melee/touch_attack"
var/hand_path = /obj/item/melee/touch_attack
var/obj/item/melee/touch_attack/attached_hand = null
invocation_type = "none" //you scream on connecting, not summoning
include_user = 1
range = -1
/obj/effect/proc_holder/spell/targeted/touch/Click(mob/user = usr)
if(attached_hand)
qdel(attached_hand)
/obj/effect/proc_holder/spell/targeted/touch/proc/remove_hand(recharge = FALSE)
QDEL_NULL(attached_hand)
if(recharge)
charge_counter = charge_max
attached_hand = null
to_chat(user, "<span class='notice'>You draw the power out of your hand.</span>")
return FALSE
..()
/obj/effect/proc_holder/spell/targeted/touch/proc/on_hand_destroy(obj/item/melee/touch_attack/hand)
if(hand != attached_hand)
CRASH("Incorrect touch spell hand.")
//Start recharging.
attached_hand = null
recharging = TRUE
action.UpdateButtonIcon()
/obj/effect/proc_holder/spell/targeted/touch/cast(list/targets,mob/user = usr)
if(!QDELETED(attached_hand))
remove_hand(TRUE)
to_chat(user, "<span class='notice'>You draw the power out of your hand.</span>")
return
for(var/mob/living/carbon/C in targets)
if(!attached_hand)
if(!ChargeHand(C))
return FALSE
while(attached_hand)
charge_counter = 0
stoplag(1)
if(ChargeHand(C))
recharging = FALSE
return
/obj/effect/proc_holder/spell/targeted/touch/can_cast(mob/user = usr)
return ..() && attached_hand
/obj/effect/proc_holder/spell/targeted/touch/charge_check(mob/user,silent = FALSE)
if(!QDELETED(attached_hand)) //Charge doesn't matter when putting the hand away.
return TRUE
else
return ..()
/obj/effect/proc_holder/spell/targeted/touch/proc/ChargeHand(mob/living/carbon/user)
attached_hand = new hand_path(src)
attached_hand.attached_spell = src
if(!user.put_in_hands(attached_hand))
qdel(attached_hand)
charge_counter = charge_max
attached_hand = null
remove_hand(TRUE)
to_chat(user, "<span class='warning'>Your hands are full!</span>")
return FALSE
to_chat(user, "<span class='notice'>You channel the power of the spell to your hand.</span>")
@@ -41,7 +50,7 @@
/obj/effect/proc_holder/spell/targeted/touch/disintegrate
name = "Disintegrate"
desc = "This spell charges your hand with vile energy that can be used to violently explode victims."
hand_path = "/obj/item/melee/touch_attack/disintegrate"
hand_path = /obj/item/melee/touch_attack/disintegrate
school = "evocation"
charge_max = 600
@@ -53,7 +62,7 @@
/obj/effect/proc_holder/spell/targeted/touch/flesh_to_stone
name = "Flesh to Stone"
desc = "This spell charges your hand with the power to turn victims into inert statues for a long period of time."
hand_path = "/obj/item/melee/touch_attack/fleshtostone"
hand_path = /obj/item/melee/touch_attack/fleshtostone
school = "transmutation"
charge_max = 600
+2
View File
@@ -42,6 +42,8 @@ Notes:
/datum/tooltip/New(client/C)
if (C)
owner = C
var/datum/asset/stuff = get_asset_datum(/datum/asset/simple/jquery)
stuff.send(owner)
owner << browse(file2text('code/modules/tooltip/tooltip.html'), "window=[control]")
..()
+2 -2
View File
@@ -453,7 +453,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/ammo/shotgun/buck
name = "12g Buckshot Drum"
desc = "An additional 8-round buckshot magazine for use with the Bulldog shotgun. Front towards enemy."
item = /obj/item/ammo_box/magazine/m12g/buckshot
item = /obj/item/ammo_box/magazine/m12g
/datum/uplink_item/ammo/shotgun/slug
name = "12g Slug Drum"
@@ -466,7 +466,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
name = "12g Stun Slug Drum"
desc = "An alternative 8-round stun slug magazine for use with the Bulldog shotgun. \
Saying that they're completely non-lethal would be lying."
item = /obj/item/ammo_box/magazine/m12g
item = /obj/item/ammo_box/magazine/m12g/stun
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/shotgun/dragon
+3 -3
View File
@@ -114,11 +114,11 @@
/obj/item/clothing/mask/muzzle = 2)
premium = list(/obj/item/clothing/suit/pirate/captain = 2,
/obj/item/clothing/head/pirate/captain = 2,
/obj/item/clothing/head/helmet/roman = 1,
/obj/item/clothing/head/helmet/roman/legionaire = 1,
/obj/item/clothing/head/helmet/roman/fake = 1,
/obj/item/clothing/head/helmet/roman/legionaire/fake = 1,
/obj/item/clothing/under/roman = 1,
/obj/item/clothing/shoes/roman = 1,
/obj/item/shield/riot/roman = 1,
/obj/item/shield/riot/roman/fake = 1,
/obj/item/skub = 1)
refill_canister = /obj/item/vending_refill/autodrobe
+3 -2
View File
@@ -19,6 +19,7 @@
/obj/item/reagent_containers/food/drinks/bottle/orangejuice = 4,
/obj/item/reagent_containers/food/drinks/bottle/tomatojuice = 4,
/obj/item/reagent_containers/food/drinks/bottle/limejuice = 4,
/obj/item/reagent_containers/food/drinks/bottle/menthol = 4,
/obj/item/reagent_containers/food/drinks/bottle/cream = 4,
/obj/item/reagent_containers/food/drinks/soda_cans/tonic = 8,
/obj/item/reagent_containers/food/drinks/soda_cans/cola = 8,
@@ -37,5 +38,5 @@
/obj/item/vending_refill/boozeomat
machine_name = "Booze-O-Mat"
icon_state = "refill_booze"
charges = list(58, 4, 0)//of 174 standard, 12 contraband
init_charges = list(58, 4, 0)
charges = list(59, 4, 0)//of 178 standard, 12 contraband
init_charges = list(59, 4, 0)
+4 -1
View File
@@ -13,7 +13,10 @@
/obj/item/stock_parts/cell/high = 10,
/obj/item/electronics/airlock = 10,
/obj/item/electronics/apc = 10,
/obj/item/electronics/airalarm = 10)
/obj/item/electronics/airalarm = 10,
/obj/item/electronics/firealarm = 10,
/obj/item/electronics/firelock = 10
)
contraband = list(/obj/item/stock_parts/cell/potato = 3)
premium = list(/obj/item/storage/belt/utility = 3,
/obj/item/storage/box/smart_metal_foam = 1)