Merge branch 'master' into upstream-merge-37423
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
. = ..()
|
||||
|
||||
@@ -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)
|
||||
..()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
@@ -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"])
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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)
|
||||
@@ -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]
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
..()
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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 you’ll 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 you’ll 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)
|
||||
..()
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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>"]"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]")
|
||||
|
||||
..()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user