mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-29 15:08:02 +01:00
Merge remote-tracking branch 'upstream/master' into plasmamen-rework
# Conflicts: # code/modules/mob/living/carbon/human/update_icons.dm # icons/obj/device.dmi # paradise.dme
This commit is contained in:
@@ -67,6 +67,23 @@
|
||||
/obj/effect/mapping_helpers/no_lava
|
||||
icon_state = "no_lava"
|
||||
|
||||
/obj/effect/mapping_helpers/airlock
|
||||
layer = DOOR_HELPER_LAYER
|
||||
|
||||
/obj/effect/mapping_helpers/airlock/unres
|
||||
name = "airlock unresctricted side helper"
|
||||
icon_state = "airlock_unres_helper"
|
||||
|
||||
/obj/effect/mapping_helpers/airlock/unres/Initialize(mapload)
|
||||
if(!mapload)
|
||||
log_world("### MAP WARNING, [src] spawned outside of mapload!")
|
||||
return
|
||||
var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in src.loc
|
||||
if(airlock)
|
||||
airlock.unres_sides ^= dir
|
||||
else
|
||||
log_world("### MAP WARNING, [src] failed to find an airlock at [AREACOORD(src)]")
|
||||
..()
|
||||
/obj/effect/mapping_helpers/no_lava/New()
|
||||
var/turf/T = get_turf(src)
|
||||
T.flags |= NO_LAVA_GEN
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
new /obj/effect/hallucination/delusion(victim.loc, victim, force_kind = "demon", duration = duration, skip_nearby = 0)
|
||||
|
||||
var/obj/item/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc)
|
||||
chainsaw.flags |= NODROP
|
||||
chainsaw.flags |= NODROP | DROPDEL
|
||||
victim.drop_l_hand()
|
||||
victim.drop_r_hand()
|
||||
victim.put_in_hands(chainsaw)
|
||||
|
||||
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
Spawners for mappers. Just plonk one down of the desired size and it will place the machinery for you. The red arrow things indicate where the chamber is.
|
||||
This spawner places pipe leading up to the interior door, you will need to finish it off yourself with a connector, canister, and pipe connecting the two. It also assumes you already put in wall and floor.
|
||||
*/
|
||||
|
||||
#define HALF_X round((tiles_in_x_direction - 1) * 0.5) //These are required so that the airlock can be in the middle of the chamber wall
|
||||
#define HALF_Y round((tiles_in_y_direction - 1) * 0.5)
|
||||
#define CHAMBER_LONG 1
|
||||
#define CHAMBER_SQUARE 2
|
||||
#define CHAMBER_BIGGER 3
|
||||
#define DOOR_NORMAL_PLACEMENT 1
|
||||
#define DOOR_FLIPPED_PLACEMENT 2
|
||||
|
||||
#define AIRPUMP_TAG "[id_to_link]_pump"
|
||||
#define SENSOR_TAG "[id_to_link]_sensor"
|
||||
#define OUTER_DOOR_TAG "[id_to_link]_outer"
|
||||
#define INNER_DOOR_TAG "[id_to_link]_inner"
|
||||
|
||||
/obj/effect/spawner/airlock
|
||||
name = "1 by 1 airlock spawner (interior north, exterior south)"
|
||||
desc = "If you can see this, there's probably a missing airlock here. Better tell an admin and report this on the github."
|
||||
icon = 'icons/obj/airlock_spawner.dmi'
|
||||
icon_state = "1x1_N_to_S"
|
||||
layer = SPLASHSCREEN_PLANE //So we absolutely always appear above everything else. We delete ourself after spawning so this is fine
|
||||
var/interior_direction = NORTH //This is also the direction the spawner will send the pipe
|
||||
var/exterior_direction = SOUTH
|
||||
var/opposite_interior_direction //We're checking these often enough for them to merit their own vars
|
||||
var/interior_direction_cw
|
||||
var/interior_direction_ccw
|
||||
var/north_or_south_interior //Used a bit everywhere for locational stuff
|
||||
var/north_or_south_exterior //Likewise
|
||||
var/tiles_in_x_direction = 1
|
||||
var/tiles_in_y_direction = 1
|
||||
var/id_to_link
|
||||
var/radio_frequency = 1379
|
||||
var/required_access = list(access_external_airlocks)
|
||||
var/door_name = "external access"
|
||||
var/door_type = /obj/machinery/door/airlock/external/glass
|
||||
var/one_door_interior //For square airlocks, if you set this then a) only one door will spawn, and b) you can choose if the door should go opposite to how it normally goes. Please use the define
|
||||
var/one_door_exterior //See above
|
||||
|
||||
/obj/effect/spawner/airlock/Initialize()
|
||||
..()
|
||||
forceMove(locate(x + 1, y + 1, z)) //Needs to move because our icon_state implies we are one turf to the northeast, when we're not
|
||||
opposite_interior_direction = turn(interior_direction, 180) //Do it this way (instead of setting it directly) to avoid code mishaps
|
||||
interior_direction_cw = turn(interior_direction, 90)
|
||||
interior_direction_ccw = turn(interior_direction, 270)
|
||||
if(interior_direction == NORTH || interior_direction == SOUTH)
|
||||
north_or_south_interior = TRUE
|
||||
if(exterior_direction == NORTH || exterior_direction == SOUTH)
|
||||
north_or_south_exterior = TRUE
|
||||
id_to_link = "[UID()]" //We want unique IDs, this will give us a unique ID
|
||||
var/turf/turf_interior = get_airlock_location(interior_direction)
|
||||
var/turf/turf_exterior = get_airlock_location(exterior_direction)
|
||||
handle_door_creation(turf_interior, TRUE, one_door_interior)
|
||||
handle_door_creation(turf_exterior, FALSE, one_door_exterior)
|
||||
handle_pipes_creation(turf_interior)
|
||||
handle_control_placement()
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/spawner/airlock/proc/get_airlock_location(desired_direction) //Finds a turf to place an airlock and returns it, this turf will be in the middle of the relevant wall
|
||||
var/turf/T
|
||||
switch(desired_direction)
|
||||
if(NORTH)
|
||||
T = locate(x + HALF_X, y + tiles_in_y_direction, z)
|
||||
if(SOUTH)
|
||||
T = locate(x + HALF_X, y - 1, z)
|
||||
if(EAST)
|
||||
T = locate(x + tiles_in_x_direction, y + HALF_Y, z)
|
||||
if(WEST)
|
||||
T = locate(x - 1, y + HALF_Y, z)
|
||||
return T
|
||||
|
||||
/obj/effect/spawner/airlock/proc/handle_door_creation(turf/T, is_this_an_interior_airlock, one_door_only) //Creates a door (or two) and also creates a button
|
||||
var/obj/machinery/door/airlock/A
|
||||
if(one_door_only != DOOR_FLIPPED_PLACEMENT)
|
||||
A = new door_type(T)
|
||||
handle_door_stuff(A, is_this_an_interior_airlock)
|
||||
var/obj/machinery/access_button/the_button = spawn_button(T, is_this_an_interior_airlock ? interior_direction : exterior_direction)
|
||||
if(one_door_only == DOOR_NORMAL_PLACEMENT) //We only need one door, we are done
|
||||
return
|
||||
if(!(tiles_in_x_direction % 2) && (is_this_an_interior_airlock && north_or_south_interior || !is_this_an_interior_airlock && north_or_south_exterior)) //Handle extra airlock for aesthetics
|
||||
A = new door_type(get_step(T, EAST))
|
||||
handle_door_stuff(A, is_this_an_interior_airlock)
|
||||
if(one_door_only == DOOR_FLIPPED_PLACEMENT)
|
||||
the_button.forceMove(get_step(the_button, EAST))
|
||||
else if(!(tiles_in_y_direction % 2) && (is_this_an_interior_airlock && !north_or_south_interior || !is_this_an_interior_airlock && !north_or_south_exterior)) //Handle extra airlock for aesthetics
|
||||
A = new door_type(get_step(T, NORTH))
|
||||
handle_door_stuff(A, is_this_an_interior_airlock)
|
||||
if(one_door_only == DOOR_FLIPPED_PLACEMENT)
|
||||
the_button.forceMove(get_step(the_button, NORTH))
|
||||
|
||||
/obj/effect/spawner/airlock/proc/handle_door_stuff(obj/machinery/door/airlock/A, is_this_an_interior_airlock) //This sets up the door vars correctly and then locks it before first use
|
||||
A.set_frequency(radio_frequency)
|
||||
A.id_tag = is_this_an_interior_airlock ? INNER_DOOR_TAG : OUTER_DOOR_TAG
|
||||
A.req_access = required_access
|
||||
A.name = door_name
|
||||
A.lock()
|
||||
|
||||
/obj/effect/spawner/airlock/proc/spawn_button(turf/T, some_direction)
|
||||
var/obj/machinery/access_button/the_button = new(T)
|
||||
the_button.master_tag = id_to_link
|
||||
the_button.set_frequency(radio_frequency)
|
||||
switch(some_direction)
|
||||
if(NORTH)
|
||||
the_button.pixel_x -= 25
|
||||
the_button.pixel_y = 7
|
||||
if(EAST)
|
||||
the_button.pixel_x = 7
|
||||
the_button.pixel_y = -25
|
||||
if(SOUTH)
|
||||
the_button.pixel_x -= 25
|
||||
the_button.pixel_y -= 7
|
||||
if(WEST)
|
||||
the_button.pixel_x -= 7
|
||||
the_button.pixel_y -= 25
|
||||
the_button.req_access = required_access
|
||||
return the_button
|
||||
|
||||
/obj/effect/spawner/airlock/proc/handle_control_placement() //Stick the sensor and controller on the same bit of wall, this will ONLY be unsuitable if airlocks are on both the south and west turfs
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/machinery/airlock_sensor/AS = new(T)
|
||||
var/obj/machinery/embedded_controller/radio/airlock/airlock_controller/AC = new(T, id_to_link, radio_frequency, OUTER_DOOR_TAG, INNER_DOOR_TAG, AIRPUMP_TAG, SENSOR_TAG)
|
||||
AC.req_access = required_access
|
||||
AS.id_tag = SENSOR_TAG
|
||||
AS.set_frequency(radio_frequency)
|
||||
if(interior_direction != WEST && exterior_direction != WEST) //If west wall is free, place stuff there
|
||||
AC.pixel_x -= 25
|
||||
AC.pixel_y += 9
|
||||
AS.pixel_x -= 25
|
||||
AS.pixel_y -= 9
|
||||
else if(interior_direction != SOUTH && exterior_direction != SOUTH) //If south wall is free, place stuff there
|
||||
AC.pixel_x += 9
|
||||
AC.pixel_y -= 25
|
||||
AS.pixel_x -= 9
|
||||
AS.pixel_y -= 25
|
||||
else //Send them over to the other side of the chamber
|
||||
T = locate(x + tiles_in_x_direction - 1, y + tiles_in_y_direction - 1, z)
|
||||
AC.forceMove(T)
|
||||
AS.forceMove(T)
|
||||
AC.pixel_x += 25
|
||||
AC.pixel_y += 9
|
||||
AS.pixel_x += 25
|
||||
AS.pixel_y -= 9
|
||||
|
||||
/obj/effect/spawner/airlock/proc/handle_pipes_creation(turf/T) //This places all required piping down, then properly initializes it. T is the turf that the interior airlock occupies
|
||||
var/turf/below_T = get_step(T, opposite_interior_direction)
|
||||
|
||||
var/two_way_pipe = interior_direction | opposite_interior_direction
|
||||
var/chamber_shape //This determines the layout of the chamber and therefore how many vents should be present
|
||||
if(tiles_in_x_direction == 2 && tiles_in_y_direction == 2)
|
||||
chamber_shape = CHAMBER_SQUARE
|
||||
else if(tiles_in_x_direction > 1 && tiles_in_y_direction > 1)
|
||||
chamber_shape = CHAMBER_BIGGER
|
||||
else
|
||||
chamber_shape = CHAMBER_LONG
|
||||
pipe_creation_helper(/obj/machinery/atmospherics/pipe/simple/visible, T, interior_direction, two_way_pipe)
|
||||
switch(chamber_shape)
|
||||
if(CHAMBER_LONG) //Easy enough, place a single vent
|
||||
pipe_creation_helper(/obj/machinery/atmospherics/unary/vent_pump/high_volume,
|
||||
below_T,
|
||||
interior_direction)
|
||||
if(CHAMBER_SQUARE) //We need a T-manifold and two vents for this
|
||||
pipe_creation_helper(/obj/machinery/atmospherics/pipe/manifold/visible,
|
||||
below_T,
|
||||
north_or_south_interior ? WEST : SOUTH,
|
||||
NORTH | EAST | (north_or_south_interior ? SOUTH : WEST))
|
||||
pipe_creation_helper(/obj/machinery/atmospherics/unary/vent_pump/high_volume,
|
||||
get_step(below_T, opposite_interior_direction),
|
||||
interior_direction)
|
||||
pipe_creation_helper(/obj/machinery/atmospherics/unary/vent_pump/high_volume,
|
||||
north_or_south_interior ? EAST_OF_TURF(below_T) : NORTH_OF_TURF(below_T),
|
||||
turn(interior_direction, interior_direction == SOUTH || interior_direction == EAST ? -90 : 90))
|
||||
if(CHAMBER_BIGGER) //We need a central column of manifolds and a vent either side of each manifold
|
||||
var/depth = north_or_south_interior ? tiles_in_y_direction : tiles_in_x_direction
|
||||
var/turf/put_thing_here = below_T
|
||||
for(var/i in 1 to depth)
|
||||
if(i != depth)//We're placing more pipe later, so we need a 4-way manifold
|
||||
pipe_creation_helper(/obj/machinery/atmospherics/pipe/manifold4w/visible, put_thing_here, interior_direction, NORTH | EAST | SOUTH | WEST)
|
||||
else //We stop here, so place a T-manifold down
|
||||
pipe_creation_helper(/obj/machinery/atmospherics/pipe/manifold/visible,
|
||||
put_thing_here,
|
||||
opposite_interior_direction,
|
||||
interior_direction_cw | interior_direction | interior_direction_ccw)
|
||||
pipe_creation_helper(/obj/machinery/atmospherics/unary/vent_pump/high_volume,
|
||||
get_step(put_thing_here, interior_direction_cw),
|
||||
interior_direction_ccw)
|
||||
pipe_creation_helper(/obj/machinery/atmospherics/unary/vent_pump/high_volume,
|
||||
get_step(put_thing_here, interior_direction_ccw),
|
||||
interior_direction_cw)
|
||||
put_thing_here = get_step(put_thing_here, opposite_interior_direction) //Now move the turf we're generating stuff from 1 forward
|
||||
|
||||
/obj/effect/spawner/airlock/proc/pipe_creation_helper(path, location, direction, initialization_directions) //Create some kind of atmospherics machinery and initialize it properly
|
||||
var/obj/machinery/atmospherics/A = new path(location)
|
||||
A.dir = direction
|
||||
A.on_construction(A.dir, initialization_directions ? initialization_directions : A.dir)
|
||||
if(istype(A, /obj/machinery/atmospherics/unary/vent_pump/high_volume))
|
||||
var/obj/machinery/atmospherics/unary/vent_pump/high_volume/created_pump = A
|
||||
created_pump.id_tag = AIRPUMP_TAG
|
||||
created_pump.set_frequency(radio_frequency)
|
||||
|
||||
|
||||
//Premade airlocks for mappers, probably won't need all of these but whatever
|
||||
/obj/effect/spawner/airlock/s_to_n
|
||||
name = "1 by 1 airlock spawner (interior south, exterior north)"
|
||||
icon_state = "1x1_S_to_N"
|
||||
interior_direction = SOUTH
|
||||
exterior_direction = NORTH
|
||||
/obj/effect/spawner/airlock/e_to_w
|
||||
name = "1 by 1 airlock spawner (interior east, exterior west)"
|
||||
icon_state = "1x1_E_to_W"
|
||||
interior_direction = EAST
|
||||
exterior_direction = WEST
|
||||
/obj/effect/spawner/airlock/w_to_e
|
||||
name = "1 by 1 airlock spawner (interior west, exterior east)"
|
||||
icon_state = "1x1_W_to_E"
|
||||
interior_direction = WEST
|
||||
exterior_direction = EAST
|
||||
|
||||
/obj/effect/spawner/airlock/long //Long and thin
|
||||
name = "long airlock spawner (interior north, exterior south)"
|
||||
icon_state = "1x2_N_to_S"
|
||||
tiles_in_y_direction = 2
|
||||
/obj/effect/spawner/airlock/s_to_n/long
|
||||
name = "long airlock spawner (interior south, exterior north)"
|
||||
icon_state = "1x2_S_to_N"
|
||||
tiles_in_y_direction = 2
|
||||
/obj/effect/spawner/airlock/e_to_w/long
|
||||
name = "long airlock spawner (interior east, exterior west)"
|
||||
icon_state = "1x2_E_to_W"
|
||||
tiles_in_x_direction = 2
|
||||
/obj/effect/spawner/airlock/w_to_e/long
|
||||
name = "long airlock spawner (interior west, exterior east)"
|
||||
icon_state = "1x2_W_to_E"
|
||||
tiles_in_x_direction = 2
|
||||
|
||||
/obj/effect/spawner/airlock/long/square //Square
|
||||
name = "square airlock spawner (interior north, exterior south)"
|
||||
icon_state = "2x2_N_to_S"
|
||||
tiles_in_x_direction = 2
|
||||
/obj/effect/spawner/airlock/s_to_n/long/square
|
||||
name = "square airlock spawner (interior south, exterior north)"
|
||||
icon_state = "2x2_S_to_N"
|
||||
tiles_in_x_direction = 2
|
||||
/obj/effect/spawner/airlock/e_to_w/long/square
|
||||
name = "square airlock spawner (interior east, exterior west)"
|
||||
icon_state = "2x2_E_to_W"
|
||||
tiles_in_y_direction = 2
|
||||
/obj/effect/spawner/airlock/w_to_e/long/square
|
||||
name = "square airlock spawner (interior west, exterior east)"
|
||||
icon_state = "2x2_W_to_E"
|
||||
tiles_in_y_direction = 2
|
||||
/obj/effect/spawner/airlock/long/square/e_to_s
|
||||
name = "square airlock spawner (interior east, exterior south)"
|
||||
icon_state = "2x2_E_to_S"
|
||||
interior_direction = EAST
|
||||
exterior_direction = SOUTH
|
||||
|
||||
/obj/effect/spawner/airlock/long/square/wide
|
||||
name = "rectangular airlock spawner (interior north, exterior south)"
|
||||
icon_state = "3x2_N_to_S"
|
||||
tiles_in_x_direction = 3
|
||||
/obj/effect/spawner/airlock/s_to_n/long/square/wide
|
||||
name = "rectangular airlock spawner (interior south, exterior north)"
|
||||
icon_state = "3x2_S_to_N"
|
||||
tiles_in_x_direction = 3
|
||||
/obj/effect/spawner/airlock/e_to_w/long/square/wide
|
||||
name = "rectangular airlock spawner (interior east, exterior west)"
|
||||
icon_state = "3x2_E_to_W"
|
||||
tiles_in_y_direction = 3
|
||||
/obj/effect/spawner/airlock/w_to_e/long/square/wide
|
||||
name = "rectangular airlock spawner (interior west, exterior east)"
|
||||
icon_state = "3x2_W_to_E"
|
||||
tiles_in_y_direction = 3
|
||||
|
||||
/obj/effect/spawner/airlock/long/square/three
|
||||
name = "3 by 3 square airlock spawner (interior north, exterior south)"
|
||||
icon_state = "3x3_N_to_S"
|
||||
interior_direction = NORTH
|
||||
exterior_direction = SOUTH
|
||||
tiles_in_x_direction = 3
|
||||
tiles_in_y_direction = 3
|
||||
|
||||
/obj/effect/spawner/airlock/e_to_w/arrivals
|
||||
required_access = null
|
||||
|
||||
/obj/effect/spawner/airlock/engineer
|
||||
required_access = list(access_engine)
|
||||
door_name = "engineering external access"
|
||||
/obj/effect/spawner/airlock/e_to_w/engineer
|
||||
required_access = list(access_engine)
|
||||
door_name = "engineering external access"
|
||||
/obj/effect/spawner/airlock/s_to_n/engineer
|
||||
required_access = list(access_engine)
|
||||
door_name = "engineering external access"
|
||||
/obj/effect/spawner/airlock/long/engineer
|
||||
required_access = list(access_engine)
|
||||
door_name = "engineering external access"
|
||||
/obj/effect/spawner/airlock/long/square/engine
|
||||
required_access = list(access_engine)
|
||||
door_name = "engine external access"
|
||||
icon_state = "2x2_N_to_S_leftdoors"
|
||||
door_type = /obj/machinery/door/airlock/external
|
||||
one_door_interior = DOOR_NORMAL_PLACEMENT
|
||||
one_door_exterior = DOOR_NORMAL_PLACEMENT
|
||||
/obj/effect/spawner/airlock/long/square/engine/reversed
|
||||
icon_state = "2x2_N_to_S_rightdoors"
|
||||
one_door_interior = DOOR_FLIPPED_PLACEMENT
|
||||
one_door_exterior = DOOR_FLIPPED_PLACEMENT
|
||||
|
||||
/obj/effect/spawner/airlock/w_to_e/long/square/wide/mining
|
||||
door_name = "mining external access"
|
||||
required_access = list(access_mining)
|
||||
/obj/effect/spawner/airlock/long/square/wide/mining
|
||||
door_name = "mining external access"
|
||||
required_access = list(access_mining)
|
||||
|
||||
/obj/effect/spawner/airlock/e_to_w/minisat
|
||||
door_name = "minisat external access"
|
||||
required_access = list(access_minisat)
|
||||
/obj/effect/spawner/airlock/long/square/e_to_s/telecoms
|
||||
door_name = "telecoms external access"
|
||||
required_access = list(access_tcomsat, access_external_airlocks)
|
||||
door_type = /obj/machinery/door/airlock/external
|
||||
|
||||
/obj/effect/spawner/airlock/long/square/three/syndicate
|
||||
name = "3 by 3 square airlock spawner (interior west, exterior north)"
|
||||
icon_state = "3x3_W_to_N"
|
||||
interior_direction = WEST
|
||||
exterior_direction = NORTH
|
||||
door_name = "ship external access"
|
||||
req_access = list(access_syndicate)
|
||||
door_type = /obj/machinery/door/airlock/external
|
||||
|
||||
#undef HALF_X
|
||||
#undef HALF_Y
|
||||
#undef CHAMBER_LONG
|
||||
#undef CHAMBER_SQUARE
|
||||
#undef CHAMBER_BIGGER
|
||||
#undef DOOR_NORMAL_PLACEMENT
|
||||
#undef DOOR_FLIPPED_PLACEMENT
|
||||
#undef AIRPUMP_TAG
|
||||
#undef SENSOR_TAG
|
||||
#undef OUTER_DOOR_TAG
|
||||
#undef INNER_DOOR_TAG
|
||||
@@ -140,6 +140,20 @@
|
||||
..()
|
||||
animate(src, alpha = 0, time = duration)
|
||||
|
||||
/obj/effect/temp_visual/fire
|
||||
icon = 'icons/goonstation/effects/fire.dmi'
|
||||
icon_state = "3"
|
||||
light_range = LIGHT_RANGE_FIRE
|
||||
light_color = LIGHT_COLOR_FIRE
|
||||
duration = 10
|
||||
layer = MASSIVE_OBJ_LAYER
|
||||
alpha = 250
|
||||
blend_mode = BLEND_ADD
|
||||
|
||||
/obj/effect/temp_visual/fire/New(loc)
|
||||
color = heat2color(FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
|
||||
..()
|
||||
|
||||
/obj/effect/temp_visual/revenant
|
||||
name = "spooky lights"
|
||||
icon_state = "purplesparkles"
|
||||
@@ -289,4 +303,33 @@
|
||||
|
||||
/obj/effect/temp_visual/dir_setting/firing_effect/magic
|
||||
icon_state = "shieldsparkles"
|
||||
duration = 3
|
||||
duration = 3
|
||||
|
||||
/obj/effect/temp_visual/impact_effect
|
||||
icon_state = "impact_bullet"
|
||||
duration = 5
|
||||
|
||||
/obj/effect/temp_visual/impact_effect/Initialize(mapload, x, y)
|
||||
pixel_x = x
|
||||
pixel_y = y
|
||||
return ..()
|
||||
|
||||
/obj/effect/temp_visual/impact_effect/red_laser
|
||||
icon_state = "impact_laser"
|
||||
duration = 4
|
||||
|
||||
/obj/effect/temp_visual/impact_effect/blue_laser
|
||||
icon_state = "impact_laser_blue"
|
||||
duration = 4
|
||||
|
||||
/obj/effect/temp_visual/impact_effect/green_laser
|
||||
icon_state = "impact_laser_green"
|
||||
duration = 4
|
||||
|
||||
/obj/effect/temp_visual/impact_effect/purple_laser
|
||||
icon_state = "impact_laser_purple"
|
||||
duration = 4
|
||||
|
||||
/obj/effect/temp_visual/impact_effect/ion
|
||||
icon_state = "shieldsparkles"
|
||||
duration = 6
|
||||
@@ -331,7 +331,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/proc/hit_reaction(mob/living/carbon/human/owner, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
/obj/item/proc/hit_reaction(mob/living/carbon/human/owner, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, atom/movable/AM)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_HIT_REACT, args)
|
||||
if(prob(final_block_chance))
|
||||
owner.visible_message("<span class='danger'>[owner] blocks [attack_text] with [src]!</span>")
|
||||
@@ -347,6 +347,8 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
|
||||
A.Remove(user)
|
||||
if(flags & DROPDEL)
|
||||
qdel(src)
|
||||
if((flags & NODROP) && !(initial(flags) & NODROP)) //Remove NODROP is dropped
|
||||
flags &= ~NODROP
|
||||
in_inventory = FALSE
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_DROPPED,user)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
/obj/item/storage/pill_bottle/happy
|
||||
name = "Happy pills"
|
||||
desc = "Highly illegal drug. When you want to see the rainbow."
|
||||
wrapper_color = COLOR_PINK
|
||||
|
||||
/obj/item/storage/pill_bottle/happy/New()
|
||||
..()
|
||||
@@ -18,6 +19,7 @@
|
||||
/obj/item/storage/pill_bottle/zoom
|
||||
name = "Zoom pills"
|
||||
desc = "Highly illegal drug. Trade brain for speed."
|
||||
wrapper_color = COLOR_BLUE
|
||||
|
||||
/obj/item/storage/pill_bottle/zoom/New()
|
||||
..()
|
||||
@@ -49,15 +51,12 @@
|
||||
adulterants--
|
||||
reagents.add_reagent(pick_list("chemistry_tools.json", "CYBERPUNK_drug_adulterants"), 3)
|
||||
|
||||
|
||||
|
||||
/obj/item/storage/pill_bottle/random_drug_bottle
|
||||
name = "pill bottle (???)"
|
||||
desc = "Huh."
|
||||
allow_wrap = FALSE
|
||||
|
||||
/obj/item/storage/pill_bottle/random_drug_bottle/New()
|
||||
..()
|
||||
for(var/i in 1 to 5)
|
||||
new /obj/item/reagent_containers/food/pill/random_drugs(src)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
//////////
|
||||
Item meant to spawn one of the three (Tesla / Singularity / Supermatter) engines on-station at round-start.
|
||||
Should be found in the CE's office. Not access-restricted.
|
||||
//////////
|
||||
*/
|
||||
|
||||
/obj/item/enginepicker
|
||||
name = "Bluespace Engine Delivery Device"
|
||||
desc = "A per-station bluespace-based delivery system for a unique engine Engineering Department's choice. Only one option can be chosen. Device self-destructs on use."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "enginepicker"
|
||||
|
||||
var/list/list_enginebeacons = list()
|
||||
var/isactive = FALSE
|
||||
|
||||
/obj/item/enginepicker/attack_self(mob/living/carbon/user)
|
||||
if(usr.stat || !usr.canmove || usr.restrained())
|
||||
return
|
||||
|
||||
if(!isactive)
|
||||
isactive = TRUE //Self-attack spam exploit prevention
|
||||
else
|
||||
return
|
||||
|
||||
locatebeacons()
|
||||
var/default = null
|
||||
var/E = input("Select the station's Engine:", "[src]", default) as null|anything in list_enginebeacons
|
||||
if(E)
|
||||
processchoice(E, user)
|
||||
else
|
||||
isactive = FALSE
|
||||
return
|
||||
|
||||
//This proc re-assigns all of engine beacons in the global list to a local list.
|
||||
/obj/item/enginepicker/proc/locatebeacons()
|
||||
LAZYCLEARLIST(list_enginebeacons)
|
||||
for(var/obj/item/radio/beacon/engine/B in GLOB.engine_beacon_list)
|
||||
if(B && !QDELETED(B)) //This ensures that the input pop-up won't have any qdeleted beacons
|
||||
list_enginebeacons += B
|
||||
|
||||
//Spawns and logs / announces the appropriate engine based on the choice made
|
||||
/obj/item/enginepicker/proc/processchoice(var/obj/item/radio/beacon/engine/choice, mob/living/carbon/user)
|
||||
var/issuccessful = FALSE //Check for a successful choice
|
||||
var/engtype //Engine type
|
||||
var/G //Generator that will be spawned
|
||||
var/turf/T = get_turf(choice)
|
||||
|
||||
if(choice.enginetype.len > 1) //If the beacon has multiple engine types
|
||||
var/default = null
|
||||
var/E = input("You have selected a combined beacon, which option would you prefer?", "[src]", default) as null|anything in choice.enginetype
|
||||
if(E)
|
||||
engtype = E
|
||||
issuccessful = TRUE
|
||||
else
|
||||
isactive = FALSE
|
||||
return
|
||||
|
||||
if(!engtype) //If it has only one type
|
||||
engtype = DEFAULTPICK(choice.enginetype, null) //This should(?) account for a possibly scrambled list with a single entry
|
||||
switch(engtype)
|
||||
if(ENGTYPE_TESLA)
|
||||
G = /obj/machinery/the_singularitygen/tesla
|
||||
if(ENGTYPE_SING)
|
||||
G = /obj/machinery/the_singularitygen
|
||||
|
||||
if(G) //This can only be not-null if the switch operation was successful
|
||||
issuccessful = TRUE
|
||||
|
||||
if(issuccessful)
|
||||
clearturf(T) //qdels all items / gibs all mobs on the turf. Let's not have an SM shard spawn on top of a poor sod.
|
||||
new G(T) //Spawns the switch-selected engine on the chosen beacon's turf
|
||||
|
||||
var/ailist[] = list()
|
||||
for(var/mob/living/silicon/ai/A in GLOB.living_mob_list)
|
||||
ailist += A
|
||||
if(ailist.len)
|
||||
var/mob/living/silicon/ai/announcer = pick(ailist)
|
||||
announcer.say(";Engine delivery detected. Type: [engtype].") //Let's announce the terrible choice to everyone
|
||||
|
||||
visible_message("<span class='notice'>\The [src] begins to violently vibrate and hiss, then promptly disintegrates!</span>")
|
||||
qdel(src) //Self-destructs to prevent crew from spawning multiple engines.
|
||||
else
|
||||
visible_message("<span class='notice'>\The [src] buzzes! No beacon found or selected!</span>")
|
||||
isactive = FALSE
|
||||
return
|
||||
|
||||
//Deletes objects and mobs from the beacon's turf.
|
||||
/obj/item/enginepicker/proc/clearturf(var/turf/T)
|
||||
for(var/obj/item/I in T)
|
||||
I.visible_message("\The [I] gets crushed to dust!")
|
||||
qdel(I)
|
||||
|
||||
for(var/mob/living/M in T)
|
||||
M.visible_message("\The [M] gets obliterated!")
|
||||
M.gib()
|
||||
@@ -85,3 +85,23 @@
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/radio/beacon/engine
|
||||
desc = "A label on it reads: <i>Warning: This device is used for transportation of high-density objects used for high-yield power generation. Stay away!</i>."
|
||||
anchored = 1 //Let's not move these around. Some folk might get the idea to use these for assassinations
|
||||
var/list/enginetype = list()
|
||||
|
||||
/obj/item/radio/beacon/engine/Initialize()
|
||||
LAZYADD(GLOB.engine_beacon_list, src)
|
||||
|
||||
/obj/item/radio/beacon/engine/tesling
|
||||
name = "Engine Beacon for Tesla and Singularity"
|
||||
enginetype = list(ENGTYPE_TESLA, ENGTYPE_SING)
|
||||
|
||||
/obj/item/radio/beacon/engine/tesla
|
||||
name = "Engine Beacon for Tesla"
|
||||
enginetype = list(ENGTYPE_TESLA)
|
||||
|
||||
/obj/item/radio/beacon/engine/sing
|
||||
name = "Engine Beacon for Singularity"
|
||||
enginetype = list(ENGTYPE_SING)
|
||||
@@ -4,6 +4,10 @@
|
||||
var/radio_desc = ""
|
||||
icon_state = "headset"
|
||||
item_state = "headset"
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/ears.dmi',
|
||||
"Vox Armalis" = 'icons/mob/species/armalis/ears.dmi'
|
||||
) //We read you loud and skree-er.
|
||||
materials = list(MAT_METAL=75)
|
||||
subspace_transmission = TRUE
|
||||
canhear_range = 0 // can't hear headsets from very far away
|
||||
|
||||
@@ -135,8 +135,13 @@ REAGENT SCANNER
|
||||
user.show_message("<span class='notice'>Key: Suffocation/Toxin/Burns/Brute</span>", 1)
|
||||
user.show_message("<span class='notice'>Body Temperature: ???</span>", 1)
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] has analyzed [M]'s vitals.</span>","<span class='notice'> You have analyzed [M]'s vitals.</span>")
|
||||
|
||||
user.visible_message("<span class='notice'>[user] has analyzed [M]'s vitals.</span>","<span class='notice'> You have analyzed [M]'s vitals.</span>")
|
||||
healthscan(user, M, mode, upgraded)
|
||||
add_fingerprint(user)
|
||||
|
||||
|
||||
proc/healthscan(mob/user, mob/living/M, mode = 1, upgraded = FALSE)
|
||||
if(!ishuman(M) || M.isSynthetic())
|
||||
//these sensors are designed for organic life
|
||||
user.show_message("<span class='notice'>Analyzing Results for ERROR:\n\t Overall Status: ERROR</span>")
|
||||
@@ -271,8 +276,9 @@ REAGENT SCANNER
|
||||
user.show_message("<span class='warning'>Subject's genes are showing minor signs of instability.</span>")
|
||||
else
|
||||
user.show_message("<span class='notice'>Subject's genes are stable.</span>")
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/item/healthanalyzer/attack_self(mob/user)
|
||||
toggle_mode()
|
||||
|
||||
/obj/item/healthanalyzer/verb/toggle_mode()
|
||||
set name = "Switch Verbosity"
|
||||
|
||||
@@ -123,6 +123,7 @@
|
||||
/obj/item/storage/pill_bottle/random_meds
|
||||
name = "unlabelled pillbottle"
|
||||
desc = "The sheer recklessness of this bottle's existence astounds you."
|
||||
allow_wrap = FALSE
|
||||
var/labelled = FALSE
|
||||
|
||||
/obj/item/storage/pill_bottle/random_meds/New()
|
||||
|
||||
@@ -178,8 +178,12 @@ var/global/list/datum/stack_recipe/wood_recipes = list(
|
||||
new /datum/stack_recipe("wooden buckler", /obj/item/shield/riot/buckler, 20, time = 40),
|
||||
new /datum/stack_recipe("apiary", /obj/structure/beebox, 40, time = 50),
|
||||
new /datum/stack_recipe("honey frame", /obj/item/honey_frame, 5, time = 10),
|
||||
new /datum/stack_recipe("wooden bucket", /obj/item/reagent_containers/glass/bucket/wooden, 3, time = 10),
|
||||
new /datum/stack_recipe("rake", /obj/item/cultivator/rake, 5, time = 10),
|
||||
new /datum/stack_recipe("ore box", /obj/structure/ore_box, 4, time = 50, one_per_turf = TRUE, on_floor = TRUE),
|
||||
new /datum/stack_recipe("baseball bat", /obj/item/melee/baseball_bat, 5, time = 15),
|
||||
new /datum/stack_recipe("fermenting barrel", /obj/structure/fermenting_barrel, 30, time = 50)
|
||||
new /datum/stack_recipe("fermenting barrel", /obj/structure/fermenting_barrel, 30, time = 50),
|
||||
new /datum/stack_recipe("firebrand", /obj/item/match/firebrand, 2, time = 100)
|
||||
)
|
||||
|
||||
/obj/item/stack/sheet/wood
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
icon = 'icons/obj/dice.dmi'
|
||||
icon_state = "dicebag"
|
||||
can_hold = list(/obj/item/dice)
|
||||
allow_wrap = FALSE
|
||||
|
||||
/obj/item/storage/pill_bottle/dice/New()
|
||||
..()
|
||||
|
||||
@@ -115,7 +115,8 @@
|
||||
throw_range = 6
|
||||
materials = list(MAT_METAL=12000)
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
sharp = 1
|
||||
sharp = TRUE
|
||||
var/bayonet = FALSE //Can this be attached to a gun?
|
||||
|
||||
/obj/item/kitchen/knife/suicide_act(mob/user)
|
||||
user.visible_message(pick("<span class='suicide'>[user] is slitting [user.p_their()] wrists with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.</span>", \
|
||||
@@ -164,6 +165,7 @@
|
||||
throwforce = 20
|
||||
origin_tech = "materials=3;combat=4"
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut")
|
||||
bayonet = TRUE
|
||||
|
||||
/obj/item/kitchen/knife/combat/survival
|
||||
name = "survival knife"
|
||||
|
||||
@@ -224,3 +224,13 @@
|
||||
var/mask_item = M.get_item_by_slot(slot_wear_mask)
|
||||
if(istype(mask_item, /obj/item/clothing/mask/cigarette))
|
||||
return mask_item
|
||||
|
||||
|
||||
/obj/item/match/firebrand
|
||||
name = "firebrand"
|
||||
desc = "An unlit firebrand. It makes you wonder why it's not just called a stick."
|
||||
smoketime = 20 //40 seconds
|
||||
|
||||
/obj/item/match/firebrand/New()
|
||||
..()
|
||||
matchignite()
|
||||
@@ -18,8 +18,10 @@
|
||||
burn_state = FLAMMABLE
|
||||
burntime = 20
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/back.dmi'
|
||||
)
|
||||
"Vox" = 'icons/mob/species/vox/back.dmi',
|
||||
"Vox Armalis" = 'icons/mob/species/armalis/back.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/back.dmi'
|
||||
) //For Armalis anything but this and the nitrogen tank will use the default backpack icon.
|
||||
|
||||
/obj/item/storage/backpack/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
playsound(src.loc, "rustle", 50, 1, -5)
|
||||
@@ -398,7 +400,7 @@
|
||||
new /obj/item/gun/projectile/automatic/shotgun/bulldog(src)
|
||||
new /obj/item/ammo_box/magazine/m12g(src)
|
||||
new /obj/item/ammo_box/magazine/m12g(src)
|
||||
new /obj/item/clothing/glasses/thermal/syndi(src)
|
||||
new /obj/item/clothing/glasses/chameleon/thermal(src)
|
||||
|
||||
/obj/item/storage/backpack/duffel/syndie/med/medicalbundle
|
||||
desc = "A large duffel bag containing a tactical medkit, a Donksoft machine gun and a big jumbo box of riot darts."
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
New()
|
||||
..()
|
||||
contents = list()
|
||||
new /obj/item/clothing/mask/breath(src)
|
||||
new /obj/item/clothing/mask/gas/explorer(src)
|
||||
new /obj/item/tank/emergency_oxygen/engi(src)
|
||||
new /obj/item/crowbar/red(src)
|
||||
new /obj/item/reagent_containers/hypospray/autoinjector(src)
|
||||
@@ -372,6 +372,20 @@
|
||||
new /obj/item/implantpad(src)
|
||||
new /obj/item/locator(src)
|
||||
|
||||
/obj/item/storage/box/minertracker
|
||||
name = "boxed tracking implant kit"
|
||||
desc = "For finding those who have died on the accursed lavaworld."
|
||||
icon_state = "implant"
|
||||
|
||||
/obj/item/storage/box/minertracker/New()
|
||||
..()
|
||||
new /obj/item/implantcase/tracking(src)
|
||||
new /obj/item/implantcase/tracking(src)
|
||||
new /obj/item/implantcase/tracking(src)
|
||||
new /obj/item/implanter(src)
|
||||
new /obj/item/implantpad(src)
|
||||
new /obj/item/locator(src)
|
||||
|
||||
/obj/item/storage/box/chemimp
|
||||
name = "chemical implant kit"
|
||||
desc = "Box of stuff used to implant chemicals."
|
||||
|
||||
@@ -254,10 +254,21 @@
|
||||
var/applying_meds = FALSE //To Prevent spam clicking and generating runtimes from apply a deleting pill multiple times.
|
||||
var/rapid_intake_message = "unscrews the cap on the pill bottle and begins dumping the entire contents down their throat!"
|
||||
var/rapid_post_instake_message = "downs the entire bottle of pills in one go!"
|
||||
var/allow_wrap = TRUE
|
||||
var/wrapper_color = null
|
||||
|
||||
/obj/item/storage/pill_bottle/New()
|
||||
..()
|
||||
base_name = name
|
||||
if(allow_wrap)
|
||||
apply_wrap()
|
||||
|
||||
/obj/item/storage/pill_bottle/proc/apply_wrap()
|
||||
if(wrapper_color)
|
||||
overlays.Cut()
|
||||
var/image/I = image(icon, "pillbottle_wrap")
|
||||
I.color = wrapper_color
|
||||
overlays += I
|
||||
|
||||
/obj/item/storage/pill_bottle/attack(mob/M, mob/user)
|
||||
if(iscarbon(M) && contents.len)
|
||||
@@ -274,6 +285,9 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/storage/pill_bottle/ert
|
||||
wrapper_color = COLOR_MAROON
|
||||
|
||||
/obj/item/storage/pill_bottle/ert/New()
|
||||
..()
|
||||
new /obj/item/reagent_containers/food/pill/salicylic(src)
|
||||
@@ -319,15 +333,18 @@
|
||||
|
||||
/obj/item/storage/pill_bottle/patch_pack
|
||||
name = "Patch Pack"
|
||||
desc = "It's a container for storing medical patches."
|
||||
icon_state = "patch_pack"
|
||||
can_hold = list(/obj/item/reagent_containers/food/pill/patch)
|
||||
cant_hold = list()
|
||||
rapid_intake_message = "flips the lid of the Patch Pack open and begins rapidly stamping patches on themselves!"
|
||||
rapid_post_instake_message = "stamps the entire contents of the Patch Pack all over their entire body!"
|
||||
allow_wrap = FALSE
|
||||
|
||||
/obj/item/storage/pill_bottle/charcoal
|
||||
name = "Pill bottle (Charcoal)"
|
||||
desc = "Contains pills used to counter toxins."
|
||||
wrapper_color = COLOR_GREEN
|
||||
|
||||
New()
|
||||
..()
|
||||
@@ -342,6 +359,7 @@
|
||||
/obj/item/storage/pill_bottle/painkillers
|
||||
name = "Pill Bottle (Salicylic Acid)"
|
||||
desc = "Contains various pills for minor pain relief."
|
||||
wrapper_color = COLOR_RED
|
||||
|
||||
/obj/item/storage/pill_bottle/painkillers/New()
|
||||
..()
|
||||
@@ -354,8 +372,11 @@
|
||||
new /obj/item/reagent_containers/food/pill/salicylic(src)
|
||||
new /obj/item/reagent_containers/food/pill/salicylic(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/fakedeath
|
||||
allow_wrap = FALSE
|
||||
|
||||
/obj/item/storage/pill_bottle/fakedeath/New()
|
||||
..()
|
||||
new /obj/item/reagent_containers/food/pill/fakedeath(src)
|
||||
new /obj/item/reagent_containers/food/pill/fakedeath(src)
|
||||
new /obj/item/reagent_containers/food/pill/fakedeath(src)
|
||||
new /obj/item/reagent_containers/food/pill/fakedeath(src)
|
||||
|
||||
@@ -116,15 +116,10 @@
|
||||
|
||||
/obj/item/storage/lockbox/medal/New()
|
||||
..()
|
||||
new /obj/item/clothing/accessory/medal/gold/heroism(src)
|
||||
new /obj/item/clothing/accessory/medal/silver/security(src)
|
||||
new /obj/item/clothing/accessory/medal/silver/valor(src)
|
||||
new /obj/item/clothing/accessory/medal/nobel_science(src)
|
||||
new /obj/item/clothing/accessory/medal/bronze_heart(src)
|
||||
new /obj/item/clothing/accessory/medal/conduct(src)
|
||||
new /obj/item/clothing/accessory/medal/conduct(src)
|
||||
new /obj/item/clothing/accessory/medal/conduct(src)
|
||||
new /obj/item/clothing/accessory/medal/gold/captain(src)
|
||||
new /obj/item/clothing/accessory/medal/silver/leadership(src)
|
||||
new /obj/item/clothing/accessory/medal/silver/valor(src)
|
||||
new /obj/item/clothing/accessory/medal/heart(src)
|
||||
|
||||
/obj/item/storage/lockbox/t4
|
||||
name = "lockbox (T4)"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
if("thief") // 40TC
|
||||
new /obj/item/gun/energy/kinetic_accelerator/crossbow(src) // 12TC
|
||||
new /obj/item/chameleon(src) // 8TC
|
||||
new /obj/item/clothing/glasses/thermal/syndi(src) // 6TC
|
||||
new /obj/item/clothing/glasses/chameleon/thermal(src) // 6TC
|
||||
new /obj/item/clothing/gloves/color/black/thief(src) // 6TC
|
||||
new /obj/item/card/id/syndicate(src) // 2TC
|
||||
new /obj/item/clothing/shoes/chameleon/noslip(src) // 2TC
|
||||
@@ -108,7 +108,7 @@
|
||||
new /obj/item/gun/projectile/automatic/sniper_rifle/syndicate/penetrator(src) // 16TC
|
||||
new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src) // 5TC
|
||||
new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) // 3TC
|
||||
new /obj/item/clothing/glasses/thermal/syndi/sunglasses(src) // 6TC
|
||||
new /obj/item/clothing/glasses/chameleon/thermal(src) // 6TC
|
||||
new /obj/item/clothing/gloves/combat(src) // 0 TC
|
||||
new /obj/item/clothing/under/suit_jacket/really_black(src) // 0 TC
|
||||
new /obj/item/clothing/suit/storage/lawyer/blackjacket/armored(src) // 0TC
|
||||
|
||||
@@ -205,7 +205,7 @@ obj/item/tank/emergency_oxygen/double/empty/New()
|
||||
desc = "A tank of nitrogen."
|
||||
icon_state = "oxygen_fr"
|
||||
distribute_pressure = ONE_ATMOSPHERE*O2STANDARD
|
||||
|
||||
sprite_sheets = list("Vox Armalis" = 'icons/mob/species/armalis/back.dmi') //Do it for Big Bird.
|
||||
|
||||
/obj/item/tank/nitrogen/New()
|
||||
..()
|
||||
@@ -222,6 +222,7 @@ obj/item/tank/emergency_oxygen/double/empty/New()
|
||||
desc = "A high-tech nitrogen tank designed specifically for Vox."
|
||||
icon_state = "emergency_vox"
|
||||
volume = 25
|
||||
sprite_sheets = list("Vox Armalis" = 'icons/mob/species/armalis/belt.dmi') //Do it for Big Bird.
|
||||
|
||||
/obj/item/tank/emergency_oxygen/vox/New()
|
||||
..()
|
||||
|
||||
@@ -157,6 +157,8 @@
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "baseball_bat"
|
||||
item_state = "baseball_bat"
|
||||
var/deflectmode = FALSE // deflect small/medium thrown objects
|
||||
var/lastdeflect
|
||||
force = 10
|
||||
throwforce = 12
|
||||
attack_verb = list("beat", "smacked")
|
||||
@@ -169,14 +171,54 @@
|
||||
desc = "This thing looks dangerous... Dangerously good at baseball, that is."
|
||||
homerun_able = 1
|
||||
|
||||
/obj/item/melee/baseball_bat/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type, atom/movable/AM)
|
||||
. = ..()
|
||||
if(!istype(AM, /obj/item) || attack_type != THROWN_PROJECTILE_ATTACK)
|
||||
return FALSE
|
||||
var/obj/item/I = AM
|
||||
if(I.w_class <= WEIGHT_CLASS_NORMAL || istype(I, /obj/item/beach_ball)) // baseball bat deflecting
|
||||
if(deflectmode)
|
||||
if(prob(10))
|
||||
visible_message("<span class='boldwarning'>[owner] Deflects [I] directly back at the thrower! It's a home run!</span>", "<span class='boldwarning'>You deflect the [I] directly back at the thrower! It's a home run!</span>")
|
||||
playsound(get_turf(owner), 'sound/weapons/homerun.ogg', 100, 1)
|
||||
do_attack_animation(I, ATTACK_EFFECT_DISARM)
|
||||
I.throw_at(I.thrownby, 20, 20, owner)
|
||||
deflectmode = FALSE
|
||||
if(!istype(I, /obj/item/beach_ball))
|
||||
lastdeflect = world.time + 3000
|
||||
return TRUE
|
||||
else if(prob(30))
|
||||
visible_message("<span class='warning'>[owner] swings! And [p_they()] miss[p_es()]! How embarassing.</span>", "<span class='warning'>You swing! You miss! Oh no!</span>")
|
||||
playsound(get_turf(owner), 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
do_attack_animation(get_step(owner, pick(alldirs)), ATTACK_EFFECT_DISARM)
|
||||
deflectmode = FALSE
|
||||
if(!istype(I, /obj/item/beach_ball))
|
||||
lastdeflect = world.time + 3000
|
||||
return FALSE
|
||||
else
|
||||
visible_message("<span class='warning'>[owner] swings and deflects [I]!</span>", "<span class='warning'>You swing and deflect the [I]!</span>")
|
||||
playsound(get_turf(owner), 'sound/weapons/baseball_hit.ogg', 50, 1, -1)
|
||||
do_attack_animation(I, ATTACK_EFFECT_DISARM)
|
||||
I.throw_at(get_edge_target_turf(owner, pick(cardinal)), rand(8,10), 14, owner)
|
||||
deflectmode = FALSE
|
||||
if(!istype(I, /obj/item/beach_ball))
|
||||
lastdeflect = world.time + 3000
|
||||
return TRUE
|
||||
|
||||
/obj/item/melee/baseball_bat/attack_self(mob/user)
|
||||
if(!homerun_able)
|
||||
..()
|
||||
return
|
||||
if(!deflectmode && world.time >= lastdeflect)
|
||||
to_chat(user, "<span class='notice'>You prepare to deflect objects thrown at you. You cannot attack during this time.</span>")
|
||||
deflectmode = TRUE
|
||||
else if(deflectmode && world.time >= lastdeflect)
|
||||
to_chat(user, "<span class='notice'>You no longer deflect objects thrown at you. You can attack during this time</span>")
|
||||
deflectmode = FALSE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to wait until you can deflect again. The ability will be ready in [time2text(lastdeflect - world.time, "m:ss")]</span>")
|
||||
return ..()
|
||||
if(homerun_ready)
|
||||
to_chat(user, "<span class='notice'>You're already ready to do a home run!</span>")
|
||||
..()
|
||||
return
|
||||
return ..()
|
||||
to_chat(user, "<span class='warning'>You begin gathering strength...</span>")
|
||||
playsound(get_turf(src), 'sound/magic/lightning_chargeup.ogg', 65, 1)
|
||||
if(do_after(user, 90, target = user))
|
||||
@@ -185,6 +227,9 @@
|
||||
..()
|
||||
|
||||
/obj/item/melee/baseball_bat/attack(mob/living/target, mob/living/user)
|
||||
if(deflectmode)
|
||||
to_chat(user, "<span class='warning'>You cannot attack in deflect mode!</span>")
|
||||
return
|
||||
. = ..()
|
||||
var/atom/throw_target = get_edge_target_turf(target, user.dir)
|
||||
if(homerun_ready)
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
new /obj/item/rpd(src)
|
||||
new /obj/item/reagent_containers/food/drinks/mug/ce(src)
|
||||
new /obj/item/organ/internal/cyberimp/eyes/meson(src)
|
||||
new /obj/item/clothing/accessory/medal/engineering(src)
|
||||
|
||||
|
||||
/obj/structure/closet/secure_closet/engineering_electrical
|
||||
|
||||
@@ -110,6 +110,7 @@
|
||||
/obj/item/storage/pill_bottle/psychiatrist
|
||||
name = "psychiatrist's pill bottle"
|
||||
desc = "Contains various pills to calm or sedate patients."
|
||||
wrapper_color = COLOR_PALE_BTL_GREEN
|
||||
|
||||
/obj/item/storage/pill_bottle/psychiatrist/New()
|
||||
..()
|
||||
@@ -193,6 +194,7 @@
|
||||
new /obj/item/organ/internal/cyberimp/eyes/hud/medical(src)
|
||||
new /obj/item/door_remote/chief_medical_officer(src)
|
||||
new /obj/item/reagent_containers/food/drinks/mug/cmo(src)
|
||||
new /obj/item/clothing/accessory/medal/medical(src)
|
||||
|
||||
|
||||
/obj/structure/closet/secure_closet/animal
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
new /obj/item/door_remote/research_director(src)
|
||||
new /obj/item/reagent_containers/food/drinks/mug/rd(src)
|
||||
new /obj/item/organ/internal/cyberimp/eyes/hud/diagnostic(src)
|
||||
|
||||
new /obj/item/clothing/accessory/medal/science(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/research_reagents
|
||||
name = "research chemical storage closet"
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
new /obj/item/clothing/accessory/petcollar(src)
|
||||
new /obj/item/door_remote/civillian(src)
|
||||
new /obj/item/reagent_containers/food/drinks/mug/hop(src)
|
||||
|
||||
new /obj/item/clothing/accessory/medal/service(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/hop2
|
||||
name = "head of personnel's attire"
|
||||
@@ -128,7 +128,7 @@
|
||||
new /obj/item/door_remote/head_of_security(src)
|
||||
new /obj/item/reagent_containers/food/drinks/mug/hos(src)
|
||||
new /obj/item/organ/internal/cyberimp/eyes/hud/security(src)
|
||||
|
||||
new /obj/item/clothing/accessory/medal/security(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/warden
|
||||
name = "warden's locker"
|
||||
@@ -464,4 +464,5 @@
|
||||
new /obj/item/clothing/head/powdered_wig(src)
|
||||
new /obj/item/gavelblock(src)
|
||||
new /obj/item/gavelhammer(src)
|
||||
new /obj/item/clothing/head/justice_wig(src)
|
||||
new /obj/item/clothing/head/justice_wig(src)
|
||||
new /obj/item/clothing/accessory/medal/legal(src)
|
||||
@@ -5,9 +5,9 @@
|
||||
icon_state = "crate"
|
||||
icon_opened = "crateopen"
|
||||
icon_closed = "crate"
|
||||
climbable = 1
|
||||
climbable = TRUE
|
||||
// mouse_drag_pointer = MOUSE_ACTIVE_POINTER //???
|
||||
var/rigged = 0
|
||||
var/rigged = FALSE
|
||||
var/obj/item/paper/manifest/manifest
|
||||
// A list of beacon names that the crate will announce the arrival of, when delivered.
|
||||
var/list/announce_beacons = list()
|
||||
@@ -23,16 +23,16 @@
|
||||
overlays += "manifest"
|
||||
|
||||
/obj/structure/closet/crate/can_open()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/structure/closet/crate/can_close()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/structure/closet/crate/open()
|
||||
if(src.opened)
|
||||
return 0
|
||||
return FALSE
|
||||
if(!src.can_open())
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(rigged && locate(/obj/item/radio/electropack) in src)
|
||||
if(isliving(usr))
|
||||
@@ -47,18 +47,18 @@
|
||||
for(var/mob/M in src) //Mobs
|
||||
M.forceMove(loc)
|
||||
icon_state = icon_opened
|
||||
src.opened = 1
|
||||
src.opened = TRUE
|
||||
|
||||
if(climbable)
|
||||
structure_shaken()
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/structure/closet/crate/close()
|
||||
if(!src.opened)
|
||||
return 0
|
||||
return FALSE
|
||||
if(!src.can_close())
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3)
|
||||
var/itemcount = 0
|
||||
@@ -75,8 +75,8 @@
|
||||
itemcount++
|
||||
|
||||
icon_state = icon_closed
|
||||
src.opened = 0
|
||||
return 1
|
||||
src.opened = FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/structure/closet/crate/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/rcs) && !src.opened)
|
||||
@@ -105,7 +105,7 @@
|
||||
return
|
||||
playsound(E.loc, E.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>Teleporting [src.name]...</span>")
|
||||
E.teleporting = 1
|
||||
E.teleporting = TRUE
|
||||
if(!do_after(user, 50 * E.toolspeed, target = src))
|
||||
E.teleporting = 0
|
||||
return
|
||||
@@ -127,9 +127,9 @@
|
||||
return
|
||||
playsound(E.loc, E.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>Teleporting [src.name]...</span>")
|
||||
E.teleporting = 1
|
||||
E.teleporting = TRUE
|
||||
if(!do_after(user, 50 * E.toolspeed, target = src))
|
||||
E.teleporting = 0
|
||||
E.teleporting = FALSE
|
||||
return
|
||||
E.teleporting = 0
|
||||
if(!(E.rcell && E.rcell.use(E.chargecost)))
|
||||
@@ -154,14 +154,16 @@
|
||||
else if(istype(W, /obj/item/stack/packageWrap))
|
||||
return
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = W
|
||||
if(rigged)
|
||||
to_chat(user, "<span class='notice'>[src] is already rigged!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You rig [src].</span>")
|
||||
user.drop_item()
|
||||
qdel(W)
|
||||
rigged = 1
|
||||
return
|
||||
if(C.use(15))
|
||||
to_chat(user, "<span class='notice'>You rig [src].</span>")
|
||||
rigged = TRUE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need atleast 15 wires to rig [src]!</span>")
|
||||
return
|
||||
else if(istype(W, /obj/item/radio/electropack))
|
||||
if(rigged)
|
||||
to_chat(user, "<span class='notice'>You attach [W] to [src].</span>")
|
||||
@@ -172,7 +174,7 @@
|
||||
if(rigged)
|
||||
to_chat(user, "<span class='notice'>You cut away the wiring.</span>")
|
||||
playsound(loc, W.usesound, 100, 1)
|
||||
rigged = 0
|
||||
rigged = FALSE
|
||||
return
|
||||
else return attack_hand(user)
|
||||
|
||||
@@ -653,4 +655,4 @@
|
||||
new /obj/item/storage/bag/ore(src)
|
||||
new /obj/item/clothing/glasses/meson(src)
|
||||
new /obj/item/card/id/golem(src)
|
||||
new /obj/item/flashlight/lantern(src)
|
||||
new /obj/item/flashlight/lantern(src)
|
||||
|
||||
@@ -226,6 +226,7 @@
|
||||
door = new airlock_type(loc)
|
||||
door.setDir(dir)
|
||||
door.electronics = electronics
|
||||
door.unres_sides = electronics.unres_sides
|
||||
door.heat_proof = heat_proof_finished
|
||||
if(electronics.one_access)
|
||||
door.req_access = null
|
||||
|
||||
@@ -97,12 +97,9 @@
|
||||
else
|
||||
icon_state = "fwall_open"
|
||||
|
||||
/obj/structure/falsewall/proc/ChangeToWall(delete = 1)
|
||||
/obj/structure/falsewall/proc/ChangeToWall(delete = TRUE)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!walltype || walltype == "metal")
|
||||
T.ChangeTurf(/turf/simulated/wall)
|
||||
else
|
||||
T.ChangeTurf(text2path("/turf/simulated/wall/mineral/[walltype]"))
|
||||
T.ChangeTurf(walltype)
|
||||
if(delete)
|
||||
qdel(src)
|
||||
return T
|
||||
|
||||
@@ -64,6 +64,12 @@
|
||||
if(usr.incapacitated())
|
||||
to_chat(usr, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
if(!usr.has_right_hand() && !usr.has_left_hand())
|
||||
to_chat(usr, "<span class='warning'>You try to grab the chair, but you are missing both of your hands!</span>")
|
||||
return
|
||||
if(usr.get_active_hand() && usr.get_inactive_hand())
|
||||
to_chat(usr, "<span class='warning'>You try to grab the chair, but your hands are already full!</span>")
|
||||
return
|
||||
if(!ishuman(usr))
|
||||
return
|
||||
usr.visible_message("<span class='notice'>[usr] grabs \the [src.name].</span>", "<span class='notice'>You grab \the [src.name].</span>")
|
||||
|
||||
@@ -91,6 +91,12 @@
|
||||
if(climber)
|
||||
climber.Weaken(2)
|
||||
climber.visible_message("<span class='warning'>[climber.name] has been knocked off the table", "You've been knocked off the table", "You see [climber.name] get knocked off the table</span>")
|
||||
else if(user.pulling.pass_flags & PASSTABLE)
|
||||
user.Move_Pulled(src)
|
||||
if (user.pulling.loc == loc)
|
||||
user.visible_message("<span class='notice'>[user] places [user.pulling] onto [src].</span>",
|
||||
"<span class='notice'>You place [user.pulling] onto [src].</span>")
|
||||
user.stop_pulling()
|
||||
|
||||
/obj/structure/table/attack_tk() // no telehulk sorry
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user