diff --git a/code/__DEFINES/dcs/signals/signals.dm b/code/__DEFINES/dcs/signals/signals.dm index aa530ada845a..8ac936b9992a 100644 --- a/code/__DEFINES/dcs/signals/signals.dm +++ b/code/__DEFINES/dcs/signals/signals.dm @@ -187,6 +187,9 @@ #define COMSIG_ATOM_TOOL_ACT(tooltype) "tool_act_[tooltype]" #define COMPONENT_BLOCK_TOOL_ATTACK (1<<0) +///from base of atom/get_cell(): (atom) +#define COMSIG_ATOM_GET_CELL "atom_get_cell" + ///called when teleporting into a protected turf: (channel, turf/origin) #define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport" #define COMPONENT_BLOCK_TELEPORT (1<<0) diff --git a/code/datums/components/melee/charged.dm b/code/datums/components/melee/charged.dm new file mode 100644 index 000000000000..9f84dae26b03 --- /dev/null +++ b/code/datums/components/melee/charged.dm @@ -0,0 +1,105 @@ +/* + * Charged weapon component. For weapons that swap between states but require a cell for function. + * For example: Stun batons. + * + * Used to easily make an item that can be attack_self'd to gain force or change mode. + * + * Only values passed on initialize will update when the item is activated (except the icon_state). + * The icon_state of the item will swap between "[icon_state]" and "[icon_state]_on". + */ +/datum/component/transforming/charged + var/obj/item/stock_parts/cell/cell + var/allowed_cells + var/preload_cell_type + var/cell_hit_cost + var/can_remove_cell + +/datum/component/transforming/charged/Initialize( + start_transformed = FALSE, + transform_cooldown_time = 0 SECONDS, + force_on = 0, + throwforce_on = 0, + throw_speed_on = 2, + sharpness_on = NONE, + hitsound_on = 'sound/weapons/blade1.ogg', + w_class_on = WEIGHT_CLASS_BULKY, + list/attack_verb_on, + inhand_icon_change = TRUE, + _allowed_cells = list(), + _preload_cell_type = /obj/item/stock_parts/cell/melee, + _cell_hit_cost = 1000 + _can_remove_cell = FALSE +) + . = ..() + + allowed_cells = _allowed_cells + preload_cell_type = _preload_cell_type + cell_hit_cost = _cell_hit_cost + can_remove_cell = _can_remove_cell + + if(preload_cell_type in allowed_cells) + cell = new preload_cell_type(parent) + +/datum/component/transforming/charged/RegisterWithParent() + RegisterSignal(parent, COMSIG_ATOM_SCREWDRIVER_ACT, proc_ref(on_screwdriver_act)) + RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, proc_ref(on_attackby)) + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, proc_ref(on_examine)) + +/datum/component/transforming/charged/on_attack_self(obj/item/source, mob/user) + if(cell && cell.charge > cell_hit_cost) + return ..() + else + set_inactive(source) + if(!cell) + to_chat(user, span_warning("[source] does not have a power source!")) + else + to_chat(user, span_warning("[source] is out of charge.")) + +/datum/component/transforming/charged/proc/on_screwdriver_act(obj/item/source, mob/user, obj/item/screwdriver) + if(cell && can_remove_cell) + cell.update_appearance() + cell.forceMove(get_turf(parent)) + cell = null + to_chat(user, span_notice("You remove the cell from [parent].")) + set_inactive(source) + parent.update_appearance() + return COMPONENT_CANCEL_ATTACK_CHAIN + +/datum/component/transforming/charged/proc/on_attackby(obj/item/source, obj/item/attacking_item, mob/user, params) + SIGNAL_HANDLER + + if(istype(attacking_item, /obj/item/stock_parts/cell)) + var/obj/item/stock_parts/cell/attacking_cell = attacking_item + if(cell) + to_chat(user, span_notice("[parent] already has a cell!")) + else + if(attacking_cell.maxcharge < cell_hit_cost) + to_chat(user, span_notice("[parent] requires a higher capacity cell.")) + return + if(!user.transferItemToLoc(attacking_item, parent)) + return + cell = attacking_item + to_chat(user, span_notice("You install a cell in [parent].")) + parent.update_appearance() + return COMPONENT_CANCEL_ATTACK_CHAIN + +/datum/component/transforming/charged/proc/on_examine(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + + if(cell) + examine_list += span_notice("\The [source] is [round(cell.percent())]% charged.") + else + examine_list += span_warning("\The [source] does not have a power source installed.") + +/datum/component/transforming/charged/proc/set_active_state(active_state = -1) + switch(active_state) + //We didnt pass a specific state to set it to so just toggle it + if(-1) + toggle_active(parent) + if(FALSE) + set_inactive(parent) + if(TRUE) + set_active(parent) + + + diff --git a/code/datums/components/transforming.dm b/code/datums/components/melee/transforming.dm similarity index 100% rename from code/datums/components/transforming.dm rename to code/datums/components/melee/transforming.dm diff --git a/code/datums/components/twohanded.dm b/code/datums/components/melee/twohanded.dm similarity index 100% rename from code/datums/components/twohanded.dm rename to code/datums/components/melee/twohanded.dm diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index e0312f21f836..f1095fa6fbe1 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1224,7 +1224,9 @@ //Returns an atom's power cell, if it has one. Overload for individual items. /atom/movable/proc/get_cell() - return + var/component_cell = SEND_SIGNAL(src, COSMIG_ATOM_GET_CELL) + if(istype(component_cell, /obj/item/stock_parts/cell)) + return component_cell /atom/movable/proc/can_be_pulled(user, grab_state, force) if(src == user || !isturf(loc)) diff --git a/shiptest.dme b/shiptest.dme index 44df7cb8f132..ba4b8fed7145 100644 --- a/shiptest.dme +++ b/shiptest.dme @@ -562,8 +562,6 @@ #include "code\datums\components\taped.dm" #include "code\datums\components\tether.dm" #include "code\datums\components\thermite.dm" -#include "code\datums\components\transforming.dm" -#include "code\datums\components\twohanded.dm" #include "code\datums\components\udder.dm" #include "code\datums\components\uplink.dm" #include "code\datums\components\wearertargeting.dm" @@ -583,6 +581,9 @@ #include "code\datums\components\fantasy\suffixes.dm" #include "code\datums\components\food\edible.dm" #include "code\datums\components\food\food_storage.dm" +#include "code\datums\components\melee\charged.dm" +#include "code\datums\components\melee\transforming.dm" +#include "code\datums\components\melee\twohanded.dm" #include "code\datums\components\plumbing\_plumbing.dm" #include "code\datums\components\plumbing\chemical_acclimator.dm" #include "code\datums\components\plumbing\filter.dm"