Merge branch 'master' into upstream-merge-37406

This commit is contained in:
LetterJay
2018-05-13 03:28:37 -05:00
committed by GitHub
67 changed files with 964 additions and 432 deletions
+1 -1
View File
@@ -27,7 +27,7 @@
if(isnewplayer(M))
continue
if (M.stat == DEAD || (M.client && M.client.holder && (M.client.prefs.chat_toggles & CHAT_DEAD))) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above
M.show_message(rendered, 2)
to_chat(M, rendered)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Dsay") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+2 -4
View File
@@ -33,10 +33,8 @@
desc = "A sword humming with unholy energy. It glows with a dim red light."
icon_state = "cultblade"
item_state = "cultblade"
lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi'
righthand_file = 'icons/mob/inhands/64x64_righthand.dmi'
inhand_x_dimension = 64
inhand_y_dimension = 64
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
flags_1 = CONDUCT_1
sharpness = IS_SHARP
w_class = WEIGHT_CLASS_BULKY
+1 -1
View File
@@ -190,7 +190,7 @@
return ..()
/mob/living/simple_animal/hostile/morph/AttackingTarget()
if(!melee_damage_disguised)
if(morphed && !melee_damage_disguised)
to_chat(src, "<span class='warning'>You can not attack while disguised!</span>")
return
if(isliving(target)) //Eat Corpses to regen health
+2 -1
View File
@@ -111,7 +111,7 @@ Code:
var/obj/item/assembly/signaler/signaler2 = W
if(secured && signaler2.secured)
code = signaler2.code
frequency = signaler2.frequency
set_frequency(signaler2.frequency)
to_chat(user, "You transfer the frequency and code of \the [signaler2.name] to \the [name]")
..()
@@ -186,6 +186,7 @@ Code:
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
var/anomaly_type = /obj/effect/anomaly
/obj/item/assembly/signaler/anomaly/receive_signal(datum/signal/signal)
if(!signal)
@@ -191,7 +191,7 @@
//fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. Again.
/datum/gas_reaction/fusion
exclude = FALSE
exclude = TRUE
priority = 2
name = "Plasmic Fusion"
id = "fusion"
+1 -1
View File
@@ -101,7 +101,7 @@
export_types = list(/obj/machinery/iv_drip)
/datum/export/large/barrier
cost = 325
cost = 100
unit_name = "security barrier"
export_types = list(/obj/item/grenade/barrier, /obj/structure/barricade/security)
+3 -2
View File
@@ -1649,8 +1649,9 @@
. = ..()
if(prob(50))
var/mob/living/simple_animal/pet/dog/corgi/D = locate() in .
qdel(D)
new /mob/living/simple_animal/pet/dog/corgi/Lisa(.)
if(D.gender == FEMALE)
qdel(D)
new /mob/living/simple_animal/pet/dog/corgi/Lisa(.)
/datum/supply_pack/critter/cow
name = "Cow Crate"
+232 -58
View File
@@ -161,8 +161,12 @@ GLOBAL_LIST_EMPTY(asset_datums)
return new type()
return GLOB.asset_datums[type]
/datum/asset
var/_abstract = /datum/asset
/datum/asset/New()
GLOB.asset_datums[type] = src
register()
/datum/asset/proc/register()
return
@@ -170,20 +174,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 +366,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 +418,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,6 +495,9 @@ GLOBAL_LIST_EMPTY(asset_datums)
"changelog.css" = 'html/changelog.css'
)
/datum/asset/group/goonchat
children = list(/datum/asset/simple/goonchat, /datum/asset/spritesheet/goonchat)
/datum/asset/simple/goonchat
verify = FALSE
assets = list(
@@ -350,6 +513,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 +543,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 +575,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 +582,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 ..()
+8 -6
View File
@@ -81,12 +81,14 @@
/obj/item/clothing/equipped(mob/user, slot)
..()
if (!istype(user))
return
if(slot_flags & slotdefine2slotbit(slot)) //Was equipped to a valid slot for this item?
for(var/variable in user_vars_to_edit)
if(variable in user.vars)
user_vars_remembered[variable] = user.vars[variable]
user.vars[variable] = user_vars_to_edit[variable]
if (LAZYLEN(user_vars_to_edit))
for(var/variable in user_vars_to_edit)
if(variable in user.vars)
LAZYSET(user_vars_remembered, variable, user.vars[variable])
user.vv_edit_var(variable, user_vars_to_edit[variable])
/obj/item/clothing/examine(mob/user)
..()
@@ -285,4 +287,4 @@ BLIND // can't see anything
Shreds.desc = "The sad remains of what used to be [name]."
deconstruct(FALSE)
else
..()
..()
@@ -365,6 +365,7 @@
scan_reagents = 1
flags_1 = NODROP_1
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
resistance_flags = LAVA_PROOF | FIRE_PROOF
/obj/item/clothing/glasses/godeye/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, src) && W != src && W.loc == user)
@@ -93,7 +93,7 @@
MA.alpha = 180
MA.maptext = "[strength]k"
MA.color = "#64C864"
MA.layer = AREA_LAYER
MA.layer = FLY_LAYER
pic.appearance = MA
flick_overlay(pic, list(user.client), 8)
+8
View File
@@ -158,12 +158,20 @@
strip_delay = 100
dog_fashion = null
/obj/item/clothing/head/helmet/roman/fake
desc = "An ancient helmet made of plastic and leather."
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
/obj/item/clothing/head/helmet/roman/legionaire
name = "roman legionaire helmet"
desc = "An ancient helmet made of bronze and leather. Has a red crest on top of it."
icon_state = "roman_c"
item_state = "roman_c"
/obj/item/clothing/head/helmet/roman/legionaire/fake
desc = "An ancient helmet made of plastic and leather. Has a red crest on top of it."
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
/obj/item/clothing/head/helmet/gladiator
name = "gladiator helmet"
desc = "Ave, Imperator, morituri te salutant."
+24 -1
View File
@@ -321,4 +321,27 @@
name = "headress of Nemes"
desc = "Lavish space tomb not included."
icon_state = "nemes_headdress"
icon_state = "nemes_headdress"
icon_state = "nemes_headdress"
/obj/item/clothing/head/frenchberet
name = "french beret"
desc = "A quality beret, infused with the aroma of chain-smoking, wine-swilling Parisians. You feel less inclined to engage military conflict, for some reason."
icon_state = "beretblack"
/obj/item/clothing/head/frenchberet/speechModification(M)
if(copytext(M, 1, 2) != "*")
M = " [M]"
var/list/french_words = strings("french_replacement.json", "french")
for(var/key in french_words)
var/value = french_words[key]
if(islist(value))
value = pick(value)
M = replacetextEx(M, " [uppertext(key)]", " [uppertext(value)]")
M = replacetextEx(M, " [capitalize(key)]", " [capitalize(value)]")
M = replacetextEx(M, " [key]", " [value]")
if(prob(3))
M += pick(" Honh honh honh!"," Honh!"," Zut Alors!")
return trim(M)
+1 -1
View File
@@ -47,7 +47,7 @@
/obj/item/clothing/mask/fakemoustache/italian/speechModification(M)
if(copytext(M, 1, 2) != "*")
M = " [M]"
var/list/italian_words = strings("word_replacement.json", "italian")
var/list/italian_words = strings("italian_replacement.json", "italian")
for(var/key in italian_words)
var/value = italian_words[key]
-180
View File
@@ -165,186 +165,6 @@
. = ..()
allowed = GLOB.detective_vest_allowed
//Reactive armor
/obj/item/clothing/suit/armor/reactive
name = "reactive armor"
desc = "Doesn't seem to do much for some reason."
var/active = 0
var/reactivearmor_cooldown_duration = 0 //cooldown specific to reactive armor
var/reactivearmor_cooldown = 0
icon_state = "reactiveoff"
item_state = "reactiveoff"
blood_overlay_type = "armor"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
actions_types = list(/datum/action/item_action/toggle)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
hit_reaction_chance = 50
/obj/item/clothing/suit/armor/reactive/attack_self(mob/user)
src.active = !( src.active )
if (src.active)
to_chat(user, "<span class='notice'>[src] is now active.</span>")
src.icon_state = "reactive"
src.item_state = "reactive"
else
to_chat(user, "<span class='notice'>[src] is now inactive.</span>")
src.icon_state = "reactiveoff"
src.item_state = "reactiveoff"
src.add_fingerprint(user)
return
/obj/item/clothing/suit/armor/reactive/emp_act(severity)
active = 0
src.icon_state = "reactiveoff"
src.item_state = "reactiveoff"
reactivearmor_cooldown = world.time + 200
..()
//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!)
/obj/item/clothing/suit/armor/reactive/teleport
name = "reactive teleport armor"
desc = "Someone separated our Research Director from his own head!"
var/tele_range = 6
var/rad_amount= 15
reactivearmor_cooldown_duration = 100
/obj/item/clothing/suit/armor/reactive/teleport/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
var/mob/living/carbon/human/H = owner
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive teleport system is still recharging! It fails to teleport [H]!</span>")
return
owner.visible_message("<span class='danger'>The reactive teleport system flings [H] clear of [attack_text], shutting itself off in the process!</span>")
var/list/turfs = new/list()
for(var/turf/T in orange(tele_range, H))
if(T.density)
continue
if(T.x>world.maxx-tele_range || T.x<tele_range)
continue
if(T.y>world.maxy-tele_range || T.y<tele_range)
continue
turfs += T
if(!turfs.len)
turfs += pick(/turf in orange(tele_range, H))
var/turf/picked = pick(turfs)
if(!isturf(picked))
return
H.forceMove(picked)
H.rad_act(rad_amount)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return 0
/obj/item/clothing/suit/armor/reactive/fire
name = "reactive incendiary armor"
desc = "An experimental suit of armor with a reactive sensor array rigged to a flame emitter. For the stylish pyromaniac."
/obj/item/clothing/suit/armor/reactive/fire/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive incendiary armor on [owner] activates, but fails to send out flames as it is still recharging its flame jets!</span>")
return
owner.visible_message("<span class='danger'>[src] blocks [attack_text], sending out jets of flame!</span>")
for(var/mob/living/carbon/C in range(6, owner))
if(C != owner)
C.fire_stacks += 8
C.IgniteMob()
owner.fire_stacks = -20
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return 0
/obj/item/clothing/suit/armor/reactive/stealth
name = "reactive stealth armor"
desc = "An experimental suit of armor that renders the wearer invisible on detection of imminent harm, and creates a decoy that runs away from the owner. You can't fight what you can't see."
/obj/item/clothing/suit/armor/reactive/stealth/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive stealth system on [owner] activates, but is still recharging its holographic emitters!</span>")
return
var/mob/living/simple_animal/hostile/illusion/escape/E = new(owner.loc)
E.Copy_Parent(owner, 50)
E.GiveTarget(owner) //so it starts running right away
E.Goto(owner, E.move_to_delay, E.minimum_distance)
owner.alpha = 0
owner.visible_message("<span class='danger'>[owner] is hit by [attack_text] in the chest!</span>") //We pretend to be hit, since blocking it would stop the message otherwise
spawn(40)
owner.alpha = initial(owner.alpha)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
/obj/item/clothing/suit/armor/reactive/tesla
name = "reactive tesla armor"
desc = "An experimental suit of armor with sensitive detectors hooked up to a huge capacitor grid, with emitters strutting out of it. Zap."
siemens_coefficient = -1
var/tesla_power = 25000
var/tesla_range = 20
var/tesla_boom = FALSE
var/tesla_stun = FALSE
/obj/item/clothing/suit/armor/reactive/tesla/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread
sparks.set_up(1, 1, src)
sparks.start()
owner.visible_message("<span class='danger'>The tesla capacitors on [owner]'s reactive tesla armor are still recharging! The armor merely emits some sparks.</span>")
return
owner.visible_message("<span class='danger'>[src] blocks [attack_text], sending out arcs of lightning!</span>")
tesla_zap(owner,tesla_range,tesla_power,tesla_boom, tesla_stun)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
/obj/item/clothing/suit/armor/reactive/table
name = "reactive table armor"
desc = "If you can't beat the memes, embrace them."
var/tele_range = 10
/obj/item/clothing/suit/armor/reactive/table/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
var/mob/living/carbon/human/H = owner
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive table armor's fabricators are still on cooldown!</span>")
return
owner.visible_message("<span class='danger'>The reactive teleport system flings [H] clear of [attack_text] and slams them into a fabricated table!</span>")
owner.visible_message("<font color='red' size='3'>[H] GOES ON THE TABLE!!!</font>")
owner.Knockdown(40)
var/list/turfs = new/list()
for(var/turf/T in orange(tele_range, H))
if(T.density)
continue
if(T.x>world.maxx-tele_range || T.x<tele_range)
continue
if(T.y>world.maxy-tele_range || T.y<tele_range)
continue
turfs += T
if(!turfs.len)
turfs += pick(/turf in orange(tele_range, H))
var/turf/picked = pick(turfs)
if(!isturf(picked))
return
H.forceMove(picked)
new /obj/structure/table(get_turf(owner))
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return 0
/obj/item/clothing/suit/armor/reactive/table/emp_act()
return
//All of the armor below is mostly unused
/obj/item/clothing/suit/armor/centcom
@@ -0,0 +1,235 @@
/obj/item/reactive_armour_shell
name = "reactive armour shell"
desc = "An experimental suit of armour, awaiting installation of an anomaly core."
icon_state = "reactiveoff"
icon = 'icons/obj/clothing/suits.dmi'
w_class = WEIGHT_CLASS_BULKY
/obj/item/reactive_armour_shell/attackby(obj/item/I, mob/user, params)
..()
var/static/list/anomaly_armour_types = list(
/obj/effect/anomaly/grav = /obj/item/clothing/suit/armor/reactive/repulse,
/obj/effect/anomaly/flux = /obj/item/clothing/suit/armor/reactive/tesla,
/obj/effect/anomaly/bluespace = /obj/item/clothing/suit/armor/reactive/teleport,
/obj/effect/anomaly/pyro = /obj/item/clothing/suit/armor/reactive/fire)
if(istype(I, /obj/item/assembly/signaler/anomaly))
var/obj/item/assembly/signaler/anomaly/A = I
var/armour_path = anomaly_armour_types[A.anomaly_type]
if(!armour_path)
armour_path = /obj/item/clothing/suit/armor/reactive/stealth //Lets not cheat the player if an anomaly type doesnt have its own armour coded
to_chat(user, "You insert [A] into the chest plate, and the armour gently hums to life.")
new armour_path(get_turf(src))
qdel(src)
qdel(A)
//Reactive armor
/obj/item/clothing/suit/armor/reactive
name = "reactive armor"
desc = "Doesn't seem to do much for some reason."
var/active = 0
var/reactivearmor_cooldown_duration = 0 //cooldown specific to reactive armor
var/reactivearmor_cooldown = 0
icon_state = "reactiveoff"
item_state = "reactiveoff"
blood_overlay_type = "armor"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
actions_types = list(/datum/action/item_action/toggle)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
hit_reaction_chance = 50
/obj/item/clothing/suit/armor/reactive/attack_self(mob/user)
active = !(active)
if(active)
to_chat(user, "<span class='notice'>[src] is now active.</span>")
icon_state = "reactive"
item_state = "reactive"
else
to_chat(user, "<span class='notice'>[src] is now inactive.</span>")
icon_state = "reactiveoff"
item_state = "reactiveoff"
add_fingerprint(user)
return
/obj/item/clothing/suit/armor/reactive/emp_act(severity)
active = 0
icon_state = "reactiveoff"
item_state = "reactiveoff"
reactivearmor_cooldown = world.time + 200
..()
//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!)
/obj/item/clothing/suit/armor/reactive/teleport
name = "reactive teleport armor"
desc = "Someone separated our Research Director from his own head!"
var/tele_range = 6
var/rad_amount= 15
reactivearmor_cooldown_duration = 100
/obj/item/clothing/suit/armor/reactive/teleport/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
var/mob/living/carbon/human/H = owner
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive teleport system is still recharging! It fails to teleport [H]!</span>")
return
owner.visible_message("<span class='danger'>The reactive teleport system flings [H] clear of [attack_text], shutting itself off in the process!</span>")
var/list/turfs = new/list()
for(var/turf/T in orange(tele_range, H))
if(T.density)
continue
if(T.x>world.maxx-tele_range || T.x<tele_range)
continue
if(T.y>world.maxy-tele_range || T.y<tele_range)
continue
turfs += T
if(!turfs.len)
turfs += pick(/turf in orange(tele_range, H))
var/turf/picked = pick(turfs)
if(!isturf(picked))
return
H.forceMove(picked)
H.rad_act(rad_amount)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return 0
//Fire
/obj/item/clothing/suit/armor/reactive/fire
name = "reactive incendiary armor"
desc = "An experimental suit of armor with a reactive sensor array rigged to a flame emitter. For the stylish pyromaniac."
/obj/item/clothing/suit/armor/reactive/fire/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive incendiary armor on [owner] activates, but fails to send out flames as it is still recharging its flame jets!</span>")
return
owner.visible_message("<span class='danger'>[src] blocks [attack_text], sending out jets of flame!</span>")
for(var/mob/living/carbon/C in range(6, owner))
if(C != owner)
C.fire_stacks += 8
C.IgniteMob()
owner.fire_stacks = -20
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return 0
//Stealth
/obj/item/clothing/suit/armor/reactive/stealth
name = "reactive stealth armor"
desc = "An experimental suit of armor that renders the wearer invisible on detection of imminent harm, and creates a decoy that runs away from the owner. You can't fight what you can't see."
/obj/item/clothing/suit/armor/reactive/stealth/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive stealth system on [owner] activates, but is still recharging its holographic emitters!</span>")
return
var/mob/living/simple_animal/hostile/illusion/escape/E = new(owner.loc)
E.Copy_Parent(owner, 50)
E.GiveTarget(owner) //so it starts running right away
E.Goto(owner, E.move_to_delay, E.minimum_distance)
owner.alpha = 0
owner.visible_message("<span class='danger'>[owner] is hit by [attack_text] in the chest!</span>") //We pretend to be hit, since blocking it would stop the message otherwise
spawn(40)
owner.alpha = initial(owner.alpha)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
//Tesla
/obj/item/clothing/suit/armor/reactive/tesla
name = "reactive tesla armor"
desc = "An experimental suit of armor with sensitive detectors hooked up to a huge capacitor grid, with emitters strutting out of it. Zap."
siemens_coefficient = -1
var/tesla_power = 25000
var/tesla_range = 20
var/tesla_boom = FALSE
var/tesla_stun = FALSE
/obj/item/clothing/suit/armor/reactive/tesla/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread
sparks.set_up(1, 1, src)
sparks.start()
owner.visible_message("<span class='danger'>The tesla capacitors on [owner]'s reactive tesla armor are still recharging! The armor merely emits some sparks.</span>")
return
owner.visible_message("<span class='danger'>[src] blocks [attack_text], sending out arcs of lightning!</span>")
tesla_zap(owner,tesla_range,tesla_power,tesla_boom, tesla_stun)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
//Repulse
/obj/item/clothing/suit/armor/reactive/repulse
name = "reactive repulse armor"
desc = "An experimental suit of armor that violently throws back attackers."
/obj/item/clothing/suit/armor/reactive/repulse/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The repulse generator is still recharging!</span>")
return 0
owner.visible_message("<span class='danger'>[src] blocks [attack_text], converting the attack into a wave of force!</span>")
var/turf/T = get_turf(owner)
var/list/thrown_items = list()
for(var/atom/movable/A in range(T, 7))
if(A == owner || A.anchored || thrown_items[A])
continue
var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(A, src)))
A.throw_at(throwtarget,10,1)
thrown_items[A] = A
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
/obj/item/clothing/suit/armor/reactive/table
name = "reactive table armor"
desc = "If you can't beat the memes, embrace them."
var/tele_range = 10
/obj/item/clothing/suit/armor/reactive/table/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
if(prob(hit_reaction_chance))
var/mob/living/carbon/human/H = owner
if(world.time < reactivearmor_cooldown)
owner.visible_message("<span class='danger'>The reactive table armor's fabricators are still on cooldown!</span>")
return
owner.visible_message("<span class='danger'>The reactive teleport system flings [H] clear of [attack_text] and slams them into a fabricated table!</span>")
owner.visible_message("<font color='red' size='3'>[H] GOES ON THE TABLE!!!</font>")
owner.Knockdown(40)
var/list/turfs = new/list()
for(var/turf/T in orange(tele_range, H))
if(T.density)
continue
if(T.x>world.maxx-tele_range || T.x<tele_range)
continue
if(T.y>world.maxy-tele_range || T.y<tele_range)
continue
turfs += T
if(!turfs.len)
turfs += pick(/turf in orange(tele_range, H))
var/turf/picked = pick(turfs)
if(!isturf(picked))
return
H.forceMove(picked)
new /obj/structure/table(get_turf(owner))
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
return 0
/obj/item/clothing/suit/armor/reactive/table/emp_act()
return
+4 -2
View File
@@ -15,8 +15,10 @@
search = findtext(text, ":", pos+1)
if(search)
emoji = lowertext(copytext(text, pos+1, search))
if(emoji in emojis)
parsed += icon2html('icons/emoji.dmi', world, emoji)
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/goonchat)
var/tag = sheet.icon_tag("emoji-[emoji]")
if(tag)
parsed += tag
pos = search + 1
else
parsed += copytext(text, pos, search)
+1 -2
View File
@@ -46,8 +46,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
if(!owner)
return
var/datum/asset/stuff = get_asset_datum(/datum/asset/simple/goonchat)
stuff.register()
var/datum/asset/stuff = get_asset_datum(/datum/asset/group/goonchat)
stuff.send(owner)
owner << browse(file('code/modules/goonchat/browserassets/html/browserOutput.html'), "window=browseroutput")
@@ -6,6 +6,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="font-awesome.css" />
<link rel="stylesheet" type="text/css" href="browserOutput.css" />
<link rel="stylesheet" type="text/css" href="spritesheet_chat.css" />
<script type="text/javascript" src="errorHandler.js"></script>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="json2.min.js"></script>
+9 -1
View File
@@ -70,6 +70,7 @@
begin_month = DECEMBER
end_day = 2
end_month = JANUARY
drone_hat = /obj/item/clothing/head/festive
/datum/holiday/new_year/getStationPrefix()
return pick("Party","New","Hangover","Resolution")
@@ -78,6 +79,7 @@
name = "Groundhog Day"
begin_day = 2
begin_month = FEBRUARY
drone_hat = /obj/item/clothing/head/helmet/space/chronos
/datum/holiday/valentines
name = VALENTINES
@@ -92,6 +94,7 @@
name = "Birthday of Space Station 13"
begin_day = 16
begin_month = FEBRUARY
drone_hat = /obj/item/clothing/head/festive
/datum/holiday/birthday/greet()
var/game_age = text2num(time2text(world.timeofday, "YY")) - 3
@@ -202,6 +205,7 @@
name = "UFO Day"
begin_day = 2
begin_month = JULY
drone_hat = /obj/item/clothing/mask/facehugger/dead
/datum/holiday/UFO/getStationPrefix() //Is such a thing even possible?
return pick("Ayy","Truth","Tsoukalos","Mulder") //Yes it is!
@@ -272,11 +276,13 @@
name = "Smiling Day"
begin_day = 7
begin_month = OCTOBER
drone_hat = /obj/item/clothing/head/papersack/smiley
/datum/holiday/boss
name = "Boss' Day"
begin_day = 16
begin_month = OCTOBER
drone_hat = /obj/item/clothing/head/that
/datum/holiday/halloween
name = HALLOWEEN
@@ -305,6 +311,7 @@
name = "Flowers Day"
begin_day = 19
begin_month = NOVEMBER
drone_hat = /obj/item/reagent_containers/food/snacks/grown/moonflower
/datum/holiday/hello
name = "Saying-'Hello' Day"
@@ -312,7 +319,7 @@
begin_month = NOVEMBER
/datum/holiday/hello/greet()
return "[pick(list("Aloha", "Bonjour", "Hello", "Hi", "Greetings", "Salutations", "Bienvenidos", "Hola", "Howdy"))]! " + ..()
return "[pick(list("Aloha", "Bonjour", "Hello", "Hi", "Greetings", "Salutations", "Bienvenidos", "Hola", "Howdy", "Ni hao", "Guten Tag", "Konnichiwa", "G'day cunt"))]! " + ..()
/datum/holiday/human_rights
name = "Human-Rights Day"
@@ -323,6 +330,7 @@
name = "Monkey Day"
begin_day = 14
begin_month = DECEMBER
drone_hat = /obj/item/clothing/mask/gas/monkeymask
/datum/holiday/thanksgiving
name = "Thanksgiving in the United States"
@@ -142,21 +142,18 @@
/obj/item/integrated_circuit/converter/concatenator
name = "concatenator"
desc = "This joins many strings together to get one big string."
desc = "This can join up to 8 strings together to get one big string."
complexity = 4
inputs = list(
"A" = IC_PINTYPE_STRING,
"B" = IC_PINTYPE_STRING,
"C" = IC_PINTYPE_STRING,
"D" = IC_PINTYPE_STRING,
"E" = IC_PINTYPE_STRING,
"F" = IC_PINTYPE_STRING,
"G" = IC_PINTYPE_STRING,
"H" = IC_PINTYPE_STRING
)
inputs = list()
outputs = list("result" = IC_PINTYPE_STRING)
activators = list("concatenate" = IC_PINTYPE_PULSE_IN, "on concatenated" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
var/number_of_pins = 8
/obj/item/integrated_circuit/converter/concatenator/Initialize()
for(var/i = 1 to number_of_pins)
inputs["input [i]"] = IC_PINTYPE_STRING
. = ..()
/obj/item/integrated_circuit/converter/concatenator/do_work()
var/result = null
@@ -169,6 +166,18 @@
push_data()
activate_pin(2)
/obj/item/integrated_circuit/converter/concatenator/small
name = "small concatenator"
desc = "This can join up to 4 strings together to get one big string."
complexity = 2
number_of_pins = 4
/obj/item/integrated_circuit/converter/concatenator/large
name = "large concatenator"
desc = "This can join up to 16 strings together to get one very big string."
complexity = 6
number_of_pins = 16
/obj/item/integrated_circuit/converter/separator
name = "separator"
desc = "This splits as single string into two at the relative split point."
@@ -203,6 +212,32 @@
activate_pin(2)
/obj/item/integrated_circuit/converter/indexer
name = "indexer"
desc = "This circuit takes a string and an index value, then returns the character found at in the string at the given index."
extended_desc = "Make sure the index is not longer or shorter than the string length. If you don't, the circuit will return empty."
icon_state = "split"
complexity = 4
inputs = list(
"string to index" = IC_PINTYPE_STRING,
"index" = IC_PINTYPE_NUMBER,
)
outputs = list(
"found character" = IC_PINTYPE_STRING
)
activators = list("index" = IC_PINTYPE_PULSE_IN, "on indexed" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/indexer/do_work()
var/strin = get_pin_data(IC_INPUT, 1)
var/ind = get_pin_data(IC_INPUT, 2)
if(ind > 0 && ind <= length(strin))
set_pin_data(IC_OUTPUT, 1, strin[ind])
else
set_pin_data(IC_OUTPUT, 1, "")
push_data()
activate_pin(2)
/obj/item/integrated_circuit/converter/findstring
name = "find text"
desc = "This gives position of sample in the string. Or returns 0."
@@ -216,14 +251,38 @@
outputs = list(
"position" = IC_PINTYPE_NUMBER
)
activators = list("search" = IC_PINTYPE_PULSE_IN, "after search" = IC_PINTYPE_PULSE_OUT)
activators = list("search" = IC_PINTYPE_PULSE_IN, "after search" = IC_PINTYPE_PULSE_OUT, "found" = IC_PINTYPE_PULSE_OUT, "not found" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/findstring/do_work()
var/position = findtext(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2))
set_pin_data(IC_OUTPUT, 1, findtext(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2)) )
set_pin_data(IC_OUTPUT, 1, position)
push_data()
activate_pin(2)
if(position)
activate_pin(3)
else
activate_pin(4)
/obj/item/integrated_circuit/converter/stringlength
name = "get length"
desc = "This circuit will return the number of characters in a string."
complexity = 1
inputs = list(
"string" = IC_PINTYPE_STRING
)
outputs = list(
"length" = IC_PINTYPE_NUMBER
)
activators = list("get length" = IC_PINTYPE_PULSE_IN, "on acquisition" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/stringlength/do_work()
set_pin_data(IC_OUTPUT, 1, length(get_pin_data(IC_INPUT, 1)))
push_data()
activate_pin(2)
@@ -232,7 +291,8 @@
name = "string exploder"
desc = "This splits a single string into a list of strings."
extended_desc = "This circuit splits a given string into a list of strings based on the string and given delimiter. \
For example, 'eat this burger' will be converted to list('eat','this','burger')."
For example, 'eat this burger' will be converted to list('eat','this','burger'). Leave the delimiter null to get a list \
of every individual character."
icon_state = "split"
complexity = 4
inputs = list(
@@ -248,7 +308,10 @@
/obj/item/integrated_circuit/converter/exploders/do_work()
var/strin = get_pin_data(IC_INPUT, 1)
var/delimiter = get_pin_data(IC_INPUT, 2)
set_pin_data(IC_OUTPUT, 1, splittext(strin, delimiter))
if(delimiter == null)
set_pin_data(IC_OUTPUT, 1, string2charlist(strin))
else
set_pin_data(IC_OUTPUT, 1, splittext(strin, delimiter))
push_data()
activate_pin(2)
+8 -3
View File
@@ -226,9 +226,14 @@ GLOBAL_PROTECT(exp_to_update)
if(!rolefound)
play_records["Unknown"] += minutes
else
play_records[EXP_TYPE_GHOST] += minutes
if(announce_changes)
to_chat(src,"<span class='notice'>You got: [minutes] Ghost EXP!</span>")
if(holder && !holder.deadmined)
play_records[EXP_TYPE_ADMIN] += minutes
if(announce_changes)
to_chat(src,"<span class='notice'>You got: [minutes] Admin EXP!</span>")
else
play_records[EXP_TYPE_GHOST] += minutes
if(announce_changes)
to_chat(src,"<span class='notice'>You got: [minutes] Ghost EXP!</span>")
else if(isobserver(mob))
play_records[EXP_TYPE_GHOST] += minutes
if(announce_changes)
+1 -1
View File
@@ -91,7 +91,7 @@ Mime
uniform = /obj/item/clothing/under/rank/mime
mask = /obj/item/clothing/mask/gas/mime
gloves = /obj/item/clothing/gloves/color/white
head = /obj/item/clothing/head/beret
head = /obj/item/clothing/head/frenchberet
suit = /obj/item/clothing/suit/suspenders
backpack_contents = list(/obj/item/reagent_containers/food/drinks/bottle/bottleofnothing=1)
+2 -1
View File
@@ -35,7 +35,8 @@
return TRUE
/datum/language/proc/get_icon()
return "[icon2html(icon, world, icon_state)]"
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/goonchat)
return sheet.icon_tag("language-[icon_state]")
/datum/language/proc/get_random_name(gender, name_count=2, syllable_count=4, syllable_divisor=2)
if(!syllables || !syllables.len)
+4 -1
View File
@@ -326,7 +326,10 @@
I.plane = initial(I.plane)
I.appearance_flags &= ~NO_CLIENT_COLOR
if(!no_move && !(I.flags_1 & DROPDEL_1)) //item may be moved/qdel'd immedietely, don't bother moving it
I.forceMove(newloc)
if (isnull(newloc))
I.moveToNullspace()
else
I.forceMove(newloc)
I.dropped(src)
return TRUE
+2 -1
View File
@@ -13,7 +13,8 @@
message = T.TongueSpeech(message)
if(wear_mask)
message = wear_mask.speechModification(message)
if(head)
message = head.speechModification(message)
return message
/mob/living/carbon/can_speak_vocal(message)
+8 -10
View File
@@ -407,16 +407,14 @@
*/
//Recursive function to find everything a mob is holding. Really shitty proc tbh.
/mob/living/get_contents()
. = list()
. |= list(src)
for(var/obj/o in .)
var/list/newlist = list()
o.SendSignal(COMSIG_TRY_STORAGE_RETURN_INVENTORY, newlist)
. |= newlist
for(var/obj/item/clothing/under/U in .)
. |= U.contents
for(var/obj/item/folder/F in .)
. |= F.contents
var/list/ret = list()
ret |= contents //add our contents
for(var/i in ret.Copy()) //iterate storage objects
var/atom/A = i
A.SendSignal(COMSIG_TRY_STORAGE_RETURN_INVENTORY, ret)
for(var/obj/item/folder/F in ret.Copy()) //very snowflakey-ly iterate folders
ret |= F.contents
return ret
// Living mobs use can_inject() to make sure that the mob is not syringe-proof in general.
/mob/living/proc/can_inject()
+1 -2
View File
@@ -317,8 +317,7 @@
return shock_damage
/mob/living/emp_act(severity)
var/list/L = src.get_contents()
for(var/obj/O in L)
for(var/obj/O in contents)
O.emp_act(severity)
..()
@@ -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
+5 -2
View File
@@ -66,7 +66,7 @@
..()
to_chat(user, "<span class='notice'>Alt-click to fold it.</span>")
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/paper)
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/paper)
assets.send(user)
if(in_range(user, src) || isobserver(user))
@@ -300,7 +300,10 @@
if(!in_range(src, user))
return
stamps += "<img src=large_[P.icon_state].png>"
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/paper)
if (isnull(stamps))
stamps = sheet.css_tag()
stamps += sheet.icon_tag(P.icon_state)
var/mutable_appearance/stampoverlay = mutable_appearance('icons/obj/bureaucracy.dmi', "paper_[P.icon_state]")
stampoverlay.pixel_x = rand(-2, 2)
stampoverlay.pixel_y = rand(-3, 2)
@@ -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
+3 -2
View File
@@ -51,8 +51,9 @@ other types of metals and chemistry for reagents).
return ..()
/datum/design/proc/icon_html(client/user)
send_asset(user, "design_[id].png", FALSE)
return "<img class='icon' src=\"design_[id].png\">"
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/research_designs)
sheet.send(user)
return sheet.icon_tag(id)
////////////////////////////////////////
//Disks for transporting design datums//
@@ -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
+2
View File
@@ -217,6 +217,8 @@ doesn't have toxins access.
/obj/machinery/computer/rdconsole/proc/ui_header()
var/list/l = list()
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/research_designs)
l += "[sheet.css_tag()][RDSCREEN_NOBREAK]"
l += "<div class='statusDisplay'><b>[stored_research.organization] Research and Development Network</b>"
l += "Available points: [round(stored_research.research_points)] (+[round(stored_research.last_bitcoins * 60)] / minute)"
l += "Security protocols: [obj_flags & EMAGGED ? "<font color='red'>Disabled</font>" : "<font color='green'>Enabled</font>"]"
+9 -1
View File
@@ -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"
+2 -2
View File
@@ -453,7 +453,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/ammo/shotgun/buck
name = "12g Buckshot Drum"
desc = "An additional 8-round buckshot magazine for use with the Bulldog shotgun. Front towards enemy."
item = /obj/item/ammo_box/magazine/m12g/buckshot
item = /obj/item/ammo_box/magazine/m12g
/datum/uplink_item/ammo/shotgun/slug
name = "12g Slug Drum"
@@ -466,7 +466,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
name = "12g Stun Slug Drum"
desc = "An alternative 8-round stun slug magazine for use with the Bulldog shotgun. \
Saying that they're completely non-lethal would be lying."
item = /obj/item/ammo_box/magazine/m12g
item = /obj/item/ammo_box/magazine/m12g/stun
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/shotgun/dragon
+3 -3
View File
@@ -114,11 +114,11 @@
/obj/item/clothing/mask/muzzle = 2)
premium = list(/obj/item/clothing/suit/pirate/captain = 2,
/obj/item/clothing/head/pirate/captain = 2,
/obj/item/clothing/head/helmet/roman = 1,
/obj/item/clothing/head/helmet/roman/legionaire = 1,
/obj/item/clothing/head/helmet/roman/fake = 1,
/obj/item/clothing/head/helmet/roman/legionaire/fake = 1,
/obj/item/clothing/under/roman = 1,
/obj/item/clothing/shoes/roman = 1,
/obj/item/shield/riot/roman = 1,
/obj/item/shield/riot/roman/fake = 1,
/obj/item/skub = 1)
refill_canister = /obj/item/vending_refill/autodrobe