Merge pull request #4383 from IK3I/Pod-Refactor

[Ready for Review] Pod refactor and fixes
This commit is contained in:
TheDZD
2016-05-31 20:48:05 -04:00
17 changed files with 522 additions and 373 deletions
@@ -118,8 +118,8 @@
return 1
if(istype(the_target, /obj/spacepod))
var/obj/spacepod/S = the_target
if(S.occupant || S.occupant2)//Just so we don't attack empty mechs
if(CanAttack(S.occupant) || CanAttack(S.occupant2))
if(S.pilot) //Just so we don't attack empty pods
if(CanAttack(S.pilot))
return 1
if(isliving(the_target))
var/mob/living/L = the_target
@@ -14,7 +14,7 @@
return A
else if(istype(A, /obj/spacepod))
var/obj/spacepod/M = A
if(M.occupant || M.occupant2)
if(M.pilot)
return A
/mob/living/simple_animal/hostile/retaliate/ListTargets()
@@ -47,9 +47,9 @@
enemies |= M.occupant
else if(istype(A, /obj/spacepod))
var/obj/spacepod/M = A
if(M.occupant || M.occupant2)
if(M.pilot)
enemies |= M
enemies |= M.occupant
enemies |= M.pilot
for(var/mob/living/simple_animal/hostile/retaliate/H in around)
var/retaliate_faction_check = 0
@@ -536,7 +536,7 @@
return 0
if (istype(the_target,/obj/spacepod))
var/obj/spacepod/S = the_target
if (S.occupant || S.occupant2)
if (S.pilot)
return 0
return 1
@@ -12,6 +12,7 @@
//////////////////////////////////////////////////
/////////SPACEPOD PARTS///////////////////////////
//////////////////////////////////////////////////
/datum/design/podframe_fp
construction_time = 200
name = "Fore port pod frame"
@@ -89,6 +90,7 @@
//////////////////////////////////////////
//////SPACEPOD GUNS///////////////////////
//////////////////////////////////////////
/datum/design/pod_gun_taser
construction_time = 200
name = "Spacepod Equipment (Taser)"
@@ -157,6 +159,7 @@
materials = list(MAT_METAL = 10000, MAT_GLASS = 5000, MAT_SILVER = 4000, MAT_GOLD = 4000, MAT_DIAMOND = 4000)
build_path = /obj/item/device/spacepod_equipment/weaponry/mining_laser_hyper
category = list("Pod_Weaponry")
//////////////////////////////////////////
//////SPACEPOD MISC. ITEMS////////////////
//////////////////////////////////////////
@@ -172,16 +175,57 @@
build_path = /obj/item/device/spacepod_equipment/misc/tracker
category = list("Pod_Parts")
//////////////////////////////////////////
//////SPACEPOD CARGO ITEMS////////////////
//////////////////////////////////////////
/datum/design/pod_cargo_ore
construction_time = 100
name = "Spacepod Ore Storage Module"
desc = "Allows for the construction of a Space Pod Ore Storage Module."
id = "podcargo_ore"
req_tech = list("materials" = 3)
req_tech = list("materials" = 3, "engineering" = 2)
build_type = PODFAB
materials = list(MAT_METAL=20000, MAT_GLASS=2000)
build_path = /obj/item/device/spacepod_equipment/cargo/ore
category = list("Pod_Parts")
category = list("Pod_Cargo")
/datum/design/pod_cargo_crate
construction_time = 100
name = "Spacepod Crate Storage Module"
desc = "Allows the construction of a Space Pod Crate Storage Module."
id = "podcargo_crate"
req_tech = list("materials" = 4, "engineering" = 2) //hollowing out this much of the pod without compromising structural integrity is hard
build_type = PODFAB
materials = list(MAT_METAL=25000)
build_path = /obj/item/device/spacepod_equipment/cargo/crate
category = list("Pod_Cargo")
//////////////////////////////////////////
//////SPACEPOD SEC CARGO ITEMS////////////
//////////////////////////////////////////
/datum/design/passenger_seat
construction_time = 100
name = "Spacepod Passenger Seat"
desc = "Allows the construction of a Space Pod Passenger Seat Module."
id = "podcargo_sec_seat"
req_tech = list("materials" = 1) // Because rule number one of refactoring
build_type = PODFAB
materials = list(MAT_METAL=7500, MAT_GLASS=2500)
build_path = /obj/item/device/spacepod_equipment/sec_cargo/chair
category = list("Pod_Cargo")
/datum/design/loot_box
construction_time = 100
name = "Spacepod Loot Storage Module"
desc = "Allows the construction of a Space Pod Auxillary Cargo Module."
id = "podcargo_sec_lootbox"
req_tech = list("materials" = 1) //it's just a set of shelves, It's not that hard to make
build_type = PODFAB
materials = list(MAT_METAL=7500, MAT_GLASS=2500)
build_path = /obj/item/device/spacepod_equipment/sec_cargo/loot_box
category = list("Pod_Cargo")
//////////////////////////////////////////
//////SPACEPOD LOCK ITEMS////////////////
+225
View File
@@ -0,0 +1,225 @@
/obj/structure/spacepod_frame
density = 1
opacity = 0
anchored = 1
layer = 3.9
icon = 'icons/goonstation/48x48/pod_construction.dmi'
icon_state = "pod_1"
var/datum/construction/construct
/obj/structure/spacepod_frame/New()
..()
bound_width = 64
bound_height = 64
construct = new /datum/construction/reversible2/pod(src)
dir = EAST
/obj/structure/spacepod_frame/attackby(obj/item/W as obj, mob/user as mob, params)
if(!construct || !construct.action(W, user))
..()
return
/obj/structure/spacepod_frame/attack_hand()
return
/////////////////////////////////
// CONSTRUCTION STEPS
/////////////////////////////////
/datum/construction/reversible2/pod
result = /obj/spacepod/civilian
base_icon="pod"
//taskpath = /datum/job_objective/make_pod
steps = list(
// 1. Initial state
list(
"desc" = "An empty pod frame.",
state_next = list(
"key" = /obj/item/stack/cable_coil,
"vis_msg" = "{USER} wires the {HOLDER}.",
"self_msg" = "You wire the {HOLDER}."
)
),
// 2. Crudely Wired
list(
"desc" = "A crudely-wired pod frame.",
state_prev = list(
"key" = /obj/item/weapon/wirecutters,
"vis_msg" = "{USER} cuts out the {HOLDER}'s wiring.",
"self_msg" = "You remove the {HOLDER}'s wiring."
),
state_next = list(
"key" = /obj/item/weapon/screwdriver,
"vis_msg" = "{USER} adjusts the wiring.",
"self_msg" = "You adjust the {HOLDER}'s wiring."
)
),
// 3. Cleanly wired
list(
"desc" = "A wired pod frame.",
state_prev = list(
"key" = /obj/item/weapon/screwdriver,
"vis_msg" = "{USER} unclips {HOLDER}'s wiring harnesses.",
"self_msg" = "You unclip {HOLDER}'s wiring harnesses."
),
state_next = list(
"key" = /obj/item/weapon/circuitboard/mecha/pod,
"vis_msg" = "{USER} inserts the mainboard into the {HOLDER}.",
"self_msg" = "You insert the mainboard into the {HOLDER}.",
"delete" = 1
)
),
// 4. Circuit added
list(
"desc" = "A wired pod frame with a loose mainboard.",
state_prev = list(
"key" = /obj/item/weapon/crowbar,
"vis_msg" = "{USER} pries out the mainboard.",
"self_msg" = "You pry out the mainboard.",
"spawn" = /obj/item/weapon/circuitboard/mecha/pod,
"amount" = 1
),
state_next = list(
"key" = /obj/item/weapon/screwdriver,
"vis_msg" = "{USER} secures the mainboard.",
"self_msg" = "You secure the mainboard."
)
),
// 5. Circuit secured
list(
"desc" = "A wired pod frame with a secured mainboard.",
state_prev = list(
"key" = /obj/item/weapon/screwdriver,
"vis_msg" = "{USER} unsecures the mainboard.",
"self_msg" = "You unscrew the mainboard from the {HOLDER}."
),
state_next = list(
"key" = /obj/item/pod_parts/core,
,
"vis_msg" = "{USER} inserts the core into the {HOLDER}.",
"self_msg" = "You carefully insert the core into the {HOLDER}.",
"delete" = 1
)
),
// 6. Core inserted
list(
"desc" = "A naked space pod with a loose core.",
state_prev = list(
"key" = /obj/item/weapon/crowbar,
"vis_msg" = "{USER} delicately removes the core from the {HOLDER} with a crowbar.",
"self_msg" = "You delicately remove the core from the {HOLDER} with a crowbar.",
"spawn" = /obj/item/pod_parts/core,
"amount" = 1
),
state_next = list(
"key" = /obj/item/weapon/wrench,
"vis_msg" = "{USER} secures the core's bolts.",
"self_msg" = "You secure the core's bolts."
)
),
// 7. Core secured
list(
"desc" = "A naked space pod with an exposed core. How lewd.",
state_prev = list(
"key" = /obj/item/weapon/wrench,
"vis_msg" = "{USER} unsecures the {HOLDER}'s core.",
"self_msg" = "You unsecure the {HOLDER}'s core."
),
state_next = list(
"key" = /obj/item/stack/sheet/metal,
"amount" = 5,
"vis_msg" = "{USER} frabricates a pressure bulkhead for the {HOLDER}.",
"self_msg" = "You frabricate a pressure bulkhead for the {HOLDER}."
)
),
// 8. Bulkhead added
list(
"desc" = "A space pod with loose bulkhead panelling exposed.",
state_prev = list(
"key" = /obj/item/weapon/crowbar,
"vis_msg" = "{USER} pops the {HOLDER}'s bulkhead panelling loose.",
"self_msg" = "You pop the {HOLDER}'s bulkhead panelling loose.",
"spawn" = /obj/item/stack/sheet/metal,
"amount" = 5,
),
state_next = list(
"key" = /obj/item/weapon/wrench,
"vis_msg" = "{USER} secures the {HOLDER}'s bulkhead panelling.",
"self_msg" = "You secure the {HOLDER}'s bulkhead panelling."
)
),
// 9. Bulkhead secured with bolts
list(
"desc" = "A space pod with unwelded bulkhead panelling exposed.",
state_prev = list(
"key" = /obj/item/weapon/wrench,
"vis_msg" = "{USER} unbolts the {HOLDER}'s bulkhead panelling.",
"self_msg" = "You unbolt the {HOLDER}'s bulkhead panelling."
),
state_next = list(
"key" = /obj/item/weapon/weldingtool,
"vis_msg" = "{USER} seals the {HOLDER}'s bulkhead panelling with a weld.",
"self_msg" = "You seal the {HOLDER}'s bulkhead panelling with a weld."
)
),
// 10. Welded bulkhead
list(
"desc" = "A space pod with sealed bulkhead panelling exposed.",
state_prev = list(
"key" = /obj/item/weapon/weldingtool,
"vis_msg" = "{USER} cuts the {HOLDER}'s bulkhead panelling loose.",
"self_msg" = "You cut the {HOLDER}'s bulkhead panelling loose."
),
state_next = list(
"key" = /obj/item/pod_parts/armor,
"vis_msg" = "{USER} installs the {HOLDER}'s armor plating.",
"self_msg" = "You install the {HOLDER}'s armor plating.",
"delete" = 1
)
),
// 11. Loose armor
list(
"desc" = "A space pod with unsecured armor.",
state_prev = list(
"key" = /obj/item/weapon/crowbar,
"vis_msg" = "{USER} pries off {HOLDER}'s armor.",
"self_msg" = "You pry off {HOLDER}'s armor.",
"spawn" = /obj/item/pod_parts/armor,
"amount" = 1
),
state_next = list(
"key" = /obj/item/weapon/wrench,
"vis_msg" = "{USER} bolts down the {HOLDER}'s armor.",
"self_msg" = "You bolt down the {HOLDER}'s armor."
)
),
// 12. Bolted-down armor
list(
"desc" = "A space pod with unsecured armor.",
state_prev = list(
"key" = /obj/item/weapon/wrench,
"vis_msg" = "{USER} unsecures the {HOLDER}'s armor.",
"self_msg" = "You unsecure the {HOLDER}'s armor."
),
state_next = list(
"key" = /obj/item/weapon/weldingtool,
"vis_msg" = "{USER} welds the {HOLDER}'s armor.",
"self_msg" = "You weld the {HOLDER}'s armor."
)
)
// EOF
)
spawn_result(mob/user as mob)
..()
feedback_inc("spacepod_created",1)
return
+286
View File
@@ -0,0 +1,286 @@
/obj/item/device/spacepod_equipment/weaponry/proc/fire_weapons()
if(my_atom.next_firetime > world.time)
to_chat(usr, "<span class='warning'>Your weapons are recharging.</span>")
return
var/turf/firstloc
var/turf/secondloc
if(!my_atom.equipment_system || !my_atom.equipment_system.weapon_system)
to_chat(usr, "<span class='warning'>Missing equipment or weapons.</span>")
my_atom.verbs -= text2path("[type]/proc/fire_weapons")
return
my_atom.battery.use(shot_cost)
var/olddir
for(var/i = 0; i < shots_per; i++)
if(olddir != my_atom.dir)
switch(my_atom.dir)
if(NORTH)
firstloc = get_step(my_atom, NORTH)
secondloc = get_step(firstloc,EAST)
if(SOUTH)
firstloc = get_turf(my_atom)
secondloc = get_step(firstloc,EAST)
if(EAST)
firstloc = get_step(my_atom, EAST)
secondloc = get_step(firstloc,NORTH)
if(WEST)
firstloc = get_turf(my_atom)
secondloc = get_step(firstloc,NORTH)
olddir = dir
var/proj_type = text2path(projectile_type)
var/obj/item/projectile/projone = new proj_type(firstloc)
var/obj/item/projectile/projtwo = new proj_type(secondloc)
projone.starting = get_turf(my_atom)
projone.shot_from = src
projone.firer = usr
projone.def_zone = "chest"
projtwo.starting = get_turf(my_atom)
projtwo.shot_from = src
projtwo.firer = usr
projtwo.def_zone = "chest"
spawn()
playsound(src, fire_sound, 50, 1)
projone.dumbfire(my_atom.dir)
projtwo.dumbfire(my_atom.dir)
sleep(2)
my_atom.next_firetime = world.time + fire_delay
/datum/spacepod/equipment
var/obj/spacepod/my_atom
var/list/obj/item/device/spacepod_equipment/installed_modules // holds an easy to access list of installed modules
var/obj/item/device/spacepod_equipment/weaponry/weapon_system // weapons system
var/obj/item/device/spacepod_equipment/misc/misc_system // misc system
var/obj/item/device/spacepod_equipment/cargo/cargo_system // cargo system
var/obj/item/device/spacepod_equipment/cargo/sec_cargo_system // secondary cargo system
var/obj/item/device/spacepod_equipment/lock/lock_system // lock system
/datum/spacepod/equipment/New(var/obj/spacepod/SP)
..()
if(istype(SP))
my_atom = SP
/obj/item/device/spacepod_equipment
name = "equipment"
var/obj/spacepod/my_atom
var/occupant_mod = 0 // so any module can modify occupancy
var/list/storage_mod = list("slots" = 0, "w_class" = 0) // so any module can modify storage slots
/obj/item/device/spacepod_equipment/proc/removed(var/mob/user) // So that you can unload cargo when you remove the module
return
/*
///////////////////////////////////////
/////////Weapon System///////////////////
///////////////////////////////////////
*/
/obj/item/device/spacepod_equipment/weaponry
name = "pod weapon"
desc = "You shouldn't be seeing this"
icon = 'icons/vehicles/spacepod.dmi'
icon_state = "blank"
var/projectile_type
var/shot_cost = 0
var/shots_per = 1
var/fire_sound
var/fire_delay = 15
/obj/item/device/spacepod_equipment/weaponry/taser
name = "disabler system"
desc = "A weak taser system for space pods, fires disabler beams."
icon_state = "weapon_taser"
projectile_type = "/obj/item/projectile/beam/disabler"
shot_cost = 400
fire_sound = "sound/weapons/Taser.ogg"
/obj/item/device/spacepod_equipment/weaponry/burst_taser
name = "burst taser system"
desc = "A weak taser system for space pods, this one fires 3 at a time."
icon_state = "weapon_burst_taser"
projectile_type = "/obj/item/projectile/beam/disabler"
shot_cost = 1200
shots_per = 3
fire_sound = "sound/weapons/Taser.ogg"
fire_delay = 30
/obj/item/device/spacepod_equipment/weaponry/laser
name = "laser system"
desc = "A weak laser system for space pods, fires concentrated bursts of energy"
icon_state = "weapon_laser"
projectile_type = "/obj/item/projectile/beam"
shot_cost = 600
fire_sound = 'sound/weapons/Laser.ogg'
// MINING LASERS
/obj/item/device/spacepod_equipment/weaponry/mining_laser_basic
name = "weak mining laser system"
desc = "A weak mining laser system for space pods, fires bursts of energy that cut through rock"
icon = 'icons/goonstation/pods/ship.dmi'
icon_state = "pod_taser"
projectile_type = "/obj/item/projectile/kinetic"
shot_cost = 300
fire_delay = 14
fire_sound = 'sound/weapons/Kenetic_accel.ogg'
/obj/item/device/spacepod_equipment/weaponry/mining_laser
name = "mining laser system"
desc = "A mining laser system for space pods, fires bursts of energy that cut through rock"
icon = 'icons/goonstation/pods/ship.dmi'
icon_state = "pod_m_laser"
projectile_type = "/obj/item/projectile/kinetic/super"
shot_cost = 250
fire_delay = 10
fire_sound = 'sound/weapons/Kenetic_accel.ogg'
/obj/item/device/spacepod_equipment/weaponry/mining_laser_hyper
name = "enhanced mining laser system"
desc = "An enhanced mining laser system for space pods, fires bursts of energy that cut through rock"
icon = 'icons/goonstation/pods/ship.dmi'
icon_state = "pod_w_laser"
projectile_type = "/obj/item/projectile/kinetic/hyper"
shot_cost = 200
fire_delay = 8
fire_sound = 'sound/weapons/Kenetic_accel.ogg'
/*
///////////////////////////////////////
/////////Misc. System///////////////////
///////////////////////////////////////
*/
/obj/item/device/spacepod_equipment/misc
name = "pod misc"
desc = "You shouldn't be seeing this"
icon = 'icons/goonstation/pods/ship.dmi'
icon_state = "blank"
var/enabled
/obj/item/device/spacepod_equipment/misc/tracker
name = "\improper spacepod tracking system"
desc = "A tracking device for spacepods."
icon_state = "pod_locator"
enabled = 0
/obj/item/device/spacepod_equipment/misc/tracker/attackby(obj/item/I as obj, mob/user as mob, params)
if(isscrewdriver(I))
if(enabled)
enabled = 0
user.show_message("<span class='notice'>You disable \the [src]'s power.")
return
enabled = 1
user.show_message("<span class='notice'>You enable \the [src]'s power.</span>")
else
..()
/*
///////////////////////////////////////
/////////Cargo System//////////////////
///////////////////////////////////////
*/
/obj/item/device/spacepod_equipment/cargo
name = "pod cargo"
desc = "You shouldn't be seeing this"
icon = 'icons/vehicles/spacepod.dmi'
icon_state = "cargo_blank"
var/obj/storage = null
/obj/item/device/spacepod_equipment/cargo/proc/passover(var/obj/item/I)
return
/obj/item/device/spacepod_equipment/cargo/proc/unload() // called by unload verb
if(storage)
storage.forceMove(get_turf(my_atom))
storage = null
/obj/item/device/spacepod_equipment/cargo/removed(var/mob/user) // called when system removed
. = ..()
unload()
// Ore System
/obj/item/device/spacepod_equipment/cargo/ore
name = "spacepod ore storage system"
desc = "An ore storage system for spacepods. Scoops up any ore you drive over."
icon_state = "cargo_ore"
/obj/item/device/spacepod_equipment/cargo/ore/passover(var/obj/item/I)
if(storage && istype(I,/obj/item/weapon/ore))
I.forceMove(storage)
// Crate System
/obj/item/device/spacepod_equipment/cargo/crate
name = "spacepod crate storage system"
desc = "A heavy duty storage system for spacepods. Holds one crate."
icon_state = "cargo_crate"
/*
///////////////////////////////////////
/////////Secondary Cargo System////////
///////////////////////////////////////
*/
/obj/item/device/spacepod_equipment/sec_cargo
name = "secondary cargo"
desc = "you shouldn't be seeing this"
icon = 'icons/vehicles/spacepod.dmi'
icon_state = "blank"
// Passenger Seat
/obj/item/device/spacepod_equipment/sec_cargo/chair
name = "passanger seat"
desc = "A passenger seat for a spacepod"
icon_state = "sec_cargo_chair"
occupant_mod = 1
// Loot Box
/obj/item/device/spacepod_equipment/sec_cargo/loot_box
name = "loot box"
desc = "A small compartment to store valuables"
icon_state = "sec_cargo_loot"
storage_mod = list("slots" = 7, "w_class" = 14)
/*
///////////////////////////////////////
/////////Lock System///////////////////
///////////////////////////////////////
*/
/obj/item/device/spacepod_equipment/lock
name = "pod lock"
desc = "You shouldn't be seeing this"
icon = 'icons/vehicles/spacepod.dmi'
icon_state = "blank"
var/mode = 0
var/id = null
// Key and Tumbler System
/obj/item/device/spacepod_equipment/lock/keyed
name = "spacepod tumbler lock"
desc = "A locking system to stop podjacking. This version uses a standalone key."
icon_state = "lock_tumbler"
var/static/id_source = 0
/obj/item/device/spacepod_equipment/lock/keyed/New()
..()
id = ++id_source
// The key
/obj/item/device/spacepod_key
name = "spacepod key"
desc = "A key for a spacepod lock."
icon = 'icons/vehicles/spacepod.dmi'
icon_state = "podkey"
w_class = 1.0
var/id = 0
// Key - Lock Interactions
/obj/item/device/spacepod_equipment/lock/keyed/attackby(obj/item/I as obj, mob/user as mob, params)
if(istype(I, /obj/item/device/spacepod_key))
var/obj/item/device/spacepod_key/key = I
if(!key.id)
key.id = id
to_chat(user, "<span class='notice'>You grind the blank key to fit the lock.</span>")
else
to_chat(user, "<span class='warning'>This key is already ground!</span>")
else
..()
+13
View File
@@ -0,0 +1,13 @@
/obj/item/device/lock_buster
name = "pod lock buster"
desc = "Destroys a podlock in mere seconds once applied. Waranty void if used."
icon_state = "lock_buster_off"
var/on = 0
/obj/item/device/lock_buster/attack_self(mob/user as mob)
on = !on
if(on)
icon_state = "lock_buster_on"
else
icon_state = "lock_buster_off"
to_chat(usr, "<span class='notice'>You turn the [src] [on ? "on" : "off"].</span>")
+125
View File
@@ -0,0 +1,125 @@
/obj/item/pod_parts
parent_type = /obj/item/mecha_parts
icon = 'icons/goonstation/pods/pod_parts.dmi'
/obj/item/pod_parts/core
name="Space Pod Core"
icon_state = "core"
flags = CONDUCT
origin_tech = "programming=2;materials=3;bluespace=2;engineering=3"
/obj/item/pod_parts/pod_frame
name = "Space Pod Frame"
icon_state = ""
flags = CONDUCT
density = 0
anchored = 0
var/link_to = null
var/link_angle = 0
/obj/item/pod_parts/pod_frame/proc/find_square()
/*
each part, in essence, stores the relative position of another part
you can find where this part should be by looking at the current direction of the current part and applying the link_angle
the link_angle is the angle between the part's direction and its following part, which is the current part's link_to
the code works by going in a loop - each part is capable of starting a loop by checking for the part after it, and that part checking, and so on
this 4-part loop, starting from any part of the frame, can determine if all the parts are properly in place and aligned
it also checks that each part is unique, and that all the parts are there for the spacepod itself
*/
var/neededparts = list(/obj/item/pod_parts/pod_frame/aft_port, /obj/item/pod_parts/pod_frame/aft_starboard, /obj/item/pod_parts/pod_frame/fore_port, /obj/item/pod_parts/pod_frame/fore_starboard)
var/turf/T
var/obj/item/pod_parts/pod_frame/linked
var/obj/item/pod_parts/pod_frame/pointer
var/connectedparts = list()
neededparts -= src
//log_admin("Starting with [src]")
linked = src
for(var/i = 1; i <= 4; i++)
T = get_turf(get_step(linked, turn(linked.dir, -linked.link_angle))) //get the next place that we want to look at
if(locate(linked.link_to) in T)
pointer = locate(linked.link_to) in T
//log_admin("Looking at [pointer.type]")
if(istype(pointer, linked.link_to) && pointer.dir == linked.dir && pointer.anchored)
if(!(pointer in connectedparts))
connectedparts += pointer
linked = pointer
pointer = null
//log_admin("Parts left: [neededparts.len]") //len not working
for(var/i = 1; i <=4; i++)
var/obj/item/pod_parts/pod_frame/F = connectedparts[i]
if(F.type in neededparts) //if one of the items can be founded in neededparts
neededparts -= F.type
log_admin("Found [F.type]")
else //because neededparts has 4 distinct items, this must be called if theyre not all in place and wrenched
return 0
return connectedparts
/obj/item/pod_parts/pod_frame/attackby(var/obj/O, mob/user)
if(istype(O, /obj/item/stack/rods))
var/obj/item/stack/rods/R = O
var/list/linkedparts = find_square()
if(!linkedparts)
to_chat(user, "<span class='rose'>You cannot assemble a pod frame because you do not have the necessary assembly.</span>")
return
var/obj/structure/spacepod_frame/pod = new /obj/structure/spacepod_frame(src.loc)
pod.dir = src.dir
to_chat(user, "<span class='notice'>You strut the pod frame together.</span>")
R.use(10)
for(var/obj/item/pod_parts/pod_frame/F in linkedparts)
if(1 == turn(F.dir, -F.link_angle)) //if the part links north during construction, as the bottom left part always does
//log_admin("Repositioning")
pod.loc = F.loc
qdel(F)
playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
if(istype(O, /obj/item/weapon/wrench))
to_chat(user, "<span class='notice'>You [!anchored ? "secure \the [src] in place." : "remove the securing bolts."]</span>")
anchored = !anchored
density = anchored
playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
/obj/item/pod_parts/pod_frame/verb/rotate()
set name = "Rotate Frame"
set category = "Object"
set src in oview(1)
if(anchored)
to_chat(usr, "\The [src] is securely bolted!")
return 0
src.dir = turn(src.dir, -90)
return 1
/obj/item/pod_parts/pod_frame/attack_hand()
src.rotate()
/obj/item/pod_parts/pod_frame/fore_port
name = "fore port pod frame"
icon_state = "pod_fp"
desc = "A space pod frame component. This is the fore port component."
link_to = /obj/item/pod_parts/pod_frame/fore_starboard
link_angle = 90
/obj/item/pod_parts/pod_frame/fore_starboard
name = "fore starboard pod frame"
icon_state = "pod_fs"
desc = "A space pod frame component. This is the fore starboard component."
link_to = /obj/item/pod_parts/pod_frame/aft_starboard
link_angle = 180
/obj/item/pod_parts/pod_frame/aft_port
name = "aft port pod frame"
icon_state = "pod_ap"
desc = "A space pod frame component. This is the aft port component."
link_to = /obj/item/pod_parts/pod_frame/fore_port
link_angle = 0
/obj/item/pod_parts/pod_frame/aft_starboard
name = "aft starboard pod frame"
icon_state = "pod_as"
desc = "A space pod frame component. This is the aft starboard component."
link_to = /obj/item/pod_parts/pod_frame/aft_port
link_angle = 270
/obj/item/pod_parts/armor
name = "civilian pod armor"
icon = 'icons/goonstation/pods/pod_parts.dmi'
icon_state = "pod_armor_civ"
desc = "Spacepod armor. This is the civilian version. It looks rather flimsy."
+551
View File
@@ -0,0 +1,551 @@
/obj/machinery/spod_part_fabricator
icon = 'icons/obj/robotics.dmi'
icon_state = "fab-idle"
name = "spacepod fabricator"
desc = "Nothing is being built."
density = 1
anchored = 1
use_power = 1
idle_power_usage = 20
active_power_usage = 5000
var/time_coeff = 1
var/resource_coeff = 1
var/time_coeff_tech = 1
var/resource_coeff_tech = 1
var/list/resources = list(
MAT_METAL=0,
MAT_GLASS=0,
MAT_BANANIUM=0,
MAT_DIAMOND=0,
MAT_GOLD=0,
MAT_PLASMA=0,
MAT_SILVER=0,
MAT_URANIUM=0
)
var/res_max_amount = 200000
var/datum/research/files
var/id
var/sync = 0
var/part_set
var/datum/design/being_built
var/list/queue = list()
var/processing_queue = 0
var/screen = "main"
var/temp
var/list/part_sets = list(
"Pod_Weaponry",
"Pod_Armor",
"Pod_Cargo",
"Pod_Parts",
"Pod_Frame",
"Misc",
)
var/turf/exit
/obj/machinery/spod_part_fabricator/New()
..()
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/podfab(null)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(null)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(null)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(null)
component_parts += new /obj/item/weapon/stock_parts/manipulator(null)
component_parts += new /obj/item/weapon/stock_parts/manipulator(null)
component_parts += new /obj/item/weapon/stock_parts/micro_laser(null)
component_parts += new /obj/item/weapon/stock_parts/micro_laser(null)
component_parts += new /obj/item/weapon/stock_parts/console_screen(null)
RefreshParts()
files = new /datum/research(src) //Setup the research data holder.
for(var/direction in cardinal)
exit = get_step(src,direction)
if(!exit.density)
break
exit = loc
/obj/machinery/spod_part_fabricator/upgraded/New()
..()
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/podfab(null)
component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(null)
component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(null)
component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(null)
component_parts += new /obj/item/weapon/stock_parts/manipulator/pico(null)
component_parts += new /obj/item/weapon/stock_parts/manipulator/pico(null)
component_parts += new /obj/item/weapon/stock_parts/micro_laser/ultra(null)
component_parts += new /obj/item/weapon/stock_parts/micro_laser/ultra(null)
component_parts += new /obj/item/weapon/stock_parts/console_screen(null)
RefreshParts()
/obj/machinery/spod_part_fabricator/RefreshParts()
var/T = 0
//maximum stocking amount (max 412000)
for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts)
T += M.rating
res_max_amount = (187000+(T * 37500))
//ressources adjustment coefficient (1 -> 0.88 -> 0.75)
T = -1
for(var/obj/item/weapon/stock_parts/micro_laser/Ma in component_parts)
T += Ma.rating
resource_coeff = round(initial(resource_coeff) - (initial(resource_coeff)*(T))/8,0.01)
//building time adjustment coefficient (1 -> 0.8 -> 0.6)
T = -1
for(var/obj/item/weapon/stock_parts/manipulator/Ml in component_parts)
T += Ml.rating
time_coeff = round(initial(time_coeff) - (initial(time_coeff)*(T))/5,0.01)
/obj/machinery/spod_part_fabricator/proc/output_parts_list(set_name)
var/output = ""
for(var/datum/design/D in files.known_designs)
if(D.build_type & PODFAB)
if(!(set_name in D.category))
continue
var/resources_available = check_resources(D)
output += "<div class='part'>[output_part_info(D)]<br>\[[resources_available?"<a href='?src=\ref[src];part=[D.id]'>Build</a> | ":null]<a href='?src=\ref[src];add_to_queue=[D.id]'>Add to queue</a>\]\[<a href='?src=\ref[src];part_desc=[D.id]'>?</a>\]</div>"
return output
/obj/machinery/spod_part_fabricator/proc/output_part_info(datum/design/D)
var/output = "[initial(D.name)] (Cost: [output_part_cost(D)]) [get_construction_time_w_coeff(D)/10] seconds"
return output
/obj/machinery/spod_part_fabricator/proc/output_part_cost(datum/design/D)
var/i = 0
var/output
for(var/c in D.materials)
if(c in resources)
output += "[i?" | ":null][get_resource_cost_w_coeff(D,c)] [material2name(c)]"
i++
return output
/obj/machinery/spod_part_fabricator/proc/output_available_resources()
var/output
for(var/resource in resources)
var/amount = min(res_max_amount, resources[resource])
output += "<span class=\"res_name\">[material2name(resource)]: </span>[amount] cm&sup3;, [round(resources[resource] / MINERAL_MATERIAL_AMOUNT,0.1)] sheets"
if(amount>0)
output += "<span style='font-size:80%;'> - Remove \[<a href='?src=\ref[src];remove_mat=1;material=[resource]'>1</a>\] | \[<a href='?src=\ref[src];remove_mat=10;material=[resource]'>10</a>\] | \[<a href='?src=\ref[src];remove_mat=1;material=[resource];custom_eject=1'>Custom</a>\] | \[<a href='?src=\ref[src];remove_mat=[resources[resource] / MINERAL_MATERIAL_AMOUNT];material=[resource]'>All</a>\]</span>"
output += "<br/>"
return output
/obj/machinery/spod_part_fabricator/proc/remove_resources(datum/design/D)
for(var/resource in D.materials)
if(resource in resources)
resources[resource] -= get_resource_cost_w_coeff(D,resource)
/obj/machinery/spod_part_fabricator/proc/check_resources(datum/design/D)
for(var/R in D.materials)
if(R in resources)
if(resources[R] < get_resource_cost_w_coeff(D, R))
return 0
else
return 0
return 1
/obj/machinery/spod_part_fabricator/proc/build_part(datum/design/D)
being_built = D
desc = "It's building \a [initial(D.name)]."
remove_resources(D)
overlays += "fab-active"
use_power = 2
updateUsrDialog()
sleep(get_construction_time_w_coeff(D))
use_power = 1
overlays -= "fab-active"
desc = initial(desc)
var/obj/item/I = new D.build_path
var/O = D.locked
if(O)
var/obj/item/weapon/storage/lockbox/L = new/obj/item/weapon/storage/lockbox(exit)
I.loc = L
L.name += " ([I.name])"
else
I.loc = exit
I.materials[MAT_METAL] = get_resource_cost_w_coeff(D,MAT_METAL)
I.materials[MAT_GLASS] = get_resource_cost_w_coeff(D,MAT_GLASS)
visible_message("\icon[src] <b>\The [src]</b> beeps, \"\The [I] is complete.\"")
being_built = null
updateUsrDialog()
return 1
/obj/machinery/spod_part_fabricator/proc/update_queue_on_page()
send_byjax(usr,"mecha_fabricator.browser","queue",list_queue())
return
/obj/machinery/spod_part_fabricator/proc/add_part_set_to_queue(set_name)
if(set_name in part_sets)
for(var/datum/design/D in files.known_designs)
if(D.build_type & PODFAB)
if(set_name in D.category)
add_to_queue(D)
/obj/machinery/spod_part_fabricator/proc/add_to_queue(D)
if(!istype(queue))
queue = list()
if(D)
queue[++queue.len] = D
return queue.len
/obj/machinery/spod_part_fabricator/proc/remove_from_queue(index)
if(!isnum(index) || !istype(queue) || (index<1 || index>queue.len))
return 0
queue.Cut(index,++index)
return 1
/obj/machinery/spod_part_fabricator/proc/process_queue()
var/datum/design/D = queue[1]
if(!D)
remove_from_queue(1)
if(queue.len)
return process_queue()
else
return
temp = null
while(D)
if(stat&(NOPOWER|BROKEN))
return 0
if(!check_resources(D))
visible_message("\icon[src] <b>\The [src]</b> beeps, \"Not enough resources. Queue processing stopped.\"")
temp = {"<span class='alert'>Not enough resources to build next part.</span><br>
<a href='?src=\ref[src];process_queue=1'>Try again</a> | <a href='?src=\ref[src];clear_temp=1'>Return</a><a>"}
return 0
remove_from_queue(1)
build_part(D)
D = listgetindex(queue, 1)
visible_message("\icon[src] <b>\The [src]</b> beeps, \"Queue processing finished successfully.\"")
/obj/machinery/spod_part_fabricator/proc/list_queue()
var/output = "<b>Queue contains:</b>"
if(!istype(queue) || !queue.len)
output += "<br>Nothing"
else
output += "<ol>"
var/i = 0
for(var/datum/design/D in queue)
i++
var/obj/part = D.build_path
output += "<li[!check_resources(D)?" style='color: #f00;'":null]>[initial(part.name)] - [i>1?"<a href='?src=\ref[src];queue_move=-1;index=[i]' class='arrow'>&uarr;</a>":null] [i<queue.len?"<a href='?src=\ref[src];queue_move=+1;index=[i]' class='arrow'>&darr;</a>":null] <a href='?src=\ref[src];remove_from_queue=[i]'>Remove</a></li>"
output += "</ol>"
output += "\[<a href='?src=\ref[src];process_queue=1'>Process queue</a> | <a href='?src=\ref[src];clear_queue=1'>Clear queue</a>\]"
return output
/obj/machinery/spod_part_fabricator/proc/update_tech()
if(!files)
return
var/output
for(var/datum/tech/T in files.known_tech)
if(T && T.level > 1)
var/diff
switch(T.id)
if("materials")
//one materials level is 1/32, so that max level is 0.75 coefficient
diff = round(initial(resource_coeff_tech) - (initial(resource_coeff_tech)*(T.level-1))/32,0.01)
if(resource_coeff_tech>diff)
resource_coeff_tech = diff
output+="Production efficiency increased.<br>"
if("programming")
//one materials level is 1/40, so that max level is 0.8 coefficient
diff = round(initial(time_coeff_tech) - (initial(time_coeff_tech)*(T.level-1))/40,0.1)
if(time_coeff_tech>diff)
time_coeff_tech = diff
output+="Production routines updated.<br>"
return output
/obj/machinery/spod_part_fabricator/proc/sync()
temp = "Updating local R&D database..."
updateUsrDialog()
sleep(30) //only sleep if called by user
var/area/localarea = get_area(src)
for(var/obj/machinery/computer/rdconsole/RDC in localarea.contents)
if(!RDC.sync)
continue
for(var/datum/tech/T in RDC.files.known_tech)
files.AddTech2Known(T)
for(var/datum/design/D in RDC.files.known_designs)
files.AddDesign2Known(D)
files.RefreshResearch()
temp = "Processed equipment designs.<br>"
//check if the tech coefficients have changed
temp += update_tech()
temp += "<a href='?src=\ref[src];clear_temp=1'>Return</a>"
updateUsrDialog()
visible_message("\icon[src] <b>\The [src]</b> beeps, \"Successfully synchronized with R&D server.\"")
return
temp = "Unable to connect to local R&D Database.<br>Please check your connections and try again.<br><a href='?src=\ref[src];clear_temp=1'>Return</a>"
updateUsrDialog()
return
/obj/machinery/spod_part_fabricator/proc/get_resource_cost_w_coeff(datum/design/D, resource, roundto = 1)
return round(D.materials[resource]*resource_coeff*resource_coeff_tech, roundto)
/obj/machinery/spod_part_fabricator/proc/get_construction_time_w_coeff(datum/design/D, roundto = 1) //aran
return round(initial(D.construction_time)*time_coeff*time_coeff_tech, roundto)
/obj/machinery/spod_part_fabricator/attack_hand(mob/user)
if(..())
return 1
return interact(user)
/obj/machinery/spod_part_fabricator/interact(mob/user as mob)
var/dat, left_part
if (..())
return
user.set_machine(src)
if(exit.density)
visible_message("\icon[src] <b>\The [src]</b> beeps, \"Error! Part outlet is obstructed.\"")
return
if(temp)
left_part = temp
else if(being_built)
var/obj/I = being_built.build_path
left_part = {"<TT>Building [initial(I.name)].<BR>
Please wait until completion...</TT>"}
else
switch(screen)
if("main")
left_part = output_available_resources()+"<hr>"
left_part += "<a href='?src=\ref[src];sync=1'>Sync with R&D servers</a><hr>"
for(var/part_set in part_sets)
left_part += "<a href='?src=\ref[src];part_set=[part_set]'>[part_set]</a> - \[<a href='?src=\ref[src];partset_to_queue=[part_set]'>Add all parts to queue</a>\]<br>"
if("parts")
left_part += output_parts_list(part_set)
left_part += "<hr><a href='?src=\ref[src];screen=main'>Return</a>"
dat = {"<html>
<head>
<title>[name]</title>
<style>
.res_name {font-weight: bold; text-transform: capitalize;}
.red {color: #f00;}
.part {margin-bottom: 10px;}
.arrow {text-decoration: none; font-size: 10px;}
body, table {height: 100%;}
td {vertical-align: top; padding: 5px;}
html, body {padding: 0px; margin: 0px;}
h1 {font-size: 18px; margin: 5px 0px;}
</style>
<script language='javascript' type='text/javascript'>
[js_byjax]
</script>
</head><body>
<body>
<table style='width: 100%;'>
<tr>
<td style='width: 65%; padding-right: 10px;'>
[left_part]
</td>
<td style='width: 35%; background: #ccc;' id='queue'>
[list_queue()]
</td>
<tr>
</table>
</body>
</html>"}
user << browse(dat, "window=mecha_fabricator;size=1000x430")
onclose(user, "mecha_fabricator")
return
/obj/machinery/spod_part_fabricator/Topic(href, href_list)
if(..())
return
var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
if(href_list["part_set"])
var/tpart_set = filter.getStr("part_set")
if(tpart_set)
if(tpart_set=="clear")
part_set = null
else
part_set = tpart_set
screen = "parts"
if(href_list["part"])
var/T = filter.getStr("part")
for(var/datum/design/D in files.known_designs)
if(D.build_type & PODFAB)
if(D.id == T)
if(!processing_queue)
build_part(D)
else
add_to_queue(D)
break
if(href_list["add_to_queue"])
var/T = filter.getStr("add_to_queue")
for(var/datum/design/D in files.known_designs)
if(D.build_type & PODFAB)
if(D.id == T)
add_to_queue(D)
break
return update_queue_on_page()
if(href_list["remove_from_queue"])
remove_from_queue(filter.getNum("remove_from_queue"))
return update_queue_on_page()
if(href_list["partset_to_queue"])
add_part_set_to_queue(filter.get("partset_to_queue"))
return update_queue_on_page()
if(href_list["process_queue"])
spawn(-1)
if(processing_queue || being_built)
return 0
processing_queue = 1
process_queue()
processing_queue = 0
if(href_list["clear_temp"])
temp = null
if(href_list["screen"])
screen = href_list["screen"]
if(href_list["queue_move"] && href_list["index"])
var/index = filter.getNum("index")
var/new_index = index + filter.getNum("queue_move")
if(isnum(index) && isnum(new_index))
if(IsInRange(new_index,1,queue.len))
queue.Swap(index,new_index)
return update_queue_on_page()
if(href_list["clear_queue"])
queue = list()
return update_queue_on_page()
if(href_list["sync"])
sync()
if(href_list["part_desc"])
var/T = filter.getStr("part_desc")
for(var/datum/design/D in files.known_designs)
if(D.build_type & PODFAB)
if(D.id == T)
var/obj/part = D.build_path
temp = {"<h1>[initial(part.name)] description:</h1>
[initial(part.desc)]<br>
<a href='?src=\ref[src];clear_temp=1'>Return</a>
"}
break
if(href_list["remove_mat"] && href_list["material"])
var/amount = text2num(href_list["remove_mat"])
var/material = href_list["material"]
if(href_list["custom_eject"])
amount = input("How many sheets would you like to eject from the machine?", "How much?", 1) as null|num
amount = max(0,min(round(resources[material]/MINERAL_MATERIAL_AMOUNT),amount)) // Rounding errors aren't scary, as the mineral eject proc is smart
if (!amount)
return
amount = round(amount)
if(amount < 0 || amount > resources[material]) //href protection
return
var/removed = remove_material(material,amount)
if(removed == -1)
temp = "Not enough [material2name(material)] to produce a sheet."
else
temp = "Ejected [removed] of [material2name(material)]"
temp += "<br><a href='?src=\ref[src];clear_temp=1'>Return</a>"
updateUsrDialog()
return
/obj/machinery/spod_part_fabricator/proc/remove_material(var/mat_string, var/amount)
if(resources[mat_string] < MINERAL_MATERIAL_AMOUNT) //not enough mineral for a sheet
return -1
var/type
switch(mat_string)
if(MAT_METAL)
type = /obj/item/stack/sheet/metal
if(MAT_GLASS)
type = /obj/item/stack/sheet/glass
if(MAT_GOLD)
type = /obj/item/stack/sheet/mineral/gold
if(MAT_SILVER)
type = /obj/item/stack/sheet/mineral/silver
if(MAT_DIAMOND)
type = /obj/item/stack/sheet/mineral/diamond
if(MAT_PLASMA)
type = /obj/item/stack/sheet/mineral/plasma
if(MAT_URANIUM)
type = /obj/item/stack/sheet/mineral/uranium
if(MAT_BANANIUM)
type = /obj/item/stack/sheet/mineral/bananium
else
return 0
var/result = 0
while(amount > 50)
new type(get_turf(src),50)
amount -= 50
result += 50
resources[mat_string] -= 50 * MINERAL_MATERIAL_AMOUNT
var/total_amount = round(resources[mat_string]/MINERAL_MATERIAL_AMOUNT)
if(total_amount)//if there's still enough material for sheets
var/obj/item/stack/sheet/res = new type(get_turf(src),min(amount,total_amount))
resources[mat_string] -= res.amount*MINERAL_MATERIAL_AMOUNT
result += res.amount
return result
/obj/machinery/spod_part_fabricator/attackby(obj/W as obj, mob/user as mob, params)
if(default_deconstruction_screwdriver(user, "fab-o", "fab-idle", W))
return
if(exchange_parts(user, W))
return
if(panel_open)
if(istype(W, /obj/item/weapon/crowbar))
for(var/material in resources)
remove_material(material, resources[material]/MINERAL_MATERIAL_AMOUNT)
default_deconstruction_crowbar(W)
return 1
else
to_chat(user, "<span class='danger'>You can't load \the [name] while it's opened.</span>")
return 1
if(istype(W, /obj/item/stack))
var/material
switch(W.type)
if(/obj/item/stack/sheet/mineral/gold)
material = MAT_GOLD
if(/obj/item/stack/sheet/mineral/silver)
material = MAT_SILVER
if(/obj/item/stack/sheet/mineral/diamond)
material = MAT_DIAMOND
if(/obj/item/stack/sheet/mineral/plasma)
material = MAT_PLASMA
if(/obj/item/stack/sheet/metal)
material = MAT_METAL
if(/obj/item/stack/sheet/glass)
material = MAT_GLASS
if(/obj/item/stack/sheet/mineral/bananium)
material = MAT_BANANIUM
if(/obj/item/stack/sheet/mineral/uranium)
material = MAT_URANIUM
else
return ..()
if(being_built)
to_chat(user, "\The [src] is currently processing. Please wait until completion.")
return
if(res_max_amount - resources[material] < MINERAL_MATERIAL_AMOUNT) //overstuffing the fabricator
to_chat(user, "\The [src] [material2name(material)] storage is full.")
return
var/obj/item/stack/sheet/stack = W
var/sname = "[stack.name]"
if(resources[material] < res_max_amount)
overlays += "fab-load-[material2name(material)]"//loading animation is now an overlay based on material type. No more spontaneous conversion of all ores to metal. -vey
var/transfer_amount = min(stack.amount, round((res_max_amount - resources[material])/MINERAL_MATERIAL_AMOUNT,1))
resources[material] += transfer_amount * MINERAL_MATERIAL_AMOUNT
stack.use(transfer_amount)
to_chat(user, "You insert [transfer_amount] [sname] sheet\s into \the [src].")
sleep(10)
updateUsrDialog()
overlays -= "fab-load-[material2name(material)]" //No matter what the overlay shall still be deleted
else
to_chat(user, "\The [src] cannot hold any more [sname] sheet\s.")
return
/obj/machinery/spod_part_fabricator/proc/material2name(var/ID)
return copytext(ID,2)
+967
View File
@@ -0,0 +1,967 @@
#define DAMAGE 1
#define FIRE 2
/obj/spacepod
name = "\improper space pod"
desc = "A space pod meant for space travel."
icon = 'icons/goonstation/48x48/pods.dmi'
density = 1 //Dense. To raise the heat.
opacity = 0
anchored = 1
unacidable = 1
layer = 3.9
infra_luminosity = 15
var/list/mob/pilot //There is only ever one pilot and he gets all the privledge
var/list/mob/passengers = list() //passengers can't do anything and are variable in number
var/max_passengers = 0
var/obj/item/weapon/storage/internal/cargo_hold
var/datum/spacepod/equipment/equipment_system
var/battery_type = "/obj/item/weapon/stock_parts/cell/high"
var/obj/item/weapon/stock_parts/cell/battery
var/datum/gas_mixture/cabin_air
var/obj/machinery/portable_atmospherics/canister/internal_tank
var/use_internal_tank = 0
var/datum/global_iterator/pr_int_temp_processor //normalizes internal air mixture temperature
var/datum/global_iterator/pr_give_air //moves air from tank to cabin
var/datum/effect/system/ion_trail_follow/space_trail/ion_trail
var/hatch_open = 0
var/next_firetime = 0
var/list/pod_overlays
var/health = 250
var/empcounter = 0 //Used for disabling movement when hit by an EMP
var/lights = 0
var/lights_power = 6
var/list/icon_light_color = list("pod_civ" = LIGHT_COLOR_WHITE, \
"pod_mil" = "#BBF093", \
"pod_synd" = LIGHT_COLOR_RED, \
"pod_gold" = LIGHT_COLOR_WHITE, \
"pod_black" = "#3B8FE5", \
"pod_industrial" = "#CCCC00")
var/unlocked = 1
var/move_delay = 2
var/next_move = 0
/obj/spacepod/New()
. = ..()
if(!pod_overlays)
pod_overlays = new/list(2)
pod_overlays[DAMAGE] = image(icon, icon_state="pod_damage")
pod_overlays[FIRE] = image(icon, icon_state="pod_fire")
bound_width = 64
bound_height = 64
dir = EAST
battery = new battery_type(src)
add_cabin()
add_airtank()
src.ion_trail = new /datum/effect/system/ion_trail_follow/space_trail()
src.ion_trail.set_up(src)
src.ion_trail.start()
src.use_internal_tank = 1
pr_int_temp_processor = new /datum/global_iterator/pod_preserve_temp(list(src))
pr_give_air = new /datum/global_iterator/pod_tank_give_air(list(src))
equipment_system = new(src)
spacepods_list += src
cargo_hold = new/obj/item/weapon/storage/internal(src)
cargo_hold.w_class = 5 //so you can put bags in
cargo_hold.storage_slots = 0 //You need to install cargo modules to use it.
cargo_hold.max_w_class = 5 //fit almost anything
cargo_hold.max_combined_w_class = 0 //you can optimize your stash with larger items
/obj/spacepod/Destroy()
if (equipment_system.cargo_system)
equipment_system.cargo_system.removed(null)
qdel(equipment_system)
equipment_system = null
qdel(cargo_hold)
cargo_hold = null
qdel(battery)
battery = null
qdel(cabin_air)
cabin_air = null
qdel(internal_tank)
internal_tank = null
qdel(pr_int_temp_processor)
pr_int_temp_processor = null
qdel(pr_give_air)
pr_give_air = null
qdel(ion_trail)
ion_trail = null
occupant_sanity_check()
if(passengers)
for(var/mob/M in passengers)
M.forceMove(get_turf(src))
passengers -= M
spacepods_list -= src
return ..()
/obj/spacepod/process()
if(src.empcounter > 0)
src.empcounter--
else
processing_objects.Remove(src)
/obj/spacepod/proc/update_icons()
if(!pod_overlays)
pod_overlays = new/list(2)
pod_overlays[DAMAGE] = image(icon, icon_state="pod_damage")
pod_overlays[FIRE] = image(icon, icon_state="pod_fire")
overlays.Cut()
if(health <= round(initial(health)/2))
overlays += pod_overlays[DAMAGE]
if(health <= round(initial(health)/4))
overlays += pod_overlays[FIRE]
light_color = icon_light_color[src.icon_state]
/obj/spacepod/bullet_act(var/obj/item/projectile/P)
if(P.damage && !P.nodamage)
deal_damage(P.damage)
else if(P.flag == "energy" && istype(P,/obj/item/projectile/ion)) //needed to make sure ions work properly
empulse(src, 1, 1)
/obj/spacepod/blob_act()
deal_damage(30)
return
/obj/spacepod/attack_animal(mob/living/simple_animal/user as mob)
if(user.melee_damage_upper == 0)
user.custom_emote(1, "[user.friendly] [src]")
else
var/damage = rand(user.melee_damage_lower, user.melee_damage_upper)
deal_damage(damage)
visible_message("\red <B>[user]</B> [user.attacktext] [src]!")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name]</font>")
return
/obj/spacepod/attack_alien(mob/user as mob)
user.changeNext_move(CLICK_CD_MELEE)
deal_damage(15)
playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1)
to_chat(user, "\red You slash at \the [src]!")
visible_message("\red The [user] slashes at [src.name]'s armor!")
return
/obj/spacepod/proc/deal_damage(var/damage)
var/oldhealth = health
health = max(0, health - damage)
var/percentage = (health / initial(health)) * 100
occupant_sanity_check()
if(passengers && oldhealth > health && percentage <= 25 && percentage > 0)
var/sound/S = sound('sound/effects/engine_alert2.ogg')
S.wait = 0 //No queue
S.channel = 0 //Any channel
S.volume = 50
for(var/mob/M in passengers)
to_chat(M, S)
if(passengers && oldhealth > health && !health)
var/sound/S = sound('sound/effects/engine_alert1.ogg')
S.wait = 0
S.channel = 0
S.volume = 50
for(var/mob/M in passengers)
to_chat(M, S)
if(!health)
spawn(0)
if(passengers)
for(var/mob/M in passengers)
to_chat(M, "<span class='userdanger'>Critical damage to the vessel detected, core explosion imminent!</span>")
for(var/i = 10, i >= 0; --i)
if(passengers)
for(var/mob/M in passengers)
to_chat(M, "<span class='warning'>[i]</span>")
if(i == 0)
explosion(loc, 2, 4, 8)
qdel(src)
sleep(10)
update_icons()
/obj/spacepod/proc/repair_damage(var/repair_amount)
if(health)
health = min(initial(health), health + repair_amount)
update_icons()
/obj/spacepod/ex_act(severity)
occupant_sanity_check()
switch(severity)
if(1)
for(var/mob/M in passengers)
var/mob/living/carbon/human/H = M
if(H)
H.forceMove(get_turf(src))
H.ex_act(severity + 1)
to_chat(H, "<span class='warning'>You are forcefully thrown from \the [src]!</span>")
qdel(ion_trail)
qdel(src)
if(2)
deal_damage(100)
if(3)
if(prob(40))
deal_damage(50)
/obj/spacepod/emp_act(severity)
occupant_sanity_check()
cargo_hold.emp_act(severity)
switch(severity)
if(1)
if(pilot)
to_chat(pilot, "<span class='warning'>The pod console flashes 'Heavy EMP WAVE DETECTED'.</span>")
if(passengers)
for(var/mob/M in passengers)
to_chat(M, "<span class='warning'>The pod console flashes 'Heavy EMP WAVE DETECTED'.</span>")//warn the passengers
if(battery)
battery.charge = max(0, battery.charge - 5000) //Cell EMP act is too weak, this pod needs to be sapped.
src.deal_damage(100)
if(src.empcounter < 40)
src.empcounter = 40 //Disable movement for 40 ticks. Plenty long enough.
processing_objects.Add(src)
if(2)
if(pilot)
to_chat(pilot, "<span class='warning'>The pod console flashes 'EMP WAVE DETECTED'.</span>")
if(passengers)
for(var/mob/M in passengers)
to_chat(M, "<span class='warning'>The pod console flashes 'EMP WAVE DETECTED'.</span>")//warn the passengers
deal_damage(40)
if(battery)
battery.charge = max(0, battery.charge - 2500) //Cell EMP act is too weak, this pod needs to be sapped.
if(empcounter < 20)
empcounter = 20 //Disable movement for 20 ticks.
processing_objects.Add(src)
/obj/spacepod/attackby(obj/item/W as obj, mob/user as mob, params)
if(iscrowbar(W))
if(!equipment_system.lock_system || unlocked || hatch_open)
hatch_open = !hatch_open
playsound(loc, 'sound/items/Crowbar.ogg', 50, 1)
to_chat(user, "<span class='notice'>You [hatch_open ? "open" : "close"] the maintenance hatch.</span>")
else
to_chat(user, "<span class='warning'>The hatch is locked shut!</span>")
return
if(istype(W, /obj/item/weapon/stock_parts/cell))
if(!hatch_open)
to_chat(user, "\red The maintenance hatch is closed!")
return
if(battery)
to_chat(user, "<span class='notice'>The pod already has a battery.</span>")
return
user.drop_item(W)
battery = W
W.forceMove(src)
return
if(istype(W, /obj/item/device/spacepod_equipment))
if(!hatch_open)
to_chat(user, "\red The maintenance hatch is closed!")
return
if(!equipment_system)
to_chat(user, "<span class='warning'>The pod has no equipment datum, yell at the coders</span>")
return
if(istype(W, /obj/item/device/spacepod_equipment/weaponry))
add_equipment(user, W, "weapon_system")
return
if(istype(W, /obj/item/device/spacepod_equipment/misc))
add_equipment(user, W, "misc_system")
return
if(istype(W, /obj/item/device/spacepod_equipment/cargo))
add_equipment(user, W, "cargo_system")
return
if(istype(W, /obj/item/device/spacepod_equipment/sec_cargo))
add_equipment(user, W, "sec_cargo_system")
return
if(istype(W, /obj/item/device/spacepod_equipment/lock))
add_equipment(user, W, "lock_system")
return
if(istype(W, /obj/item/device/spacepod_key) && istype(equipment_system.lock_system, /obj/item/device/spacepod_equipment/lock/keyed))
var/obj/item/device/spacepod_key/key = W
if (key.id == equipment_system.lock_system.id)
lock_pod()
return
else
to_chat(user, "<span class='warning'>This is the wrong key!</span>")
return
if(istype(W, /obj/item/weapon/weldingtool))
if(!hatch_open)
to_chat(user, "\red You must open the maintenance hatch before attempting repairs.")
return
var/obj/item/weapon/weldingtool/WT = W
if(!WT.isOn())
to_chat(user, "\red The welder must be on for this task.")
return
if (health < initial(health))
to_chat(user, "\blue You start welding the spacepod...")
playsound(loc, 'sound/items/Welder.ogg', 50, 1)
if(do_after(user, 20, target = src))
if(!src || !WT.remove_fuel(3, user)) return
repair_damage(10)
to_chat(user, "\blue You mend some [pick("dents","bumps","damage")] with \the [WT]")
return
to_chat(user, "\blue <b>\The [src] is fully repaired!</b>")
return
if(istype(W, /obj/item/device/lock_buster))
var/obj/item/device/lock_buster/L = W
if(L.on & equipment_system.lock_system)
user.visible_message(user, "<span class='warning'>[user] is drilling through the [src]'s lock!</span>",
"<span class='notice'>You start drilling through the [src]'s lock!</span>")
if(do_after(user, 100, target = src))
qdel(equipment_system.lock_system)
equipment_system.lock_system = null
user.visible_message(user, "<span class='warning'>[user] has destroyed the [src]'s lock!</span>",
"<span class='notice'>You destroy the [src]'s lock!</span>")
else
user.visible_message(user, "<span class='warning'>[user] fails to break through the [src]'s lock!</span>",
"<span class='notice'>You were unable to break through the [src]'s lock!</span>")
return
to_chat(user, "<span class='notice'>Turn the [L] on first.</span>")
return
if(cargo_hold.storage_slots > 0 && !hatch_open && unlocked) // must be the last option as all items not listed prior will be stored
cargo_hold.attackby(W, user, params)
obj/spacepod/proc/add_equipment(mob/user, var/obj/item/device/spacepod_equipment/SPE, var/slot)
if(equipment_system.vars[slot])
to_chat(user, "<span class='notice'>The pod already has a [slot], remove it first.</span>")
return
else
to_chat(user, "<span class='notice'>You insert \the [SPE] into the pod.</span>")
user.drop_item(SPE)
SPE.forceMove(src)
equipment_system.vars[slot] = SPE
var/obj/item/device/spacepod_equipment/system = equipment_system.vars[slot]
system.my_atom = src
equipment_system.installed_modules += SPE
max_passengers += SPE.occupant_mod
cargo_hold.storage_slots += SPE.storage_mod["slots"]
cargo_hold.max_combined_w_class += SPE.storage_mod["w_class"]
/obj/spacepod/attack_hand(mob/user as mob)
if(user.a_intent == I_GRAB && unlocked)
var/mob/target
if(pilot)
target = pilot
else if(passengers.len > 0)
target = passengers[1]
if(target && istype(target))
src.visible_message("<span class='warning'>[user] is trying to rip the door open and pull [target] out of the [src]!</span>",
"<span class='warning'>You see [user] outside the door trying to rip it open!</span>")
if(do_after(user, 50, target = src))
target.forceMove(get_turf(src))
target.Stun(1)
passengers -= target
target.visible_message("<span class='warning'>[user] flings the door open and tears [target] out of the [src]</span>",
"<span class='warning'>The door flies open and you are thrown out of the [src] and to the ground!</span>")
return
target.visible_message("<span class='warning'>[user] was unable to get the door open!</span>",
"<span class='warning'>You manage to keep [user] out of the [src]!</span>")
if(!hatch_open)
if(cargo_hold.storage_slots > 0)
if(unlocked)
cargo_hold.open(user)
else
to_chat(user, "<span class='notice'>The storage compartment is locked</span>")
return ..()
if(!equipment_system || !istype(equipment_system))
to_chat(user, "<span class='warning'>The pod has no equpment datum, or is the wrong type, yell at IK3I.</span>")
return
var/list/possible = list()
if(battery)
possible.Add("Energy Cell")
if(equipment_system.weapon_system)
possible.Add("Weapon System")
if(equipment_system.misc_system)
possible.Add("Misc. System")
if(equipment_system.cargo_system)
possible.Add("Cargo System")
if(equipment_system.sec_cargo_system)
possible.Add("Secondary Cargo System")
if(equipment_system.lock_system)
possible.Add("Lock System")
switch(input(user, "Remove which equipment?", null, null) as null|anything in possible)
if("Energy Cell")
if(user.put_in_any_hand_if_possible(battery))
to_chat(user, "<span class='notice'>You remove \the [battery] from the space pod</span>")
battery = null
else
to_chat(user, "<span class='warning'>You need an open hand to do that.</span>")
return
if("Weapon System")
remove_equipment(user, equipment_system.weapon_system, "weapon_system")
return
if("Misc. System")
remove_equipment(user, equipment_system.misc_system, "misc_system")
return
if("Cargo System")
remove_equipment(user, equipment_system.cargo_system, "cargo_system")
return
if("Secondary Cargo System")
remove_equipment(user, equipment_system.sec_cargo_system, "sec_cargo_system")
return
if("Lock System")
remove_equipment(user, equipment_system.lock_system, "lock_system")
/obj/spacepod/proc/remove_equipment(mob/user, var/obj/item/device/spacepod_equipment/SPE, var/slot)
if(passengers.len > max_passengers - SPE.occupant_mod)
to_chat(user, "<span class='warning'>Someone is sitting in \the [SPE]!</span>")
return
var/sum_w_class = 0
for(var/obj/item/I in cargo_hold.contents)
sum_w_class += I.w_class
if(cargo_hold.contents.len > cargo_hold.storage_slots - SPE.storage_mod["slots"] || sum_w_class > cargo_hold.max_combined_w_class - SPE.storage_mod["w_class"])
to_chat(user, "<span class='warning'>Empty \the [SPE] first!</span>")
return
if(user.put_in_any_hand_if_possible(SPE))
to_chat(user, "<span class='notice'>You remove \the [SPE] from the equipment system.</span>")
equipment_system.installed_modules -= SPE
max_passengers -= SPE.occupant_mod
cargo_hold.storage_slots -= SPE.storage_mod["slots"]
cargo_hold.max_combined_w_class -= SPE.storage_mod["w_class"]
SPE.removed(user)
SPE.my_atom = null
equipment_system.vars[slot] = null
return
to_chat(user, "<span class='warning'>You need an open hand to do that.</span>")
/obj/spacepod/hear_talk/hear_talk(mob/M, var/msg)
cargo_hold.hear_talk(M, msg)
..()
/obj/spacepod/hear_message(mob/M, var/msg)
cargo_hold.hear_message(M, msg)
..()
/obj/spacepod/proc/return_inv()
var/list/L = list( )
L += src.contents
for(var/obj/item/weapon/storage/S in src)
L += S.return_inv()
for(var/obj/item/weapon/gift/G in src)
L += G.gift
if (istype(G.gift, /obj/item/weapon/storage))
var/obj/item/weapon/storage/inv = G.gift
L += inv.return_inv()
return L
/obj/spacepod/civilian
icon_state = "pod_civ"
desc = "A sleek civilian space pod."
/obj/spacepod/random
icon_state = "pod_civ"
// placeholder
/obj/spacepod/sec
name = "\improper security spacepod"
desc = "An armed security spacepod with reinforced armor plating."
icon_state = "pod_mil"
health = 400
/obj/spacepod/sec/New()
..()
var/obj/item/device/spacepod_equipment/weaponry/burst_taser/T = new /obj/item/device/spacepod_equipment/weaponry/taser
T.loc = equipment_system
equipment_system.weapon_system = T
equipment_system.weapon_system.my_atom = src
var/obj/item/device/spacepod_equipment/misc/tracker/L = new /obj/item/device/spacepod_equipment/misc/tracker
L.loc = equipment_system
equipment_system.misc_system = L
equipment_system.misc_system.my_atom = src
equipment_system.misc_system.enabled = 1
var/obj/item/device/spacepod_equipment/sec_cargo/chair/C = new /obj/item/device/spacepod_equipment/sec_cargo/chair
C.loc = equipment_system
equipment_system.sec_cargo_system = C
equipment_system.sec_cargo_system.my_atom = src
max_passengers = 1
var/obj/item/device/spacepod_equipment/lock/keyed/K = new /obj/item/device/spacepod_equipment/lock/keyed
K.loc = equipment_system
equipment_system.lock_system = K
equipment_system.lock_system.my_atom = src
equipment_system.lock_system.id = 100000
/obj/spacepod/random/New()
..()
icon_state = pick("pod_civ", "pod_black", "pod_mil", "pod_synd", "pod_gold", "pod_industrial")
switch(icon_state)
if("pod_civ")
desc = "A sleek civilian space pod."
if("pod_black")
desc = "An all black space pod with no insignias."
if("pod_mil")
desc = "A dark grey space pod brandishing the Nanotrasen Military insignia"
if("pod_synd")
desc = "A menacing military space pod with Fuck NT stenciled onto the side"
if("pod_gold")
desc = "A civilian space pod with a gold body, must have cost somebody a pretty penny"
if("pod_industrial")
desc = "A rough looking space pod meant for industrial work"
update_icons()
/obj/spacepod/verb/toggle_internal_tank()
set name = "Toggle internal airtank usage"
set category = "Spacepod"
set src = usr.loc
set popup_menu = 0
if(usr != src.pilot)
to_chat(usr, "<span class='notice'>You can't reach the controls from your chair")
return
use_internal_tank = !use_internal_tank
to_chat(usr, "<span class='notice'>Now taking air from [use_internal_tank?"internal airtank":"environment"].</span>")
/obj/spacepod/proc/add_cabin()
cabin_air = new
cabin_air.temperature = T20C
cabin_air.volume = 200
cabin_air.oxygen = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
cabin_air.nitrogen = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
return cabin_air
/obj/spacepod/proc/add_airtank()
internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src)
return internal_tank
/obj/spacepod/proc/get_turf_air()
var/turf/T = get_turf(src)
if(T)
. = T.return_air()
/obj/spacepod/remove_air(amount)
if(use_internal_tank)
return cabin_air.remove(amount)
else
var/turf/T = get_turf(src)
if(T)
return T.remove_air(amount)
/obj/spacepod/return_air()
if(use_internal_tank)
return cabin_air
return get_turf_air()
/obj/spacepod/proc/return_pressure()
. = 0
if(use_internal_tank)
. = cabin_air.return_pressure()
else
var/datum/gas_mixture/t_air = get_turf_air()
if(t_air)
. = t_air.return_pressure()
/obj/spacepod/proc/return_temperature()
. = 0
if(use_internal_tank)
. = cabin_air.return_temperature()
else
var/datum/gas_mixture/t_air = get_turf_air()
if(t_air)
. = t_air.return_temperature()
/obj/spacepod/proc/moved_other_inside(var/mob/living/carbon/human/H as mob)
occupant_sanity_check()
if(passengers.len < max_passengers)
H.stop_pulling()
H.forceMove(src)
passengers += H
H.forceMove(src)
playsound(src, 'sound/machines/windowdoor.ogg', 50, 1)
return 1
/obj/spacepod/MouseDrop_T(atom/A, mob/user)
if(user == pilot || user in passengers)
return
if(istype(A,/mob))
var/mob/M = A
if(!isliving(M))
return
occupant_sanity_check()
if(M != user && unlocked && (M.stat == DEAD || M.incapacitated()))
if(passengers.len >= max_passengers && !pilot)
to_chat(usr, "<span class='danger'><b>That person can't fly the pod!</b></span>")
return 0
if(passengers.len < max_passengers)
visible_message("<span class='danger'>[user.name] starts loading [M.name] into the pod!</span>")
if(do_after(user, 50, target = M))
moved_other_inside(M)
return
if(M == user)
enter_pod(user)
return
if(istype(A, /obj/structure/ore_box) && equipment_system.cargo_system && istype(equipment_system.cargo_system,/obj/item/device/spacepod_equipment/cargo/ore)) // For loading ore boxes
load_cargo(user, A)
return
if(istype(A, /obj/structure/closet/crate) && equipment_system.cargo_system && istype(equipment_system.cargo_system, /obj/item/device/spacepod_equipment/cargo/crate)) // For loading crates
load_cargo(user, A)
/obj/spacepod/proc/load_cargo(mob/user, var/obj/O)
var/obj/item/device/spacepod_equipment/cargo/ore/C = equipment_system.cargo_system
if(!C.storage)
to_chat(user, "<span class='notice'>You begin loading \the [O] into \the [src]'s [equipment_system.cargo_system]</span>")
if(do_after(user, 40, target = src))
C.storage = O
O.forceMove(C)
to_chat(user, "<span class='notice'>You load \the [O] into \the [src]'s [equipment_system.cargo_system]!</span>")
else
to_chat(user, "<span class='warning'>You fail to load \the [O] into \the [src]'s [equipment_system.cargo_system]</span>")
else
to_chat(user, "<span class='warning'>\The [src] already has \an [C.storage]</span>")
/obj/spacepod/proc/enter_pod(mob/user)
if (usr.stat != CONSCIOUS)
return 0
if(equipment_system.lock_system && !unlocked)
to_chat(user, "<span class='warning'>\The [src]'s doors are locked!</span>")
return 0
if(get_dist(src, user) > 2 || get_dist(usr, user) > 1)
to_chat(usr, "They are too far away to put inside")
return 0
if(!istype(user))
return 0
var/fukkendisk = user.GetTypeInAllContents(/obj/item/weapon/disk/nuclear)
if(user.incapacitated()) //are you cuffed, dying, lying, stunned or other
return 0
if(!ishuman(user))
return 0
if(fukkendisk)
to_chat(user, "<span class='danger'><B>The nuke-disk is locking the door every time you try to open it. You get the feeling that it doesn't want to go into the spacepod.</b></span>")
return 0
for(var/mob/living/carbon/slime/S in range(1,usr))
if(S.Victim == user)
to_chat(user, "You're too busy getting your life sucked out of you.")
return 0
move_inside(user)
/obj/spacepod/proc/move_inside(mob/user)
if(!istype(user))
log_debug("SHIT'S GONE WRONG WITH THE SPACEPOD [src] AT [x], [y], [z], AREA [get_area(src)], TURF [get_turf(src)]")
occupant_sanity_check()
if(passengers.len <= max_passengers)
visible_message("<span class='notice'>[user] starts to climb into \the [src].</span>")
if(do_after(user, 40, target = src))
if(!pilot || pilot == null)
user.stop_pulling()
pilot = user
user.forceMove(src)
add_fingerprint(user)
playsound(src, 'sound/machines/windowdoor.ogg', 50, 1)
return
if(passengers.len < max_passengers)
user.stop_pulling()
passengers += user
user.forceMove(src)
add_fingerprint(user)
playsound(src, 'sound/machines/windowdoor.ogg', 50, 1)
else
to_chat(user, "<span class='notice'>You were too slow. Try better next time, loser.</span>")
else
to_chat(user, "<span class='notice'>You stop entering \the [src].</span>")
else
to_chat(user, "<span class='danger'>You can't fit in \the [src], it's full!</span>")
/obj/spacepod/proc/occupant_sanity_check() // going to have to adjust this later for cargo refactor
if(passengers)
if(passengers.len > max_passengers)
for(var/i = passengers.len; i <= max_passengers; i--)
var/mob/occupant = passengers[i - 1]
occupant.forceMove(get_turf(src))
log_debug("##SPACEPOD WARNING: passengers EXCEED CAP: MAX passengers [max_passengers], passengers [english_list(passengers)], TURF [get_turf(src)] | AREA [get_area(src)] | COORDS [x], [y], [z]")
passengers[i - 1] = null
for(var/mob/M in passengers)
if(!ismob(M))
M.forceMove(get_turf(src))
log_debug("##SPACEPOD WARNING: NON-MOB OCCUPANT [M], TURF [get_turf(src)] | AREA [get_area(src)] | COORDS [x], [y], [z]")
passengers -= M
else if(M.loc != src)
log_debug("##SPACEPOD WARNING: OCCUPANT [M] ESCAPED, TURF [get_turf(src)] | AREA [get_area(src)] | COORDS [x], [y], [z]")
passengers -= M
/obj/spacepod/verb/exit_pod()
set name = "Exit pod"
set category = "Spacepod"
set src = usr.loc
var/mob/user = usr
if(!istype(user))
return
if (user.stat != CONSCIOUS || user.incapacitated()) // unconscious and restrained people can't let themselves out
return
occupant_sanity_check()
if(user == pilot)
user.forceMove(get_turf(src))
pilot = null
to_chat(user, "<span class='notice'>You climb out of \the [src].</span>")
if(user in passengers)
user.forceMove(get_turf(src))
passengers -= user
to_chat(user, "<span class='notice'>You climb out of \the [src].</span>")
/obj/spacepod/verb/lock_pod()
set name = "Lock Doors"
set category = "Spacepod"
set src = usr.loc
if(usr in passengers && usr != src.pilot)
to_chat(usr, "<span class='notice'>You can't reach the controls from your chair")
return
unlocked = !unlocked
to_chat(usr, "<span class='warning'>You [unlocked ? "unlock" : "lock"] the doors.</span>")
/obj/spacepod/verb/toggleDoors()
set name = "Toggle Nearby Pod Doors"
set category = "Spacepod"
set src = usr.loc
if(usr != src.pilot)
to_chat(usr, "<span class='notice'>You can't reach the controls from your chair")
return
for(var/obj/machinery/door/poddoor/multi_tile/P in orange(3,src))
var/mob/living/carbon/human/L = usr
if(P.check_access(L.get_active_hand()) || P.check_access(L.wear_id))
if(P.density)
P.open()
return 1
else
P.close()
return 1
for(var/mob/living/carbon/human/O in passengers)
if(P.check_access(O.get_active_hand()) || P.check_access(O.wear_id))
if(P.density)
P.open()
return 1
else
P.close()
return 1
to_chat(usr, "<span class='warning'>Access denied.</span>")
return
to_chat(usr, "<span class='warning'>You are not close to any pod doors.</span>")
/obj/spacepod/verb/fireWeapon()
set name = "Fire Pod Weapons"
set desc = "Fire the weapons."
set category = "Spacepod"
set src = usr.loc
if(usr != src.pilot)
to_chat(usr, "<span class='notice'>You can't reach the controls from your chair")
return
if(!equipment_system.weapon_system)
to_chat(usr, "<span class='warning'>\The [src] has no weapons!</span>")
return
equipment_system.weapon_system.fire_weapons()
/obj/spacepod/verb/unload()
set name = "Unload Cargo"
set desc = "Unloads the cargo"
set category = "Spacepod"
set src = usr.loc
if(usr != src.pilot)
to_chat(usr, "<span class='notice'>You can't reach the controls from your chair")
return
if(!equipment_system.cargo_system)
to_chat(usr, "<span class='warning'>\The [src] has no cargo system!</span>")
return
equipment_system.cargo_system.unload()
/obj/spacepod/verb/toggleLights()
set name = "Toggle Lights"
set category = "Spacepod"
set src = usr.loc
if(usr != src.pilot)
to_chat(usr, "<span class='notice'>You can't reach the controls from your chair")
return
lightsToggle()
/obj/spacepod/proc/lightsToggle()
lights = !lights
if(lights)
set_light(lights_power)
else
set_light(0)
to_chat(usr, "Lights toggled [lights ? "on" : "off"].")
for(var/mob/M in passengers)
to_chat(M, "Lights toggled [lights ? "on" : "off"].")
/obj/spacepod/verb/checkSeat()
set name = "Check under Seat"
set category = "Spacepod"
set src = usr.loc
var/mob/user = usr
to_chat(user, "<span class='notice'>You start rooting around under the seat for lost items</span>")
if(do_after(user, 40, target = src))
var/obj/badlist = list(internal_tank, cargo_hold, pilot, battery) + passengers + equipment_system.installed_modules
var/list/true_contents = contents - badlist
if(true_contents.len > 0)
var/obj/I = pick(true_contents)
if(user.put_in_any_hand_if_possible(I))
src.contents -= I
to_chat(user, "<span class='notice'>You find a [I] [pick("under the seat", "under the console", "in the mainenance access")]!</span>")
else
to_chat(user, "<span class='notice'>You think you saw something shiny, but you can't reach it!</span>")
else
to_chat(user, "<span class='notice'>You fail to find anything of value.</span>")
else
to_chat(user, "<span class='notice'>You decide against searching the [src]</span>")
/obj/spacepod/proc/enter_after(delay as num, var/mob/user as mob, var/numticks = 5)
var/delayfraction = delay/numticks
var/turf/T = user.loc
for(var/i = 0, i<numticks, i++)
sleep(delayfraction)
if(!src || !user || !user.canmove || !(user.loc == T))
return 0
return 1
/datum/global_iterator/pod_preserve_temp //normalizing cabin air temperature to 20 degrees celsium
delay = 20
process(var/obj/spacepod/spacepod)
if(spacepod.cabin_air && spacepod.cabin_air.return_volume() > 0)
var/delta = spacepod.cabin_air.temperature - T20C
spacepod.cabin_air.temperature -= max(-10, min(10, round(delta/4,0.1)))
/datum/global_iterator/pod_tank_give_air
delay = 15
/datum/global_iterator/pod_tank_give_air/process(var/obj/spacepod/spacepod)
if(spacepod && spacepod.internal_tank)
var/datum/gas_mixture/tank_air = spacepod.internal_tank.return_air()
var/datum/gas_mixture/cabin_air = spacepod.cabin_air
var/release_pressure = ONE_ATMOSPHERE
var/cabin_pressure = cabin_air.return_pressure()
var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2)
var/transfer_moles = 0
if(pressure_delta > 0) //cabin pressure lower than release pressure
if(tank_air.return_temperature() > 0)
transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = tank_air.remove(transfer_moles)
cabin_air.merge(removed)
else if(pressure_delta < 0) //cabin pressure higher than release pressure
var/datum/gas_mixture/t_air = spacepod.get_turf_air()
pressure_delta = cabin_pressure - release_pressure
if(t_air)
pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta)
if(pressure_delta > 0) //if location pressure is lower than cabin pressure
transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = cabin_air.remove(transfer_moles)
if(t_air)
t_air.merge(removed)
else //just delete the cabin gas, we're in space or some shit
qdel(removed)
else
return stop()
/obj/spacepod/relaymove(mob/user, direction)
if(usr != src.pilot)
return
handlerelaymove(user, direction)
/obj/spacepod/proc/handlerelaymove(mob/user, direction)
if(world.time < next_move)
return 0
var/moveship = 1
if(battery && battery.charge >= 1 && health && empcounter == 0)
src.dir = direction
switch(direction)
if(NORTH)
if(inertia_dir == SOUTH)
inertia_dir = 0
moveship = 0
if(SOUTH)
if(inertia_dir == NORTH)
inertia_dir = 0
moveship = 0
if(EAST)
if(inertia_dir == WEST)
inertia_dir = 0
moveship = 0
if(WEST)
if(inertia_dir == EAST)
inertia_dir = 0
moveship = 0
if(moveship)
Move(get_step(src, direction), direction)
if(equipment_system.cargo_system)
for (var/turf/T in locs)
for (var/obj/item/I in T.contents)
equipment_system.cargo_system.passover(I)
else
if(!battery)
to_chat(user, "<span class='warning'>No energy cell detected.</span>")
else if(battery.charge < 1)
to_chat(user, "<span class='warning'>Not enough charge left.</span>")
else if(!health)
to_chat(user, "<span class='warning'>She's dead, Jim</span>")
else if(empcounter != 0)
to_chat(user, "<span class='warning'>The pod control interface isn't responding. The console indicates [empcounter] seconds before reboot.</span>")
else
to_chat(user, "<span class='warning'>Unknown error has occurred, yell at the coders.</span>")
return 0
battery.charge = max(0, battery.charge - 1)
next_move = world.time + move_delay
/obj/effect/landmark/spacepod/random
name = "spacepod spawner"
invisibility = 101
icon = 'icons/mob/screen_gen.dmi'
icon_state = "x"
anchored = 1
/obj/effect/landmark/spacepod/random/New()
..()
#undef DAMAGE
#undef FIRE