Merge branch 'master' of https://github.com/PolarisSS13/Polaris into scratch_damage

# Conflicts:
#	code/modules/mob/living/carbon/human/human_defense.dm
This commit is contained in:
Anewbe
2017-04-19 12:55:11 -05:00
43 changed files with 755 additions and 77 deletions

View File

@@ -42,6 +42,8 @@
#define isxeno(A) istype(A, /mob/living/simple_animal/xeno)
#define isopenspace(A) istype(A, /turf/simulated/open)
#define isweakref(A) istype(A, /weakref)
#define RANDOM_BLOOD_TYPE pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")

View File

@@ -115,12 +115,7 @@
else if(isturf(hit_atom))
src.throwing = 0
var/turf/T = hit_atom
if(T.density)
spawn(2)
step(src, turn(src.last_move, 180))
if(istype(src,/mob/living))
var/mob/living/M = src
M.turf_collision(T, speed)
T.hitby(src,speed)
//decided whether a movable atom being thrown can pass through the turf it is in.
/atom/movable/proc/hit_check(var/speed)

View File

@@ -13,6 +13,8 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
var/isabsorbing = 0
var/geneticpoints = 5
var/max_geneticpoints = 5
var/readapts = 1
var/max_readapts = 2
var/list/purchased_powers = list()
var/mimicing = ""
var/cloaked = 0
@@ -60,6 +62,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
if(!mind.changeling) mind.changeling = new /datum/changeling(gender)
verbs += /datum/changeling/proc/EvolutionMenu
verbs += /mob/proc/changeling_respec
add_language("Changeling")
var/lesser_form = !ishuman(src)

View File

@@ -72,7 +72,12 @@
if(src.nutrition < 400)
src.nutrition = min((src.nutrition + T.nutrition), 400)
changeling.chem_charges += 10
src.verbs += /mob/proc/changeling_respec
if(changeling.readapts <= 0)
changeling.readapts = 0 //SANITYYYYYY
changeling.readapts++
if(changeling.readapts > changeling.max_readapts)
changeling.readapts = changeling.max_readapts
src << "<span class='notice'>We can now re-adapt, reverting our evolution so that we may start anew, if needed.</span>"
var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages, T.identifying_gender, T.flavor_texts)

View File

@@ -24,7 +24,7 @@
if(held_item == null)
if(src.mind.changeling.recursive_enhancement)
if(changeling_generic_weapon(/obj/item/weapon/electric_hand/efficent))
if(changeling_generic_weapon(/obj/item/weapon/electric_hand/efficent,0))
src << "<span class='notice'>We will shock others more efficently.</span>"
return 1
else

View File

@@ -6,9 +6,14 @@
var/datum/changeling/changeling = changeling_power(0,0,100)
if(!changeling)
return
if(src.mind.changeling.readapts <= 0)
to_chat(src, "<span class='warning'>We must first absorb another compatable creature!</span>")
src.mind.changeling.readapts = 0
return
src.remove_changeling_powers() //First, remove the verbs.
var/datum/changeling/ling_datum = src.mind.changeling
ling_datum.readapts--
ling_datum.purchased_powers = list() //Then wipe all the powers we bought.
ling_datum.geneticpoints = ling_datum.max_geneticpoints //Now refund our points to the maximum.
ling_datum.chem_recharge_rate = 0.5 //If glands were bought, revert that upgrade.
@@ -26,4 +31,4 @@
ling_datum.purchased_powers_history.Add("Re-adapt (Reset to [ling_datum.max_geneticpoints])")
//Now to lose the verb, so no unlimited resets.
src.verbs -= /mob/proc/changeling_respec

View File

@@ -12,6 +12,7 @@
desc = "That looks like it doesn't open easily."
icon = 'icons/obj/doors/rapid_pdoor.dmi'
icon_state = null
min_force = 20 //minimum amount of force needed to damage the door with a melee weapon
// Icon states for different shutter types. Simply change this instead of rewriting the update_icon proc.
var/icon_state_open = null
@@ -78,7 +79,10 @@
// Proc: force_toggle()
// Parameters: None
// Description: Opens or closes the door, depending on current state. No checks are done inside this proc.
/obj/machinery/door/blast/proc/force_toggle()
/obj/machinery/door/blast/proc/force_toggle(var/forced = 0, mob/user as mob)
if (forced)
playsound(src.loc, 'sound/machines/airlock_creaking.ogg', 100, 1)
if(src.density)
src.force_open()
else
@@ -91,7 +95,7 @@
/obj/machinery/door/blast/attackby(obj/item/weapon/C as obj, mob/user as mob)
src.add_fingerprint(user)
if(istype(C, /obj/item/weapon)) // For reasons unknown, sometimes C is actually not what it is advertised as, like a mob.
if(C.pry == 1) // Can we pry it open with something, like a crowbar/fireaxe/lingblade?
if(C.pry == 1 && (user.a_intent != I_HURT || (stat & BROKEN))) // Can we pry it open with something, like a crowbar/fireaxe/lingblade?
if(istype(C,/obj/item/weapon/material/twohanded/fireaxe)) // Fireaxes need to be in both hands to pry.
var/obj/item/weapon/material/twohanded/fireaxe/F = C
if(!F.wielded)
@@ -100,7 +104,8 @@
// If we're at this point, it's a fireaxe in both hands or something else that doesn't care for twohanding.
if(((stat & NOPOWER) || (stat & BROKEN)) && !( src.operating ))
force_toggle()
force_toggle(1, user)
else
usr << "<span class='notice'>[src]'s motors resist your effort.</span>"
return
@@ -123,15 +128,33 @@
usr << "<span class='warning'>You don't have enough sheets to repair this! You need at least [amt] sheets.</span>"
else if(src.density)
var/obj/item/weapon/W = C
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(W.damtype == BRUTE || W.damtype == BURN)
user.do_attack_animation(src)
if(W.force < min_force)
user.visible_message("<span class='danger'>\The [user] hits \the [src] with \the [W] with no visible effect.</span>")
else
user.visible_message("<span class='danger'>\The [user] forcefully strikes \the [src] with \the [W]!</span>")
playsound(src.loc, hitsound, 100, 1)
take_damage(W.force*0.35) //it's a blast door, it should take a while. -Luke
return
// Proc: open()
// Parameters: None
// Description: Opens the door. Does necessary checks. Automatically closes if autoclose is true
/obj/machinery/door/blast/open()
if (src.operating || (stat & BROKEN || stat & NOPOWER))
return
force_open()
if(autoclose)
/obj/machinery/door/blast/open(var/forced = 0)
if(forced)
force_open()
return 1
else
if (src.operating || (stat & BROKEN || stat & NOPOWER))
return 1
force_open()
if(autoclose && src.operating && !(stat & BROKEN || stat & NOPOWER))
spawn(150)
close()
return 1

View File

@@ -312,6 +312,8 @@
/obj/machinery/door/examine(mob/user)
. = ..()
if(src.health <= 0)
user << "\The [src] is broken!"
if(src.health < src.maxhealth / 4)
user << "\The [src] looks like it's about to break!"
else if(src.health < src.maxhealth / 2)

View File

@@ -0,0 +1,263 @@
#define MATERIAL_ARMOR_COEFFICENT 0.05
/*
SEE code/modules/materials/materials.dm FOR DETAILS ON INHERITED DATUM.
This class of armor takes armor and appearance data from a material "datum".
They are also fragile based on material data and many can break/smash apart when hit.
Materials has a var called protectiveness which plays a major factor in how good it is for armor.
With the coefficent being 0.05, this is how strong different levels of protectiveness are (for melee)
For bullets and lasers, material hardness and reflectivity also play a major role, respectively.
Protectiveness | Armor %
0 = 0%
5 = 20%
10 = 33%
15 = 42%
20 = 50%
25 = 55%
30 = 60%
40 = 66%
50 = 71%
60 = 75%
70 = 77%
80 = 80%
*/
// Putting these at /clothing/ level saves a lot of code duplication in armor/helmets/gauntlets/etc
/obj/item/clothing
var/material/material = null // Why isn't this a datum?
var/applies_material_color = TRUE
var/unbreakable = FALSE
var/default_material = null // Set this to something else if you want material attributes on init.
var/material_armor_modifer = 1 // Adjust if you want seperate types of armor made from the same material to have different protectiveness (e.g. makeshift vs real armor)
/obj/item/clothing/New(var/newloc, var/material_key)
..(newloc)
if(!material_key)
material_key = default_material
if(material_key) // May still be null if a material was not specified as a default.
set_material(material_key)
/obj/item/clothing/Destroy()
processing_objects -= src
..()
/obj/item/clothing/get_material()
return material
// Debating if this should be made an /obj/item/ proc.
/obj/item/clothing/proc/set_material(var/new_material)
material = get_material_by_name(new_material)
if(!material)
qdel(src)
else
name = "[material.display_name] [initial(name)]"
health = round(material.integrity/10)
if(applies_material_color)
color = material.icon_colour
if(material.products_need_process())
processing_objects |= src
update_armor()
// This is called when someone wearing the object gets hit in some form (melee, bullet_act(), etc).
// Note that this cannot change if someone gets hurt, as it merely reacts to being hit.
/obj/item/clothing/proc/clothing_impact(var/obj/source, var/damage)
if(material && damage)
material_impact(source, damage)
/obj/item/clothing/proc/material_impact(var/obj/source, var/damage)
if(!material || unbreakable)
return
if(istype(source, /obj/item/projectile))
var/obj/item/projectile/P = source
if(P.pass_flags & PASSGLASS)
if(material.opacity - 0.3 <= 0)
return // Lasers ignore 'fully' transparent material.
if(material.is_brittle())
health = 0
else if(!prob(material.hardness))
health--
if(health <= 0)
shatter()
/obj/item/clothing/proc/shatter()
if(!material)
return
var/turf/T = get_turf(src)
T.visible_message("<span class='danger'>\The [src] [material.destruction_desc]!</span>")
if(istype(loc, /mob/living))
var/mob/living/M = loc
M.drop_from_inventory(src)
if(material.shard_type == SHARD_SHARD) // Wearing glass armor is a bad idea.
var/obj/item/weapon/material/shard/S = material.place_shard(T)
M.embed(S)
playsound(src, "shatter", 70, 1)
qdel(src)
// Might be best to make ablative vests a material armor using a new material to cut down on this copypaste.
/obj/item/clothing/suit/armor/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(!material) // No point checking for reflection.
return ..()
if(material.reflectivity)
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 * material.reflectivity) - round(damage/3)
reflectchance *= material_armor_modifer
if(!(def_zone in list(BP_TORSO, BP_GROIN)))
reflectchance /= 2
if(P.starting && prob(reflectchance))
visible_message("<span class='danger'>\The [user]'s [src.name] reflects [attack_text]!</span>")
// Find a turf near or on the original location to bounce to
var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/turf/curloc = get_turf(user)
// redirect the projectile
P.redirect(new_x, new_y, curloc, user)
P.reflected = 1
return PROJECTILE_CONTINUE // complete projectile permutation
/proc/calculate_material_armor(amount)
var/result = 1 - MATERIAL_ARMOR_COEFFICENT * amount / (1 + MATERIAL_ARMOR_COEFFICENT * abs(amount))
result = result * 100
result = abs(result - 100)
return round(result)
/obj/item/clothing/proc/update_armor()
if(material)
var/melee_armor = 0, bullet_armor = 0, laser_armor = 0, energy_armor = 0, bomb_armor = 0
melee_armor = calculate_material_armor(material.protectiveness * material_armor_modifer)
bullet_armor = calculate_material_armor((material.protectiveness * (material.hardness / 100) * material_armor_modifer) * 0.7)
laser_armor = calculate_material_armor((material.protectiveness * (material.reflectivity + 1) * material_armor_modifer) * 0.7)
if(material.opacity != 1)
laser_armor *= max(material.opacity - 0.3, 0) // Glass and such has an opacity of 0.3, but lasers should go through glass armor entirely.
energy_armor = calculate_material_armor((material.protectiveness * material_armor_modifer) * 0.4)
bomb_armor = calculate_material_armor((material.protectiveness * material_armor_modifer) * 0.5)
// Makes sure the numbers stay capped.
for(var/number in list(melee_armor, bullet_armor, laser_armor, energy_armor, bomb_armor))
number = between(0, number, 100)
armor["melee"] = melee_armor
armor["bullet"] = bullet_armor
armor["laser"] = laser_armor
armor["energy"] = energy_armor
armor["bomb"] = bomb_armor
if(!isnull(material.conductivity))
siemens_coefficient = between(0, material.conductivity / 10, 10)
slowdown = between(0, round(material.weight / 10, 0.1), 6)
/obj/item/clothing/suit/armor/material
name = "armor"
default_material = DEFAULT_WALL_MATERIAL
/obj/item/clothing/suit/armor/material/makeshift
name = "sheet armor"
desc = "This appears to be two 'sheets' of a material held together by cable. If the sheets are strong, this could be rather protective."
icon_state = "material_armor_makeshift"
/obj/item/clothing/suit/armor/material/makeshift/durasteel
default_material = "durasteel"
/obj/item/clothing/suit/armor/material/makeshift/glass
default_material = "glass"
// Used to craft sheet armor, and possibly other things in the Future(tm).
/obj/item/weapon/material/armor_plating
name = "armor plating"
desc = "A sheet designed to protect something."
icon = 'icons/obj/items.dmi'
icon_state = "armor_plate"
unbreakable = TRUE
force_divisor = 0.05 // Really bad as a weapon.
thrown_force_divisor = 0.2
var/wired = FALSE
/obj/item/weapon/material/armor_plating/attackby(var/obj/O, mob/user)
if(istype(O, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/S = O
if(wired)
to_chat(user, "<span class='warning'>This already has enough wires on it.</span>")
return
if(S.use(20))
to_chat(user, "<span class='notice'>You attach several wires to \the [src]. Now it needs another plate.</span>")
wired = TRUE
icon_state = "[initial(icon_state)]_wired"
return
else
to_chat(user, "<span class='notice'>You need more wire for that.</span>")
return
if(istype(O, /obj/item/weapon/material/armor_plating))
var/obj/item/weapon/material/armor_plating/second_plate = O
if(!wired && !second_plate.wired)
to_chat(user, "<span class='warning'>You need something to hold the two pieces of plating together.</span>")
return
if(second_plate.material != src.material)
to_chat(user, "<span class='warning'>Both plates need to be the same type of material.</span>")
return
user.drop_from_inventory(src)
user.drop_from_inventory(second_plate)
var/obj/item/clothing/suit/armor/material/makeshift/new_armor = new(null, src.material.name)
user.put_in_hands(new_armor)
qdel(second_plate)
qdel(src)
else
..()
// Used to craft the makeshift helmet
/obj/item/clothing/head/helmet/bucket
name = "bucket"
desc = "It's a bucket with a large hole cut into it. You could wear it on your head and look really stupid."
flags_inv = HIDEEARS|HIDEEYES|BLOCKHAIR
icon_state = "bucket"
armor = list(melee = 5, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
/obj/item/clothing/head/helmet/bucket/attackby(var/obj/O, mob/user)
if(istype(O, /obj/item/stack/material))
var/obj/item/stack/material/S = O
if(S.use(2))
to_chat(user, "<span class='notice'>You apply some [S.material.use_name] to \the [src]. Hopefully it'll make the makeshift helmet stronger.</span>")
var/obj/item/clothing/head/helmet/material/makeshift/helmet = new(null, S.material.name)
user.put_in_hands(helmet)
user.drop_from_inventory(src)
qdel(src)
return
else
to_chat(user, "<span class='warning'>You don't have enough material to build a helmet!</span>")
else
..()
/obj/item/clothing/head/helmet/material
name = "helmet"
flags_inv = HIDEEARS|HIDEEYES|BLOCKHAIR
default_material = DEFAULT_WALL_MATERIAL
/obj/item/clothing/head/helmet/material/makeshift
name = "bucket"
desc = "A bucket with plating applied to the outside. Very crude, but could potentially be rather protective, if \
it was plated with something strong."
icon_state = "material_armor_makeshift"
/obj/item/clothing/head/helmet/material/makeshift/durasteel
default_material = "durasteel"

View File

@@ -243,3 +243,11 @@ var/const/enterloopsanity = 100
/turf/proc/update_blood_overlays()
return
// Called when turf is hit by a thrown object
/turf/hitby(atom/movable/AM as mob|obj, var/speed)
if(src.density)
spawn(2)
step(AM, turn(AM.last_move, 180))
if(isliving(AM))
var/mob/living/M = AM
M.turf_collision(src, speed)

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

@@ -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

@@ -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

@@ -88,6 +88,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)

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
@@ -242,9 +256,14 @@ emp_act
if(!affecting)
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...

View File

@@ -34,19 +34,21 @@
ambiguous_genders = TRUE
gluttonous = 1
slowdown = 0.5
brute_mod = 0.9
burn_mod = 0.9
brute_mod = 0.85
burn_mod = 0.85
metabolic_rate = 0.85
item_slowdown_halved = 1
num_alternate_languages = 3
secondary_langs = list(LANGUAGE_UNATHI)
name_language = LANGUAGE_UNATHI
health_hud_intensity = 2.5
min_age = 18
max_age = 60
min_age = 32
max_age = 260
blurb = "A heavily reptillian species, Unathi (or 'Sinta as they call themselves) hail from the \
Uuosa-Eso system, which roughly translates to 'burning mother'.<br/><br/>Coming from a harsh, radioactive \
desert planet, they mostly hold ideals of honesty, virtue, martial combat and bravery above all \
Uuosa-Eso system, which roughly translates to 'burning mother'.<br/><br/>Coming from a harsh, inhospitable \
planet, they mostly hold ideals of honesty, virtue, proficiency and bravery above all \
else, frequently even their own lives. They prefer warmer temperatures than most species and \
their native tongue is a heavy hissing laungage called Sinta'Unathi."
@@ -62,9 +64,34 @@
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
flesh_color = "#34AF10"
blood_color = "#b3cbc3"
base_color = "#066000"
reagent_tag = IS_UNATHI
base_color = "#066000"
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
heat_discomfort_strings = list(

View File

@@ -11,25 +11,35 @@ var/z_levels = 0 // Each bit represents a connection between adjacent levels. S
qdel(src)
// The storage of connections between adjacent levels means some bitwise magic is needed.
proc/HasAbove(var/z)
/proc/HasAbove(var/z)
if(z >= world.maxz || z > 16 || z < 1)
return 0
return z_levels & (1 << (z - 1))
proc/HasBelow(var/z)
/proc/HasBelow(var/z)
if(z > world.maxz || z > 17 || z < 2)
return 0
return z_levels & (1 << (z - 2))
// Thankfully, no bitwise magic is needed here.
proc/GetAbove(var/atom/atom)
/proc/GetAbove(var/atom/atom)
var/turf/turf = get_turf(atom)
if(!turf)
return null
return HasAbove(turf.z) ? get_step(turf, UP) : null
proc/GetBelow(var/atom/atom)
/proc/GetBelow(var/atom/atom)
var/turf/turf = get_turf(atom)
if(!turf)
return null
return HasBelow(turf.z) ? get_step(turf, DOWN) : null
/proc/GetConnectedZlevels(z)
. = list(z)
for(var/level = z, HasBelow(level), level--)
. |= level-1
for(var/level = z, HasAbove(level), level++)
. |= level+1
proc/AreConnectedZLevels(var/zA, var/zB)
return zA == zB || (zB in GetConnectedZlevels(zA))

View File

@@ -3,34 +3,38 @@
set category = "IC"
if(zMove(UP))
to_chat(usr, "<span class='notice'>You move upwards.</span>")
to_chat(src, "<span class='notice'>You move upwards.</span>")
/mob/verb/down()
set name = "Move Down"
set category = "IC"
if(zMove(DOWN))
to_chat(usr, "<span class='notice'>You move down.</span>")
to_chat(src, "<span class='notice'>You move down.</span>")
/mob/proc/zMove(direction)
if(eyeobj)
return eyeobj.zMove(direction)
if(!can_ztravel())
to_chat(usr, "<span class='warning'>You lack means of travel in that direction.</span>")
to_chat(src, "<span class='warning'>You lack means of travel in that direction.</span>")
return
var/turf/start = loc
if(!istype(start))
to_chat(src, "<span class='notice'>You are unable to move from here.</span>")
return 0
var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src)
if(!destination)
to_chat(usr, "<span class='notice'>There is nothing of interest in this direction.</span>")
to_chat(src, "<span class='notice'>There is nothing of interest in this direction.</span>")
return 0
if(!start.CanZPass(src, direction))
to_chat(src, "<span class='warning'>\The [start] is in the way.</span>")
return 0
var/turf/start = get_turf(src)
if(!start.CanZPass(src, direction))
to_chat(usr, "<span class='warning'>\The [start] is in the way.</span>")
return 0
if(!destination.CanZPass(src, direction))
to_chat(usr, "<span class='warning'>\The [destination] blocks your way.</span>")
to_chat(src, "<span class='warning'>\The [destination] blocks your way.</span>")
return 0
var/area/area = get_area(src)
@@ -46,12 +50,12 @@
to_chat(src, "<span class='warning'>You gave up on pulling yourself up.</span>")
return 0
else
to_chat(usr, "<span class='warning'>Gravity stops you from moving upward.</span>")
to_chat(src, "<span class='warning'>Gravity stops you from moving upward.</span>")
return 0
for(var/atom/A in destination)
if(!A.CanPass(src, start, 1.5, 0))
to_chat(usr, "<span class='warning'>\The [A] blocks you.</span>")
to_chat(src, "<span class='warning'>\The [A] blocks you.</span>")
return 0
Move(destination)
return 1
@@ -61,14 +65,14 @@
if(destination)
forceMove(destination)
else
to_chat(usr, "<span class='notice'>There is nothing of interest in this direction.</span>")
to_chat(src, "<span class='notice'>There is nothing of interest in this direction.</span>")
/mob/observer/eye/zMove(direction)
var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src)
if(destination)
setLoc(destination)
else
to_chat(usr, "<span class='notice'>There is nothing of interest in this direction.</span>")
to_chat(src, "<span class='notice'>There is nothing of interest in this direction.</span>")
/mob/proc/can_ztravel()
return 0

View File

@@ -13,6 +13,9 @@ obj/machinery/atmospherics/pipe/zpipe
dir = SOUTH
initialize_directions = SOUTH
// node1 is the connection on the same Z
// node2 is the connection on the other Z
var/minimum_temperature_difference = 300
var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No

View File

@@ -122,10 +122,6 @@
allowed_directions = UP|DOWN
icon_state = "ladder11"
/obj/structure/stairs
name = "Stairs"
desc = "Stairs leading to another deck. Not too useful if the gravity goes out."

View File

@@ -36,6 +36,11 @@
..()
mover.fall()
// Called when thrown object lands on this turf.
/turf/simulated/open/hitby(var/atom/movable/AM, var/speed)
. = ..()
AM.fall()
/turf/simulated/open/proc/update()
below = GetBelow(src)
turf_changed_event.register(below, src, /turf/simulated/open/update_icon)
@@ -82,7 +87,7 @@
return
var/obj/item/stack/rods/R = C
if (R.use(1))
user << "<span class='notice'>Constructing support lattice ...</span>"
to_chat(user, "<span class='notice'>Constructing support lattice ...</span>")
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
ReplaceWithLattice()
return
@@ -99,7 +104,7 @@
ChangeTurf(/turf/simulated/floor/airless)
return
else
user << "<span class='warning'>The plating is going to need some support.</span>"
to_chat(user, "<span class='warning'>The plating is going to need some support.</span>")
//To lay cable.
if(istype(C, /obj/item/stack/cable_coil))

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

@@ -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

@@ -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

View File

@@ -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

@@ -429,6 +429,7 @@
glass_name = "beer"
glass_desc = "A freezing pint of beer"
/* Drugs */
/datum/reagent/space_drugs

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

@@ -221,7 +221,7 @@
var/turf/T = locate(int_panel_x, int_panel_y, uz)
lift.control_panel_interior = new(T, lift)
lift.control_panel_interior.set_dir(udir)
lift.current_floor = lift.floors[uz]
lift.current_floor = lift.floors[1]
lift.open_doors()