SPACEPODS!
@@ -210,6 +210,8 @@ GLOBAL_LIST_INIT(heavyfootmob, typecacheof(list(
|
||||
|
||||
#define ismecha(A) (istype(A, /obj/mecha))
|
||||
|
||||
#define isspacepod(A) (istype(A, /obj/spacepod)) // yogs
|
||||
|
||||
#define is_cleanable(A) (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/rune)) //if something is cleanable
|
||||
|
||||
#define isorgan(A) (istype(A, /obj/item/organ))
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
|
||||
#define BELOW_MOB_LAYER 3.7
|
||||
#define LYING_MOB_LAYER 3.8
|
||||
#define SPACEPOD_LAYER 3.9 // yogs
|
||||
//#define MOB_LAYER 4 //For easy recordkeeping; this is a byond define
|
||||
#define ABOVE_MOB_LAYER 4.1
|
||||
#define WALL_OBJ_LAYER 4.25
|
||||
|
||||
18
code/__DEFINES/~yogs_defines/spacepods.dm
Normal file
@@ -0,0 +1,18 @@
|
||||
#define SPACEPOD_EMPTY 1
|
||||
#define SPACEPOD_WIRES_LOOSE 2
|
||||
#define SPACEPOD_WIRES_SECURED 3
|
||||
#define SPACEPOD_CIRCUIT_LOOSE 4
|
||||
#define SPACEPOD_CIRCUIT_SECURED 5
|
||||
#define SPACEPOD_CORE_LOOSE 6
|
||||
#define SPACEPOD_CORE_SECURED 7
|
||||
#define SPACEPOD_BULKHEAD_LOOSE 8
|
||||
#define SPACEPOD_BULKHEAD_SECURED 9
|
||||
#define SPACEPOD_BULKHEAD_WELDED 10
|
||||
#define SPACEPOD_ARMOR_LOOSE 11
|
||||
#define SPACEPOD_ARMOR_SECURED 12
|
||||
#define SPACEPOD_ARMOR_WELDED 13
|
||||
|
||||
#define SPACEPOD_SLOT_CARGO "cargo"
|
||||
#define SPACEPOD_SLOT_MISC "misc"
|
||||
#define SPACEPOD_SLOT_WEAPON "weapon"
|
||||
#define SPACEPOD_SLOT_LOCK "lock"
|
||||
@@ -106,5 +106,10 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
|
||||
/obj/item/storage/toolbox/artistic = 2,
|
||||
/obj/item/toy/eightball = 1,
|
||||
/obj/item/reagent_containers/pill/floorpill = 1,
|
||||
// yogs start
|
||||
/obj/item/pod_parts/core = 1,
|
||||
/obj/item/pod_parts/armor = 1,
|
||||
/obj/item/circuitboard/mecha/pod = 1,
|
||||
// yogs end
|
||||
"" = 3
|
||||
))
|
||||
|
||||
@@ -209,11 +209,28 @@
|
||||
direct = get_dir(src, newloc)
|
||||
setDir(direct)
|
||||
|
||||
// yogs start - multi tile object handling
|
||||
if(bound_width != world.icon_size || bound_height != world.icon_size)
|
||||
var/list/newlocs = isturf(newloc) ? block(locate(newloc.x+(-bound_x)/world.icon_size,newloc.y+(-bound_y)/world.icon_size,newloc.z),locate(newloc.x+(-bound_x+bound_width)/world.icon_size-1,newloc.y+(-bound_y+bound_height)/world.icon_size-1,newloc.z)) : list(newloc)
|
||||
if(!newlocs)
|
||||
return // we're trying to cross into the edge of space
|
||||
var/bothturfs = isturf(newloc) && isturf(loc)
|
||||
var/dx = bothturfs ? newloc.x - loc.x : 0
|
||||
var/dy = bothturfs ? newloc.y - loc.y : 0
|
||||
var/dz = bothturfs ? newloc.z - loc.z : 0
|
||||
for(var/atom/A in (locs - newlocs))
|
||||
if(!A.Exit(src, bothturfs ? locate(A.x+dx,A.y+dy,A.z+dz) : newloc))
|
||||
return
|
||||
for(var/atom/A in (newlocs - locs))
|
||||
if(!A.Enter(src, bothturfs ? locate(A.x-dx,A.y-dy,A.z+dz) : loc))
|
||||
return
|
||||
else
|
||||
if(!loc.Exit(src, newloc))
|
||||
return
|
||||
|
||||
if(!newloc.Enter(src, src.loc))
|
||||
return
|
||||
// yogs end
|
||||
|
||||
// Past this is the point of no return
|
||||
var/atom/oldloc = loc
|
||||
|
||||
@@ -2,6 +2,13 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
|
||||
new/datum/stack_recipe("grille", /obj/structure/grille, 2, time = 10, one_per_turf = TRUE, on_floor = FALSE), \
|
||||
new/datum/stack_recipe("table frame", /obj/structure/table_frame, 2, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("scooter frame", /obj/item/scooter_frame, 10, time = 25, one_per_turf = 0), \
|
||||
// yogs start
|
||||
null, \
|
||||
new/datum/stack_recipe("fore port spacepod frame", /obj/item/pod_parts/pod_frame/fore_port, 15, time = 30, one_per_turf = 0), \
|
||||
new/datum/stack_recipe("fore starboard spacepod frame", /obj/item/pod_parts/pod_frame/fore_starboard, 15, time = 30, one_per_turf = 0), \
|
||||
new/datum/stack_recipe("aft port spacepod frame", /obj/item/pod_parts/pod_frame/aft_port, 15, time = 30, one_per_turf = 0), \
|
||||
new/datum/stack_recipe("aft starboard spacepod frame", /obj/item/pod_parts/pod_frame/aft_starboard, 15, time = 30, one_per_turf = 0), \
|
||||
// yogs end
|
||||
))
|
||||
|
||||
/obj/item/stack/rods
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
if(!search_objects)
|
||||
. = hearers(vision_range, targets_from) - src //Remove self, so we don't suicide
|
||||
|
||||
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden))
|
||||
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden, /obj/spacepod)) // yogs - add spacepod
|
||||
|
||||
for(var/HM in typecache_filter_list(range(vision_range, targets_from), hostile_machines))
|
||||
if(can_see(targets_from, HM, vision_range))
|
||||
@@ -563,7 +563,7 @@ mob/living/simple_animal/hostile/proc/DestroySurroundings() // for use with mega
|
||||
toggle_ai(AI_ON)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/ListTargetsLazy(var/_Z)//Step 1, find out what we can see
|
||||
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden))
|
||||
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden, /obj/spacepod)) // yogs - add spacepod
|
||||
. = list()
|
||||
for (var/I in SSmobs.clients_by_zlevel[_Z])
|
||||
var/mob/M = I
|
||||
|
||||
@@ -12,6 +12,12 @@
|
||||
var/obj/mecha/M = A
|
||||
if(M.occupant)
|
||||
return A
|
||||
// yogs start
|
||||
else if(istype(A, /obj/spacepod))
|
||||
var/obj/spacepod/M = A
|
||||
if(M.pilot || M.passengers.len)
|
||||
return A
|
||||
// yogs end
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/ListTargets()
|
||||
if(!enemies.len)
|
||||
|
||||
@@ -342,6 +342,12 @@
|
||||
var/obj/mecha/M = the_target
|
||||
if (M.occupant)
|
||||
return FALSE
|
||||
// yogs start
|
||||
if(isspacepod(the_target))
|
||||
var/obj/spacepod/SP = the_target
|
||||
if(SP.pilot || SP.passengers.len)
|
||||
return FALSE
|
||||
// yogs end
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/handle_fire()
|
||||
|
||||
@@ -247,9 +247,16 @@
|
||||
return TRUE
|
||||
if(firer && !ignore_source_check)
|
||||
var/mob/checking = firer
|
||||
if((A == firer) || (((A in firer.buckled_mobs) || (istype(checking) && (A == checking.buckled))) && (A != original)) || (A == firer.loc && ismecha(A))) //cannot shoot yourself or your mech
|
||||
if((A == firer) || (((A in firer.buckled_mobs) || (istype(checking) && (A == checking.buckled))) && (A != original)) || (A == firer.loc && (ismecha(A) || isspacepod(A)))) //cannot shoot yourself or your mech // yogs - or your spacepod
|
||||
trajectory_ignore_forcemove = TRUE
|
||||
forceMove(get_turf(A))
|
||||
// yogs start - multitile objects
|
||||
var/turf/T = trajectory.return_turf()
|
||||
if(!istype(T))
|
||||
qdel(src)
|
||||
return
|
||||
if(T != loc)
|
||||
forceMove(get_step_towards(src, T))
|
||||
// yogs end
|
||||
trajectory_ignore_forcemove = FALSE
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
"Weapons",
|
||||
"Ammo",
|
||||
"Firing Pins",
|
||||
"Computer Parts"
|
||||
"Computer Parts",
|
||||
"Spacepod Designs" // yogs
|
||||
)
|
||||
production_animation = "protolathe_n"
|
||||
allowed_buildtypes = PROTOLATHE
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
"Subspace Telecomms",
|
||||
"Research Machinery",
|
||||
"Misc. Machinery",
|
||||
"Computer Parts"
|
||||
"Computer Parts",
|
||||
"Spacepod Designs" // yogs
|
||||
)
|
||||
console_link = FALSE
|
||||
production_animation = "protolathe_n"
|
||||
|
||||
@@ -118,6 +118,7 @@
|
||||
#include "code\__DEFINES\~yogs_defines\mentor.dm"
|
||||
#include "code\__DEFINES\~yogs_defines\preferences.dm"
|
||||
#include "code\__DEFINES\~yogs_defines\shuttles.dm"
|
||||
#include "code\__DEFINES\~yogs_defines\spacepods.dm"
|
||||
#include "code\__DEFINES\~yogs_defines\wires.dm"
|
||||
#include "code\__HELPERS\_lists.dm"
|
||||
#include "code\__HELPERS\_logging.dm"
|
||||
@@ -2750,6 +2751,7 @@
|
||||
#include "yogstation\code\_globalvars\configuration.dm"
|
||||
#include "yogstation\code\_globalvars\logging.dm"
|
||||
#include "yogstation\code\_globalvars\lists\mobs.dm"
|
||||
#include "yogstation\code\_onclick\adjacent.dm"
|
||||
#include "yogstation\code\_onclick\click.dm"
|
||||
#include "yogstation\code\_onclick\hud\vampire.dm"
|
||||
#include "yogstation\code\controllers\configuration\entries\general.dm"
|
||||
@@ -2803,6 +2805,8 @@
|
||||
#include "yogstation\code\game\machinery\computer\medical.dm"
|
||||
#include "yogstation\code\game\machinery\computer\Operating.dm"
|
||||
#include "yogstation\code\game\machinery\doors\airlock.dm"
|
||||
#include "yogstation\code\game\machinery\doors\poddoor.dm"
|
||||
#include "yogstation\code\game\machinery\doors\spacepod.dm"
|
||||
#include "yogstation\code\game\machinery\pipe\construction.dm"
|
||||
#include "yogstation\code\game\machinery\telecomms\computers\logbrowser.dm"
|
||||
#include "yogstation\code\game\machinery\telecomms\computers\telemonitor.dm"
|
||||
@@ -2985,9 +2989,17 @@
|
||||
#include "yogstation\code\modules\research\rdconsole.dm"
|
||||
#include "yogstation\code\modules\research\designs\bluespace_designs.dm"
|
||||
#include "yogstation\code\modules\research\designs\comp_board_designs.dm"
|
||||
#include "yogstation\code\modules\research\designs\spacepod_designs.dm"
|
||||
#include "yogstation\code\modules\research\designs\stock_parts_designs.dm"
|
||||
#include "yogstation\code\modules\research\designs\tool_designs.dm"
|
||||
#include "yogstation\code\modules\research\techweb\all_nodes.dm"
|
||||
#include "yogstation\code\modules\shuttle\emergency.dm"
|
||||
#include "yogstation\code\modules\spacepods\construction.dm"
|
||||
#include "yogstation\code\modules\spacepods\equipment.dm"
|
||||
#include "yogstation\code\modules\spacepods\parts.dm"
|
||||
#include "yogstation\code\modules\spacepods\physics.dm"
|
||||
#include "yogstation\code\modules\spacepods\prebuilt.dm"
|
||||
#include "yogstation\code\modules\spacepods\spacepod.dm"
|
||||
#include "yogstation\code\modules\spells\cluwnecurse.dm"
|
||||
#include "yogstation\code\modules\spells\spells.dm"
|
||||
#include "yogstation\code\modules\spells\spell_types\mime.dm"
|
||||
|
||||
70
yogstation/code/_onclick/adjacent.dm
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
Adjacency (to turf):
|
||||
* If you are in the same turf, always true
|
||||
* If you are vertically/horizontally adjacent, ensure there are no border objects
|
||||
* If you are diagonally adjacent, ensure you can pass through at least one of the mutually adjacent square.
|
||||
* Passing through in this case ignores anything with the LETPASSTHROW pass flag, such as tables, racks, and morgue trays.
|
||||
*/
|
||||
/turf/Adjacent(atom/neighbor, atom/target = null, atom/movable/mover = null)
|
||||
if(neighbor == src)
|
||||
return TRUE //don't be retarded!!
|
||||
|
||||
if(istype(neighbor, /atom/movable)) //fml
|
||||
var/atom/movable/AM = neighbor
|
||||
if((AM.bound_width != world.icon_size || AM.bound_height != world.icon_size) && (islist(AM.locs) && AM.locs.len > 1))
|
||||
for(var/turf/T in AM.locs)
|
||||
if(Adjacent(T, target, mover))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
var/turf/T0 = get_turf(neighbor)
|
||||
|
||||
if(T0 == src) //same turf
|
||||
return TRUE
|
||||
|
||||
if(get_dist(src, T0) > 1 || z != T0.z) //too far
|
||||
return FALSE
|
||||
|
||||
// Non diagonal case
|
||||
if(T0.x == x || T0.y == y)
|
||||
// Check for border blockages
|
||||
return T0.ClickCross(get_dir(T0,src), border_only = 1, target_atom = target, mover = mover) && src.ClickCross(get_dir(src,T0), border_only = 1, target_atom = target, mover = mover)
|
||||
|
||||
// Diagonal case
|
||||
var/in_dir = get_dir(T0,src) // eg. northwest (1+8) = 9 (00001001)
|
||||
var/d1 = in_dir&3 // eg. north (1+8)&3 (0000 0011) = 1 (0000 0001)
|
||||
var/d2 = in_dir&12 // eg. west (1+8)&12 (0000 1100) = 8 (0000 1000)
|
||||
|
||||
for(var/d in list(d1,d2))
|
||||
if(!T0.ClickCross(d, border_only = 1, target_atom = target, mover = mover))
|
||||
continue // could not leave T0 in that direction
|
||||
|
||||
var/turf/T1 = get_step(T0,d)
|
||||
if(!T1 || T1.density)
|
||||
continue
|
||||
if(!T1.ClickCross(get_dir(T1,src), border_only = 0, target_atom = target, mover = mover) || !T1.ClickCross(get_dir(T1,T0), border_only = 0, target_atom = target, mover = mover))
|
||||
continue // couldn't enter or couldn't leave T1
|
||||
|
||||
if(!src.ClickCross(get_dir(src,T1), border_only = 1, target_atom = target, mover = mover))
|
||||
continue // could not enter src
|
||||
|
||||
return TRUE // we don't care about our own density
|
||||
|
||||
return FALSE
|
||||
|
||||
/*
|
||||
Adjacency (to anything else):
|
||||
* Must be on a turf
|
||||
*/
|
||||
/atom/movable/Adjacent(var/atom/neighbor)
|
||||
if(neighbor == loc)
|
||||
return TRUE
|
||||
if(!isturf(loc))
|
||||
return FALSE
|
||||
if((islist(locs) && locs.len > 1) && (bound_width != world.icon_size || bound_height != world.icon_size))
|
||||
for(var/turf/T in locs) //this is to handle multi tile objects
|
||||
if(T.Adjacent(neighbor, src, src))
|
||||
return TRUE
|
||||
else if(loc.Adjacent(neighbor,target = neighbor, mover = src))
|
||||
return TRUE
|
||||
return FALSE
|
||||
60
yogstation/code/game/machinery/doors/poddoor.dm
Normal file
@@ -0,0 +1,60 @@
|
||||
/obj/machinery/door/poddoor/multi_tile
|
||||
name = "large pod door"
|
||||
layer = CLOSED_DOOR_LAYER
|
||||
closingLayer = CLOSED_DOOR_LAYER
|
||||
|
||||
/obj/machinery/door/poddoor/multi_tile/New()
|
||||
. = ..()
|
||||
apply_opacity_to_my_turfs(opacity)
|
||||
|
||||
/obj/machinery/door/poddoor/multi_tile/open()
|
||||
if(..())
|
||||
apply_opacity_to_my_turfs(opacity)
|
||||
|
||||
|
||||
/obj/machinery/door/poddoor/multi_tile/close()
|
||||
if(..())
|
||||
apply_opacity_to_my_turfs(opacity)
|
||||
|
||||
/obj/machinery/door/poddoor/multi_tile/Destroy()
|
||||
apply_opacity_to_my_turfs(0)
|
||||
return ..()
|
||||
|
||||
//Multi-tile poddoors don't turn invisible automatically, so we change the opacity of the turfs below instead one by one.
|
||||
/obj/machinery/door/poddoor/multi_tile/proc/apply_opacity_to_my_turfs(var/new_opacity)
|
||||
for(var/turf/T in locs)
|
||||
T.opacity = new_opacity
|
||||
T.has_opaque_atom = new_opacity
|
||||
T.reconsider_lights()
|
||||
T.air_update_turf(1)
|
||||
update_freelook_sight()
|
||||
|
||||
/obj/machinery/door/poddoor/multi_tile/four_tile_ver/
|
||||
icon = 'yogstation/icons/obj/doors/1x4blast_vert.dmi'
|
||||
bound_height = 128
|
||||
dir = NORTH
|
||||
|
||||
/obj/machinery/door/poddoor/multi_tile/three_tile_ver/
|
||||
icon = 'yogstation/icons/obj/doors/1x3blast_vert.dmi'
|
||||
bound_height = 96
|
||||
dir = NORTH
|
||||
|
||||
/obj/machinery/door/poddoor/multi_tile/two_tile_ver/
|
||||
icon = 'yogstation/icons/obj/doors/1x2blast_vert.dmi'
|
||||
bound_height = 64
|
||||
dir = NORTH
|
||||
|
||||
/obj/machinery/door/poddoor/multi_tile/four_tile_hor/
|
||||
icon = 'yogstation/icons/obj/doors/1x4blast_hor.dmi'
|
||||
bound_width = 128
|
||||
dir = EAST
|
||||
|
||||
/obj/machinery/door/poddoor/multi_tile/three_tile_hor/
|
||||
icon = 'yogstation/icons/obj/doors/1x3blast_hor.dmi'
|
||||
bound_width = 96
|
||||
dir = EAST
|
||||
|
||||
/obj/machinery/door/poddoor/multi_tile/two_tile_hor/
|
||||
icon = 'yogstation/icons/obj/doors/1x2blast_hor.dmi'
|
||||
bound_width = 64
|
||||
dir = EAST
|
||||
22
yogstation/code/game/machinery/doors/spacepod.dm
Normal file
@@ -0,0 +1,22 @@
|
||||
/obj/structure/spacepoddoor
|
||||
name = "podlock"
|
||||
desc = "Why it no open!!!"
|
||||
icon = 'yogstation/icons/effects/beam.dmi'
|
||||
icon_state = "n_beam"
|
||||
density = 1
|
||||
anchored = 1
|
||||
var/id = 1.0
|
||||
CanAtmosPass = ATMOS_PASS_NO
|
||||
|
||||
/obj/structure/spacepoddoor/Initialize()
|
||||
..()
|
||||
air_update_turf(1)
|
||||
|
||||
/obj/structure/spacepoddoor/Destroy()
|
||||
air_update_turf(1)
|
||||
return ..()
|
||||
|
||||
/obj/structure/spacepoddoor/CanPass(atom/movable/A, turf/T)
|
||||
if(istype(A, /obj/spacepod))
|
||||
return TRUE
|
||||
return ..()
|
||||
237
yogstation/code/modules/research/designs/spacepod_designs.dm
Normal file
@@ -0,0 +1,237 @@
|
||||
/datum/design/board/spacepod_main
|
||||
name = "Circuit Design (Space Pod Mainboard)"
|
||||
desc = "Allows for the construction of a Space Pod mainboard."
|
||||
id = "spacepod_main"
|
||||
build_path = /obj/item/circuitboard/mecha/pod
|
||||
category = list("Exosuit Modules")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ALL
|
||||
|
||||
/datum/design/pod_core
|
||||
name = "Spacepod Core"
|
||||
desc = "Allows for the construction of a spacepod core system, made up of the engine and life support systems."
|
||||
id = "podcore"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL=5000, MAT_URANIUM=1000, MAT_PLASMA=5000)
|
||||
build_path = /obj/item/pod_parts/core
|
||||
category = list("Spacepod Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ALL
|
||||
|
||||
/datum/design/pod_armor_civ
|
||||
name = "Spacepod Armor (civilian)"
|
||||
desc = "Allows for the construction of spcaepod armor. This is the civilian version."
|
||||
id = "podarmor_civ"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL=15000,MAT_GLASS=5000,MAT_PLASMA=10000)
|
||||
build_path = /obj/item/pod_parts/armor
|
||||
category = list("Spacepod Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ALL
|
||||
|
||||
/datum/design/pod_armor_black
|
||||
name = "Spacepod Armor (dark)"
|
||||
desc = "Allows for the construction of spacepod armor. This is the dark civillian version."
|
||||
id = "podarmor_dark"
|
||||
build_type = PROTOLATHE
|
||||
build_path = /obj/item/pod_parts/armor/black
|
||||
category = list("Spacepod Designs")
|
||||
materials = list(MAT_METAL=15000,MAT_GLASS=5000,MAT_PLASMA=10000)
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ALL
|
||||
|
||||
/datum/design/pod_armor_industrial
|
||||
name = "Spacepod Armor (industrial)"
|
||||
desc = "Allows for the construction of spacepod armor. This is the industrial grade version."
|
||||
id = "podarmor_industiral"
|
||||
build_type = PROTOLATHE
|
||||
build_path = /obj/item/pod_parts/armor/industrial
|
||||
category = list("Spacepod Designs")
|
||||
materials = list(MAT_METAL=15000,MAT_GLASS=5000,MAT_PLASMA=10000,MAT_DIAMOND=5000,MAT_SILVER=7500)
|
||||
departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_ENGINEERING
|
||||
|
||||
/datum/design/pod_armor_sec
|
||||
name = "Spacepod Armor (security)"
|
||||
desc = "Allows for the construction of spacepod armor. This is the security version."
|
||||
id = "podarmor_sec"
|
||||
build_type = PROTOLATHE
|
||||
build_path = /obj/item/pod_parts/armor/security
|
||||
category = list("Spacepod Designs")
|
||||
materials = list(MAT_METAL=15000,MAT_GLASS=5000,MAT_PLASMA=10000,MAT_DIAMOND=5000,MAT_SILVER=7500)
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
|
||||
|
||||
/datum/design/pod_armor_gold
|
||||
name = "Spacepod Armor (golden)"
|
||||
desc = "Allows for the construction of spacepod armor. This is the golden version."
|
||||
id = "podarmor_gold"
|
||||
build_type = PROTOLATHE
|
||||
build_path = /obj/item/pod_parts/armor/gold
|
||||
category = list("Spacepod Designs")
|
||||
materials = list(MAT_METAL=5000,MAT_GLASS=2500,MAT_PLASMA=7500,MAT_GOLD=10000)
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ALL
|
||||
|
||||
//////////////////////////////////////////
|
||||
//////SPACEPOD GUNS///////////////////////
|
||||
//////////////////////////////////////////
|
||||
|
||||
/datum/design/pod_gun_disabler
|
||||
name = "Spacepod Equipment (Disabler)"
|
||||
desc = "Allows for the construction of a spacepod mounted disabler."
|
||||
id = "podgun_disabler"
|
||||
build_type = PROTOLATHE
|
||||
build_path = /obj/item/spacepod_equipment/weaponry/disabler
|
||||
category = list("Spacepod Designs")
|
||||
materials = list(MAT_METAL = 15000)
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
|
||||
|
||||
/datum/design/pod_gun_bdisabler
|
||||
name = "Spacepod Equipment (Burst Disabler)"
|
||||
desc = "Allows for the construction of a spacepod mounted disabler. This is the burst-fire model."
|
||||
id = "podgun_bdisabler"
|
||||
build_type = PROTOLATHE
|
||||
build_path = /obj/item/spacepod_equipment/weaponry/burst_disabler
|
||||
category = list("Spacepod Designs")
|
||||
materials = list(MAT_METAL = 15000,MAT_PLASMA=2000)
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
|
||||
|
||||
/datum/design/pod_gun_laser
|
||||
name = "Spacepod Equipment (Laser)"
|
||||
desc = "Allows for the construction of a spacepod mounted laser."
|
||||
id = "podgun_laser"
|
||||
build_type = PROTOLATHE
|
||||
build_path = /obj/item/spacepod_equipment/weaponry/laser
|
||||
category = list("Spacepod Designs")
|
||||
materials = list(MAT_METAL=10000,MAT_GLASS=5000,MAT_GOLD=1000,MAT_SILVER=2000)
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
|
||||
|
||||
/datum/design/pod_ka_basic
|
||||
name = "Spacepod Equipment (Basic Kinetic Accelerator)"
|
||||
desc = "Allows for the construction of a weak spacepod Kinetic Accelerator"
|
||||
id = "pod_ka_basic"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 10000, MAT_GLASS = 5000, MAT_SILVER = 2000, MAT_URANIUM = 2000)
|
||||
build_path = /obj/item/spacepod_equipment/weaponry/basic_pod_ka
|
||||
category = list("Spacepod Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_CARGO
|
||||
|
||||
/datum/design/pod_ka
|
||||
name = "Spacepod Equipment (Kinetic Accelerator)"
|
||||
desc = "Allows for the construction of a spacepod Kinetic Accelerator."
|
||||
id = "pod_ka"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 10000, MAT_GLASS = 5000, MAT_SILVER = 2000, MAT_GOLD = 2000, MAT_DIAMOND = 2000)
|
||||
build_path = /obj/item/spacepod_equipment/weaponry/pod_ka
|
||||
category = list("Spacepod Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_CARGO
|
||||
|
||||
|
||||
/datum/design/pod_plasma_cutter
|
||||
name = "Spacepod Equipment (Plasma Cutter)"
|
||||
desc = "Allows for the construction of a plasma cutter."
|
||||
id = "pod_plasma_cutter"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 10000, MAT_GLASS = 5000, MAT_SILVER = 2000, MAT_GOLD = 2000, MAT_DIAMOND = 2000)
|
||||
build_path = /obj/item/spacepod_equipment/weaponry/plasma_cutter
|
||||
category = list("Spacepod Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_CARGO
|
||||
|
||||
/datum/design/pod_adv_plasma_cutter
|
||||
name = "Spacepod Equipment (Advanced Plasma cutter)"
|
||||
desc = "Allows for the construction of an advanced plasma cutter."
|
||||
id = "pod_adv_plasma_cutter"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 10000, MAT_GLASS = 5000, MAT_SILVER = 4000, MAT_GOLD = 4000, MAT_DIAMOND = 4000)
|
||||
build_path = /obj/item/spacepod_equipment/weaponry/plasma_cutter/adv
|
||||
category = list("Spacepod Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_CARGO
|
||||
|
||||
//////////////////////////////////////////
|
||||
//////SPACEPOD MISC. ITEMS////////////////
|
||||
//////////////////////////////////////////
|
||||
|
||||
/datum/design/pod_misc_tracker
|
||||
name = "Spacepod Tracking Module"
|
||||
desc = "Allows for the construction of a Space Pod Tracking Module."
|
||||
id = "podmisc_tracker"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL=5000)
|
||||
build_path = /obj/item/spacepod_equipment/tracker
|
||||
category = list("Spacepod Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ALL
|
||||
|
||||
//////////////////////////////////////////
|
||||
//////SPACEPOD CARGO ITEMS////////////////
|
||||
//////////////////////////////////////////
|
||||
|
||||
/datum/design/pod_cargo_ore
|
||||
name = "Spacepod Ore Storage Module"
|
||||
desc = "Allows for the construction of a Space Pod Ore Storage Module."
|
||||
id = "podcargo_ore"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL=20000, MAT_GLASS=2000)
|
||||
build_path = /obj/item/spacepod_equipment/cargo/large/ore
|
||||
category = list("Spacepod Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_CARGO
|
||||
|
||||
/datum/design/pod_cargo_crate
|
||||
name = "Spacepod Crate Storage Module"
|
||||
desc = "Allows the construction of a Space Pod Crate Storage Module."
|
||||
id = "podcargo_crate"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL=25000)
|
||||
build_path = /obj/item/spacepod_equipment/cargo/large
|
||||
category = list("Spacepod Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ALL
|
||||
|
||||
//////////////////////////////////////////
|
||||
//////SPACEPOD SEC CARGO ITEMS////////////
|
||||
//////////////////////////////////////////
|
||||
|
||||
/datum/design/passenger_seat
|
||||
name = "Spacepod Passenger Seat"
|
||||
desc = "Allows the construction of a Space Pod Passenger Seat Module."
|
||||
id = "podcargo_seat"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL=7500, MAT_GLASS=2500)
|
||||
build_path = /obj/item/spacepod_equipment/cargo/chair
|
||||
category = list("Spacepod Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ALL
|
||||
|
||||
/*/datum/design/loot_box
|
||||
name = "Spacepod Loot Storage Module"
|
||||
desc = "Allows the construction of a Space Pod Auxillary Cargo Module."
|
||||
id = "podcargo_lootbox"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL=7500, MAT_GLASS=2500)
|
||||
build_path = /obj/item/spacepod_equipment/cargo/loot_box
|
||||
category = list("Spacepod Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ALL*/
|
||||
|
||||
//////////////////////////////////////////
|
||||
//////SPACEPOD LOCK ITEMS////////////////
|
||||
//////////////////////////////////////////
|
||||
/datum/design/pod_lock_keyed
|
||||
name = "Spacepod Tumbler Lock"
|
||||
desc = "Allows for the construction of a tumbler style podlock."
|
||||
id = "podlock_keyed"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL=4500)
|
||||
build_path = /obj/item/spacepod_equipment/lock/keyed
|
||||
category = list("Spacepod Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ALL
|
||||
|
||||
/datum/design/pod_key
|
||||
name = "Spacepod Tumbler Lock Key"
|
||||
desc = "Allows for the construction of a blank key for a podlock."
|
||||
id = "podkey"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL=500)
|
||||
build_path = /obj/item/spacepod_key
|
||||
category = list("Spacepod Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_ALL
|
||||
|
||||
/datum/design/lockbuster
|
||||
name = "Spacepod Lock Buster"
|
||||
desc = "Allows for the construction of a spacepod lockbuster."
|
||||
id = "pod_lockbuster"
|
||||
build_type = PROTOLATHE
|
||||
build_path = /obj/item/device/lock_buster
|
||||
category = list("Spacepod Designs")
|
||||
materials = list(MAT_METAL = 15000, MAT_DIAMOND=2500) //it IS a drill!
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
|
||||
89
yogstation/code/modules/research/techweb/all_nodes.dm
Normal file
@@ -0,0 +1,89 @@
|
||||
/datum/techweb_node/spacepod_basic
|
||||
id = "spacepod_basic"
|
||||
display_name = "Spacepod Construction"
|
||||
description = "Basic stuff to construct Spacepods. Don't crash your first spacepod into the station, especially while going more than 10 m/s."
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
export_price = 2500
|
||||
prereq_ids = list("base")
|
||||
design_ids = list("podcore", "podarmor_civ", "podarmor_dark", "spacepod_main")
|
||||
|
||||
/datum/techweb_node/spacepod_disabler
|
||||
id = "spacepod_disabler"
|
||||
display_name = "Spacepod Weaponry"
|
||||
description = "For a bit of pew pew space battles"
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500)
|
||||
export_price = 3500
|
||||
prereq_ids = list("spacepod_basic", "weaponry")
|
||||
design_ids = list("podgun_disabler")
|
||||
|
||||
/datum/techweb_node/spacepod_lasers
|
||||
id = "spacepod_lasers"
|
||||
display_name = "Advanced Spacepod Weaponry"
|
||||
description = "For a lot of pew pew space battles. PEW PEW PEW!! Shit, I missed. I need better aim. Whatever."
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5250)
|
||||
export_price = 5250
|
||||
prereq_ids = list("spacepod_disabler", "electronic_weapons")
|
||||
design_ids = list("podgun_laser", "podgun_bdisabler")
|
||||
|
||||
/datum/techweb_node/spacepod_ka
|
||||
id = "spacepod_ka"
|
||||
display_name = "Spacepod Mining Tech"
|
||||
description = "Cutting up asteroids using your spacepods"
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500)
|
||||
export_price = 500
|
||||
prereq_ids = list("basic_mining", "spacepod_disabler")
|
||||
design_ids = list("pod_ka_basic")
|
||||
|
||||
/datum/techweb_node/spacepod_advmining
|
||||
id = "spacepod_aka"
|
||||
display_name = "Advanced Spacepod Mining Tech"
|
||||
description = "Cutting up asteroids using your spacepods.... faster!"
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500)
|
||||
export_price = 3500
|
||||
prereq_ids = list("spacepod_ka", "adv_mining")
|
||||
design_ids = list("pod_ka", "pod_plasma_cutter")
|
||||
|
||||
/datum/techweb_node/spacepod_advplasmacutter
|
||||
id = "spacepod_apc"
|
||||
display_name = "Advanced Spacepod Plasma Cutter"
|
||||
description = "Cutting up asteroids using your spacepods........... FASTERRRRRR!!!!!! Oh shit, that was gibtonite."
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4500)
|
||||
export_price = 4500
|
||||
prereq_ids = list("spacepod_aka", "adv_plasma")
|
||||
design_ids = list("pod_adv_plasma_cutter")
|
||||
|
||||
/datum/techweb_node/spacepod_pseat
|
||||
id = "spacepod_pseat"
|
||||
display_name = "Spacepod Passenger Seat"
|
||||
description = "For bringing along victims as you fly off into the far reaches of space"
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3750)
|
||||
export_price = 3750
|
||||
prereq_ids = list("spacepod_basic", "adv_engi")
|
||||
design_ids = list("podcargo_seat")
|
||||
|
||||
/datum/techweb_node/spacepod_storage
|
||||
id = "spacepod_storage"
|
||||
display_name = "Spacepod Storage"
|
||||
description = "For storing the stuff you find in the far reaches of space"
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4500)
|
||||
export_price = 4500
|
||||
prereq_ids = list("spacepod_pseat", "high_efficiency")
|
||||
design_ids = list("podcargo_lootbox", "podcargo_crate", "podcargo_ore")
|
||||
|
||||
/datum/techweb_node/spacepod_lockbuster
|
||||
id = "spacepod_lockbuster"
|
||||
display_name = "Spacepod Lock Buster"
|
||||
description = "For when someone's being really naughty with a spacepod"
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 8500)
|
||||
export_price = 8500
|
||||
prereq_ids = list("spacepod_lasers", "high_efficiency", "adv_mining")
|
||||
design_ids = list("pod_lockbuster")
|
||||
|
||||
/datum/techweb_node/spacepod_iarmor
|
||||
id = "spacepod_iarmor"
|
||||
display_name = "Advanced Spacepod Armor"
|
||||
description = "Better protection for your precious ride. You'll need it if you plan on engaging in spacepod battles."
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2750)
|
||||
export_price = 2750
|
||||
prereq_ids = list("spacepod_storage", "high_efficiency")
|
||||
design_ids = list("podarmor_industiral", "podarmor_sec", "podarmor_gold")
|
||||
202
yogstation/code/modules/spacepods/construction.dm
Normal file
@@ -0,0 +1,202 @@
|
||||
/obj/spacepod/examine(mob/user)
|
||||
..()
|
||||
switch(construction_state) // more construction states than r-walls!
|
||||
if(SPACEPOD_EMPTY)
|
||||
to_chat(user, "<span class='notice'>The strits holding it together can be <b>cut</b> and i't is missing <i>wires</i>.</span>")
|
||||
if(SPACEPOD_WIRES_LOOSE)
|
||||
to_chat(user, "<span class='notice'>The <b>wires</b> need to be <i>screwed</i> on.</span>")
|
||||
if(SPACEPOD_WIRES_SECURED)
|
||||
to_chat(user, "<span class='notice'>The wires are <b>screwed</b> on and needs a <i>circuit board</i>.</span>")
|
||||
if(SPACEPOD_CIRCUIT_LOOSE)
|
||||
to_chat(user, "<span class='notice'>The circuit board is <b>loosely attached</b> and needs to be <i>screwed</i> on.</span>")
|
||||
if(SPACEPOD_CIRCUIT_SECURED)
|
||||
to_chat(user, "<span class='notice'>The circuit board is <b>screwed</b> on, and there is space for a <i>core</i>.</span>")
|
||||
if(SPACEPOD_CORE_LOOSE)
|
||||
to_chat(user, "<span class='notice'>The core is <b>loosely attached</b> and needs to be <i>bolted</i> on.</span>")
|
||||
if(SPACEPOD_CORE_SECURED)
|
||||
to_chat(user, "<span class='notice'>The core is <b>bolted</b> on and the <i>metal</i> bulkhead can be attached.</span>")
|
||||
if(SPACEPOD_BULKHEAD_LOOSE)
|
||||
to_chat(user, "<span class='notice'>The bulkhead is <b>loosely attached</b> and can be <i>bolted</i> down.</span>")
|
||||
if(SPACEPOD_BULKHEAD_SECURED)
|
||||
to_chat(user, "<span class='notice'>The bulkhead is <b>bolted</b> on but not <i>welded</i> on.</span>")
|
||||
if(SPACEPOD_BULKHEAD_WELDED)
|
||||
to_chat(user, "<span class='notice'>The bulkhead is <b>welded</b> on and <i>armor</i> can be attached.</span>")
|
||||
if(SPACEPOD_ARMOR_LOOSE)
|
||||
to_chat(user, "<span class='notice'>The armor is <b>loosely attached</b> and can be <i>bolted</i> down.</span>")
|
||||
if(SPACEPOD_ARMOR_SECURED)
|
||||
to_chat(user, "<span class='notice'>The armor is <b>bolted</b> on but not <i>welded</i> on.</span>")
|
||||
if(SPACEPOD_ARMOR_WELDED)
|
||||
if(hatch_open)
|
||||
if(cell || internal_tank || equipment.len)
|
||||
to_chat(user, "<span class='notice'>The maintenance hatch is <i>pried</i> and there are parts inside that can be <b>removed</b>.")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The maintenance hatch is <i>pried</i> open and the armor is <b>welded</b> on.</span>")
|
||||
else
|
||||
if(locked)
|
||||
to_chat(user, "<span class='notice'>[src] is <b>locked</b>.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The maintenance hatch is <b>pried</b> closed.")
|
||||
|
||||
/obj/spacepod/proc/handle_spacepod_construction(obj/item/W, mob/living/user)
|
||||
// time for a construction/deconstruction process to rival r-walls
|
||||
var/obj/item/stack/ST = W
|
||||
switch(construction_state)
|
||||
if(SPACEPOD_EMPTY)
|
||||
if(W.tool_behaviour == TOOL_WIRECUTTER)
|
||||
. = TRUE
|
||||
user.visible_message("[user] deconstructs [src].", "You deconstruct [src].")
|
||||
deconstruct(TRUE)
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
. = TRUE
|
||||
if(ST.use(10))
|
||||
user.visible_message("[user] wires [src].", "You wire [src].")
|
||||
construction_state++
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need 10 wires for this!</span>")
|
||||
if(SPACEPOD_WIRES_LOOSE)
|
||||
if(W.tool_behaviour == TOOL_WIRECUTTER)
|
||||
. = TRUE
|
||||
var/obj/item/stack/cable_coil/CC = new
|
||||
CC.amount = 10
|
||||
CC.forceMove(loc)
|
||||
W.play_tool_sound(src)
|
||||
construction_state--
|
||||
user.visible_message("[user] cuts [src]'s wiring.", "You remove [src]'s wiring.")
|
||||
else if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
. = TRUE
|
||||
W.play_tool_sound(src)
|
||||
construction_state++
|
||||
user.visible_message("[user] adjusts the wiring.", "You adjust [src]'s wiring.")
|
||||
if(SPACEPOD_WIRES_SECURED)
|
||||
if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
. = TRUE
|
||||
W.play_tool_sound(src)
|
||||
construction_state--
|
||||
user.visible_message("[user] unclips [src]'s wiring harnesses.", "You unclip [src]'s wiring harnesses.")
|
||||
else if(istype(W, /obj/item/circuitboard/mecha/pod))
|
||||
. = TRUE
|
||||
if(user.temporarilyRemoveItemFromInventory(W))
|
||||
qdel(W)
|
||||
construction_state++
|
||||
user.visible_message("[user] inserts the mainboard into [src].", "You insert the mainboard into [src].")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[W] is stuck to your hand!</span>")
|
||||
if(SPACEPOD_CIRCUIT_LOOSE)
|
||||
if(W.tool_behaviour == TOOL_CROWBAR)
|
||||
. = TRUE
|
||||
W.play_tool_sound(src)
|
||||
construction_state--
|
||||
var/obj/item/circuitboard/mecha/pod/B = new
|
||||
B.forceMove(loc)
|
||||
user.visible_message("[user] pries out the mainboard.", "You pry out the mainboard.")
|
||||
else if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
. = TRUE
|
||||
W.play_tool_sound(src)
|
||||
construction_state++
|
||||
user.visible_message("[user] secures the mainboard.", "You secure the mainboard.")
|
||||
if(SPACEPOD_CIRCUIT_SECURED)
|
||||
if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
. = TRUE
|
||||
W.play_tool_sound(src)
|
||||
construction_state--
|
||||
user.visible_message("[user] unsecures the mainboard.", "You unscrew the mainboard from [src].")
|
||||
else if(istype(W, /obj/item/pod_parts/core))
|
||||
. = TRUE
|
||||
if(user.temporarilyRemoveItemFromInventory(W))
|
||||
qdel(W)
|
||||
construction_state++
|
||||
user.visible_message("[user] inserts the core into [src].", "You carefully insert the core into [src].")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[W] is stuck to your hand!</span>")
|
||||
if(SPACEPOD_CORE_LOOSE)
|
||||
if(W.tool_behaviour == TOOL_CROWBAR)
|
||||
. = TRUE
|
||||
W.play_tool_sound(src)
|
||||
var/obj/item/pod_parts/core/C = new
|
||||
C.forceMove(loc)
|
||||
construction_state--
|
||||
user.visible_message("[user] delicately removes the core from [src] with a crowbar.", "You delicately remove the core from [src] with a crowbar.")
|
||||
else if(W.tool_behaviour == TOOL_WRENCH)
|
||||
. = TRUE
|
||||
W.play_tool_sound(src)
|
||||
construction_state++
|
||||
user.visible_message("[user] secures the core's bolts.", "You secure the core's bolts.")
|
||||
if(SPACEPOD_CORE_SECURED)
|
||||
if(W.tool_behaviour == TOOL_WRENCH)
|
||||
. = TRUE
|
||||
W.play_tool_sound(src)
|
||||
construction_state--
|
||||
user.visible_message("[user] unsecures [src]'s core.", "You unsecure [src]'s core.")
|
||||
else if(istype(W, /obj/item/stack/sheet/metal))
|
||||
. = TRUE
|
||||
if(ST.use(5))
|
||||
user.visible_message("[user] fabricates a pressure bulkhead for [src].", "You frabricate a pressure bulkhead for [src].")
|
||||
construction_state++
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need 5 metal for this!</span>")
|
||||
if(SPACEPOD_BULKHEAD_LOOSE)
|
||||
if(W.tool_behaviour == TOOL_CROWBAR)
|
||||
. = TRUE
|
||||
W.play_tool_sound(src)
|
||||
construction_state--
|
||||
var/obj/item/stack/sheet/metal/five/M = new
|
||||
M.forceMove(loc)
|
||||
user.visible_message("[user] pops [src]'s bulkhead panelling loose.", "You pop [src]'s bulkhead panelling loose.")
|
||||
else if(W.tool_behaviour == TOOL_WRENCH)
|
||||
. = TRUE
|
||||
W.play_tool_sound(src)
|
||||
construction_state++
|
||||
user.visible_message("[user] secures [src]'s bulkhead panelling.", "You secure [src]'s bulkhead panelling.")
|
||||
if(SPACEPOD_BULKHEAD_SECURED)
|
||||
if(W.tool_behaviour == TOOL_WRENCH)
|
||||
. = TRUE
|
||||
W.play_tool_sound(src)
|
||||
construction_state--
|
||||
user.visible_message("[user] unbolts [src]'s bulkhead panelling.", "You unbolt [src]'s bulkhead panelling.")
|
||||
else if(W.tool_behaviour == TOOL_WELDER)
|
||||
. = TRUE
|
||||
if(W.use_tool(src, user, 20, amount=3, volume = 50))
|
||||
construction_state = SPACEPOD_ARMOR_WELDED
|
||||
user.visible_message("[user] seals [src]'s bulkhead panelling with a weld.", "You seal [src]'s bulkhead panelling with a weld.")
|
||||
if(SPACEPOD_BULKHEAD_WELDED)
|
||||
if(W.tool_behaviour == TOOL_WELDER)
|
||||
. = TRUE
|
||||
if(W.use_tool(src, user, 20, amount=3, volume = 50))
|
||||
construction_state = SPACEPOD_BULKHEAD_SECURED
|
||||
user.visible_message("[user] cuts [src]'s bulkhead panelling loose.", "You cut [src]'s bulkhead panelling loose.")
|
||||
if(istype(W, /obj/item/pod_parts/armor))
|
||||
. = TRUE
|
||||
if(user.transferItemToLoc(W, src))
|
||||
add_armor(W)
|
||||
construction_state++
|
||||
user.visible_message("[user] installs [src]'s armor plating.", "You install [src]'s armor plating.")
|
||||
else
|
||||
to_chat(user, "[W] is stuck to your hand!")
|
||||
if(SPACEPOD_ARMOR_LOOSE)
|
||||
if(W.tool_behaviour == TOOL_CROWBAR)
|
||||
. = TRUE
|
||||
if(pod_armor)
|
||||
pod_armor.forceMove(loc)
|
||||
remove_armor()
|
||||
W.play_tool_sound(src)
|
||||
construction_state--
|
||||
user.visible_message("[user] pries off [src]'s armor.", "You pry off [src]'s armor.")
|
||||
if(W.tool_behaviour == TOOL_WRENCH)
|
||||
. = TRUE
|
||||
W.play_tool_sound(src)
|
||||
construction_state++
|
||||
user.visible_message("[user] bolts down [src]'s armor.", "You bolt down [src]'s armor.")
|
||||
if(SPACEPOD_ARMOR_SECURED)
|
||||
if(W.tool_behaviour == TOOL_WRENCH)
|
||||
. = TRUE
|
||||
W.play_tool_sound(src)
|
||||
construction_state--
|
||||
user.visible_message("[user] unsecures [src]'s armor.", "You unsecure [src]'s armor.")
|
||||
else if(W.tool_behaviour == TOOL_WELDER)
|
||||
. = TRUE
|
||||
if(W.use_tool(src, user, 50, amount=3, volume = 50))
|
||||
construction_state = SPACEPOD_ARMOR_WELDED
|
||||
user.visible_message("[user] welds [src]'s armor.", "You weld [src]'s armor.")
|
||||
// finally this took too fucking long
|
||||
// somehow this takes up 40 lines less code than the original, code-less version. And it actually works
|
||||
update_icon()
|
||||
349
yogstation/code/modules/spacepods/equipment.dm
Normal file
@@ -0,0 +1,349 @@
|
||||
/obj/item/spacepod_equipment
|
||||
var/obj/spacepod/spacepod
|
||||
icon = 'yogstation/icons/obj/spacepods/parts.dmi'
|
||||
var/slot = SPACEPOD_SLOT_MISC
|
||||
var/slot_space = 1
|
||||
|
||||
/obj/item/spacepod_equipment/proc/on_install(obj/spacepod/SP)
|
||||
spacepod = SP
|
||||
SP.equipment |= src
|
||||
forceMove(SP)
|
||||
|
||||
/obj/item/spacepod_equipment/proc/on_uninstall()
|
||||
spacepod.equipment -= src
|
||||
|
||||
/obj/item/spacepod_equipment/proc/can_install(obj/spacepod/SP, mob/user)
|
||||
var/room = SP.equipment_slot_limits[slot] || 0
|
||||
for(var/obj/item/spacepod_equipment/EQ in SP.equipment)
|
||||
if(EQ.slot == slot)
|
||||
room -= EQ.slot_space
|
||||
if(room < slot_space)
|
||||
to_chat(user, "<span class='warning'>There's no room for another [slot] system!</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/spacepod_equipment/proc/can_uninstall(mob/user)
|
||||
return TRUE
|
||||
|
||||
/obj/item/spacepod_equipment/weaponry
|
||||
slot = SPACEPOD_SLOT_WEAPON
|
||||
var/projectile_type
|
||||
var/shot_cost = 0
|
||||
var/shots_per = 1
|
||||
var/fire_sound
|
||||
var/fire_delay = 15
|
||||
var/overlay_icon
|
||||
var/overlay_icon_state
|
||||
|
||||
/obj/item/spacepod_equipment/weaponry/on_install(obj/spacepod/SP)
|
||||
. = ..()
|
||||
SP.weapon = src
|
||||
SP.update_icon()
|
||||
|
||||
/obj/item/spacepod_equipment/weaponry/on_uninstall()
|
||||
. = ..()
|
||||
if(spacepod.weapon == src)
|
||||
spacepod.weapon = null
|
||||
|
||||
/obj/item/spacepod_equipment/weaponry/proc/fire_weapons(target)
|
||||
if(spacepod.next_firetime > world.time)
|
||||
to_chat(usr, "<span class='warning'>Your weapons are recharging.</span>")
|
||||
playsound(src, 'sound/weapons/gun_dry_fire.ogg', 30, TRUE)
|
||||
return
|
||||
spacepod.next_firetime = world.time + fire_delay
|
||||
if(!spacepod.cell || !spacepod.cell.use(shot_cost))
|
||||
to_chat(usr, "<span class='warning'>Insufficient charge to fire the weapons</span>")
|
||||
playsound(src, 'sound/weapons/gun_dry_fire.ogg', 30, TRUE)
|
||||
return
|
||||
for(var/I in 1 to shots_per)
|
||||
spacepod.fire_projectiles(projectile_type, target)
|
||||
playsound(src, fire_sound, 50, TRUE)
|
||||
sleep(2)
|
||||
|
||||
/*
|
||||
///////////////////////////////////////
|
||||
/////////Cargo System//////////////////
|
||||
///////////////////////////////////////
|
||||
*/
|
||||
|
||||
/obj/item/spacepod_equipment/cargo // this one holds large crates and shit
|
||||
name = "pod cargo"
|
||||
desc = "You shouldn't be seeing this"
|
||||
icon_state = "cargo_blank"
|
||||
slot = SPACEPOD_SLOT_CARGO
|
||||
|
||||
/obj/item/spacepod_equipment/cargo/large
|
||||
name = "spacepod crate storage system"
|
||||
desc = "A heavy duty storage system for spacepods. Holds one crate."
|
||||
icon_state = "cargo_crate"
|
||||
var/obj/storage = null
|
||||
var/storage_type = /obj/structure/closet/crate
|
||||
|
||||
/obj/item/spacepod_equipment/cargo/large/on_install(obj/spacepod/SP)
|
||||
..()
|
||||
// COMSIG - a way to make component signals sound more important than they actually are.
|
||||
// it's not even limited to components. Does this look like a component to you?
|
||||
// Okay here's a better name: It's a fucking *event handler*. Like the ones in javascript.
|
||||
// a much more descriptive and less scary name than fucking "COMSIG". But noooooooooo
|
||||
// the TG coders were too self important to pick a descriptive name and wanted to sound all scientific
|
||||
RegisterSignal(SP, COMSIG_MOUSEDROPPED_ONTO, .proc/spacepod_mousedrop)
|
||||
|
||||
/obj/item/spacepod_equipment/cargo/large/on_uninstall()
|
||||
UnregisterSignal(spacepod, COMSIG_MOUSEDROPPED_ONTO)
|
||||
..()
|
||||
|
||||
/obj/item/spacepod_equipment/cargo/large/can_uninstall(mob/user)
|
||||
if(storage)
|
||||
to_chat(user, "<span class='warning'>Unload the cargo first!</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/spacepod_equipment/cargo/large/proc/spacepod_mousedrop(obj/spacepod/SP, obj/A, mob/user)
|
||||
if(user == SP.pilot || user in SP.passengers)
|
||||
return FALSE
|
||||
if(istype(A, storage_type) && SP.Adjacent(A)) // For loading ore boxes
|
||||
if(!storage)
|
||||
to_chat(user, "<span class='notice'>You begin loading [A] into [SP]'s [src]</span>")
|
||||
if(do_after_mob(user, list(A, SP), 40))
|
||||
storage = A
|
||||
A.forceMove(src)
|
||||
to_chat(user, "<span class='notice'>You load [A] into [SP]'s [src]!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You fail to load [A] into [SP]'s [src]</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[SP] already has \an [storage]</span>")
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/spacepod_equipment/cargo/large/ore
|
||||
name = "spacepod ore storage system"
|
||||
desc = "An ore storage system for spacepods. Scoops up any ore you drive over. Needs to be loaded with an ore box to work"
|
||||
icon_state = "cargo_ore"
|
||||
storage_type = /obj/structure/ore_box
|
||||
|
||||
/obj/item/spacepod_equipment/cargo/large/ore/on_install(obj/spacepod/SP)
|
||||
..()
|
||||
RegisterSignal(SP, COMSIG_MOVABLE_MOVED, .proc/spacepod_moved)
|
||||
|
||||
/obj/item/spacepod_equipment/cargo/large/ore/on_uninstall()
|
||||
UnregisterSignal(spacepod, COMSIG_MOVABLE_MOVED)
|
||||
..()
|
||||
|
||||
/obj/item/spacepod_equipment/cargo/large/ore/proc/spacepod_moved(obj/spacepod/SP)
|
||||
if(storage)
|
||||
for(var/turf/T in SP.locs)
|
||||
for(var/obj/item/stack/ore in T)
|
||||
ore.forceMove(storage)
|
||||
|
||||
/obj/item/spacepod_equipment/cargo/chair
|
||||
name = "passenger seat"
|
||||
desc = "A passenger seat for a spacepod."
|
||||
icon_state = "sec_cargo_chair"
|
||||
var/occupant_mod = 1
|
||||
|
||||
/obj/item/spacepod_equipment/cargo/chair/on_install(obj/spacepod/SP)
|
||||
..()
|
||||
SP.max_passengers += occupant_mod
|
||||
|
||||
/obj/item/spacepod_equipment/cargo/chair/on_uninstall()
|
||||
spacepod.max_passengers -= occupant_mod
|
||||
..()
|
||||
|
||||
/obj/item/spacepod_equipment/cargo/chair/can_uninstall(mob/user)
|
||||
if(spacepod.passengers.len > (spacepod.max_passengers - occupant_mod))
|
||||
to_chat(user, "<span class='warning'>You can't remove an occupied seat! Remove the occupant first.</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/*
|
||||
///////////////////////////////////////
|
||||
/////////Weapon System///////////////////
|
||||
///////////////////////////////////////
|
||||
*/
|
||||
|
||||
/obj/item/spacepod_equipment/weaponry/disabler
|
||||
name = "disabler system"
|
||||
desc = "A weak disabler 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/taser2.ogg'
|
||||
overlay_icon = 'yogstation/icons/obj/spacepods/2x2.dmi'
|
||||
overlay_icon_state = "pod_weapon_disabler"
|
||||
|
||||
/obj/item/spacepod_equipment/weaponry/burst_disabler
|
||||
name = "burst disabler system"
|
||||
desc = "A weak disabler 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/taser2.ogg'
|
||||
fire_delay = 30
|
||||
overlay_icon = 'yogstation/icons/obj/spacepods/2x2.dmi'
|
||||
overlay_icon_state = "pod_weapon_disabler"
|
||||
|
||||
/obj/item/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'
|
||||
overlay_icon = 'yogstation/icons/obj/spacepods/2x2.dmi'
|
||||
overlay_icon_state = "pod_weapon_laser"
|
||||
|
||||
// MINING LASERS
|
||||
/obj/item/spacepod_equipment/weaponry/basic_pod_ka
|
||||
name = "weak kinetic accelerator"
|
||||
desc = "A weak kinetic accelerator for space pods, fires bursts of energy that cut through rock."
|
||||
icon = 'yogstation/goon/icons/obj/spacepods/parts.dmi'
|
||||
icon_state = "pod_taser"
|
||||
projectile_type = /obj/item/projectile/kinetic/pod
|
||||
shot_cost = 300
|
||||
fire_delay = 14
|
||||
fire_sound = 'sound/weapons/Kenetic_accel.ogg'
|
||||
|
||||
/obj/item/spacepod_equipment/weaponry/pod_ka
|
||||
name = "kinetic accelerator system"
|
||||
desc = "A kinetic accelerator system for space pods, fires bursts of energy that cut through rock."
|
||||
icon = 'yogstation/goon/icons/obj/spacepods/parts.dmi'
|
||||
icon_state = "pod_m_laser"
|
||||
projectile_type = /obj/item/projectile/kinetic/pod/regular
|
||||
shot_cost = 250
|
||||
fire_delay = 10
|
||||
fire_sound = 'sound/weapons/Kenetic_accel.ogg'
|
||||
|
||||
/obj/item/projectile/kinetic/pod
|
||||
range = 4
|
||||
|
||||
/obj/item/projectile/kinetic/pod/regular
|
||||
damage = 50
|
||||
pressure_decrease = 0.5
|
||||
|
||||
/obj/item/spacepod_equipment/weaponry/plasma_cutter
|
||||
name = "plasma cutter system"
|
||||
desc = "A plasma cutter system for space pods. It is capable of expelling concentrated plasma bursts to mine or cut off xeno limbs!"
|
||||
icon = 'yogstation/goon/icons/obj/spacepods/parts.dmi'
|
||||
icon_state = "pod_p_cutter"
|
||||
projectile_type = /obj/item/projectile/plasma
|
||||
shot_cost = 250
|
||||
fire_delay = 10
|
||||
fire_sound = 'sound/weapons/plasma_cutter.ogg'
|
||||
overlay_icon = 'yogstation/icons/obj/spacepods/2x2.dmi'
|
||||
overlay_icon_state = "pod_weapon_plasma"
|
||||
|
||||
/obj/item/spacepod_equipment/weaponry/plasma_cutter/adv
|
||||
name = "enhanced plasma cutter system"
|
||||
desc = "An enhanced plasma cutter system for space pods. It is capable of expelling concentrated plasma bursts to mine or cut off xeno faces!"
|
||||
icon_state = "pod_ap_cutter"
|
||||
projectile_type = /obj/item/projectile/plasma/adv
|
||||
shot_cost = 200
|
||||
fire_delay = 8
|
||||
|
||||
/*
|
||||
///////////////////////////////////////
|
||||
/////////Misc. System///////////////////
|
||||
///////////////////////////////////////
|
||||
*/
|
||||
|
||||
/obj/item/spacepod_equipment/tracker
|
||||
name = "spacepod tracking system"
|
||||
desc = "A tracking device for spacepods."
|
||||
icon = 'yogstation/goon/icons/obj/spacepods/parts.dmi'
|
||||
icon_state = "pod_locator"
|
||||
|
||||
/*
|
||||
///////////////////////////////////////
|
||||
/////////Lock System///////////////////
|
||||
///////////////////////////////////////
|
||||
*/
|
||||
|
||||
/obj/item/spacepod_equipment/lock
|
||||
name = "pod lock"
|
||||
desc = "You shouldn't be seeing this"
|
||||
icon_state = "blank"
|
||||
slot = SPACEPOD_SLOT_LOCK
|
||||
|
||||
/obj/item/spacepod_equipment/lock/on_install(obj/spacepod/SP)
|
||||
..()
|
||||
RegisterSignal(SP, COMSIG_PARENT_ATTACKBY, .proc/spacepod_attackby)
|
||||
SP.lock = src
|
||||
|
||||
/obj/item/spacepod_equipment/lock/on_uninstall()
|
||||
UnregisterSignal(spacepod, COMSIG_PARENT_ATTACKBY)
|
||||
if(spacepod.lock == src)
|
||||
spacepod.lock = null
|
||||
spacepod.locked = FALSE
|
||||
..()
|
||||
|
||||
/obj/item/spacepod_equipment/lock/proc/spacepod_attackby(obj/spacepod/SP, I, mob/user)
|
||||
return FALSE
|
||||
|
||||
// Key and Tumbler System
|
||||
/obj/item/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
|
||||
var/id = null
|
||||
|
||||
/obj/item/spacepod_equipment/lock/keyed/Initialize()
|
||||
. = ..()
|
||||
if(id == null)
|
||||
id = ++id_source
|
||||
|
||||
|
||||
/obj/item/spacepod_equipment/lock/keyed/spacepod_attackby(obj/spacepod/SP, obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/spacepod_key))
|
||||
var/obj/item/spacepod_key/key = I
|
||||
if(key.id == id)
|
||||
SP.lock_pod()
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>This is the wrong key!</span>")
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/spacepod_equipment/lock/keyed/attackby(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/spacepod_key))
|
||||
var/obj/item/spacepod_key/key = I
|
||||
if(key.id == null)
|
||||
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
|
||||
..()
|
||||
|
||||
/obj/item/spacepod_equipment/lock/keyed/sec
|
||||
id = "security spacepod"
|
||||
|
||||
// The key
|
||||
/obj/item/spacepod_key
|
||||
name = "spacepod key"
|
||||
desc = "A key for a spacepod lock."
|
||||
icon = 'yogstation/icons/obj/spacepods/parts.dmi'
|
||||
icon_state = "podkey"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/id = null
|
||||
|
||||
/obj/item/spacepod_key/sec
|
||||
name = "security spacepod key"
|
||||
desc = "Unlocks the security spacepod. Probably best kept out of assistant hands."
|
||||
id = "security spacepod"
|
||||
|
||||
/obj/item/device/lock_buster
|
||||
name = "pod lock buster"
|
||||
desc = "Destroys a podlock in mere seconds once applied. Waranty void if used."
|
||||
icon = 'yogstation/icons/obj/spacepods/parts.dmi'
|
||||
icon_state = "lock_buster_off"
|
||||
var/on = FALSE
|
||||
|
||||
/obj/item/device/lock_buster/attack_self(mob/user)
|
||||
on = !on
|
||||
if(on)
|
||||
icon_state = "lock_buster_on"
|
||||
else
|
||||
icon_state = "lock_buster_off"
|
||||
to_chat(user, "<span class='notice'>You turn the [src] [on ? "on" : "off"].</span>")
|
||||
168
yogstation/code/modules/spacepods/parts.dm
Normal file
@@ -0,0 +1,168 @@
|
||||
/obj/item/pod_parts
|
||||
icon = 'yogstation/goon/icons/obj/spacepods/parts.dmi'
|
||||
w_class = WEIGHT_CLASS_GIGANTIC
|
||||
flags_1 = CONDUCT_1
|
||||
|
||||
/obj/item/pod_parts/core
|
||||
name = "space pod core"
|
||||
icon_state = "core"
|
||||
|
||||
/obj/item/pod_parts/pod_frame
|
||||
name = "space pod frame"
|
||||
density = 0
|
||||
anchored = 0
|
||||
var/link_to = null
|
||||
var/link_angle = 0
|
||||
|
||||
/obj/item/pod_parts/pod_frame/ComponentInitialize()
|
||||
AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE)
|
||||
|
||||
/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/list/connectedparts = list()
|
||||
neededparts -= 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
|
||||
if(istype(pointer, linked.link_to) && pointer.dir == linked.dir && pointer.anchored)
|
||||
if(!(pointer in connectedparts))
|
||||
connectedparts += pointer
|
||||
linked = pointer
|
||||
pointer = null
|
||||
if(connectedparts.len < 4)
|
||||
return 0
|
||||
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
|
||||
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/item/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='warning'>You cannot assemble a pod frame because you do not have the necessary assembly.</span>")
|
||||
return TRUE
|
||||
if(!R.use(10))
|
||||
to_chat(user, "<span class='warning'>You need 10 rods for this.</span>")
|
||||
return TRUE
|
||||
var/obj/spacepod/pod = new
|
||||
pod.forceMove(loc)
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
pod.angle = 0
|
||||
if(SOUTH)
|
||||
pod.angle = 180
|
||||
if(WEST)
|
||||
pod.angle = 270
|
||||
if(EAST)
|
||||
pod.angle = 90
|
||||
pod.process(2)
|
||||
to_chat(user, "<span class='notice'>You strut the pod frame together.</span>")
|
||||
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
|
||||
pod.forceMove(F.loc)
|
||||
qdel(F)
|
||||
return TRUE
|
||||
if(O.tool_behaviour == TOOL_WRENCH)
|
||||
to_chat(user, "<span class='notice'>You [!anchored ? "secure \the [src] in place." : "remove the securing bolts."]</span>")
|
||||
anchored = !anchored
|
||||
density = anchored
|
||||
O.play_tool_sound(src)
|
||||
return TRUE
|
||||
|
||||
/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_state = "pod_armor_civ"
|
||||
desc = "Spacepod armor. This is the civilian version. It looks rather flimsy."
|
||||
var/pod_icon = 'yogstation/goon/icons/obj/spacepods/2x2.dmi'
|
||||
var/pod_icon_state = "pod_civ"
|
||||
var/pod_desc = "A sleek civilian space pod."
|
||||
var/pod_integrity = 250
|
||||
|
||||
/obj/item/pod_parts/armor/syndicate
|
||||
name = "syndicate pod armor"
|
||||
icon_state = "pod_armor_synd"
|
||||
desc = "Tough-looking spacepod armor, with a bold \"FUCK NT\" stenciled directly into it."
|
||||
pod_icon_state = "pod_synd"
|
||||
pod_desc = "A menacing military space pod with \"FUCK NT\" stenciled onto the side"
|
||||
pod_integrity = 400
|
||||
|
||||
/obj/item/pod_parts/armor/black
|
||||
name = "black pod armor"
|
||||
icon_state = "pod_armor_black"
|
||||
desc = "Plain black spacepod armor, with no logos or insignias anywhere on it."
|
||||
pod_icon_state = "pod_black"
|
||||
pod_desc = "An all black space pod with no insignias."
|
||||
|
||||
/obj/item/pod_parts/armor/gold
|
||||
name = "golden pod armor"
|
||||
icon_state = "pod_armor_gold"
|
||||
desc = "Golden spacepod armor. Looks like what a rich spessmen put on their spacepod."
|
||||
pod_icon_state = "pod_gold"
|
||||
pod_desc = "A civilian space pod with a gold body, must have cost somebody a pretty penny"
|
||||
pod_integrity = 220
|
||||
|
||||
/obj/item/pod_parts/armor/industrial
|
||||
name = "industrial pod armor"
|
||||
icon_state = "pod_armor_industrial"
|
||||
desc = "Tough industrial-grade spacepod armor. While meant for construction work, it is commonly used in spacepod battles, too."
|
||||
pod_icon_state = "pod_industrial"
|
||||
pod_desc = "A rough looking space pod meant for industrial work"
|
||||
pod_integrity = 330
|
||||
|
||||
/obj/item/pod_parts/armor/security
|
||||
name = "security pod armor"
|
||||
icon_state = "pod_armor_mil"
|
||||
desc = "Tough military-grade pod armor, meant for use by the NanoTrasen military and it's sub-divisons for space combat."
|
||||
pod_icon_state = "pod_mil"
|
||||
pod_desc = "An armed security spacepod with reinforced armor plating brandishing the Nanotrasen Military insignia"
|
||||
pod_integrity = 350
|
||||
|
||||
/obj/item/circuitboard/mecha/pod
|
||||
name = "Circuit board (Space Pod Mainboard)"
|
||||
icon_state = "mainboard"
|
||||
295
yogstation/code/modules/spacepods/physics.dm
Normal file
@@ -0,0 +1,295 @@
|
||||
/obj/spacepod/process(time)
|
||||
time /= 10 // fuck off with your deciseconds
|
||||
|
||||
if(world.time > last_slowprocess + 15)
|
||||
last_slowprocess = world.time
|
||||
slowprocess()
|
||||
|
||||
var/last_offset_x = offset_x
|
||||
var/last_offset_y = offset_y
|
||||
var/last_angle = angle
|
||||
var/desired_angular_velocity = 0
|
||||
if(isnum(desired_angle))
|
||||
// do some finagling to make sure that our angles end up rotating the short way
|
||||
while(angle > desired_angle + 180)
|
||||
angle -= 360
|
||||
last_angle -= 360
|
||||
while(angle < desired_angle - 180)
|
||||
angle += 360
|
||||
last_angle += 360
|
||||
if(abs(desired_angle - angle) < (max_angular_acceleration * time))
|
||||
desired_angular_velocity = (desired_angle - angle) / time
|
||||
else if(desired_angle > angle)
|
||||
desired_angular_velocity = 2 * sqrt((desired_angle - angle) * max_angular_acceleration * 0.25)
|
||||
else
|
||||
desired_angular_velocity = -2 * sqrt((angle - desired_angle) * max_angular_acceleration * 0.25)
|
||||
var/angular_velocity_adjustment = CLAMP(desired_angular_velocity - angular_velocity, -max_angular_acceleration*time, max_angular_acceleration*time)
|
||||
if(angular_velocity_adjustment && cell && cell.use(abs(angular_velocity_adjustment) * 0.05))
|
||||
last_rotate = angular_velocity_adjustment / time
|
||||
angular_velocity += angular_velocity_adjustment
|
||||
else
|
||||
last_rotate = 0
|
||||
angle += angular_velocity * time
|
||||
|
||||
// calculate drag and shit
|
||||
|
||||
var/velocity_mag = sqrt(velocity_x*velocity_x+velocity_y*velocity_y) // magnitude
|
||||
if(velocity_mag || angular_velocity != 0)
|
||||
var/drag = 0
|
||||
for(var/turf/T in locs)
|
||||
if(isspaceturf(T))
|
||||
continue
|
||||
drag += 0.001
|
||||
var/floating = FALSE
|
||||
if(T.has_gravity() && !brakes && velocity_mag > 0.1 && cell && cell.use((is_mining_level(z) ? 3 : 15) * time))
|
||||
floating = TRUE // want to fly this shit on the station? Have fun draining your battery.
|
||||
if((!floating && T.has_gravity()) || brakes) // brakes are a kind of magboots okay?
|
||||
drag += is_mining_level(z) ? 0.1 : 0.5 // some serious drag. Damn. Except lavaland, it has less gravity or something
|
||||
if(velocity_mag > 5 && prob(velocity_mag * 4) && istype(T, /turf/open/floor))
|
||||
var/turf/open/floor/TF = T
|
||||
TF.make_plating() // pull up some floor tiles. Stop going so fast, ree.
|
||||
var/datum/gas_mixture/env = T.return_air()
|
||||
if(env)
|
||||
var/pressure = env.return_pressure()
|
||||
drag += velocity_mag * pressure * 0.0001 // 1 atmosphere should shave off 1% of velocity per tile
|
||||
if(velocity_mag > 20)
|
||||
drag = max(drag, (velocity_mag - 20) / time)
|
||||
if(drag)
|
||||
if(velocity_mag)
|
||||
var/drag_factor = 1 - CLAMP(drag * time / velocity_mag, 0, 1)
|
||||
velocity_x *= drag_factor
|
||||
velocity_y *= drag_factor
|
||||
if(angular_velocity != 0)
|
||||
var/drag_factor_spin = 1 - CLAMP(drag * 30 * time / abs(angular_velocity), 0, 1)
|
||||
angular_velocity *= drag_factor_spin
|
||||
|
||||
// Alright now calculate the THRUST
|
||||
var/thrust_x
|
||||
var/thrust_y
|
||||
var/fx = cos(90 - angle)
|
||||
var/fy = sin(90 - angle)
|
||||
var/sx = fy
|
||||
var/sy = -fx
|
||||
last_thrust_forward = 0
|
||||
last_thrust_right = 0
|
||||
if(brakes)
|
||||
if(user_thrust_dir)
|
||||
to_chat(pilot, "<span class='warning'>Your brakes are on!</span>")
|
||||
// basically calculates how much we can brake using the thrust
|
||||
var/forward_thrust = -((fx * velocity_x) + (fy * velocity_y)) / time
|
||||
var/right_thrust = -((sx * velocity_x) + (sy * velocity_y)) / time
|
||||
forward_thrust = CLAMP(forward_thrust, -backward_maxthrust, forward_maxthrust)
|
||||
right_thrust = CLAMP(right_thrust, -side_maxthrust, side_maxthrust)
|
||||
thrust_x += forward_thrust * fx + right_thrust * sx;
|
||||
thrust_y += forward_thrust * fy + right_thrust * sy;
|
||||
last_thrust_forward = forward_thrust
|
||||
last_thrust_right = right_thrust
|
||||
else // want some sort of help piloting the ship? Haha no fuck you do it yourself
|
||||
if(user_thrust_dir & NORTH)
|
||||
thrust_x += fx * forward_maxthrust
|
||||
thrust_y += fy * forward_maxthrust
|
||||
last_thrust_forward = forward_maxthrust
|
||||
if(user_thrust_dir & SOUTH)
|
||||
thrust_x -= fx * backward_maxthrust
|
||||
thrust_y -= fy * backward_maxthrust
|
||||
last_thrust_forward = -backward_maxthrust
|
||||
if(user_thrust_dir & EAST)
|
||||
thrust_x += sx * side_maxthrust
|
||||
thrust_y += sy * side_maxthrust
|
||||
last_thrust_right = side_maxthrust
|
||||
if(user_thrust_dir & WEST)
|
||||
thrust_x -= sx * side_maxthrust
|
||||
thrust_y -= sy * side_maxthrust
|
||||
last_thrust_right = -side_maxthrust
|
||||
|
||||
if(cell && cell.use(10 * sqrt((thrust_x*thrust_x)+(thrust_y*thrust_y)) * time))
|
||||
velocity_x += thrust_x * time
|
||||
velocity_y += thrust_y * time
|
||||
else
|
||||
last_thrust_forward = 0
|
||||
last_thrust_right = 0
|
||||
if(!brakes && user_thrust_dir)
|
||||
to_chat(pilot, "<span class='warning'>You are out of power!</span>")
|
||||
|
||||
offset_x += velocity_x * time
|
||||
offset_y += velocity_y * time
|
||||
// alright so now we reconcile the offsets with the in-world position.
|
||||
while((offset_x > 0 && velocity_x > 0) || (offset_y > 0 && velocity_y > 0) || (offset_x < 0 && velocity_x < 0) || (offset_y < 0 && velocity_y < 0))
|
||||
var/failed_x = FALSE
|
||||
var/failed_y = FALSE
|
||||
if(offset_x > 0 && velocity_x > 0)
|
||||
dir = EAST
|
||||
if(!Move(get_step(src, EAST)))
|
||||
offset_x = 0
|
||||
failed_x = TRUE
|
||||
velocity_x *= -bounce_factor
|
||||
velocity_y *= lateral_bounce_factor
|
||||
else
|
||||
offset_x--
|
||||
last_offset_x--
|
||||
else if(offset_x < 0 && velocity_x < 0)
|
||||
dir = WEST
|
||||
if(!Move(get_step(src, WEST)))
|
||||
offset_x = 0
|
||||
failed_x = TRUE
|
||||
velocity_x *= -bounce_factor
|
||||
velocity_y *= lateral_bounce_factor
|
||||
else
|
||||
offset_x++
|
||||
last_offset_x++
|
||||
else
|
||||
failed_x = TRUE
|
||||
if(offset_y > 0 && velocity_y > 0)
|
||||
dir = NORTH
|
||||
if(!Move(get_step(src, NORTH)))
|
||||
offset_y = 0
|
||||
failed_y = TRUE
|
||||
velocity_y *= -bounce_factor
|
||||
velocity_x *= lateral_bounce_factor
|
||||
else
|
||||
offset_y--
|
||||
last_offset_y--
|
||||
else if(offset_y < 0 && velocity_y < 0)
|
||||
dir = SOUTH
|
||||
if(!Move(get_step(src, SOUTH)))
|
||||
offset_y = 0
|
||||
failed_y = TRUE
|
||||
velocity_y *= -bounce_factor
|
||||
velocity_x *= lateral_bounce_factor
|
||||
else
|
||||
offset_y++
|
||||
last_offset_y++
|
||||
else
|
||||
failed_y = TRUE
|
||||
if(failed_x && failed_y)
|
||||
break
|
||||
// prevents situations where you go "wtf I'm clearly right next to it" as you enter a stationary spacepod
|
||||
if(velocity_x == 0)
|
||||
if(offset_x > 0.5)
|
||||
if(Move(get_step(src, EAST)))
|
||||
offset_x--
|
||||
last_offset_x--
|
||||
else
|
||||
offset_x = 0
|
||||
if(offset_x < -0.5)
|
||||
if(Move(get_step(src, WEST)))
|
||||
offset_x++
|
||||
last_offset_x++
|
||||
else
|
||||
offset_x = 0
|
||||
if(velocity_y == 0)
|
||||
if(offset_y > 0.5)
|
||||
if(Move(get_step(src, NORTH)))
|
||||
offset_y--
|
||||
last_offset_y--
|
||||
else
|
||||
offset_y = 0
|
||||
if(offset_y < -0.5)
|
||||
if(Move(get_step(src, SOUTH)))
|
||||
offset_y++
|
||||
last_offset_y++
|
||||
else
|
||||
offset_y = 0
|
||||
dir = NORTH
|
||||
var/matrix/mat_from = new()
|
||||
mat_from.Turn(last_angle)
|
||||
var/matrix/mat_to = new()
|
||||
mat_to.Turn(angle)
|
||||
transform = mat_from
|
||||
pixel_x = last_offset_x*32
|
||||
pixel_y = last_offset_y*32
|
||||
animate(src, transform=mat_to, pixel_x = offset_x*32, pixel_y = offset_y*32, time = time*10, flags=ANIMATION_END_NOW)
|
||||
for(var/mob/living/M in contents)
|
||||
var/client/C = M.client
|
||||
if(!C)
|
||||
continue
|
||||
C.pixel_x = last_offset_x*32
|
||||
C.pixel_y = last_offset_y*32
|
||||
animate(C, pixel_x = offset_x*32, pixel_y = offset_y*32, time = time*10, flags=ANIMATION_END_NOW)
|
||||
user_thrust_dir = 0
|
||||
update_icon()
|
||||
|
||||
/obj/spacepod/Bumped(atom/movable/A)
|
||||
if(A.dir & NORTH)
|
||||
velocity_y += bump_impulse
|
||||
if(A.dir & SOUTH)
|
||||
velocity_y -= bump_impulse
|
||||
if(A.dir & EAST)
|
||||
velocity_x += bump_impulse
|
||||
if(A.dir & WEST)
|
||||
velocity_x -= bump_impulse
|
||||
return ..()
|
||||
|
||||
/obj/spacepod/Bump(atom/A)
|
||||
var/bump_velocity = 0
|
||||
if(dir & (NORTH|SOUTH))
|
||||
bump_velocity = abs(velocity_y) + (abs(velocity_x) / 15)
|
||||
else
|
||||
bump_velocity = abs(velocity_x) + (abs(velocity_y) / 15)
|
||||
if(istype(A, /obj/machinery/door/airlock)) // try to open doors
|
||||
var/obj/machinery/door/D = A
|
||||
if(!D.operating)
|
||||
if(D.allowed(D.requiresID() ? pilot : null))
|
||||
spawn(0)
|
||||
D.open()
|
||||
else
|
||||
D.do_animate("deny")
|
||||
var/atom/movable/AM = A
|
||||
if(istype(AM) && !AM.anchored && bump_velocity > 1)
|
||||
step(AM, dir)
|
||||
// if a bump is that fast then it's not a bump. It's a collision.
|
||||
if(bump_velocity > 10 && !ismob(A))
|
||||
var/strength = bump_velocity / 10
|
||||
strength = strength * strength
|
||||
strength = min(strength, 5) // don't want the explosions *too* big
|
||||
// wew lad, might wanna slow down there
|
||||
explosion(A, -1, round((strength - 1) / 2), round(strength))
|
||||
message_admins("[key_name_admin(pilot)] has impacted a spacepod into a wall with velocity [bump_velocity]")
|
||||
take_damage(strength*10, BRUTE, "melee", TRUE)
|
||||
log_game("[key_name(pilot)] has impacted a spacepod into a wall with velocity [bump_velocity]")
|
||||
visible_message("<span class='danger'>The force of the impact causes a shockwave</span>")
|
||||
else if(isliving(A) && bump_velocity > 5)
|
||||
var/mob/living/M = A
|
||||
M.apply_damage(bump_velocity * 2)
|
||||
take_damage(bump_velocity, BRUTE, "melee", FALSE)
|
||||
playsound(M.loc, "swing_hit", 1000, 1, -1)
|
||||
M.Knockdown(bump_velocity * 2)
|
||||
M.visible_message("<span class='warning'>The force of the impact knocks [M] down!</span>","<span class='userdanger'>The force of the impact knocks you down!</span>")
|
||||
log_combat(pilot, M, "impacted", src, "with velocity of [bump_velocity]")
|
||||
return ..()
|
||||
|
||||
/obj/spacepod/proc/fire_projectiles(proj_type, target) // if spacepods of other sizes are added override this or something
|
||||
var/fx = cos(90 - angle)
|
||||
var/fy = sin(90 - angle)
|
||||
var/sx = fy
|
||||
var/sy = -fx
|
||||
var/ox = (offset_x * 32) + 16
|
||||
var/oy = (offset_y * 32) + 16
|
||||
var/list/origins = list(list(ox + fx*16 - sx*16, oy + fy*16 - sy*16), list(ox + fx*16 + sx*16, oy + fy*16 + sy*16))
|
||||
for(var/list/origin in origins)
|
||||
var/this_x = origin[1]
|
||||
var/this_y = origin[2]
|
||||
var/turf/T = get_turf(src)
|
||||
while(this_x > 16)
|
||||
T = get_step(T, EAST)
|
||||
this_x -= 32
|
||||
while(this_x < -16)
|
||||
T = get_step(T, WEST)
|
||||
this_x += 32
|
||||
while(this_y > 16)
|
||||
T = get_step(T, NORTH)
|
||||
this_y -= 32
|
||||
while(this_y < -16)
|
||||
T = get_step(T, SOUTH)
|
||||
this_y += 32
|
||||
if(!T)
|
||||
continue
|
||||
var/obj/item/projectile/proj = new proj_type(T)
|
||||
proj.starting = T
|
||||
proj.firer = usr
|
||||
proj.def_zone = "chest"
|
||||
proj.original = target
|
||||
proj.pixel_x = round(this_x)
|
||||
proj.pixel_y = round(this_y)
|
||||
spawn()
|
||||
proj.fire(angle)
|
||||
29
yogstation/code/modules/spacepods/prebuilt.dm
Normal file
@@ -0,0 +1,29 @@
|
||||
/obj/spacepod/prebuilt
|
||||
icon = 'yogstation/goon/icons/obj/spacepods/2x2.dmi'
|
||||
icon_state = "pod_civ"
|
||||
var/cell_type = /obj/item/stock_parts/cell/high/plus
|
||||
var/armor_type = /obj/item/pod_parts/armor
|
||||
var/internal_tank_type = /obj/machinery/portable_atmospherics/canister/air
|
||||
var/equipment_types = list()
|
||||
construction_state = SPACEPOD_ARMOR_WELDED
|
||||
|
||||
/obj/spacepod/prebuilt/Initialize()
|
||||
..()
|
||||
add_armor(new armor_type(src))
|
||||
if(cell_type)
|
||||
cell = new cell_type(src)
|
||||
if(internal_tank_type)
|
||||
internal_tank = new internal_tank_type(src)
|
||||
for(var/equip in equipment_types)
|
||||
var/obj/item/spacepod_equipment/SE = new equip(src)
|
||||
SE.on_install(src)
|
||||
|
||||
/obj/spacepod/prebuilt/sec
|
||||
name = "security space pod"
|
||||
icon_state = "pod_mil"
|
||||
locked = TRUE
|
||||
armor_type = /obj/item/pod_parts/armor/security
|
||||
equipment_types = list(/obj/item/spacepod_equipment/weaponry/disabler,
|
||||
/obj/item/spacepod_equipment/lock/keyed/sec,
|
||||
/obj/item/spacepod_equipment/tracker,
|
||||
/obj/item/spacepod_equipment/cargo/chair)
|
||||
683
yogstation/code/modules/spacepods/spacepod.dm
Normal file
@@ -0,0 +1,683 @@
|
||||
// This is like paradise spacepods but with a few differences:
|
||||
// - no spacepod fabricator, parts are made in techfabs and frames are made using metal rods.
|
||||
// - not tile based, instead has velocity and acceleration. why? so I can put all this math to use.
|
||||
// - damages shit if you run into it too fast instead of just stopping. You have to have a huge running start to do that though and damages the spacepod as well.
|
||||
// - doesn't explode
|
||||
|
||||
GLOBAL_LIST_INIT(spacepods_list, list())
|
||||
|
||||
/obj/spacepod
|
||||
name = "space pod"
|
||||
desc = "A frame for a spacepod."
|
||||
icon = 'yogstation/goon/icons/obj/spacepods/construction_2x2.dmi'
|
||||
icon_state = "pod_1"
|
||||
density = 1
|
||||
opacity = 0
|
||||
dir = NORTH // always points north because why not
|
||||
layer = SPACEPOD_LAYER
|
||||
bound_width = 64
|
||||
bound_height = 64
|
||||
animate_movement = NO_STEPS // we do our own gliding here
|
||||
|
||||
anchored = 1
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF // it floats above lava or something, I dunno
|
||||
|
||||
max_integrity = 50
|
||||
integrity_failure = 50
|
||||
|
||||
var/list/equipment = list()
|
||||
var/list/equipment_slot_limits = list(
|
||||
SPACEPOD_SLOT_MISC = 1,
|
||||
SPACEPOD_SLOT_CARGO = 2,
|
||||
SPACEPOD_SLOT_WEAPON = 1,
|
||||
SPACEPOD_SLOT_LOCK = 1)
|
||||
var/obj/item/spacepod_equipment/lock/lock
|
||||
var/obj/item/spacepod_equipment/weaponry/weapon
|
||||
var/next_firetime = 0
|
||||
var/locked = FALSE
|
||||
var/hatch_open = FALSE
|
||||
var/construction_state = SPACEPOD_EMPTY
|
||||
var/obj/item/pod_parts/armor/pod_armor = null
|
||||
var/obj/item/stock_parts/cell/cell = null
|
||||
var/datum/gas_mixture/cabin_air
|
||||
var/obj/machinery/portable_atmospherics/canister/internal_tank
|
||||
var/last_slowprocess = 0
|
||||
|
||||
var/mob/living/pilot
|
||||
var/list/passengers = list()
|
||||
var/max_passengers = 0
|
||||
|
||||
var/velocity_x = 0 // tiles per second.
|
||||
var/velocity_y = 0
|
||||
var/offset_x = 0 // like pixel_x/y but in tiles
|
||||
var/offset_y = 0
|
||||
var/angle = 0 // degrees, clockwise
|
||||
var/desired_angle = null // set by pilot moving his mouse
|
||||
var/angular_velocity = 0 // degrees per second
|
||||
var/max_angular_acceleration = 360 // in degrees per second per second
|
||||
var/last_thrust_forward = 0
|
||||
var/last_thrust_right = 0
|
||||
var/last_rotate = 0
|
||||
|
||||
var/brakes = TRUE
|
||||
var/user_thrust_dir = 0
|
||||
var/forward_maxthrust = 6
|
||||
var/backward_maxthrust = 3
|
||||
var/side_maxthrust = 1
|
||||
|
||||
var/lights = 0
|
||||
var/lights_power = 6
|
||||
var/static/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/bump_impulse = 0.6
|
||||
var/bounce_factor = 0.2 // how much of our velocity to keep on collision
|
||||
var/lateral_bounce_factor = 0.95 // mostly there to slow you down when you drive (pilot?) down a 2x2 corridor
|
||||
|
||||
/obj/spacepod/Initialize()
|
||||
. = ..()
|
||||
GLOB.spacepods_list += src
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
cabin_air = new
|
||||
cabin_air.temperature = T20C
|
||||
cabin_air.volume = 200
|
||||
/*cabin_air.assert_gas(/datum/gas/oxygen)
|
||||
cabin_air.assert_gas(/datum/gas/nitrogen)
|
||||
cabin_air.gases[/datum/gas/oxygen][MOLES] = ONE_ATMOSPHERE*O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
|
||||
cabin_air.gases[/datum/gas/nitrogen][MOLES] = ONE_ATMOSPHERE*N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)*/
|
||||
|
||||
/obj/spacepod/Destroy()
|
||||
GLOB.spacepods_list -= src
|
||||
QDEL_NULL(pilot)
|
||||
QDEL_LIST(passengers)
|
||||
QDEL_LIST(equipment)
|
||||
QDEL_NULL(cabin_air)
|
||||
QDEL_NULL(cell)
|
||||
return ..()
|
||||
|
||||
/obj/spacepod/attackby(obj/item/W, mob/living/user)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
else if(construction_state != SPACEPOD_ARMOR_WELDED)
|
||||
. = handle_spacepod_construction(W, user)
|
||||
if(.)
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
// and now for the real stuff
|
||||
else
|
||||
if(W.tool_behaviour == TOOL_CROWBAR)
|
||||
if(hatch_open || !locked)
|
||||
hatch_open = !hatch_open
|
||||
W.play_tool_sound(src)
|
||||
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 TRUE
|
||||
if(istype(W, /obj/item/stock_parts/cell))
|
||||
if(!hatch_open)
|
||||
to_chat(user, "<span class='warning'>The maintenance hatch is closed!</span>")
|
||||
return TRUE
|
||||
if(cell)
|
||||
to_chat(user, "<span class='notice'>The pod already has a battery.</span>")
|
||||
return TRUE
|
||||
if(user.transferItemToLoc(W, src))
|
||||
to_chat(user, "<span class='notice'>You insert [W] into the pod.</span>")
|
||||
cell = W
|
||||
return TRUE
|
||||
if(istype(W, /obj/item/spacepod_equipment))
|
||||
if(!hatch_open)
|
||||
to_chat(user, "<span class='warning'>The maintenance hatch is closed!</span>")
|
||||
return TRUE
|
||||
var/obj/item/spacepod_equipment/SE = W
|
||||
if(SE.can_install(src, user) && user.temporarilyRemoveItemFromInventory(SE))
|
||||
SE.forceMove(src)
|
||||
SE.on_install(src)
|
||||
return TRUE
|
||||
if(lock && istype(W, /obj/item/device/lock_buster))
|
||||
var/obj/item/device/lock_buster/L = W
|
||||
if(L.on)
|
||||
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 * W.toolspeed, target = src))
|
||||
if(lock)
|
||||
var/obj/O = lock
|
||||
lock.on_uninstall()
|
||||
qdel(O)
|
||||
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 TRUE
|
||||
to_chat(user, "<span class='notice'>Turn the [L] on first.</span>")
|
||||
return TRUE
|
||||
if(W.tool_behaviour == TOOL_WELDER)
|
||||
var/repairing = cell || internal_tank || equipment.len || (obj_integrity < max_integrity) || pilot || passengers.len
|
||||
if(!hatch_open)
|
||||
to_chat(user, "<span class='warning'>You must open the maintenance hatch before [repairing ? "attempting repairs" : "unwelding the armor"].</span>")
|
||||
return TRUE
|
||||
if(repairing && obj_integrity >= max_integrity)
|
||||
to_chat(user, "<span class='warning'>[src] is fully repaired!</span>")
|
||||
return TRUE
|
||||
to_chat(user, "<span class='notice'>You start [repairing ? "repairing [src]" : "slicing off [src]'s armor'"]")
|
||||
if(W.use_tool(src, user, 50, amount=3, volume = 50))
|
||||
if(repairing)
|
||||
obj_integrity = min(max_integrity, obj_integrity + 10)
|
||||
update_icon()
|
||||
to_chat(user, "<span class='notice'>You mend some [pick("dents","bumps","damage")] with [W]</span>")
|
||||
else if(!cell && !internal_tank && !equipment.len && !pilot && !passengers.len && construction_state == SPACEPOD_ARMOR_WELDED)
|
||||
user.visible_message("[user] slices off [src]'s armor.", "You slice off [src]'s armor.")
|
||||
construction_state = SPACEPOD_ARMOR_SECURED
|
||||
update_icon()
|
||||
return ..()
|
||||
|
||||
/obj/spacepod/attack_hand(mob/user as mob)
|
||||
if(user.a_intent == INTENT_GRAB && !locked)
|
||||
var/mob/living/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) && construction_state == SPACEPOD_ARMOR_WELDED)
|
||||
if(remove_rider(target))
|
||||
target.Stun(20)
|
||||
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(!locked)
|
||||
// cargo_hold.open(user)
|
||||
// else
|
||||
// to_chat(user, "<span class='notice'>The storage compartment is locked</span>")
|
||||
return ..()
|
||||
var/list/items = list(cell, internal_tank)
|
||||
items += equipment
|
||||
var/list/item_map = list()
|
||||
for(var/obj/I in items)
|
||||
item_map[I.name] = I
|
||||
var/selection = input(user, "Remove which equipment?", null, null) as null|anything in item_map
|
||||
var/obj/O = item_map[selection]
|
||||
if(O && istype(O) && O in contents)
|
||||
// alrightey now to figure out what it is
|
||||
if(O == cell)
|
||||
cell = null
|
||||
else if(O == internal_tank)
|
||||
internal_tank = null
|
||||
else if(O in equipment)
|
||||
var/obj/item/spacepod_equipment/SE = O
|
||||
if(!SE.can_uninstall(user))
|
||||
return
|
||||
SE.on_uninstall()
|
||||
else
|
||||
return
|
||||
O.forceMove(loc)
|
||||
if(isitem(O))
|
||||
user.put_in_hands(O)
|
||||
|
||||
|
||||
/obj/spacepod/proc/add_armor(obj/item/pod_parts/armor/armor)
|
||||
desc = armor.pod_desc
|
||||
max_integrity = armor.pod_integrity
|
||||
obj_integrity = max_integrity - integrity_failure + obj_integrity
|
||||
pod_armor = armor
|
||||
update_icon()
|
||||
|
||||
/obj/spacepod/proc/remove_armor()
|
||||
if(!pod_armor)
|
||||
obj_integrity = min(integrity_failure, obj_integrity)
|
||||
max_integrity = integrity_failure
|
||||
desc = initial(desc)
|
||||
pod_armor = null
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/spacepod/proc/InterceptClickOn(mob/user, params, atom/target)
|
||||
var/list/params_list = params2list(params)
|
||||
if(target == src || istype(target, /obj/screen) || (target && (target in user.GetAllContents())) || user != pilot || params_list["shift"] || params_list["alt"] || params_list["ctrl"])
|
||||
return FALSE
|
||||
if(weapon)
|
||||
weapon.fire_weapons(target)
|
||||
return TRUE
|
||||
|
||||
/obj/spacepod/take_damage()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/spacepod/return_air()
|
||||
return cabin_air
|
||||
/obj/spacepod/remove_air(amount)
|
||||
return cabin_air.remove(amount)
|
||||
|
||||
/obj/spacepod/proc/slowprocess()
|
||||
if(cabin_air && cabin_air.volume > 0)
|
||||
var/delta = cabin_air.temperature - T20C
|
||||
cabin_air.temperature -= max(-10, min(10, round(delta/4,0.1)))
|
||||
if(internal_tank && cabin_air)
|
||||
var/datum/gas_mixture/tank_air = internal_tank.return_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/turf/T = get_turf(src)
|
||||
var/datum/gas_mixture/t_air = T.return_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)
|
||||
T.assume_air(removed)
|
||||
else //just delete the cabin gas, we're in space or some shit
|
||||
qdel(removed)
|
||||
|
||||
/mob/Stat()
|
||||
. = ..()
|
||||
if(isspacepod(loc) && statpanel("Status"))
|
||||
var/obj/spacepod/S = loc
|
||||
stat(null)
|
||||
stat(null, "Spacepod Charge: [S.cell ? "[round(S.cell.charge,0.1)]/[S.cell.maxcharge] KJ" : "NONE"]")
|
||||
stat(null, "Spacepod Integrity: [round(S.obj_integrity,0.1)]/[S.max_integrity]")
|
||||
stat(null, "Spacepod Velocity: [round(sqrt(S.velocity_x*S.velocity_x+S.velocity_y*S.velocity_y), 0.1)] m/s")
|
||||
stat(null)
|
||||
|
||||
/obj/spacepod/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1)
|
||||
for(var/mob/living/M in contents)
|
||||
M.ex_act(severity+1)
|
||||
deconstruct()
|
||||
if(2)
|
||||
take_damage(100, BRUTE, "bomb", 0)
|
||||
if(3)
|
||||
if(prob(40))
|
||||
take_damage(40, BRUTE, "bomb", 0)
|
||||
|
||||
/obj/spacepod/obj_break()
|
||||
if(obj_integrity <= 0)
|
||||
return // nah we'll let the other boy handle it
|
||||
if(construction_state < SPACEPOD_ARMOR_LOOSE)
|
||||
return
|
||||
if(pod_armor)
|
||||
var/obj/A = pod_armor
|
||||
remove_armor()
|
||||
qdel(A)
|
||||
if(prob(40))
|
||||
new /obj/item/stack/sheet/metal/five(loc)
|
||||
if(prob(40))
|
||||
new /obj/item/stack/sheet/metal/five(loc)
|
||||
construction_state = SPACEPOD_CORE_SECURED
|
||||
if(cabin_air)
|
||||
var/datum/gas_mixture/GM = cabin_air.remove_ratio(1)
|
||||
var/turf/T = get_turf(src)
|
||||
if(GM && T)
|
||||
T.assume_air(GM)
|
||||
cell = null
|
||||
internal_tank = null
|
||||
for(var/atom/movable/AM in contents)
|
||||
if(ismob(AM))
|
||||
forceMove(AM, loc)
|
||||
remove_rider(AM)
|
||||
else if(prob(60))
|
||||
AM.forceMove(loc)
|
||||
else if(isitem(AM) || !isobj(AM))
|
||||
qdel(AM)
|
||||
else
|
||||
var/obj/O = AM
|
||||
O.forceMove(loc)
|
||||
O.deconstruct()
|
||||
|
||||
|
||||
/obj/spacepod/deconstruct(disassembled = FALSE)
|
||||
if(!get_turf(src))
|
||||
qdel(src)
|
||||
return
|
||||
remove_rider(pilot)
|
||||
while(passengers.len)
|
||||
remove_rider(passengers[1])
|
||||
passengers.Cut()
|
||||
if(disassembled)
|
||||
// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
// alright fine fine you can have the frame pieces back
|
||||
var/clamped_angle = (round(angle, 90) % 360 + 360) % 360
|
||||
var/target_dir = NORTH
|
||||
switch(clamped_angle)
|
||||
if(0)
|
||||
target_dir = NORTH
|
||||
if(90)
|
||||
target_dir = EAST
|
||||
if(180)
|
||||
target_dir = SOUTH
|
||||
if(270)
|
||||
target_dir = WEST
|
||||
|
||||
var/list/frame_piece_types = 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/obj/item/pod_parts/pod_frame/current_piece = null
|
||||
var/turf/CT = get_turf(src)
|
||||
var/list/frame_pieces = list()
|
||||
for(var/frame_type in frame_piece_types)
|
||||
var/obj/item/pod_parts/pod_frame/F = new frame_type
|
||||
F.dir = target_dir
|
||||
F.anchored = TRUE
|
||||
if(1 == turn(F.dir, -F.link_angle))
|
||||
current_piece = F
|
||||
frame_pieces += F
|
||||
while(current_piece && !current_piece.loc)
|
||||
if(!CT)
|
||||
break
|
||||
current_piece.forceMove(CT)
|
||||
CT = get_step(CT, turn(current_piece.dir, -current_piece.link_angle))
|
||||
current_piece = locate(current_piece.link_to) in frame_pieces
|
||||
// there here's your frame pieces back, happy?
|
||||
qdel(src)
|
||||
|
||||
/obj/spacepod/update_icon()
|
||||
cut_overlays()
|
||||
if(construction_state != SPACEPOD_ARMOR_WELDED)
|
||||
icon = 'yogstation/goon/icons/obj/spacepods/construction_2x2.dmi'
|
||||
icon_state = "pod_[construction_state]"
|
||||
if(pod_armor && construction_state >= SPACEPOD_ARMOR_LOOSE)
|
||||
var/mutable_appearance/masked_armor = mutable_appearance(icon = 'yogstation/goon/icons/obj/spacepods/construction_2x2.dmi', icon_state = "armor_mask")
|
||||
var/mutable_appearance/armor = mutable_appearance(pod_armor.pod_icon, pod_armor.pod_icon_state)
|
||||
armor.blend_mode = BLEND_MULTIPLY
|
||||
masked_armor.overlays = list(armor)
|
||||
masked_armor.appearance_flags = KEEP_TOGETHER
|
||||
add_overlay(masked_armor)
|
||||
return
|
||||
|
||||
if(pod_armor)
|
||||
icon = pod_armor.pod_icon
|
||||
icon_state = pod_armor.pod_icon_state
|
||||
else
|
||||
icon = 'yogstation/goon/icons/obj/spacepods/2x2.dmi'
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
if(obj_integrity <= max_integrity / 2)
|
||||
add_overlay(image(icon='yogstation/goon/icons/obj/spacepods/2x2.dmi', icon_state="pod_damage"))
|
||||
if(obj_integrity <= max_integrity / 4)
|
||||
add_overlay(image(icon='yogstation/goon/icons/obj/spacepods/2x2.dmi', icon_state="pod_fire"))
|
||||
|
||||
if(weapon && weapon.overlay_icon_state)
|
||||
add_overlay(image(icon=weapon.overlay_icon,icon_state=weapon.overlay_icon_state))
|
||||
|
||||
light_color = icon_light_color[icon_state] || LIGHT_COLOR_WHITE
|
||||
|
||||
// Thrust!
|
||||
var/list/left_thrusts = list()
|
||||
left_thrusts.len = 8
|
||||
var/list/right_thrusts = list()
|
||||
right_thrusts.len = 8
|
||||
for(var/cdir in GLOB.cardinals)
|
||||
left_thrusts[cdir] = 0
|
||||
right_thrusts[cdir] = 0
|
||||
var/back_thrust = 0
|
||||
if(last_thrust_right != 0)
|
||||
var/tdir = last_thrust_right > 0 ? WEST : EAST
|
||||
left_thrusts[tdir] = abs(last_thrust_right) / side_maxthrust
|
||||
right_thrusts[tdir] = abs(last_thrust_right) / side_maxthrust
|
||||
if(last_thrust_forward > 0)
|
||||
back_thrust = last_thrust_forward / forward_maxthrust
|
||||
if(last_thrust_forward < 0)
|
||||
left_thrusts[NORTH] = -last_thrust_forward / backward_maxthrust
|
||||
right_thrusts[NORTH] = -last_thrust_forward / backward_maxthrust
|
||||
if(last_rotate != 0)
|
||||
var/frac = abs(last_rotate) / max_angular_acceleration
|
||||
for(var/cdir in GLOB.cardinals)
|
||||
if(last_rotate > 0)
|
||||
right_thrusts[cdir] += frac
|
||||
else
|
||||
left_thrusts[cdir] += frac
|
||||
for(var/cdir in GLOB.cardinals)
|
||||
var/left_thrust = left_thrusts[cdir]
|
||||
var/right_thrust = right_thrusts[cdir]
|
||||
if(left_thrust)
|
||||
add_overlay(image(icon = 'yogstation/icons/obj/spacepods/2x2.dmi', icon_state = "rcs_left", dir = cdir))
|
||||
if(right_thrust)
|
||||
add_overlay(image(icon = 'yogstation/icons/obj/spacepods/2x2.dmi', icon_state = "rcs_right", dir = cdir))
|
||||
if(back_thrust)
|
||||
var/image/I = image(icon = 'yogstation/icons/obj/spacepods/2x2.dmi', icon_state = "thrust")
|
||||
I.transform = matrix(1, 0, 0, 0, 1, -32)
|
||||
add_overlay(I)
|
||||
|
||||
/obj/spacepod/MouseDrop_T(atom/movable/A, mob/living/user)
|
||||
if(user == pilot || user in passengers || construction_state != SPACEPOD_ARMOR_WELDED)
|
||||
return
|
||||
|
||||
if(istype(A, /obj/machinery/portable_atmospherics/canister))
|
||||
if(internal_tank)
|
||||
to_chat(user, "<span class='warning'>[src] already has an internal_tank!</span>")
|
||||
return
|
||||
if(!A.Adjacent(src))
|
||||
to_chat(user, "<span class='warning'>The canister is not close enough!</span>")
|
||||
return
|
||||
if(hatch_open)
|
||||
to_chat(user, "<span class='warning'>The hatch is shut!</span>")
|
||||
to_chat(user, "<span class='notice'>You begin inserting the canister into [src]</span>")
|
||||
if(do_after_mob(user, list(A, src), 50) && construction_state == SPACEPOD_ARMOR_WELDED)
|
||||
to_chat(user, "<span class='notice'>You insert the canister into [src]</span>")
|
||||
A.forceMove(src)
|
||||
internal_tank = A
|
||||
return
|
||||
|
||||
if(isliving(A))
|
||||
var/mob/living/M = A
|
||||
if(M != user && !locked)
|
||||
if(passengers.len >= max_passengers && !pilot)
|
||||
to_chat(user, "<span class='danger'><b>That person can't fly the pod!</b></span>")
|
||||
return
|
||||
if(passengers.len < max_passengers)
|
||||
visible_message("<span class='danger'>[user] starts loading [M] into [src]!</span>")
|
||||
if(do_after_mob(user, list(M, src), 50) && construction_state == SPACEPOD_ARMOR_WELDED)
|
||||
add_rider(M, FALSE)
|
||||
return
|
||||
if(M == user)
|
||||
enter_pod(user)
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/spacepod/proc/enter_pod(mob/living/user)
|
||||
if(user.stat != CONSCIOUS)
|
||||
return FALSE
|
||||
|
||||
if(locked)
|
||||
to_chat(user, "<span class='warning'>[src]'s doors are locked!</span>")
|
||||
return FALSE
|
||||
|
||||
if(!istype(user))
|
||||
return FALSE
|
||||
|
||||
if(user.incapacitated())
|
||||
return FALSE
|
||||
if(!ishuman(user))
|
||||
return FALSE
|
||||
|
||||
if(passengers.len <= max_passengers || !pilot)
|
||||
visible_message("<span class='notice'>[user] starts to climb into [src].</span>")
|
||||
if(do_after(user, 40, target = src) && construction_state == SPACEPOD_ARMOR_WELDED)
|
||||
var/success = add_rider(user)
|
||||
if(!success)
|
||||
to_chat(user, "<span class='notice'>You were too slow. Try better next time, loser.</span>")
|
||||
return success
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You stop entering [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='danger'>You can't fit in [src], it's full!</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/spacepod/proc/verb_check(require_pilot = TRUE, mob/user = null)
|
||||
if(!user)
|
||||
user = usr
|
||||
if(require_pilot && user != pilot)
|
||||
to_chat(user, "<span class='notice'>You can't reach the controls from your chair</span>")
|
||||
return FALSE
|
||||
return !user.incapacitated() && isliving(user)
|
||||
|
||||
/obj/spacepod/verb/exit_pod()
|
||||
set name = "Exit pod"
|
||||
set category = "Spacepod"
|
||||
set src = usr.loc
|
||||
|
||||
if(!isliving(usr) || usr.stat > CONSCIOUS)
|
||||
return
|
||||
|
||||
if(usr.restrained())
|
||||
to_chat(usr, "<span class='notice'>You attempt to stumble out of the [src]. This will take two minutes.</span>")
|
||||
if(pilot)
|
||||
to_chat(pilot, "<span class='warning'>[usr] is trying to escape the [src].</span>")
|
||||
if(!do_after(usr, 1200, target = src))
|
||||
return
|
||||
|
||||
if(remove_rider(usr))
|
||||
to_chat(usr, "<span class='notice'>You climb out of [src].</span>")
|
||||
|
||||
/obj/spacepod/verb/lock_pod()
|
||||
set name = "Lock Doors"
|
||||
set category = "Spacepod"
|
||||
set src = usr.loc
|
||||
|
||||
if(!verb_check(FALSE))
|
||||
return
|
||||
|
||||
if(!lock)
|
||||
to_chat(usr, "<span class='warning'>[src] has no locking mechanism.</span>")
|
||||
locked = FALSE //Should never be false without a lock, but if it somehow happens, that will force an unlock.
|
||||
else
|
||||
locked = !locked
|
||||
to_chat(usr, "<span class='warning'>You [locked ? "lock" : "unlock"] the doors.</span>")
|
||||
|
||||
/obj/spacepod/verb/toggle_brakes()
|
||||
set name = "Toggle Brakes"
|
||||
set category = "Spacepod"
|
||||
set src = usr.loc
|
||||
|
||||
if(!verb_check())
|
||||
return
|
||||
brakes = !brakes
|
||||
to_chat(usr, "<span class='notice'>You toggle the brakes [brakes ? "on" : "off"].</span>")
|
||||
|
||||
/obj/spacepod/AltClick(user)
|
||||
if(!verb_check(user = user))
|
||||
return
|
||||
brakes = !brakes
|
||||
to_chat(usr, "<span class='notice'>You toggle the brakes [brakes ? "on" : "off"].</span>")
|
||||
|
||||
/obj/spacepod/verb/toggleLights()
|
||||
set name = "Toggle Lights"
|
||||
set category = "Spacepod"
|
||||
set src = usr.loc
|
||||
|
||||
if(!verb_check())
|
||||
return
|
||||
|
||||
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/toggleDoors()
|
||||
set name = "Toggle Nearby Pod Doors"
|
||||
set category = "Spacepod"
|
||||
set src = usr.loc
|
||||
|
||||
if(!verb_check())
|
||||
return
|
||||
|
||||
for(var/obj/machinery/door/poddoor/multi_tile/P in orange(3,src))
|
||||
for(var/mob/living/carbon/human/O in contents)
|
||||
if(P.check_access(O.get_active_held_item()) || P.check_access(O.wear_id))
|
||||
if(P.density)
|
||||
P.open()
|
||||
return TRUE
|
||||
else
|
||||
P.close()
|
||||
return TRUE
|
||||
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/proc/add_rider(mob/living/M, allow_pilot = TRUE)
|
||||
if(M == pilot || (M in passengers))
|
||||
return FALSE
|
||||
if(!pilot && allow_pilot)
|
||||
pilot = M
|
||||
LAZYOR(M.mousemove_intercept_objects, src)
|
||||
M.click_intercept = src
|
||||
else if(passengers.len < max_passengers)
|
||||
passengers += M
|
||||
else
|
||||
return FALSE
|
||||
M.stop_pulling()
|
||||
M.forceMove(src)
|
||||
playsound(src, 'sound/machines/windowdoor.ogg', 50, 1)
|
||||
return TRUE
|
||||
|
||||
/obj/spacepod/proc/remove_rider(mob/living/M)
|
||||
if(!M)
|
||||
return
|
||||
if(M == pilot)
|
||||
pilot = null
|
||||
LAZYREMOVE(M.mousemove_intercept_objects, src)
|
||||
if(M.click_intercept == src)
|
||||
M.click_intercept = null
|
||||
desired_angle = null // since there's no pilot there's no one aiming it.
|
||||
else if(M in passengers)
|
||||
passengers -= M
|
||||
else
|
||||
return FALSE
|
||||
if(M.loc == src)
|
||||
M.forceMove(loc)
|
||||
if(M.client)
|
||||
M.client.pixel_x = 0
|
||||
M.client.pixel_y = 0
|
||||
return TRUE
|
||||
|
||||
/obj/spacepod/onMouseMove(object,location,control,params)
|
||||
if(!pilot || !pilot.client || pilot.incapacitated())
|
||||
return // I don't know what's going on.
|
||||
var/list/params_list = params2list(params)
|
||||
var/sl_list = splittext(params_list["screen-loc"],",")
|
||||
var/sl_x_list = splittext(sl_list[1], ":")
|
||||
var/sl_y_list = splittext(sl_list[2], ":")
|
||||
var/view_list = isnum(pilot.client.view) ? list("[pilot.client.view*2+1]","[pilot.client.view*2+1]") : splittext(pilot.client.view, "x")
|
||||
var/dx = text2num(sl_x_list[1]) + (text2num(sl_x_list[2]) / world.icon_size) - 1 - text2num(view_list[1]) / 2
|
||||
var/dy = text2num(sl_y_list[1]) + (text2num(sl_y_list[2]) / world.icon_size) - 1 - text2num(view_list[2]) / 2
|
||||
if(sqrt(dx*dx+dy*dy) > 1)
|
||||
desired_angle = 90 - ATAN2(dx, dy)
|
||||
else
|
||||
desired_angle = null
|
||||
|
||||
/obj/spacepod/relaymove(mob/user, direction)
|
||||
if(user != pilot || pilot.incapacitated())
|
||||
return
|
||||
user_thrust_dir = direction
|
||||
|
||||
/obj/spacepod/Entered()
|
||||
. = ..()
|
||||
/obj/spacepod/Exited()
|
||||
. = ..()
|
||||
4
yogstation/goon/LICENSE.md
Normal file
@@ -0,0 +1,4 @@
|
||||
This work is licensed under the Creative Commons
|
||||
Attribution-NonCommercial-ShareAlike 3.0 United States License. To view a copy
|
||||
of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/us/ or
|
||||
send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
|
||||
8
yogstation/goon/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Goon-ported-assets
|
||||
|
||||
All files excluding this one you're reading right now have been most likely, taken from [goonstation's 2016 release](https://github.com/goonstation/goonstation-2016), unless stated otherwise.
|
||||
It is very likely that there are modifications to be compatible or on par with our code, however. These changes are licensed under the same license as the other goon files.
|
||||
|
||||
## License
|
||||
|
||||
See LICENSE.md
|
||||
BIN
yogstation/goon/icons/obj/spacepods/2x2.dmi
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
yogstation/goon/icons/obj/spacepods/construction_2x2.dmi
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
yogstation/goon/icons/obj/spacepods/parts.dmi
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
yogstation/icons/effects/beam.dmi
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
yogstation/icons/obj/doors/1x2blast_hor.dmi
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
yogstation/icons/obj/doors/1x2blast_vert.dmi
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
yogstation/icons/obj/doors/1x3blast_hor.dmi
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
yogstation/icons/obj/doors/1x3blast_vert.dmi
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
yogstation/icons/obj/doors/1x4blast_hor.dmi
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
yogstation/icons/obj/doors/1x4blast_vert.dmi
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
yogstation/icons/obj/spacepods/2x2.dmi
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
yogstation/icons/obj/spacepods/parts.dmi
Normal file
|
After Width: | Height: | Size: 4.6 KiB |