a394ccdc2b
removes materials list from items, uses custom_materials instead. This might introduce some bugs so we should testmerge this for a while (and Ill test stuff locally as much as I can) this also adds material crafting to sheets. Test case being chairs. In the future we can add stuff like tables, walls, doors etc. also applies materials to everything, with fixes, which can close #46299
281 lines
7.9 KiB
Plaintext
281 lines
7.9 KiB
Plaintext
/obj/item/tank
|
|
name = "tank"
|
|
icon = 'icons/obj/tank.dmi'
|
|
lefthand_file = 'icons/mob/inhands/equipment/tanks_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/equipment/tanks_righthand.dmi'
|
|
flags_1 = CONDUCT_1
|
|
slot_flags = ITEM_SLOT_BACK
|
|
hitsound = 'sound/weapons/smash.ogg'
|
|
pressure_resistance = ONE_ATMOSPHERE * 5
|
|
force = 5
|
|
throwforce = 10
|
|
throw_speed = 1
|
|
throw_range = 4
|
|
custom_materials = list(/datum/material/iron = 500)
|
|
actions_types = list(/datum/action/item_action/set_internals)
|
|
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 30)
|
|
var/datum/gas_mixture/air_contents = null
|
|
var/distribute_pressure = ONE_ATMOSPHERE
|
|
var/integrity = 3
|
|
var/volume = 70
|
|
|
|
/obj/item/tank/ui_action_click(mob/user)
|
|
toggle_internals(user)
|
|
|
|
/obj/item/tank/proc/toggle_internals(mob/user)
|
|
var/mob/living/carbon/human/H = user
|
|
if(!istype(H))
|
|
return
|
|
|
|
if(H.internal == src)
|
|
to_chat(H, "<span class='notice'>You close [src] valve.</span>")
|
|
H.internal = null
|
|
H.update_internals_hud_icon(0)
|
|
else
|
|
if(!H.getorganslot(ORGAN_SLOT_BREATHING_TUBE))
|
|
if(!H.wear_mask)
|
|
to_chat(H, "<span class='warning'>You need a mask!</span>")
|
|
return
|
|
if(H.wear_mask.mask_adjusted)
|
|
H.wear_mask.adjustmask(H)
|
|
if(!(H.wear_mask.clothing_flags & MASKINTERNALS))
|
|
to_chat(H, "<span class='warning'>[H.wear_mask] can't use [src]!</span>")
|
|
return
|
|
|
|
if(H.internal)
|
|
to_chat(H, "<span class='notice'>You switch your internals to [src].</span>")
|
|
else
|
|
to_chat(H, "<span class='notice'>You open [src] valve.</span>")
|
|
H.internal = src
|
|
H.update_internals_hud_icon(1)
|
|
H.update_action_buttons_icon()
|
|
|
|
|
|
/obj/item/tank/Initialize()
|
|
. = ..()
|
|
|
|
air_contents = new(volume) //liters
|
|
air_contents.temperature = T20C
|
|
|
|
populate_gas()
|
|
|
|
START_PROCESSING(SSobj, src)
|
|
|
|
/obj/item/tank/proc/populate_gas()
|
|
return
|
|
|
|
/obj/item/tank/Destroy()
|
|
if(air_contents)
|
|
qdel(air_contents)
|
|
|
|
STOP_PROCESSING(SSobj, src)
|
|
. = ..()
|
|
|
|
/obj/item/tank/examine(mob/user)
|
|
var/obj/icon = src
|
|
. = ..()
|
|
if(istype(src.loc, /obj/item/assembly))
|
|
icon = src.loc
|
|
if(!in_range(src, user) && !isobserver(user))
|
|
if(icon == src)
|
|
. += "<span class='notice'>If you want any more information you'll need to get closer.</span>"
|
|
return
|
|
|
|
. += "<span class='notice'>The pressure gauge reads [round(src.air_contents.return_pressure(),0.01)] kPa.</span>"
|
|
|
|
var/celsius_temperature = src.air_contents.temperature-T0C
|
|
var/descriptive
|
|
|
|
if (celsius_temperature < 20)
|
|
descriptive = "cold"
|
|
else if (celsius_temperature < 40)
|
|
descriptive = "room temperature"
|
|
else if (celsius_temperature < 80)
|
|
descriptive = "lukewarm"
|
|
else if (celsius_temperature < 100)
|
|
descriptive = "warm"
|
|
else if (celsius_temperature < 300)
|
|
descriptive = "hot"
|
|
else
|
|
descriptive = "furiously hot"
|
|
|
|
. += "<span class='notice'>It feels [descriptive].</span>"
|
|
|
|
/obj/item/tank/blob_act(obj/structure/blob/B)
|
|
if(B && B.loc == loc)
|
|
var/turf/location = get_turf(src)
|
|
if(!location)
|
|
qdel(src)
|
|
|
|
if(air_contents)
|
|
location.assume_air(air_contents)
|
|
|
|
qdel(src)
|
|
|
|
/obj/item/tank/deconstruct(disassembled = TRUE)
|
|
if(!disassembled)
|
|
var/turf/T = get_turf(src)
|
|
if(T)
|
|
T.assume_air(air_contents)
|
|
air_update_turf()
|
|
playsound(src.loc, 'sound/effects/spray.ogg', 10, TRUE, -3)
|
|
qdel(src)
|
|
|
|
/obj/item/tank/suicide_act(mob/user)
|
|
var/mob/living/carbon/human/H = user
|
|
user.visible_message("<span class='suicide'>[user] is putting [src]'s valve to [user.p_their()] lips! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
|
playsound(loc, 'sound/effects/spray.ogg', 10, TRUE, -3)
|
|
if (!QDELETED(H) && air_contents && air_contents.return_pressure() >= 1000)
|
|
for(var/obj/item/W in H)
|
|
H.dropItemToGround(W)
|
|
if(prob(50))
|
|
step(W, pick(GLOB.alldirs))
|
|
ADD_TRAIT(H, TRAIT_DISFIGURED, TRAIT_GENERIC)
|
|
H.bleed_rate = 5
|
|
H.gib_animation()
|
|
sleep(3)
|
|
H.adjustBruteLoss(1000) //to make the body super-bloody
|
|
H.spawn_gibs()
|
|
H.spill_organs()
|
|
H.spread_bodyparts()
|
|
|
|
return (BRUTELOSS)
|
|
|
|
/obj/item/tank/attackby(obj/item/W, mob/user, params)
|
|
add_fingerprint(user)
|
|
if(istype(W, /obj/item/assembly_holder))
|
|
bomb_assemble(W,user)
|
|
else
|
|
. = ..()
|
|
|
|
/obj/item/tank/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
|
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
|
|
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
|
if(!ui)
|
|
ui = new(user, src, ui_key, "tanks", name, 420, 200, master_ui, state)
|
|
ui.open()
|
|
|
|
/obj/item/tank/ui_data(mob/user)
|
|
var/list/data = list()
|
|
data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
|
|
data["releasePressure"] = round(distribute_pressure ? distribute_pressure : 0)
|
|
data["defaultReleasePressure"] = round(TANK_DEFAULT_RELEASE_PRESSURE)
|
|
data["minReleasePressure"] = round(TANK_MIN_RELEASE_PRESSURE)
|
|
data["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE)
|
|
|
|
var/mob/living/carbon/C = user
|
|
if(!istype(C))
|
|
C = loc.loc
|
|
if(!istype(C))
|
|
return data
|
|
|
|
if(C.internal == src)
|
|
data["connected"] = TRUE
|
|
|
|
return data
|
|
|
|
/obj/item/tank/ui_act(action, params)
|
|
if(..())
|
|
return
|
|
switch(action)
|
|
if("pressure")
|
|
var/pressure = params["pressure"]
|
|
if(pressure == "reset")
|
|
pressure = initial(distribute_pressure)
|
|
. = TRUE
|
|
else if(pressure == "min")
|
|
pressure = TANK_MIN_RELEASE_PRESSURE
|
|
. = TRUE
|
|
else if(pressure == "max")
|
|
pressure = TANK_MAX_RELEASE_PRESSURE
|
|
. = TRUE
|
|
else if(pressure == "input")
|
|
pressure = input("New release pressure ([TANK_MIN_RELEASE_PRESSURE]-[TANK_MAX_RELEASE_PRESSURE] kPa):", name, distribute_pressure) as num|null
|
|
if(!isnull(pressure) && !..())
|
|
. = TRUE
|
|
else if(text2num(pressure) != null)
|
|
pressure = text2num(pressure)
|
|
. = TRUE
|
|
if(.)
|
|
distribute_pressure = CLAMP(round(pressure), TANK_MIN_RELEASE_PRESSURE, TANK_MAX_RELEASE_PRESSURE)
|
|
|
|
/obj/item/tank/remove_air(amount)
|
|
return air_contents.remove(amount)
|
|
|
|
/obj/item/tank/return_air()
|
|
return air_contents
|
|
|
|
/obj/item/tank/return_analyzable_air()
|
|
return air_contents
|
|
|
|
/obj/item/tank/assume_air(datum/gas_mixture/giver)
|
|
air_contents.merge(giver)
|
|
|
|
check_status()
|
|
return 1
|
|
|
|
/obj/item/tank/proc/remove_air_volume(volume_to_return)
|
|
if(!air_contents)
|
|
return null
|
|
|
|
var/tank_pressure = air_contents.return_pressure()
|
|
var/actual_distribute_pressure = CLAMP(tank_pressure, 0, distribute_pressure)
|
|
|
|
var/moles_needed = actual_distribute_pressure*volume_to_return/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
|
|
|
|
return remove_air(moles_needed)
|
|
|
|
/obj/item/tank/process()
|
|
//Allow for reactions
|
|
air_contents.react()
|
|
check_status()
|
|
|
|
/obj/item/tank/proc/check_status()
|
|
//Handle exploding, leaking, and rupturing of the tank
|
|
|
|
if(!air_contents)
|
|
return 0
|
|
|
|
var/pressure = air_contents.return_pressure()
|
|
var/temperature = air_contents.return_temperature()
|
|
|
|
if(pressure > TANK_FRAGMENT_PRESSURE)
|
|
if(!istype(src.loc, /obj/item/transfer_valve))
|
|
log_bomber(get_mob_by_key(fingerprintslast), "was last key to touch", src, "which ruptured explosively")
|
|
//Give the gas a chance to build up more pressure through reacting
|
|
air_contents.react(src)
|
|
pressure = air_contents.return_pressure()
|
|
var/range = (pressure-TANK_FRAGMENT_PRESSURE)/TANK_FRAGMENT_SCALE
|
|
var/turf/epicenter = get_turf(loc)
|
|
|
|
|
|
explosion(epicenter, round(range*0.25), round(range*0.5), round(range), round(range*1.5))
|
|
if(istype(src.loc, /obj/item/transfer_valve))
|
|
qdel(src.loc)
|
|
else
|
|
qdel(src)
|
|
|
|
else if(pressure > TANK_RUPTURE_PRESSURE || temperature > TANK_MELT_TEMPERATURE)
|
|
if(integrity <= 0)
|
|
var/turf/T = get_turf(src)
|
|
if(!T)
|
|
return
|
|
T.assume_air(air_contents)
|
|
playsound(src.loc, 'sound/effects/spray.ogg', 10, TRUE, -3)
|
|
qdel(src)
|
|
else
|
|
integrity--
|
|
|
|
else if(pressure > TANK_LEAK_PRESSURE)
|
|
if(integrity <= 0)
|
|
var/turf/T = get_turf(src)
|
|
if(!T)
|
|
return
|
|
var/datum/gas_mixture/leaked_gas = air_contents.remove_ratio(0.25)
|
|
T.assume_air(leaked_gas)
|
|
else
|
|
integrity--
|
|
|
|
else if(integrity < 3)
|
|
integrity++
|