Merge pull request #1429 from VOREStation/aro-sync

Polaris Sync
This commit is contained in:
Arokha Sieyes
2017-04-25 18:35:58 -04:00
committed by GitHub
234 changed files with 2523 additions and 1109 deletions

View File

@@ -408,6 +408,7 @@
projectile_type = /obj/item/projectile/chameleon
charge_meter = 0
charge_cost = 48 //uses next to no power, since it's just holograms
battery_lock = 1
var/obj/item/projectile/copy_projectile
var/global/list/gun_choices

View File

@@ -347,7 +347,9 @@
body_parts_covered = FACE|EYES
sprite_sheets = list(
"Teshari" = 'icons/mob/species/seromi/masks.dmi',
"Vox" = 'icons/mob/species/vox/masks.dmi'
"Vox" = 'icons/mob/species/vox/masks.dmi',
"Tajara" = 'icons/mob/species/tajaran/mask.dmi',
"Unathi" = 'icons/mob/species/unathi/mask.dmi'
)
var/voicechange = 0

View File

@@ -402,7 +402,7 @@ BLIND // can't see anything
var/mob/living/carbon/human/M = src.loc
M << "\red The Optical Thermal Scanner overloads and blinds you!"
if(M.glasses == src)
M.eye_blind = 3
M.Blind(3)
M.eye_blurry = 5
// Don't cure being nearsighted
if(!(M.disabilities & NEARSIGHTED))

View File

@@ -6,10 +6,6 @@
flags_inv = HIDEFACE|BLOCKHAIR
body_parts_covered = FACE|HEAD
w_class = ITEMSIZE_SMALL
sprite_sheets = list(
"Tajara" = 'icons/mob/species/tajaran/mask.dmi',
"Unathi" = 'icons/mob/species/unathi/mask.dmi',
)
/obj/item/clothing/mask/balaclava/tactical
name = "green balaclava"
@@ -18,10 +14,6 @@
item_state_slots = list(slot_r_hand_str = "bandgreen", slot_l_hand_str = "bandgreen")
flags_inv = HIDEFACE|BLOCKHAIR
w_class = ITEMSIZE_SMALL
sprite_sheets = list(
"Tajara" = 'icons/mob/species/tajaran/mask.dmi',
"Unathi" = 'icons/mob/species/unathi/mask.dmi',
)
/obj/item/clothing/mask/luchador
name = "Luchador Mask"

View File

@@ -34,7 +34,7 @@
item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL | PHORONGUARD
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank)
phoronproof = 1
slowdown = 2
slowdown = 0.5
armor = list(melee = 60, bullet = 50, laser = 40,energy = 15, bomb = 30, bio = 100, rad = 50)
siemens_coefficient = 0.2
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS

View File

@@ -80,6 +80,9 @@
if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam))
var/obj/item/projectile/P = damage_source
if(P.reflected) // Can't reflect twice
return ..()
var/reflectchance = 40 - round(damage/3)
if(!(def_zone in list(BP_TORSO, BP_GROIN)))
reflectchance /= 2

View File

@@ -76,10 +76,12 @@
/obj/item/clothing/accessory/holster/on_attached(obj/item/clothing/under/S, mob/user as mob)
..()
has_suit.verbs += /obj/item/clothing/accessory/holster/verb/holster_verb
if(has_suit)
has_suit.verbs += /obj/item/clothing/accessory/holster/verb/holster_verb
/obj/item/clothing/accessory/holster/on_removed(mob/user as mob)
has_suit.verbs -= /obj/item/clothing/accessory/holster/verb/holster_verb
if(has_suit)
has_suit.verbs -= /obj/item/clothing/accessory/holster/verb/holster_verb
..()
//For the holster hotkey

View File

@@ -41,9 +41,11 @@
i++
/datum/event/carp_migration/end()
for(var/mob/living/simple_animal/hostile/carp/C in spawned_carp)
if(!C.stat)
var/turf/T = get_turf(C)
if(istype(T, /turf/space))
if(!prob(25))
qdel(C)
spawn(0)
for(var/mob/living/simple_animal/hostile/C in spawned_carp)
if(!C.stat)
var/turf/T = get_turf(C)
if(istype(T, /turf/space))
if(prob(75))
qdel(C)
sleep(1)

View File

@@ -72,7 +72,7 @@
finish(mob/living/carbon/human/H)
if(!H.reagents.has_reagent("anti_toxin"))
H.confused += 100
H.Confuse(100)
proc/trigger_side_effect(mob/living/carbon/human/H)
spawn

View File

@@ -8,7 +8,7 @@
#define IC_SPAWN_DEFAULT 1 // If the circuit comes in the default circuit box.
#define IC_SPAWN_RESEARCH 2 // If the circuit design will be autogenerated for RnD.
#define IC_FORMAT_STRING "\<STRING\>"
#define IC_FORMAT_STRING "\<TEXT\>"
#define IC_FORMAT_NUMBER "\<NUM\>"
#define IC_FORMAT_REF "\<REF\>"
#define IC_FORMAT_LIST "\<LIST\>"

View File

@@ -107,6 +107,7 @@
for(var/obj/item/integrated_circuit/circuit in contents)
HTML += "<a href=?src=\ref[circuit];examine=1>[circuit.name]</a> | "
HTML += "<a href=?src=\ref[circuit];rename=1>\[Rename\]</a> | "
HTML += "<a href=?src=\ref[circuit];scan=1>\[Scan with Debugger\]</a> | "
if(circuit.removable)
HTML += "<a href=?src=\ref[circuit];remove=1>\[Remove\]</a>"
HTML += "<br>"
@@ -223,9 +224,10 @@
if(proximity)
var/scanned = FALSE
for(var/obj/item/integrated_circuit/input/sensor/S in contents)
S.set_pin_data(IC_OUTPUT, 1, weakref(target))
S.check_then_do_work()
scanned = TRUE
// S.set_pin_data(IC_OUTPUT, 1, weakref(target))
// S.check_then_do_work()
if(S.scan(target))
scanned = TRUE
if(scanned)
visible_message("<span class='notice'>\The [user] waves \the [src] around [target].</span>")

View File

@@ -6,6 +6,7 @@ a creative player the means to solve many problems. Circuits are held inside an
/obj/item/integrated_circuit/examine(mob/user)
. = ..()
external_examine(user)
interact(user)
// This should be used when someone is examining while the case is opened.
/obj/item/integrated_circuit/proc/internal_examine(mob/user)
@@ -86,16 +87,14 @@ a creative player the means to solve many problems. Circuits are held inside an
var/HTML = list()
HTML += "<html><head><title>[src.name]</title></head><body>"
HTML += "<div align='center'>"
HTML += "<table border='1' style='undefined;table-layout: fixed; width: 424px'>"
HTML += "<table border='1' style='undefined;table-layout: fixed; width: 80%'>"
HTML += "<br><a href='?src=\ref[src];'>\[Refresh\]</a> | "
HTML += "<a href='?src=\ref[src];rename=1'>\[Rename\]</a> | "
HTML += "<a href='?src=\ref[src];scan=1'>\[Scan with Debugger\]</a> | "
HTML += "<a href='?src=\ref[src];remove=1'>\[Remove\]</a><br>"
HTML += "<colgroup>"
//HTML += "<col style='width: 121px'>"
//HTML += "<col style='width: 181px'>"
//HTML += "<col style='width: 122px'>"
HTML += "<col style='width: [table_edge_width]'>"
HTML += "<col style='width: [table_middle_width]'>"
HTML += "<col style='width: [table_edge_width]'>"
@@ -212,6 +211,16 @@ a creative player the means to solve many problems. Circuits are held inside an
if(href_list["rename"])
rename_component(usr)
if(href_list["scan"])
if(istype(held_item, /obj/item/device/integrated_electronics/debugger))
var/obj/item/device/integrated_electronics/debugger/D = held_item
if(D.accepting_refs)
D.afterattack(src, usr, TRUE)
else
to_chat(usr, "<span class='warning'>The Debugger's 'ref scanner' needs to be on.</span>")
else
to_chat(usr, "<span class='warning'>You need a Debugger set to 'ref' mode to do that.</span>")
if(href_list["autopulse"])
if(autopulse != -1)
autopulse = !autopulse
@@ -260,10 +269,10 @@ a creative player the means to solve many problems. Circuits are held inside an
return TRUE // Battery has enough.
return FALSE // Not enough power.
/obj/item/integrated_circuit/proc/check_then_do_work()
/obj/item/integrated_circuit/proc/check_then_do_work(var/ignore_power = FALSE)
if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam.
return
if(power_draw_per_use)
if(power_draw_per_use && !ignore_power)
if(!check_power())
power_fail()
return

View File

@@ -160,7 +160,7 @@
data_to_show = A.name
to_chat(user, "<span class='notice'>You write '[data_to_write ? data_to_show : "NULL"]' to the '[io]' pin of \the [io.holder].</span>")
else if(io.io_type == PULSE_CHANNEL)
io.holder.check_then_do_work()
io.holder.check_then_do_work(ignore_power = TRUE)
to_chat(user, "<span class='notice'>You pulse \the [io.holder]'s [io].</span>")
io.holder.interact(user) // This is to update the UI.

View File

@@ -1,9 +1,18 @@
//These circuits do simple math.
/obj/item/integrated_circuit/arithmetic
complexity = 1
inputs = list("A","B","C","D","E","F","G","H")
outputs = list("result")
activators = list("compute")
inputs = list(
"\<NUM\> A",
"\<NUM\> B",
"\<NUM\> C",
"\<NUM\> D",
"\<NUM\> E",
"\<NUM\> F",
"\<NUM\> G",
"\<NUM\> H"
)
outputs = list("\<NUM\> result")
activators = list("\<PULSE IN\> compute", "\<PULSE OUT\> on computed")
category_text = "Arithmetic"
autopulse = 1
power_draw_per_use = 5 // Math is pretty cheap.
@@ -30,9 +39,9 @@
if(isnum(I.data))
result = result + I.data
for(var/datum/integrated_io/output/O in outputs)
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// -Subtracting- //
@@ -58,9 +67,9 @@
if(isnum(I.data))
result = result - I.data
for(var/datum/integrated_io/output/O in outputs)
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// *Multiply* //
@@ -86,9 +95,9 @@
if(isnum(I.data))
result = result * I.data
for(var/datum/integrated_io/output/O in outputs)
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// /Division/ //
@@ -114,9 +123,9 @@
if(isnum(I.data) && I.data != 0) //No runtimes here.
result = result / I.data
for(var/datum/integrated_io/output/O in outputs)
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
//^ Exponent ^//
@@ -134,9 +143,9 @@
if(isnum(A.data) && isnum(B.data))
result = A.data ** B.data
for(var/datum/integrated_io/output/O in outputs)
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// +-Sign-+ //
@@ -159,9 +168,9 @@
else
result = 0
for(var/datum/integrated_io/output/O in outputs)
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// Round //
@@ -183,9 +192,9 @@
else
result = round(A.data)
for(var/datum/integrated_io/output/O in outputs)
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// Absolute //
@@ -204,9 +213,9 @@
if(isnum(I.data))
result = abs(I.data)
for(var/datum/integrated_io/output/O in outputs)
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// Averaging //
@@ -229,9 +238,9 @@
if(inputs_used)
result = result / inputs_used
for(var/datum/integrated_io/output/O in outputs)
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// Pi, because why the hell not? //
/obj/item/integrated_circuit/arithmetic/pi
@@ -242,9 +251,9 @@
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/arithmetic/pi/do_work()
var/datum/integrated_io/output/O = outputs[1]
O.data = 3.14159
O.push_data()
set_pin_data(IC_OUTPUT, 1, 3.14159)
push_data()
activate_pin(2)
// Random //
/obj/item/integrated_circuit/arithmetic/random
@@ -253,20 +262,20 @@
extended_desc = "'Inclusive' means that the upper bound is included in the range of numbers, e.g. L = 1 and H = 3 will allow \
for outputs of 1, 2, or 3. H being the higher number is not <i>strictly</i> required."
icon_state = "random"
inputs = list("L","H")
inputs = list("\<NUM\> L","\<NUM\> H")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/arithmetic/random/do_work()
var/result = 0
var/datum/integrated_io/L = inputs[1]
var/datum/integrated_io/H = inputs[2]
var/L = get_pin_data(IC_INPUT, 1)
var/H = get_pin_data(IC_INPUT, 2)
if(isnum(L.data) && isnum(H.data))
result = rand(L.data, H.data)
if(isnum(L) && isnum(H))
result = rand(L, H)
for(var/datum/integrated_io/output/O in outputs)
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// Square Root //
@@ -274,7 +283,7 @@
name = "square root circuit"
desc = "This outputs the square root of a number you put in."
icon_state = "square_root"
inputs = list("A")
inputs = list("\<NUM\> A")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/arithmetic/square_root/do_work()
@@ -284,9 +293,9 @@
if(isnum(I.data))
result = sqrt(I.data)
for(var/datum/integrated_io/output/O in outputs)
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// % Modulo % //
@@ -294,17 +303,17 @@
name = "modulo circuit"
desc = "Gets the remainder of A / B."
icon_state = "modulo"
inputs = list("A", "B")
inputs = list("\<NUM\> A", "\<NUM\> B")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/arithmetic/modulo/do_work()
var/result = 0
var/datum/integrated_io/input/A = inputs[1]
var/datum/integrated_io/input/B = inputs[2]
if(isnum(A.data) && isnum(B.data) && B.data != 0)
result = A.data % B.data
var/A = get_pin_data(IC_INPUT, 1)
var/B = get_pin_data(IC_INPUT, 2)
if(isnum(A) && isnum(B) && B != 0)
result = A % B
for(var/datum/integrated_io/output/O in outputs)
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)

View File

@@ -3,7 +3,7 @@
complexity = 2
inputs = list("input")
outputs = list("output")
activators = list("convert")
activators = list("\<PULSE IN\> convert", "\<PULSE OUT\> on convert")
category_text = "Converter"
autopulse = 1
power_draw_per_use = 10
@@ -16,89 +16,113 @@
name = "number to string"
desc = "This circuit can convert a number variable into a string."
icon_state = "num-string"
inputs = list("\<NUM\> input")
outputs = list("\<TEXT\> output")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/num2text/do_work()
var/result = null
var/datum/integrated_io/incoming = inputs[1]
var/datum/integrated_io/outgoing = outputs[1]
if(incoming.data && isnum(incoming.data))
result = num2text(incoming.data)
pull_data()
var/incoming = get_pin_data(IC_INPUT, 1)
if(incoming && isnum(incoming))
result = num2text(incoming)
outgoing.data = result
outgoing.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
/obj/item/integrated_circuit/converter/text2num
name = "string to number"
desc = "This circuit can convert a string variable into a number."
icon_state = "string-num"
inputs = list("\<TEXT\> input")
outputs = list("\<NUM\> output")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/text2num/do_work()
var/result = null
var/datum/integrated_io/incoming = inputs[1]
var/datum/integrated_io/outgoing = outputs[1]
if(incoming.data && istext(incoming.data))
result = text2num(incoming.data)
pull_data()
var/incoming = get_pin_data(IC_INPUT, 1)
if(incoming && istext(incoming))
result = text2num(incoming)
outgoing.data = result
outgoing.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
/obj/item/integrated_circuit/converter/ref2text
name = "reference to string"
desc = "This circuit can convert a reference to something else to a string, specifically the name of that reference."
icon_state = "ref-string"
inputs = list("\<REF\> input")
outputs = list("\<TEXT\> output")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/ref2text/do_work()
var/result = null
var/datum/integrated_io/incoming = inputs[1]
var/datum/integrated_io/outgoing = outputs[1]
var/atom/A = incoming.data_as_type(/atom)
result = A && A.name
pull_data()
var/atom/A = get_pin_data(IC_INPUT, 1)
if(A && istype(A))
result = A.name
outgoing.data = result
outgoing.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
/obj/item/integrated_circuit/converter/lowercase
name = "lowercase string converter"
desc = "this will cause a string to come out in all lowercase."
icon_state = "lowercase"
inputs = list("\<TEXT\> input")
outputs = list("\<TEXT\> output")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/lowercase/do_work()
var/result = null
var/datum/integrated_io/incoming = inputs[1]
var/datum/integrated_io/outgoing = outputs[1]
if(incoming.data && istext(incoming.data))
result = lowertext(incoming.data)
pull_data()
var/incoming = get_pin_data(IC_INPUT, 1)
if(incoming && istext(incoming))
result = lowertext(incoming)
outgoing.data = result
outgoing.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
/obj/item/integrated_circuit/converter/uppercase
name = "uppercase string converter"
desc = "THIS WILL CAUSE A STRING TO COME OUT IN ALL UPPERCASE."
icon_state = "uppercase"
inputs = list("\<TEXT\> input")
outputs = list("\<TEXT\> output")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/uppercase/do_work()
var/result = null
var/datum/integrated_io/incoming = inputs[1]
var/datum/integrated_io/outgoing = outputs[1]
if(incoming.data && istext(incoming.data))
result = uppertext(incoming.data)
pull_data()
var/incoming = get_pin_data(IC_INPUT, 1)
if(incoming && istext(incoming))
result = uppertext(incoming)
outgoing.data = result
outgoing.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
/obj/item/integrated_circuit/converter/concatenatior
name = "concatenatior"
desc = "This joins many strings together to get one big string."
desc = "This joins many strings or numbers together to get one big string."
complexity = 4
inputs = list("A","B","C","D","E","F","G","H")
outputs = list("result")
activators = list("concatenate")
inputs = list(
"\<TEXT/NUM\> A",
"\<TEXT/NUM\> B",
"\<TEXT/NUM\> C",
"\<TEXT/NUM\> D",
"\<TEXT/NUM\> E",
"\<TEXT/NUM\> F",
"\<TEXT/NUM\> G",
"\<TEXT/NUM\> H"
)
outputs = list("\<TEXT\> result")
activators = list("\<PULSE IN\> concatenate", "\<PULSE OUT\> on concatenated")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/concatenatior/do_work()
@@ -107,70 +131,70 @@
I.pull_data()
if(istext(I.data))
result = result + I.data
else if(!isnull(I.data) && num2text(I.data))
result = result + num2text(I.data)
var/datum/integrated_io/outgoing = outputs[1]
outgoing.data = result
outgoing.push_data()
activate_pin(2)
/obj/item/integrated_circuit/converter/radians2degrees
name = "radians to degrees converter"
desc = "Converts radians to degrees."
inputs = list("radian")
outputs = list("degrees")
inputs = list("\<NUM\> radian")
outputs = list("\<NUM\> degrees")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/radians2degrees/do_work()
var/result = null
var/datum/integrated_io/incoming = inputs[1]
var/datum/integrated_io/outgoing = outputs[1]
incoming.pull_data()
if(incoming.data && isnum(incoming.data))
result = ToDegrees(incoming.data)
pull_data()
var/incoming = get_pin_data(IC_INPUT, 1)
if(incoming && isnum(incoming))
result = ToDegrees(incoming)
outgoing.data = result
outgoing.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
/obj/item/integrated_circuit/converter/degrees2radians
name = "degrees to radians converter"
desc = "Converts degrees to radians."
inputs = list("degrees")
outputs = list("radians")
inputs = list("\<NUM\> degrees")
outputs = list("\<NUM\> radians")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/degrees2radians/do_work()
var/result = null
var/datum/integrated_io/incoming = inputs[1]
var/datum/integrated_io/outgoing = outputs[1]
incoming.pull_data()
if(incoming.data && isnum(incoming.data))
result = ToRadians(incoming.data)
pull_data()
var/incoming = get_pin_data(IC_INPUT, 1)
if(incoming && isnum(incoming))
result = ToRadians(incoming)
outgoing.data = result
outgoing.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
/obj/item/integrated_circuit/converter/abs_to_rel_coords
name = "abs to rel coordinate converter"
desc = "Easily convert absolute coordinates to relative coordinates with this."
complexity = 4
inputs = list("X1 (abs)", "Y1 (abs)", "X2 (abs)", "Y2 (abs)")
outputs = list("X (rel)", "Y (rel)")
activators = list("compute rel coordinates")
inputs = list("\<NUM\> X1", "\<NUM\> Y1", "\<NUM\> X2", "\<NUM\> Y2")
outputs = list("\<NUM\> X", "\<NUM\> Y")
activators = list("\<PULSE IN\> compute rel coordinates", "\<PULSE OUT\> on convert")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/abs_to_rel_coords/do_work()
var/datum/integrated_io/x1 = inputs[1]
var/datum/integrated_io/y1 = inputs[2]
var/x1 = get_pin_data(IC_INPUT, 1)
var/y1 = get_pin_data(IC_INPUT, 2)
var/datum/integrated_io/x2 = inputs[3]
var/datum/integrated_io/y2 = inputs[4]
var/x2 = get_pin_data(IC_INPUT, 3)
var/y2 = get_pin_data(IC_INPUT, 4)
var/datum/integrated_io/result_x = outputs[1]
var/datum/integrated_io/result_y = outputs[2]
if(x1 && y1 && x2 && y2)
set_pin_data(IC_OUTPUT, 1, x1 - x2)
set_pin_data(IC_OUTPUT, 2, y1 - y2)
if(x1.data && y1.data && x2.data && y2.data)
result_x.data = x1.data - x2.data
result_y.data = y1.data - y2.data
for(var/datum/integrated_io/output/O in outputs)
O.push_data()
push_data()
activate_pin(2)

View File

@@ -14,28 +14,27 @@
can_be_asked_input = 1
inputs = list()
outputs = list()
activators = list("on pressed")
activators = list("\<PULSE OUT\> on pressed")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/input/button/ask_for_input(mob/user) //Bit misleading name for this specific use.
var/datum/integrated_io/A = activators[1]
if(A.linked.len)
for(var/datum/integrated_io/activate/target in A.linked)
target.holder.check_then_do_work()
to_chat(user, "<span class='notice'>You press the button labeled '[src.name]'.</span>")
activate_pin(1)
/obj/item/integrated_circuit/input/toggle_button
name = "toggle button"
desc = "It toggles on, off, on, off..."
icon_state = "toggle_button"
complexity = 1
can_be_asked_input = 1
inputs = list()
outputs = list("on" = 0)
activators = list("on toggle")
outputs = list("\<NUM\> on" = 0)
activators = list("\<PULSE OUT\> on toggle")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/input/toggle_button/ask_for_input(mob/user) // Ditto.
set_pin_data(IC_OUTPUT, 1, !get_pin_data(IC_OUTPUT, 1))
push_data()
activate_pin(1)
to_chat(user, "<span class='notice'>You toggle the button labeled '[src.name]' [get_pin_data(IC_OUTPUT, 1) ? "on" : "off"].</span>")
@@ -46,19 +45,17 @@
complexity = 2
can_be_asked_input = 1
inputs = list()
outputs = list("number entered")
activators = list("on entered")
outputs = list("\<NUM\> number entered")
activators = list("\<PULSE OUT\> on entered")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 4
/obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user)
var/new_input = input(user, "Enter a number, please.","Number pad") as null|num
if(isnum(new_input) && CanInteract(user, physical_state))
var/datum/integrated_io/O = outputs[1]
O.data = new_input
O.push_data()
var/datum/integrated_io/A = activators[1]
A.push_data()
set_pin_data(IC_OUTPUT, 1, new_input)
push_data()
activate_pin(1)
/obj/item/integrated_circuit/input/textpad
name = "text pad"
@@ -67,49 +64,43 @@
complexity = 2
can_be_asked_input = 1
inputs = list()
outputs = list("string entered")
activators = list("on entered")
outputs = list("\<TEXT\> string entered")
activators = list("\<PULSE OUT\> on entered")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 4
/obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user)
var/new_input = input(user, "Enter some words, please.","Number pad") as null|text
if(istext(new_input) && CanInteract(user, physical_state))
var/datum/integrated_io/O = outputs[1]
O.data = new_input
O.push_data()
var/datum/integrated_io/A = activators[1]
A.push_data()
set_pin_data(IC_OUTPUT, 1, new_input)
push_data()
activate_pin(1)
/obj/item/integrated_circuit/input/med_scanner
name = "integrated medical analyser"
desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is."
icon_state = "medscan"
complexity = 4
inputs = list("target ref")
outputs = list("total health %", "total missing health")
activators = list("scan")
inputs = list("\<REF\> target")
outputs = list("\<NUM\> total health %", "\<NUM\> total missing health")
activators = list("\<PULSE IN\> scan", "\<PULSE OUT\> on scanned")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
power_draw_per_use = 40
/obj/item/integrated_circuit/input/med_scanner/do_work()
var/datum/integrated_io/I = inputs[1]
var/mob/living/carbon/human/H = I.data_as_type(/mob/living/carbon/human)
var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human)
if(!istype(H)) //Invalid input
return
if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range.
var/total_health = round(H.health/H.maxHealth, 0.1)*100
var/missing_health = H.maxHealth - H.health
var/total_health = round(H.health/H.getMaxHealth(), 0.1)*100
var/missing_health = H.getMaxHealth() - H.health
var/datum/integrated_io/total = outputs[1]
var/datum/integrated_io/missing = outputs[2]
set_pin_data(IC_OUTPUT, 1, total_health)
set_pin_data(IC_OUTPUT, 2, missing_health)
total.data = total_health
missing.data = missing_health
for(var/datum/integrated_io/output/O in outputs)
O.push_data()
push_data()
activate_pin(2)
/obj/item/integrated_circuit/input/adv_med_scanner
name = "integrated advanced medical analyser"
@@ -117,48 +108,39 @@
This type is much more precise, allowing the machine to know much more about the target than a normal analyzer."
icon_state = "medscan_adv"
complexity = 12
inputs = list("target ref")
inputs = list("\<REF\> target")
outputs = list(
"total health %",
"total missing health",
"brute damage",
"burn damage",
"tox damage",
"oxy damage",
"clone damage"
"\<NUM\> total health %",
"\<NUM\> total missing health",
"\<NUM\> brute damage",
"\<NUM\> burn damage",
"\<NUM\> tox damage",
"\<NUM\> oxy damage",
"\<NUM\> clone damage"
)
activators = list("scan")
activators = list("\<PULSE IN\> scan", "\<PULSE OUT\> on scanned")
spawn_flags = IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4)
power_draw_per_use = 80
/obj/item/integrated_circuit/input/adv_med_scanner/do_work()
var/datum/integrated_io/I = inputs[1]
var/mob/living/carbon/human/H = I.data_as_type(/mob/living/carbon/human)
var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human)
if(!istype(H)) //Invalid input
return
if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range.
var/total_health = round(H.health/H.maxHealth, 0.1)*100
var/missing_health = H.maxHealth - H.health
var/total_health = round(H.health/H.getMaxHealth(), 0.1)*100
var/missing_health = H.getMaxHealth() - H.health
var/datum/integrated_io/total = outputs[1]
var/datum/integrated_io/missing = outputs[2]
var/datum/integrated_io/brute = outputs[3]
var/datum/integrated_io/burn = outputs[4]
var/datum/integrated_io/tox = outputs[5]
var/datum/integrated_io/oxy = outputs[6]
var/datum/integrated_io/clone = outputs[7]
set_pin_data(IC_OUTPUT, 1, total_health)
set_pin_data(IC_OUTPUT, 2, missing_health)
set_pin_data(IC_OUTPUT, 3, H.getBruteLoss())
set_pin_data(IC_OUTPUT, 4, H.getFireLoss())
set_pin_data(IC_OUTPUT, 5, H.getToxLoss())
set_pin_data(IC_OUTPUT, 6, H.getOxyLoss())
set_pin_data(IC_OUTPUT, 7, H.getCloneLoss())
total.data = total_health
missing.data = missing_health
brute.data = H.getBruteLoss()
burn.data = H.getFireLoss()
tox.data = H.getToxLoss()
oxy.data = H.getOxyLoss()
clone.data = H.getCloneLoss()
for(var/datum/integrated_io/output/O in outputs)
O.push_data()
push_data()
activate_pin(2)
/obj/item/integrated_circuit/input/local_locator
name = "local locator"
@@ -222,9 +204,9 @@
Meaning the default frequency is expressed as 1457, not 145.7. To send a signal, pulse the 'send signal' activator pin."
icon_state = "signal"
complexity = 4
inputs = list("frequency","code")
inputs = list("\<NUM\> frequency","\<NUM\> code")
outputs = list()
activators = list("send signal","on signal received")
activators = list("\<PULSE IN\> send signal","\<PULSE OUT\> on signal sent", "\<PULSE OUT\> on signal received")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2)
power_draw_idle = 5
@@ -237,11 +219,9 @@
/obj/item/integrated_circuit/input/signaler/initialize()
..()
set_frequency(frequency)
var/datum/integrated_io/new_freq = inputs[1]
var/datum/integrated_io/new_code = inputs[2]
// Set the pins so when someone sees them, they won't show as null
new_freq.data = frequency
new_code.data = code
set_pin_data(IC_INPUT, 1, frequency)
set_pin_data(IC_INPUT, 2, code)
/obj/item/integrated_circuit/input/signaler/Destroy()
if(radio_controller)
@@ -250,12 +230,12 @@
. = ..()
/obj/item/integrated_circuit/input/signaler/on_data_written()
var/datum/integrated_io/new_freq = inputs[1]
var/datum/integrated_io/new_code = inputs[2]
if(isnum(new_freq.data) && new_freq.data > 0)
set_frequency(new_freq.data)
if(isnum(new_code.data))
code = new_code.data
var/new_freq = get_pin_data(IC_INPUT, 1)
var/new_code = get_pin_data(IC_INPUT, 2)
if(isnum(new_freq) && new_freq > 0)
set_frequency(new_freq)
if(isnum(new_code))
code = new_code
/obj/item/integrated_circuit/input/signaler/do_work() // Sends a signal.
@@ -267,6 +247,7 @@
signal.encryption = code
signal.data["message"] = "ACTIVATE"
radio_connection.post_signal(src, signal)
activate_pin(2)
/obj/item/integrated_circuit/input/signaler/proc/set_frequency(new_frequency)
if(!frequency)
@@ -280,11 +261,11 @@
radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT)
/obj/item/integrated_circuit/input/signaler/receive_signal(datum/signal/signal)
var/datum/integrated_io/new_code = inputs[2]
var/new_code = get_pin_data(IC_INPUT, 2)
var/code = 0
if(isnum(new_code.data))
code = new_code.data
if(isnum(new_code))
code = new_code
if(!signal)
return 0
if(signal.encryption != code)
@@ -292,8 +273,7 @@
if(signal.source == src) // Don't trigger ourselves.
return 0
var/datum/integrated_io/A = activators[2]
A.push_data()
activate_pin(3)
for(var/mob/O in hearers(1, get_turf(src)))
O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2)
@@ -306,9 +286,9 @@
will pulse whatever's connected to it. Pulsing the first activation pin will send a message."
icon_state = "signal"
complexity = 4
inputs = list("target EPv2 address", "data to send", "secondary text")
outputs = list("address received", "data received", "secondary text received")
activators = list("send data", "on data received")
inputs = list("\<TEXT\> target EPv2 address", "\<TEXT\> data to send", "\<TEXT\> secondary text")
outputs = list("\<TEXT\> address received", "\<TEXT\> data received", "\<TEXT\> secondary text received")
activators = list("\<PULSE IN\> send data", "\<PULSE OUT\> on data received")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2)
power_draw_per_use = 50
@@ -318,7 +298,7 @@
..()
exonet = new(src)
exonet.make_address("EPv2_circuit-\ref[src]")
desc += "<br>This circuit's EPv2 address is: [exonet.address]."
desc += "<br>This circuit's EPv2 address is: [exonet.address]"
/obj/item/integrated_circuit/input/EPv2/Destroy()
if(exonet)
@@ -327,64 +307,60 @@
..()
/obj/item/integrated_circuit/input/EPv2/do_work()
var/datum/integrated_io/target_address = inputs[1]
var/datum/integrated_io/message = inputs[2]
var/datum/integrated_io/text = inputs[3]
if(istext(target_address.data))
exonet.send_message(target_address.data, message.data, text.data)
var/target_address = get_pin_data(IC_INPUT, 1)
var/message = get_pin_data(IC_INPUT, 2)
var/text = get_pin_data(IC_INPUT, 3)
if(target_address && istext(target_address))
exonet.send_message(target_address, message, text)
/obj/item/integrated_circuit/input/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text)
var/datum/integrated_io/message_received = outputs[1]
var/datum/integrated_io/data_received = outputs[2]
var/datum/integrated_io/text_received = outputs[3]
set_pin_data(IC_OUTPUT, 1, origin_address)
set_pin_data(IC_OUTPUT, 2, message)
set_pin_data(IC_OUTPUT, 3, text)
var/datum/integrated_io/A = activators[2]
A.push_data()
message_received.write_data_to_pin(origin_address)
data_received.write_data_to_pin(message)
text_received.write_data_to_pin(text)
for(var/datum/integrated_io/output/O in outputs)
O.push_data()
push_data()
activate_pin(2)
//This circuit gives information on where the machine is.
/obj/item/integrated_circuit/input/gps
name = "global positioning system"
desc = "This allows you to easily know the position of a machine containing this device."
extended_desc = "The GPS's coordinates it gives is absolute, not relative."
icon_state = "gps"
complexity = 4
inputs = list()
outputs = list("X (abs)", "Y (abs)")
activators = list("get coordinates")
outputs = list("\<NUM\> X", "\<NUM\> Y")
activators = list("\<PULSE IN\> get coordinates", "\<PULSE OUT\> on get coordinates")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 30
/obj/item/integrated_circuit/input/gps/do_work()
var/turf/T = get_turf(src)
var/datum/integrated_io/result_x = outputs[1]
var/datum/integrated_io/result_y = outputs[2]
result_x.data = null
result_y.data = null
set_pin_data(IC_OUTPUT, 1, null)
set_pin_data(IC_OUTPUT, 2, null)
if(!T)
return
result_x.data = T.x
result_y.data = T.y
set_pin_data(IC_OUTPUT, 1, T.x)
set_pin_data(IC_OUTPUT, 2, T.y)
for(var/datum/integrated_io/output/O in outputs)
O.push_data()
push_data()
activate_pin(2)
/obj/item/integrated_circuit/input/microphone
name = "microphone"
desc = "Useful for spying on people or for voice activated machines."
extended_desc = "This will automatically translate most languages it hears to Galactic Common. \
The first activation pin is always pulsed when the circuit hears someone talk, while the second one \
is only triggered if it hears someone speaking a language other than Galactic Common."
icon_state = "recorder"
complexity = 8
inputs = list()
outputs = list("speaker \<String\>", "message \<String\>")
activators = list("on message received")
outputs = list("\<TEXT\> speaker", "\<TEXT\> message")
activators = list("\<PULSE OUT\> on message received", "\<PULSE OUT\> on translation")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 15
@@ -397,42 +373,45 @@
..()
/obj/item/integrated_circuit/input/microphone/hear_talk(mob/living/M, msg, var/verb="says", datum/language/speaking=null)
var/datum/integrated_io/V = outputs[1]
var/datum/integrated_io/O = outputs[2]
var/datum/integrated_io/A = activators[1]
var/translated = FALSE
if(M && msg)
if(speaking)
if(!speaking.machine_understands)
msg = speaking.scramble(msg)
V.data = M.GetVoice()
O.data = msg
A.push_data()
if(!istype(speaking, /datum/language/common))
translated = TRUE
set_pin_data(IC_OUTPUT, 1, M.GetVoice())
set_pin_data(IC_OUTPUT, 2, msg)
for(var/datum/integrated_io/output/out in outputs)
out.push_data()
A.push_data()
push_data()
activate_pin(1)
if(translated)
activate_pin(2)
/obj/item/integrated_circuit/input/sensor
name = "sensor"
desc = "Scans and obtains a reference for any objects or persons near you. All you need to do is shove the machine in their face."
extended_desc = "If 'ignore storage' pin is set to 1, the sensor will disregard scanning various storage containers such as backpacks."
icon_state = "recorder"
complexity = 12
inputs = list()
outputs = list("scanned ref \<Ref\>")
activators = list("on scanned")
inputs = list("\<NUM\> ignore storage" = 1)
outputs = list("\<REF\> scanned")
activators = list("\<PULSE OUT\> on scanned")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 120
/obj/item/integrated_circuit/input/sensor/do_work()
// Because this gets called by attack(), all this needs to do is pulse the activator.
for(var/datum/integrated_io/output/O in outputs)
O.push_data()
var/datum/integrated_io/activate/A = activators[1]
A.push_data()
/obj/item/integrated_circuit/input/sensor/proc/scan(var/atom/A)
var/ignore_bags = get_pin_data(IC_INPUT, 1)
if(ignore_bags)
if(istype(A, /obj/item/weapon/storage))
return FALSE
set_pin_data(IC_OUTPUT, 1, weakref(A))
push_data()
activate_pin(1)
return TRUE
/obj/item/integrated_circuit/output
category_text = "Output"
@@ -441,9 +420,9 @@
name = "small screen"
desc = "This small screen can display a single piece of data, when the machine is examined closely."
icon_state = "screen"
inputs = list("displayed data")
inputs = list("\<TEXT/NUM\> displayed data")
outputs = list()
activators = list("load data")
activators = list("\<PULSE IN\> load data")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 10
autopulse = 1
@@ -497,7 +476,7 @@
complexity = 4
inputs = list()
outputs = list()
activators = list("toggle light")
activators = list("\<PULSE IN\> toggle light")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
var/light_toggled = 0
var/light_brightness = 3
@@ -519,18 +498,18 @@
power_draw_idle = light_toggled ? light_brightness * 2 : 0
/obj/item/integrated_circuit/output/light/advanced/update_lighting()
var/datum/integrated_io/R = inputs[1]
var/datum/integrated_io/G = inputs[2]
var/datum/integrated_io/B = inputs[3]
var/datum/integrated_io/brightness = inputs[4]
var/R = get_pin_data(IC_INPUT, 1)
var/G = get_pin_data(IC_INPUT, 2)
var/B = get_pin_data(IC_INPUT, 3)
var/brightness = get_pin_data(IC_INPUT, 4)
if(isnum(R.data) && isnum(G.data) && isnum(B.data) && isnum(brightness.data))
R.data = Clamp(R.data, 0, 255)
G.data = Clamp(G.data, 0, 255)
B.data = Clamp(B.data, 0, 255)
brightness.data = Clamp(brightness.data, 0, 6)
light_rgb = rgb(R.data, G.data, B.data)
light_brightness = brightness.data
if(isnum(R) && isnum(G) && isnum(B) && isnum(brightness))
R = Clamp(R, 0, 255)
G = Clamp(G, 0, 255)
B = Clamp(B, 0, 255)
brightness = Clamp(brightness, 0, 6)
light_rgb = rgb(R, G, B)
light_brightness = brightness
..()
@@ -544,10 +523,10 @@
icon_state = "light_adv"
complexity = 8
inputs = list(
"R",
"G",
"B",
"Brightness"
"\<NUM\> R",
"\<NUM\> G",
"\<NUM\> B",
"\<NUM\> Brightness"
)
outputs = list()
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
@@ -563,9 +542,9 @@
complexity = 8
cooldown_per_use = 4 SECONDS
inputs = list(
"sound ID",
"volume",
"frequency"
"\<TEXT\> sound ID",
"\<NUM\> volume",
"\<NUM\> frequency"
)
outputs = list()
activators = list("play sound")

View File

@@ -4,7 +4,7 @@
extended_desc = "Logic circuits will treat a null, 0, and a \"\" string value as FALSE and anything else as TRUE."
complexity = 3
outputs = list("result")
activators = list("compare", "on true result", "on false result")
activators = list("\<PULSE IN\> compare", "\<PULSE OUT\> on true result", "\<PULSE OUT\> on false result")
category_text = "Logic"
autopulse = 1
power_draw_per_use = 1
@@ -14,19 +14,17 @@
check_then_do_work()
/obj/item/integrated_circuit/logic/do_work()
var/datum/integrated_io/O = outputs[1]
var/datum/integrated_io/T = activators[2]
var/datum/integrated_io/F = activators[3]
O.push_data()
if(O.data)
T.push_data()
push_data()
if(get_pin_data(IC_INPUT, 1))
activate_pin(1)
else
F.push_data()
activate_pin(2)
/obj/item/integrated_circuit/logic/binary
inputs = list("A","B")
inputs = list("\<ANY\> A","\<ANY\> B")
/obj/item/integrated_circuit/logic/binary/do_work()
pull_data()
var/datum/integrated_io/A = inputs[1]
var/datum/integrated_io/B = inputs[2]
var/datum/integrated_io/O = outputs[1]
@@ -37,9 +35,10 @@
return FALSE
/obj/item/integrated_circuit/logic/unary
inputs = list("A")
inputs = list("\<ANY\> A")
/obj/item/integrated_circuit/logic/unary/do_work()
pull_data()
var/datum/integrated_io/A = inputs[1]
var/datum/integrated_io/O = outputs[1]
O.data = do_check(A) ? TRUE : FALSE

View File

@@ -11,12 +11,12 @@
complexity = 20
w_class = ITEMSIZE_NORMAL
inputs = list(
"target X rel",
"target Y rel"
"\<NUM\> target X rel",
"\<NUM\> target Y rel"
)
outputs = list()
activators = list(
"fire"
"\<PULSE IN\> fire"
)
var/obj/item/weapon/gun/installed_gun = null
spawn_flags = IC_SPAWN_RESEARCH

View File

@@ -11,9 +11,9 @@
some power is lost due to ineffiency."
w_class = ITEMSIZE_SMALL
complexity = 16
inputs = list("target ref")
outputs = list("target cell charge", "target cell max charge", "target cell percentage")
activators = list("transmit")
inputs = list("\<REF\> target")
outputs = list("\<NUM\> target cell charge", "\<NUM\> target cell max charge", "\<NUM\> target cell percentage")
activators = list("\<PULSE IN\> transmit")
spawn_flags = IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3)
power_draw_per_use = 500 // Inefficency has to come from somewhere.

View File

@@ -43,39 +43,39 @@
flags = OPENCONTAINER
complexity = 20
cooldown_per_use = 6 SECONDS
inputs = list("target ref", "injection amount" = 5)
inputs = list("\<REF\> target", "\<NUM\> injection amount" = 5)
outputs = list()
activators = list("inject")
activators = list("\<PULSE IN\> inject")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
volume = 30
power_draw_per_use = 15
/obj/item/integrated_circuit/reagent/injector/proc/inject_amount()
var/datum/integrated_io/amount = inputs[2]
if(isnum(amount.data))
return Clamp(amount.data, 0, 30)
var/amount = get_pin_data(IC_INPUT, 2)
if(isnum(amount))
return Clamp(amount, 0, 30)
/obj/item/integrated_circuit/reagent/injector/do_work()
set waitfor = 0 // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing
var/datum/integrated_io/target = inputs[1]
var/atom/movable/AM = target.data_as_type(/atom/movable)
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
if(!istype(AM)) //Invalid input
return
if(!reagents.total_volume) // Empty
return
if(AM.can_be_injected_by(src))
if(isliving(AM))
var/mob/living/L = AM
var/turf/T = get_turf(AM)
T.visible_message("<span class='warning'>[src] is trying to inject [AM]!</span>")
T.visible_message("<span class='warning'>[src] is trying to inject [L]!</span>")
sleep(3 SECONDS)
if(!AM.can_be_injected_by(src))
if(!L.can_be_injected_by(src))
return
var/contained = reagents.get_reagents()
var/trans = reagents.trans_to_mob(target, inject_amount(), CHEM_BLOOD)
log_debug("[src] injected \the [AM] with [trans]u of [contained].") //VOREStation Edit - I don't care THAT much.
var/trans = reagents.trans_to_mob(L, inject_amount(), CHEM_BLOOD)
message_admins("[src] injected \the [L] with [trans]u of [contained].")
to_chat(AM, "<span class='notice'>You feel a tiny prick!</span>")
visible_message("<span class='warning'>[src] injects [AM]!</span>")
visible_message("<span class='warning'>[src] injects [L]!</span>")
else
reagents.trans_to(AM, inject_amount())
@@ -88,9 +88,9 @@
outside the machine if it is next to the machine. Note that this cannot be used on entities."
flags = OPENCONTAINER
complexity = 8
inputs = list("source ref", "target ref", "injection amount" = 10)
inputs = list("\<REF\> source", "\<REF\> target", "\<NUM\> injection amount" = 10)
outputs = list()
activators = list("transfer reagents")
activators = list("\<PULSE IN\> transfer reagents", "\<PULSE OUT\> on transfer")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
var/transfer_amount = 10
@@ -103,10 +103,9 @@
transfer_amount = amount.data
/obj/item/integrated_circuit/reagent/pump/do_work()
var/datum/integrated_io/A = inputs[1]
var/datum/integrated_io/B = inputs[2]
var/atom/movable/source = A.data_as_type(/atom/movable)
var/atom/movable/target = B.data_as_type(/atom/movable)
var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
var/atom/movable/target = get_pin_data_as_type(IC_INPUT, 2, /atom/movable)
if(!istype(source) || !istype(target)) //Invalid input
return
var/turf/T = get_turf(src)
@@ -117,10 +116,11 @@
return
if(!source.is_open_container() || !target.is_open_container())
return
if(!source.reagents.get_free_space() || !target.reagents.get_free_space())
if(!target.reagents.get_free_space())
return
source.reagents.trans_to(target, transfer_amount)
activate_pin(2)
/obj/item/integrated_circuit/reagent/storage
name = "reagent storage"

View File

@@ -8,17 +8,16 @@
cannot see the target, it will not be able to calculate the correct direction."
icon_state = "numberpad"
complexity = 25
inputs = list("target ref")
outputs = list("dir")
activators = list("calculate dir")
inputs = list("\<REF\> target")
outputs = list("\<NUM\> dir")
activators = list("\<PULSE IN\> calculate dir", "\<PULSE OUT\> on calculated")
spawn_flags = IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 5)
power_draw_per_use = 40
/obj/item/integrated_circuit/smart/basic_pathfinder/do_work()
var/datum/integrated_io/I = inputs[1]
var/datum/integrated_io/O = outputs[1]
O.data = null
set_pin_data(IC_OUTPUT, 1, null)
if(!isweakref(I.data))
return
@@ -28,6 +27,6 @@
if(!(A in view(get_turf(src))))
return // Can't see the target.
var/desired_dir = get_dir(get_turf(src), A)
if(desired_dir)
O.data = desired_dir
O.push_data()
set_pin_data(IC_OUTPUT, 1, desired_dir)
push_data()

View File

@@ -12,16 +12,15 @@
This circuit is set to send a pulse after a delay of two seconds."
icon_state = "delay-20"
var/delay = 2 SECONDS
activators = list("incoming pulse","outgoing pulse")
activators = list("\<PULSE IN\> incoming","\<PULSE OUT\> outgoing")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 2
/obj/item/integrated_circuit/time/delay/do_work()
set waitfor = 0 // Don't sleep in a proc that is called by a processor. It'll delay the entire thing
var/datum/integrated_io/out_pulse = activators[2]
sleep(delay)
out_pulse.push_data()
activate_pin(2)
/obj/item/integrated_circuit/time/delay/five_sec
name = "five-sec delay circuit"
@@ -60,14 +59,13 @@
desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \
This circuit's delay can be customized, between 1/10th of a second to one hour. The delay is updated upon receiving a pulse."
icon_state = "delay"
inputs = list("delay time")
inputs = list("\<NUM\> delay time")
spawn_flags = IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/time/delay/custom/do_work()
var/datum/integrated_io/delay_input = inputs[1]
if(delay_input.data && isnum(delay_input.data) )
var/new_delay = min(delay_input.data, 1)
new_delay = max(new_delay, 36000) //An hour.
var/delay_input = get_pin_data(IC_INPUT, 1)
if(delay_input && isnum(delay_input) )
var/new_delay = between(1, delay_input, 36000) //An hour.
delay = new_delay
..()
@@ -80,8 +78,8 @@
var/ticks_to_pulse = 4
var/ticks_completed = 0
var/is_running = FALSE
inputs = list("enable ticking")
activators = list("outgoing pulse")
inputs = list("\<NUM\> enable ticking" = 0)
activators = list("\<PULSE OUT\> outgoing pulse")
spawn_flags = IC_SPAWN_RESEARCH
power_draw_per_use = 4
@@ -91,8 +89,8 @@
. = ..()
/obj/item/integrated_circuit/time/ticker/on_data_written()
var/datum/integrated_io/do_tick = inputs[1]
if(do_tick.data && !is_running)
var/do_tick = get_pin_data(IC_INPUT, 1)
if(do_tick && !is_running)
is_running = TRUE
processing_objects |= src
else if(is_running)
@@ -108,8 +106,7 @@
ticks_completed -= ticks_to_pulse
else
ticks_completed = 0
var/datum/integrated_io/pulser = activators[1]
pulser.push_data()
activate_pin(1)
/obj/item/integrated_circuit/time/ticker/fast
name = "fast ticker"
@@ -134,20 +131,16 @@
desc = "Tells you what the local time is, specific to your station or planet."
icon_state = "clock"
inputs = list()
outputs = list("time (string)", "hours (number)", "minutes (number)", "seconds (number)")
outputs = list("\<TEXT\> time", "\<NUM\> hours", "\<NUM\> minutes", "\<NUM\> seconds")
activators = list("\<PULSE IN\> get time","\<PULSE OUT\> on time got")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 4
/obj/item/integrated_circuit/time/clock/do_work()
var/datum/integrated_io/time = outputs[1]
var/datum/integrated_io/hour = outputs[2]
var/datum/integrated_io/min = outputs[3]
var/datum/integrated_io/sec = outputs[4]
set_pin_data(IC_OUTPUT, 1, time2text(station_time_in_ticks, "hh:mm:ss") )
set_pin_data(IC_OUTPUT, 2, text2num(time2text(station_time_in_ticks, "hh") ) )
set_pin_data(IC_OUTPUT, 3, text2num(time2text(station_time_in_ticks, "mm") ) )
set_pin_data(IC_OUTPUT, 4, text2num(time2text(station_time_in_ticks, "ss") ) )
time.data = time2text(station_time_in_ticks, "hh:mm:ss")
hour.data = text2num(time2text(station_time_in_ticks, "hh"))
min.data = text2num(time2text(station_time_in_ticks, "mm"))
sec.data = text2num(time2text(station_time_in_ticks, "ss"))
for(var/datum/integrated_io/output/O in outputs)
O.push_data()
push_data()
activate_pin(2)

View File

@@ -1,9 +1,18 @@
//These circuits do not-so-simple math.
/obj/item/integrated_circuit/trig
complexity = 1
inputs = list("A","B","C","D","E","F","G","H")
outputs = list("result")
activators = list("compute")
inputs = list(
"\<NUM\> A",
"\<NUM\> B",
"\<NUM\> C",
"\<NUM\> D",
"\<NUM\> E",
"\<NUM\> F",
"\<NUM\> G",
"\<NUM\> H"
)
outputs = list("\<NUM\> result")
activators = list("\<PULSE IN\> compute", "\<PULSE OUT\> on computed")
category_text = "Trig"
extended_desc = "Input and output are in degrees."
autopulse = 1
@@ -19,19 +28,19 @@
name = "sin circuit"
desc = "Has nothing to do with evil, unless you consider trigonometry to be evil. Outputs the sine of A."
icon_state = "sine"
inputs = list("A")
inputs = list("\<NUM\> A")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/sine/do_work()
pull_data()
var/result = null
var/datum/integrated_io/input/A = inputs[1]
A.pull_data()
if(isnum(A.data))
result = sin(A.data)
var/A = get_pin_data(IC_INPUT, 1)
if(isnum(A))
result = sin(A)
var/datum/integrated_io/output/O = outputs[1]
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// Cosine //
@@ -39,19 +48,19 @@
name = "cos circuit"
desc = "Outputs the cosine of A."
icon_state = "cosine"
inputs = list("A")
inputs = list("\<NUM\> A")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/cosine/do_work()
pull_data()
var/result = null
var/datum/integrated_io/input/A = inputs[1]
A.pull_data()
if(isnum(A.data))
result = cos(A.data)
var/A = get_pin_data(IC_INPUT, 1)
if(isnum(A))
result = cos(A)
var/datum/integrated_io/output/O = outputs[1]
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// Tangent //
@@ -59,19 +68,19 @@
name = "tan circuit"
desc = "Outputs the tangent of A. Guaranteed to not go on a tangent about its existance."
icon_state = "tangent"
inputs = list("A")
inputs = list("\<NUM\> A")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/tangent/do_work()
pull_data()
var/result = null
var/datum/integrated_io/input/A = inputs[1]
A.pull_data()
if(isnum(A.data))
result = Tan(A.data)
var/A = get_pin_data(IC_INPUT, 1)
if(isnum(A))
result = Tan(A)
var/datum/integrated_io/output/O = outputs[1]
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// Cosecant //
@@ -79,19 +88,19 @@
name = "csc circuit"
desc = "Outputs the cosecant of A."
icon_state = "cosecant"
inputs = list("A")
inputs = list("\<NUM\> A")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/cosecant/do_work()
pull_data()
var/result = null
var/datum/integrated_io/input/A = inputs[1]
A.pull_data()
if(isnum(A.data))
result = Csc(A.data)
var/A = get_pin_data(IC_INPUT, 1)
if(isnum(A))
result = Csc(A)
var/datum/integrated_io/output/O = outputs[1]
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// Secant //
@@ -100,19 +109,19 @@
name = "sec circuit"
desc = "Outputs the secant of A. Has nothing to do with the security department."
icon_state = "secant"
inputs = list("A")
inputs = list("\<NUM\> A")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/secant/do_work()
pull_data()
var/result = null
var/datum/integrated_io/input/A = inputs[1]
A.pull_data()
if(isnum(A.data))
result = Sec(A.data)
var/A = get_pin_data(IC_INPUT, 1)
if(isnum(A))
result = Sec(A)
var/datum/integrated_io/output/O = outputs[1]
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// Cotangent //
@@ -121,16 +130,16 @@
name = "cot circuit"
desc = "Outputs the cotangent of A."
icon_state = "cotangent"
inputs = list("A")
inputs = list("\<NUM\> A")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/cotangent/do_work()
pull_data()
var/result = null
var/datum/integrated_io/input/A = inputs[1]
A.pull_data()
if(isnum(A.data))
result = Cot(A.data)
var/A = get_pin_data(IC_INPUT, 1)
if(isnum(A))
result = Cot(A)
var/datum/integrated_io/output/O = outputs[1]
O.data = result
O.push_data()
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)

View File

@@ -38,16 +38,11 @@
/datum/lore/codex/page/unathi
name = "Unathi"
data = "The author wishes to apologize to the reader, as they currently lack enough knowledge of the Unathi to write about them, as they are \
rather rare inside Vir." // Replace this when Anewbe finishes the lizard rewrite.
/*
data = "Raging in from Moghes, the Unathi are a race of tall, reptilian humanoids that possess both crocodile-like and serpent-like features. \
They are a proud, warlike species that favors honor and strength, their home, Moghes, is a desert planet but was once believed to be full of life. \
Of all the currently known sentient species, the Unathi are the most unequal in gender with females tending to be property of the males. Most Unathi \
outside of Moghes tend to be exiles however, and with influence of other species the gender difference is not nearly as pronounced. Unathi were \
humanity's second contact, and despite their aggressive nature, seem to get along well enough with humanity, though are often considered to be \
'second-class' citizens and are rarely seen in jobs other than where muscle is needed." // This probably needs to be updated.
*/
data = "The Unathi are a race of tall, reptilian humanoids that possess a blend of serpentine features reminiscent of crocodiles. \
They are a proud, religious species that favors honor and strength, and originate from the desert planet of Moghes. \
The Unathi follow a religious code known as the Unity, and they carry this with them on their travels. \
Unathi once fought a serious war against SolGov, and as a result are often considered to be second-class citizens, \
rarely seen in jobs that don't require a little muscle."
/datum/lore/codex/page/tajaran
name = "Tajaran"

View File

@@ -10,6 +10,7 @@
recipes += new/datum/stack_recipe("[display_name] baseball bat", /obj/item/weapon/material/twohanded/baseballbat, 10, time = 20, one_per_turf = 0, on_floor = 1, supplied_material = "[name]")
recipes += new/datum/stack_recipe("[display_name] ashtray", /obj/item/weapon/material/ashtray, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]")
recipes += new/datum/stack_recipe("[display_name] spoon", /obj/item/weapon/material/kitchen/utensil/spoon/plastic, 1, on_floor = 1, supplied_material = "[name]")
recipes += new/datum/stack_recipe("[display_name] armor plate", /obj/item/weapon/material/armor_plating, 1, time = 20, on_floor = 1, supplied_material = "[name]")
if(integrity>=50)
recipes += new/datum/stack_recipe("[display_name] door", /obj/structure/simple_door, 10, one_per_turf = 1, on_floor = 1, supplied_material = "[name]")

View File

@@ -90,10 +90,12 @@ var/list/name_to_material
var/ignition_point // K, point at which the material catches on fire.
var/melting_point = 1800 // K, walls will take damage if they're next to a fire hotter than this
var/integrity = 150 // General-use HP value for products.
var/protectiveness = 10 // How well this material works as armor. Higher numbers are better, diminishing returns applies.
var/opacity = 1 // Is the material transparent? 0.5< makes transparent walls/doors.
var/reflectivity = 0 // How reflective to light is the material? Currently used for laser defense.
var/reflectivity = 0 // How reflective to light is the material? Currently used for laser reflection and defense.
var/explosion_resistance = 5 // Only used by walls currently.
var/conductive = 1 // Objects with this var add CONDUCTS to flags on spawn.
var/conductivity = null // How conductive the material is. Iron acts as the baseline, at 10.
var/list/composite_material // If set, object matter var will be a list containing these values.
// Placeholder vars for the time being, todo properly integrate windows/light tiles/rods.
@@ -103,7 +105,7 @@ var/list/name_to_material
var/list/window_options = list()
// Damage values.
var/hardness = 60 // Prob of wall destruction by hulk, used for edge damage in weapons.
var/hardness = 60 // Prob of wall destruction by hulk, used for edge damage in weapons. Also used for bullet protection in armor.
var/weight = 20 // Determines blunt damage/throwforce for weapons.
// Noise when someone is faceplanted onto a table made of this material.
@@ -236,6 +238,7 @@ var/list/name_to_material
icon_colour = "#00FFE1"
opacity = 0.4
reflectivity = 0.6
conductivity = 1
shard_type = SHARD_SHARD
tableslam_noise = 'sound/effects/Glasshit.ogg'
hardness = 100
@@ -247,6 +250,7 @@ var/list/name_to_material
icon_colour = "#EDD12F"
weight = 24
hardness = 40
conductivity = 41
stack_origin_tech = list(TECH_MATERIAL = 4)
sheet_singular_name = "ingot"
sheet_plural_name = "ingots"
@@ -261,6 +265,7 @@ var/list/name_to_material
icon_colour = "#D1E6E3"
weight = 22
hardness = 50
conductivity = 63
stack_origin_tech = list(TECH_MATERIAL = 3)
sheet_singular_name = "ingot"
sheet_plural_name = "ingots"
@@ -304,6 +309,8 @@ var/list/name_to_material
shard_type = SHARD_STONE_PIECE
weight = 22
hardness = 55
protectiveness = 5 // 20%
conductivity = 5
door_icon_base = "stone"
sheet_singular_name = "brick"
sheet_plural_name = "bricks"
@@ -320,6 +327,8 @@ var/list/name_to_material
name = DEFAULT_WALL_MATERIAL
stack_type = /obj/item/stack/material/steel
integrity = 150
conductivity = 11 // Assuming this is carbon steel, it would actually be slightly less conductive than iron, but lets ignore that.
protectiveness = 10 // 33%
icon_base = "solid"
icon_reinf = "reinf_over"
icon_colour = "#666666"
@@ -355,6 +364,8 @@ var/list/name_to_material
explosion_resistance = 25
hardness = 80
weight = 23
protectiveness = 20 // 50%
conductivity = 13 // For the purposes of balance.
stack_origin_tech = list(TECH_MATERIAL = 2)
composite_material = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT, "platinum" = SHEET_MATERIAL_AMOUNT) //todo
@@ -370,6 +381,7 @@ var/list/name_to_material
explosion_resistance = 75
hardness = 100
weight = 28
protectiveness = 60 // 75%
reflectivity = 0.7 // Not a perfect mirror, but close.
stack_origin_tech = list(TECH_MATERIAL = 8)
composite_material = list("plasteel" = SHEET_MATERIAL_AMOUNT, "diamond" = SHEET_MATERIAL_AMOUNT) //shrug
@@ -377,6 +389,7 @@ var/list/name_to_material
/material/plasteel/titanium
name = "titanium"
stack_type = null
conductivity = 2.38
icon_base = "metal"
door_icon_base = "metal"
icon_colour = "#D1E6E3"
@@ -393,6 +406,8 @@ var/list/name_to_material
tableslam_noise = 'sound/effects/Glasshit.ogg'
hardness = 30
weight = 15
protectiveness = 0 // 0%
conductivity = 1 // Glass shards don't conduct.
door_icon_base = "stone"
destruction_desc = "shatters"
window_options = list("One Direction" = 1, "Full Window" = 4, "Windoor" = 2)
@@ -526,6 +541,8 @@ var/list/name_to_material
icon_colour = "#CCCCCC"
hardness = 10
weight = 12
protectiveness = 5 // 20%
conductivity = 2 // For the sake of material armor diversity, we're gonna pretend this plastic is a good insulator.
melting_point = T0C+371 //assuming heat resistant plastic
stack_origin_tech = list(TECH_MATERIAL = 3)
@@ -556,12 +573,14 @@ var/list/name_to_material
stack_type = /obj/item/stack/material/mhydrogen
icon_colour = "#E6C5DE"
stack_origin_tech = list(TECH_MATERIAL = 6, TECH_POWER = 6, TECH_MAGNET = 5)
conductivity = 100
/material/platinum
name = "platinum"
stack_type = /obj/item/stack/material/platinum
icon_colour = "#9999FF"
weight = 27
conductivity = 9.43
stack_origin_tech = list(TECH_MATERIAL = 2)
sheet_singular_name = "ingot"
sheet_plural_name = "ingots"
@@ -571,6 +590,7 @@ var/list/name_to_material
stack_type = /obj/item/stack/material/iron
icon_colour = "#5C5454"
weight = 22
conductivity = 10
sheet_singular_name = "ingot"
sheet_plural_name = "ingots"
@@ -585,6 +605,7 @@ var/list/name_to_material
explosion_resistance = 200 // Hull plating.
hardness = 500
weight = 500
protectiveness = 80 // 80%
// Likewise.
/material/alienalloy/elevatorium
@@ -603,6 +624,8 @@ var/list/name_to_material
shard_can_repair = 0 // you can't weld splinters back into planks
hardness = 15
weight = 18
protectiveness = 8 // 28%
conductivity = 1
melting_point = T0C+300 //okay, not melting in this case, but hot enough to destroy wood
ignition_point = T0C+288
stack_origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 1)
@@ -634,6 +657,7 @@ var/list/name_to_material
icon_colour = "#AAAAAA"
hardness = 1
weight = 1
protectiveness = 0 // 0%
ignition_point = T0C+232 //"the temperature at which book-paper catches fire, and burns." close enough
melting_point = T0C+232 //temperature at which cardboard walls would be destroyed
stack_origin_tech = list(TECH_MATERIAL = 1)
@@ -650,6 +674,7 @@ var/list/name_to_material
integrity = 1
hardness = 1
weight = 1
protectiveness = 0 // 0%
stack_origin_tech = list(TECH_MATERIAL = 1)
melting_point = T0C+1
destruction_desc = "crumples"
@@ -662,6 +687,7 @@ var/list/name_to_material
door_icon_base = "wood"
ignition_point = T0C+232
melting_point = T0C+300
protectiveness = 1 // 4%
flags = MATERIAL_PADDING
/material/cult
@@ -695,6 +721,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+300
melting_point = T0C+300
protectiveness = 3 // 13%
/material/carpet
name = "carpet"
@@ -706,6 +733,7 @@ var/list/name_to_material
melting_point = T0C+300
sheet_singular_name = "tile"
sheet_plural_name = "tiles"
protectiveness = 1 // 4%
/material/cotton
name = "cotton"
@@ -714,7 +742,9 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
protectiveness = 1 // 4%
// This all needs to be OOP'd and use inheritence if its ever used in the future.
/material/cloth_teal
name = "teal"
display_name ="teal"
@@ -723,6 +753,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
protectiveness = 1 // 4%
/material/cloth_black
name = "black"
@@ -732,6 +763,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
protectiveness = 1 // 4%
/material/cloth_green
name = "green"
@@ -741,6 +773,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
protectiveness = 1 // 4%
/material/cloth_puple
name = "purple"
@@ -750,6 +783,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
protectiveness = 1 // 4%
/material/cloth_blue
name = "blue"
@@ -759,6 +793,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
protectiveness = 1 // 4%
/material/cloth_beige
name = "beige"
@@ -768,6 +803,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
protectiveness = 1 // 4%
/material/cloth_lime
name = "lime"
@@ -777,6 +813,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
protectiveness = 1 // 4%
/material/toy_foam
name = "foam"
@@ -787,4 +824,5 @@ var/list/name_to_material
melting_point = T0C+300
icon_colour = "#ff9900"
hardness = 1
weight = 1
weight = 1
protectiveness = 0 // 0%

View File

@@ -37,7 +37,7 @@
var/mob/living/carbon/human/H = hit_atom
if(istype(H) && H.has_eyes() && prob(85))
H << "<span class='danger'>Some of \the [src] gets in your eyes!</span>"
H.eye_blind += 5
H.Blind(5)
H.eye_blurry += 10
spawn(1)
if(istype(loc, /turf/)) qdel(src)

View File

@@ -24,7 +24,7 @@
/datum/language/unathi
name = LANGUAGE_UNATHI
desc = "The common language of Moghes, composed of sibilant hisses and rattles. Spoken natively by Unathi."
desc = "The common language of the Moghes Hegemony, composed of sibilant hisses and rattles. Spoken natively by Unathi."
speech_verb = "hisses"
ask_verb = "hisses"
exclaim_verb = "roars"

View File

@@ -70,10 +70,10 @@
/mob/living/bot/updatehealth()
if(status_flags & GODMODE)
health = maxHealth
health = getMaxHealth()
stat = CONSCIOUS
else
health = maxHealth - getFireLoss() - getBruteLoss()
health = getMaxHealth() - getFireLoss() - getBruteLoss()
oxyloss = 0
toxloss = 0
cloneloss = 0
@@ -104,9 +104,9 @@
user << "<span class='notice'>You need to unlock the controls first.</span>"
return
else if(istype(O, /obj/item/weapon/weldingtool))
if(health < maxHealth)
if(health < getMaxHealth())
if(open)
health = min(maxHealth, health + 10)
health = min(getMaxHealth(), health + 10)
user.visible_message("<span class='notice'>[user] repairs [src].</span>","<span class='notice'>You repair [src].</span>")
else
user << "<span class='notice'>Unable to repair with the maintenance panel closed.</span>"
@@ -224,7 +224,7 @@
/mob/living/bot/proc/getPatrolTurf()
var/minDist = INFINITY
var/obj/machinery/navbeacon/targ = locate() in get_turf(src)
if(!targ)
for(var/obj/machinery/navbeacon/N in navbeacons)
if(!N.codes["patrol"])

View File

@@ -73,11 +73,11 @@
// Eyes and blindness.
if(!has_eyes())
eye_blind = 1
SetBlinded(1)
blinded = 1
eye_blurry = 1
else if(eye_blind)
eye_blind = max(eye_blind-1,0)
AdjustBlinded(-1)
blinded = 1
else if(eye_blurry)
eye_blurry = max(eye_blurry-1, 0)

View File

@@ -76,7 +76,7 @@
if(ingested) ingested.metabolize()
if(bloodstr) bloodstr.metabolize()
confused = max(0, confused - 1)
AdjustConfused(-1)
// decrement dizziness counter, clamped to 0
if(resting)
dizziness = max(0, dizziness - 5)
@@ -110,7 +110,7 @@
if(31 to INFINITY)
emp_damage = 30//Let's not overdo it
if(21 to 30)//High level of EMP damage, unable to see, hear, or speak
eye_blind = 1
SetBlinded(1)
blinded = 1
ear_deaf = 1
silent = 1
@@ -123,7 +123,7 @@
if(20)
alert = 0
blinded = 0
eye_blind = 0
SetBlinded(0)
ear_deaf = 0
silent = 0
emp_damage -= 1

View File

@@ -1,11 +1,11 @@
/mob/living/carbon/human/verb/give(var/mob/living/target in view(1)-usr)
/mob/living/carbon/human/verb/give(var/mob/living/carbon/target in view(1)-usr)
set category = "IC"
set name = "Give"
// TODO : Change to incapacitated() on merge.
if(src.stat || src.lying || src.resting || src.buckled)
if(src.stat || src.lying || src.resting || src.handcuffed)
return
if(!istype(target) || target.stat || target.lying || target.resting || target.buckled || target.client == null)
if(!istype(target) || target.stat || target.lying || target.resting || target.handcuffed || target.client == null)
return
var/obj/item/I = src.get_active_hand()

View File

@@ -94,6 +94,7 @@
if(mind.changeling)
stat("Chemical Storage", mind.changeling.chem_charges)
stat("Genetic Damage Time", mind.changeling.geneticdamage)
stat("Re-Adaptations", "[mind.changeling.readapts]/[mind.changeling.max_readapts]")
/mob/living/carbon/human/ex_act(severity)
if(!blinded)
@@ -1518,3 +1519,11 @@
/mob/living/carbon/human/is_muzzled()
return (wear_mask && (istype(wear_mask, /obj/item/clothing/mask/muzzle) || istype(src.wear_mask, /obj/item/weapon/grenade)))
// Called by job_controller. Makes drones start with a permit, might be useful for other people later too.
/mob/living/carbon/human/equip_post_job()
var/braintype = get_FBP_type()
if(braintype == FBP_DRONE)
var/turf/T = get_turf(src)
var/obj/item/weapon/permit/drone/permit = new(T)
permit.set_name(real_name)
equip_to_appropriate_slot(permit) // If for some reason it can't find room, it'll still be on the floor.

View File

@@ -2,7 +2,7 @@
/mob/living/carbon/human/updatehealth()
if(status_flags & GODMODE)
health = maxHealth
health = getMaxHealth()
stat = CONSCIOUS
return
@@ -14,10 +14,10 @@
total_brute += O.brute_dam
total_burn += O.burn_dam
health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
health = getMaxHealth() - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
//TODO: fix husking
if( ((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD)
if( ((getMaxHealth() - total_burn) < config.health_threshold_dead) && stat == DEAD)
ChangeToHusk()
return
@@ -42,7 +42,7 @@
if(should_have_organ("brain"))
var/obj/item/organ/internal/brain/sponge = internal_organs_by_name["brain"]
if(sponge)
sponge.damage = min(max(amount, 0),(maxHealth*2))
sponge.damage = min(max(amount, 0),(getMaxHealth()*2))
brainloss = sponge.damage
else
brainloss = 200
@@ -56,7 +56,7 @@
if(should_have_organ("brain"))
var/obj/item/organ/internal/brain/sponge = internal_organs_by_name["brain"]
if(sponge)
brainloss = min(sponge.damage,maxHealth*2)
brainloss = min(sponge.damage,getMaxHealth()*2)
else
brainloss = 200
else
@@ -99,16 +99,32 @@
/mob/living/carbon/human/adjustBruteLoss(var/amount)
amount = amount*species.brute_mod
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
amount *= M.incoming_brute_damage_percent
take_overall_damage(amount, 0)
else
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_healing_percent))
amount *= M.incoming_healing_percent
heal_overall_damage(-amount, 0)
BITSET(hud_updateflag, HEALTH_HUD)
/mob/living/carbon/human/adjustFireLoss(var/amount)
amount = amount*species.burn_mod
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_fire_damage_percent))
amount *= M.incoming_fire_damage_percent
take_overall_damage(0, amount)
else
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_healing_percent))
amount *= M.incoming_healing_percent
heal_overall_damage(0, -amount)
BITSET(hud_updateflag, HEALTH_HUD)
@@ -118,8 +134,16 @@
var/obj/item/organ/external/O = get_organ(organ_name)
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
amount *= M.incoming_brute_damage_percent
O.take_damage(amount, 0, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
else
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_healing_percent))
amount *= M.incoming_healing_percent
//if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
O.heal_damage(-amount, 0, internal=0, robo_repair=(O.robotic >= ORGAN_ROBOT))
@@ -131,8 +155,16 @@
var/obj/item/organ/external/O = get_organ(organ_name)
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_fire_damage_percent))
amount *= M.incoming_fire_damage_percent
O.take_damage(0, amount, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
else
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_healing_percent))
amount *= M.incoming_healing_percent
//if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
O.heal_damage(0, -amount, internal=0, robo_repair=(O.robotic >= ORGAN_ROBOT))
@@ -400,11 +432,25 @@ This function restores all organs.
if(BRUTE)
damageoverlaytemp = 20
damage = damage*species.brute_mod
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
damage *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
damage *= M.incoming_brute_damage_percent
if(organ.take_damage(damage, 0, sharp, edge, used_weapon))
UpdateDamageIcon()
if(BURN)
damageoverlaytemp = 20
damage = damage*species.burn_mod
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
damage *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
damage *= M.incoming_fire_damage_percent
if(organ.take_damage(0, damage, sharp, edge, used_weapon))
UpdateDamageIcon()

View File

@@ -27,6 +27,11 @@ emp_act
if(!P.nodamage)
organ.add_autopsy_data("[P.name]", P.damage)
// Tell clothing we're wearing that it got hit by a bullet/laser/etc
var/list/clothing = get_clothing_list_organ(organ)
for(var/obj/item/clothing/C in clothing)
C.clothing_impact(P, P.damage)
//Shrapnel
if(P.can_embed())
var/armor = getarmor_organ(organ, "bullet")
@@ -130,6 +135,15 @@ emp_act
return siemens_coefficient
// Returns a list of clothing that is currently covering def_zone.
/mob/living/carbon/human/proc/get_clothing_list_organ(var/obj/item/organ/external/def_zone, var/type)
var/list/results = list()
var/list/clothing_items = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes)
for(var/obj/item/clothing/C in clothing_items)
if(istype(C) && (C.body_parts_covered & def_zone.body_part))
results.Add(C)
return results
//this proc returns the armour value for a particular external organ.
/mob/living/carbon/human/proc/getarmor_organ(var/obj/item/organ/external/def_zone, var/type)
if(!type || !def_zone) return 0
@@ -231,10 +245,6 @@ emp_act
var/soaked = get_armor_soak(hit_zone, "melee", I.armor_penetration)
if(soaked >= effective_force)
src << "Your armor absorbs the force of [I.name]!"
return
var/blocked = run_armor_check(hit_zone, "melee", I.armor_penetration, "Your armor has protected your [affecting.name].", "Your armor has softened the blow to your [affecting.name].")
standard_weapon_hit_effects(I, user, effective_force, blocked, soaked, hit_zone)
@@ -246,9 +256,14 @@ emp_act
if(!affecting)
return 0
if(soaked >= effective_force)
return 0
// Allow clothing to respond to being hit.
// This is done up here so that clothing damage occurs even if fully blocked.
var/list/clothing = get_clothing_list_organ(affecting)
for(var/obj/item/clothing/C in clothing)
C.clothing_impact(I, effective_force)
if(soaked >= round(effective_force*0.8))
effective_force -= round(effective_force*0.8)
// Handle striking to cripple.
if(user.a_intent == I_DISARM)
effective_force *= 0.5 //reduced effective force...
@@ -309,12 +324,15 @@ emp_act
return 1
/mob/living/carbon/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/W, var/effective_force, var/dislocate_mult, var/blocked, var/soaked)
if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1) || blocked >= 100 || soaked > effective_force)
if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1) || blocked >= 100)
return 0
if(W.damtype != BRUTE)
return 0
if(soaked >= round(effective_force*0.8))
effective_force -= round(effective_force*0.8)
//want the dislocation chance to be such that the limb is expected to dislocate after dealing a fraction of the damage needed to break the limb
var/dislocate_chance = effective_force/(dislocate_mult * organ.min_broken_damage * config.organ_health_multiplier)*100
if(prob(dislocate_chance * (100 - blocked)/100))

View File

@@ -95,3 +95,5 @@
mob_swap_flags = ~HEAVY
var/identifying_gender // In case the human identifies as another gender than it's biological
var/step_count = 0 // Track how many footsteps have been taken to know when to play footstep sounds

View File

@@ -90,6 +90,24 @@
return 0
// Returns a string based on what kind of brain the FBP has.
/mob/living/carbon/human/proc/get_FBP_type()
if(!isSynthetic())
return FBP_NONE
var/obj/item/organ/internal/brain/B
B = internal_organs_by_name[O_BRAIN]
if(B) // Incase we lost our brain for some reason, like if we got decapped.
if(istype(B, /obj/item/organ/internal/mmi_holder))
var/obj/item/organ/internal/mmi_holder/mmi_holder = B
if(istype(mmi_holder.stored_mmi, /obj/item/device/mmi/digital/posibrain))
return FBP_POSI
else if(istype(mmi_holder.stored_mmi, /obj/item/device/mmi/digital/robot))
return FBP_DRONE
else if(istype(mmi_holder.stored_mmi, /obj/item/device/mmi)) // This needs to come last because inheritence.
return FBP_CYBORG
return FBP_NONE
#undef HUMAN_EATING_NO_ISSUE
#undef HUMAN_EATING_NO_MOUTH
#undef HUMAN_EATING_BLOCKED_MOUTH

View File

@@ -15,7 +15,11 @@
if(force_max_speed)
return -3 // Returning -1 will actually result in a slowdown for Teshari.
var/health_deficiency = (maxHealth - health)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.slowdown))
tally += M.slowdown
var/health_deficiency = (getMaxHealth() - health)
if(health_deficiency >= 40) tally += (health_deficiency / 25)
if(can_feel_pain())
@@ -146,3 +150,36 @@
prob_slip = round(prob_slip)
return(prob_slip)
// Handle footstep sounds
/mob/living/carbon/human/handle_footstep(var/turf/T)
if(!config.footstep_volume || !T.footstep_sounds || !T.footstep_sounds.len)
return
// Future Upgrades - Multi species support
var/list/footstep_sounds = T.footstep_sounds["human"]
if(!footstep_sounds)
return
var/S = pick(footstep_sounds)
if(!S) return
// Only play every other step while running
if(m_intent == "run" && step_count++ % 2 == 0)
return
var/volume = config.footstep_volume
// Reduce volume while walking or barefoot
if(!shoes || m_intent != "run")
volume *= 0.5
if(!has_organ(BP_L_FOOT) && !has_organ(BP_R_FOOT))
return // no feet = no footsteps
if(buckled || lying || throwing)
return // people flying, lying down or sitting do not step
if(!has_gravity(src) && prob(75))
return // Far less likely to make noise in no gravity
playsound(T, S, volume, FALSE)
return

View File

@@ -971,18 +971,18 @@
vision = internal_organs_by_name[species.vision_organ]
if(!species.vision_organ) // Presumably if a species has no vision organs, they see via some other means.
eye_blind = 0
SetBlinded(0)
blinded = 0
eye_blurry = 0
else if(!vision || vision.is_broken()) // Vision organs cut out or broken? Permablind.
eye_blind = 1
SetBlinded(1)
blinded = 1
eye_blurry = 1
else //You have the requisite organs
if(sdisabilities & BLIND) // Disabled-blind, doesn't get better on its own
blinded = 1
else if(eye_blind) // Blindness, heals slowly over time
eye_blind = max(eye_blind-1,0)
AdjustBlinded(-1)
blinded = 1
else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) //resting your eyes with a blindfold heals blurry eyes faster
eye_blurry = max(eye_blurry-3, 0)
@@ -1542,7 +1542,7 @@
if(stat == DEAD)
holder.icon_state = "-100" // X_X
else
holder.icon_state = RoundHealth((health-config.health_threshold_crit)/(maxHealth-config.health_threshold_crit)*100)
holder.icon_state = RoundHealth((health-config.health_threshold_crit)/(getMaxHealth()-config.health_threshold_crit)*100)
hud_list[HEALTH_HUD] = holder
if (BITTEST(hud_updateflag, LIFE_HUD))

View File

@@ -36,6 +36,8 @@
slowdown = 0.5
brute_mod = 0.9
burn_mod = 0.9
metabolic_rate = 0.85
item_slowdown_halved = 1
num_alternate_languages = 3
secondary_langs = list(LANGUAGE_UNATHI)
name_language = LANGUAGE_UNATHI
@@ -62,11 +64,36 @@
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
flesh_color = "#34AF10"
//reagent_tag = IS_UNATHI //VOREStation Removal
blood_color = "#b3cbc3"
base_color = "#066000"
//heat_discomfort_level = 295 //VOREStation Removal
//reagent_tag = IS_UNATHI //VOREStation Edit
has_limbs = list(
BP_TORSO = list("path" = /obj/item/organ/external/chest/unathi),
BP_GROIN = list("path" = /obj/item/organ/external/groin/unathi),
BP_HEAD = list("path" = /obj/item/organ/external/head/unathi),
BP_L_ARM = list("path" = /obj/item/organ/external/arm),
BP_R_ARM = list("path" = /obj/item/organ/external/arm/right),
BP_L_LEG = list("path" = /obj/item/organ/external/leg),
BP_R_LEG = list("path" = /obj/item/organ/external/leg/right),
BP_L_HAND = list("path" = /obj/item/organ/external/hand),
BP_R_HAND = list("path" = /obj/item/organ/external/hand/right),
BP_L_FOOT = list("path" = /obj/item/organ/external/foot),
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
)
//No kidneys or appendix
has_organ = list(
O_HEART = /obj/item/organ/internal/heart/unathi,
O_LUNGS = /obj/item/organ/internal/lungs/unathi,
O_LIVER = /obj/item/organ/internal/liver/unathi,
O_BRAIN = /obj/item/organ/internal/brain/unathi,
O_EYES = /obj/item/organ/internal/eyes,
)
//heat_discomfort_level = 295 //VOREStation Edit
heat_discomfort_strings = list(
"You feel soothingly warm.",
"You feel the heat sink into your bones.",

View File

@@ -80,7 +80,7 @@
src.blinded = null
health = maxHealth - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
health = getMaxHealth() - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
if(health < 0 && stat != DEAD)
death()
@@ -118,7 +118,7 @@
if (src.stuttering) src.stuttering = 0
if (src.eye_blind)
src.eye_blind = 0
SetBlinded(0)
src.blinded = 1
if (src.ear_deaf > 0) src.ear_deaf = 0

View File

@@ -81,7 +81,7 @@
var/tally = 0
var/health_deficiency = (maxHealth - health)
var/health_deficiency = (getMaxHealth() - health)
if(health_deficiency >= 30) tally += (health_deficiency / 25)
if (bodytemperature < 183.222)
@@ -146,7 +146,7 @@
..()
statpanel("Status")
stat(null, "Health: [round((health / maxHealth) * 100)]%")
stat(null, "Health: [round((health / getMaxHealth()) * 100)]%")
stat(null, "Intent: [a_intent]")
if (client.statpanel == "Status")

View File

@@ -21,7 +21,7 @@
return "I cannot feed on other slimes..."
if (!Adjacent(M))
return "This subject is too far away..."
if (istype(M, /mob/living/carbon) && M.getCloneLoss() >= M.maxHealth * 1.5 || istype(M, /mob/living/simple_animal) && M.stat == DEAD)
if (istype(M, /mob/living/carbon) && M.getCloneLoss() >= M.getMaxHealth() * 1.5 || istype(M, /mob/living/simple_animal) && M.stat == DEAD)
return "This subject does not have an edible life energy..."
for(var/mob/living/carbon/slime/met in view())
if(met.Victim == M && met != src)

View File

@@ -11,10 +11,13 @@
/mob/living/proc/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/soaked = 0, var/used_weapon = null, var/sharp = 0, var/edge = 0)
if(Debug2)
world.log << "## DEBUG: apply_damage() was called on [src], with [damage] damage, and an armor value of [blocked]."
if(!damage || (blocked >= 100) || soaked >= damage)
if(!damage || (blocked >= 100))
return 0
if(soaked)
damage -= soaked
if(soaked >= round(damage*0.8))
damage -= round(damage*0.8)
else
damage -= soaked
blocked = (100-blocked)/100
switch(damagetype)
if(BRUTE)

View File

@@ -10,6 +10,8 @@
return
var/datum/gas_mixture/environment = loc.return_air()
handle_modifiers() // Do this early since it might affect other things later.
if(stat != DEAD)
//Breathing, if applicable
handle_breathing()
@@ -150,9 +152,9 @@
/mob/living/proc/handle_disabilities()
//Eyes
if(sdisabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own
eye_blind = max(eye_blind, 1)
SetBlinded(1)
else if(eye_blind) //blindness, heals slowly over time
eye_blind = max(eye_blind-1,0)
AdjustBlinded(-1)
else if(eye_blurry) //blurry eyes heal slowly
eye_blurry = max(eye_blurry-1, 0)

View File

@@ -163,9 +163,9 @@ default behaviour is:
/mob/living/verb/succumb()
set hidden = 1
if ((src.health < 0 && src.health > (5-src.maxHealth))) // Health below Zero but above 5-away-from-death, as before, but variable
src.adjustOxyLoss(src.health + src.maxHealth * 2) // Deal 2x health in OxyLoss damage, as before but variable.
src.health = src.maxHealth - src.getOxyLoss() - src.getToxLoss() - src.getFireLoss() - src.getBruteLoss()
if ((src.health < 0 && src.health > (5-src.getMaxHealth()))) // Health below Zero but above 5-away-from-death, as before, but variable
src.adjustOxyLoss(src.health + src.getMaxHealth() * 2) // Deal 2x health in OxyLoss damage, as before but variable.
src.health = src.getMaxHealth() - src.getOxyLoss() - src.getToxLoss() - src.getFireLoss() - src.getBruteLoss()
src << "\blue You have given up life and succumbed to death."
@@ -174,7 +174,7 @@ default behaviour is:
health = 100
stat = CONSCIOUS
else
health = maxHealth - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss() - halloss
health = getMaxHealth() - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss() - halloss
//This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually
@@ -236,14 +236,38 @@ default behaviour is:
/mob/living/proc/adjustBruteLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
bruteloss = min(max(bruteloss + amount, 0),(maxHealth*2))
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
amount *= M.incoming_brute_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_healing_percent))
amount *= M.incoming_healing_percent
bruteloss = min(max(bruteloss + amount, 0),(getMaxHealth()*2))
/mob/living/proc/getOxyLoss()
return oxyloss
/mob/living/proc/adjustOxyLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
oxyloss = min(max(oxyloss + amount, 0),(maxHealth*2))
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_oxy_damage_percent))
amount *= M.incoming_oxy_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_healing_percent))
amount *= M.incoming_healing_percent
oxyloss = min(max(oxyloss + amount, 0),(getMaxHealth()*2))
/mob/living/proc/setOxyLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
@@ -254,7 +278,19 @@ default behaviour is:
/mob/living/proc/adjustToxLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
toxloss = min(max(toxloss + amount, 0),(maxHealth*2))
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_tox_damage_percent))
amount *= M.incoming_tox_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_healing_percent))
amount *= M.incoming_healing_percent
toxloss = min(max(toxloss + amount, 0),(getMaxHealth()*2))
/mob/living/proc/setToxLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
@@ -268,14 +304,37 @@ default behaviour is:
/mob/living/proc/adjustFireLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
fireloss = min(max(fireloss + amount, 0),(maxHealth*2))
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_fire_damage_percent))
amount *= M.incoming_fire_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_healing_percent))
amount *= M.incoming_healing_percent
fireloss = min(max(fireloss + amount, 0),(getMaxHealth()*2))
/mob/living/proc/getCloneLoss()
return cloneloss
/mob/living/proc/adjustCloneLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
cloneloss = min(max(cloneloss + amount, 0),(maxHealth*2))
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_clone_damage_percent))
amount *= M.incoming_clone_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_healing_percent))
amount *= M.incoming_healing_percent
cloneloss = min(max(cloneloss + amount, 0),(getMaxHealth()*2))
/mob/living/proc/setCloneLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
@@ -286,7 +345,7 @@ default behaviour is:
/mob/living/proc/adjustBrainLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
brainloss = min(max(brainloss + amount, 0),(maxHealth*2))
brainloss = min(max(brainloss + amount, 0),(getMaxHealth()*2))
/mob/living/proc/setBrainLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
@@ -297,18 +356,117 @@ default behaviour is:
/mob/living/proc/adjustHalLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
halloss = min(max(halloss + amount, 0),(maxHealth*2))
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_hal_damage_percent))
amount *= M.incoming_hal_damage_percent
if(!isnull(M.disable_duration_percent))
amount *= M.incoming_hal_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_healing_percent))
amount *= M.incoming_healing_percent
halloss = min(max(halloss + amount, 0),(getMaxHealth()*2))
/mob/living/proc/setHalLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
halloss = amount
// Use this to get a mob's max health whenever possible. Reading maxHealth directly will give inaccurate results if any modifiers exist.
/mob/living/proc/getMaxHealth()
return maxHealth
var/result = maxHealth
for(var/datum/modifier/M in modifiers)
if(!isnull(M.max_health_flat))
result += M.max_health_flat
// Second loop is so we can get all the flat adjustments first before multiplying, otherwise the result will be different.
for(var/datum/modifier/M in modifiers)
if(!isnull(M.max_health_percent))
result *= M.max_health_percent
return result
/mob/living/proc/setMaxHealth(var/newMaxHealth)
maxHealth = newMaxHealth
/mob/living/Stun(amount)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.disable_duration_percent))
amount = round(amount * M.disable_duration_percent)
..(amount)
/mob/living/AdjustStunned(amount)
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.disable_duration_percent))
amount = round(amount * M.disable_duration_percent)
..(amount)
/mob/living/Weaken(amount)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.disable_duration_percent))
amount = round(amount * M.disable_duration_percent)
..(amount)
/mob/living/AdjustWeakened(amount)
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.disable_duration_percent))
amount = round(amount * M.disable_duration_percent)
..(amount)
/mob/living/Paralyse(amount)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.disable_duration_percent))
amount = round(amount * M.disable_duration_percent)
..(amount)
/mob/living/AdjustParalysis(amount)
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.disable_duration_percent))
amount = round(amount * M.disable_duration_percent)
..(amount)
/mob/living/Sleeping(amount)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.disable_duration_percent))
amount = round(amount * M.disable_duration_percent)
..(amount)
/mob/living/AdjustSleeping(amount)
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.disable_duration_percent))
amount = round(amount * M.disable_duration_percent)
..(amount)
/mob/living/Confuse(amount)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.disable_duration_percent))
amount = round(amount * M.disable_duration_percent)
..(amount)
/mob/living/AdjustConfused(amount)
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.disable_duration_percent))
amount = round(amount * M.disable_duration_percent)
..(amount)
/mob/living/Blind(amount)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.disable_duration_percent))
amount = round(amount * M.disable_duration_percent)
..(amount)
/mob/living/AdjustBlinded(amount)
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.disable_duration_percent))
amount = round(amount * M.disable_duration_percent)
..(amount)
// ++++ROCKDTBEN++++ MOB PROCS //END
/mob/proc/get_contents()
@@ -446,7 +604,7 @@ default behaviour is:
// fix blindness and deafness
blinded = 0
eye_blind = 0
SetBlinded(0)
eye_blurry = 0
ear_deaf = 0
ear_damage = 0
@@ -585,6 +743,9 @@ default behaviour is:
for(var/mob/living/carbon/slime/M in view(1,src))
M.UpdateFeed(src)
/mob/living/proc/handle_footstep(turf/T)
return FALSE
/mob/living/verb/resist()
set name = "Resist"
set category = "IC"
@@ -821,3 +982,7 @@ default behaviour is:
if(isSynthetic())
return FALSE
return TRUE
// Called by job_controller.
/mob/living/proc/equip_post_job()
return

View File

@@ -107,6 +107,11 @@
var/absorb = run_armor_check(def_zone, P.check_armour, P.armor_penetration)
var/proj_sharp = is_sharp(P)
var/proj_edge = has_edge(P)
if ((proj_sharp || proj_edge) && (soaked >= round(P.damage*0.8)))
proj_sharp = 0
proj_edge = 0
if ((proj_sharp || proj_edge) && prob(getarmor(def_zone, P.check_armour)))
proj_sharp = 0
proj_edge = 0
@@ -167,13 +172,11 @@
var/soaked = get_armor_soak(hit_zone, "melee")
var/blocked = run_armor_check(hit_zone, "melee")
//If the armor absorbs all of the damage, skip the damage calculation and the blood
if(!(soaked > effective_force))
standard_weapon_hit_effects(I, user, effective_force, blocked, soaked, hit_zone)
standard_weapon_hit_effects(I, user, effective_force, blocked, soaked, hit_zone)
if(I.damtype == BRUTE && prob(33)) // Added blood for whacking non-humans too
var/turf/simulated/location = get_turf(src)
if(istype(location)) location.add_blood_floor(src)
if(I.damtype == BRUTE && prob(33)) // Added blood for whacking non-humans too
var/turf/simulated/location = get_turf(src)
if(istype(location)) location.add_blood_floor(src)
return blocked
@@ -186,13 +189,14 @@
if(HULK in user.mutations)
effective_force *= 2
//Armor soak
if(soaked >= effective_force)
return 0
//Apply weapon damage
var/weapon_sharp = is_sharp(I)
var/weapon_edge = has_edge(I)
if(getsoak(hit_zone, "melee",) - (I.armor_penetration/5) > round(effective_force*0.8)) //soaking a hit turns sharp attacks into blunt ones
weapon_sharp = 0
weapon_edge = 0
if(prob(max(getarmor(hit_zone, "melee") - I.armor_penetration, 0))) //melee armour provides a chance to turn sharp/edge weapon attacks into blunt ones
weapon_sharp = 0
weapon_edge = 0
@@ -251,7 +255,7 @@
if(!O || !src) return
if(O.sharp) //Projectile is suitable for pinning.
if(soaked >= throw_damage) //Don't embed if it didn't actually damage
if(soaked >= round(throw_damage*0.8))
return
//Handles embedding for non-humans and simple_animals.

View File

@@ -2,7 +2,7 @@
see_invisible = SEE_INVISIBLE_LIVING
//Health and life related vars
var/maxHealth = 100 //Maximum health that should be possible.
var/maxHealth = 100 //Maximum health that should be possible. Avoid adjusting this if you can, and instead use modifiers datums.
var/health = 100 //A mob's health
var/hud_updateflag = 0

View File

@@ -1,7 +1,6 @@
/obj/machinery/computer/drone_control
name = "Maintenance Drone Control"
desc = "Used to monitor the station's drone population and the assembler that services them."
icon = 'icons/obj/computer.dmi'
icon_keyboard = "power_key"
icon_screen = "power"
req_access = list(access_engine_equip)

View File

@@ -98,7 +98,7 @@
else //Not stunned.
src.stat = 0
confused = max(0, confused - 1)
AdjustConfused(-1)
else //Dead.
src.blinded = 1
@@ -107,7 +107,7 @@
if (src.stuttering) src.stuttering--
if (src.eye_blind)
src.eye_blind--
src.AdjustBlinded(-1)
src.blinded = 1
if (src.ear_deaf > 0) src.ear_deaf--

View File

@@ -1,9 +1,9 @@
/mob/living/silicon/robot/updatehealth()
if(status_flags & GODMODE)
health = maxHealth
health = getMaxHealth()
stat = CONSCIOUS
return
health = maxHealth - (getBruteLoss() + getFireLoss())
health = getMaxHealth() - (getBruteLoss() + getFireLoss())
return
/mob/living/silicon/robot/getBruteLoss()

View File

@@ -63,16 +63,16 @@
switch(severity)
if(1)
src.take_organ_damage(0,20,emp=1)
confused = (min(confused + 5, 30))
Confuse(5)
if(2)
src.take_organ_damage(0,15,emp=1)
confused = (min(confused + 4, 30))
Confuse(4)
if(3)
src.take_organ_damage(0,10,emp=1)
confused = (min(confused + 3, 30))
Confuse(3)
if(4)
src.take_organ_damage(0,5,emp=1)
confused = (min(confused + 2, 30))
Confuse(2)
flash_eyes(affect_silicon = 1)
src << "<span class='danger'><B>*BZZZT*</B></span>"
src << "<span class='danger'>Warning: Electromagnetic pulse detected.</span>"
@@ -148,7 +148,7 @@
// this function shows the health of the AI in the Status panel
/mob/living/silicon/proc/show_system_integrity()
if(!src.stat)
stat(null, text("System integrity: [round((health/maxHealth)*100)]%"))
stat(null, text("System integrity: [round((health/getMaxHealth())*100)]%"))
else
stat(null, text("Systems nonfunctional"))

View File

@@ -17,7 +17,7 @@
response_help = "pokes"
response_disarm = "gently pushes aside"
response_harm = "hits"
a_intent = I_HURT
ranged = 1
rapid = 1
@@ -99,16 +99,16 @@
src.visible_message("\red \icon[src] [src] suddenly lights up, and additional targetting vanes slide into place.")
hostile = 1
if(health / maxHealth > 0.9)
if(health / getMaxHealth() > 0.9)
icon_state = "drone3"
explode_chance = 0
else if(health / maxHealth > 0.7)
else if(health / getMaxHealth() > 0.7)
icon_state = "drone2"
explode_chance = 0
else if(health / maxHealth > 0.5)
else if(health / getMaxHealth() > 0.5)
icon_state = "drone1"
explode_chance = 0.5
else if(health / maxHealth > 0.3)
else if(health / getMaxHealth() > 0.3)
icon_state = "drone0"
explode_chance = 5
else if(health > 0)

View File

@@ -95,10 +95,10 @@
if (istype(O, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = O
if (WT.remove_fuel(0))
if(health < maxHealth)
if(health < getMaxHealth())
health += pick(1,1,1,2,2,3)
if(health > maxHealth)
health = maxHealth
if(health > getMaxHealth())
health = getMaxHealth()
add_fingerprint(user)
src.visible_message("<span class='notice'>\The [user] has spot-welded some of the damage to \the [src]!</span>")
else

View File

@@ -57,7 +57,7 @@
/mob/living/simple_animal/construct/attack_generic(var/mob/user)
if(istype(user, /mob/living/simple_animal/construct/builder))
if(health < maxHealth)
if(health < getMaxHealth())
adjustBruteLoss(-5)
user.visible_message("<span class='notice'>\The [user] mends some of \the [src]'s wounds.</span>")
else
@@ -68,9 +68,9 @@
/mob/living/simple_animal/construct/examine(mob/user)
..(user)
var/msg = "<span cass='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n"
if (src.health < src.maxHealth)
if (src.health < src.getMaxHealth())
msg += "<span class='warning'>"
if (src.health >= src.maxHealth/2)
if (src.health >= src.getMaxHealth()/2)
msg += "It looks slightly dented.\n"
else
msg += "<B>It looks severely dented!</B>\n"

View File

@@ -170,7 +170,7 @@
T.forceMove(src) //put shade in stone
T.status_flags |= GODMODE
T.canmove = 0
T.health = T.maxHealth
T.health = T.getMaxHealth()
src.icon_state = "soulstone2"
T << "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form"

View File

@@ -75,7 +75,7 @@
/mob/living/simple_animal/hostile/mecha/Life()
. = ..()
if(!.) return
if((health < maxHealth*0.3) && prob(10))
if((health < getMaxHealth()*0.3) && prob(10))
sparks.start()
/mob/living/simple_animal/hostile/mecha/bullet_act()

View File

@@ -234,8 +234,8 @@
density = 1
//Overhealth
else if(health > maxHealth)
health = maxHealth
else if(health > getMaxHealth())
health = getMaxHealth()
/mob/living/simple_animal/update_icon()
..()
@@ -534,7 +534,7 @@
if(istype(O, /obj/item/stack/medical))
if(stat != DEAD)
var/obj/item/stack/medical/MED = O
if(health < maxHealth)
if(health < getMaxHealth())
if(MED.amount >= 1)
adjustBruteLoss(-MED.heal_brute)
MED.amount -= 1
@@ -602,7 +602,7 @@
..()
if(statpanel("Status") && show_stat_health)
stat(null, "Health: [round((health / maxHealth) * 100)]%")
stat(null, "Health: [round((health / getMaxHealth()) * 100)]%")
/mob/living/simple_animal/lay_down()
..()
@@ -645,10 +645,10 @@
adjustBruteLoss(30)
/mob/living/simple_animal/adjustBruteLoss(damage)
health = Clamp(health - damage, 0, maxHealth)
health = Clamp(health - damage, 0, getMaxHealth())
/mob/living/simple_animal/adjustFireLoss(damage)
health = Clamp(health - damage, 0, maxHealth)
health = Clamp(health - damage, 0, getMaxHealth())
// Check target_mob if worthy of attack (i.e. check if they are dead or empty mecha)
/mob/living/simple_animal/proc/SA_attackable(target_mob)

View File

@@ -805,6 +805,30 @@
sleeping = max(sleeping + amount,0)
return
/mob/proc/Confuse(amount)
confused = max(max(confused,amount),0)
return
/mob/proc/SetConfused(amount)
confused = max(amount,0)
return
/mob/proc/AdjustConfused(amount)
confused = max(confused + amount,0)
return
/mob/proc/Blind(amount)
eye_blind = max(max(eye_blind,amount),0)
return
/mob/proc/SetBlinded(amount)
eye_blind = max(amount,0)
return
/mob/proc/AdjustBlinded(amount)
eye_blind = max(eye_blind + amount,0)
return
/mob/proc/Resting(amount)
facing_dir = null
resting = max(max(resting,amount),0)

View File

@@ -170,7 +170,7 @@
if(announce)
assailant.visible_message("<span class='warning'>[assailant] covers [affecting]'s eyes!</span>")
if(affecting.eye_blind < 3)
affecting.eye_blind = 3
affecting.Blind(3)
/obj/item/weapon/grab/attack_self()
return s_click(hud)

View File

@@ -0,0 +1,106 @@
// This is a datum that tells the mob that something is affecting them.
// The advantage of using this datum verses just setting a variable on the mob directly, is that there is no risk of two different procs overwriting
// each other, or other weirdness. An excellent example is adjusting max health.
/datum/modifier
var/name = null // Mostly used to organize, might show up on the UI in the Future(tm)
var/desc = null // Ditto.
var/icon_state = null // See above.
var/mob/living/holder = null // The mob that this datum is affecting.
var/expire_at = null // world.time when holder's Life() will remove the datum. If null, it lasts forever or until it gets deleted by something else.
var/on_created_text = null // Text to show to holder upon being created.
var/on_expired_text = null // Text to show to holder when it expires.
var/hidden = FALSE // If true, it will not show up on the HUD in the Future(tm)
var/stacks = MODIFIER_STACK_FORBID // If true, attempts to add a second instance of this type will refresh expire_at instead.
var/flags = 0 // Flags for the modifier, see mobs.dm defines for more details.
// Now for all the different effects.
// Percentage modifiers are expressed as a multipler. (e.g. +25% damage should be written as 1.25)
var/max_health_flat // Adjusts max health by a flat (e.g. +20) amount. Note this is added to base health.
var/max_health_percent // Adjusts max health by a percentage (e.g. -30%).
var/disable_duration_percent // Adjusts duration of 'disables' (stun, weaken, paralyze, confusion, sleep, halloss, etc) Setting to 0 will grant immunity.
var/incoming_damage_percent // Adjusts all incoming damage.
var/incoming_brute_damage_percent // Only affects bruteloss.
var/incoming_fire_damage_percent // Only affects fireloss.
var/incoming_tox_damage_percent // Only affects toxloss.
var/incoming_oxy_damage_percent // Only affects oxyloss.
var/incoming_clone_damage_percent // Only affects cloneloss.
var/incoming_hal_damage_percent // Only affects halloss.
var/incoming_healing_percent // Adjusts amount of healing received.
var/outgoing_melee_damage_percent // Adjusts melee damage inflicted by holder by a percentage. Affects attacks by melee weapons and hand-to-hand.
var/slowdown // Negative numbers speed up, positive numbers slow down movement.
/datum/modifier/New(var/new_holder)
holder = new_holder
..()
// Checks to see if this datum should continue existing.
/datum/modifier/proc/check_if_valid()
if(expire_at && expire_at < world.time) // Is our time up?
src.expire()
/datum/modifier/proc/expire(var/silent = FALSE)
if(on_expired_text && !silent)
to_chat(holder, on_expired_text)
on_expire()
holder.modifiers.Remove(src)
qdel(src)
// Override this for special effects when it gets removed.
/datum/modifier/proc/on_expire()
return
/mob/living
var/list/modifiers = list() // A list of modifier datums, which can adjust certain mob numbers.
/mob/living/Destroy()
remove_all_modifiers(TRUE)
..()
// Called by Life().
/mob/living/proc/handle_modifiers()
if(!modifiers.len) // No work to do.
return
// Get rid of anything we shouldn't have.
for(var/datum/modifier/M in modifiers)
M.check_if_valid()
// Call this to add a modifier to a mob. First argument is the modifier type you want, second is how long it should last, in ticks.
// The SECONDS/MINUTES macro is very helpful for this. E.g. M.add_modifier(/datum/modifier/example, 5 MINUTES)
/mob/living/proc/add_modifier(var/modifier_type, var/expire_at = null)
// First, check if the mob already has this modifier.
for(var/datum/modifier/M in modifiers)
if(ispath(modifier_type, M.type))
switch(M.stacks)
if(MODIFIER_STACK_FORBID)
return // Stop here.
if(MODIFIER_STACK_ALLOWED)
break // No point checking anymore.
if(MODIFIER_STACK_EXTEND)
// Not allow to add a second instance, but we can try to prolong the first instance.
if(expire_at && world.time + expire_at > M.expire_at)
M.expire_at = world.time + expire_at
return
// If we're at this point, the mob doesn't already have it, or it does but stacking is allowed.
var/datum/modifier/mod = new modifier_type(src)
if(expire_at)
mod.expire_at = world.time + expire_at
if(mod.on_created_text)
to_chat(src, mod.on_created_text)
modifiers.Add(mod)
// Removes a specific instance of modifier
/mob/living/proc/remove_specific_modifier(var/datum/modifier/M, var/silent = FALSE)
M.expire(silent)
// Removes all modifiers of a type
/mob/living/proc/remove_modifiers_of_type(var/modifier_type, var/silent = FALSE)
for(var/datum/modifier/M in modifiers)
if(ispath(modifier_type, M.type))
M.expire(silent)
// Removes all modifiers, useful if the mob's being deleted
/mob/living/proc/remove_all_modifiers(var/silent = FALSE)
for(var/datum/modifier/M in modifiers)
M.expire(silent)

View File

@@ -43,3 +43,11 @@ var/z_levels = 0 // Each bit represents a connection between adjacent levels. S
proc/AreConnectedZLevels(var/zA, var/zB)
return zA == zB || (zB in GetConnectedZlevels(zA))
/proc/get_zstep(ref, dir)
if(dir == UP)
. = GetAbove(ref)
else if (dir == DOWN)
. = GetBelow(ref)
else
. = get_step(ref, dir)

View File

@@ -51,7 +51,7 @@ obj/machinery/atmospherics/pipe/zpipe/New()
invisibility = i ? 101 : 0
update_icon()
obj/machinery/atmospherics/pipe/up/process()
obj/machinery/atmospherics/pipe/zpipe/process()
if(!parent) //This should cut back on the overhead calling build_network thousands of times per cycle
..()
else
@@ -81,10 +81,10 @@ obj/machinery/atmospherics/pipe/zpipe/proc/burst()
qdel(src) // NOT qdel.
obj/machinery/atmospherics/pipe/zpipe/proc/normalize_dir()
if(dir==3)
set_dir(1)
else if(dir==12)
set_dir(4)
if(dir == (NORTH|SOUTH))
set_dir(NORTH)
else if(dir == (EAST|WEST))
set_dir(EAST)
obj/machinery/atmospherics/pipe/zpipe/Destroy()
if(node1)

View File

@@ -35,7 +35,7 @@
if (. >= 2)
if(prob(1))
owner.custom_pain("Your feel very dizzy for a moment!",0)
owner.confused = max(owner.confused, 2)
owner.Confuse(2)
/obj/item/organ/internal/brain/proc/replace_self_with(replace_path)
var/mob/living/carbon/human/tmp_owner = owner

View File

@@ -72,7 +72,7 @@
if(is_bruised())
owner.eye_blurry = 20
if(is_broken())
owner.eye_blind = 20
owner.Blind(20)
/obj/item/organ/internal/eyes/handle_germ_effects()
. = ..() //Up should return an infection level as an integer

View File

@@ -53,6 +53,6 @@
if(prob(1))
owner.custom_pain("There's a sharp pain in your upper-right abdomen!",1)
if (. >= 2)
if(prob(1) && owner.getToxLoss() < owner.maxHealth*0.3)
if(prob(1) && owner.getToxLoss() < owner.getMaxHealth()*0.3)
//owner << "" //Toxins provide their own messages for pain
owner.adjustToxLoss(5) //Not realistic to PA but there are basically no 'real' liver infections

View File

@@ -492,7 +492,7 @@ This function completely restores a damaged organ to perfect condition.
//Burn damage can cause fluid loss due to blistering and cook-off
if((damage > 5 || damage + burn_dam >= 15) && type == BURN && (robotic < ORGAN_ROBOT) && !istype(owner.loc,/mob/living) && !istype(owner.loc,/obj/item/device/dogborg/sleeper)) // VOREStation Edit
var/fluid_loss = 0.75 * (damage/(owner.maxHealth - config.health_threshold_dead)) * owner.species.blood_volume*(1 - BLOOD_VOLUME_SURVIVE/100)
var/fluid_loss = 0.75 * (damage/(owner.getMaxHealth() - config.health_threshold_dead)) * owner.species.blood_volume*(1 - BLOOD_VOLUME_SURVIVE/100)
owner.remove_blood(fluid_loss)
// first check whether we can widen an existing wound

View File

@@ -165,7 +165,7 @@
if(is_bruised())
owner.eye_blurry = 20
if(is_broken())
owner.eye_blind = 20
owner.Blind(20)
/obj/item/organ/internal/liver
name = "liver"

View File

@@ -0,0 +1,50 @@
/obj/item/organ/external/chest/unathi
max_damage = 100
min_broken_damage = 40
encased = "upper ribplates"
/obj/item/organ/external/groin/unathi
max_damage = 100
min_broken_damage = 40
encased = "lower ribplates"
/obj/item/organ/external/head/unathi
max_damage = 75
min_broken_damage = 35
eye_icon = "eyes_s"
force = 5
throwforce = 10
/obj/item/organ/internal/heart/unathi
icon_state = "unathi_heart-on"
dead_icon = "unath_heart-off"
/obj/item/organ/internal/lungs/unathi
color = "#b3cbc3"
/obj/item/organ/internal/liver/unathi
name = "filtration organ"
icon_state = "unathi_liver"
//Unathi liver acts as kidneys, too.
/obj/item/organ/internal/liver/unathi/process()
..()
if(!owner) return
var/datum/reagent/coffee = locate(/datum/reagent/drink/coffee) in owner.reagents.reagent_list
if(coffee)
if(is_bruised())
owner.adjustToxLoss(0.1 * PROCESS_ACCURACY)
else if(is_broken())
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
var/datum/reagent/sugar = locate(/datum/reagent/sugar) in owner.reagents.reagent_list
if(sugar)
if(is_bruised())
owner.adjustToxLoss(0.1 * PROCESS_ACCURACY)
else if(is_broken())
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
/obj/item/organ/internal/brain/unathi
color = "#b3cbc3"

View File

@@ -12,8 +12,17 @@
var/datum/weather_holder/weather_holder
var/sun_position = 0 // 0 means midnight, 1 means noon.
var/list/sun = list("range","brightness","color")
var/expected_z_levels = list()
var/turf/unsimulated/wall/planetary/planetary_wall_type = /turf/unsimulated/wall/planetary
var/turf/simulated/floor/planet_floors = list()
var/turf/unsimulated/wall/planetary/planet_walls = list()
var/needs_work = 0 // Bitflags to signal to the planet controller these need (properly deferrable) work. Flags defined in controller.
/datum/planet/New()
..()
weather_holder = new(src)
@@ -31,17 +40,13 @@
/datum/planet/proc/update_sun()
sun_last_process = world.time
/datum/planet/proc/update_weather()
if(weather_holder)
weather_holder.process()
/datum/planet/proc/update_sun_deferred(var/new_range, var/new_brightness, var/new_color)
set background = 1
set waitfor = 0
var/i = 0
for(var/turf/simulated/floor/T in outdoor_turfs)
T.set_light(new_range, new_brightness, new_color)
i++
if(i % 30 == 0)
sleep(1)
sun["range"] = new_range
sun["brightness"] = new_brightness
sun["color"] = new_color
needs_work |= PLANET_PROCESS_SUN

View File

@@ -10,6 +10,7 @@ var/datum/planet/sif/planet_sif = null
Its center of government is the equatorial city and site of first settlement, New Reykjavik." // Ripped straight from the wiki.
current_time = new /datum/time/sif() // 32 hour clocks are nice.
expected_z_levels = list(1) // To be changed when real map is finished.
planetary_wall_type = /turf/unsimulated/wall/planetary/sif
/datum/planet/sif/New()
..()
@@ -104,3 +105,197 @@ var/datum/planet/sif/planet_sif = null
/proc/get_sif_time()
if(planet_sif)
return planet_sif.current_time
//Weather definitions
/datum/weather_holder/sif
temperature = T0C
allowed_weather_types = list(
WEATHER_CLEAR = new /datum/weather/sif/clear(),
WEATHER_OVERCAST = new /datum/weather/sif/overcast(),
WEATHER_LIGHT_SNOW = new /datum/weather/sif/light_snow(),
WEATHER_SNOW = new /datum/weather/sif/snow(),
WEATHER_BLIZZARD = new /datum/weather/sif/blizzard(),
WEATHER_RAIN = new /datum/weather/sif/rain(),
WEATHER_STORM = new /datum/weather/sif/storm(),
WEATHER_HAIL = new /datum/weather/sif/hail(),
WEATHER_BLOOD_MOON = new /datum/weather/sif/blood_moon()
)
roundstart_weather_chances = list(
WEATHER_CLEAR = 30,
WEATHER_OVERCAST = 30,
WEATHER_LIGHT_SNOW = 20,
WEATHER_SNOW = 5,
WEATHER_BLIZZARD = 5,
WEATHER_RAIN = 5,
WEATHER_STORM = 2.5,
WEATHER_HAIL = 2.5
)
datum/weather/sif
name = "sif base"
temp_high = 243.15 // -20c
temp_low = 233.15 // -30c
/datum/weather/sif/clear
name = "clear"
transition_chances = list(
WEATHER_CLEAR = 60,
WEATHER_OVERCAST = 40
)
/datum/weather/sif/overcast
name = "overcast"
light_modifier = 0.8
transition_chances = list(
WEATHER_CLEAR = 25,
WEATHER_OVERCAST = 50,
WEATHER_LIGHT_SNOW = 10,
WEATHER_SNOW = 5,
WEATHER_RAIN = 5,
WEATHER_HAIL = 5
)
/datum/weather/sif/light_snow
name = "light snow"
icon_state = "snowfall_light"
temp_high = 238.15 // -25c
temp_low = 228.15 // -35c
light_modifier = 0.7
transition_chances = list(
WEATHER_OVERCAST = 20,
WEATHER_LIGHT_SNOW = 50,
WEATHER_SNOW = 25,
WEATHER_HAIL = 5
)
/datum/weather/sif/snow
name = "moderate snow"
icon_state = "snowfall_med"
temp_high = 233.15 // -30c
temp_low = 223.15 // -40c
light_modifier = 0.5
transition_chances = list(
WEATHER_LIGHT_SNOW = 20,
WEATHER_SNOW = 50,
WEATHER_BLIZZARD = 20,
WEATHER_HAIL = 5,
WEATHER_OVERCAST = 5
)
/datum/weather/sif/snow/process_effects()
for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs)
if(S.z in holder.our_planet.expected_z_levels)
for(var/dir_checked in cardinal)
var/turf/simulated/floor/T = get_step(S, dir_checked)
if(istype(T))
if(istype(T, /turf/simulated/floor/outdoors) && prob(33))
T.chill()
/datum/weather/sif/blizzard
name = "blizzard"
icon_state = "snowfall_heavy"
temp_high = 223.15 // -40c
temp_low = 203.15 // -60c
light_modifier = 0.3
transition_chances = list(
WEATHER_SNOW = 45,
WEATHER_BLIZZARD = 40,
WEATHER_HAIL = 10,
WEATHER_OVERCAST = 5
)
/datum/weather/sif/blizzard/process_effects()
for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs)
if(S.z in holder.our_planet.expected_z_levels)
for(var/dir_checked in cardinal)
var/turf/simulated/floor/T = get_step(S, dir_checked)
if(istype(T))
if(istype(T, /turf/simulated/floor/outdoors) && prob(50))
T.chill()
/datum/weather/sif/rain
name = "rain"
icon_state = "rain"
light_modifier = 0.5
transition_chances = list(
WEATHER_OVERCAST = 25,
WEATHER_LIGHT_SNOW = 10,
WEATHER_RAIN = 50,
WEATHER_STORM = 10,
WEATHER_HAIL = 5
)
/datum/weather/sif/rain/process_effects()
for(var/mob/living/L in living_mob_list)
if(L.z in holder.our_planet.expected_z_levels)
var/turf/T = get_turf(L)
if(!T.outdoors)
return // They're indoors, so no need to rain on them.
L.adjust_fire_stacks(-5)
to_chat(L, "<span class='warning'>Rain falls on you.</span>")
/datum/weather/sif/storm
name = "storm"
icon_state = "storm"
temp_high = 233.15 // -30c
temp_low = 213.15 // -50c
light_modifier = 0.3
transition_chances = list(
WEATHER_RAIN = 45,
WEATHER_STORM = 40,
WEATHER_HAIL = 10,
WEATHER_OVERCAST = 5
)
/datum/weather/sif/rain/process_effects()
for(var/mob/living/L in living_mob_list)
if(L.z in holder.our_planet.expected_z_levels)
var/turf/T = get_turf(L)
if(!T.outdoors)
return // They're indoors, so no need to rain on them.
L.adjust_fire_stacks(-10)
to_chat(L, "<span class='warning'>Rain falls on you, drenching you in water.</span>")
/datum/weather/sif/hail
name = "hail"
icon_state = "hail"
temp_high = 233.15 // -30c
temp_low = 213.15 // -50c
light_modifier = 0.3
transition_chances = list(
WEATHER_RAIN = 45,
WEATHER_STORM = 10,
WEATHER_HAIL = 40,
WEATHER_OVERCAST = 5
)
/datum/weather/sif/hail/process_effects()
for(var/mob/living/L in living_mob_list)
if(L.z in holder.our_planet.expected_z_levels)
var/turf/T = get_turf(L)
if(!T.outdoors)
return // They're indoors, so no need to pelt them with ice.
var/target_zone = pick(BP_ALL)
var/amount_blocked = L.run_armor_check(target_zone, "melee")
var/amount_soaked = L.get_armor_soak(target_zone, "melee")
if(amount_blocked >= 100)
return // No need to apply damage.
if(amount_soaked >= 10)
return // No need to apply damage.
L.apply_damage(rand(5, 10), BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail")
to_chat(L, "<span class='warning'>The hail raining down on you [L.can_feel_pain() ? "hurts" : "damages you"]!</span>")
/datum/weather/sif/blood_moon
name = "blood moon"
light_modifier = 0.5
light_color = "#FF0000"
transition_chances = list(
WEATHER_BLOODMOON = 100
)

View File

@@ -1,15 +1,3 @@
#define WEATHER_CLEAR "clear"
#define WEATHER_OVERCAST "overcast"
#define WEATHER_LIGHT_SNOW "light snow"
#define WEATHER_SNOW "snow"
#define WEATHER_BLIZZARD "blizzard"
#define WEATHER_RAIN "rain"
#define WEATHER_STORM "storm"
#define WEATHER_HAIL "hail"
#define WEATHER_WINDY "windy"
#define WEATHER_HOT "hot"
#define WEATHER_BLOOD_MOON "blood moon" // For admin fun or cult later on.
/datum/weather_holder
var/datum/planet/our_planet = null
var/datum/weather/current_weather = null
@@ -19,7 +7,6 @@
var/list/allowed_weather_types = list()
var/list/roundstart_weather_chances = list()
var/next_weather_shift = null
var/planetary_wall_type = null // Which walls to look for when updating temperature.
/datum/weather_holder/New(var/source)
..()
@@ -54,55 +41,15 @@
current_weather.process_effects()
/datum/weather_holder/proc/update_icon_effects()
set background = 1
set waitfor = 0
if(current_weather)
for(var/turf/simulated/floor/T in outdoor_turfs)
if(T.z in our_planet.expected_z_levels)
T.overlays -= T.weather_overlay
T.weather_overlay = image(icon = current_weather.icon, icon_state = current_weather.icon_state, layer = LIGHTING_LAYER - 1)
T.overlays += T.weather_overlay
our_planet.needs_work |= PLANET_PROCESS_WEATHER
/datum/weather_holder/proc/update_temperature()
temperature = Interpolate(current_weather.temp_low, current_weather.temp_high, weight = our_planet.sun_position)
for(var/turf/unsimulated/wall/planetary/wall in planetary_walls)
if(ispath(wall.type, planetary_wall_type))
wall.temperature = temperature
for(var/dir in cardinal)
var/turf/simulated/T = get_step(wall, dir)
if(istype(T))
if(T.zone)
T.zone.rebuild()
our_planet.needs_work |= PLANET_PROCESS_TEMP
/datum/weather_holder/proc/get_weather_datum(desired_type)
return allowed_weather_types[desired_type]
/datum/weather_holder/sif
temperature = T0C
allowed_weather_types = list(
WEATHER_CLEAR = new /datum/weather/sif/clear(),
WEATHER_OVERCAST = new /datum/weather/sif/overcast(),
WEATHER_LIGHT_SNOW = new /datum/weather/sif/light_snow(),
WEATHER_SNOW = new /datum/weather/sif/snow(),
WEATHER_BLIZZARD = new /datum/weather/sif/blizzard(),
WEATHER_RAIN = new /datum/weather/sif/rain(),
WEATHER_STORM = new /datum/weather/sif/storm(),
WEATHER_HAIL = new /datum/weather/sif/hail(),
WEATHER_BLOOD_MOON = new /datum/weather/sif/blood_moon()
)
planetary_wall_type = /turf/unsimulated/wall/planetary/sif
roundstart_weather_chances = list(
WEATHER_CLEAR = 30,
WEATHER_OVERCAST = 30,
WEATHER_LIGHT_SNOW = 20,
WEATHER_SNOW = 5,
WEATHER_BLIZZARD = 5,
WEATHER_RAIN = 5,
WEATHER_STORM = 2.5,
WEATHER_HAIL = 2.5
)
/datum/weather
var/name = "weather base"
@@ -117,169 +64,3 @@
/datum/weather/proc/process_effects()
return
/datum/weather/sif
name = "sif base"
temp_high = 243.15 // -20c
temp_low = 233.15 // -30c
/datum/weather/sif/clear
name = "clear"
transition_chances = list(
WEATHER_CLEAR = 60,
WEATHER_OVERCAST = 40
)
/datum/weather/sif/overcast
name = "overcast"
light_modifier = 0.8
transition_chances = list(
WEATHER_CLEAR = 25,
WEATHER_OVERCAST = 50,
WEATHER_LIGHT_SNOW = 10,
WEATHER_SNOW = 5,
WEATHER_RAIN = 5,
WEATHER_HAIL = 5
)
/datum/weather/sif/light_snow
name = "light snow"
icon_state = "snowfall_light"
temp_high = 238.15 // -25c
temp_low = 228.15 // -35c
light_modifier = 0.7
transition_chances = list(
WEATHER_OVERCAST = 20,
WEATHER_LIGHT_SNOW = 50,
WEATHER_SNOW = 25,
WEATHER_HAIL = 5
)
/datum/weather/sif/snow
name = "moderate snow"
icon_state = "snowfall_med"
temp_high = 233.15 // -30c
temp_low = 223.15 // -40c
light_modifier = 0.5
transition_chances = list(
WEATHER_LIGHT_SNOW = 20,
WEATHER_SNOW = 50,
WEATHER_BLIZZARD = 20,
WEATHER_HAIL = 5,
WEATHER_OVERCAST = 5
)
/datum/weather/sif/snow/process_effects()
for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs)
for(var/dir_checked in cardinal)
var/turf/simulated/floor/T = get_step(S, dir_checked)
if(istype(T))
if(istype(T, /turf/simulated/floor/outdoors) && prob(33))
T.chill()
/datum/weather/sif/blizzard
name = "blizzard"
icon_state = "snowfall_heavy"
temp_high = 223.15 // -40c
temp_low = 203.15 // -60c
light_modifier = 0.3
transition_chances = list(
WEATHER_SNOW = 45,
WEATHER_BLIZZARD = 40,
WEATHER_HAIL = 10,
WEATHER_OVERCAST = 5
)
/datum/weather/sif/blizzard/process_effects()
for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs)
for(var/dir_checked in cardinal)
var/turf/simulated/floor/T = get_step(S, dir_checked)
if(istype(T))
if(istype(T, /turf/simulated/floor/outdoors) && prob(50))
T.chill()
/datum/weather/sif/rain
name = "rain"
icon_state = "rain"
light_modifier = 0.5
transition_chances = list(
WEATHER_OVERCAST = 25,
WEATHER_LIGHT_SNOW = 10,
WEATHER_RAIN = 50,
WEATHER_STORM = 10,
WEATHER_HAIL = 5
)
/datum/weather/sif/rain/process_effects()
for(var/mob/living/L in living_mob_list)
if(L.z in holder.our_planet.expected_z_levels)
var/turf/T = get_turf(L)
if(!T.outdoors)
return // They're indoors, so no need to rain on them.
L.adjust_fire_stacks(-5)
to_chat(L, "<span class='warning'>Rain falls on you.</span>")
/datum/weather/sif/storm
name = "storm"
icon_state = "storm"
temp_high = 233.15 // -30c
temp_low = 213.15 // -50c
light_modifier = 0.3
transition_chances = list(
WEATHER_RAIN = 45,
WEATHER_STORM = 40,
WEATHER_HAIL = 10,
WEATHER_OVERCAST = 5
)
/datum/weather/sif/rain/process_effects()
for(var/mob/living/L in living_mob_list)
if(L.z in holder.our_planet.expected_z_levels)
var/turf/T = get_turf(L)
if(!T.outdoors)
return // They're indoors, so no need to rain on them.
L.adjust_fire_stacks(-10)
to_chat(L, "<span class='warning'>Rain falls on you, drenching you in water.</span>")
/datum/weather/sif/hail
name = "hail"
icon_state = "hail"
temp_high = 233.15 // -30c
temp_low = 213.15 // -50c
light_modifier = 0.3
transition_chances = list(
WEATHER_RAIN = 45,
WEATHER_STORM = 10,
WEATHER_HAIL = 40,
WEATHER_OVERCAST = 5
)
/datum/weather/sif/hail/process_effects()
for(var/mob/living/L in living_mob_list)
if(L.z in holder.our_planet.expected_z_levels)
var/turf/T = get_turf(L)
if(!T.outdoors)
return // They're indoors, so no need to pelt them with ice.
var/target_zone = pick(BP_ALL)
var/amount_blocked = L.run_armor_check(target_zone, "melee")
var/amount_soaked = L.get_armor_soak(target_zone, "melee")
if(amount_blocked >= 100)
return // No need to apply damage.
if(amount_soaked >= 10)
return // No need to apply damage.
L.apply_damage(rand(5, 10), BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail")
to_chat(L, "<span class='warning'>The hail raining down on you [L.can_feel_pain() ? "hurts" : "damages you"]!</span>")
/datum/weather/sif/blood_moon
name = "blood moon"
light_modifier = 0.5
light_color = "#FF0000"
transition_chances = list(
WEATHER_BLOODMOON = 100
)

View File

@@ -48,7 +48,7 @@ var/list/possible_cable_coil_colours = list(
anchored =1
var/datum/powernet/powernet
name = "power cable"
desc = "A flexible superconducting cable for heavy-duty power transfer"
desc = "A flexible superconducting cable for heavy-duty power transfer."
icon = 'icons/obj/power_cond_white.dmi'
icon_state = "0-1"
var/d1 = 0
@@ -116,9 +116,9 @@ var/list/possible_cable_coil_colours = list(
user.examinate(src)
// following code taken from attackby (multitool)
if(powernet && (powernet.avail > 0))
user << "<span class='warning'>[powernet.avail]W in power network.</span>"
to_chat(user, "<span class='warning'>[powernet.avail]W in power network.</span>")
else
user << "<span class='warning'>The cable is not powered.</span>"
to_chat(user, "<span class='warning'>The cable is not powered.</span>")
return
///////////////////////////////////
@@ -159,12 +159,12 @@ var/list/possible_cable_coil_colours = list(
return
if(istype(W, /obj/item/weapon/wirecutters))
if(d1 == 12 || d2 == 12)
user << "<span class='warning'>You must cut this cable from above.</span>"
if(d1 == UP || d2 == UP)
to_chat(user, "<span class='warning'>You must cut this cable from above.</span>")
return
if(breaker_box)
user << "\red This cable is connected to nearby breaker box. Use breaker box to interact with it."
to_chat(user, "<span class='warning'>This cable is connected to nearby breaker box. Use breaker box to interact with it.</span>")
return
if (shock(user, 50))
@@ -178,11 +178,11 @@ var/list/possible_cable_coil_colours = list(
for(var/mob/O in viewers(src, null))
O.show_message("<span class='warning'>[user] cuts the cable.</span>", 1)
if(d1 == 11 || d2 == 11)
if(d1 == DOWN || d2 == DOWN)
var/turf/turf = GetBelow(src)
if(turf)
for(var/obj/structure/cable/c in turf)
if(c.d1 == 12 || c.d2 == 12)
if(c.d1 == UP || c.d2 == UP)
qdel(c)
investigate_log("was cut by [key_name(usr, usr.client)] in [user.loc.loc]","wires")
@@ -194,17 +194,17 @@ var/list/possible_cable_coil_colours = list(
else if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/coil = W
if (coil.get_amount() < 1)
user << "Not enough cable"
to_chat(user, "Not enough cable")
return
coil.cable_join(src, user)
else if(istype(W, /obj/item/device/multitool))
if(powernet && (powernet.avail > 0)) // is it powered?
user << "<span class='warning'>[powernet.avail]W in power network.</span>"
to_chat(user, "<span class='warning'>[powernet.avail]W in power network.</span>")
else
user << "<span class='warning'>The cable is not powered.</span>"
to_chat(user, "<span class='warning'>The cable is not powered.</span>")
shock(user, 5, 0.2)
@@ -300,12 +300,12 @@ obj/structure/cable/proc/cableColor(var/colorC)
// merge with the powernets of power objects in the given direction
/obj/structure/cable/proc/mergeConnectedNetworks(var/direction)
var/fdir = (!direction)? 0 : turn(direction, 180) //flip the direction, to match with the source position on its turf
var/fdir = direction ? reverse_dir[direction] : 0 //flip the direction, to match with the source position on its turf
if(!(d1 == direction || d2 == direction)) //if the cable is not pointed in this direction, do nothing
return
var/turf/TB = get_step(src, direction)
var/turf/TB = get_zstep(src, direction)
for(var/obj/structure/cable/C in TB)
@@ -376,25 +376,15 @@ obj/structure/cable/proc/cableColor(var/colorC)
. = list() // this will be a list of all connected power objects
var/turf/T
// Handle up/down cables
if(d1 == 11 || d2 == 11)
T = GetBelow(src)
if(T)
. += power_list(T, src, 12, 1)
if(d1 == 12 || d1 == 12)
T = GetAbove(src)
if(T)
. += power_list(T, src, 11, 1)
// Handle standard cables in adjacent turfs
for(var/cable_dir in list(d1, d2))
if(cable_dir == 11 || cable_dir == 12 || cable_dir == 0)
if(cable_dir == 0)
continue
var/reverse = reverse_dir[cable_dir]
T = get_step(src, cable_dir)
T = get_zstep(src, cable_dir)
if(T)
for(var/obj/structure/cable/C in T)
if((C.d1 && C.d1 == reverse) || (C.d2 && C.d2 == reverse))
if(C.d1 == reverse || C.d2 == reverse)
. += C
if(cable_dir & (cable_dir - 1)) // Diagonal, check for /\/\/\ style cables along cardinal directions
for(var/pair in list(NORTH|SOUTH, EAST|WEST))
@@ -402,7 +392,7 @@ obj/structure/cable/proc/cableColor(var/colorC)
if(T)
var/req_dir = cable_dir ^ pair
for(var/obj/structure/cable/C in T)
if((C.d1 && C.d1 == req_dir) || (C.d2 && C.d2 == req_dir))
if(C.d1 == req_dir || C.d2 == req_dir)
. += C
// Handle cables on the same turf as us
@@ -566,7 +556,7 @@ obj/structure/cable/proc/cableColor(var/colorC)
final_color = possible_cable_coil_colours["Red"]
selected_color = "red"
color = final_color
user << "<span class='notice'>You change \the [src]'s color to [lowertext(selected_color)].</span>"
to_chat(user, "<span class='notice'>You change \the [src]'s color to [lowertext(selected_color)].</span>")
/obj/item/stack/cable_coil/proc/update_wclass()
if(amount == 1)
@@ -579,11 +569,11 @@ obj/structure/cable/proc/cableColor(var/colorC)
return
if(get_amount() == 1)
user << "A short piece of power cable."
to_chat(user, "A short piece of power cable.")
else if(get_amount() == 2)
user << "A piece of power cable."
to_chat(user, "A piece of power cable.")
else
user << "A coil of power cable. There are [get_amount()] lengths of cable in the coil."
to_chat(user, "A coil of power cable. There are [get_amount()] lengths of cable in the coil.")
/obj/item/stack/cable_coil/verb/make_restraint()
@@ -594,14 +584,14 @@ obj/structure/cable/proc/cableColor(var/colorC)
if(ishuman(M) && !M.restrained() && !M.stat && !M.paralysis && ! M.stunned)
if(!istype(usr.loc,/turf)) return
if(src.amount <= 14)
usr << "\red You need at least 15 lengths to make restraints!"
to_chat(usr, "<span class='warning'>You need at least 15 lengths to make restraints!</span>")
return
var/obj/item/weapon/handcuffs/cable/B = new /obj/item/weapon/handcuffs/cable(usr.loc)
B.color = color
usr << "<span class='notice'>You wind some cable together to make some restraints.</span>"
to_chat(usr, "<span class='notice'>You wind some cable together to make some restraints.</span>")
src.use(15)
else
usr << "\blue You cannot do that."
to_chat(usr, "<span class='notice'>You cannot do that.</span>")
..()
/obj/item/stack/cable_coil/cyborg/verb/set_colour()

View File

@@ -3,7 +3,6 @@
/obj/machinery/computer/gravity_control_computer
name = "Gravity Generator Control"
desc = "A computer to control a local gravity generator. Qualified personnel only."
icon = 'icons/obj/computer.dmi'
icon_state = "airtunnel0e"
anchored = 1
density = 1

View File

@@ -209,16 +209,8 @@
// if unmarked==1, only return those with no powernet
/proc/power_list(var/turf/T, var/source, var/d, var/unmarked=0, var/cable_only = 0)
. = list()
var/fdir = (!d)? 0 : turn(d, 180) // the opposite direction to d (or 0 if d==0)
///// Z-Level Stuff
var/Zdir
if(d==11)
Zdir = 11
else if (d==12)
Zdir = 12
else
Zdir = 999
///// Z-Level Stuff
var/reverse = d ? reverse_dir[d] : 0
for(var/AM in T)
if(AM == source) continue //we don't want to return source
@@ -234,11 +226,7 @@
var/obj/structure/cable/C = AM
if(!unmarked || !C.powernet)
///// Z-Level Stuff
if(C.d1 == fdir || C.d2 == fdir || C.d1 == Zdir || C.d2 == Zdir)
///// Z-Level Stuff
. += C
else if(C.d1 == d || C.d2 == d)
if(C.d1 == d || C.d2 == d || C.d1 == reverse || C.d2 == reverse )
. += C
return .

View File

@@ -6,7 +6,6 @@
/obj/machinery/computer/power_monitor
name = "Power Monitoring Console"
desc = "Computer designed to remotely monitor power levels around the station"
icon = 'icons/obj/computer.dmi'
icon_keyboard = "power_key"
icon_screen = "power:0"
light_color = "#ffcc33"

View File

@@ -28,7 +28,6 @@
/obj/machinery/computer/turbine_computer
name = "Gas turbine control computer"
desc = "A computer to remotely control a gas turbine"
icon = 'icons/obj/computer.dmi'
icon_keyboard = "tech_key"
icon_screen = "turbinecomp"
circuit = /obj/item/weapon/circuitboard/turbine_control

View File

@@ -425,21 +425,21 @@
/obj/item/weapon/gun/proc/handle_post_fire(mob/user, atom/target, var/pointblank=0, var/reflex=0)
if(silenced)
playsound(user, fire_sound, 10, 1)
to_chat(user, "<span class='warning'>You fire \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]</span>")
for(var/mob/living/L in oview(2,user))
if(L.stat)
continue
if(L.blinded)
to_chat(L, "You hear a [fire_sound_text]!")
continue
to_chat(L, "<span class='warning'>[user] fires \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]</span>")
else
playsound(user, fire_sound, 50, 1)
if(reflex)
user.visible_message(
"<span class='reflex_shoot'><b>\The [user] fires \the [src][pointblank ? " point blank at \the [target]":""] by reflex!</b></span>",
"<span class='reflex_shoot'>You fire \the [src] by reflex!</span>",
"You hear a [fire_sound_text]!"
)
else
user.visible_message(
"<span class='danger'>\The [user] fires \the [src][pointblank ? " point blank at \the [target]":""]!</span>",
"<span class='warning'>You fire \the [src]!</span>",
"You hear a [fire_sound_text]!"
)
user.visible_message(
"<span class='warning'>[user] fires \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]</span>",
"<span class='warning'>You fire \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]</span>",
"You hear a [fire_sound_text]!"
)
if(muzzle_flash)
set_light(muzzle_flash)

View File

@@ -21,7 +21,7 @@
item_state = null
w_class = ITEMSIZE_NORMAL
force = 5
slot_flags = SLOT_BELT
slot_flags = SLOT_BELT|SLOT_HOLSTER
charge_cost = 480
projectile_type = /obj/item/projectile/ion

View File

@@ -49,4 +49,19 @@
desc = "The firepower of a Mosin, now the size of a pistol, with an effective combat range of about three feet. Uses 7.62mm rounds."
user << "<span class='warning'>You shorten the barrel and stock of \the [src]!</span>"
else
..()
..()
//Lever actions are the same thing, but bigger.
/obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever
name = "lever-action rifle"
desc = "A reproduction of an almost ancient weapon design from the 19th century. This one uses a lever-action to move new rounds into the chamber. Uses 5.56mm rounds."
item_state = "leveraction"
icon_state = "leveraction"
fire_sound = 'sound/weapons/rifleshot.ogg'
max_shells = 5
caliber = "a556"
origin_tech = list(TECH_COMBAT = 1)// Old as shit rifle doesn't have very good tech.
ammo_type = /obj/item/ammo_casing/a556
load_method = SINGLE_CASING|SPEEDLOADER
action_sound = 'sound/weapons/riflebolt.ogg'

View File

@@ -29,8 +29,8 @@
flash_strength *= H.species.flash_mod
if(flash_strength > 0)
H.confused = max(H.confused, flash_strength + 5)
H.eye_blind = max(H.eye_blind, flash_strength)
H.Confuse(flash_strength + 5)
H.Blind(flash_strength)
H.eye_blurry = max(H.eye_blurry, flash_strength + 5)
H.adjustHalLoss(22 * (flash_strength / 5)) // Five flashes to stun. Bit weaker than melee flashes due to being ranged.
@@ -146,9 +146,9 @@
var/ear_safety = 0
ear_safety = M.get_ear_protection()
if(ear_safety == 1)
M.confused += 150
M.Confuse(150)
else if (ear_safety > 1)
M.confused += 30
M.Confuse(30)
else if (!ear_safety)
M.Stun(10)
M.Weaken(2)

View File

@@ -150,7 +150,7 @@
on_hit(var/atom/target, var/blocked = 0)
if(ishuman(target))
var/mob/living/carbon/human/M = target
M.confused += rand(5,8)
M.Confuse(rand(5,8))
/obj/item/projectile/chameleon
name = "bullet"

View File

@@ -96,6 +96,8 @@
strength_mod *= 5
if(alien == IS_TAJARA)
strength_mod *= 1.75
if(alien == IS_UNATHI)
strength_mod *= 0.75
if(alien == IS_DIONA)
strength_mod = 0
@@ -106,7 +108,7 @@
if(dose * strength_mod >= strength * 2) // Slurring
M.slurring = max(M.slurring, 30)
if(dose * strength_mod >= strength * 3) // Confusion - walking in random directions
M.confused = max(M.confused, 20)
M.Confuse(20)
if(dose * strength_mod >= strength * 4) // Blurry vision
M.eye_blurry = max(M.eye_blurry, 10)
if(dose * strength_mod >= strength * 5) // Drowsyness - periodically falling asleep

View File

@@ -376,7 +376,7 @@
else if(eyes_covered)
M << "<span class='warning'>Your [safe_thing] protect you from most of the pepperspray!</span>"
M.eye_blurry = max(M.eye_blurry, effective_strength * 3)
M.eye_blind = max(M.eye_blind, effective_strength)
M.Blind(effective_strength)
M.Stun(5)
M.Weaken(5)
return
@@ -387,7 +387,7 @@
else // Oh dear :D
M << "<span class='warning'>You're sprayed directly in the eyes with pepperspray!</span>"
M.eye_blurry = max(M.eye_blurry, effective_strength * 5)
M.eye_blind = max(M.eye_blind, effective_strength * 2)
M.Blind(effective_strength * 2)
M.Stun(5)
M.Weaken(5)
return
@@ -1166,7 +1166,7 @@
if(M.dizziness)
M.dizziness = max(0, M.dizziness - 15)
if(M.confused)
M.confused = max(0, M.confused - 5)
M.Confuse(-5)
/datum/reagent/drink/dry_ramen
name = "Dry Ramen"
@@ -2232,3 +2232,26 @@
glass_name = "special blend whiskey"
glass_desc = "Just when you thought regular station whiskey was good... This silky, amber goodness has to come along and ruin everything."
/datum/reagent/ethanol/unathiliquor //Needs a better name
name = "Unathi Liquor"
id = "unathiliquor"
description = "This barely qualifies as a drink, and could give jetfuel a run for its money. Also known to cause feelings of euphoria and numbness."
taste_description = "spiced numbness"
color = "#242424"
strength = 5
glass_name = "unathi liquor"
glass_desc = "This barely qualifies as a drink, and may cause euphoria and numbness. Imbimber beware!"
/datum/reagent/ethanol/unathiliquor/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
..()
if(alien == IS_DIONA)
return
var/drug_strength = 10
if(alien == IS_SKRELL)
drug_strength = drug_strength * 0.8
M.druggy = max(M.druggy, drug_strength)
if(prob(10) && isturf(M.loc) && !istype(M.loc, /turf/space) && M.canmove && !M.restrained())
step(M, pick(cardinal))

View File

@@ -258,7 +258,7 @@
/datum/reagent/oxycodone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.add_chemical_effect(CE_PAINKILLER, 200)
M.eye_blurry += 10
M.confused += 5
M.Confuse(5)
/datum/reagent/oxycodone/overdose(var/mob/living/carbon/M, var/alien)
..()
@@ -319,7 +319,7 @@
/datum/reagent/imidazoline/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.eye_blurry = max(M.eye_blurry - 5, 0)
M.eye_blind = max(M.eye_blind - 5, 0)
M.AdjustBlinded(-5)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES]
@@ -349,7 +349,7 @@
continue
if(I.damage > 0) //Peridaxon heals only non-robotic organs
I.damage = max(I.damage - removed, 0)
H.confused += 5
H.Confuse(5)
if(I.damage <= 5 && I.organ_tag == O_EYES)
H.eye_blurry += 10 //Eyes need to reset, or something
H.sdisabilities &= ~BLIND
@@ -441,7 +441,7 @@
M.dizziness = 0
M.drowsyness = 0
M.stuttering = 0
M.confused = 0
M.SetConfused(0)
if(M.ingested)
for(var/datum/reagent/R in M.ingested.reagent_list)
if(istype(R, /datum/reagent/ethanol))

View File

@@ -133,7 +133,7 @@
M.disabilities = 0
M.sdisabilities = 0
M.eye_blurry = 0
M.eye_blind = 0
M.SetBlinded(0)
M.SetWeakened(0)
M.SetStunned(0)
M.SetParalysis(0)
@@ -141,7 +141,7 @@
M.dizziness = 0
M.drowsyness = 0
M.stuttering = 0
M.confused = 0
M.SetConfused(0)
M.sleeping = 0
M.jitteriness = 0

View File

@@ -403,7 +403,7 @@
effective_dose *= 2
if(effective_dose == metabolism)
M.confused += 2
M.Confuse(2)
M.drowsyness += 2
else if(effective_dose < 2 * threshold)
M.Weaken(30)
@@ -429,6 +429,7 @@
glass_name = "beer"
glass_desc = "A freezing pint of beer"
/* Drugs */
/datum/reagent/space_drugs
@@ -490,7 +491,7 @@
if(alien == IS_SKRELL)
drug_strength = drug_strength * 0.8
M.make_dizzy(drug_strength)
M.confused = max(M.confused, drug_strength * 5)
M.Confuse(drug_strength * 5)
/datum/reagent/impedrezene
name = "Impedrezene"

View File

@@ -384,7 +384,7 @@
name = "Stimm"
id = "stimm"
result = "stimm"
required_reagents = list("sugar" = 1, "fuel" = 1)
required_reagents = list("left4zed" = 1, "fuel" = 1)
catalysts = list("fuel" = 5)
result_amount = 2

View File

@@ -121,7 +121,7 @@
recharge_time = 3
volume = 60
possible_transfer_amounts = list(5, 10, 20, 30)
reagent_ids = list("beer", "kahlua", "whiskey", "specialwhiskey", "wine", "vodka", "gin", "rum", "tequilla", "vermouth", "cognac", "ale", "mead", "water", "sugar", "ice", "tea", "icetea", "cola", "spacemountainwind", "dr_gibb", "space_up", "tonic", "sodawater", "lemon_lime", "orangejuice", "limejuice", "watermelonjuice")
reagent_ids = list("ale", "beer", "berryjuice", "coffee", "cognac", "cola", "dr_gibb", "egg", "gin", "hot_coco", "ice", "icetea", "kahlua", "lemonjuice", "lemon_lime", "limejuice", "mead", "milk", "mint", "orangejuice", "rum", "sodawater", "soymilk", "space_up", "spacemountainwind", "specialwhiskey", "sugar", "tea", "tequilla", "tomatojuice", "tonic", "vermouth", "vodka", "water", "watermelonjuice", "whiskey", "wine")
/obj/item/weapon/reagent_containers/borghypo/service/attack(var/mob/M, var/mob/user)
return

View File

@@ -243,6 +243,12 @@
user.drop_from_inventory(src)
qdel(src)
return
else if(istype(D, /obj/item/weapon/wirecutters))
to_chat(user, "<span class='notice'>You cut a big hole in \the [src] with \the [D]. It's kinda useless as a bucket now.</span>")
user.put_in_hands(new /obj/item/clothing/head/helmet/bucket)
user.drop_from_inventory(src)
qdel(src)
return
else if(istype(D, /obj/item/weapon/mop))
if(reagents.total_volume < 1)
user << "<span class='warning'>\The [src] is empty!</span>"

View File

@@ -290,7 +290,7 @@
else if(istype(W, /obj/item/stack/cable_coil) && malfunction && is_open)
var/obj/item/stack/cable_coil/coil = W
user << "<span class='notice'>You begin to replace the wires.</span>"
//if(do_after(user, min(60, round( ((maxhealth/health)*10)+(malfunction*10) ))) //Take longer to repair heavier damage
//if(do_after(user, min(60, round( ((getMaxHealth()/health)*10)+(malfunction*10) ))) //Take longer to repair heavier damage
if(do_after(user, 30))
if (coil.use(1))
health = max_health

View File

@@ -1,6 +1,5 @@
/obj/machinery/computer/shuttle_control
name = "shuttle control console"
icon = 'icons/obj/computer.dmi'
icon_keyboard = "atmos_key"
icon_screen = "shuttle"
circuit = null

View File

@@ -322,7 +322,7 @@
/obj/item/weapon/spellbook/oneuse/blind/recoil(mob/user as mob)
..()
user <<"<span class='warning'>You go blind!</span>"
user.eye_blind = 10
user.Blind(10)
/obj/item/weapon/spellbook/oneuse/mindswap
spell = /spell/targeted/mind_transfer

View File

@@ -138,8 +138,8 @@ Targeted spells have two useful flags: INCLUDEUSER and SELECTABLE. These are exp
if(amt_weakened || amt_paralysis || amt_stunned)
if(target.buckled)
target.buckled = null
target.eye_blind += amt_eye_blind
target.Blind(amt_eye_blind)
target.eye_blurry += amt_eye_blurry
target.dizziness += amt_dizziness
target.confused += amt_confused
target.Confuse(amt_confused)
target.stuttering += amt_stuttering

View File

@@ -44,10 +44,15 @@ var/list/ventcrawl_machinery = list(
/mob/living/proc/is_allowed_vent_crawl_item(var/obj/item/carried_item)
if(carried_item == ability_master)
return 1
var/list/allowed = list()
for(var/type in can_enter_vent_with)
if(istype(carried_item, type)) //VOREStation Edit - It was a typo before maybe?
return 1 //VOREStation Edit also
return 0
var/list/types = typesof(type)
allowed += types
if(carried_item.type in allowed)
if(get_inventory_slot(carried_item) == 0)
return 1
/mob/living/carbon/is_allowed_vent_crawl_item(var/obj/item/carried_item)
if(carried_item in internal_organs)

View File

@@ -1,6 +1,5 @@
/obj/machinery/computer/curer
name = "cure research machine"
icon = 'icons/obj/computer.dmi'
icon_keyboard = "med_key"
icon_screen = "dna"
circuit = /obj/item/weapon/circuitboard/curefab

View File

@@ -1,6 +1,5 @@
/obj/machinery/computer/diseasesplicer
name = "disease splicer"
icon = 'icons/obj/computer.dmi'
icon_keyboard = "med_key"
icon_screen = "crew"

View File

@@ -264,7 +264,7 @@
stage = 3
activate(var/mob/living/carbon/mob,var/multiplier)
mob << "<span class='notice'>You have trouble telling right and left apart all of a sudden.</span>"
mob.confused += 10
mob.Confuse(10)
/datum/disease2/effect/mutation
name = "DNA Degradation"

View File

@@ -76,7 +76,7 @@
if(injector.occupant)
data["occupantHealth"] = injector.occupant.health
data["occupantHealthMax"] = injector.occupant.maxHealth
data["occupantHealthMax"] = injector.occupant.getMaxHealth()
else
data["occupantHealth"] = null
data["occupantHealthMax"] = null