Merge remote-tracking branch 'citadel/master' into mobility_flags
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
///Component specifically for explosion sensetive things, currently only applies to heat based explosions but can later perhaps be used for things that are dangerous to handle carelessly like nitroglycerin.
|
||||
/datum/component/explodable
|
||||
var/devastation_range = 0
|
||||
var/heavy_impact_range = 0
|
||||
var/light_impact_range = 2
|
||||
var/flash_range = 3
|
||||
var/equipped_slot //For items, lets us determine where things should be hit.
|
||||
|
||||
/datum/component/explodable/Initialize(devastation_range_override, heavy_impact_range_override, light_impact_range_override, flash_range_override)
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/explodable_attack)
|
||||
RegisterSignal(parent, COMSIG_TRY_STORAGE_INSERT, .proc/explodable_insert_item)
|
||||
RegisterSignal(parent, COMSIG_ATOM_EX_ACT, .proc/detonate)
|
||||
if(ismovableatom(parent))
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_IMPACT, .proc/explodable_impact)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_BUMP, .proc/explodable_bump)
|
||||
if(isitem(parent))
|
||||
RegisterSignal(parent, list(COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_OBJ, COMSIG_ITEM_HIT_REACT), .proc/explodable_attack)
|
||||
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
|
||||
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
|
||||
|
||||
|
||||
|
||||
if(devastation_range_override)
|
||||
devastation_range = devastation_range_override
|
||||
if(heavy_impact_range_override)
|
||||
heavy_impact_range = heavy_impact_range_override
|
||||
if(light_impact_range_override)
|
||||
light_impact_range = light_impact_range_override
|
||||
if(flash_range_override)
|
||||
flash_range = flash_range_override
|
||||
|
||||
/datum/component/explodable/proc/explodable_insert_item(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE)
|
||||
check_if_detonate(I)
|
||||
|
||||
/datum/component/explodable/proc/explodable_impact(datum/source, atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
check_if_detonate(hit_atom)
|
||||
|
||||
/datum/component/explodable/proc/explodable_bump(datum/source, atom/A)
|
||||
check_if_detonate(A)
|
||||
|
||||
///Called when you use this object to attack sopmething
|
||||
/datum/component/explodable/proc/explodable_attack(datum/source, atom/movable/target, mob/living/user)
|
||||
check_if_detonate(target)
|
||||
|
||||
///Called when you attack a specific body part of the thing this is equipped on. Useful for exploding pants.
|
||||
/datum/component/explodable/proc/explodable_attack_zone(datum/source, damage, damagetype, def_zone)
|
||||
if(!def_zone)
|
||||
return
|
||||
if(damagetype != BURN) //Don't bother if it's not fire.
|
||||
return
|
||||
if(!is_hitting_zone(def_zone)) //You didn't hit us! ha!
|
||||
return
|
||||
detonate()
|
||||
|
||||
/datum/component/explodable/proc/on_equip(datum/source, mob/equipper, slot)
|
||||
RegisterSignal(equipper, COMSIG_MOB_APPLY_DAMGE, .proc/explodable_attack_zone, TRUE)
|
||||
|
||||
/datum/component/explodable/proc/on_drop(datum/source, mob/user)
|
||||
UnregisterSignal(user, COMSIG_MOB_APPLY_DAMGE)
|
||||
|
||||
/// Checks if we're hitting the zone this component is covering
|
||||
/datum/component/explodable/proc/is_hitting_zone(def_zone)
|
||||
var/obj/item/item = parent
|
||||
var/mob/living/L = item.loc //Get whoever is equipping the item currently
|
||||
|
||||
if(!istype(L))
|
||||
return
|
||||
|
||||
var/obj/item/bodypart/bodypart = L.get_bodypart(check_zone(def_zone))
|
||||
|
||||
var/list/equipment_items = list()
|
||||
if(iscarbon(L))
|
||||
var/mob/living/carbon/C = L
|
||||
equipment_items += list(C.head, C.wear_mask, C.back, C.gloves, C.shoes, C.glasses, C.ears)
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
equipment_items += list(H.wear_suit, H.w_uniform, H.belt, H.s_store, H.wear_id)
|
||||
|
||||
for(var/bp in equipment_items)
|
||||
if(!bp)
|
||||
continue
|
||||
|
||||
var/obj/item/I = bp
|
||||
if(I.body_parts_covered & bodypart.body_part)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/component/explodable/proc/check_if_detonate(target)
|
||||
if(!isitem(target))
|
||||
return
|
||||
var/obj/item/I = target
|
||||
if(!I.get_temperature())
|
||||
return
|
||||
detonate() //If we're touching a hot item we go boom
|
||||
|
||||
|
||||
/// Expldoe and remove the object
|
||||
/datum/component/explodable/proc/detonate()
|
||||
var/atom/A = parent
|
||||
explosion(A, devastation_range, heavy_impact_range, light_impact_range, flash_range) //epic explosion time
|
||||
qdel(A)
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*!
|
||||
This datum should be used for handling mineral contents of machines and whatever else is supposed to hold minerals and make use of them.
|
||||
|
||||
Variables:
|
||||
@@ -13,7 +13,7 @@
|
||||
var/total_amount = 0
|
||||
var/max_amount
|
||||
var/sheet_type
|
||||
var/list/materials
|
||||
var/list/materials //Map of key = material ref | Value = amount
|
||||
var/show_on_examine
|
||||
var/disable_attackby
|
||||
var/list/allowed_typecache
|
||||
@@ -22,6 +22,7 @@
|
||||
var/datum/callback/precondition
|
||||
var/datum/callback/after_insert
|
||||
|
||||
/// Sets up the proper signals and fills the list of materials with the appropriate references.
|
||||
/datum/component/material_container/Initialize(list/mat_list, max_amt = 0, _show_on_examine = FALSE, list/allowed_types, datum/callback/_precondition, datum/callback/_after_insert, _disable_attackby)
|
||||
materials = list()
|
||||
max_amount = max(0, max_amt)
|
||||
@@ -40,23 +41,19 @@
|
||||
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
|
||||
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/OnExamine)
|
||||
|
||||
var/list/possible_mats = list()
|
||||
for(var/mat_type in subtypesof(/datum/material))
|
||||
var/datum/material/MT = mat_type
|
||||
possible_mats[initial(MT.id)] = mat_type
|
||||
for(var/id in mat_list)
|
||||
if(possible_mats[id])
|
||||
var/mat_path = possible_mats[id]
|
||||
materials[id] = new mat_path()
|
||||
for(var/mat in mat_list) //Make the assoc list ref | amount
|
||||
var/datum/material/M = getmaterialref(mat) || mat
|
||||
materials[M] = 0
|
||||
|
||||
/datum/component/material_container/proc/OnExamine(datum/source, mob/user, list/examine_list)
|
||||
if(show_on_examine)
|
||||
for(var/I in materials)
|
||||
var/datum/material/M = materials[I]
|
||||
var/amt = amount(M.id)
|
||||
var/datum/material/M = I
|
||||
var/amt = materials[I]
|
||||
if(amt)
|
||||
examine_list += "<span class='notice'>It has [amt] units of [lowertext(M.name)] stored.</span>"
|
||||
|
||||
/// Proc that allows players to fill the parent with mats
|
||||
/datum/component/material_container/proc/OnAttackBy(datum/source, obj/item/I, mob/living/user)
|
||||
var/list/tc = allowed_typecache
|
||||
if(disable_attackby)
|
||||
@@ -74,13 +71,14 @@
|
||||
return
|
||||
var/material_amount = get_item_material_amount(I)
|
||||
if(!material_amount)
|
||||
to_chat(user, "<span class='warning'>[I] does not contain sufficient amounts of metal or glass to be accepted by [parent].</span>")
|
||||
to_chat(user, "<span class='warning'>[I] does not contain sufficient materials to be accepted by [parent].</span>")
|
||||
return
|
||||
if(!has_space(material_amount))
|
||||
to_chat(user, "<span class='warning'>[parent] is full. Please remove metal or glass from [parent] in order to insert more.</span>")
|
||||
to_chat(user, "<span class='warning'>[parent] has not enough space. Please remove materials from [parent] in order to insert more.</span>")
|
||||
return
|
||||
user_insert(I, user)
|
||||
|
||||
/// Proc used for when player inserts materials
|
||||
/datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user)
|
||||
set waitfor = FALSE
|
||||
var/requested_amount
|
||||
@@ -98,299 +96,225 @@
|
||||
return
|
||||
var/inserted = insert_item(I, stack_amt = requested_amount)
|
||||
if(inserted)
|
||||
if(istype(I, /obj/item/stack))
|
||||
var/obj/item/stack/S = I
|
||||
to_chat(user, "<span class='notice'>You insert [inserted] [S.singular_name][inserted>1 ? "s" : ""] into [parent].</span>")
|
||||
if(!QDELETED(I) && I == active_held && !user.put_in_hands(I))
|
||||
stack_trace("Warning: User could not put object back in hand during material container insertion, line [__LINE__]! This can lead to issues.")
|
||||
I.forceMove(user.drop_location())
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You insert a material total of [inserted] into [parent].</span>")
|
||||
qdel(I)
|
||||
to_chat(user, "<span class='notice'>You insert a material total of [inserted] into [parent].</span>")
|
||||
qdel(I)
|
||||
if(after_insert)
|
||||
after_insert.Invoke(I.type, last_inserted_id, inserted)
|
||||
after_insert.Invoke(I, last_inserted_id, inserted)
|
||||
else if(I == active_held)
|
||||
user.put_in_active_hand(I)
|
||||
|
||||
//For inserting an amount of material
|
||||
/datum/component/material_container/proc/insert_amount(amt, id = null)
|
||||
if(amt > 0 && has_space(amt))
|
||||
var/total_amount_saved = total_amount
|
||||
if(id)
|
||||
var/datum/material/M = materials[id]
|
||||
if(M)
|
||||
M.amount += amt
|
||||
total_amount += amt
|
||||
else
|
||||
for(var/i in materials)
|
||||
var/datum/material/M = materials[i]
|
||||
M.amount += amt
|
||||
total_amount += amt
|
||||
return (total_amount - total_amount_saved)
|
||||
return FALSE
|
||||
|
||||
/datum/component/material_container/proc/insert_stack(obj/item/stack/S, amt, multiplier = 1)
|
||||
if(isnull(amt))
|
||||
amt = S.amount
|
||||
|
||||
if(amt <= 0)
|
||||
return FALSE
|
||||
|
||||
if(amt > S.amount)
|
||||
amt = S.amount
|
||||
|
||||
var/material_amt = get_item_material_amount(S)
|
||||
if(!material_amt)
|
||||
return FALSE
|
||||
|
||||
amt = min(amt, round(((max_amount - total_amount) / material_amt)))
|
||||
if(!amt)
|
||||
return FALSE
|
||||
|
||||
last_inserted_id = insert_materials(S,amt * multiplier)
|
||||
S.use(amt)
|
||||
return amt
|
||||
|
||||
/datum/component/material_container/proc/insert_item(obj/item/I, multiplier = 1, stack_amt)
|
||||
/// Proc specifically for inserting items, returns the amount of materials entered.
|
||||
/datum/component/material_container/proc/insert_item(obj/item/I, var/multiplier = 1, stack_amt)
|
||||
if(!I)
|
||||
return FALSE
|
||||
if(istype(I, /obj/item/stack))
|
||||
return insert_stack(I, stack_amt, multiplier)
|
||||
|
||||
multiplier = CEILING(multiplier, 0.01)
|
||||
|
||||
var/material_amount = get_item_material_amount(I)
|
||||
if(!material_amount || !has_space(material_amount))
|
||||
return FALSE
|
||||
|
||||
last_inserted_id = insert_materials(I, multiplier)
|
||||
last_inserted_id = insert_item_materials(I, multiplier)
|
||||
return material_amount
|
||||
|
||||
/datum/component/material_container/proc/insert_materials(obj/item/I, multiplier = 1) //for internal usage only
|
||||
var/datum/material/M
|
||||
/datum/component/material_container/proc/insert_item_materials(obj/item/I, multiplier = 1)
|
||||
var/primary_mat
|
||||
var/max_mat_value = 0
|
||||
for(var/MAT in materials)
|
||||
M = materials[MAT]
|
||||
M.amount += I.materials[MAT] * multiplier
|
||||
total_amount += I.materials[MAT] * multiplier
|
||||
if(I.materials[MAT] > max_mat_value)
|
||||
materials[MAT] += I.custom_materials[MAT] * multiplier
|
||||
total_amount += I.custom_materials[MAT] * multiplier
|
||||
if(I.custom_materials[MAT] > max_mat_value)
|
||||
primary_mat = MAT
|
||||
return primary_mat
|
||||
|
||||
//For consuming material
|
||||
//mats is a list of types of material to use and the corresponding amounts, example: list(MAT_METAL=100, MAT_GLASS=200)
|
||||
/datum/component/material_container/proc/use_amount(list/mats, multiplier=1)
|
||||
if(!mats || !mats.len)
|
||||
return FALSE
|
||||
/// For inserting an amount of material
|
||||
/datum/component/material_container/proc/insert_amount_mat(amt, var/datum/material/mat)
|
||||
if(!istype(mat))
|
||||
mat = getmaterialref(mat)
|
||||
if(amt > 0 && has_space(amt))
|
||||
var/total_amount_saved = total_amount
|
||||
if(mat)
|
||||
materials[mat] += amt
|
||||
else
|
||||
for(var/i in materials)
|
||||
materials[i] += amt
|
||||
total_amount += amt
|
||||
return (total_amount - total_amount_saved)
|
||||
return FALSE
|
||||
|
||||
var/datum/material/M
|
||||
for(var/MAT in materials)
|
||||
M = materials[MAT]
|
||||
if(M.amount < (mats[MAT] * multiplier))
|
||||
return FALSE
|
||||
|
||||
var/total_amount_save = total_amount
|
||||
for(var/MAT in materials)
|
||||
M = materials[MAT]
|
||||
M.amount -= mats[MAT] * multiplier
|
||||
total_amount -= mats[MAT] * multiplier
|
||||
|
||||
return total_amount_save - total_amount
|
||||
|
||||
|
||||
/datum/component/material_container/proc/use_amount_type(amt, id)
|
||||
var/datum/material/M = materials[id]
|
||||
if(M)
|
||||
if(M.amount >= amt)
|
||||
M.amount -= amt
|
||||
/// Uses an amount of a specific material, effectively removing it.
|
||||
/datum/component/material_container/proc/use_amount_mat(amt, var/datum/material/mat)
|
||||
if(!istype(mat))
|
||||
mat = getmaterialref(mat)
|
||||
var/amount = materials[mat]
|
||||
if(mat)
|
||||
if(amount >= amt)
|
||||
materials[mat] -= amt
|
||||
total_amount -= amt
|
||||
return amt
|
||||
return FALSE
|
||||
|
||||
/datum/component/material_container/proc/transer_amt_to(var/datum/component/material_container/T, amt, id)
|
||||
if((amt==0)||(!T)||(!id))
|
||||
/// Proc for transfering materials to another container.
|
||||
/datum/component/material_container/proc/transer_amt_to(var/datum/component/material_container/T, amt, var/datum/material/mat)
|
||||
if(!istype(mat))
|
||||
mat = getmaterialref(mat)
|
||||
if((amt==0)||(!T)||(!mat))
|
||||
return FALSE
|
||||
if(amt<0)
|
||||
return T.transer_amt_to(src, -amt, id)
|
||||
var/datum/material/M = materials[id]
|
||||
|
||||
if(M)
|
||||
var/tr = min(amt, M.amount,T.can_insert_amount(amt, id))
|
||||
if(tr)
|
||||
use_amount_type(tr, id)
|
||||
T.insert_amount(tr, id)
|
||||
return tr
|
||||
return T.transer_amt_to(src, -amt, mat)
|
||||
var/tr = min(amt, materials[mat],T.can_insert_amount_mat(amt, mat))
|
||||
if(tr)
|
||||
use_amount_mat(tr, mat)
|
||||
T.insert_amount_mat(tr, mat)
|
||||
return tr
|
||||
return FALSE
|
||||
|
||||
/datum/component/material_container/proc/can_insert_amount(amt, id)
|
||||
if(amt && id)
|
||||
var/datum/material/M = materials[id]
|
||||
/// Proc for checking if there is room in the component, returning the amount or else the amount lacking.
|
||||
/datum/component/material_container/proc/can_insert_amount_mat(amt, mat)
|
||||
if(amt && mat)
|
||||
var/datum/material/M = mat
|
||||
if(M)
|
||||
if((total_amount + amt) <= max_amount)
|
||||
return amt
|
||||
else
|
||||
return (max_amount-total_amount)
|
||||
|
||||
/datum/component/material_container/proc/can_use_amount(amt, id, list/mats)
|
||||
if(amt && id)
|
||||
var/datum/material/M = materials[id]
|
||||
if(M && M.amount >= amt)
|
||||
return TRUE
|
||||
else if(istype(mats))
|
||||
for(var/M in mats)
|
||||
if(materials[M] && (mats[M] <= materials[M]))
|
||||
continue
|
||||
else
|
||||
return FALSE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//For spawning mineral sheets; internal use only
|
||||
/datum/component/material_container/proc/retrieve(sheet_amt, datum/material/M, target = null)
|
||||
/// For consuming a dictionary of materials. mats is the map of materials to use and the corresponding amounts, example: list(M/datum/material/glass =100, datum/material/iron=200)
|
||||
/datum/component/material_container/proc/use_materials(list/mats, multiplier=1)
|
||||
if(!mats || !length(mats))
|
||||
return FALSE
|
||||
|
||||
var/list/mats_to_remove = list() //Assoc list MAT | AMOUNT
|
||||
|
||||
for(var/x in mats) //Loop through all required materials
|
||||
var/datum/material/req_mat = x
|
||||
if(!istype(req_mat))
|
||||
req_mat = getmaterialref(req_mat) //Get the ref if necesary
|
||||
if(!materials[req_mat]) //Do we have the resource?
|
||||
return FALSE //Can't afford it
|
||||
var/amount_required = mats[x] * multiplier
|
||||
if(!(materials[req_mat] >= amount_required)) // do we have enough of the resource?
|
||||
return FALSE //Can't afford it
|
||||
mats_to_remove[req_mat] += amount_required //Add it to the assoc list of things to remove
|
||||
continue
|
||||
|
||||
var/total_amount_save = total_amount
|
||||
|
||||
for(var/i in mats_to_remove)
|
||||
total_amount_save -= use_amount_mat(mats_to_remove[i], i)
|
||||
|
||||
return total_amount_save - total_amount
|
||||
|
||||
/// For spawning mineral sheets at a specific location. Used by machines to output sheets.
|
||||
/datum/component/material_container/proc/retrieve_sheets(sheet_amt, var/datum/material/M, target = null)
|
||||
if(!M.sheet_type)
|
||||
return 0
|
||||
return 0 //Add greyscale sheet handling here later
|
||||
if(sheet_amt <= 0)
|
||||
return 0
|
||||
|
||||
if(!target)
|
||||
target = get_turf(parent)
|
||||
if(M.amount < (sheet_amt * MINERAL_MATERIAL_AMOUNT))
|
||||
sheet_amt = round(M.amount / MINERAL_MATERIAL_AMOUNT)
|
||||
if(materials[M] < (sheet_amt * MINERAL_MATERIAL_AMOUNT))
|
||||
sheet_amt = round(materials[M] / MINERAL_MATERIAL_AMOUNT)
|
||||
var/count = 0
|
||||
while(sheet_amt > MAX_STACK_SIZE)
|
||||
new M.sheet_type(target, MAX_STACK_SIZE)
|
||||
count += MAX_STACK_SIZE
|
||||
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
|
||||
use_amount_mat(sheet_amt * MINERAL_MATERIAL_AMOUNT, M)
|
||||
sheet_amt -= MAX_STACK_SIZE
|
||||
if(sheet_amt >= 1)
|
||||
new M.sheet_type(target, sheet_amt)
|
||||
count += sheet_amt
|
||||
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
|
||||
use_amount_mat(sheet_amt * MINERAL_MATERIAL_AMOUNT, M)
|
||||
return count
|
||||
|
||||
/datum/component/material_container/proc/retrieve_sheets(sheet_amt, id, target = null)
|
||||
if(materials[id])
|
||||
return retrieve(sheet_amt, materials[id], target)
|
||||
return FALSE
|
||||
|
||||
/datum/component/material_container/proc/retrieve_amount(amt, id, target)
|
||||
return retrieve_sheets(amount2sheet(amt), id, target)
|
||||
|
||||
/// Proc to get all the materials and dump them as sheets
|
||||
/datum/component/material_container/proc/retrieve_all(target = null)
|
||||
var/result = 0
|
||||
var/datum/material/M
|
||||
for(var/MAT in materials)
|
||||
M = materials[MAT]
|
||||
result += retrieve_sheets(amount2sheet(M.amount), MAT, target)
|
||||
var/amount = materials[MAT]
|
||||
result += retrieve_sheets(amount2sheet(amount), MAT, target)
|
||||
return result
|
||||
|
||||
/// Proc that returns TRUE if the container has space
|
||||
/datum/component/material_container/proc/has_space(amt = 0)
|
||||
return (total_amount + amt) <= max_amount
|
||||
|
||||
/// Checks if its possible to afford a certain amount of materials. Takes a dictionary of materials.
|
||||
/datum/component/material_container/proc/has_materials(list/mats, multiplier=1)
|
||||
if(!mats || !mats.len)
|
||||
return FALSE
|
||||
|
||||
var/datum/material/M
|
||||
for(var/MAT in mats)
|
||||
M = materials[MAT]
|
||||
if(M.amount < (mats[MAT] * multiplier))
|
||||
for(var/x in mats) //Loop through all required materials
|
||||
var/datum/material/req_mat = x
|
||||
if(!istype(req_mat))
|
||||
if(ispath(req_mat)) //Is this an actual material, or is it a category?
|
||||
req_mat = getmaterialref(req_mat) //Get the ref
|
||||
|
||||
else // Its a category. (For example MAT_CATEGORY_RIGID)
|
||||
if(!has_enough_of_category(req_mat, mats[req_mat], multiplier)) //Do we have enough of this category?
|
||||
return FALSE
|
||||
else
|
||||
continue
|
||||
|
||||
if(!has_enough_of_material(req_mat, mats[req_mat], multiplier))//Not a category, so just check the normal way
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/// Returns all the categories in a recipe.
|
||||
/datum/component/material_container/proc/get_categories(list/mats)
|
||||
var/list/categories = list()
|
||||
for(var/x in mats) //Loop through all required materials
|
||||
if(!istext(x)) //This means its not a category
|
||||
continue
|
||||
categories += x
|
||||
return categories
|
||||
|
||||
|
||||
/// Returns TRUE if you have enough of the specified material.
|
||||
/datum/component/material_container/proc/has_enough_of_material(var/datum/material/req_mat, amount, multiplier=1)
|
||||
if(!materials[req_mat]) //Do we have the resource?
|
||||
return FALSE //Can't afford it
|
||||
var/amount_required = amount * multiplier
|
||||
if(materials[req_mat] >= amount_required) // do we have enough of the resource?
|
||||
return TRUE
|
||||
return FALSE //Can't afford it
|
||||
|
||||
/// Returns TRUE if you have enough of a specified material category (Which could be multiple materials)
|
||||
/datum/component/material_container/proc/has_enough_of_category(category, amount, multiplier=1)
|
||||
for(var/i in SSmaterials.materials_by_category[category])
|
||||
var/datum/material/mat = i
|
||||
if(materials[mat] >= amount) //we have enough
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/// Turns a material amount into the amount of sheets it should output
|
||||
/datum/component/material_container/proc/amount2sheet(amt)
|
||||
if(amt >= MINERAL_MATERIAL_AMOUNT)
|
||||
return round(amt / MINERAL_MATERIAL_AMOUNT)
|
||||
return FALSE
|
||||
|
||||
/// Turns an amount of sheets into the amount of material amount it should output
|
||||
/datum/component/material_container/proc/sheet2amount(sheet_amt)
|
||||
if(sheet_amt > 0)
|
||||
return sheet_amt * MINERAL_MATERIAL_AMOUNT
|
||||
return FALSE
|
||||
|
||||
/datum/component/material_container/proc/amount(id)
|
||||
var/datum/material/M = materials[id]
|
||||
return M ? M.amount : 0
|
||||
|
||||
//returns the amount of material relevant to this container;
|
||||
//if this container does not support glass, any glass in 'I' will not be taken into account
|
||||
///returns the amount of material relevant to this container; if this container does not support glass, any glass in 'I' will not be taken into account
|
||||
/datum/component/material_container/proc/get_item_material_amount(obj/item/I)
|
||||
if(!istype(I))
|
||||
if(!istype(I) || !I.custom_materials)
|
||||
return FALSE
|
||||
var/material_amount = 0
|
||||
for(var/MAT in materials)
|
||||
material_amount += I.materials[MAT]
|
||||
material_amount += I.custom_materials[MAT]
|
||||
return material_amount
|
||||
|
||||
|
||||
/datum/material
|
||||
var/name
|
||||
var/amount = 0
|
||||
var/id = null
|
||||
var/sheet_type = null
|
||||
var/coin_type = null
|
||||
|
||||
/datum/material/metal
|
||||
name = "Metal"
|
||||
id = MAT_METAL
|
||||
sheet_type = /obj/item/stack/sheet/metal
|
||||
coin_type = /obj/item/coin/iron
|
||||
|
||||
/datum/material/glass
|
||||
name = "Glass"
|
||||
id = MAT_GLASS
|
||||
sheet_type = /obj/item/stack/sheet/glass
|
||||
|
||||
/datum/material/silver
|
||||
name = "Silver"
|
||||
id = MAT_SILVER
|
||||
sheet_type = /obj/item/stack/sheet/mineral/silver
|
||||
coin_type = /obj/item/coin/silver
|
||||
|
||||
/datum/material/gold
|
||||
name = "Gold"
|
||||
id = MAT_GOLD
|
||||
sheet_type = /obj/item/stack/sheet/mineral/gold
|
||||
coin_type = /obj/item/coin/gold
|
||||
|
||||
/datum/material/diamond
|
||||
name = "Diamond"
|
||||
id = MAT_DIAMOND
|
||||
sheet_type = /obj/item/stack/sheet/mineral/diamond
|
||||
coin_type = /obj/item/coin/diamond
|
||||
|
||||
/datum/material/uranium
|
||||
name = "Uranium"
|
||||
id = MAT_URANIUM
|
||||
sheet_type = /obj/item/stack/sheet/mineral/uranium
|
||||
coin_type = /obj/item/coin/uranium
|
||||
|
||||
/datum/material/plasma
|
||||
name = "Solid Plasma"
|
||||
id = MAT_PLASMA
|
||||
sheet_type = /obj/item/stack/sheet/mineral/plasma
|
||||
coin_type = /obj/item/coin/plasma
|
||||
|
||||
/datum/material/bluespace
|
||||
name = "Bluespace Mesh"
|
||||
id = MAT_BLUESPACE
|
||||
sheet_type = /obj/item/stack/sheet/bluespace_crystal
|
||||
|
||||
/datum/material/bananium
|
||||
name = "Bananium"
|
||||
id = MAT_BANANIUM
|
||||
sheet_type = /obj/item/stack/sheet/mineral/bananium
|
||||
coin_type = /obj/item/coin/bananium
|
||||
|
||||
/datum/material/titanium
|
||||
name = "Titanium"
|
||||
id = MAT_TITANIUM
|
||||
sheet_type = /obj/item/stack/sheet/mineral/titanium
|
||||
|
||||
/datum/material/biomass
|
||||
name = "Biomass"
|
||||
id = MAT_BIOMASS
|
||||
|
||||
/datum/material/plastic
|
||||
name = "Plastic"
|
||||
id = MAT_PLASTIC
|
||||
sheet_type = /obj/item/stack/sheet/plastic
|
||||
/// Returns the amount of a specific material in this container.
|
||||
/datum/component/material_container/proc/get_material_amount(var/datum/material/mat)
|
||||
if(!istype(mat))
|
||||
mat = getmaterialref(mat)
|
||||
return(materials[mat])
|
||||
|
||||
@@ -77,6 +77,8 @@
|
||||
/datum/component/radioactive/proc/rad_attack(datum/source, atom/movable/target, mob/living/user)
|
||||
radiation_pulse(parent, strength/20)
|
||||
target.rad_act(strength/2)
|
||||
if(!hl3_release_date)
|
||||
return
|
||||
strength -= strength / hl3_release_date
|
||||
|
||||
#undef RAD_AMOUNT_LOW
|
||||
|
||||
@@ -54,7 +54,7 @@ handles linking back and forth.
|
||||
/datum/component/remote_materials/proc/_MakeLocal()
|
||||
silo = null
|
||||
mat_container = parent.AddComponent(/datum/component/material_container,
|
||||
list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE, MAT_PLASTIC),
|
||||
list(/datum/material/iron, /datum/material/glass, /datum/material/silver, /datum/material/gold, /datum/material/diamond, /datum/material/plasma, /datum/material/uranium, /datum/material/bananium, /datum/material/titanium, /datum/material/bluespace, /datum/material/plastic),
|
||||
local_size,
|
||||
FALSE,
|
||||
/obj/item/stack)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
intensity = max(_intensity, 0)
|
||||
lube_flags = _lube_flags
|
||||
callback = _callback
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Slip)
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED, COMSIG_ITEM_WEARERCROSSED), .proc/Slip)
|
||||
|
||||
/datum/component/slippery/proc/Slip(datum/source, atom/movable/AM)
|
||||
var/mob/victim = AM
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
RegisterSignal(parent, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_PARENT_ATTACKBY), .proc/play_squeak)
|
||||
if(ismovableatom(parent))
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_IMPACT), .proc/play_squeak)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/play_squeak_crossed)
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ITEM_WEARERCROSSED), .proc/play_squeak_crossed)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_DISPOSING, .proc/disposing_react)
|
||||
if(isitem(parent))
|
||||
RegisterSignal(parent, list(COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_OBJ, COMSIG_ITEM_HIT_REACT), .proc/play_squeak)
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Can be applied to /atom/movable subtypes to make them apply fire stacks to things they hit
|
||||
*/
|
||||
/datum/element/firestacker
|
||||
element_flags = ELEMENT_BESPOKE
|
||||
id_arg_index = 2
|
||||
/// How many firestacks to apply per hit
|
||||
var/amount
|
||||
|
||||
/datum/element/firestacker/Attach(datum/target, amount)
|
||||
. = ..()
|
||||
|
||||
if(!ismovableatom(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
|
||||
src.amount = amount
|
||||
|
||||
RegisterSignal(target, COMSIG_MOVABLE_IMPACT, .proc/impact, override = TRUE)
|
||||
if(isitem(target))
|
||||
RegisterSignal(target, COMSIG_ITEM_ATTACK, .proc/item_attack, override = TRUE)
|
||||
RegisterSignal(target, COMSIG_ITEM_ATTACK_SELF, .proc/item_attack_self, override = TRUE)
|
||||
|
||||
/datum/element/firestacker/Detach(datum/source, force)
|
||||
. = ..()
|
||||
UnregisterSignal(source, list(COMSIG_MOVABLE_IMPACT, COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_SELF))
|
||||
|
||||
/datum/element/firestacker/proc/stack_on(datum/owner, mob/living/target)
|
||||
target.adjust_fire_stacks(amount)
|
||||
|
||||
/datum/element/firestacker/proc/impact(datum/source, atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
if(isliving(hit_atom))
|
||||
stack_on(source, hit_atom)
|
||||
|
||||
/datum/element/firestacker/proc/item_attack(datum/source, atom/movable/target, mob/living/user)
|
||||
if(isliving(target))
|
||||
stack_on(source, target)
|
||||
|
||||
/datum/element/firestacker/proc/item_attack_self(datum/source, mob/user)
|
||||
if(isliving(user))
|
||||
stack_on(source, user)
|
||||
@@ -216,7 +216,7 @@
|
||||
desc = "Stores recorder holocalls."
|
||||
icon_state = "holodisk"
|
||||
obj_flags = UNIQUE_RENAME
|
||||
materials = list(MAT_METAL = 100, MAT_GLASS = 100)
|
||||
custom_materials = list(/datum/material/iron = 100, /datum/material/glass = 100)
|
||||
var/datum/holorecord/record
|
||||
//Preset variables
|
||||
var/preset_image_type
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*! Material datum
|
||||
Simple datum which is instanced once per type and is used for every object of said material. It has a variety of variables that define behavior. Subtyping from this makes it easier to create your own materials.
|
||||
*/
|
||||
|
||||
|
||||
/datum/material
|
||||
var/name = "material"
|
||||
var/desc = "its..stuff."
|
||||
///Var that's mostly used by science machines to identify specific materials, should most likely be phased out at some point
|
||||
var/id = "mat"
|
||||
///Base color of the material, is used for greyscale. Item isn't changed in color if this is null.
|
||||
var/color
|
||||
///Base alpha of the material, is used for greyscale icons.
|
||||
var/alpha
|
||||
///Materials "Traits". its a map of key = category | Value = Bool. Used to define what it can be used for
|
||||
var/list/categories = list()
|
||||
///The type of sheet this material creates. This should be replaced as soon as possible by greyscale sheets
|
||||
var/sheet_type
|
||||
///This is a modifier for force, and resembles the strength of the material
|
||||
var/strength_modifier = 1
|
||||
///This is a modifier for integrity, and resembles the strength of the material
|
||||
var/integrity_modifier = 1
|
||||
///This is the amount of value per 1 unit of the material
|
||||
var/value_per_unit = 0
|
||||
///Armor modifiers, multiplies an items normal armor vars by these amounts.
|
||||
var/armor_modifiers = list("melee" = 1, "bullet" = 1, "laser" = 1, "energy" = 1, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 1, "acid" = 1)
|
||||
|
||||
///This proc is called when the material is added to an object.
|
||||
/datum/material/proc/on_applied(atom/source, amount, material_flags)
|
||||
if(material_flags & MATERIAL_COLOR) //Prevent changing things with pre-set colors, to keep colored toolboxes their looks for example
|
||||
if(color) //Do we have a custom color?
|
||||
source.add_atom_colour(color, FIXED_COLOUR_PRIORITY)
|
||||
if(alpha)
|
||||
source.alpha = alpha
|
||||
|
||||
if(material_flags & MATERIAL_ADD_PREFIX)
|
||||
source.name = "[name] [source.name]"
|
||||
|
||||
if(istype(source, /obj)) //objs
|
||||
on_applied_obj(source, amount, material_flags)
|
||||
|
||||
///This proc is called when the material is added to an object specifically.
|
||||
/datum/material/proc/on_applied_obj(var/obj/o, amount, material_flags)
|
||||
var/new_max_integrity = CEILING(o.max_integrity * integrity_modifier, 1)
|
||||
o.modify_max_integrity(new_max_integrity)
|
||||
o.force *= strength_modifier
|
||||
o.throwforce *= strength_modifier
|
||||
|
||||
var/list/temp_armor_list = list() //Time to add armor modifiers!
|
||||
|
||||
if(!istype(o.armor))
|
||||
return
|
||||
var/list/current_armor = o.armor?.getList()
|
||||
|
||||
for(var/i in current_armor)
|
||||
temp_armor_list[i] = current_armor[i] * armor_modifiers[i]
|
||||
o.armor = getArmor(arglist(temp_armor_list))
|
||||
|
||||
///This proc is called when the material is removed from an object.
|
||||
/datum/material/proc/on_removed(atom/source, material_flags)
|
||||
if(material_flags & MATERIAL_COLOR) //Prevent changing things with pre-set colors, to keep colored toolboxes their looks for example
|
||||
if(color)
|
||||
source.remove_atom_colour(FIXED_COLOUR_PRIORITY, color)
|
||||
source.alpha = initial(source.alpha)
|
||||
|
||||
if(material_flags & MATERIAL_ADD_PREFIX)
|
||||
source.name = initial(source.name)
|
||||
|
||||
if(istype(source, /obj)) //objs
|
||||
on_removed_obj(source, material_flags)
|
||||
|
||||
///This proc is called when the material is removed from an object specifically.
|
||||
/datum/material/proc/on_removed_obj(var/obj/o, amount, material_flags)
|
||||
var/new_max_integrity = initial(o.max_integrity)
|
||||
o.modify_max_integrity(new_max_integrity)
|
||||
o.force = initial(o.force)
|
||||
o.throwforce = initial(o.throwforce)
|
||||
@@ -0,0 +1,210 @@
|
||||
///Has no special properties.
|
||||
/datum/material/iron
|
||||
name = "iron"
|
||||
id = "iron"
|
||||
desc = "Common iron ore often found in sedimentary and igneous layers of the crust."
|
||||
color = "#878687"
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/metal
|
||||
value_per_unit = 0.0025
|
||||
|
||||
///Breaks extremely easily but is transparent.
|
||||
/datum/material/glass
|
||||
name = "glass"
|
||||
id = "glass"
|
||||
desc = "Glass forged by melting sand."
|
||||
color = "#88cdf1"
|
||||
alpha = 150
|
||||
categories = list(MAT_CATEGORY_RIGID = TRUE)
|
||||
integrity_modifier = 0.1
|
||||
sheet_type = /obj/item/stack/sheet/glass
|
||||
value_per_unit = 0.0025
|
||||
armor_modifiers = list("melee" = 0.2, "bullet" = 0.2, "laser" = 0, "energy" = 1, "bomb" = 0, "bio" = 0.2, "rad" = 0.2, "fire" = 1, "acid" = 0.2) // yeah ok retard
|
||||
|
||||
/*
|
||||
Color matrices are like regular colors but unlike with normal colors, you can go over 255 on a channel.
|
||||
Unless you know what you're doing, only use the first three numbers. They're in RGB order.
|
||||
*/
|
||||
|
||||
///Has no special properties. Could be good against vampires in the future perhaps.
|
||||
/datum/material/silver
|
||||
name = "silver"
|
||||
id = "silver"
|
||||
desc = "Silver"
|
||||
color = list(255/255, 284/255, 302/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0)
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/silver
|
||||
value_per_unit = 0.025
|
||||
|
||||
///Slight force increase
|
||||
/datum/material/gold
|
||||
name = "gold"
|
||||
id = "gold"
|
||||
desc = "Gold"
|
||||
color = list(340/255, 240/255, 50/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) //gold is shiny, but not as bright as bananium
|
||||
strength_modifier = 1.2
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/gold
|
||||
value_per_unit = 0.0625
|
||||
armor_modifiers = list("melee" = 1.1, "bullet" = 1.1, "laser" = 1.15, "energy" = 1.15, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 0.7, "acid" = 1.1)
|
||||
|
||||
///Has no special properties
|
||||
/datum/material/diamond
|
||||
name = "diamond"
|
||||
id = "diamond"
|
||||
desc = "Highly pressurized carbon"
|
||||
color = list(48/255, 272/255, 301/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0)
|
||||
alpha = 132
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/diamond
|
||||
value_per_unit = 0.25
|
||||
|
||||
///Is slightly radioactive
|
||||
/datum/material/uranium
|
||||
name = "uranium"
|
||||
id = "uranium"
|
||||
desc = "Uranium"
|
||||
color = rgb(48, 237, 26)
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/uranium
|
||||
value_per_unit = 0.05
|
||||
armor_modifiers = list("melee" = 1.5, "bullet" = 1.4, "laser" = 0.5, "energy" = 0.5, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 1, "acid" = 1)
|
||||
|
||||
/datum/material/uranium/on_applied(atom/source, amount, material_flags)
|
||||
. = ..()
|
||||
source.AddComponent(/datum/component/radioactive, amount / 20, source, 0) //half-life of 0 because we keep on going.
|
||||
|
||||
/datum/material/uranium/on_removed(atom/source, material_flags)
|
||||
. = ..()
|
||||
qdel(source.GetComponent(/datum/component/radioactive))
|
||||
|
||||
|
||||
///Adds firestacks on hit (Still needs support to turn into gas on destruction)
|
||||
/datum/material/plasma
|
||||
name = "plasma"
|
||||
id = "plasma"
|
||||
desc = "Isn't plasma a state of matter? Oh whatever."
|
||||
color = list(298/255, 46/255, 352/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0)
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/plasma
|
||||
value_per_unit = 0.1
|
||||
armor_modifiers = list("melee" = 1.4, "bullet" = 0.7, "laser" = 0, "energy" = 1.2, "bomb" = 0, "bio" = 1.2, "rad" = 1, "fire" = 0, "acid" = 0.5)
|
||||
|
||||
/datum/material/plasma/on_applied(atom/source, amount, material_flags)
|
||||
. = ..()
|
||||
if(ismovableatom(source))
|
||||
source.AddElement(/datum/element/firestacker)
|
||||
source.AddComponent(/datum/component/explodable, 0, 0, amount / 2500, amount / 1250)
|
||||
|
||||
/datum/material/plasma/on_removed(atom/source, material_flags)
|
||||
. = ..()
|
||||
source.RemoveElement(/datum/element/firestacker)
|
||||
qdel(source.GetComponent(/datum/component/explodable))
|
||||
|
||||
///Can cause bluespace effects on use. (Teleportation) (Not yet implemented)
|
||||
/datum/material/bluespace
|
||||
name = "bluespace crystal"
|
||||
id = "bluespace_crystal"
|
||||
desc = "Crystals with bluespace properties"
|
||||
color = list(119/255, 217/255, 396/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0)
|
||||
alpha = 200
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/bluespace_crystal
|
||||
value_per_unit = 0.15
|
||||
|
||||
///Honks and slips
|
||||
/datum/material/bananium
|
||||
name = "bananium"
|
||||
id = "bananium"
|
||||
desc = "Material with hilarious properties"
|
||||
color = list(460/255, 464/255, 0, 0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) //obnoxiously bright yellow
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/bananium
|
||||
value_per_unit = 0.5
|
||||
armor_modifiers = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 10, "acid" = 0) //Clowns cant be blown away
|
||||
|
||||
/datum/material/bananium/on_applied(atom/source, amount, material_flags)
|
||||
. = ..()
|
||||
source.AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50)
|
||||
source.AddComponent(/datum/component/slippery, min(amount / 10, 80))
|
||||
|
||||
/datum/material/bananium/on_removed(atom/source, amount, material_flags)
|
||||
. = ..()
|
||||
qdel(source.GetComponent(/datum/component/slippery))
|
||||
qdel(source.GetComponent(/datum/component/squeak))
|
||||
|
||||
|
||||
///Mediocre force increase
|
||||
/datum/material/titanium
|
||||
name = "titanium"
|
||||
id = "titanium"
|
||||
desc = "Titanium"
|
||||
color = "#b3c0c7"
|
||||
strength_modifier = 1.3
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/titanium
|
||||
value_per_unit = 0.0625
|
||||
armor_modifiers = list("melee" = 1.35, "bullet" = 1.3, "laser" = 1.3, "energy" = 1.25, "bomb" = 1.25, "bio" = 1, "rad" = 1, "fire" = 0.7, "acid" = 1)
|
||||
|
||||
/datum/material/runite
|
||||
name = "runite"
|
||||
id = "runite"
|
||||
desc = "Runite"
|
||||
color = "#3F9995"
|
||||
strength_modifier = 1.3
|
||||
categories = list(MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/runite
|
||||
armor_modifiers = list("melee" = 1.35, "bullet" = 2, "laser" = 0.5, "energy" = 1.25, "bomb" = 1.25, "bio" = 1, "rad" = 1, "fire" = 1.4, "acid" = 1) //rune is weak against magic lasers but strong against bullets. This is the combat triangle.
|
||||
|
||||
///Force decrease
|
||||
/datum/material/plastic
|
||||
name = "plastic"
|
||||
id = "plastic"
|
||||
desc = "Plastic"
|
||||
color = "#caccd9"
|
||||
strength_modifier = 0.85
|
||||
sheet_type = /obj/item/stack/sheet/plastic
|
||||
value_per_unit = 0.0125
|
||||
armor_modifiers = list("melee" = 1.5, "bullet" = 1.1, "laser" = 0.3, "energy" = 0.5, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 1.1, "acid" = 1)
|
||||
|
||||
///Force decrease and mushy sound effect. (Not yet implemented)
|
||||
/datum/material/biomass
|
||||
name = "biomass"
|
||||
id = "biomass"
|
||||
desc = "Organic matter"
|
||||
color = "#735b4d"
|
||||
strength_modifier = 0.8
|
||||
value_per_unit = 0.025
|
||||
|
||||
///Stronk force increase
|
||||
/datum/material/adamantine
|
||||
name = "adamantine"
|
||||
id = "adamantine"
|
||||
desc = "A powerful material made out of magic, I mean science!"
|
||||
color = "#6d7e8e"
|
||||
strength_modifier = 1.5
|
||||
categories = list(MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/adamantine
|
||||
value_per_unit = 0.25
|
||||
armor_modifiers = list("melee" = 1.5, "bullet" = 1.5, "laser" = 1.3, "energy" = 1.3, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 2.5, "acid" = 1)
|
||||
|
||||
///RPG Magic. (Admin only)
|
||||
/datum/material/mythril
|
||||
name = "mythril"
|
||||
id = "mythril"
|
||||
desc = "How this even exists is byond me"
|
||||
color = "#f2d5d7"
|
||||
categories = list(MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/mythril
|
||||
value_per_unit = 0.75
|
||||
armor_modifiers = list("melee" = 2, "bullet" = 2, "laser" = 2, "energy" = 2, "bomb" = 2, "bio" = 2, "rad" = 2, "fire" = 2, "acid" = 2)
|
||||
|
||||
/datum/material/mythril/on_applied_obj(atom/source, amount, material_flags)
|
||||
. = ..()
|
||||
if(istype(source, /obj/item))
|
||||
source.AddComponent(/datum/component/fantasy)
|
||||
|
||||
/datum/material/mythril/on_removed_obj(atom/source, material_flags)
|
||||
. = ..()
|
||||
if(istype(source, /obj/item))
|
||||
qdel(source.GetComponent(/datum/component/fantasy))
|
||||
@@ -224,6 +224,13 @@
|
||||
allow_duplicates = FALSE
|
||||
cost = 5
|
||||
|
||||
/datum/map_template/ruin/lavaland/dark_wizards
|
||||
name = "Dark Wizard Altar"
|
||||
id = "dark_wizards"
|
||||
description = "A ruin with dark wizards. What secret do they guard?"
|
||||
suffix = "lavaland_surface_wizard.dmm"
|
||||
cost = 5
|
||||
|
||||
/datum/map_template/ruin/lavaland/puzzle
|
||||
name = "Ancient Puzzle"
|
||||
id = "puzzle"
|
||||
|
||||
@@ -311,6 +311,12 @@
|
||||
name = "Space Hermit"
|
||||
description = "A late awakening cryo pod in a crashed escape pod wakes up to find what befell of his fellow survivors. Contains all the necessary resources to actually make it out alive. Good luck."
|
||||
|
||||
/datum/map_template/ruin/space/clericden
|
||||
id = "clericden"
|
||||
suffix = "clericden.dmm"
|
||||
name = "Cleric's Den"
|
||||
description = "Once part of a larger monastery, this holy order of long dead clerics practiced far less non-violence than they preached. Appears to have been untouched by looters, however. Odd."
|
||||
|
||||
/datum/map_template/ruin/space/advancedlab
|
||||
id = "advancedlab"
|
||||
suffix = "advancedlab.dmm"
|
||||
|
||||
Reference in New Issue
Block a user