This commit is contained in:
Ghommie
2020-05-18 03:15:54 +02:00
112 changed files with 656 additions and 655 deletions
@@ -23,5 +23,5 @@
addtimer(CALLBACK(src, .proc/zap), rand(30, 100))
/obj/item/organ/heart/gland/electric/proc/zap()
tesla_zap(owner, 4, 8000, TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN)
tesla_zap(owner, 4, 8000, ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_MOB_STUN)
playsound(get_turf(owner), 'sound/magic/lightningshock.ogg', 50, TRUE)
@@ -207,8 +207,8 @@
if(prob(100 - severity * 30))
new /obj/effect/temp_visual/emp(get_turf(src))
/obj/structure/blob/tesla_act(power)
..()
/obj/structure/blob/zap_act(power)
. = ..()
if(overmind)
if(overmind.blobstrain.tesla_reaction(src, power))
take_damage(power/400, BURN, "energy")
@@ -492,7 +492,7 @@
/obj/structure/bloodsucker/candelabrum/process()
if(!lit)
return
for(var/mob/living/carbon/human/H in get_actual_viewers(7, src))
for(var/mob/living/carbon/human/H in fov_viewers(7, src))
var/datum/antagonist/vassal/T = H.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
if(AmBloodsucker(H) || T) //We dont want vassals or vampires affected by this
return
@@ -19,7 +19,7 @@
if(!.)
return
// must have nobody around to see the cloak
for(var/mob/living/M in get_actual_viewers(9, owner) - owner)
for(var/mob/living/M in fov_viewers(9, owner) - owner)
to_chat(owner, "<span class='warning'>You may only vanish into the shadows unseen.</span>")
return FALSE
return TRUE
@@ -169,7 +169,7 @@
vision_distance = notice_range, ignored_mobs = target) // Only people who AREN'T the target will notice this action.
// Warn Feeder about Witnesses...
var/was_unnoticed = TRUE
for(var/mob/living/M in get_actual_viewers(notice_range, owner) - owner - target)
for(var/mob/living/M in fov_viewers(notice_range, owner) - owner - target)
if(M.client && !M.silicon_privileges && !M.eye_blind && !M.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
was_unnoticed = FALSE
break
@@ -64,7 +64,7 @@
var/turf/T = get_turf(user)
if(T && T.lighting_object && T.get_lumcount()>= 0.1)
// B) Check for Viewers
for(var/mob/living/M in get_actual_viewers(world.view, get_turf(owner)) - owner)
for(var/mob/living/M in fov_viewers(world.view, get_turf(owner)) - owner)
if(M.client && !M.silicon_privileges && !M.eye_blind)
am_seen = TRUE
if (!M.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
@@ -64,7 +64,7 @@
to_chat(owner, "<span class='warning'>Your victim's eyes are glazed over. They cannot perceive you.</span>")
return FALSE
// Check: Target See Me? (behind wall)
if(!(owner in target.visible_atoms()))
if(!(owner in target.fov_view()))
// Sub-Check: GET CLOSER
//if (!(owner in range(target_range, get_turf(target)))
// if (display_error)
@@ -137,7 +137,7 @@
if(istype(target) && success)
target.notransform = FALSE
REMOVE_TRAIT(target, TRAIT_COMBAT_MODE_LOCKED, src)
if(istype(L) && target.stat == CONSCIOUS && (target in L.visible_atoms(10))) // They Woke Up! (Notice if within view)
if(istype(L) && target.stat == CONSCIOUS && (target in L.fov_view(10))) // They Woke Up! (Notice if within view)
to_chat(L, "<span class='warning'>[target] has snapped out of their trance.</span>")
@@ -5,6 +5,7 @@
clockwork_desc = "A sigil of some purpose."
icon_state = "sigil"
layer = LOW_OBJ_LAYER
plane = ABOVE_WALL_PLANE
alpha = 50
resistance_flags = NONE
var/affects_servants = FALSE
@@ -451,9 +451,9 @@
return
qdel(src)
/obj/machinery/nuclearbomb/tesla_act(power, tesla_flags)
/obj/machinery/nuclearbomb/zap_act(power, zap_flags)
..()
if(tesla_flags & TESLA_MACHINE_EXPLOSIVE)
if(zap_flags & ZAP_MACHINE_EXPLOSIVE)
qdel(src)//like the singulo, tesla deletes it. stops it from exploding over and over
#define NUKERANGE 127
@@ -226,7 +226,11 @@
/datum/spellbook_entry/lightningbolt/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) //return 1 on success
. = ..()
user.flags_1 |= TESLA_IGNORE_1
ADD_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "lightning_bolt_spell")
/datum/spellbook_entry/lightningbolt/Refund(mob/living/carbon/human/user, obj/item/spellbook/book)
. = ..()
REMOVE_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "lightning_bolt_spell")
/datum/spellbook_entry/infinite_guns
name = "Lesser Summon Guns"
@@ -17,6 +17,7 @@
active_power_usage = 0
power_channel = ENVIRON
layer = GAS_PIPE_HIDDEN_LAYER //under wires
plane = ABOVE_WALL_PLANE
resistance_flags = FIRE_PROOF
max_integrity = 200
obj_flags = CAN_BE_HIT | ON_BLUEPRINTS
@@ -7,6 +7,7 @@
name = "circulator/heat exchanger"
desc = "A gas circulator pump and heat exchanger."
icon_state = "circ-off-0"
plane = GAME_PLANE
var/active = FALSE
@@ -32,7 +32,7 @@
var/turf/T = loc
if(level == 2 || (istype(T) && !T.intact))
showpipe = TRUE
plane = GAME_PLANE
plane = ABOVE_WALL_PLANE
else
showpipe = FALSE
plane = FLOOR_PLANE
@@ -6,6 +6,7 @@
max_integrity = 350
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 30, "acid" = 30)
layer = ABOVE_WINDOW_LAYER
plane = GAME_PLANE
state_open = FALSE
circuit = /obj/item/circuitboard/machine/cryo_tube
pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY
@@ -15,8 +16,8 @@
var/volume = 100
var/efficiency = 1
var/sleep_factor = 0.00125
var/unconscious_factor = 0.001
var/base_knockout = 30 SECONDS
var/knockout_factor = 1
var/heat_capacity = 20000
var/conduction_coefficient = 0.3
@@ -53,10 +54,9 @@
var/C
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
C += M.rating
// 2 bins total, so C ranges from 2 to 8.
efficiency = initial(efficiency) * C
sleep_factor = initial(sleep_factor) * C
unconscious_factor = initial(unconscious_factor) * C
knockout_factor = initial(knockout_factor) / max(1, (C * 0.33))
heat_capacity = initial(heat_capacity) / C
conduction_coefficient = initial(conduction_coefficient) * C
@@ -188,8 +188,10 @@
if(air1.gases.len)
if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic.
mob_occupant.Sleeping((mob_occupant.bodytemperature * sleep_factor) * 2000)
mob_occupant.Unconscious((mob_occupant.bodytemperature * unconscious_factor) * 2000)
// temperature factor goes from 1 to about 2.5
var/amount = max(1, (4 * log(T0C - mob_occupant.bodytemperature)) - 20) * knockout_factor * base_knockout
mob_occupant.Sleeping(amount)
mob_occupant.Unconscious(amount)
if(beaker)
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents.
@@ -7,6 +7,7 @@
max_integrity = 800
density = TRUE
layer = ABOVE_WINDOW_LAYER
plane = GAME_PLANE
pipe_flags = PIPING_ONE_PER_TURF
var/volume = 10000 //in liters
var/gas_type = 0
@@ -9,6 +9,7 @@
max_integrity = 300
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 30)
layer = OBJ_LAYER
plane = GAME_PLANE
circuit = /obj/item/circuitboard/machine/thermomachine
ui_x = 300
ui_y = 230
+4 -2
View File
@@ -2385,9 +2385,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("ambientocclusion")
ambientocclusion = !ambientocclusion
if(parent && parent.screen && parent.screen.len)
var/obj/screen/plane_master/game_world/PM = parent.mob.hud_used.plane_masters["[GAME_PLANE]"]
var/obj/screen/plane_master/game_world/G = parent.mob.hud_used.plane_masters["[GAME_PLANE]"]
var/obj/screen/plane_master/above_wall/A = parent.mob.hud_used.plane_masters["[ABOVE_WALL_PLANE]"]
var/obj/screen/plane_master/wall/W = parent.mob.hud_used.plane_masters["[WALL_PLANE]"]
PM.backdrop(parent.mob)
G.backdrop(parent.mob)
A.backdrop(parent.mob)
W.backdrop(parent.mob)
if("auto_fit_viewport")
+3 -3
View File
@@ -649,7 +649,6 @@
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | IMMUTABLE_SLOW
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
flags_1 = TESLA_IGNORE_1
/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason
name = "M.A.S.O.N RIG helmet"
@@ -665,7 +664,6 @@
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
flags_1 = TESLA_IGNORE_1
/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/Initialize()
. = ..()
@@ -676,12 +674,14 @@
if (slot == SLOT_HEAD)
var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC]
DHUD.add_hud_to(user)
ADD_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "mason_hardsuit")
/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/dropped(mob/living/carbon/human/user)
..()
if (user.head == src)
if (HAS_TRAIT_FROM(user, TRAIT_TESLA_SHOCKIMMUNE, "mason_hardsuit"))
var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC]
DHUD.remove_hud_from(user)
REMOVE_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "mason_hardsuit")
/obj/item/clothing/suit/space/hardsuit/ancient/proc/on_mob_move()
var/mob/living/carbon/human/H = loc
@@ -164,21 +164,21 @@
desc = "An experimental suit of armor with sensitive detectors hooked up to a huge capacitor grid, with emitters strutting out of it. Zap."
siemens_coefficient = -1
reactivearmor_cooldown_duration = 20
var/tesla_power = 25000
var/tesla_range = 20
var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE
var/zap_power = 25000
var/zap_range = 20
var/zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE
var/legacy = FALSE
var/legacy_dmg = 30
/obj/item/clothing/suit/armor/reactive/tesla/dropped(mob/user)
..()
if(istype(user))
user.flags_1 &= ~TESLA_IGNORE_1
REMOVE_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "reactive_tesla_armor")
/obj/item/clothing/suit/armor/reactive/tesla/equipped(mob/user, slot)
..()
if(slot_flags & slotdefine2slotbit(slot)) //Was equipped to a valid slot for this item?
user.flags_1 |= TESLA_IGNORE_1
ADD_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "reactive_tesla_armor")
/obj/item/clothing/suit/armor/reactive/tesla/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(prob(hit_reaction_chance))
@@ -190,7 +190,7 @@
return
owner.visible_message("<span class='danger'>[src] blocks [attack_text], sending out arcs of lightning!</span>")
if(!legacy)
tesla_zap(owner, tesla_range, tesla_power, tesla_flags)
tesla_zap(owner, zap_range, zap_power, zap_flags)
else
for(var/mob/living/M in view(7, owner))
if(M == owner)
+2 -2
View File
@@ -1258,7 +1258,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
..()
if(!target.halbody)
var/list/possible_points = list()
for(var/turf/open/floor/F in target.visible_atoms(world.view))
for(var/turf/open/floor/F in target.fov_view(world.view))
possible_points += F
if(possible_points.len)
var/turf/open/floor/husk_point = pick(possible_points)
@@ -1289,7 +1289,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
set waitfor = FALSE
..()
var/list/turf/startlocs = list()
for(var/turf/open/T in target.visible_atoms(world.view+1)-view(world.view,target))
for(var/turf/open/T in target.fov_view(world.view+1)-view(world.view,target))
startlocs += T
if(!startlocs.len)
qdel(src)
@@ -29,7 +29,7 @@
<span class="ms" id="pingMs">--ms</span>
</div>
<div id="darkmodething">
<a href="#" class="subCell toggle" id="changeColorPreset" title="Change color preset"><i class="fas fa-eye-open"></i></a>
<a href="#" class="subCell toggle" id="changeColorPreset" title="Change color preset"><i class="fas fa-eye"></i></a>
</div>
<div id="audio">
<a href="#" class="subCell toggle" id="toggleAudio" title="Audio"><i class="fas fa-volume-up"></i></a>
+18 -1
View File
@@ -102,7 +102,22 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
/obj/item/stack/ore/glass/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(..() || !ishuman(hit_atom))
return
var/mob/living/carbon/human/C = hit_atom
var/mob/living/carbon/human/poorsod = hit_atom
eyesand(poorsod)
/obj/item/stack/ore/glass/attack(mob/living/M, mob/living/user)
if(!ishuman(M))
return ..()
if(user.zone_selected != BODY_ZONE_PRECISE_EYES && user.zone_selected != BODY_ZONE_HEAD)
return ..()
var/mob/living/carbon/human/poorsod = M
visible_message("<span class='danger'>[user] throws the sand at [poorsod]'s face!</span>")
if(ishuman(user))
var/mob/living/carbon/human/sayer = user
sayer.forcesay("POCKET SAAND!!")
eyesand(poorsod)
/obj/item/stack/ore/glass/proc/eyesand(mob/living/carbon/human/C)
if(C.head && C.head.flags_cover & HEADCOVERSEYES)
visible_message("<span class='danger'>[C]'s headgear blocks the sand!</span>")
return
@@ -116,8 +131,10 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
C.adjustStaminaLoss(15)//the pain from your eyes burning does stamina damage
C.confused += 5
to_chat(C, "<span class='userdanger'>\The [src] gets into your eyes! The pain, it burns!</span>")
C.forcesay("*scream")
qdel(src)
/obj/item/stack/ore/glass/ex_act(severity, target)
if (severity == EXPLODE_NONE)
return
+1 -1
View File
@@ -707,7 +707,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
//this is a mob verb instead of atom for performance reasons
//see /mob/verb/examinate() in mob.dm for more info
//overridden here and in /mob/living for different point span classes and sanity checks
/mob/dead/observer/pointed(atom/A as mob|obj|turf in visible_atoms())
/mob/dead/observer/pointed(atom/A as mob|obj|turf in fov_view())
if(!..())
return 0
usr.visible_message("<span class='deadsay'><b>[src]</b> points to [A].</span>")
@@ -234,38 +234,44 @@
var/obj/item/organ/O = X
O.emp_act(severity)
///Adds to the parent by also adding functionality to propagate shocks through pulling and doing some fluff effects.
/mob/living/carbon/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
if((flags & SHOCK_TESLA) && (flags_1 & TESLA_IGNORE_1))
return FALSE
if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE))
return FALSE
shock_damage *= siemens_coeff
if(dna && dna.species)
shock_damage *= dna.species.siemens_coeff
if(shock_damage < 1)
return 0
if(reagents.has_reagent(/datum/reagent/teslium))
shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
if((flags & SHOCK_ILLUSION))
adjustStaminaLoss(shock_damage)
else
take_overall_damage(0,shock_damage)
visible_message(
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
"<span class='italics'>You hear a heavy electrical crack.</span>" \
)
jitteriness += 1000 //High numbers for violent convulsions
. = ..()
if(!.)
return
//Propagation through pulling, fireman carry
if(!(flags & SHOCK_ILLUSION))
var/list/shocking_queue = list()
if(iscarbon(pulling) && source != pulling)
shocking_queue += pulling
if(iscarbon(pulledby) && source != pulledby)
shocking_queue += pulledby
if(iscarbon(buckled) && source != buckled)
shocking_queue += buckled
for(var/mob/living/carbon/carried in buckled_mobs)
if(source != carried)
shocking_queue += carried
//Found our victims, now lets shock them all
for(var/victim in shocking_queue)
var/mob/living/carbon/C = victim
C.electrocute_act(shock_damage*0.75, src, 1, flags)
//Stun
var/should_stun = (!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN)
if(should_stun)
Stun(40)
//Jitter and other fluff.
jitteriness += 1000
do_jitter_animation(jitteriness)
stuttering += 2
if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN))
Stun(40)
spawn(20)
jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less
if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN))
DefaultCombatKnockdown(60)
addtimer(CALLBACK(src, .proc/secondary_shock, should_stun), 20)
return shock_damage
///Called slightly after electrocute act to reduce jittering and apply a secondary stun.
/mob/living/carbon/proc/secondary_shock(should_stun)
jitteriness = max(jitteriness - 990, 10)
if(should_stun)
DefaultCombatKnockdown(60)
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
if(on_fire)
to_chat(M, "<span class='warning'>You can't put [p_them()] out with just your bare hands!</span>")
@@ -348,40 +348,34 @@
apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee"))
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
///Calculates the siemens coeff based on clothing and species, can also restart hearts.
/mob/living/carbon/human/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
if(flags & SHOCK_TESLA)
var/total_coeff = 1
if(gloves)
var/obj/item/clothing/gloves/G = gloves
if(G.siemens_coefficient <= 0)
total_coeff -= 0.5
//Calculates the siemens coeff based on clothing. Completely ignores the arguments
if(flags & SHOCK_TESLA) //I hate this entire block. This gets the siemens_coeff for tesla shocks
if(gloves && gloves.siemens_coefficient <= 0)
siemens_coeff -= 0.5
if(wear_suit)
var/obj/item/clothing/suit/S = wear_suit
if(S.siemens_coefficient <= 0)
total_coeff -= 0.95
else if(S.siemens_coefficient == (-1))
total_coeff -= 1
siemens_coeff = total_coeff
if(flags_1 & TESLA_IGNORE_1)
siemens_coeff = 0
else if(!(flags & SHOCK_NOGLOVES))
var/gloves_siemens_coeff = 1
if(wear_suit.siemens_coefficient == -1)
siemens_coeff -= 1
else if(wear_suit.siemens_coefficient <= 0)
siemens_coeff -= 0.95
siemens_coeff = max(siemens_coeff, 0)
else if(!(flags & SHOCK_NOGLOVES)) //This gets the siemens_coeff for all non tesla shocks
if(gloves)
var/obj/item/clothing/gloves/G = gloves
gloves_siemens_coeff = G.siemens_coefficient
siemens_coeff = gloves_siemens_coeff
if(undergoing_cardiac_arrest() && !(flags & SHOCK_ILLUSION))
if(shock_damage * siemens_coeff >= 1 && prob(25))
var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
heart.beating = TRUE
if(stat == CONSCIOUS)
to_chat(src, "<span class='notice'>You feel your heart beating again!</span>")
siemens_coeff *= gloves.siemens_coefficient
siemens_coeff *= physiology.siemens_coeff
. = ..()
if(.)
electrocution_animation(40)
//Don't go further if the shock was blocked/too weak.
if(!.)
return
//Note we both check that the user is in cardiac arrest and can actually heartattack
//If they can't, they're missing their heart and this would runtime
if(undergoing_cardiac_arrest() && can_heartattack() && !(flags & SHOCK_ILLUSION))
if(shock_damage * siemens_coeff >= 1 && prob(25))
var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
if(heart.Restart() && stat == CONSCIOUS)
to_chat(src, "<span class='notice'>You feel your heart beating again!</span>")
electrocution_animation(40)
/mob/living/carbon/human/emp_act(severity)
. = ..()
@@ -121,7 +121,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
return
//Filth Reactions - Since miasma now exists
var/filth_counter = 0 //Holder for the filth check cycle, basically contains how much filth dwarf sees numerically.
for(var/fuck in owner.visible_atoms(7)) //hello byond for view loop.
for(var/fuck in owner.fov_view(7)) //hello byond for view loop.
if(istype(fuck, /mob/living/carbon/human))
var/mob/living/carbon/human/H = fuck
if(H.stat == DEAD || (HAS_TRAIT(H, TRAIT_FAKEDEATH)))
+1 -1
View File
@@ -379,7 +379,7 @@
stop_pulling()
//same as above
/mob/living/pointed(atom/A as mob|obj|turf in visible_atoms())
/mob/living/pointed(atom/A as mob|obj|turf in fov_view())
if(incapacitated())
return FALSE
if(HAS_TRAIT(src, TRAIT_DEATHCOMA))
+16 -12
View File
@@ -412,21 +412,26 @@
take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1))
return 1
///As the name suggests, this should be called to apply electric shocks.
/mob/living/proc/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage, source, siemens_coeff, flags)
if((flags & SHOCK_TESLA) && (flags_1 & TESLA_IGNORE_1))
shock_damage *= siemens_coeff
if((flags & SHOCK_TESLA) && HAS_TRAIT(src, TRAIT_TESLA_SHOCKIMMUNE))
return FALSE
if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE))
return FALSE
if(shock_damage > 0)
if(!(flags & SHOCK_ILLUSION))
adjustFireLoss(shock_damage)
visible_message(
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
"<span class='italics'>You hear a heavy electrical crack.</span>" \
)
return shock_damage
if(shock_damage < 1)
return FALSE
if(!(flags & SHOCK_ILLUSION))
adjustFireLoss(shock_damage)
else
adjustStaminaLoss(shock_damage)
visible_message(
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
"<span class='hear'>You hear a heavy electrical crack.</span>" \
)
return shock_damage
/mob/living/emp_act(severity)
. = ..()
@@ -509,7 +514,6 @@
/mob/living/proc/getBruteLoss_nonProsthetic()
return getBruteLoss()
/mob/living/proc/getFireLoss_nonProsthetic()
return getFireLoss()
@@ -418,7 +418,7 @@
else
..()
/mob/living/simple_animal/bot/medbot/examinate(atom/A as mob|obj|turf in visible_atoms())
/mob/living/simple_animal/bot/medbot/examinate(atom/A as mob|obj|turf in fov_view())
..()
if(!is_blind(src))
chemscan(src, A)
@@ -20,7 +20,6 @@
mouse_opacity = 2
density = TRUE
ventcrawler = VENTCRAWLER_ALWAYS
gold_core_spawnable = FRIENDLY_SPAWN
verb_say = "chitters"
verb_ask = "chitters inquisitively"
verb_exclaim = "chitters loudly"
@@ -125,7 +125,7 @@
// This loop will, at most, loop twice.
for(var/atom/check in check_list)
for(var/mob/living/M in get_actual_viewers(world.view + 1, check) - src)
for(var/mob/living/M in fov_viewers(world.view + 1, check) - src)
if(M.client && CanAttack(M) && !M.silicon_privileges)
if(!M.eye_blind)
return M
@@ -28,7 +28,7 @@
return 0
var/list/choices = list()
for(var/mob/living/C in visible_atoms(1,src))
for(var/mob/living/C in fov_view(1,src))
if(C!=src && Adjacent(C))
choices += C
+4 -4
View File
@@ -319,12 +319,12 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
return
//view() but with a signal, to allow blacklisting some of the otherwise visible atoms.
/mob/proc/visible_atoms(dist = world.view)
/mob/proc/fov_view(dist = world.view)
. = view(dist, src)
SEND_SIGNAL(src, COMSIG_MOB_VISIBLE_ATOMS, .)
SEND_SIGNAL(src, COMSIG_MOB_FOV_VIEW, .)
//mob verbs are faster than object verbs. See https://secure.byond.com/forum/?post=1326139&page=2#comment8198716 for why this isn't atom/verb/examine()
/mob/verb/examinate(atom/A as mob|obj|turf in visible_atoms()) //It used to be oview(12), but I can't really say why
/mob/verb/examinate(atom/A as mob|obj|turf in fov_view()) //It used to be oview(12), but I can't really say why
set name = "Examine"
set category = "IC"
@@ -349,7 +349,7 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
//note: ghosts can point, this is intended
//visible_message will handle invisibility properly
//overridden here and in /mob/dead/observer for different point span classes and sanity checks
/mob/verb/pointed(atom/A as mob|obj|turf in visible_atoms())
/mob/verb/pointed(atom/A as mob|obj|turf in fov_view())
set name = "Point To"
set category = "Object"
+1
View File
@@ -39,6 +39,7 @@ By design, d1 is the smallest direction and d2 is the highest
icon = 'icons/obj/power_cond/cables.dmi'
icon_state = "0-1"
level = 1 //is underfloor
plane = ABOVE_WALL_PLANE
layer = WIRE_LAYER //Above hidden pipes, GAS_PIPE_HIDDEN_LAYER
anchored = TRUE
obj_flags = CAN_BE_HIT | ON_BLUEPRINTS
+2 -2
View File
@@ -39,9 +39,9 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
if(prob(20))
set_broken()
/obj/machinery/gravity_generator/tesla_act(power, tesla_flags)
/obj/machinery/gravity_generator/zap_act(power, zap_flags)
..()
if(tesla_flags & TESLA_MACHINE_EXPLOSIVE)
if(zap_flags & ZAP_MACHINE_EXPLOSIVE)
qdel(src)//like the singulo, tesla deletes it. stops it from exploding over and over
/obj/machinery/gravity_generator/update_icon_state()
+3 -3
View File
@@ -687,9 +687,9 @@
on = TRUE
update()
/obj/machinery/light/tesla_act(power, tesla_flags)
if(tesla_flags & TESLA_MACHINE_EXPLOSIVE)
explosion(src,0,0,0,flame_range = 5, adminlog = 0)
/obj/machinery/light/zap_act(power, zap_flags)
if(zap_flags & ZAP_MACHINE_EXPLOSIVE)
explosion(src,0,0,0,flame_range = 5, adminlog = FALSE)
qdel(src)
else
return ..()
+4 -3
View File
@@ -97,6 +97,7 @@
/obj/machinery/power/rtg/abductor/fire_act(exposed_temperature, exposed_volume)
overload()
/obj/machinery/power/rtg/abductor/tesla_act()
..() //extend the zap
overload()
/obj/machinery/power/rtg/abductor/zap_act(power, zap_flags, shocked_objects)
. = ..() //extend the zap
if(zap_flags & ZAP_MACHINE_EXPLOSIVE)
overload()
+1 -1
View File
@@ -127,7 +127,7 @@
/obj/singularity/narsie/mezzer()
for(var/mob/living/carbon/M in get_actual_viewers(consume_range, src))
for(var/mob/living/carbon/M in fov_viewers(consume_range, src))
if(M.stat == CONSCIOUS)
if(!iscultist(M))
to_chat(M, "<span class='cultsmall'>You feel conscious thought crumble away in an instant as you gaze upon [src.name]...</span>")
@@ -433,7 +433,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
env.merge(removed)
air_update_turf()
for(var/mob/living/carbon/human/l in get_actual_viewers(HALLUCINATION_RANGE(power), src)) // If they can see it without mesons on. Bad on them.
for(var/mob/living/carbon/human/l in fov_viewers(HALLUCINATION_RANGE(power), src)) // If they can see it without mesons on. Bad on them.
if(!istype(l.glasses, /obj/item/clothing/glasses/meson))
var/D = sqrt(1 / max(1, get_dist(l, src)))
l.hallucination += power * config_hallucination_power * D
@@ -666,7 +666,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
//Some poor sod got eaten, go ahead and irradiate people nearby.
radiation_pulse(src, 3000, 2, TRUE)
var/list/viewers = get_actual_viewers(world.view, src)
var/list/viewers = fov_viewers(world.view, src)
for(var/mob/living/L in range(10))
investigate_log("has irradiated [key_name(L)] after consuming [AM].", INVESTIGATE_SUPERMATTER)
if(L in viewers)
+16 -15
View File
@@ -73,7 +73,7 @@
return ..()
/obj/machinery/power/tesla_coil/tesla_act(power, tesla_flags, shocked_targets)
/obj/machinery/power/tesla_coil/zap_act(power, zap_flags, shocked_targets)
if(anchored && !panel_open)
obj_flags |= BEING_SHOCKED
//don't lose arc power when it's not connected to anything
@@ -81,17 +81,17 @@
var/power_produced = powernet ? power / power_loss : power
add_avail(power_produced*input_power_multiplier)
flick("coilhit", src)
playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5)
tesla_zap(src, 5, power_produced, tesla_flags, shocked_targets)
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_ENG)
if(D)
D.adjust_money(min(power_produced, 1))
if(istype(linked_techweb))
linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min(power_produced, 1)) // x4 coils = ~240/m point bonus for R&D
addtimer(CALLBACK(src, .proc/reset_shocked), 10)
tesla_buckle_check(power)
zap_buckle_check(power)
playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5)
return power_produced
else
..()
. = ..()
/obj/machinery/power/tesla_coil/proc/zap()
if((last_zap + zap_cooldown) > world.time || !powernet)
@@ -102,8 +102,8 @@
var/power = (powernet.avail/2)
add_load(power)
playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5)
tesla_zap(src, 10, power/(coeff/2), TESLA_FUSION_FLAGS)
tesla_buckle_check(power/(coeff/2))
tesla_zap(src, 10, power/(coeff/2), ZAP_FUSION_FLAGS)
zap_buckle_check(power/(coeff/2))
// Tesla R&D researcher
/obj/machinery/power/tesla_coil/research
@@ -113,23 +113,23 @@
circuit = /obj/item/circuitboard/machine/tesla_coil/research
power_loss = 20 // something something, high voltage + resistance
/obj/machinery/power/tesla_coil/research/tesla_act(power, tesla_flags, shocked_things)
/obj/machinery/power/tesla_coil/research/zap_act(power, zap_flags, shocked_targets)
if(anchored && !panel_open)
obj_flags |= BEING_SHOCKED
var/power_produced = powernet ? power / power_loss : power
add_avail(power_produced*input_power_multiplier)
flick("rpcoilhit", src)
playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5)
tesla_zap(src, 5, power_produced, tesla_flags, shocked_things)
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_ENG)
if(D)
D.adjust_money(min(power_produced, 3))
if(istype(linked_techweb))
linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min(power_produced, 3)) // x4 coils with a pulse per second or so = ~720/m point bonus for R&D
addtimer(CALLBACK(src, .proc/reset_shocked), 10)
tesla_buckle_check(power)
zap_buckle_check(power)
playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5)
return power_produced
else
..()
. = ..()
/obj/machinery/power/tesla_coil/research/default_unfasten_wrench(mob/user, obj/item/wrench/W, time = 20)
. = ..()
@@ -180,9 +180,10 @@
return ..()
/obj/machinery/power/grounding_rod/tesla_act(var/power)
/obj/machinery/power/grounding_rod/zap_act(var/power)
if(anchored && !panel_open)
flick("grounding_rodhit", src)
tesla_buckle_check(power)
zap_buckle_check(power)
return 0
else
..()
. = ..()
+116 -87
View File
@@ -1,5 +1,14 @@
#define TESLA_DEFAULT_POWER 1738260
#define TESLA_MINI_POWER 869130
//Zap constants, speeds up targeting
#define BIKE (COIL + 1)
#define COIL (ROD + 1)
#define ROD (RIDE + 1)
#define RIDE (LIVING + 1)
#define LIVING (MACHINERY + 1)
#define MACHINERY (BLOB + 1)
#define BLOB (STRUCTURE + 1)
#define STRUCTURE (1)
/obj/singularity/energy_ball
name = "energy ball"
@@ -32,6 +41,9 @@
/obj/singularity/energy_ball/ex_act(severity, target)
return
/obj/singularity/energy_ball/consume(severity, target)
return
/obj/singularity/energy_ball/Destroy()
if(orbiting && istype(orbiting.parent, /obj/singularity/energy_ball))
var/obj/singularity/energy_ball/EB = orbiting.parent
@@ -39,7 +51,7 @@
for(var/ball in orbiting_balls)
var/obj/singularity/energy_ball/EB = ball
qdel(EB)
QDEL_NULL(EB)
. = ..()
@@ -55,12 +67,12 @@
move_the_basket_ball(4 + orbiting_balls.len * 1.5)
playsound(src.loc, 'sound/magic/lightningbolt.ogg', 100, 1, extrarange = 30)
playsound(src.loc, 'sound/magic/lightningbolt.ogg', 100, TRUE, extrarange = 30)
pixel_x = 0
pixel_y = 0
tesla_zap(src, 7, TESLA_DEFAULT_POWER, TRUE)
tesla_zap(src, 7, TESLA_DEFAULT_POWER)
pixel_x = -32
pixel_y = -32
@@ -73,7 +85,7 @@
/obj/singularity/energy_ball/examine(mob/user)
. = ..()
if(orbiting_balls.len)
. += "The amount of orbiting mini-balls is [orbiting_balls.len]."
. += "There are [orbiting_balls.len] mini-balls orbiting it."
/obj/singularity/energy_ball/proc/move_the_basket_ball(var/move_amount)
@@ -96,7 +108,7 @@
energy_to_lower = energy_to_raise - 20
energy_to_raise = energy_to_raise * 1.25
playsound(src.loc, 'sound/magic/lightning_chargeup.ogg', 100, 1, extrarange = 30)
playsound(src.loc, 'sound/magic/lightning_chargeup.ogg', 100, TRUE, extrarange = 30)
addtimer(CALLBACK(src, .proc/new_mini_ball), 100)
else if(energy < energy_to_lower && orbiting_balls.len)
@@ -132,22 +144,19 @@
/obj/singularity/energy_ball/attack_tk(mob/user)
if(iscarbon(user))
var/mob/living/carbon/C = user
log_game("[key_name(C)] has been disintegrated by a telekenetic grab on a tesla ball.</span>")
to_chat(C, "<span class='userdanger'>That was a shockingly dumb idea.</span>")
C.visible_message("<span class='userdanger'>A bright flare of lightning is seen from [C]'s head, shortly before you hear a sickening sizzling!</span>")
var/obj/item/organ/brain/rip_u = locate(/obj/item/organ/brain) in C.internal_organs
rip_u.Remove()
C.ghostize(0)
qdel(rip_u)
return
return ..()
C.death()
/obj/singularity/energy_ball/orbit(obj/singularity/energy_ball/target)
if (istype(target))
target.orbiting_balls += src
GLOB.poi_list -= src
target.dissipate_strength = target.orbiting_balls.len
. = ..()
/obj/singularity/energy_ball/stop_orbit()
if (orbiting && istype(orbiting.parent, /obj/singularity/energy_ball))
var/obj/singularity/energy_ball/orbitingball = orbiting.parent
@@ -171,20 +180,19 @@
var/mob/living/carbon/C = A
C.dust()
/proc/tesla_zap(atom/source, zap_range = 3, power, tesla_flags = TESLA_DEFAULT_FLAGS, list/shocked_targets)
/proc/tesla_zap(atom/source, zap_range = 3, power, zap_flags = ZAP_DEFAULT_FLAGS, list/shocked_targets)
if(QDELETED(source))
return
. = source.dir
if(power < 1000)
return
var/closest_dist = 0
var/closest_atom
var/obj/machinery/power/tesla_coil/closest_tesla_coil
var/obj/machinery/power/grounding_rod/closest_grounding_rod
var/mob/living/closest_mob
var/obj/machinery/closest_machine
var/obj/structure/closest_structure
var/obj/structure/blob/closest_blob
var/static/things_to_shock = typecacheof(list(/obj/machinery, /mob/living, /obj/structure))
/*
THIS IS SO FUCKING UGLY AND I HATE IT, but I can't make it nice without making it slower, check*N rather then n. So we're stuck with it.
*/
var/atom/closest_atom
var/closest_type = 0
var/static/things_to_shock = typecacheof(list(/obj/machinery, /mob/living, /obj/structure, /obj/vehicle/ridden))
var/static/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics,
/obj/machinery/power/emitter,
/obj/machinery/field/generator,
@@ -205,112 +213,133 @@
/obj/machinery/gateway,
/obj/structure/lattice,
/obj/structure/grille,
/obj/machinery/the_singularitygen/tesla,
/obj/structure/frame/machine))
for(var/A in typecache_filter_multi_list_exclusion(oview(source, zap_range+2), things_to_shock, blacklisted_tesla_types))
if(!(tesla_flags & TESLA_ALLOW_DUPLICATES) && LAZYACCESS(shocked_targets, A))
//Ok so we are making an assumption here. We assume that view() still calculates from the center out.
//This means that if we find an object we can assume it is the closest one of its type. This is somewhat of a speed increase.
//This also means we have no need to track distance, as the doview() proc does it all for us.
//Darkness fucks oview up hard. I've tried dview() but it doesn't seem to work
//I hate existance
for(var/a in typecache_filter_multi_list_exclusion(oview(zap_range+2, source), things_to_shock, blacklisted_tesla_types))
var/atom/A = a
if(!(zap_flags & ZAP_ALLOW_DUPLICATES) && LAZYACCESS(shocked_targets, A))
continue
if(closest_type >= BIKE)
break
if(istype(A, /obj/machinery/power/tesla_coil))
var/dist = get_dist(source, A)
var/obj/machinery/power/tesla_coil/C = A
if(dist <= zap_range && (dist < closest_dist || !closest_tesla_coil) && !(C.obj_flags & BEING_SHOCKED))
closest_dist = dist
else if(istype(A, /obj/vehicle/ridden/bicycle))//God's not on our side cause he hates idiots.
var/obj/vehicle/ridden/bicycle/B = A
if(!(B.obj_flags & BEING_SHOCKED) && B.can_buckle)//Gee goof thanks for the boolean
//we use both of these to save on istype and typecasting overhead later on
//while still allowing common code to run before hand
closest_tesla_coil = C
closest_atom = C
closest_type = BIKE
closest_atom = B
else if(closest_tesla_coil)
else if(closest_type >= COIL)
continue //no need checking these other things
else if(istype(A, /obj/machinery/power/grounding_rod))
var/dist = get_dist(source, A)-2
if(dist <= zap_range && (dist < closest_dist || !closest_grounding_rod))
closest_grounding_rod = A
closest_atom = A
closest_dist = dist
else if(istype(A, /obj/machinery/power/tesla_coil))
var/obj/machinery/power/tesla_coil/C = A
if(!(C.obj_flags & BEING_SHOCKED))
closest_type = COIL
closest_atom = C
else if(closest_grounding_rod)
else if(closest_type >= ROD)
continue
else if(istype(A, /obj/machinery/power/grounding_rod))
closest_type = ROD
closest_atom = A
else if(closest_type >= RIDE)
continue
else if(istype(A,/obj/vehicle/ridden))
var/obj/vehicle/ridden/R = A
if(R.can_buckle && !(R.obj_flags & BEING_SHOCKED))
closest_type = RIDE
closest_atom = A
else if(closest_type >= LIVING)
continue
else if(isliving(A))
var/dist = get_dist(source, A)
var/mob/living/L = A
if(dist <= zap_range && (dist < closest_dist || !closest_mob) && L.stat != DEAD && !(L.flags_1 & TESLA_IGNORE_1))
closest_mob = L
if(L.stat != DEAD && !(HAS_TRAIT(L, TRAIT_TESLA_SHOCKIMMUNE)) && !(L.flags_1 & SHOCKED_1))
closest_type = LIVING
closest_atom = A
closest_dist = dist
else if(closest_mob)
else if(closest_type >= MACHINERY)
continue
else if(ismachinery(A))
var/obj/machinery/M = A
var/dist = get_dist(source, A)
if(dist <= zap_range && (dist < closest_dist || !closest_machine) && !(M.obj_flags & BEING_SHOCKED))
closest_machine = M
if(!(M.obj_flags & BEING_SHOCKED))
closest_type = MACHINERY
closest_atom = A
closest_dist = dist
else if(closest_mob)
else if(closest_type >= BLOB)
continue
else if(istype(A, /obj/structure/blob))
var/obj/structure/blob/B = A
var/dist = get_dist(source, A)
if(dist <= zap_range && (dist < closest_dist || !closest_tesla_coil) && !(B.obj_flags & BEING_SHOCKED))
closest_blob = B
if(!(B.obj_flags & BEING_SHOCKED))
closest_type = BLOB
closest_atom = A
closest_dist = dist
else if(closest_blob)
else if(closest_type >= STRUCTURE)
continue
else if(isstructure(A))
var/obj/structure/S = A
var/dist = get_dist(source, A)
if(dist <= zap_range && (dist < closest_dist || !closest_tesla_coil) && !(S.obj_flags & BEING_SHOCKED))
closest_structure = S
if(!(S.obj_flags & BEING_SHOCKED))
closest_type = STRUCTURE
closest_atom = A
closest_dist = dist
//Alright, we've done our loop, now lets see if was anything interesting in range
if(closest_atom)
//common stuff
source.Beam(closest_atom, icon_state="lightning[rand(1,12)]", time=5, maxdistance = INFINITY)
if(!(tesla_flags & TESLA_ALLOW_DUPLICATES))
LAZYSET(shocked_targets, closest_atom, TRUE)
var/zapdir = get_dir(source, closest_atom)
if(zapdir)
. = zapdir
if(!closest_atom)
return
//common stuff
source.Beam(closest_atom, icon_state="lightning[rand(1,12)]", time=5, maxdistance = INFINITY)
if(!(zap_flags & ZAP_ALLOW_DUPLICATES))
LAZYSET(shocked_targets, closest_atom, TRUE)
var/zapdir = get_dir(source, closest_atom)
if(zapdir)
. = zapdir
//per type stuff:
if(closest_tesla_coil)
closest_tesla_coil.tesla_act(power, tesla_flags, shocked_targets)
var/next_range = 3
if(closest_type == COIL)
next_range = 5
else if(closest_grounding_rod)
closest_grounding_rod.tesla_act(power, tesla_flags, shocked_targets)
else if(closest_mob)
var/shock_damage = (tesla_flags & TESLA_MOB_DAMAGE)? (min(round(power/600), 90) + rand(-5, 5)) : 0
closest_mob.electrocute_act(shock_damage, source, 1, SHOCK_TESLA | ((tesla_flags & TESLA_MOB_STUN) ? NONE : SHOCK_NOSTUN))
if(closest_type == LIVING)
var/mob/living/closest_mob = closest_atom
closest_mob.set_shocked()
addtimer(CALLBACK(closest_mob, /mob/living/proc/reset_shocked), 10)
var/shock_damage = (zap_flags & ZAP_MOB_DAMAGE) ? (min(round(power/600), 90) + rand(-5, 5)) : 0
closest_mob.electrocute_act(shock_damage, source, 1, SHOCK_TESLA | ((zap_flags & ZAP_MOB_STUN) ? NONE : SHOCK_NOSTUN))
if(issilicon(closest_mob))
var/mob/living/silicon/S = closest_mob
if((tesla_flags & TESLA_MOB_STUN) && (tesla_flags & TESLA_MOB_DAMAGE))
if((zap_flags & ZAP_MOB_STUN) && (zap_flags & ZAP_MOB_DAMAGE))
S.emp_act(EMP_LIGHT)
tesla_zap(S, 7, power / 1.5, tesla_flags, shocked_targets) // metallic folks bounce it further
next_range = 7 // metallic folks bounce it further
else
tesla_zap(closest_mob, 5, power / 1.5, tesla_flags, shocked_targets)
next_range = 5
power /= 1.5
else if(closest_machine)
closest_machine.tesla_act(power, tesla_flags, shocked_targets)
else
power = closest_atom.zap_act(power, zap_flags, shocked_targets)
if(prob(20))//I know I know
tesla_zap(closest_atom, next_range, power * 0.5, zap_flags, shocked_targets)
tesla_zap(closest_atom, next_range, power * 0.5, zap_flags, shocked_targets)
else
tesla_zap(closest_atom, next_range, power, zap_flags, shocked_targets)
else if(closest_blob)
closest_blob.tesla_act(power, tesla_flags, shocked_targets)
else if(closest_structure)
closest_structure.tesla_act(power, tesla_flags, shocked_targets)
#undef BIKE
#undef COIL
#undef ROD
#undef RIDE
#undef LIVING
#undef MACHINERY
#undef BLOB
#undef STRUCTURE
+2 -2
View File
@@ -5,6 +5,6 @@
icon_state = "TheSingGen"
creation_type = /obj/singularity/energy_ball
/obj/machinery/the_singularitygen/tesla/tesla_act(power, tesla_flags)
if(tesla_flags & TESLA_MACHINE_EXPLOSIVE)
/obj/machinery/the_singularitygen/tesla/zap_act(power, zap_flags)
if(zap_flags & ZAP_MACHINE_EXPLOSIVE)
energy += power
@@ -31,6 +31,10 @@
else
BB.def_zone = user.zone_selected
BB.suppressed = quiet
if(isgun(fired_from))
var/obj/item/gun/G = fired_from
BB.damage *= G.projectile_damage_multiplier
if(reagents && BB.reagents)
reagents.trans_to(BB, reagents.total_volume) //For chemical darts/bullets
+3
View File
@@ -76,6 +76,9 @@
var/datum/action/item_action/toggle_scope_zoom/azoom
var/dualwield_spread_mult = 1 //dualwield spread multiplier
/// Just 'slightly' snowflakey way to modify projectile damage for projectiles fired from this gun.
var/projectile_damage_multiplier = 1
/obj/item/gun/Initialize()
. = ..()
@@ -3,7 +3,7 @@
icon_state = "tesla_projectile"
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
var/chain
var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE
var/zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE
var/zap_range = 3
var/power = 10000
@@ -15,7 +15,7 @@
/obj/item/projectile/energy/tesla/on_hit(atom/target)
. = ..()
tesla_zap(target, zap_range, power, tesla_flags)
tesla_zap(target, zap_range, power, zap_flags)
qdel(src)
/obj/item/projectile/energy/tesla/Destroy()
+4 -4
View File
@@ -437,9 +437,9 @@
speed = 0.3
flag = "magic"
var/tesla_power = 20000
var/tesla_range = 15
var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_MOB_STUN | TESLA_OBJ_DAMAGE
var/zap_power = 20000
var/zap_range = 15
var/zap_flags = ZAP_MOB_DAMAGE | ZAP_MOB_STUN | ZAP_OBJ_DAMAGE
var/chain
var/mob/living/caster
@@ -456,7 +456,7 @@
visible_message("<span class='warning'>[src] fizzles on contact with [target]!</span>")
qdel(src)
return BULLET_ACT_BLOCK
tesla_zap(src, tesla_range, tesla_power, tesla_flags)
tesla_zap(src, zap_range, zap_power, zap_flags)
qdel(src)
/obj/item/projectile/magic/aoe/lightning/Destroy()
@@ -50,7 +50,7 @@
if(M == hal_target)
to_chat(hal_target, "<span class='userdanger'>[M] is hit by \a [src] in the chest!</span>")
hal_apply_effect()
else if(M in hal_target.visible_atoms())
else if(M in hal_target.fov_view())
to_chat(hal_target, "<span class='danger'>[M] is hit by \a [src] in the chest!!</span>")
if(damage_type == BRUTE)
var/splatter_dir = dir
+1 -1
View File
@@ -535,7 +535,7 @@
add_reagent(P, cached_results[P]*multiplier, null, chem_temp)
var/list/seen = get_actual_viewers(4, get_turf(my_atom))//Sound and sight checkers
var/list/seen = fov_viewers(4, get_turf(my_atom))//Sound and sight checkers
var/iconhtml = icon2html(cached_my_atom, seen)
if(cached_my_atom)
if(!ismob(cached_my_atom)) // No bubbling mobs
@@ -227,6 +227,18 @@
playsound(M, "sparks", 50, 1)
..()
/datum/reagent/teslium/on_mob_metabolize(mob/living/carbon/human/L)
. = ..()
if(!istype(L))
return
L.physiology.siemens_coeff *= 2
/datum/reagent/teslium/on_mob_end_metabolize(mob/living/carbon/human/L)
. = ..()
if(!istype(L))
return
L.physiology.siemens_coeff *= 0.5
/datum/reagent/teslium/energized_jelly
name = "Energized Jelly"
description = "Electrically-charged jelly. Boosts jellypeople's nervous system, but only shocks other lifeforms."
@@ -429,7 +429,7 @@
noexplosion = TRUE
mix_message = "<span class='boldannounce'>The teslium starts to spark as electricity arcs away from it!</span>"
mix_sound = 'sound/machines/defib_zap.ogg'
var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN
var/zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_MOB_STUN
/datum/chemical_reaction/reagent_explosion/teslium_lightning/on_reaction(datum/reagents/holder, multiplier)
var/T1 = multiplier * 20 //100 units : Zap 3 times, with powers 2000/5000/12000. Tesla revolvers have a power of 10000 for comparison.
@@ -437,15 +437,15 @@
var/T3 = multiplier * 120
sleep(5)
if(multiplier >= 75)
tesla_zap(holder.my_atom, 7, T1, tesla_flags)
tesla_zap(holder.my_atom, 7, T1, zap_flags)
playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, 1)
sleep(15)
if(multiplier >= 40)
tesla_zap(holder.my_atom, 7, T2, tesla_flags)
tesla_zap(holder.my_atom, 7, T2, zap_flags)
playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, 1)
sleep(15)
if(multiplier >= 10) //10 units minimum for lightning, 40 units for secondary blast, 75 units for tertiary blast.
tesla_zap(holder.my_atom, 7, T3, tesla_flags)
tesla_zap(holder.my_atom, 7, T3, zap_flags)
playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, 1)
..()
+3 -2
View File
@@ -120,9 +120,10 @@
/obj/structure/reagent_dispensers/fueltank/fire_act(exposed_temperature, exposed_volume)
boom()
/obj/structure/reagent_dispensers/fueltank/tesla_act()
/obj/structure/reagent_dispensers/fueltank/zap_act(power, zap_flags, shocked_objects)
..() //extend the zap
boom()
if(ZAP_OBJ_DAMAGE & zap_flags)
boom()
/obj/structure/reagent_dispensers/fueltank/bullet_act(obj/item/projectile/P)
. = ..()
+1
View File
@@ -14,6 +14,7 @@
max_integrity = 200
armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30)
layer = DISPOSAL_PIPE_LAYER // slightly lower than wires and other pipes
plane = ABOVE_WALL_PLANE
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
var/dpdir = NONE // bitmask of pipe directions
var/initialize_dirs = NONE // bitflags of pipe directions added on init, see \code\_DEFINES\pipe_construction.dm
+1 -1
View File
@@ -101,7 +101,7 @@
base_icon_state = "lightning"
sound = 'sound/magic/lightningbolt.ogg'
active = FALSE
projectile_var_overrides = list("tesla_range" = 15, "tesla_power" = 20000, "tesla_flags" = TESLA_MOB_DAMAGE)
projectile_var_overrides = list("zap_range" = 15, "zap_power" = 20000, "zap_flags" = ZAP_MOB_DAMAGE)
active_msg = "You energize your hand with arcane lightning!"
deactive_msg = "You let the energy flow out of your hands back into yourself..."
projectile_type = /obj/item/projectile/magic/aoe/lightning
@@ -32,13 +32,11 @@
name = "Grounded Nerves"
desc = "Nerves form a safe path for electricity to traverse, protecting the body from electric shocks."
mod_type = BIOWARE_NERVES
var/prev_coeff
/datum/bioware/grounded_nerves/on_gain()
..()
prev_coeff = owner.physiology.siemens_coeff
owner.physiology.siemens_coeff = 0
ADD_TRAIT(owner, TRAIT_SHOCKIMMUNE, "grounded_nerves")
/datum/bioware/grounded_nerves/on_lose()
..()
owner.physiology.siemens_coeff = prev_coeff
REMOVE_TRAIT(owner, TRAIT_SHOCKIMMUNE, "grounded_nerves")
+1 -1
View File
@@ -99,7 +99,7 @@
* return UI_state The state of the UI.
**/
/mob/living/proc/shared_living_ui_distance(atom/movable/src_object)
if(!(src_object in visible_atoms())) // If the object is obscured, close it.
if(!(src_object in fov_view())) // If the object is obscured, close it.
return UI_CLOSE
var/dist = get_dist(src_object, src)
+3 -1
View File
@@ -24,10 +24,12 @@
buckled_mob.stop_sound_channel(CHANNEL_BICYCLE)
. =..()
/obj/vehicle/ridden/bicycle/tesla_act() // :::^^^)))
/obj/vehicle/ridden/bicycle/zap_act(zap_str, zap_flags, shocked_targets) // :::^^^)))
//This didn't work for 3 years because none ever tested it I hate life
name = "fried bicycle"
desc = "Well spent."
color = rgb(63, 23, 4)
can_buckle = FALSE
. = ..()
for(var/m in buckled_mobs)
unbuckle_mob(m,1)
+4
View File
@@ -77,3 +77,7 @@
if(!force && occupant_amount() >= max_occupants)
return FALSE
return ..()
/obj/vehicle/ridden/zap_act(zap_str, zap_flags, shocked_targets)
zap_buckle_check(zap_str)
. = ..()
+2 -4
View File
@@ -20,12 +20,10 @@
/obj/item/reagent_containers/food/condiment/saltshaker = 5,
/obj/item/reagent_containers/food/condiment/peppermill = 5)
contraband = list(
/obj/item/reagent_containers/food/snacks/cube/monkey= 1,
/obj/item/kitchen/knife/butcher = 2,
/obj/item/reagent_containers/syringe = 3)
premium = list(
/obj/item/reagent_containers/food/condiment/enzyme = 1,
/obj/item/reagent_containers/glass/bottle/cryoxadone = 2) // Bartender can literally make this with upgraded parts, or it gets stolen from medical.
/obj/item/reagent_containers/food/condiment/enzyme = 1)
armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
refill_canister = /obj/item/vending_refill/dinnerware
resistance_flags = FIRE_PROOF
@@ -35,4 +33,4 @@
cost_multiplier_per_dept = list(ACCOUNT_SRV = 0)
/obj/item/vending_refill/dinnerware
icon_state = "refill_cook"
icon_state = "refill_cook"
+1 -1
View File
@@ -542,7 +542,7 @@
if (!(R in contents))
return // User is not in this belly
R.setClickCooldown(50)
R.changeNext_move(CLICK_CD_BREAKOUT*0.5)
if(owner.stat) //If owner is stat (dead, KO) we can actually escape
to_chat(R,"<span class='warning'>You attempt to climb out of \the [lowertext(name)]. (This will take around [escapetime/10] seconds.)</span>")
+4 -1
View File
@@ -358,6 +358,9 @@
if(incapacitated(ignore_restraints = TRUE))
to_chat(src, "<span class='warning'>You can't do that while incapacitated.</span>")
return
if(next_move > world.time)
to_chat(src, "<span class='warning'>You can't do that so fast, slow down.</span>")
return
var/list/choices
for(var/mob/living/L in view(1))
@@ -372,7 +375,7 @@
if(QDELETED(tasted) || (tasted.ckey && !(tasted.client?.prefs.vore_flags & LICKABLE)) || !Adjacent(tasted) || incapacitated(ignore_restraints = TRUE))
return
setClickCooldown(100)
changeNext_move(CLICK_CD_MELEE)
visible_message("<span class='warning'>[src] licks [tasted]!</span>","<span class='notice'>You lick [tasted]. They taste rather like [tasted.get_taste_message()].</span>","<b>Slurp!</b>")