mirror of
https://github.com/Skyrat-SS13/Skyrat-tg.git
synced 2026-08-23 21:09:00 +01:00
3591 individual conflicts Update build.js Update install_node.sh Update byond.js oh my fucking god hat slow huh holy shit we all fall down 2 more I missed 2900 individual conflicts 2700 Individual conflicts replaces yarn file with tg version, bumping us down to 2200-ish Down to 2000 individual conflicts 140 down mmm aaaaaaaaaaaaaaaaaaa not yt 575 soon 900 individual conflicts 600 individual conflicts, 121 file conflicts im not okay 160 across 19 files 29 in 4 files 0 conflicts, compiletime fix time some minor incap stuff missed ticks weird dupe definition stuff missed ticks 2 incap fixes undefs and pie fix Radio update and some extra minor stuff returns a single override no more dupe definitions, 175 compiletime errors Unticked file fix sound and emote stuff honk and more radio stuff
333 lines
12 KiB
Plaintext
333 lines
12 KiB
Plaintext
#define CELL_DRAIN_TIME 35
|
|
#define CELL_POWER_GAIN (0.06 * STANDARD_CELL_CHARGE)
|
|
#define CELL_POWER_DRAIN (0.75 * STANDARD_CELL_CHARGE)
|
|
|
|
/**
|
|
* # Power store abstract type
|
|
*
|
|
* Abstract type for a stock part that holds power.
|
|
*/
|
|
/obj/item/stock_parts/power_store
|
|
name = "power store abstract"
|
|
/// The size icon overlay prefix.
|
|
var/cell_size_prefix = "cell"
|
|
///Current charge in cell units
|
|
var/charge = 0
|
|
/// Standard cell charge used for rating
|
|
var/rating_base = STANDARD_CELL_CHARGE
|
|
///Maximum charge in cell units
|
|
var/maxcharge = STANDARD_CELL_CHARGE
|
|
///If the cell has been booby-trapped by injecting it with plasma. Chance on use() to explode.
|
|
var/rigged = FALSE
|
|
///If the power cell was damaged by an explosion, chance for it to become corrupted and function the same as rigged.
|
|
var/corrupted = FALSE
|
|
///How much power is given per second in a recharger.
|
|
var/chargerate = STANDARD_CELL_RATE * 0.05
|
|
///If true, the cell will state it's maximum charge in it's description
|
|
var/ratingdesc = TRUE
|
|
///If it's a grown that acts as a battery, add a wire overlay to it.
|
|
var/grown_battery = FALSE
|
|
///What charge lige sprite to use, null if no light
|
|
var/charge_light_type = "standard"
|
|
///What connector sprite to use when in a cell charger, null if no connectors
|
|
var/connector_type = "standard"
|
|
///Does the cell start without any charge?
|
|
var/empty = FALSE
|
|
|
|
/obj/item/stock_parts/power_store/get_cell()
|
|
return src
|
|
|
|
/obj/item/stock_parts/power_store/Initialize(mapload, override_maxcharge)
|
|
. = ..()
|
|
create_reagents(5, INJECTABLE | DRAINABLE)
|
|
if (override_maxcharge)
|
|
maxcharge = override_maxcharge
|
|
rating = max(round(maxcharge / (rating_base * 10), 1), 1)
|
|
if(!charge)
|
|
charge = maxcharge
|
|
if(empty)
|
|
charge = 0
|
|
if(ratingdesc)
|
|
desc += " This one has a rating of [display_energy(maxcharge)][prob(10) ? ", and you should not swallow it" : ""]." //joke works better if it's not on every cell
|
|
update_appearance()
|
|
|
|
RegisterSignal(src, COMSIG_ITEM_MAGICALLY_CHARGED, PROC_REF(on_magic_charge))
|
|
var/static/list/loc_connections = list(
|
|
COMSIG_ITEM_MAGICALLY_CHARGED = PROC_REF(on_magic_charge),
|
|
)
|
|
AddElement(/datum/element/connect_loc, loc_connections)
|
|
|
|
|
|
/obj/item/stock_parts/power_store/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE)
|
|
. = ..()
|
|
if(!isturf(old_loc))
|
|
update_appearance()
|
|
|
|
|
|
/**
|
|
* Signal proc for [COMSIG_ITEM_MAGICALLY_CHARGED]
|
|
*
|
|
* If we, or the item we're located in, is subject to the charge spell, gain some charge back
|
|
*/
|
|
/obj/item/stock_parts/power_store/proc/on_magic_charge(datum/source, datum/action/cooldown/spell/charge/spell, mob/living/caster)
|
|
SIGNAL_HANDLER
|
|
|
|
// This shouldn't be running if we're not being held by a mob,
|
|
// or if we're not within an object being held by a mob, but just in case...
|
|
if(!ismovable(loc))
|
|
return
|
|
|
|
. = COMPONENT_ITEM_CHARGED
|
|
|
|
if(prob(80))
|
|
maxcharge -= rating_base * 0.2
|
|
|
|
if(maxcharge <= 1) // Div by 0 protection
|
|
maxcharge = 1
|
|
. |= COMPONENT_ITEM_BURNT_OUT
|
|
|
|
charge = maxcharge
|
|
update_appearance()
|
|
|
|
// Guns need to process their chamber when we've been charged
|
|
if(isgun(loc))
|
|
var/obj/item/gun/gun_loc = loc
|
|
gun_loc.process_chamber()
|
|
|
|
// The thing we're in might have overlays or icon states for whether the cell is charged
|
|
if(!ismob(loc))
|
|
loc.update_appearance()
|
|
|
|
return .
|
|
|
|
/obj/item/stock_parts/power_store/create_reagents(max_vol, flags)
|
|
. = ..()
|
|
RegisterSignals(reagents, list(COMSIG_REAGENTS_NEW_REAGENT, COMSIG_REAGENTS_ADD_REAGENT, COMSIG_REAGENTS_DEL_REAGENT, COMSIG_REAGENTS_REM_REAGENT), PROC_REF(on_reagent_change))
|
|
RegisterSignal(reagents, COMSIG_QDELETING, PROC_REF(on_reagents_del))
|
|
|
|
/// Handles properly detaching signal hooks.
|
|
/obj/item/stock_parts/power_store/proc/on_reagents_del(datum/reagents/reagents)
|
|
SIGNAL_HANDLER
|
|
UnregisterSignal(reagents, list(COMSIG_REAGENTS_NEW_REAGENT, COMSIG_REAGENTS_ADD_REAGENT, COMSIG_REAGENTS_DEL_REAGENT, COMSIG_REAGENTS_REM_REAGENT, COMSIG_QDELETING))
|
|
return NONE
|
|
|
|
/obj/item/stock_parts/power_store/update_overlays()
|
|
. = ..()
|
|
if(grown_battery)
|
|
. += mutable_appearance('icons/obj/machines/cell_charger.dmi', "grown_wires")
|
|
if((charge < 0.01) || !charge_light_type)
|
|
return
|
|
. += mutable_appearance('icons/obj/machines/cell_charger.dmi', "[cell_size_prefix]-[charge_light_type]-o[(percent() >= 99.5) ? 2 : 1]")
|
|
|
|
/obj/item/stock_parts/power_store/vv_edit_var(vname, vval)
|
|
if(vname == NAMEOF(src, charge))
|
|
charge = clamp(vval, 0, maxcharge)
|
|
return TRUE
|
|
if(vname == NAMEOF(src, maxcharge))
|
|
if(charge > vval)
|
|
charge = vval
|
|
if(vname == NAMEOF(src, corrupted) && vval && !corrupted)
|
|
corrupt(TRUE)
|
|
return TRUE
|
|
return ..()
|
|
|
|
|
|
/**
|
|
* Returns the percentage of the cell's charge.
|
|
*/
|
|
/obj/item/stock_parts/power_store/proc/percent() // return % charge of cell
|
|
return 100 * charge / maxcharge
|
|
|
|
/**
|
|
* Returns the maximum charge of the cell.
|
|
*/
|
|
/obj/item/stock_parts/power_store/proc/max_charge()
|
|
return maxcharge
|
|
|
|
/**
|
|
* Returns the current charge of the cell.
|
|
*/
|
|
/obj/item/stock_parts/power_store/proc/charge()
|
|
return charge
|
|
|
|
/**
|
|
* Returns the amount of charge used on the cell.
|
|
*/
|
|
/obj/item/stock_parts/power_store/proc/used_charge()
|
|
return maxcharge - charge
|
|
|
|
/// Use power from the cell.
|
|
/// Args:
|
|
/// - used: Amount of power in joules to use.
|
|
/// - force: If true, uses the remaining power from the cell if there isn't enough power to supply the demand.
|
|
/// Returns: The power used from the cell in joules.
|
|
/obj/item/stock_parts/power_store/use(used, force = FALSE)
|
|
var/power_used = min(used, charge)
|
|
if(rigged && power_used > 0)
|
|
explode()
|
|
return 0 // The cell decided to explode so we won't be able to use it.
|
|
if(!force && charge < used)
|
|
return 0
|
|
charge -= power_used
|
|
if(!istype(loc, /obj/machinery/power/apc))
|
|
SSblackbox.record_feedback("tally", "cell_used", 1, type)
|
|
return power_used
|
|
|
|
/// Recharge the cell.
|
|
/// Args:
|
|
/// - amount: The amount of energy to give to the cell in joules.
|
|
/// Returns: The power given to the cell in joules.
|
|
/obj/item/stock_parts/power_store/proc/give(amount)
|
|
var/power_used = min(maxcharge-charge,amount)
|
|
charge += power_used
|
|
if(rigged && amount > 0)
|
|
explode()
|
|
return power_used
|
|
|
|
/**
|
|
* Changes the charge of the cell.
|
|
* Args:
|
|
* - amount: The energy to give to the cell (can be negative).
|
|
* Returns: The energy that was given to the cell (can be negative).
|
|
*/
|
|
/obj/item/stock_parts/power_store/proc/change(amount)
|
|
var/energy_used = clamp(amount, -charge, maxcharge - charge)
|
|
charge += energy_used
|
|
if(rigged && energy_used)
|
|
explode()
|
|
return energy_used
|
|
|
|
/obj/item/stock_parts/power_store/examine(mob/user)
|
|
. = ..()
|
|
if(rigged)
|
|
. += span_danger("This [name] seems to be faulty!")
|
|
else
|
|
. += "The charge meter reads [CEILING(percent(), 0.1)]%." //so it doesn't say 0% charge when the overlay indicates it still has charge
|
|
|
|
/obj/item/stock_parts/power_store/proc/on_reagent_change(datum/reagents/holder, ...)
|
|
SIGNAL_HANDLER
|
|
rigged = (corrupted || holder.has_reagent(/datum/reagent/toxin/plasma, 5)) ? TRUE : FALSE //has_reagent returns the reagent datum
|
|
return NONE
|
|
|
|
|
|
/obj/item/stock_parts/power_store/proc/explode()
|
|
if(!charge)
|
|
return
|
|
var/range_devastation = -1
|
|
var/range_heavy = round(sqrt(charge / (3.6 * rating_base)))
|
|
var/range_light = round(sqrt(charge / (0.9 * rating_base)))
|
|
var/range_flash = range_light
|
|
if(!range_light)
|
|
rigged = FALSE
|
|
corrupt()
|
|
return
|
|
|
|
message_admins("[ADMIN_LOOKUPFLW(usr)] has triggered a rigged/corrupted power cell explosion at [AREACOORD(loc)].")
|
|
usr?.log_message("triggered a rigged/corrupted power cell explosion", LOG_GAME)
|
|
usr?.log_message("triggered a rigged/corrupted power cell explosion", LOG_VICTIM, log_globally = FALSE)
|
|
|
|
explosion(src, devastation_range = range_devastation, heavy_impact_range = range_heavy, light_impact_range = range_light, flash_range = range_flash)
|
|
qdel(src)
|
|
|
|
/obj/item/stock_parts/power_store/proc/corrupt(force)
|
|
charge /= 2
|
|
maxcharge = max(maxcharge/2, chargerate)
|
|
if (force || prob(10))
|
|
rigged = TRUE //broken batterys are dangerous
|
|
corrupted = TRUE
|
|
|
|
/obj/item/stock_parts/power_store/emp_act(severity)
|
|
. = ..()
|
|
if(. & EMP_PROTECT_SELF)
|
|
return
|
|
use(STANDARD_CELL_CHARGE / severity, force = TRUE)
|
|
|
|
/obj/item/stock_parts/power_store/ex_act(severity, target)
|
|
. = ..()
|
|
if(QDELETED(src))
|
|
return FALSE
|
|
|
|
switch(severity)
|
|
if(EXPLODE_HEAVY)
|
|
if(prob(50))
|
|
corrupt()
|
|
if(EXPLODE_LIGHT)
|
|
if(prob(25))
|
|
corrupt()
|
|
|
|
return TRUE
|
|
|
|
/obj/item/stock_parts/power_store/suicide_act(mob/living/user)
|
|
user.visible_message(span_suicide("[user] is licking the electrodes of [src]! It looks like [user.p_theyre()] trying to commit suicide!"))
|
|
do_sparks(2, TRUE, user)
|
|
var/eating_success = do_after(user, 5 SECONDS, src)
|
|
if(QDELETED(user))
|
|
return SHAME
|
|
if(!eating_success || QDELETED(src) || charge == 0)
|
|
user.visible_message(span_suicide("[user] chickens out!"))
|
|
return SHAME
|
|
playsound(user, 'sound/effects/sparks1.ogg', charge / maxcharge)
|
|
var/damage = charge / (1 KILO JOULES)
|
|
user.electrocute_act(damage, src, 1, SHOCK_IGNORE_IMMUNITY|SHOCK_DELAY_STUN|SHOCK_NOGLOVES)
|
|
charge = 0
|
|
update_appearance()
|
|
if(user.stat != DEAD)
|
|
to_chat(user, span_suicide("There's not enough charge in [src] to kill you!"))
|
|
return SHAME
|
|
addtimer(CALLBACK(src, PROC_REF(gib_user), user, charge), 3 SECONDS)
|
|
return MANUAL_SUICIDE
|
|
|
|
/obj/item/stock_parts/power_store/proc/gib_user(mob/living/user, discharged_energy)
|
|
if(QDELETED(user))
|
|
return
|
|
if(discharged_energy < STANDARD_BATTERY_CHARGE)
|
|
return
|
|
user.dropItemToGround(src)
|
|
user.dust(just_ash = TRUE)
|
|
playsound(src, 'sound/magic/lightningshock.ogg', 50, TRUE, 10)
|
|
tesla_zap(source = src, zap_range = 10, power = discharged_energy)
|
|
|
|
/obj/item/stock_parts/power_store/attack_self(mob/user)
|
|
if(ishuman(user))
|
|
var/mob/living/carbon/human/H = user
|
|
var/obj/item/organ/internal/stomach/maybe_stomach = H.get_organ_slot(ORGAN_SLOT_STOMACH)
|
|
|
|
if(istype(maybe_stomach, /obj/item/organ/internal/stomach/ethereal))
|
|
|
|
var/charge_limit = ETHEREAL_CHARGE_DANGEROUS - CELL_POWER_GAIN
|
|
var/obj/item/organ/internal/stomach/ethereal/stomach = maybe_stomach
|
|
var/obj/item/stock_parts/power_store/stomach_cell = stomach.cell
|
|
if((stomach.drain_time > world.time) || !stomach)
|
|
return
|
|
if(charge < CELL_POWER_DRAIN)
|
|
to_chat(H, span_warning("[src] doesn't have enough power!"))
|
|
return
|
|
if(stomach_cell.charge() > charge_limit)
|
|
to_chat(H, span_warning("Your charge is full!"))
|
|
return
|
|
H.visible_message(span_notice("[user] hovers their fingers above [src], arcs forming from its surface!")) //SKYRAT EDIT CHANGE - Ethereal Rework 2024 - ORIGINAL: to_chat(H, span_notice("You begin clumsily channeling power from [src] into your body."))
|
|
stomach.drain_time = world.time + CELL_DRAIN_TIME
|
|
while(do_after(user, CELL_DRAIN_TIME, target = src))
|
|
if((charge < CELL_POWER_DRAIN) || (stomach_cell.charge() > charge_limit))
|
|
return
|
|
if(istype(stomach))
|
|
to_chat(H, span_notice("You receive some charge from [src], wasting some in the process."))
|
|
stomach.adjust_charge(CELL_POWER_GAIN)
|
|
charge -= CELL_POWER_DRAIN //you waste way more than you receive, so that ethereals cant just steal one cell and forget about hunger
|
|
else
|
|
to_chat(H, span_warning("You can't receive charge from [src]!"))
|
|
return
|
|
|
|
/obj/item/stock_parts/power_store/blob_act(obj/structure/blob/B)
|
|
SSexplosions.high_mov_atom += src
|
|
|
|
/obj/item/stock_parts/power_store/proc/get_electrocute_damage()
|
|
return ELECTROCUTE_DAMAGE(charge / max(0.001 * STANDARD_CELL_CHARGE, 1)) // Wouldn't want it to consider more energy than whatever is actually in the cell if for some strange reason someone set the STANDARD_CELL_CHARGE to below 1kJ.
|
|
|
|
/obj/item/stock_parts/power_store/get_part_rating()
|
|
return maxcharge * 10 + charge
|
|
|
|
#undef CELL_DRAIN_TIME
|
|
#undef CELL_POWER_GAIN
|
|
#undef CELL_POWER_DRAIN
|