mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-19 05:26:28 +00:00
## About The Pull Request The changes made can be best summarized into points **1. Cleans up `code/_DEFINES/construction.dm`** Looking at the top comment of this file0fb8b8b218/code/__DEFINES/construction.dm (L1)One would expect stuff related to materials, rcd, and other construction related stuff. Well this file is anything but Why is there stuff related to food & crafting over here then?0fb8b8b218/code/__DEFINES/construction.dm (L91-L94)It gets worse why are global lists declared here?0fb8b8b218/code/__DEFINES/construction.dm (L115)There is a dedicated folder to store global lists i.e. `code/_globalvars/lists` for lists like these. These clearly don't belong here On top of that a lot of construction related defines has been just dumped here making it too large for it's purposes. which is why this file has been scraped and it's 1. crafting related stuff have been moved to its `code/_DEFINES/crafting.dm` 2. global lists for crafting moved to `code/_globalvars/lists/crafting.dm` 3. Finally remaining construction related defines split apart into 4 file types under the new `code/_DEFINES/construction` folder - `code/_DEFINES/construction/actions.dm` -> for wrench act or other construction related actions - `code/_DEFINES/construction/material.dm` -> contains your sheet defines and cable & stack related values. Also merged `code/_DEFINES/material.dm` with this file so it belongs in one place - `code/_DEFINES/construction/rcd.dm` -> dedicated file for everything rcd related - `code/_DEFINES/construction/structures.dm` -> contains the construction states for various stuff like walls, girders, floodlight etc By splitting this file into multiple meaningful define file names will help in reducing merge conflicts and will aid in faster navigation so this is the 1st part of this PR **2. Debloats the `RCD.dm` file(Part 1)** This uses the same concepts as above. i.e. moving defines into their appropriate files for e.g.0fb8b8b218/code/game/objects/items/rcd/RCD.dm (L170)1. Global vars belong in the `code/_globalvars` folder so these vars and their related functions to initialize them are moved into the `code/_globalvars/rcd.dm` file 2. See this proc0fb8b8b218/code/game/objects/items/rcd/RCD.dm (L200)This proc does not belong to the `obj/item/construction/rcd` type it's a global "helper function" this is an effect proc as it creates rcd holograms so it has been moved to the `code/game/objects/effects/rcd.dm` file which is a global effect that can be used by anyone And with that we have moved these vars & procs into their correct places & reduced the size of this file . We can go even further **3. Debloats the `RCD.dm` file(Part 2)** This deals with the large list which contains all the designs supported by the RCD0fb8b8b218/code/game/objects/items/rcd/RCD.dm (L42)This list contains a lot of local defines. We can scrape some of them and reduce the overall bulkiness & memory requirements of this list and so the following defines ``` #define WINDOW_TYPE "window_type" #define COMPUTER_DIR "computer_dir" #define WALLFRAME_TYPE "wallframe_type" #define FURNISH_TYPE "furnish_type" #define AIRLOCK_TYPE "airlock_type" #define TITLE "title" #define ICON "icon" #define CATEGORY_ICON_STATE "category_icon_state" #define CATEGORY_ICON_SUFFIX "category_icon_suffix" #define TITLE_ICON "ICON=TITLE" ``` Have all been removed making this list a lot more cleaner. Why? because a lot of these are just semantic sugar, we can infer the value of a lot of these defines if we just know the type path of the structure the rcd is trying to build for e.g. take these 2 defines0fb8b8b218/code/game/objects/items/rcd/RCD.dm (L13-L15)These defines tell the rcd UI the name and the icon it should display. Rather than specifying these manually in the design we can infer them like this ``` var/obj/design = /obj/structure/window //let's say the rcd is trying to build an window var/name = initial(design.name) //we have inferred the name of the design without requiring TITLE define var/icon = initial(design.icon_state) //we have inferred the icon of the design without requiring ICON define ``` And so by using similar logic to the remaining defines we can eliminate a lot of these local defines and reduce the overall size of this list. The same logic applies to the different modes of construction, the following defines0fb8b8b218/code/__DEFINES/construction.dm (L186-L192)Have all been removed and replaced with a single value `RCD_STRUCTURE` All these modes follow the same principle when building them 1. First check the turf if the structure exists. If it does early return 2. If not create a new structure there and that's it So rather than creating a new construction mode every time you want to add a new design we can use this mode to apply this general approach every time The design list has also now been made into a global list rather than a private static list. The big advantage to this is that the rcd asset cache can now access this list and load the correct icons from the list directly. This means you no longer have to manually specify what icons you want to load which is the case currently.0fb8b8b218/code/modules/asset_cache/assets/rcd.dm (L8-L9)This has lead to the UI icons breaking twice now in the past - #74194 - #77217 Hopefully this should never repeat itself again **4. Other RCD like device changes** - Fixed the broken silo link icon when the radial menu of the RLD was opened - replaced a lot of vars inside RLD with defines to save memory - Small changes to `ui_act` across RCD, Plumbing RCD and RTD - Removed unused vars in RCD and snowflaked code - Moved a large majority of `ui_data()` to `ui_static_data()` making the experience much faster Just some general clean up going on here **5. The Large majority of other code changes** These are actually small code changes spread across multiple files. These effect the `rcd_act()` & the `rcd_vals()` procs across all items. Basically it - Removes a large majority of `to_chat()` & `visible_message()` calls. This was done because we already have enough visual feedback of what's going on. When we construct a wall we don't need a `to_chat()` to tell us you have a built a wall, we can clearly see that - replaces the static string `"mode"` with a predefined constant `RCD_DESIGN_MODE` to bring some standard to use across all cases Should reduce chat spam and improve readability of code. **6. Airlock & Window names** The rcd asset cache relies on the design name to be unique. So i filled in the missing names for some airlocks & windows which are subjective and open to change but must have some value **7 Removes Microwave PDA upgrade** The RCD should not be allowed to build this microwave considering how quickly it can spawn multiple structures and more importantly as it's a special multipurpose machine so you should spend some effort in printing it's parts and acquiring tools to complete it. This upgrade makes obsolete the need to carry an - A RPED to install the parts - A screwdriver to complete the frame - The circuit board for the microwave The most important point to note here is that whenever an RPED/circuit board is printed at an lathe it charges you "Lathe Tax". The RCD with this upgrade would essentially bypass the need to "Pay Taxes" at these lathes as you are just creating a circuit board from thin air. This causes economy imbalance(10 cr per print) which scales up the more of these machines you make so to avoid this let's end the problem here Not to mention people would not find the need to print the circuit board for a regular microwave now if they have an RCD because they can just make this microwave type making the need for a regular microwave completely pointless. Just build a machine frame with the RCD and complete the microwave from there ## Changelog 🆑 code: moved global vars, lists and helper procs for construction related stuff to their appropriate files code: reduced overall code size & memory of rcd design list and removed unused defines refactor: removed a ton of chat alerts for rcd related actions to help reduce chat spam refactor: some airlock & window default names have changed fix: broken icon in radial menu of rld silo link remove: removes microwave pda upgrade from RCD. It's a special machine so spend some time in building it rather than shitting them out for free with the RCD. Use the RCD upgrade to spawn a machine frame instead & go from there /🆑 --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
898 lines
31 KiB
Plaintext
898 lines
31 KiB
Plaintext
/* Tables and Racks
|
|
* Contains:
|
|
* Tables
|
|
* Glass Tables
|
|
* Wooden Tables
|
|
* Reinforced Tables
|
|
* Racks
|
|
* Rack Parts
|
|
*/
|
|
|
|
/*
|
|
* Tables
|
|
*/
|
|
|
|
/obj/structure/table
|
|
name = "table"
|
|
desc = "A square piece of iron standing on four metal legs. It can not move."
|
|
icon = 'icons/obj/smooth_structures/table.dmi'
|
|
icon_state = "table-0"
|
|
base_icon_state = "table"
|
|
density = TRUE
|
|
anchored = TRUE
|
|
pass_flags_self = PASSTABLE | LETPASSTHROW
|
|
layer = TABLE_LAYER
|
|
obj_flags = CAN_BE_HIT | IGNORE_DENSITY
|
|
custom_materials = list(/datum/material/iron =SHEET_MATERIAL_AMOUNT)
|
|
max_integrity = 100
|
|
integrity_failure = 0.33
|
|
smoothing_flags = SMOOTH_BITMASK
|
|
smoothing_groups = SMOOTH_GROUP_TABLES
|
|
canSmoothWith = SMOOTH_GROUP_TABLES
|
|
///TRUE if the table can be climbed on and have living mobs placed on it normally, FALSE otherwise
|
|
var/climbable = TRUE
|
|
var/frame = /obj/structure/table_frame
|
|
var/framestack = /obj/item/stack/rods
|
|
var/glass_shard_type = /obj/item/shard
|
|
var/buildstack = /obj/item/stack/sheet/iron
|
|
var/busy = FALSE
|
|
var/buildstackamount = 1
|
|
var/framestackamount = 2
|
|
var/deconstruction_ready = TRUE
|
|
|
|
/obj/structure/table/Initialize(mapload, _buildstack)
|
|
. = ..()
|
|
if(_buildstack)
|
|
buildstack = _buildstack
|
|
AddElement(/datum/element/footstep_override, priority = STEP_SOUND_TABLE_PRIORITY)
|
|
|
|
if (climbable)
|
|
AddElement(/datum/element/climbable)
|
|
|
|
var/static/list/loc_connections = list(
|
|
COMSIG_CARBON_DISARM_COLLIDE = PROC_REF(table_carbon),
|
|
)
|
|
|
|
AddElement(/datum/element/connect_loc, loc_connections)
|
|
var/static/list/give_turf_traits = list(TRAIT_TURF_IGNORE_SLOWDOWN, TRAIT_TURF_IGNORE_SLIPPERY, TRAIT_IMMERSE_STOPPED)
|
|
AddElement(/datum/element/give_turf_traits, give_turf_traits)
|
|
register_context()
|
|
|
|
/obj/structure/table/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
|
|
. = ..()
|
|
|
|
if(isnull(held_item))
|
|
return NONE
|
|
|
|
if(istype(held_item, /obj/item/toy/cards/deck))
|
|
var/obj/item/toy/cards/deck/dealer_deck = held_item
|
|
if(HAS_TRAIT(dealer_deck, TRAIT_WIELDED))
|
|
context[SCREENTIP_CONTEXT_LMB] = "Deal card"
|
|
context[SCREENTIP_CONTEXT_RMB] = "Deal card faceup"
|
|
. = CONTEXTUAL_SCREENTIP_SET
|
|
|
|
if(!(flags_1 & NODECONSTRUCT_1) && deconstruction_ready)
|
|
if(held_item.tool_behaviour == TOOL_SCREWDRIVER)
|
|
context[SCREENTIP_CONTEXT_RMB] = "Disassemble"
|
|
. = CONTEXTUAL_SCREENTIP_SET
|
|
if(held_item.tool_behaviour == TOOL_WRENCH)
|
|
context[SCREENTIP_CONTEXT_RMB] = "Deconstruct"
|
|
. = CONTEXTUAL_SCREENTIP_SET
|
|
|
|
return . || NONE
|
|
|
|
/obj/structure/table/examine(mob/user)
|
|
. = ..()
|
|
. += deconstruction_hints(user)
|
|
|
|
/obj/structure/table/proc/deconstruction_hints(mob/user)
|
|
return span_notice("The top is <b>screwed</b> on, but the main <b>bolts</b> are also visible.")
|
|
|
|
/obj/structure/table/update_icon(updates=ALL)
|
|
. = ..()
|
|
if((updates & UPDATE_SMOOTHING) && (smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK)))
|
|
QUEUE_SMOOTH(src)
|
|
QUEUE_SMOOTH_NEIGHBORS(src)
|
|
|
|
/obj/structure/table/narsie_act()
|
|
var/atom/A = loc
|
|
qdel(src)
|
|
new /obj/structure/table/wood(A)
|
|
|
|
/obj/structure/table/attack_paw(mob/user, list/modifiers)
|
|
return attack_hand(user, modifiers)
|
|
|
|
/obj/structure/table/attack_hand(mob/living/user, list/modifiers)
|
|
if(Adjacent(user) && user.pulling)
|
|
if(isliving(user.pulling))
|
|
var/mob/living/pushed_mob = user.pulling
|
|
if(pushed_mob.buckled)
|
|
if(pushed_mob.buckled == src)
|
|
//Already buckled to the table, you probably meant to unbuckle them
|
|
return ..()
|
|
to_chat(user, span_warning("[pushed_mob] is buckled to [pushed_mob.buckled]!"))
|
|
return
|
|
if(user.combat_mode)
|
|
switch(user.grab_state)
|
|
if(GRAB_PASSIVE)
|
|
to_chat(user, span_warning("You need a better grip to do that!"))
|
|
return
|
|
if(GRAB_AGGRESSIVE)
|
|
tablepush(user, pushed_mob)
|
|
if(GRAB_NECK to GRAB_KILL)
|
|
tablelimbsmash(user, pushed_mob)
|
|
else
|
|
pushed_mob.visible_message(span_notice("[user] begins to place [pushed_mob] onto [src]..."), \
|
|
span_userdanger("[user] begins to place [pushed_mob] onto [src]..."))
|
|
if(do_after(user, 3.5 SECONDS, target = pushed_mob))
|
|
tableplace(user, pushed_mob)
|
|
else
|
|
return
|
|
user.stop_pulling()
|
|
else if(user.pulling.pass_flags & PASSTABLE)
|
|
user.Move_Pulled(src)
|
|
if (user.pulling.loc == loc)
|
|
user.visible_message(span_notice("[user] places [user.pulling] onto [src]."),
|
|
span_notice("You place [user.pulling] onto [src]."))
|
|
user.stop_pulling()
|
|
return ..()
|
|
|
|
/obj/structure/table/attack_tk(mob/user)
|
|
return
|
|
|
|
/obj/structure/table/CanAllowThrough(atom/movable/mover, border_dir)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
if(mover.throwing)
|
|
return TRUE
|
|
if(locate(/obj/structure/table) in get_turf(mover))
|
|
return TRUE
|
|
|
|
/obj/structure/table/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller, no_id = FALSE)
|
|
. = !density
|
|
if(caller)
|
|
. = . || (caller.pass_flags & PASSTABLE)
|
|
|
|
/obj/structure/table/proc/tableplace(mob/living/user, mob/living/pushed_mob)
|
|
pushed_mob.forceMove(loc)
|
|
pushed_mob.set_resting(TRUE, TRUE)
|
|
pushed_mob.visible_message(span_notice("[user] places [pushed_mob] onto [src]."), \
|
|
span_notice("[user] places [pushed_mob] onto [src]."))
|
|
log_combat(user, pushed_mob, "places", null, "onto [src]")
|
|
|
|
/obj/structure/table/proc/tablepush(mob/living/user, mob/living/pushed_mob)
|
|
if(HAS_TRAIT(user, TRAIT_PACIFISM))
|
|
to_chat(user, span_danger("Throwing [pushed_mob] onto the table might hurt them!"))
|
|
return
|
|
var/passtable_key = REF(user)
|
|
passtable_on(pushed_mob, passtable_key)
|
|
for (var/obj/obj in user.loc.contents)
|
|
if(!obj.CanAllowThrough(pushed_mob))
|
|
return
|
|
pushed_mob.Move(src.loc)
|
|
passtable_off(pushed_mob, passtable_key)
|
|
if(pushed_mob.loc != loc) //Something prevented the tabling
|
|
return
|
|
pushed_mob.Knockdown(30)
|
|
pushed_mob.apply_damage(10, BRUTE)
|
|
pushed_mob.apply_damage(40, STAMINA)
|
|
if(user.mind?.martial_art.smashes_tables && user.mind?.martial_art.can_use(user))
|
|
deconstruct(FALSE)
|
|
playsound(pushed_mob, 'sound/effects/tableslam.ogg', 90, TRUE)
|
|
pushed_mob.visible_message(span_danger("[user] slams [pushed_mob] onto \the [src]!"), \
|
|
span_userdanger("[user] slams you onto \the [src]!"))
|
|
log_combat(user, pushed_mob, "tabled", null, "onto [src]")
|
|
pushed_mob.add_mood_event("table", /datum/mood_event/table)
|
|
|
|
/obj/structure/table/proc/tablelimbsmash(mob/living/user, mob/living/pushed_mob)
|
|
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))
|
|
extra_wound = 20
|
|
banged_limb?.receive_damage(30, wound_bonus = extra_wound)
|
|
pushed_mob.apply_damage(60, STAMINA)
|
|
take_damage(50)
|
|
if(user.mind?.martial_art.smashes_tables && user.mind?.martial_art.can_use(user))
|
|
deconstruct(FALSE)
|
|
playsound(pushed_mob, 'sound/effects/bang.ogg', 90, TRUE)
|
|
pushed_mob.visible_message(span_danger("[user] smashes [pushed_mob]'s [banged_limb.plaintext_zone] against \the [src]!"),
|
|
span_userdanger("[user] smashes your [banged_limb.plaintext_zone] against \the [src]"))
|
|
log_combat(user, pushed_mob, "head slammed", null, "against [src]")
|
|
pushed_mob.add_mood_event("table", /datum/mood_event/table_limbsmash, banged_limb)
|
|
|
|
/obj/structure/table/screwdriver_act_secondary(mob/living/user, obj/item/tool)
|
|
if(flags_1 & NODECONSTRUCT_1 || !deconstruction_ready)
|
|
return FALSE
|
|
to_chat(user, span_notice("You start disassembling [src]..."))
|
|
if(tool.use_tool(src, user, 2 SECONDS, volume=50))
|
|
deconstruct(TRUE)
|
|
return TOOL_ACT_TOOLTYPE_SUCCESS
|
|
|
|
/obj/structure/table/wrench_act_secondary(mob/living/user, obj/item/tool)
|
|
if(flags_1 & NODECONSTRUCT_1 || !deconstruction_ready)
|
|
return FALSE
|
|
to_chat(user, span_notice("You start deconstructing [src]..."))
|
|
if(tool.use_tool(src, user, 4 SECONDS, volume=50))
|
|
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
|
|
deconstruct(TRUE, 1)
|
|
return TOOL_ACT_TOOLTYPE_SUCCESS
|
|
|
|
/obj/structure/table/attackby(obj/item/I, mob/living/user, params)
|
|
var/list/modifiers = params2list(params)
|
|
|
|
if(istype(I, /obj/item/storage/bag/tray))
|
|
var/obj/item/storage/bag/tray/T = I
|
|
if(T.contents.len > 0) // If the tray isn't empty
|
|
for(var/x in T.contents)
|
|
var/obj/item/item = x
|
|
AfterPutItemOnTable(item, user)
|
|
I.atom_storage.remove_all(drop_location())
|
|
user.visible_message(span_notice("[user] empties [I] on [src]."))
|
|
return
|
|
// If the tray IS empty, continue on (tray will be placed on the table like other items)
|
|
|
|
if(istype(I, /obj/item/toy/cards/deck))
|
|
var/obj/item/toy/cards/deck/dealer_deck = I
|
|
if(HAS_TRAIT(dealer_deck, TRAIT_WIELDED)) // deal a card facedown on the table
|
|
var/obj/item/toy/singlecard/card = dealer_deck.draw(user)
|
|
if(card)
|
|
attackby(card, user, params)
|
|
return
|
|
|
|
if(istype(I, /obj/item/riding_offhand))
|
|
var/obj/item/riding_offhand/riding_item = I
|
|
var/mob/living/carried_mob = riding_item.rider
|
|
if(carried_mob == user) //Piggyback user.
|
|
return
|
|
if(user.combat_mode)
|
|
user.unbuckle_mob(carried_mob)
|
|
tablelimbsmash(user, carried_mob)
|
|
else
|
|
var/tableplace_delay = 3.5 SECONDS
|
|
var/skills_space = ""
|
|
if(HAS_TRAIT(user, TRAIT_QUICKER_CARRY))
|
|
tableplace_delay = 2 SECONDS
|
|
skills_space = " expertly"
|
|
else if(HAS_TRAIT(user, TRAIT_QUICK_CARRY))
|
|
tableplace_delay = 2.75 SECONDS
|
|
skills_space = " quickly"
|
|
carried_mob.visible_message(span_notice("[user] begins to[skills_space] place [carried_mob] onto [src]..."),
|
|
span_userdanger("[user] begins to[skills_space] place [carried_mob] onto [src]..."))
|
|
if(do_after(user, tableplace_delay, target = carried_mob))
|
|
user.unbuckle_mob(carried_mob)
|
|
tableplace(user, carried_mob)
|
|
return TRUE
|
|
|
|
if(!user.combat_mode && !(I.item_flags & ABSTRACT))
|
|
if(user.transferItemToLoc(I, drop_location(), silent = FALSE))
|
|
//Center the icon where the user clicked.
|
|
if(!LAZYACCESS(modifiers, ICON_X) || !LAZYACCESS(modifiers, ICON_Y))
|
|
return
|
|
//Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf)
|
|
I.pixel_x = clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(world.icon_size/2), world.icon_size/2)
|
|
I.pixel_y = clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(world.icon_size/2), world.icon_size/2)
|
|
AfterPutItemOnTable(I, user)
|
|
return TRUE
|
|
else
|
|
return ..()
|
|
|
|
/obj/structure/table/attackby_secondary(obj/item/weapon, mob/user, params)
|
|
if(istype(weapon, /obj/item/toy/cards/deck))
|
|
var/obj/item/toy/cards/deck/dealer_deck = weapon
|
|
if(HAS_TRAIT(dealer_deck, TRAIT_WIELDED)) // deal a card faceup on the table
|
|
var/obj/item/toy/singlecard/card = dealer_deck.draw(user)
|
|
if(card)
|
|
card.Flip()
|
|
attackby(card, user, params)
|
|
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
|
..()
|
|
return SECONDARY_ATTACK_CONTINUE_CHAIN
|
|
|
|
/obj/structure/table/proc/AfterPutItemOnTable(obj/item/I, mob/living/user)
|
|
return
|
|
|
|
/obj/structure/table/deconstruct(disassembled = TRUE, wrench_disassembly = 0)
|
|
if(!(flags_1 & NODECONSTRUCT_1))
|
|
var/turf/T = get_turf(src)
|
|
if(buildstack)
|
|
new buildstack(T, buildstackamount)
|
|
else
|
|
for(var/i in custom_materials)
|
|
var/datum/material/M = i
|
|
new M.sheet_type(T, FLOOR(custom_materials[M] / SHEET_MATERIAL_AMOUNT, 1))
|
|
if(!wrench_disassembly)
|
|
new frame(T)
|
|
else
|
|
new framestack(T, framestackamount)
|
|
qdel(src)
|
|
|
|
/obj/structure/table/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
|
|
if(the_rcd.mode == RCD_DECONSTRUCT)
|
|
return list("delay" = 2.4 SECONDS, "cost" = 16)
|
|
return FALSE
|
|
|
|
/obj/structure/table/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data)
|
|
if(rcd_data["[RCD_DESIGN_MODE]"] == RCD_DECONSTRUCT)
|
|
qdel(src)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/obj/structure/table/proc/table_carbon(datum/source, mob/living/carbon/shover, mob/living/carbon/target, shove_blocked)
|
|
SIGNAL_HANDLER
|
|
if(!shove_blocked)
|
|
return
|
|
target.Knockdown(SHOVE_KNOCKDOWN_TABLE)
|
|
target.visible_message(span_danger("[shover.name] shoves [target.name] onto \the [src]!"),
|
|
span_userdanger("You're shoved onto \the [src] by [shover.name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, src)
|
|
to_chat(shover, span_danger("You shove [target.name] onto \the [src]!"))
|
|
target.throw_at(src, 1, 1, null, FALSE) //1 speed throws with no spin are basically just forcemoves with a hard collision check
|
|
log_combat(shover, target, "shoved", "onto [src] (table)")
|
|
return COMSIG_CARBON_SHOVE_HANDLED
|
|
|
|
/obj/structure/table/greyscale
|
|
icon = 'icons/obj/smooth_structures/table_greyscale.dmi'
|
|
icon_state = "table_greyscale-0"
|
|
base_icon_state = "table_greyscale"
|
|
material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS
|
|
buildstack = null //No buildstack, so generate from mat datums
|
|
|
|
/obj/structure/table/greyscale/set_custom_materials(list/materials, multiplier)
|
|
. = ..()
|
|
var/list/materials_list = list()
|
|
for(var/custom_material in custom_materials)
|
|
var/datum/material/current_material = GET_MATERIAL_REF(custom_material)
|
|
materials_list += "[current_material.name]"
|
|
desc = "A square [(materials_list.len > 1) ? "amalgamation" : "piece"] of [english_list(materials_list)] on four legs. It can not move."
|
|
|
|
///Table on wheels
|
|
/obj/structure/table/rolling
|
|
name = "Rolling table"
|
|
desc = "An NT brand \"Rolly poly\" rolling table. It can and will move."
|
|
anchored = FALSE
|
|
smoothing_flags = NONE
|
|
smoothing_groups = null
|
|
canSmoothWith = null
|
|
icon = 'icons/obj/smooth_structures/rollingtable.dmi'
|
|
icon_state = "rollingtable"
|
|
var/list/attached_items = list()
|
|
|
|
/obj/structure/table/rolling/Initialize(mapload)
|
|
. = ..()
|
|
AddElement(/datum/element/noisy_movement)
|
|
|
|
/obj/structure/table/rolling/AfterPutItemOnTable(obj/item/I, mob/living/user)
|
|
. = ..()
|
|
attached_items += I
|
|
RegisterSignal(I, COMSIG_MOVABLE_MOVED, PROC_REF(RemoveItemFromTable)) //Listen for the pickup event, unregister on pick-up so we aren't moved
|
|
|
|
/obj/structure/table/rolling/proc/RemoveItemFromTable(datum/source, newloc, dir)
|
|
SIGNAL_HANDLER
|
|
|
|
if(newloc != loc) //Did we not move with the table? because that shit's ok
|
|
return FALSE
|
|
attached_items -= source
|
|
UnregisterSignal(source, COMSIG_MOVABLE_MOVED)
|
|
|
|
/obj/structure/table/rolling/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE)
|
|
. = ..()
|
|
if(!loc)
|
|
return
|
|
for(var/mob/living/living_mob in old_loc.contents)//Kidnap everyone on top
|
|
living_mob.forceMove(loc)
|
|
for(var/atom/movable/attached_movable as anything in attached_items)
|
|
if(!attached_movable.Move(loc))
|
|
RemoveItemFromTable(attached_movable, attached_movable.loc)
|
|
|
|
/*
|
|
* Glass tables
|
|
*/
|
|
/obj/structure/table/glass
|
|
name = "glass table"
|
|
desc = "What did I say about leaning on the glass tables? Now you need surgery."
|
|
icon = 'icons/obj/smooth_structures/glass_table.dmi'
|
|
icon_state = "glass_table-0"
|
|
base_icon_state = "glass_table"
|
|
custom_materials = list(/datum/material/glass =SHEET_MATERIAL_AMOUNT)
|
|
buildstack = /obj/item/stack/sheet/glass
|
|
smoothing_groups = SMOOTH_GROUP_GLASS_TABLES
|
|
canSmoothWith = SMOOTH_GROUP_GLASS_TABLES
|
|
max_integrity = 70
|
|
resistance_flags = ACID_PROOF
|
|
armor_type = /datum/armor/table_glass
|
|
|
|
/datum/armor/table_glass
|
|
fire = 80
|
|
acid = 100
|
|
|
|
/obj/structure/table/glass/Initialize(mapload)
|
|
. = ..()
|
|
var/static/list/loc_connections = list(
|
|
COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
|
|
)
|
|
AddElement(/datum/element/connect_loc, loc_connections)
|
|
|
|
/obj/structure/table/glass/proc/on_entered(datum/source, atom/movable/AM)
|
|
SIGNAL_HANDLER
|
|
if(flags_1 & NODECONSTRUCT_1)
|
|
return
|
|
if(!isliving(AM))
|
|
return
|
|
// Don't break if they're just flying past
|
|
if(AM.throwing)
|
|
addtimer(CALLBACK(src, PROC_REF(throw_check), AM), 5)
|
|
else
|
|
check_break(AM)
|
|
|
|
/obj/structure/table/glass/proc/throw_check(mob/living/M)
|
|
if(M.loc == get_turf(src))
|
|
check_break(M)
|
|
|
|
/obj/structure/table/glass/proc/check_break(mob/living/M)
|
|
if(M.has_gravity() && M.mob_size > MOB_SIZE_SMALL && !(M.movement_type & FLYING))
|
|
table_shatter(M)
|
|
|
|
/obj/structure/table/glass/proc/table_shatter(mob/living/victim)
|
|
visible_message(span_warning("[src] breaks!"),
|
|
span_danger("You hear breaking glass."))
|
|
|
|
playsound(loc, SFX_SHATTER, 50, TRUE)
|
|
|
|
new frame(loc)
|
|
|
|
var/obj/item/shard/shard = new glass_shard_type(loc)
|
|
shard.throw_impact(victim)
|
|
|
|
victim.Paralyze(100)
|
|
qdel(src)
|
|
|
|
/obj/structure/table/glass/deconstruct(disassembled = TRUE, wrench_disassembly = 0)
|
|
if(!(flags_1 & NODECONSTRUCT_1))
|
|
if(disassembled)
|
|
..()
|
|
return
|
|
else
|
|
var/turf/T = get_turf(src)
|
|
playsound(T, SFX_SHATTER, 50, TRUE)
|
|
|
|
new frame(loc)
|
|
new glass_shard_type(loc)
|
|
|
|
qdel(src)
|
|
|
|
/obj/structure/table/glass/narsie_act()
|
|
color = NARSIE_WINDOW_COLOUR
|
|
|
|
/obj/structure/table/glass/plasmaglass
|
|
name = "plasma glass table"
|
|
desc = "Someone thought this was a good idea."
|
|
icon = 'icons/obj/smooth_structures/plasmaglass_table.dmi'
|
|
icon_state = "plasmaglass_table-0"
|
|
base_icon_state = "plasmaglass_table"
|
|
custom_materials = list(/datum/material/alloy/plasmaglass =SHEET_MATERIAL_AMOUNT)
|
|
buildstack = /obj/item/stack/sheet/plasmaglass
|
|
glass_shard_type = /obj/item/shard/plasma
|
|
max_integrity = 100
|
|
|
|
/*
|
|
* Wooden tables
|
|
*/
|
|
|
|
/obj/structure/table/wood
|
|
name = "wooden table"
|
|
desc = "Do not apply fire to this. Rumour says it burns easily."
|
|
icon = 'icons/obj/smooth_structures/wood_table.dmi'
|
|
icon_state = "wood_table-0"
|
|
base_icon_state = "wood_table"
|
|
frame = /obj/structure/table_frame/wood
|
|
framestack = /obj/item/stack/sheet/mineral/wood
|
|
buildstack = /obj/item/stack/sheet/mineral/wood
|
|
resistance_flags = FLAMMABLE
|
|
max_integrity = 70
|
|
smoothing_groups = SMOOTH_GROUP_WOOD_TABLES //Don't smooth with SMOOTH_GROUP_TABLES
|
|
canSmoothWith = SMOOTH_GROUP_WOOD_TABLES
|
|
|
|
/obj/structure/table/wood/narsie_act(total_override = TRUE)
|
|
if(!total_override)
|
|
..()
|
|
|
|
/obj/structure/table/wood/poker //No specialties, Just a mapping object.
|
|
name = "gambling table"
|
|
desc = "A seedy table for seedy dealings in seedy places."
|
|
icon = 'icons/obj/smooth_structures/poker_table.dmi'
|
|
icon_state = "poker_table-0"
|
|
base_icon_state = "poker_table"
|
|
buildstack = /obj/item/stack/tile/carpet
|
|
|
|
/obj/structure/table/wood/poker/narsie_act()
|
|
..(FALSE)
|
|
|
|
/obj/structure/table/wood/fancy
|
|
name = "fancy table"
|
|
desc = "A standard metal table frame covered with an amazingly fancy, patterned cloth."
|
|
icon = 'icons/obj/structures.dmi'
|
|
icon_state = "fancy_table"
|
|
base_icon_state = "fancy_table"
|
|
frame = /obj/structure/table_frame
|
|
framestack = /obj/item/stack/rods
|
|
buildstack = /obj/item/stack/tile/carpet
|
|
smoothing_groups = SMOOTH_GROUP_FANCY_WOOD_TABLES //Don't smooth with SMOOTH_GROUP_TABLES or SMOOTH_GROUP_WOOD_TABLES
|
|
canSmoothWith = SMOOTH_GROUP_FANCY_WOOD_TABLES
|
|
var/smooth_icon = 'icons/obj/smooth_structures/fancy_table.dmi' // see Initialize()
|
|
|
|
/obj/structure/table/wood/fancy/Initialize(mapload)
|
|
. = ..()
|
|
// Needs to be set dynamically because table smooth sprites are 32x34,
|
|
// which the editor treats as a two-tile-tall object. The sprites are that
|
|
// size so that the north/south corners look nice - examine the detail on
|
|
// the sprites in the editor to see why.
|
|
icon = smooth_icon
|
|
|
|
/obj/structure/table/wood/fancy/black
|
|
icon_state = "fancy_table_black"
|
|
base_icon_state = "fancy_table_black"
|
|
buildstack = /obj/item/stack/tile/carpet/black
|
|
smooth_icon = 'icons/obj/smooth_structures/fancy_table_black.dmi'
|
|
|
|
/obj/structure/table/wood/fancy/blue
|
|
icon_state = "fancy_table_blue"
|
|
base_icon_state = "fancy_table_blue"
|
|
buildstack = /obj/item/stack/tile/carpet/blue
|
|
smooth_icon = 'icons/obj/smooth_structures/fancy_table_blue.dmi'
|
|
|
|
/obj/structure/table/wood/fancy/cyan
|
|
icon_state = "fancy_table_cyan"
|
|
base_icon_state = "fancy_table_cyan"
|
|
buildstack = /obj/item/stack/tile/carpet/cyan
|
|
smooth_icon = 'icons/obj/smooth_structures/fancy_table_cyan.dmi'
|
|
|
|
/obj/structure/table/wood/fancy/green
|
|
icon_state = "fancy_table_green"
|
|
base_icon_state = "fancy_table_green"
|
|
buildstack = /obj/item/stack/tile/carpet/green
|
|
smooth_icon = 'icons/obj/smooth_structures/fancy_table_green.dmi'
|
|
|
|
/obj/structure/table/wood/fancy/orange
|
|
icon_state = "fancy_table_orange"
|
|
base_icon_state = "fancy_table_orange"
|
|
buildstack = /obj/item/stack/tile/carpet/orange
|
|
smooth_icon = 'icons/obj/smooth_structures/fancy_table_orange.dmi'
|
|
|
|
/obj/structure/table/wood/fancy/purple
|
|
icon_state = "fancy_table_purple"
|
|
base_icon_state = "fancy_table_purple"
|
|
buildstack = /obj/item/stack/tile/carpet/purple
|
|
smooth_icon = 'icons/obj/smooth_structures/fancy_table_purple.dmi'
|
|
|
|
/obj/structure/table/wood/fancy/red
|
|
icon_state = "fancy_table_red"
|
|
base_icon_state = "fancy_table_red"
|
|
buildstack = /obj/item/stack/tile/carpet/red
|
|
smooth_icon = 'icons/obj/smooth_structures/fancy_table_red.dmi'
|
|
|
|
/obj/structure/table/wood/fancy/royalblack
|
|
icon_state = "fancy_table_royalblack"
|
|
base_icon_state = "fancy_table_royalblack"
|
|
buildstack = /obj/item/stack/tile/carpet/royalblack
|
|
smooth_icon = 'icons/obj/smooth_structures/fancy_table_royalblack.dmi'
|
|
|
|
/obj/structure/table/wood/fancy/royalblue
|
|
icon_state = "fancy_table_royalblue"
|
|
base_icon_state = "fancy_table_royalblue"
|
|
buildstack = /obj/item/stack/tile/carpet/royalblue
|
|
smooth_icon = 'icons/obj/smooth_structures/fancy_table_royalblue.dmi'
|
|
|
|
/*
|
|
* Reinforced tables
|
|
*/
|
|
/obj/structure/table/reinforced
|
|
name = "reinforced table"
|
|
desc = "A reinforced version of the four legged table."
|
|
icon = 'icons/obj/smooth_structures/reinforced_table.dmi'
|
|
icon_state = "reinforced_table-0"
|
|
base_icon_state = "reinforced_table"
|
|
deconstruction_ready = FALSE
|
|
buildstack = /obj/item/stack/sheet/plasteel
|
|
max_integrity = 200
|
|
integrity_failure = 0.25
|
|
armor_type = /datum/armor/table_reinforced
|
|
|
|
/datum/armor/table_reinforced
|
|
melee = 10
|
|
bullet = 30
|
|
laser = 30
|
|
energy = 100
|
|
bomb = 20
|
|
fire = 80
|
|
acid = 70
|
|
|
|
/obj/structure/table/reinforced/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
|
|
. = ..()
|
|
|
|
if(isnull(held_item))
|
|
return NONE
|
|
|
|
if(held_item.tool_behaviour == TOOL_WELDER)
|
|
context[SCREENTIP_CONTEXT_RMB] = deconstruction_ready ? "Strengthen" : "Weaken"
|
|
. = CONTEXTUAL_SCREENTIP_SET
|
|
|
|
return . || NONE
|
|
|
|
/obj/structure/table/reinforced/deconstruction_hints(mob/user)
|
|
if(deconstruction_ready)
|
|
return span_notice("The top cover has been <i>welded</i> loose and the main frame's <b>bolts</b> are exposed.")
|
|
else
|
|
return span_notice("The top cover is firmly <b>welded</b> on.")
|
|
|
|
/obj/structure/table/reinforced/attackby_secondary(obj/item/weapon, mob/user, params)
|
|
if(weapon.tool_behaviour == TOOL_WELDER)
|
|
if(weapon.tool_start_check(user, amount = 0))
|
|
if(deconstruction_ready)
|
|
to_chat(user, span_notice("You start strengthening the reinforced table..."))
|
|
if (weapon.use_tool(src, user, 50, volume = 50))
|
|
to_chat(user, span_notice("You strengthen the table."))
|
|
deconstruction_ready = FALSE
|
|
else
|
|
to_chat(user, span_notice("You start weakening the reinforced table..."))
|
|
if (weapon.use_tool(src, user, 50, volume = 50))
|
|
to_chat(user, span_notice("You weaken the table."))
|
|
deconstruction_ready = TRUE
|
|
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
|
|
|
else
|
|
. = ..()
|
|
|
|
/obj/structure/table/bronze
|
|
name = "bronze table"
|
|
desc = "A solid table made out of bronze."
|
|
icon = 'icons/obj/smooth_structures/brass_table.dmi'
|
|
icon_state = "brass_table-0"
|
|
base_icon_state = "brass_table"
|
|
resistance_flags = FIRE_PROOF | ACID_PROOF
|
|
buildstack = /obj/item/stack/sheet/bronze
|
|
smoothing_groups = SMOOTH_GROUP_BRONZE_TABLES //Don't smooth with SMOOTH_GROUP_TABLES
|
|
canSmoothWith = SMOOTH_GROUP_BRONZE_TABLES
|
|
|
|
/obj/structure/table/bronze/tablepush(mob/living/user, mob/living/pushed_mob)
|
|
..()
|
|
playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 50, TRUE)
|
|
|
|
/obj/structure/table/reinforced/rglass
|
|
name = "reinforced glass table"
|
|
desc = "A reinforced version of the glass table."
|
|
icon = 'icons/obj/smooth_structures/rglass_table.dmi'
|
|
icon_state = "rglass_table-0"
|
|
base_icon_state = "rglass_table"
|
|
custom_materials = list(/datum/material/glass =SHEET_MATERIAL_AMOUNT, /datum/material/iron =SHEET_MATERIAL_AMOUNT)
|
|
buildstack = /obj/item/stack/sheet/rglass
|
|
max_integrity = 150
|
|
|
|
/obj/structure/table/reinforced/plasmarglass
|
|
name = "reinforced plasma glass table"
|
|
desc = "A reinforced version of the plasma glass table."
|
|
icon = 'icons/obj/smooth_structures/rplasmaglass_table.dmi'
|
|
icon_state = "rplasmaglass_table-0"
|
|
base_icon_state = "rplasmaglass_table"
|
|
custom_materials = list(/datum/material/alloy/plasmaglass =SHEET_MATERIAL_AMOUNT, /datum/material/iron =SHEET_MATERIAL_AMOUNT)
|
|
buildstack = /obj/item/stack/sheet/plasmarglass
|
|
|
|
/obj/structure/table/reinforced/titaniumglass
|
|
name = "titanium glass table"
|
|
desc = "A titanium reinforced glass table, with a fresh coat of NT white paint."
|
|
icon = 'icons/obj/smooth_structures/titaniumglass_table.dmi'
|
|
icon_state = "titaniumglass_table-0"
|
|
base_icon_state = "titaniumglass_table"
|
|
custom_materials = list(/datum/material/alloy/titaniumglass =SHEET_MATERIAL_AMOUNT)
|
|
buildstack = /obj/item/stack/sheet/titaniumglass
|
|
max_integrity = 250
|
|
|
|
/obj/structure/table/reinforced/plastitaniumglass
|
|
name = "plastitanium glass table"
|
|
desc = "A table made of titanium reinforced silica-plasma composite. About as durable as it sounds."
|
|
icon = 'icons/obj/smooth_structures/plastitaniumglass_table.dmi'
|
|
icon_state = "plastitaniumglass_table-0"
|
|
base_icon_state = "plastitaniumglass_table"
|
|
custom_materials = list(/datum/material/alloy/plastitaniumglass =SHEET_MATERIAL_AMOUNT)
|
|
buildstack = /obj/item/stack/sheet/plastitaniumglass
|
|
max_integrity = 300
|
|
|
|
/*
|
|
* Surgery Tables
|
|
*/
|
|
|
|
/obj/structure/table/optable
|
|
name = "operating table"
|
|
desc = "Used for advanced medical procedures."
|
|
icon = 'icons/obj/medical/surgery_table.dmi'
|
|
icon_state = "surgery_table"
|
|
buildstack = /obj/item/stack/sheet/mineral/silver
|
|
smoothing_flags = NONE
|
|
smoothing_groups = null
|
|
canSmoothWith = null
|
|
can_buckle = 1
|
|
buckle_lying = 90
|
|
climbable = FALSE
|
|
custom_materials = list(/datum/material/silver =SHEET_MATERIAL_AMOUNT)
|
|
var/mob/living/carbon/patient = null
|
|
var/obj/machinery/computer/operating/computer = null
|
|
|
|
/obj/structure/table/optable/Initialize(mapload)
|
|
. = ..()
|
|
for(var/direction in GLOB.alldirs)
|
|
computer = locate(/obj/machinery/computer/operating) in get_step(src, direction)
|
|
if(computer)
|
|
computer.table = src
|
|
break
|
|
|
|
RegisterSignal(loc, COMSIG_ATOM_ENTERED, PROC_REF(mark_patient))
|
|
RegisterSignal(loc, COMSIG_ATOM_EXITED, PROC_REF(unmark_patient))
|
|
|
|
/obj/structure/table/optable/Destroy()
|
|
if(computer && computer.table == src)
|
|
computer.table = null
|
|
patient = null
|
|
UnregisterSignal(loc, COMSIG_ATOM_ENTERED)
|
|
UnregisterSignal(loc, COMSIG_ATOM_EXITED)
|
|
return ..()
|
|
|
|
/obj/structure/table/optable/tablepush(mob/living/user, mob/living/pushed_mob)
|
|
pushed_mob.forceMove(loc)
|
|
pushed_mob.set_resting(TRUE, TRUE)
|
|
visible_message(span_notice("[user] lays [pushed_mob] on [src]."))
|
|
|
|
/// Any mob that enters our tile will be marked as a potential patient. They will be turned into a patient if they lie down.
|
|
/obj/structure/table/optable/proc/mark_patient(datum/source, mob/living/carbon/potential_patient)
|
|
SIGNAL_HANDLER
|
|
if(!istype(potential_patient))
|
|
return
|
|
RegisterSignal(potential_patient, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(recheck_patient))
|
|
recheck_patient(potential_patient) // In case the mob is already lying down before they entered.
|
|
potential_patient.pixel_y = potential_patient.base_pixel_y
|
|
|
|
/// Unmark the potential patient.
|
|
/obj/structure/table/optable/proc/unmark_patient(datum/source, mob/living/carbon/potential_patient)
|
|
SIGNAL_HANDLER
|
|
if(!istype(potential_patient))
|
|
return
|
|
if(potential_patient == patient)
|
|
recheck_patient(patient) // Can just set patient to null, but doing the recheck lets us find a replacement patient.
|
|
UnregisterSignal(potential_patient, COMSIG_LIVING_SET_BODY_POSITION)
|
|
potential_patient.pixel_y = potential_patient.base_pixel_y + potential_patient.body_position_pixel_y_offset
|
|
|
|
/// Someone on our tile just lied down, got up, moved in, or moved out.
|
|
/// potential_patient is the mob that had one of those four things change.
|
|
/// The check is a bit broad so we can find a replacement patient.
|
|
/obj/structure/table/optable/proc/recheck_patient(mob/living/carbon/potential_patient)
|
|
SIGNAL_HANDLER
|
|
if(patient && patient != potential_patient)
|
|
return
|
|
|
|
if(potential_patient.body_position == LYING_DOWN && potential_patient.loc == loc)
|
|
patient = potential_patient
|
|
return
|
|
|
|
// Find another lying mob as a replacement.
|
|
for (var/mob/living/carbon/replacement_patient in loc.contents)
|
|
if(replacement_patient.body_position == LYING_DOWN)
|
|
patient = replacement_patient
|
|
return
|
|
patient = null
|
|
|
|
/*
|
|
* Racks
|
|
*/
|
|
/obj/structure/rack
|
|
name = "rack"
|
|
desc = "Different from the Middle Ages version."
|
|
icon = 'icons/obj/structures.dmi'
|
|
icon_state = "rack"
|
|
layer = TABLE_LAYER
|
|
density = TRUE
|
|
anchored = TRUE
|
|
pass_flags_self = LETPASSTHROW //You can throw objects over this, despite it's density.
|
|
max_integrity = 20
|
|
|
|
/obj/structure/rack/examine(mob/user)
|
|
. = ..()
|
|
. += span_notice("It's held together by a couple of <b>bolts</b>.")
|
|
|
|
/obj/structure/rack/CanAllowThrough(atom/movable/mover, border_dir)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
if(istype(mover) && (mover.pass_flags & PASSTABLE))
|
|
return TRUE
|
|
|
|
/obj/structure/rack/MouseDrop_T(obj/O, mob/user)
|
|
. = ..()
|
|
if ((!( isitem(O) ) || user.get_active_held_item() != O))
|
|
return
|
|
if(!user.dropItemToGround(O))
|
|
return
|
|
if(O.loc != src.loc)
|
|
step(O, get_dir(O, src))
|
|
|
|
/obj/structure/rack/attackby(obj/item/W, mob/living/user, params)
|
|
var/list/modifiers = params2list(params)
|
|
if (W.tool_behaviour == TOOL_WRENCH && !(flags_1&NODECONSTRUCT_1) && LAZYACCESS(modifiers, RIGHT_CLICK))
|
|
W.play_tool_sound(src)
|
|
deconstruct(TRUE)
|
|
return
|
|
if(user.combat_mode)
|
|
return ..()
|
|
if(user.transferItemToLoc(W, drop_location()))
|
|
return 1
|
|
|
|
/obj/structure/rack/attack_paw(mob/living/user, list/modifiers)
|
|
attack_hand(user, modifiers)
|
|
|
|
/obj/structure/rack/attack_hand(mob/living/user, list/modifiers)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
if(user.body_position == LYING_DOWN || user.usable_legs < 2)
|
|
return
|
|
user.changeNext_move(CLICK_CD_MELEE)
|
|
user.do_attack_animation(src, ATTACK_EFFECT_KICK)
|
|
user.visible_message(span_danger("[user] kicks [src]."), null, null, COMBAT_MESSAGE_RANGE)
|
|
take_damage(rand(4,8), BRUTE, MELEE, 1)
|
|
|
|
/obj/structure/rack/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
|
|
switch(damage_type)
|
|
if(BRUTE)
|
|
if(damage_amount)
|
|
playsound(loc, 'sound/items/dodgeball.ogg', 80, TRUE)
|
|
else
|
|
playsound(loc, 'sound/weapons/tap.ogg', 50, TRUE)
|
|
if(BURN)
|
|
playsound(loc, 'sound/items/welder.ogg', 40, TRUE)
|
|
|
|
/*
|
|
* Rack destruction
|
|
*/
|
|
|
|
/obj/structure/rack/deconstruct(disassembled = TRUE)
|
|
if(!(flags_1&NODECONSTRUCT_1))
|
|
set_density(FALSE)
|
|
var/obj/item/rack_parts/newparts = new(loc)
|
|
transfer_fingerprints_to(newparts)
|
|
qdel(src)
|
|
|
|
|
|
/*
|
|
* Rack Parts
|
|
*/
|
|
|
|
/obj/item/rack_parts
|
|
name = "rack parts"
|
|
desc = "Parts of a rack."
|
|
icon = 'icons/obj/structures.dmi'
|
|
icon_state = "rack_parts"
|
|
inhand_icon_state = "rack_parts"
|
|
flags_1 = CONDUCT_1
|
|
custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT)
|
|
var/building = FALSE
|
|
|
|
/obj/item/rack_parts/attackby(obj/item/W, mob/user, params)
|
|
if (W.tool_behaviour == TOOL_WRENCH)
|
|
new /obj/item/stack/sheet/iron(user.loc)
|
|
qdel(src)
|
|
else
|
|
. = ..()
|
|
|
|
/obj/item/rack_parts/attack_self(mob/user)
|
|
if(building)
|
|
return
|
|
building = TRUE
|
|
to_chat(user, span_notice("You start constructing a rack..."))
|
|
if(do_after(user, 50, target = user, progress=TRUE))
|
|
if(!user.temporarilyRemoveItemFromInventory(src))
|
|
return
|
|
var/obj/structure/rack/R = new /obj/structure/rack(get_turf(src))
|
|
user.visible_message("<span class='notice'>[user] assembles \a [R].\
|
|
</span>", span_notice("You assemble \a [R]."))
|
|
R.add_fingerprint(user)
|
|
qdel(src)
|
|
building = FALSE
|