Merge remote-tracking branch 'citadel/master' into combat_rework_experimental
This commit is contained in:
@@ -37,6 +37,10 @@
|
||||
name = "winterball Zone"
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
|
||||
/area/centcom/supplypod/supplypod_temp_holding
|
||||
name = "Supplypod Shipping lane"
|
||||
icon_state = "supplypod_flight"
|
||||
|
||||
/area/centcom/supplypod
|
||||
name = "Supplypod Facility"
|
||||
icon_state = "supplypod"
|
||||
@@ -49,18 +53,35 @@
|
||||
/area/centcom/supplypod/loading
|
||||
name = "Supplypod Loading Facility"
|
||||
icon_state = "supplypod_loading"
|
||||
var/loading_id = ""
|
||||
|
||||
/area/centcom/supplypod/loading/Initialize()
|
||||
. = ..()
|
||||
if(!loading_id)
|
||||
CRASH("[type] created without a loading_id")
|
||||
if(GLOB.supplypod_loading_bays[loading_id])
|
||||
CRASH("Duplicate loading bay area: [type] ([loading_id])")
|
||||
GLOB.supplypod_loading_bays[loading_id] = src
|
||||
|
||||
/area/centcom/supplypod/loading/one
|
||||
name = "Supplypod Loading Bay #1"
|
||||
name = "Bay #1"
|
||||
loading_id = "1"
|
||||
|
||||
/area/centcom/supplypod/loading/two
|
||||
name = "Supplypod Loading Bay #2"
|
||||
name = "Bay #2"
|
||||
loading_id = "2"
|
||||
|
||||
/area/centcom/supplypod/loading/three
|
||||
name = "Supplypod Loading Bay #3"
|
||||
name = "Bay #3"
|
||||
loading_id = "3"
|
||||
|
||||
/area/centcom/supplypod/loading/four
|
||||
name = "Supplypod Loading Bay #4"
|
||||
name = "Bay #4"
|
||||
loading_id = "4"
|
||||
|
||||
/area/centcom/supplypod/loading/ert
|
||||
name = "ERT Bay"
|
||||
loading_id = "5"
|
||||
//THUNDERDOME
|
||||
|
||||
/area/tdome
|
||||
|
||||
@@ -1128,6 +1128,22 @@
|
||||
/atom/proc/rust_heretic_act()
|
||||
return
|
||||
|
||||
/**
|
||||
* Used to set something as 'open' if it's being used as a supplypod
|
||||
*
|
||||
* Override this if you want an atom to be usable as a supplypod.
|
||||
*/
|
||||
/atom/proc/setOpened()
|
||||
return
|
||||
|
||||
/**
|
||||
* Used to set something as 'closed' if it's being used as a supplypod
|
||||
*
|
||||
* Override this if you want an atom to be usable as a supplypod.
|
||||
*/
|
||||
/atom/proc/setClosed()
|
||||
return
|
||||
|
||||
///Passes Stat Browser Panel clicks to the game and calls client click on an atom
|
||||
/atom/Topic(href, list/href_list)
|
||||
. = ..()
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
var/datum/action/innate/camera_off/off_action = new
|
||||
var/datum/action/innate/camera_jump/jump_action = new
|
||||
var/list/actions = list()
|
||||
/// Should we suppress the user's view?
|
||||
var/should_supress_view_changes = TRUE
|
||||
|
||||
light_color = LIGHT_COLOR_RED
|
||||
|
||||
@@ -77,6 +79,7 @@
|
||||
|
||||
current_user = null
|
||||
user.unset_machine()
|
||||
user.client.view_size.unsupress()
|
||||
playsound(src, 'sound/machines/terminal_off.ogg', 25, 0)
|
||||
|
||||
/obj/machinery/computer/camera_advanced/check_eye(mob/user)
|
||||
@@ -157,6 +160,8 @@
|
||||
user.remote_control = eyeobj
|
||||
user.reset_perspective(eyeobj)
|
||||
eyeobj.setLoc(eyeobj.loc)
|
||||
if(should_supress_view_changes)
|
||||
user.client.view_size.supress()
|
||||
|
||||
/mob/camera/aiEye/remote
|
||||
name = "Inactive Camera Eye"
|
||||
@@ -273,4 +278,4 @@
|
||||
C.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static)
|
||||
C.clear_fullscreen("flash", 3) //Shorter flash than normal since it's an ~~advanced~~ console!
|
||||
else
|
||||
playsound(origin, 'sound/machines/terminal_prompt_deny.ogg', 25, 0)
|
||||
playsound(origin, 'sound/machines/terminal_prompt_deny.ogg', 25, 0)
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
/obj/machinery/computer/mechpad
|
||||
name = "orbital mech pad console"
|
||||
desc = "A computer designed to handle the calculations and routing required for sending and receiving mechs from orbit. Requires a link to a nearby Orbital Mech Pad to function."
|
||||
icon_screen = "mechpad"
|
||||
icon_keyboard = "teleport_key"
|
||||
circuit = /obj/item/circuitboard/computer/mechpad
|
||||
///ID of the mechpad, used for linking up
|
||||
var/id = "roboticsmining"
|
||||
///Selected mechpad in the console
|
||||
var/selected_id
|
||||
///Mechpads that it can send mechs through to other mechpads
|
||||
var/obj/machinery/mechpad/connected_mechpad
|
||||
///List of mechpads connected
|
||||
var/list/obj/machinery/mechpad/mechpads = list()
|
||||
///Maximum amount of pads connected at once
|
||||
var/maximum_pads = 3
|
||||
|
||||
/obj/machinery/computer/mechpad/Initialize(mapload)
|
||||
. = ..()
|
||||
if(mapload)
|
||||
connected_mechpad = connect_to_pad()
|
||||
connected_mechpad.connected_console = src
|
||||
connected_mechpad.id = id
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
else
|
||||
id ="handmade"
|
||||
|
||||
/obj/machinery/computer/mechpad/LateInitialize()
|
||||
for(var/obj/machinery/mechpad/pad in GLOB.mechpad_list)
|
||||
if(pad == connected_mechpad)
|
||||
continue
|
||||
if(pad.id != id)
|
||||
continue
|
||||
mechpads += pad
|
||||
LAZYADD(pad.consoles, src)
|
||||
if(mechpads.len > maximum_pads)
|
||||
break
|
||||
|
||||
/obj/machinery/computer/mechpad/Destroy()
|
||||
if(connected_mechpad)
|
||||
connected_mechpad.connected_console = null
|
||||
connected_mechpad = null
|
||||
for(var/obj/machinery/mechpad/mechpad in mechpads)
|
||||
LAZYREMOVE(mechpad.consoles, src)
|
||||
return ..()
|
||||
|
||||
///Tries to locate a pad in the cardinal directions, if it finds one it returns it
|
||||
/obj/machinery/computer/mechpad/proc/connect_to_pad()
|
||||
if(connected_mechpad)
|
||||
return
|
||||
for(var/direction in GLOB.cardinals)
|
||||
connected_mechpad = locate(/obj/machinery/mechpad, get_step(src, direction))
|
||||
if(connected_mechpad)
|
||||
break
|
||||
return connected_mechpad
|
||||
|
||||
/obj/machinery/computer/mechpad/multitool_act(mob/living/user, obj/item/tool)
|
||||
if(!multitool_check_buffer(user, tool))
|
||||
return
|
||||
var/obj/item/multitool/multitool = tool
|
||||
if(istype(multitool.buffer, /obj/machinery/mechpad))
|
||||
var/obj/machinery/mechpad/buffered_console = multitool.buffer
|
||||
if(!(mechpads.len < maximum_pads))
|
||||
to_chat(user, "<span class='warning'>[src] cannot handle any more connections!</span>")
|
||||
return
|
||||
if(buffered_console == connected_mechpad)
|
||||
to_chat(user, "<span class='warning'>[src] cannot connect to its own mechpad!</span>")
|
||||
else if(!connected_mechpad && buffered_console == connect_to_pad())
|
||||
connected_mechpad = buffered_console
|
||||
connected_mechpad.connected_console = src
|
||||
connected_mechpad.id = id
|
||||
multitool.buffer = null
|
||||
to_chat(user, "<span class='notice'>You connect the console to the pad with data from the [multitool.name]'s buffer.</span>")
|
||||
else
|
||||
mechpads += buffered_console
|
||||
LAZYADD(buffered_console.consoles, src)
|
||||
multitool.buffer = null
|
||||
to_chat(user, "<span class='notice'>You upload the data from the [multitool.name]'s buffer.</span>")
|
||||
|
||||
/**
|
||||
* Tries to call the launch proc on the connected mechpad, returns if there is no connected mechpad or there is no mecha on the pad
|
||||
* Arguments:
|
||||
* * user - The user of the proc
|
||||
* * where - The mechpad that the connected mechpad will try to send a supply pod to
|
||||
*/
|
||||
/obj/machinery/computer/mechpad/proc/try_launch(var/mob/user, var/obj/machinery/mechpad/where)
|
||||
if(!connected_mechpad)
|
||||
to_chat(user, "<span class='warning'>[src] has no connected pad!</span>")
|
||||
return
|
||||
if(connected_mechpad.panel_open)
|
||||
to_chat(user, "<span class='warning'>[src]'s pad has its' panel open! It won't work!</span>")
|
||||
return
|
||||
if(!(locate(/obj/vehicle/sealed/mecha) in get_turf(connected_mechpad)))
|
||||
to_chat(user, "<span class='warning'>[src] detects no mecha on the pad!</span>")
|
||||
return
|
||||
connected_mechpad.launch(where)
|
||||
|
||||
///Checks if the pad of a certain number has been QDELETED, if yes returns FALSE, otherwise returns TRUE
|
||||
/obj/machinery/computer/mechpad/proc/pad_exists(number)
|
||||
var/obj/machinery/mechpad/pad = mechpads[number]
|
||||
if(QDELETED(pad))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
///Returns the pad of the value specified
|
||||
/obj/machinery/computer/mechpad/proc/get_pad(number)
|
||||
var/obj/machinery/mechpad/pad = mechpads[number]
|
||||
return pad
|
||||
|
||||
/obj/machinery/computer/mechpad/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "MechpadConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/mechpad/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/list/pad_list = list()
|
||||
for(var/i in 1 to LAZYLEN(mechpads))
|
||||
if(pad_exists(i))
|
||||
var/obj/machinery/mechpad/pad = get_pad(i)
|
||||
var/list/this_pad = list()
|
||||
this_pad["name"] = pad.display_name
|
||||
this_pad["id"] = i
|
||||
if(pad.machine_stat & NOPOWER)
|
||||
this_pad["inactive"] = TRUE
|
||||
pad_list += list(this_pad)
|
||||
else
|
||||
mechpads -= get_pad(i)
|
||||
data["mechpads"] = pad_list
|
||||
data["selected_id"] = selected_id
|
||||
data["connected_mechpad"] = !!connected_mechpad
|
||||
if(selected_id)
|
||||
var/obj/machinery/mechpad/current_pad = mechpads[selected_id]
|
||||
data["pad_name"] = current_pad.display_name
|
||||
data["selected_pad"] = current_pad
|
||||
if(QDELETED(current_pad) || (current_pad.machine_stat & NOPOWER))
|
||||
data["pad_active"] = FALSE
|
||||
return data
|
||||
data["pad_active"] = TRUE
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/mechpad/ui_act(action, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
var/obj/machinery/mechpad/current_pad = mechpads[selected_id]
|
||||
switch(action)
|
||||
if("select_pad")
|
||||
selected_id = text2num(params["id"])
|
||||
if("rename")
|
||||
var/new_name = params["name"]
|
||||
if(!new_name)
|
||||
return
|
||||
current_pad.display_name = new_name
|
||||
if("remove")
|
||||
if(usr && alert(usr, "Are you sure?", "Unlink Orbital Pad", "I'm Sure", "Abort") != "Abort")
|
||||
mechpads -= current_pad
|
||||
LAZYREMOVE(current_pad.consoles, src)
|
||||
selected_id = null
|
||||
if("launch")
|
||||
try_launch(usr, current_pad)
|
||||
. = TRUE
|
||||
@@ -0,0 +1,76 @@
|
||||
/obj/machinery/mechpad
|
||||
name = "orbital mech pad"
|
||||
desc = "A slab of heavy plating designed to withstand orbital-drop impacts. Through some sort of advanced bluespace tech, this one seems able to send and receive Mechs. Requires linking to a console to function."
|
||||
icon = 'icons/obj/telescience.dmi'
|
||||
icon_state = "mechpad"
|
||||
circuit = /obj/item/circuitboard/machine/mechpad
|
||||
///ID of the console, used for linking up
|
||||
var/id = "roboticsmining"
|
||||
///Name of the mechpad in a mechpad console
|
||||
var/display_name = "Orbital Pad"
|
||||
///The console the pad is linked to
|
||||
var/obj/machinery/computer/mechpad/connected_console
|
||||
///List of consoles that can access the pad
|
||||
var/list/obj/machinery/computer/mechpad/consoles
|
||||
|
||||
/obj/machinery/mechpad/Initialize()
|
||||
. = ..()
|
||||
display_name = "Orbital Pad - [get_area_name(src)]"
|
||||
GLOB.mechpad_list += src
|
||||
|
||||
/obj/machinery/mechpad/Destroy()
|
||||
if(connected_console)
|
||||
connected_console.connected_mechpad = null
|
||||
connected_console = null
|
||||
for(var/obj/machinery/computer/mechpad/console in consoles)
|
||||
console.mechpads -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/mechpad/screwdriver_act(mob/user, obj/item/tool)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return default_deconstruction_screwdriver(user, "mechpad-o", "mechpad", tool)
|
||||
|
||||
/obj/machinery/mechpad/crowbar_act(mob/user, obj/item/tool)
|
||||
..()
|
||||
if(default_deconstruction_crowbar(tool))
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/mechpad/multitool_act(mob/living/user, obj/item/tool)
|
||||
if(!panel_open)
|
||||
return
|
||||
if(!multitool_check_buffer(user, tool))
|
||||
return
|
||||
var/obj/item/multitool/multitool = tool
|
||||
multitool.buffer = src
|
||||
to_chat(user, "<span class='notice'>You save the data in the [multitool.name]'s buffer.</span>")
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Spawns a special supply pod whitelisted to only accept mechs and have its drop off location be another mechpad
|
||||
* Arguments:
|
||||
* * where - where the supply pod will land after grabbing the mech
|
||||
*/
|
||||
/obj/machinery/mechpad/proc/launch(obj/machinery/mechpad/where)
|
||||
var/obj/structure/closet/supplypod/mechpod/pod = new()
|
||||
var/turf/target_turf = get_turf(where)
|
||||
pod.reverse_dropoff_coords = list(target_turf.x, target_turf.y, target_turf.z)
|
||||
new /obj/effect/pod_landingzone(get_turf(src), pod)
|
||||
|
||||
/obj/structure/closet/supplypod/mechpod
|
||||
style = STYLE_SEETHROUGH
|
||||
explosionSize = list(0,0,0,0)
|
||||
reversing = TRUE
|
||||
landingDelay = 0
|
||||
openingDelay = 0
|
||||
departureDelay = 0
|
||||
effectOrgans = TRUE
|
||||
effectQuiet = TRUE
|
||||
leavingSound = 'sound/vehicles/rocketlaunch.ogg'
|
||||
close_sound = null
|
||||
pod_flags = FIRST_SOUNDS
|
||||
|
||||
/obj/structure/closet/supplypod/mechpod/insertion_allowed(atom/movable/AM)
|
||||
if(!ismecha(AM))
|
||||
return FALSE
|
||||
. = ..()
|
||||
@@ -1007,7 +1007,7 @@
|
||||
|
||||
if(L && L.client)
|
||||
L.update_mouse_pointer()
|
||||
L.client.change_view(CONFIG_GET(string/default_view))
|
||||
L.client.view_size.resetToDefault()
|
||||
zoom_mode = 0
|
||||
|
||||
/////////////////////////
|
||||
|
||||
@@ -243,10 +243,10 @@
|
||||
chassis.mecha_log_message("Toggled zoom mode.")
|
||||
chassis.occupant_message("<font color='[chassis.zoom_mode?"blue":"red"]'>Zoom mode [chassis.zoom_mode?"en":"dis"]abled.</font>")
|
||||
if(chassis.zoom_mode)
|
||||
owner.client.change_view(12)
|
||||
owner.client.view_size.setTo(4.5)
|
||||
SEND_SOUND(owner, sound('sound/mecha/imag_enh.ogg',volume=50))
|
||||
else
|
||||
owner.client.change_view(CONFIG_GET(string/default_view)) //world.view - default mob view size
|
||||
owner.client.view_size.resetToDefault()
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/innate/mecha/mech_switch_damtype
|
||||
|
||||
@@ -9,12 +9,19 @@
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
icon_state = "glowshroom" //replaced in New
|
||||
layer = ABOVE_NORMAL_TURF_LAYER
|
||||
max_integrity = 5
|
||||
var/delay = 1200
|
||||
/// Time interval between glowshroom "spreads"
|
||||
var/delay_spread = 2 MINUTES
|
||||
/// Time interval between glowshroom decay checks
|
||||
var/delay_decay = 30 SECONDS
|
||||
/// Boolean to indicate if the shroom is on the floor/wall
|
||||
var/floor = 0
|
||||
/// Mushroom generation number
|
||||
var/generation = 1
|
||||
var/spreadIntoAdjacentChance = 60
|
||||
/// Chance to spread into adjacent tiles (0-100)
|
||||
var/spreadIntoAdjacentChance = 75
|
||||
/// Internal seed of the glowshroom, stats are stored here
|
||||
var/obj/item/seeds/myseed = /obj/item/seeds/glowshroom
|
||||
/// Turfs where the glowshroom cannot spread to
|
||||
var/static/list/blacklisted_glowshroom_turfs = typecacheof(list(
|
||||
/turf/open/lava,
|
||||
/turf/open/floor/plating/beach/water))
|
||||
@@ -43,21 +50,30 @@
|
||||
QDEL_NULL(myseed)
|
||||
return ..()
|
||||
|
||||
/obj/structure/glowshroom/New(loc, obj/item/seeds/newseed, mutate_stats)
|
||||
..()
|
||||
/**
|
||||
* Creates a new glowshroom structure.
|
||||
*
|
||||
* Arguments:
|
||||
* * newseed - Seed of the shroom
|
||||
* * mutate_stats - If the plant needs to mutate their stats
|
||||
* * spread - If the plant is a result of spreading, reduce its stats
|
||||
*/
|
||||
|
||||
/obj/structure/glowshroom/Initialize(mapload, obj/item/seeds/newseed, mutate_stats, spread)
|
||||
. = ..()
|
||||
if(newseed)
|
||||
myseed = newseed.Copy()
|
||||
myseed.forceMove(src)
|
||||
else
|
||||
myseed = new myseed(src)
|
||||
if(spread)
|
||||
myseed.potency -= round(myseed.potency * 0.25) // Reduce potency of the little mushie if it's spreading
|
||||
if(mutate_stats) //baby mushrooms have different stats :3
|
||||
myseed.adjust_potency(rand(-3,6))
|
||||
myseed.adjust_yield(rand(-1,2))
|
||||
myseed.adjust_production(rand(-3,6))
|
||||
myseed.adjust_endurance(rand(-3,6))
|
||||
delay = delay - myseed.production * 100 //So the delay goes DOWN with better stats instead of up. :I
|
||||
obj_integrity = myseed.endurance / 7
|
||||
max_integrity = myseed.endurance / 7
|
||||
myseed.adjust_potency(rand(-4,3))
|
||||
myseed.adjust_yield(rand(-3,2))
|
||||
myseed.adjust_production(rand(-3,3))
|
||||
myseed.endurance = clamp(myseed.endurance + rand(-3,2), 0, 100) // adjust_endurance has a min value of 10, need to edit directly
|
||||
delay_spread = delay_spread - myseed.production * 100 //So the delay goes DOWN with better stats instead of up. :I
|
||||
var/datum/plant_gene/trait/glow/G = myseed.get_gene(/datum/plant_gene/trait/glow)
|
||||
if(ispath(G)) // Seeds were ported to initialize so their genes are still typepaths here, luckily their initializer is smart enough to handle us doing this
|
||||
myseed.genes -= G
|
||||
@@ -80,13 +96,20 @@
|
||||
else //if on the floor, glowshroom on-floor sprite
|
||||
icon_state = base_icon_state
|
||||
|
||||
addtimer(CALLBACK(src, .proc/Spread), delay)
|
||||
addtimer(CALLBACK(src, .proc/Spread), delay_spread)
|
||||
addtimer(CALLBACK(src, .proc/Decay), delay_decay, FALSE) // Start decaying the plant
|
||||
|
||||
/**
|
||||
* Causes glowshroom spreading across the floor/walls.
|
||||
*/
|
||||
|
||||
/obj/structure/glowshroom/proc/Spread()
|
||||
var/turf/ownturf = get_turf(src)
|
||||
var/shrooms_planted = 0
|
||||
for(var/i in 1 to myseed.yield)
|
||||
if(prob(1/(generation * generation) * 100))//This formula gives you diminishing returns based on generation. 100% with 1st gen, decreasing to 25%, 11%, 6, 4, 2...
|
||||
var/chance_stats = ((myseed.potency + myseed.endurance * 2) * 0.2) // Chance of generating a new mushroom based on stats
|
||||
var/chance_generation = (100 / (generation * generation)) // This formula gives you diminishing returns based on generation. 100% with 1st gen, decreasing to 25%, 11%, 6, 4, 2...
|
||||
if(prob(max(chance_stats, chance_generation))) // Whatever is the higher chance we use it
|
||||
var/list/possibleLocs = list()
|
||||
var/spreadsIntoAdjacent = FALSE
|
||||
|
||||
@@ -96,7 +119,7 @@
|
||||
for(var/turf/open/floor/earth in view(3,src))
|
||||
if(is_type_in_typecache(earth, blacklisted_glowshroom_turfs))
|
||||
continue
|
||||
if(!disease_air_spread_walk(ownturf, earth))
|
||||
if(!ownturf.CanAtmosPass(earth))
|
||||
continue
|
||||
if(spreadsIntoAdjacent || !locate(/obj/structure/glowshroom) in view(1,earth))
|
||||
possibleLocs += earth
|
||||
@@ -118,16 +141,15 @@
|
||||
if(shroomCount >= placeCount)
|
||||
continue
|
||||
|
||||
var/obj/structure/glowshroom/child = new type(newLoc, myseed, TRUE)
|
||||
Decay(TRUE, 2) // Decay before spawning new mushrooms to reduce their endurance
|
||||
var/obj/structure/glowshroom/child = new type(newLoc, myseed, TRUE, TRUE)
|
||||
child.generation = generation + 1
|
||||
shrooms_planted++
|
||||
|
||||
CHECK_TICK
|
||||
else
|
||||
shrooms_planted++ //if we failed due to generation, don't try to plant one later
|
||||
if(shrooms_planted < myseed.yield) //if we didn't get all possible shrooms planted, try again later
|
||||
myseed.yield -= shrooms_planted
|
||||
addtimer(CALLBACK(src, .proc/Spread), delay)
|
||||
if(shrooms_planted <= myseed.yield) //if we didn't get all possible shrooms planted, try again later
|
||||
myseed.adjust_yield(-shrooms_planted)
|
||||
addtimer(CALLBACK(src, .proc/Spread), delay_spread)
|
||||
|
||||
/obj/structure/glowshroom/proc/CalcDir(turf/location = loc)
|
||||
var/direction = 16
|
||||
@@ -161,9 +183,27 @@
|
||||
floor = 1
|
||||
return 1
|
||||
|
||||
/**
|
||||
* Causes the glowshroom to decay by decreasing its endurance.
|
||||
*
|
||||
* Arguments:
|
||||
* * spread - Boolean to indicate if the decay is due to spreading or natural decay.
|
||||
* * amount - Amount of endurance to be reduced due to spread decay.
|
||||
*/
|
||||
/obj/structure/glowshroom/proc/Decay(spread, amount)
|
||||
if (spread) // Decay due to spread
|
||||
myseed.endurance -= amount
|
||||
else // Timed decay
|
||||
myseed.endurance -= 1
|
||||
if (myseed.endurance > 0)
|
||||
addtimer(CALLBACK(src, .proc/Decay), delay_decay, FALSE) // Recall decay timer
|
||||
return
|
||||
if (myseed.endurance < 1) // Plant is gone
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/glowshroom/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
|
||||
if(damage_type == BURN && damage_amount)
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 100, TRUE)
|
||||
|
||||
/obj/structure/glowshroom/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > 300)
|
||||
@@ -175,3 +215,8 @@
|
||||
var/obj/effect/decal/cleanable/molten_object/I = new (get_turf(src))
|
||||
I.desc = "Looks like this was \an [src] some time ago."
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/glowshroom/attackby(obj/item/I, mob/living/user, params)
|
||||
if (istype(I, /obj/item/plant_analyzer))
|
||||
return myseed.attackby(I, user, params) // Hacky I guess
|
||||
return ..() // Attack normally
|
||||
|
||||
@@ -40,10 +40,6 @@
|
||||
density = TRUE
|
||||
layer = FLY_LAYER
|
||||
|
||||
/obj/effect/supplypod_selector
|
||||
icon_state = "supplypod_selector"
|
||||
layer = FLY_LAYER
|
||||
|
||||
//Makes a tile fully lit no matter what
|
||||
/obj/effect/fullbright
|
||||
icon = 'icons/effects/alphacolors.dmi'
|
||||
@@ -91,4 +87,4 @@
|
||||
/obj/effect/dummy/lighting_obj/moblight/Initialize(mapload, _color, _range, _power, _duration)
|
||||
. = ..()
|
||||
if(!ismob(loc))
|
||||
return INITIALIZE_HINT_QDEL
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
@@ -515,3 +515,12 @@
|
||||
/obj/effect/temp_visual/dir_setting/space_wind/Initialize(mapload, set_dir, set_alpha = 255)
|
||||
. = ..()
|
||||
alpha = set_alpha
|
||||
|
||||
/obj/effect/temp_visual/slime_puddle
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
duration = 12
|
||||
icon_state = "to_puddle"
|
||||
|
||||
/obj/effect/temp_visual/slime_puddle/reverse
|
||||
icon_state = "from_puddle"
|
||||
duration = 7
|
||||
|
||||
@@ -315,7 +315,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
|
||||
return
|
||||
if(loc == user && current_equipped_slot && current_equipped_slot != SLOT_HANDS)
|
||||
if(current_equipped_slot in user.check_obscured_slots())
|
||||
to_chat(src, "<span class='warning'>You are unable to unequip that while wearing other garments over it!</span>")
|
||||
to_chat(user, "<span class='warning'>You are unable to unequip that while wearing other garments over it!</span>")
|
||||
return FALSE
|
||||
|
||||
if(resistance_flags & ON_FIRE)
|
||||
@@ -383,7 +383,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
|
||||
return
|
||||
if(loc == user && current_equipped_slot && current_equipped_slot != SLOT_HANDS)
|
||||
if(current_equipped_slot in user.check_obscured_slots())
|
||||
to_chat(src, "<span class='warning'>You are unable to unequip that while wearing other garments over it!</span>")
|
||||
to_chat(user, "<span class='warning'>You are unable to unequip that while wearing other garments over it!</span>")
|
||||
return FALSE
|
||||
|
||||
|
||||
|
||||
@@ -25,41 +25,32 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/binoculars/proc/on_wield(obj/item/source, mob/user)
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/unwield)
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/on_walk)
|
||||
RegisterSignal(user, COMSIG_ATOM_DIR_CHANGE, .proc/rotate)
|
||||
listeningTo = user
|
||||
user.visible_message("<span class='notice'>[user] holds [src] up to [user.p_their()] eyes.</span>", "<span class='notice'>You hold [src] up to your eyes.</span>")
|
||||
item_state = "binoculars_wielded"
|
||||
user.regenerate_icons()
|
||||
if(!user?.client)
|
||||
return
|
||||
var/client/C = user.client
|
||||
var/_x = 0
|
||||
var/_y = 0
|
||||
switch(user.dir)
|
||||
if(NORTH)
|
||||
_y = zoom_amt
|
||||
if(EAST)
|
||||
_x = zoom_amt
|
||||
if(SOUTH)
|
||||
_y = -zoom_amt
|
||||
if(WEST)
|
||||
_x = -zoom_amt
|
||||
C.change_view(world.view + zoom_out_amt)
|
||||
C.pixel_x = world.icon_size*_x
|
||||
C.pixel_y = world.icon_size*_y
|
||||
user.client.view_size.zoomOut(zoom_out_amt, zoom_amt, user.dir)
|
||||
|
||||
/obj/item/binoculars/proc/rotate(atom/thing, old_dir, new_dir)
|
||||
if(ismob(thing))
|
||||
var/mob/lad = thing
|
||||
lad.regenerate_icons()
|
||||
lad.client.view_size.zoomOut(zoom_out_amt, zoom_amt, new_dir)
|
||||
|
||||
/obj/item/binoculars/proc/on_walk()
|
||||
attack_self(listeningTo) //Yes I have sinned, why do you ask?
|
||||
|
||||
/obj/item/binoculars/proc/on_unwield(obj/item/source, mob/user)
|
||||
unwield(user)
|
||||
|
||||
/obj/item/binoculars/proc/unwield(mob/user)
|
||||
if(listeningTo)
|
||||
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
|
||||
UnregisterSignal(user, COMSIG_ATOM_DIR_CHANGE)
|
||||
listeningTo = null
|
||||
user.visible_message("<span class='notice'>[user] lowers [src].</span>", "<span class='notice'>You lower [src].</span>")
|
||||
item_state = "binoculars"
|
||||
user.regenerate_icons()
|
||||
if(user && user.client)
|
||||
user.regenerate_icons()
|
||||
var/client/C = user.client
|
||||
C.change_view(CONFIG_GET(string/default_view))
|
||||
user.client.pixel_x = 0
|
||||
user.client.pixel_y = 0
|
||||
user.client.view_size.zoomIn()
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/obj/item/defibrillator
|
||||
name = "defibrillator"
|
||||
desc = "A device that delivers powerful shocks to detachable paddles that resuscitate incapacitated patients."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon = 'icons/obj/defibrillators.dmi'
|
||||
icon_state = "defibunit"
|
||||
item_state = "defibunit"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
@@ -23,8 +23,8 @@
|
||||
var/obj/item/stock_parts/cell/cell
|
||||
var/combat = FALSE //can we revive through space suits?
|
||||
var/grab_ghost = FALSE // Do we pull the ghost back into their body?
|
||||
var/healdisk = FALSE // Will we shock people dragging the body?
|
||||
var/pullshocksafely = FALSE //Dose the unit have the healdisk upgrade?
|
||||
var/healdisk = FALSE // Does the unit have the healdisk upgrade?
|
||||
var/pullshocksafely = FALSE // Will we shock people dragging the body?
|
||||
var/primetime = 0 // is the defib faster
|
||||
var/timedeath = 10
|
||||
var/disarm_shock_time = 10
|
||||
@@ -261,7 +261,7 @@
|
||||
/obj/item/shockpaddles
|
||||
name = "defibrillator paddles"
|
||||
desc = "A pair of plastic-gripped paddles with flat metal surfaces that are used to deliver powerful electric shocks."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon = 'icons/obj/defibrillators.dmi'
|
||||
icon_state = "defibpaddles0"
|
||||
item_state = "defibpaddles0"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
@@ -682,7 +682,7 @@
|
||||
|
||||
/obj/item/shockpaddles/cyborg
|
||||
name = "cyborg defibrillator paddles"
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon = 'icons/obj/defibrillators.dmi'
|
||||
icon_state = "defibpaddles0"
|
||||
item_state = "defibpaddles0"
|
||||
req_defib = FALSE
|
||||
@@ -703,7 +703,7 @@
|
||||
name = "syndicate defibrillator paddles"
|
||||
desc = "A pair of paddles used to revive deceased operatives. It possesses both the ability to penetrate armor and to deliver powerful shocks offensively."
|
||||
combat = TRUE
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon = 'icons/obj/defibrillators.dmi'
|
||||
icon_state = "defibpaddles0"
|
||||
item_state = "defibpaddles0"
|
||||
req_defib = FALSE
|
||||
|
||||
@@ -366,6 +366,11 @@
|
||||
flashlight_power = 0.8
|
||||
custom_price = PRICE_CHEAP
|
||||
|
||||
/obj/item/flashlight/lantern/heirloom_moth
|
||||
name = "old lantern"
|
||||
desc = "An old lantern that has seen plenty of use."
|
||||
light_range = 4
|
||||
|
||||
/obj/item/flashlight/lantern/jade
|
||||
name = "jade lantern"
|
||||
desc = "An ornate, green lantern."
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
var/starting_tape_type = /obj/item/tape/random
|
||||
var/open_panel = 0
|
||||
var/canprint = 1
|
||||
|
||||
var/list/icons_available = list()
|
||||
var/icon_directory = 'icons/radials/taperecorder.dmi'
|
||||
|
||||
/obj/item/taperecorder/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -32,6 +33,29 @@
|
||||
. = ..()
|
||||
. += "The wire panel is [open_panel ? "opened" : "closed"]."
|
||||
|
||||
/obj/item/taperecorder/AltClick(mob/user)
|
||||
. = ..()
|
||||
play()
|
||||
|
||||
/obj/item/taperecorder/proc/update_available_icons()
|
||||
icons_available = list()
|
||||
|
||||
if(recording)
|
||||
icons_available += list("Stop Recording" = image(icon = icon_directory, icon_state = "record_stop"))
|
||||
else
|
||||
if(!playing)
|
||||
icons_available += list("Record" = image(icon = icon_directory, icon_state = "record"))
|
||||
|
||||
if(playing)
|
||||
icons_available += list("Pause" = image(icon = icon_directory, icon_state = "pause"))
|
||||
else
|
||||
if(!recording)
|
||||
icons_available += list("Play" = image(icon = icon_directory, icon_state = "play"))
|
||||
|
||||
if(canprint && !recording && !playing)
|
||||
icons_available += list("Print Transcript" = image(icon = icon_directory, icon_state = "print"))
|
||||
if(mytape)
|
||||
icons_available += list("Eject" = image(icon = icon_directory, icon_state = "eject"))
|
||||
|
||||
/obj/item/taperecorder/attackby(obj/item/I, mob/user, params)
|
||||
if(!mytape && istype(I, /obj/item/tape))
|
||||
@@ -69,7 +93,6 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/obj/item/taperecorder/verb/ejectverb()
|
||||
set name = "Eject Tape"
|
||||
set category = "Object"
|
||||
@@ -81,7 +104,6 @@
|
||||
|
||||
eject(usr)
|
||||
|
||||
|
||||
/obj/item/taperecorder/update_icon_state()
|
||||
if(!mytape)
|
||||
icon_state = "taperecorder_empty"
|
||||
@@ -92,7 +114,6 @@
|
||||
else
|
||||
icon_state = "taperecorder_idle"
|
||||
|
||||
|
||||
/obj/item/taperecorder/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode, atom/movable/source)
|
||||
. = ..()
|
||||
if(mytape && recording)
|
||||
@@ -193,13 +214,31 @@
|
||||
|
||||
|
||||
/obj/item/taperecorder/attack_self(mob/user)
|
||||
if(!mytape || mytape.ruined)
|
||||
if(!mytape)
|
||||
to_chat(user, "<span class='notice'>The [src] does not have a tape inside.</span>")
|
||||
return
|
||||
if(mytape.ruined)
|
||||
to_chat(user, "<span class='notice'>The tape inside the [src] appears to be broken.</span>")
|
||||
return
|
||||
if(recording)
|
||||
stop()
|
||||
else
|
||||
record()
|
||||
|
||||
update_available_icons()
|
||||
if(icons_available)
|
||||
var/selection = show_radial_menu(user, src, icons_available, radius = 38, require_near = TRUE, tooltips = TRUE)
|
||||
if(!selection)
|
||||
return
|
||||
switch(selection)
|
||||
if("Pause")
|
||||
stop()
|
||||
if("Stop Recording") // yes we actually need 2 seperate stops for the same proc- Hopek
|
||||
stop()
|
||||
if("Record")
|
||||
record()
|
||||
if("Play")
|
||||
play()
|
||||
if("Print Transcript")
|
||||
print_transcript()
|
||||
if("Eject")
|
||||
eject(user)
|
||||
|
||||
/obj/item/taperecorder/verb/print_transcript()
|
||||
set name = "Print Transcript"
|
||||
|
||||
@@ -40,11 +40,11 @@
|
||||
//What does the implant do upon injection?
|
||||
//return 1 if the implant injects
|
||||
//return 0 if there is no room for implant / it fails
|
||||
/obj/item/implant/proc/implant(mob/living/target, mob/user, silent = FALSE)
|
||||
/obj/item/implant/proc/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE)
|
||||
if(SEND_SIGNAL(src, COMSIG_IMPLANT_IMPLANTING, args) & COMPONENT_STOP_IMPLANTING)
|
||||
return
|
||||
LAZYINITLIST(target.implants)
|
||||
if(!target.can_be_implanted() || !can_be_implanted_in(target))
|
||||
if(!force && (!target.can_be_implanted() || !can_be_implanted_in(target)))
|
||||
return FALSE
|
||||
for(var/X in target.implants)
|
||||
var/obj/item/implant/imp_e = X
|
||||
|
||||
@@ -40,17 +40,80 @@
|
||||
|
||||
/obj/item/implant/warp
|
||||
name = "warp implant"
|
||||
desc = "Saves your position somewhere, and then warps you back to it after five seconds."
|
||||
desc = "Warps you to where you were 10 seconds before when activated."
|
||||
icon_state = "warp"
|
||||
uses = 15
|
||||
uses = -1
|
||||
var/total_delay = 10 SECONDS
|
||||
var/cooldown = 10 SECONDS
|
||||
var/last_use = 0
|
||||
var/list/positions = list()
|
||||
var/next_prune = 0
|
||||
|
||||
/obj/item/implant/warp/Destroy()
|
||||
positions = null
|
||||
return ..()
|
||||
|
||||
/obj/item/implant/warp/implant(mob/living/target, mob/user, silent, force)
|
||||
. = ..()
|
||||
if(.)
|
||||
update_position()
|
||||
RegisterSignal(imp_in, COMSIG_MOVABLE_MOVED, .proc/update_position)
|
||||
|
||||
/obj/item/implant/warp/removed(mob/living/source, silent, special)
|
||||
. = ..()
|
||||
clear_positions()
|
||||
|
||||
/obj/item/implant/warp/proc/update_position(datum/source)
|
||||
if(!isatom(imp_in.loc))
|
||||
return
|
||||
positions[num2text(world.time)] = imp_in.loc
|
||||
if(!((++next_prune) % 10))
|
||||
prune()
|
||||
|
||||
/obj/item/implant/warp/proc/clear_positions()
|
||||
positions = list()
|
||||
|
||||
/obj/item/implant/warp/proc/get_tele_position()
|
||||
prune()
|
||||
return positions[positions[1]]
|
||||
|
||||
/obj/item/implant/warp/proc/do_teleport_effects()
|
||||
var/safety = 100
|
||||
var/list/done = list()
|
||||
var/time
|
||||
var/turf/target
|
||||
for(var/i in 1 to positions.len)
|
||||
if(!--safety)
|
||||
break
|
||||
time = positions[i]
|
||||
target = positions[time]
|
||||
if(done[target])
|
||||
continue
|
||||
done[target] = TRUE
|
||||
if(!istype(target))
|
||||
continue
|
||||
new /obj/effect/temp_visual/dir_setting/ninja(target)
|
||||
|
||||
/obj/item/implant/warp/activate()
|
||||
. = ..()
|
||||
uses--
|
||||
imp_in.do_adrenaline(20, TRUE, 0, 0, TRUE, list(/datum/reagent/fermi/eigenstate = 1.2), "<span class='boldnotice'>You feel an internal prick as as the bluespace starts ramping up!</span>")
|
||||
to_chat(imp_in, "<span class='notice'>You feel an internal prick as as the bluespace starts ramping up!</span>")
|
||||
if(!uses)
|
||||
qdel(src)
|
||||
if(last_use + cooldown > world.time)
|
||||
to_chat(imp_in, "<span class=warning'>[src] is still recharging!</span>")
|
||||
return
|
||||
last_use = world.time
|
||||
prune()
|
||||
do_teleport_effects() //first.
|
||||
do_teleport(imp_in, get_tele_position(), 0, TRUE, null, null, null, null, null, TELEPORT_CHANNEL_QUANTUM, TRUE)
|
||||
|
||||
/obj/item/implant/warp/proc/prune()
|
||||
var/minimum_time = world.time - total_delay
|
||||
var/remove = 0
|
||||
for(var/i in 1 to length(positions))
|
||||
if(text2num(positions[i]) < minimum_time)
|
||||
remove++
|
||||
else
|
||||
break
|
||||
if(remove)
|
||||
positions.Cut(1, remove + 1)
|
||||
|
||||
/obj/item/implanter/warp
|
||||
name = "implanter (warp)"
|
||||
|
||||
@@ -190,12 +190,53 @@
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/saber
|
||||
possible_colors = list("red" = LIGHT_COLOR_RED, "blue" = LIGHT_COLOR_LIGHT_CYAN, "green" = LIGHT_COLOR_GREEN, "purple" = LIGHT_COLOR_LAVENDER)
|
||||
unique_reskin = list("Sword" = "sword0", "saber" = "esaber0")
|
||||
var/hacked = FALSE
|
||||
var/saber = FALSE
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/saber/set_sword_color()
|
||||
if(LAZYLEN(possible_colors))
|
||||
/obj/item/melee/transforming/energy/sword/saber/transform_weapon(mob/living/user, supress_message_text)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(active)
|
||||
if(sword_color)
|
||||
if(saber)
|
||||
icon_state = "esaber[sword_color]"
|
||||
else
|
||||
icon_state = "sword[sword_color]"
|
||||
else
|
||||
if(saber)
|
||||
icon_state = "esaber0"
|
||||
else
|
||||
icon_state = "sword0"
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/saber/reskin_obj(mob/M)
|
||||
. = ..()
|
||||
if(icon_state == "esaber0")
|
||||
saber = TRUE
|
||||
if(active)
|
||||
if(saber)
|
||||
icon_state = "esaber[sword_color]"
|
||||
else
|
||||
icon_state = "sword[sword_color]"
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/saber/set_sword_color(var/color_forced)
|
||||
if(color_forced) // wow i really do not like this at fucking all holy SHIT
|
||||
if(color_forced == "red")
|
||||
sword_color = "red"
|
||||
light_color = LIGHT_COLOR_RED
|
||||
else if(color_forced == "blue")
|
||||
sword_color = "blue"
|
||||
light_color = LIGHT_COLOR_LIGHT_CYAN
|
||||
else if(color_forced == "green")
|
||||
sword_color = "green"
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
else if(color_forced == "purple")
|
||||
sword_color = "purple"
|
||||
light_color = LIGHT_COLOR_LAVENDER
|
||||
else if(LAZYLEN(possible_colors))
|
||||
sword_color = pick(possible_colors)
|
||||
light_color = possible_colors[sword_color]
|
||||
return
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/saber/process()
|
||||
. = ..()
|
||||
@@ -204,30 +245,59 @@
|
||||
light_color = possible_colors[set_color]
|
||||
update_light()
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/saber/red
|
||||
possible_colors = list("red" = LIGHT_COLOR_RED)
|
||||
/obj/item/melee/transforming/energy/sword/saber/red/Initialize(mapload)
|
||||
. = ..()
|
||||
set_sword_color("red")
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/saber/blue
|
||||
possible_colors = list("blue" = LIGHT_COLOR_LIGHT_CYAN)
|
||||
/obj/item/melee/transforming/energy/sword/saber/blue/Initialize(mapload)
|
||||
. = ..()
|
||||
set_sword_color("blue")
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/saber/green
|
||||
possible_colors = list("green" = LIGHT_COLOR_GREEN)
|
||||
/obj/item/melee/transforming/energy/sword/saber/green/Initialize(mapload)
|
||||
. = ..()
|
||||
set_sword_color("green")
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/saber/purple
|
||||
possible_colors = list("purple" = LIGHT_COLOR_LAVENDER)
|
||||
/obj/item/melee/transforming/energy/sword/saber/purple/Initialize(mapload)
|
||||
. = ..()
|
||||
set_sword_color("purple")
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/saber/proc/select_sword_color(mob/user) /// this is for the radial
|
||||
if(!istype(user) || user.incapacitated())
|
||||
return
|
||||
|
||||
var/static/list/options = list(
|
||||
"red" = image(icon = 'icons/obj/items_and_weapons.dmi', icon_state = "swordred-blade"),
|
||||
"blue" = image(icon = 'icons/obj/items_and_weapons.dmi', icon_state = "swordblue-blade"),
|
||||
"green" = image(icon = 'icons/obj/items_and_weapons.dmi', icon_state = "swordgreen-blade"),
|
||||
"purple" = image(icon = 'icons/obj/items_and_weapons.dmi', icon_state = "swordpurple-blade")
|
||||
)
|
||||
|
||||
var/choice = show_radial_menu(user, src, options, custom_check = FALSE, radius = 36, require_near = TRUE)
|
||||
|
||||
if(src && choice && !user.incapacitated() && in_range(user,src))
|
||||
set_sword_color(choice)
|
||||
to_chat(user, "<span class='notice'>[src] is now [choice].</span>")
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/saber/attackby(obj/item/W, mob/living/user, params)
|
||||
if(istype(W, /obj/item/multitool))
|
||||
if(user.a_intent == INTENT_DISARM)
|
||||
if(!active)
|
||||
to_chat(user, "<span class='warning'>COLOR_SET</span>")
|
||||
hacked = FALSE
|
||||
select_sword_color(user)
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>Turn it off first - getting that close to an active sword is not a great idea.</span>")
|
||||
return
|
||||
if(!hacked)
|
||||
hacked = TRUE
|
||||
sword_color = "rainbow"
|
||||
to_chat(user, "<span class='warning'>RNBW_ENGAGE</span>")
|
||||
|
||||
if(active)
|
||||
icon_state = "swordrainbow"
|
||||
user.update_inv_hands()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>It's already fabulous!</span>")
|
||||
to_chat(user, "<span class='warning'>It's already fabulous!</span> <span class='notice'>If you wanted to reset the color, though, try a disarming intent while it's off.</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
msg = "You hear something crackle in your ears for a moment before a voice speaks. \"Please stand by for a message from Central Command. Message as follows: <span class='bold'>Item request received. Your package is inbound, please stand back from the landing site.</span> Message ends.\""
|
||||
to_chat(M, msg)
|
||||
|
||||
new /obj/effect/abstract/DPtarget(get_turf(src), pod)
|
||||
new /obj/effect/pod_landingzone(get_turf(src), pod)
|
||||
|
||||
/obj/item/choice_beacon/ingredients
|
||||
name = "ingredient box delivery beacon"
|
||||
|
||||
@@ -199,4 +199,12 @@
|
||||
|
||||
/obj/item/pinpointer/shuttle/Destroy()
|
||||
shuttleport = null
|
||||
. = ..()
|
||||
. = ..()
|
||||
|
||||
/obj/item/pinpointer/ian
|
||||
name = "ian pinpointer"
|
||||
desc = "A handheld tracking device that locates Ian. Made with real corgis!"
|
||||
icon_state = "pinpointer_ian"
|
||||
|
||||
/obj/item/pinpointer/ian/scan_for_target()
|
||||
target = locate(/mob/living/simple_animal/pet/dog/corgi/Ian) in GLOB.mob_living_list
|
||||
|
||||
@@ -234,7 +234,7 @@
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_combined_w_class = 100
|
||||
STR.max_items = 100
|
||||
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/grown, /obj/item/seeds, /obj/item/grown, /obj/item/reagent_containers/honeycomb))
|
||||
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/grown, /obj/item/seeds, /obj/item/grown, /obj/item/reagent_containers/honeycomb, /obj/item/disk/plantgene))
|
||||
|
||||
////////
|
||||
|
||||
|
||||
@@ -830,3 +830,28 @@
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 2
|
||||
STR.max_w_class = WEIGHT_CLASS_BULKY + WEIGHT_CLASS_NORMAL //katana and waki.
|
||||
|
||||
/obj/item/storage/belt/plant
|
||||
name = "botanical belt"
|
||||
desc = "A belt used to hold most hydroponics supplies. Suprisingly, not green."
|
||||
icon_state = "plantbelt"
|
||||
item_state = "plantbelt"
|
||||
content_overlays = TRUE
|
||||
|
||||
/obj/item/storage/belt/plant/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.can_hold = typecacheof(list(
|
||||
/obj/item/reagent_containers/spray/plantbgone,
|
||||
/obj/item/plant_analyzer,
|
||||
/obj/item/seeds,
|
||||
/obj/item/reagent_containers/glass/bottle,
|
||||
/obj/item/reagent_containers/glass/beaker,
|
||||
/obj/item/cultivator,
|
||||
/obj/item/reagent_containers/spray/pestspray,
|
||||
/obj/item/hatchet,
|
||||
/obj/item/shovel/spade,
|
||||
/obj/item/gun/energy/floragun
|
||||
))
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
icon_state = "crowbar_clock"
|
||||
toolspeed = 0.5
|
||||
|
||||
/obj/item/crowbar/brass/family
|
||||
toolspeed = 1
|
||||
|
||||
/obj/item/crowbar/bronze
|
||||
name = "bronze plated crowbar"
|
||||
desc = "A bronze plated crowbar."
|
||||
|
||||
@@ -89,6 +89,9 @@
|
||||
toolspeed = 0.5
|
||||
random_color = FALSE
|
||||
|
||||
/obj/item/screwdriver/brass/family
|
||||
toolspeed = 1
|
||||
|
||||
/obj/item/screwdriver/bronze
|
||||
name = "bronze screwdriver"
|
||||
desc = "A screwdriver plated with bronze."
|
||||
|
||||
@@ -69,6 +69,9 @@
|
||||
random_color = FALSE
|
||||
toolspeed = 0.5
|
||||
|
||||
/obj/item/wirecutters/brass/family
|
||||
toolspeed = 1
|
||||
|
||||
/obj/item/wirecutters/bronze
|
||||
name = "bronze plated wirecutters"
|
||||
desc = "A pair of wirecutters plated with bronze."
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
icon_state = "wrench_clock"
|
||||
toolspeed = 0.5
|
||||
|
||||
/obj/item/wrench/brass/family
|
||||
toolspeed = 1
|
||||
|
||||
/obj/item/wrench/bronze
|
||||
name = "bronze plated wrench"
|
||||
desc = "A bronze plated wrench."
|
||||
|
||||
+29
-11
@@ -304,18 +304,36 @@
|
||||
/obj/proc/reskin_obj(mob/M)
|
||||
if(!LAZYLEN(unique_reskin))
|
||||
return
|
||||
var/list/skins = list()
|
||||
for(var/S in unique_reskin)
|
||||
skins[S] = image(icon = icon, icon_state = unique_reskin[S])
|
||||
var/choice = show_radial_menu(M, src, skins, custom_check = CALLBACK(src, .proc/check_skinnable, M), radius = 40, require_near = TRUE)
|
||||
if(!choice)
|
||||
return FALSE
|
||||
icon_state = unique_reskin[choice]
|
||||
current_skin = choice
|
||||
return
|
||||
|
||||
/obj/proc/check_skinnable(/mob/M)
|
||||
if(current_skin || !always_reskinnable)
|
||||
var/list/items = list()
|
||||
for(var/reskin_option in unique_reskin)
|
||||
var/image/item_image = image(icon = src.icon, icon_state = unique_reskin[reskin_option])
|
||||
items += list("[reskin_option]" = item_image)
|
||||
sortList(items)
|
||||
|
||||
var/pick = show_radial_menu(M, src, items, custom_check = CALLBACK(src, .proc/check_reskin_menu, M), radius = 38, require_near = TRUE)
|
||||
if(!pick)
|
||||
return
|
||||
if(!unique_reskin[pick])
|
||||
return
|
||||
current_skin = pick
|
||||
icon_state = unique_reskin[pick]
|
||||
to_chat(M, "[src] is now skinned as '[pick].'")
|
||||
|
||||
/**
|
||||
* Checks if we are allowed to interact with a radial menu for reskins
|
||||
*
|
||||
* Arguments:
|
||||
* * user The mob interacting with the menu
|
||||
*/
|
||||
/obj/proc/check_reskin_menu(mob/user)
|
||||
if(QDELETED(src))
|
||||
return FALSE
|
||||
if(current_skin)
|
||||
return FALSE
|
||||
if(!istype(user))
|
||||
return FALSE
|
||||
if(user.incapacitated())
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
number_of_rods = 2
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = null
|
||||
obj_flags = CAN_BE_HIT | BLOCK_Z_FALL
|
||||
obj_flags = CAN_BE_HIT | BLOCK_Z_OUT_DOWN | BLOCK_Z_IN_UP
|
||||
|
||||
/obj/structure/lattice/catwalk/deconstruction_hints(mob/user)
|
||||
to_chat(user, "<span class='notice'>The supporting rods look like they could be <b>cut</b>.</span>")
|
||||
@@ -159,7 +159,7 @@
|
||||
color = "#5286b9ff"
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = null
|
||||
obj_flags = CAN_BE_HIT | BLOCK_Z_FALL
|
||||
obj_flags = CAN_BE_HIT | BLOCK_Z_OUT_DOWN | BLOCK_Z_IN_UP
|
||||
resistance_flags = FIRE_PROOF | LAVA_PROOF
|
||||
|
||||
/obj/structure/lattice/lava/deconstruction_hints(mob/user)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
max_integrity = 100
|
||||
buckle_lying = FALSE
|
||||
layer = ABOVE_MOB_LAYER
|
||||
var/view_range = 10
|
||||
var/view_range = 3
|
||||
var/cooldown = 0
|
||||
var/projectile_type = /obj/item/projectile/bullet/manned_turret
|
||||
var/rate_of_fire = 1
|
||||
@@ -38,7 +38,7 @@
|
||||
buckled_mob.pixel_x = 0
|
||||
buckled_mob.pixel_y = 0
|
||||
if(buckled_mob.client)
|
||||
buckled_mob.client.change_view(CONFIG_GET(string/default_view))
|
||||
buckled_mob.client.view_size.resetToDefault()
|
||||
anchored = FALSE
|
||||
. = ..()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
@@ -65,7 +65,7 @@
|
||||
playsound(src,'sound/mecha/mechmove01.ogg', 50, 1)
|
||||
anchored = TRUE
|
||||
if(M.client)
|
||||
M.client.change_view(view_range)
|
||||
M.client.view_size.setTo(view_range)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/obj/machinery/manned_turret/process()
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
if(user.grab_state < GRAB_AGGRESSIVE)
|
||||
to_chat(user, "<span class='warning'>You need a better grip to do that!</span>")
|
||||
return
|
||||
if(user.grab_state >= GRAB_NECK)
|
||||
if(user.grab_state >= GRAB_NECK || HAS_TRAIT(user, TRAIT_MAULER))
|
||||
tablelimbsmash(user, pushed_mob)
|
||||
else
|
||||
tablepush(user, pushed_mob)
|
||||
@@ -147,7 +147,7 @@
|
||||
pushed_mob.Knockdown(30)
|
||||
var/obj/item/bodypart/banged_limb = pushed_mob.get_bodypart(user.zone_selected) || pushed_mob.get_bodypart(BODY_ZONE_HEAD)
|
||||
var/extra_wound = 0
|
||||
if(HAS_TRAIT(user, TRAIT_HULK))
|
||||
if(HAS_TRAIT(user, TRAIT_HULK) || HAS_TRAIT(user, TRAIT_MAULER))
|
||||
extra_wound = 20
|
||||
banged_limb.receive_damage(30, wound_bonus = extra_wound)
|
||||
pushed_mob.apply_damage(60, STAMINA)
|
||||
|
||||
+12
-2
@@ -18,11 +18,21 @@
|
||||
|
||||
//direction is direction of travel of A
|
||||
/turf/open/zPassIn(atom/movable/A, direction, turf/source)
|
||||
return (direction == DOWN)
|
||||
if(direction == DOWN)
|
||||
for(var/obj/O in contents)
|
||||
if(O.obj_flags & BLOCK_Z_IN_DOWN)
|
||||
return FALSE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//direction is direction of travel of A
|
||||
/turf/open/zPassOut(atom/movable/A, direction, turf/destination)
|
||||
return (direction == UP)
|
||||
if(direction == UP)
|
||||
for(var/obj/O in contents)
|
||||
if(O.obj_flags & BLOCK_Z_OUT_UP)
|
||||
return FALSE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//direction is direction of travel of air
|
||||
/turf/open/zAirIn(direction, turf/source)
|
||||
|
||||
@@ -49,15 +49,32 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
return TRUE
|
||||
|
||||
/turf/open/transparent/openspace/zPassIn(atom/movable/A, direction, turf/source)
|
||||
return TRUE
|
||||
if(direction == DOWN)
|
||||
for(var/obj/O in contents)
|
||||
if(O.obj_flags & BLOCK_Z_IN_DOWN)
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(direction == UP)
|
||||
for(var/obj/O in contents)
|
||||
if(O.obj_flags & BLOCK_Z_IN_UP)
|
||||
return FALSE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/turf/open/transparent/openspace/zPassOut(atom/movable/A, direction, turf/destination)
|
||||
if(A.anchored)
|
||||
return FALSE
|
||||
for(var/obj/O in contents)
|
||||
if(O.obj_flags & BLOCK_Z_FALL)
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(direction == DOWN)
|
||||
for(var/obj/O in contents)
|
||||
if(O.obj_flags & BLOCK_Z_OUT_DOWN)
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(direction == UP)
|
||||
for(var/obj/O in contents)
|
||||
if(O.obj_flags & BLOCK_Z_OUT_UP)
|
||||
return FALSE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/turf/open/transparent/openspace/proc/CanCoverUp()
|
||||
return can_cover_up
|
||||
|
||||
@@ -204,7 +204,8 @@
|
||||
digResult = /obj/item/stack/sheet/mineral/snow
|
||||
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/wolf = 50, /obj/structure/spawner/ice_moon = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear = 30, /obj/structure/spawner/ice_moon/polarbear = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50, /mob/living/simple_animal/hostile/asteroid/goldgrub = 10)
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50, /mob/living/simple_animal/hostile/asteroid/goldgrub = 10, \
|
||||
/mob/living/simple_animal/hostile/asteroid/lobstrosity = 15)
|
||||
flora_spawn_list = list(/obj/structure/flora/tree/pine = 2, /obj/structure/flora/grass/both = 12, /obj/structure/flora/rock/icy = 6, /obj/structure/flora/rock/pile/icy = 6)
|
||||
data_having_type = /turf/open/floor/plating/asteroid/airless/cave/snow/has_data
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
|
||||
@@ -235,3 +235,110 @@
|
||||
destination_x = dest_x
|
||||
destination_y = dest_y
|
||||
destination_z = dest_z
|
||||
|
||||
|
||||
/turf/open/space/transparent
|
||||
baseturfs = /turf/open/space/transparent/openspace
|
||||
intact = FALSE //this means wires go on top
|
||||
|
||||
/turf/open/space/transparent/Initialize() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker
|
||||
..()
|
||||
plane = OPENSPACE_PLANE
|
||||
layer = OPENSPACE_LAYER
|
||||
icon_state = "transparent"
|
||||
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/turf/open/space/transparent/LateInitialize()
|
||||
update_multiz(TRUE, TRUE)
|
||||
|
||||
/turf/open/space/transparent/Destroy()
|
||||
vis_contents.len = 0
|
||||
return ..()
|
||||
|
||||
/turf/open/space/transparent/update_multiz(prune_on_fail = FALSE, init = FALSE)
|
||||
. = ..()
|
||||
var/turf/T = below()
|
||||
if(!T)
|
||||
vis_contents.len = 0
|
||||
if(!show_bottom_level() && prune_on_fail) //If we cant show whats below, and we prune on fail, change the turf to space as a fallback
|
||||
ChangeTurf(/turf/open/space)
|
||||
return FALSE
|
||||
if(init)
|
||||
vis_contents += T
|
||||
return TRUE
|
||||
|
||||
/turf/open/space/transparent/multiz_turf_del(turf/T, dir)
|
||||
if(dir != DOWN)
|
||||
return
|
||||
update_multiz()
|
||||
|
||||
/turf/open/space/transparent/multiz_turf_new(turf/T, dir)
|
||||
if(dir != DOWN)
|
||||
return
|
||||
update_multiz()
|
||||
|
||||
///Called when there is no real turf below this turf
|
||||
/turf/open/space/transparent/proc/show_bottom_level()
|
||||
var/turf/path = SSmapping.level_trait(z, ZTRAIT_BASETURF) || /turf/open/space
|
||||
if(!ispath(path))
|
||||
path = text2path(path)
|
||||
if(!ispath(path))
|
||||
warning("Z-level [z] has invalid baseturf '[SSmapping.level_trait(z, ZTRAIT_BASETURF)]'")
|
||||
path = /turf/open/space
|
||||
var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), initial(path.icon_state), layer = TURF_LAYER, plane = PLANE_SPACE)
|
||||
underlays += underlay_appearance
|
||||
return TRUE
|
||||
|
||||
/turf/open/space/transparent/openspace
|
||||
name = "open space"
|
||||
desc = "Watch your step!"
|
||||
icon_state = "transparent"
|
||||
baseturfs = /turf/open/space/transparent/openspace
|
||||
CanAtmosPassVertical = ATMOS_PASS_YES
|
||||
//mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
///No bottom level for openspace.
|
||||
/turf/open/space/transparent/openspace/show_bottom_level()
|
||||
return FALSE
|
||||
|
||||
/turf/open/space/transparent/openspace/Initialize() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker
|
||||
. = ..()
|
||||
|
||||
icon_state = "transparent"
|
||||
|
||||
vis_contents += GLOB.openspace_backdrop_one_for_all //Special grey square for projecting backdrop darkness filter on it.
|
||||
|
||||
/turf/open/space/transparent/openspace/zAirIn()
|
||||
return TRUE
|
||||
|
||||
/turf/open/space/transparent/openspace/zAirOut()
|
||||
return TRUE
|
||||
|
||||
/turf/open/space/transparent/openspace/zPassIn(atom/movable/A, direction, turf/source)
|
||||
if(direction == DOWN)
|
||||
for(var/obj/O in contents)
|
||||
if(O.obj_flags & BLOCK_Z_IN_DOWN)
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(direction == UP)
|
||||
for(var/obj/O in contents)
|
||||
if(O.obj_flags & BLOCK_Z_IN_UP)
|
||||
return FALSE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/turf/open/space/transparent/openspace/zPassOut(atom/movable/A, direction, turf/destination)
|
||||
if(A.anchored)
|
||||
return FALSE
|
||||
if(direction == DOWN)
|
||||
for(var/obj/O in contents)
|
||||
if(O.obj_flags & BLOCK_Z_OUT_DOWN)
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(direction == UP)
|
||||
for(var/obj/O in contents)
|
||||
if(O.obj_flags & BLOCK_Z_OUT_UP)
|
||||
return FALSE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
Reference in New Issue
Block a user