mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
[MIRROR] up ports incorp and proximity handling (#10266)
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
f84c502d2c
commit
3444e3e21d
@@ -96,7 +96,7 @@ avoid code duplication. This includes items that may sometimes act as a standard
|
||||
return 0
|
||||
if(M == user && user.a_intent != I_HURT)
|
||||
return 0
|
||||
if(M.is_incorporeal()) // CHOMPEdit - No attacking phased entities :)
|
||||
if(M.is_incorporeal()) // No attacking phased entities :)
|
||||
return 0
|
||||
|
||||
/////////////////////////
|
||||
|
||||
@@ -110,6 +110,8 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease))
|
||||
/datum/disease/proc/spread(force_spread = 0)
|
||||
if(!affected_mob)
|
||||
return
|
||||
if(affected_mob.is_incorporeal())
|
||||
return
|
||||
|
||||
if((spread_flags & SPECIAL || spread_flags & NON_CONTAGIOUS || spread_flags & BLOOD) && !force_spread)
|
||||
return
|
||||
@@ -128,6 +130,8 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease))
|
||||
var/turf/target = affected_mob.loc
|
||||
if(istype(target))
|
||||
for(var/mob/living/carbon/human/C in oview(spread_range, affected_mob))
|
||||
if(C.is_incorporeal())
|
||||
continue
|
||||
var/turf/current = get_turf(C)
|
||||
if(current)
|
||||
while(TRUE)
|
||||
|
||||
@@ -108,7 +108,7 @@ Bonus
|
||||
|
||||
var/mob/living/unlucky = locate() in place
|
||||
|
||||
if(unlucky && !unlucky.is_incorporeal()) // CHOMPEdit
|
||||
if(unlucky && !unlucky.is_incorporeal())
|
||||
if(unlucky.can_be_drop_pred && mob.can_be_drop_prey && mob.devourable)
|
||||
place = unlucky.vore_selected
|
||||
else if(unlucky.devourable && unlucky.can_be_drop_prey && mob.can_be_drop_pred)
|
||||
|
||||
@@ -445,7 +445,7 @@ var/list/mob/living/forced_ambiance_list = new
|
||||
return // Being buckled to something solid keeps you in place.
|
||||
if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.item_flags & NOSLIP))
|
||||
return
|
||||
if(H.incorporeal_move) // VOREstation edit - Phaseshifted beings should not be affected by gravity
|
||||
if(H.is_incorporeal()) // VOREstation edit - Phaseshifted beings should not be affected by gravity
|
||||
return
|
||||
if(H.species.can_zero_g_move || H.species.can_space_freemove)
|
||||
return
|
||||
@@ -558,7 +558,7 @@ GLOBAL_DATUM(spoiler_obfuscation_image, /image)
|
||||
|
||||
// RS Port #658 Start
|
||||
/area/proc/check_phase_shift(var/mob/ourmob)
|
||||
if(!flag_check(AREA_BLOCK_PHASE_SHIFT) || !ourmob.incorporeal_move)
|
||||
if(!flag_check(AREA_BLOCK_PHASE_SHIFT) || !ourmob.is_incorporeal())
|
||||
return
|
||||
if(!isliving(ourmob))
|
||||
return
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
// Used to be for the PROXMOVE flag, but that was terrible, so instead it's just here as a stub for
|
||||
// all the atoms that still have the proc, but get events other ways.
|
||||
/atom/proc/HasProximity(turf/T, datum/weakref/WF, old_loc)
|
||||
SIGNAL_HANDLER // CHOMPAdd
|
||||
SIGNAL_HANDLER
|
||||
return
|
||||
|
||||
//Register listeners on turfs in a certain range
|
||||
|
||||
@@ -422,10 +422,14 @@
|
||||
/atom/movable/proc/hit_check(var/speed)
|
||||
if(src.throwing)
|
||||
for(var/atom/A in get_turf(src))
|
||||
if(A == src) continue
|
||||
if(A == src)
|
||||
continue
|
||||
if(A.is_incorporeal())
|
||||
continue
|
||||
if(isliving(A))
|
||||
if(A:lying) continue
|
||||
if(A.is_incorporeal()) continue // CHOMPEdit - For phased entities
|
||||
var/mob/living/M = A
|
||||
if(M.lying)
|
||||
continue
|
||||
src.throw_impact(A,speed)
|
||||
if(isobj(A))
|
||||
if(!A.density || A.throwpass)
|
||||
|
||||
@@ -54,7 +54,6 @@
|
||||
detectTime = -1
|
||||
return 1
|
||||
|
||||
// CHOMPEdit start
|
||||
/obj/machinery/camera/HasProximity(turf/T, datum/weakref/WF, old_loc)
|
||||
SIGNAL_HANDLER
|
||||
if(isnull(WF))
|
||||
@@ -63,7 +62,6 @@
|
||||
if(isnull(AM))
|
||||
log_debug("DEBUG: HasProximity called without reference on [src].")
|
||||
return
|
||||
// CHOMPEdit End
|
||||
// Motion cameras outside of an "ai monitored" area will use this to detect stuff.
|
||||
if (!area_motion)
|
||||
if(isliving(AM))
|
||||
|
||||
@@ -251,7 +251,7 @@ var/global/list/engineering_networks = list(
|
||||
assembly.upgrades.Add(new /obj/item/assembly/prox_sensor(assembly))
|
||||
setPowerUsage()
|
||||
START_MACHINE_PROCESSING(src)
|
||||
sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity)) // CHOMPEdit
|
||||
sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity))
|
||||
update_coverage()
|
||||
|
||||
/obj/machinery/camera/proc/setPowerUsage()
|
||||
|
||||
@@ -97,7 +97,6 @@
|
||||
flash()
|
||||
..(severity)
|
||||
|
||||
// CHOMPEdit Start
|
||||
/obj/machinery/flasher/portable/HasProximity(turf/T, datum/weakref/WF, oldloc)
|
||||
SIGNAL_HANDLER
|
||||
if(isnull(WF))
|
||||
@@ -107,7 +106,6 @@
|
||||
if(isnull(AM))
|
||||
log_debug("DEBUG: HasProximity called without reference on [src].")
|
||||
return
|
||||
// CHOMPEdit End
|
||||
if(disable || !anchored || (last_flash && world.time < last_flash + 150))
|
||||
return
|
||||
|
||||
|
||||
@@ -71,8 +71,6 @@ when portals are shortly lived, or when portals are made to be obvious with spec
|
||||
|
||||
// Called when something touches the portal, and usually teleports them to the other side.
|
||||
/obj/effect/map_effect/portal/Crossed(atom/movable/AM)
|
||||
/*if(AM.is_incorporeal())
|
||||
return CHOMPEdit: This is why phased critters couldn't enter z transits */
|
||||
..()
|
||||
if(!AM)
|
||||
return
|
||||
|
||||
@@ -11,7 +11,7 @@ GLOBAL_LIST_BOILERPLATE(all_portals, /obj/effect/portal)
|
||||
var/obj/item/target = null
|
||||
var/creator = null
|
||||
anchored = TRUE
|
||||
var/event = FALSE // CHOMPAdd
|
||||
var/event = FALSE
|
||||
|
||||
/obj/effect/portal/Bumped(mob/M as mob|obj)
|
||||
if(ismob(M) && !(isliving(M)))
|
||||
@@ -22,14 +22,12 @@ GLOBAL_LIST_BOILERPLATE(all_portals, /obj/effect/portal)
|
||||
return
|
||||
|
||||
/obj/effect/portal/Crossed(atom/movable/AM as mob|obj)
|
||||
// CHOMPEdit Start - Dephase kins on crossed
|
||||
if(AM.is_incorporeal())
|
||||
if(event)
|
||||
if(iscarbon(AM))
|
||||
var/mob/living/carbon/human/H = AM
|
||||
H.attack_dephase()
|
||||
else return
|
||||
// CHOMPEdit End
|
||||
if(!event)
|
||||
return
|
||||
if(iscarbon(AM))
|
||||
var/mob/living/carbon/human/H = AM
|
||||
H.attack_dephase(null, src)
|
||||
if(ismob(AM) && !(isliving(AM)))
|
||||
return //do not send ghosts, zshadows, ai eyes, etc
|
||||
spawn(0)
|
||||
|
||||
@@ -367,7 +367,7 @@
|
||||
|
||||
/obj/item/throw_impact(atom/hit_atom)
|
||||
..()
|
||||
if(isliving(hit_atom)) //Living mobs handle hit sounds differently.
|
||||
if(isliving(hit_atom) && !hit_atom.is_incorporeal()) //Living mobs handle hit sounds differently.
|
||||
var/volume = get_volume_by_throwforce_and_or_w_class()
|
||||
if (throwforce > 0)
|
||||
if (mob_throw_hit_sound)
|
||||
|
||||
@@ -55,7 +55,6 @@
|
||||
SStgui.update_uis(src) // update all UIs attached to src
|
||||
return
|
||||
|
||||
// CHOMPEdit Start
|
||||
/obj/item/transfer_valve/HasProximity(turf/T, datum/weakref/WF, old_loc)
|
||||
SIGNAL_HANDLER
|
||||
if(isnull(WF))
|
||||
@@ -64,14 +63,13 @@
|
||||
if(isnull(AM))
|
||||
log_debug("DEBUG: HasProximity called without reference on [src].")
|
||||
attached_device?.HasProximity(T, WEAKREF(AM), old_loc)
|
||||
// CHOMPEdit End
|
||||
|
||||
/obj/item/transfer_valve/Moved(old_loc, direction, forced)
|
||||
. = ..()
|
||||
if(isturf(old_loc))
|
||||
unsense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity), center = old_loc) // CHOMPEdit
|
||||
unsense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity), center = old_loc)
|
||||
if(isturf(loc))
|
||||
sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity)) // CHOMPEdit
|
||||
sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity))
|
||||
|
||||
/obj/item/transfer_valve/attack_self(mob/user)
|
||||
tgui_interact(user)
|
||||
|
||||
@@ -661,7 +661,6 @@ var/list/global/tank_gauge_cache = list()
|
||||
tank.update_icon()
|
||||
tank.cut_overlay("bomb_assembly")
|
||||
|
||||
// CHOMPEdit Start
|
||||
/obj/item/tankassemblyproxy/HasProximity(turf/T, datum/weakref/WF, old_loc)
|
||||
SIGNAL_HANDLER
|
||||
if(isnull(WF))
|
||||
@@ -671,11 +670,11 @@ var/list/global/tank_gauge_cache = list()
|
||||
log_debug("DEBUG: HasProximity called without reference on [src].")
|
||||
return
|
||||
assembly?.HasProximity(T, WEAKREF(AM), old_loc)
|
||||
// CHOMPEdit End
|
||||
|
||||
/obj/item/tankassemblyproxy/Moved(old_loc, direction, forced)
|
||||
if(isturf(old_loc))
|
||||
unsense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity), center = old_loc) // CHOMPEdit
|
||||
unsense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity), center = old_loc)
|
||||
if(isturf(loc))
|
||||
sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity)) // CHOMPEdit
|
||||
sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity))
|
||||
|
||||
#undef TANK_IDEAL_PRESSURE
|
||||
|
||||
@@ -66,11 +66,10 @@
|
||||
/obj/item/assembly_holder/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(isturf(old_loc))
|
||||
unsense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity), center = old_loc) // CHOMPEdit
|
||||
unsense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity), center = old_loc)
|
||||
if(isturf(loc))
|
||||
sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity)) // CHOMPEdit
|
||||
sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity))
|
||||
|
||||
// CHOMPEdit Start
|
||||
/obj/item/assembly_holder/HasProximity(turf/T, datum/weakref/WF, old_loc)
|
||||
SIGNAL_HANDLER
|
||||
if(isnull(WF))
|
||||
@@ -79,7 +78,6 @@
|
||||
if(isnull(AM))
|
||||
log_debug("DEBUG: HasProximity called without reference on [src].")
|
||||
return
|
||||
// CHOMPEdit End
|
||||
if(a_left)
|
||||
a_left.HasProximity(T, AM, old_loc)
|
||||
if(a_right)
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
update_icon()
|
||||
return secured
|
||||
|
||||
// CHOMPEdit Start
|
||||
/obj/item/assembly/prox_sensor/HasProximity(turf/T, datum/weakref/WF, old_loc)
|
||||
SIGNAL_HANDLER
|
||||
if(isnull(WF))
|
||||
@@ -41,7 +40,6 @@
|
||||
if(isnull(AM))
|
||||
log_debug("DEBUG: HasProximity called without reference on [src].")
|
||||
return
|
||||
// CHOMPEdit End
|
||||
if (istype(AM, /obj/effect/beam))
|
||||
return
|
||||
if (!isobserver(AM) && AM.move_speed < 12)
|
||||
|
||||
@@ -577,7 +577,7 @@
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(istype(H) && (H.back != src && H.belt != src))
|
||||
fail_msg = span_warning("You must be wearing \the [src] to do this.")
|
||||
else if(user.incorporeal_move)
|
||||
else if(user.is_incorporeal())
|
||||
fail_msg = span_warning("You must be solid to do this.")
|
||||
if(sealing)
|
||||
fail_msg = span_warning("The hardsuit is in the process of adjusting seals and cannot be activated.")
|
||||
|
||||
@@ -785,7 +785,7 @@ GLOBAL_LIST_EMPTY(vending_products)
|
||||
if(!target)
|
||||
return 0
|
||||
|
||||
if(target.is_incorporeal()) // CHOMPADD - Don't shoot at things that aren't there.
|
||||
if(target.is_incorporeal()) // Don't shoot at things that aren't there.
|
||||
return 0
|
||||
|
||||
for(var/datum/stored_item/vending_product/R in shuffle(product_records))
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
/obj/effect/plant/Destroy()
|
||||
neighbors.Cut()
|
||||
if(seed.get_trait(TRAIT_SPREAD)==2)
|
||||
unsense_proximity(callback = /atom/proc/HasProximity, center = get_turf(src))
|
||||
unsense_proximity(callback = TYPE_PROC_REF(/atom, HasProximity), center = get_turf(src))
|
||||
SSplants.remove_plant(src)
|
||||
for(var/obj/effect/plant/neighbor in range(1,src))
|
||||
SSplants.add_plant(neighbor)
|
||||
@@ -112,7 +112,7 @@
|
||||
name = seed.display_name
|
||||
max_health = round(seed.get_trait(TRAIT_ENDURANCE)/2)
|
||||
if(seed.get_trait(TRAIT_SPREAD)==2)
|
||||
sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity)) // Grabby - CHOMPEdit
|
||||
sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity)) // Grabby
|
||||
max_growth = VINE_GROWTH_STAGES
|
||||
growth_threshold = max_health/VINE_GROWTH_STAGES
|
||||
icon = 'icons/obj/hydroponics_vines.dmi'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// CHOMPEdit Start
|
||||
/obj/effect/plant/HasProximity(turf/T, datum/weakref/WF, old_loc)
|
||||
SIGNAL_HANDLER
|
||||
if(isnull(WF))
|
||||
@@ -7,7 +6,6 @@
|
||||
if(isnull(AM))
|
||||
log_debug("DEBUG: HasProximity called without reference on [src].")
|
||||
return
|
||||
// CHOMPEdit End
|
||||
if(!is_mature() || seed.get_trait(TRAIT_SPREAD) != 2)
|
||||
return
|
||||
|
||||
@@ -15,7 +13,7 @@
|
||||
if(!istype(M))
|
||||
return
|
||||
|
||||
if(M.is_incorporeal()) // CHOMPEdit - Don't buckle phased entities.
|
||||
if(M.is_incorporeal()) // Don't buckle phased entities.
|
||||
return
|
||||
|
||||
if(!has_buckled_mobs() && !M.buckled && !M.anchored && (issmall(M) || prob(round(seed.get_trait(TRAIT_POTENCY)/3))))
|
||||
|
||||
@@ -532,7 +532,7 @@
|
||||
complexity = 8
|
||||
inputs = list()
|
||||
outputs = list(
|
||||
"speaker ref",//CHOMPADDITION: so we can target the speaker with an action
|
||||
"speaker ref",
|
||||
"speaker" = IC_PINTYPE_STRING,
|
||||
"message" = IC_PINTYPE_STRING
|
||||
)
|
||||
@@ -558,7 +558,7 @@
|
||||
// as a translation, when it is not.
|
||||
if(S.speaking && !istype(S.speaking, /datum/language/common))
|
||||
translated = TRUE
|
||||
set_pin_data(IC_OUTPUT , 1, WEAKREF(M))//CHOMPADDITION: so we can target the speaker with an action
|
||||
set_pin_data(IC_OUTPUT , 1, WEAKREF(M))
|
||||
set_pin_data(IC_OUTPUT, 2, M.GetVoice())
|
||||
set_pin_data(IC_OUTPUT, 3, msg)
|
||||
|
||||
@@ -578,7 +578,7 @@
|
||||
complexity = 12
|
||||
inputs = list()
|
||||
outputs = list(
|
||||
"speaker ref",//CHOMPADDITION: so we can target the speaker with an action
|
||||
"speaker ref",
|
||||
"speaker" = IC_PINTYPE_STRING,
|
||||
"message" = IC_PINTYPE_STRING
|
||||
)
|
||||
@@ -605,13 +605,12 @@
|
||||
/obj/item/integrated_circuit/input/microphone/sign/hear_talk(mob/M, list/message_pieces, verb)
|
||||
var/msg = multilingual_to_message(message_pieces)
|
||||
|
||||
var/translated = TRUE //CHOMPEDIT: There is no common signlanguage so its all translated, pin 1 is basically useless
|
||||
//CHOMPEDIT:making the signlanguage translator actually useful
|
||||
var/translated = TRUE
|
||||
if(M && msg)
|
||||
for(var/datum/multilingual_say_piece/S in message_pieces)
|
||||
if(!((S.speaking.flags & NONVERBAL) || (S.speaking.flags & SIGNLANG))||S.speaking.name == LANGUAGE_ECHOSONG) //Ignore verbal languages
|
||||
return
|
||||
set_pin_data(IC_OUTPUT , 1, WEAKREF(M))//CHOMPADDITION: so we can target the speaker with an action
|
||||
set_pin_data(IC_OUTPUT , 1, WEAKREF(M))
|
||||
set_pin_data(IC_OUTPUT, 2, M.GetVoice())
|
||||
set_pin_data(IC_OUTPUT, 3, msg)
|
||||
|
||||
@@ -622,11 +621,11 @@
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/microphone/sign/hear_signlang(text, verb, datum/language/speaking, mob/M as mob)
|
||||
var/translated = TRUE //CHOMPEDIT: There is no common signlanguage so its all translated, pin 1 is basically useless
|
||||
var/translated = TRUE
|
||||
if(M && text)
|
||||
if(speaking)
|
||||
if(!((speaking.flags & NONVERBAL) || (speaking.flags & SIGNLANG))||speaking.name == LANGUAGE_ECHOSONG) //CHOMPEDIT: ignore echo song too
|
||||
return //CHOMPEDIT: dont spam the chat with scrambled text
|
||||
if(!((speaking.flags & NONVERBAL) || (speaking.flags & SIGNLANG))||speaking.name == LANGUAGE_ECHOSONG)
|
||||
return
|
||||
set_pin_data(IC_OUTPUT, 1, M.GetVoice())
|
||||
set_pin_data(IC_OUTPUT, 2, text)
|
||||
|
||||
|
||||
@@ -304,8 +304,8 @@
|
||||
M.adjust_fire_stacks(-1)
|
||||
if(M.on_fire)
|
||||
src.IgniteMob()
|
||||
if(do_after(M, 0.5 SECONDS)) //.5 second delay. Makes it a bit stronger than just typing rest.
|
||||
M.resting = 0 //Hoist yourself up up off the ground. No para/stunned/weakened removal.
|
||||
M.resting = 0 //Hoist yourself up up off the ground. No para/stunned/weakened removal.
|
||||
update_canmove()
|
||||
else if(istype(hugger))
|
||||
hugger.species.hug(hugger,src)
|
||||
else
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/verb/give(var/mob/living/target in living_mobs_in_view(1)) // CHOMPEdit
|
||||
/mob/living/verb/give(var/mob/living/target in living_mobs_in_view(1))
|
||||
set category = "IC.Game"
|
||||
set name = "Give"
|
||||
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
/mob/living/carbon/human/attack_hand(mob/living/M as mob)
|
||||
var/datum/gender/TT = gender_datums[M.get_visible_gender()]
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
if(is_incorporeal())
|
||||
return
|
||||
|
||||
var/has_hands = TRUE
|
||||
if(istype(H))
|
||||
var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
|
||||
@@ -53,8 +57,6 @@
|
||||
if(D.IsSpreadByTouch())
|
||||
ContractDisease(D)
|
||||
|
||||
if(H.lying)
|
||||
return
|
||||
M.break_cloak()
|
||||
|
||||
..()
|
||||
|
||||
@@ -390,10 +390,8 @@ emp_act
|
||||
|
||||
//this proc handles being hit by a thrown atom
|
||||
/mob/living/carbon/human/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR)
|
||||
// CHOMPADD Start
|
||||
if(src.is_incorporeal())
|
||||
return
|
||||
// CHOMPAdd End
|
||||
// if(buckled && buckled == AM)
|
||||
// return // Don't get hit by the thing we're buckled to.
|
||||
|
||||
@@ -435,7 +433,7 @@ emp_act
|
||||
I.forceMove(vore_selected)
|
||||
return
|
||||
if(in_throw_mode && speed <= THROWFORCE_SPEED_DIVISOR) //empty active hand and we're in throw mode
|
||||
if(canmove && !restrained() && !src.is_incorporeal()) // CHOMPADD - No hands for the phased ones.
|
||||
if(canmove && !restrained() && !src.is_incorporeal())
|
||||
if(isturf(O.loc))
|
||||
if(can_catch(O))
|
||||
put_in_active_hand(O)
|
||||
|
||||
@@ -263,7 +263,7 @@
|
||||
to_chat(src, span_notice("You take a moment to listen in to your environment..."))
|
||||
for(var/mob/living/L in range(client.view, src))
|
||||
var/turf/T = get_turf(L)
|
||||
if(!T || L == src || L.stat == DEAD || is_below_sound_pressure(T) || L.is_incorporeal()) // CHOMPAdd - No bluespace ears.
|
||||
if(!T || L == src || L.stat == DEAD || is_below_sound_pressure(T) || L.is_incorporeal())
|
||||
continue
|
||||
heard_something = TRUE
|
||||
var/feedback = list()
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
breath_type = null
|
||||
poison_type = null
|
||||
water_breather = TRUE //They don't quite breathe
|
||||
var/doing_phase = FALSE // Prevent bugs when spamming phase button
|
||||
|
||||
vision_flags = SEE_SELF|SEE_MOBS
|
||||
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_SKIN_COLOR | HAS_EYE_COLOR | HAS_UNDERWEAR
|
||||
@@ -122,7 +123,6 @@
|
||||
var/energy_dark = 0.75
|
||||
var/nutrition_conversion_scaling = 0.5 //CHOMPEdit - Add nutrition <-> dark energy conversion
|
||||
var/phase_gentle = TRUE //CHOMPEdit - Add gentle phasing, defaults to on.
|
||||
var/doing_phase = FALSE //CHOMPEdit - Prevent bugs when spamming phase button
|
||||
var/manual_respite = FALSE //CHOMPEdit - Dark Respite
|
||||
var/respite_activating = FALSE //CHOMPEdit - Dark Respite
|
||||
var/nutrition_energy_conversion = TRUE //CHOMPEdit - Add toggle to nutrition and energy conversions
|
||||
|
||||
@@ -61,9 +61,6 @@
|
||||
if(!T)
|
||||
to_chat(src,span_warning("You can't use that here!"))
|
||||
return FALSE
|
||||
if((get_area(src).flags & PHASE_SHIELDED)) //CHOMPAdd - Mapping tools to control phasing
|
||||
to_chat(src,span_warning("This area is preventing you from phasing!"))
|
||||
return FALSE
|
||||
|
||||
if(ability_flags & AB_PHASE_SHIFTING)
|
||||
return FALSE
|
||||
@@ -72,61 +69,27 @@
|
||||
darkness = 1-brightness //Invert
|
||||
|
||||
var/watcher = 0
|
||||
//Chompedit start - Nerf to phasing
|
||||
for(var/thing in orange(7, src))
|
||||
if(istype(thing, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/watchers = thing
|
||||
if(watchers in oviewers(7,src) && watchers.species != SPECIES_SHADEKIN) // And they can see us... //CHOMPEDIT - (And aren't themselves a shadekin)
|
||||
if(!(watchers.stat) && !isbelly(watchers.loc) && !istype(watchers.loc, /obj/item/holder)) // And they are alive and not being held by someone...
|
||||
watcher++ // They are watching us!
|
||||
else if(istype(thing, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/watchers = thing
|
||||
if(watchers in oviewers(7,src))
|
||||
if(!watchers.stat && !isbelly(watchers.loc))
|
||||
watcher++ //The robot is watching us!
|
||||
else if(istype(thing, /obj/machinery/camera))
|
||||
var/obj/machinery/camera/watchers = thing
|
||||
if(watchers.can_use())
|
||||
if(src in watchers.can_see())
|
||||
watcher++ //The camera is watching us!
|
||||
//CHOMPedit end
|
||||
|
||||
for(var/mob/living/carbon/human/watchers in oview(7,src )) // If we can see them...
|
||||
if(watchers in oviewers(7,src)) // And they can see us...
|
||||
if(!(watchers.stat) && !isbelly(watchers.loc) && !istype(watchers.loc, /obj/item/holder)) // And they are alive and not being held by someone...
|
||||
watcher++ // They are watching us!
|
||||
|
||||
ability_cost = CLAMP(ability_cost/(0.01+darkness*2),50, 80)//This allows for 1 watcher in full light
|
||||
if(watcher>0)
|
||||
ability_cost = ability_cost + ( 15 * watcher )
|
||||
if(!(ability_flags & AB_PHASE_SHIFTED))
|
||||
log_debug("[src] attempted to shift with [watcher] observers with a cost of [ability_cost] in a darkness level of [darkness]")
|
||||
//CHOMPEdit start - inform about the observers affecting phasing
|
||||
if(darkness<=0.4 && watcher>=2)
|
||||
to_chat(src, span_warning("You have a few observers in a well-lit area! This may prevent phasing. (Working cameras count towards observers)"))
|
||||
else if(watcher>=3)
|
||||
to_chat(src, span_warning("You have a large number of observers! This may prevent phasing. (Working cameras count towards observers)"))
|
||||
//CHOMPEdit end
|
||||
|
||||
log_debug("[src] attempted to shift with [watcher] visible Carbons with a cost of [ability_cost] in a darkness level of [darkness]")
|
||||
|
||||
var/datum/species/shadekin/SK = species
|
||||
/* CHOMPEdit start - general shadekin ability check
|
||||
if(!istype(SK))
|
||||
to_chat(src, span_warning("Only a shadekin can use that!"))
|
||||
return FALSE
|
||||
else if(stat)
|
||||
to_chat(src, span_warning("Can't use that ability in your state!"))
|
||||
return FALSE
|
||||
//CHOMPEdit Start - Dark Respite
|
||||
else if((ability_flags & AB_DARK_RESPITE || has_modifier_of_type(/datum/modifier/dark_respite)) && !(ability_flags & AB_PHASE_SHIFTED))
|
||||
to_chat(src, span_warning("You can't use that so soon after an emergency warp!"))
|
||||
return FALSE
|
||||
*/
|
||||
if(!shadekin_ability_check())
|
||||
return FALSE
|
||||
//CHOMPEdit End
|
||||
//CHOMPEdit Start - Prevent bugs when spamming phase button
|
||||
else if(SK.doing_phase)
|
||||
to_chat(src, span_warning("You are already trying to phase!"))
|
||||
return FALSE
|
||||
//CHOMPEdit End
|
||||
|
||||
else if(shadekin_get_energy() < ability_cost && !(ability_flags & AB_PHASE_SHIFTED))
|
||||
to_chat(src, span_warning("Not enough energy for that ability!"))
|
||||
return FALSE
|
||||
@@ -139,13 +102,14 @@
|
||||
to_chat(src,span_warning("You can't use that here!"))
|
||||
return FALSE
|
||||
|
||||
SK.doing_phase = TRUE //CHOMPEdit - Prevent bugs when spamming phase button
|
||||
SK.doing_phase = TRUE // Prevent bugs when spamming phase button
|
||||
//Shifting in
|
||||
if(ability_flags & AB_PHASE_SHIFTED)
|
||||
phase_in(T)
|
||||
//Shifting out
|
||||
else
|
||||
phase_out(T)
|
||||
SK.doing_phase = FALSE // Prevent bugs when spamming phase button
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/phase_in(var/turf/T)
|
||||
@@ -166,7 +130,7 @@
|
||||
canmove = FALSE
|
||||
ability_flags &= ~AB_PHASE_SHIFTED
|
||||
ability_flags |= AB_PHASE_SHIFTING
|
||||
mouse_opacity = 1
|
||||
throwpass = FALSE
|
||||
name = get_visible_name()
|
||||
for(var/obj/belly/B as anything in vore_organs)
|
||||
B.escapable = initial(B.escapable)
|
||||
@@ -174,19 +138,15 @@
|
||||
//cut_overlays()
|
||||
invisibility = initial(invisibility)
|
||||
see_invisible = initial(see_invisible)
|
||||
see_invisible_default = initial(see_invisible_default) // CHOMPEdit - Allow seeing phased entities while phased.
|
||||
incorporeal_move = initial(incorporeal_move)
|
||||
density = initial(density)
|
||||
force_max_speed = initial(force_max_speed)
|
||||
//CHOMPEdit begin - resetting pull ability after phasing back in
|
||||
can_pull_size = initial(can_pull_size)
|
||||
can_pull_mobs = initial(can_pull_mobs)
|
||||
hovering = initial(hovering)
|
||||
//CHOMPEdit end
|
||||
update_icon()
|
||||
|
||||
//Cosmetics mostly
|
||||
var/obj/effect/temp_visual/shadekin/phase_in/phaseanim = new /obj/effect/temp_visual/shadekin/phase_in(src.loc)
|
||||
phaseanim.pixel_y = (src.size_multiplier - 1) * 16 // Pixel shift for the animation placement
|
||||
phaseanim.adjust_scale(src.size_multiplier, src.size_multiplier)
|
||||
phaseanim.dir = dir
|
||||
alpha = 0
|
||||
custom_emote(1,"phases in!")
|
||||
@@ -194,52 +154,30 @@
|
||||
canmove = original_canmove
|
||||
alpha = initial(alpha)
|
||||
remove_modifiers_of_type(/datum/modifier/shadekin_phase_vision)
|
||||
remove_modifiers_of_type(/datum/modifier/shadekin_phase) //CHOMPEdit - Shadekin probably shouldn't be hit while phasing
|
||||
|
||||
//Potential phase-in vore
|
||||
if(can_be_drop_pred || can_be_drop_prey) //Toggleable in vore panel
|
||||
if(can_be_drop_pred) //Toggleable in vore panel
|
||||
var/list/potentials = living_mobs(0)
|
||||
if(potentials.len)
|
||||
var/mob/living/target = pick(potentials)
|
||||
if(can_be_drop_pred && istype(target) && target.devourable && target.can_be_drop_prey && target.phase_vore && vore_selected && phase_vore)
|
||||
if(istype(target) && target.devourable && target.can_be_drop_prey && vore_selected)
|
||||
target.forceMove(vore_selected)
|
||||
to_chat(target, span_vwarning("\The [src] phases in around you, [vore_selected.vore_verb]ing you into their [vore_selected.name]!"))
|
||||
to_chat(src, span_vwarning("You phase around [target], [vore_selected.vore_verb]ing them into your [vore_selected.name]!"))
|
||||
else if(can_be_drop_prey && istype(target) && devourable && target.can_be_drop_pred && target.phase_vore && target.vore_selected && phase_vore)
|
||||
forceMove(target.vore_selected)
|
||||
to_chat(target, span_vwarning("\The [src] phases into you, [target.vore_selected.vore_verb]ing them into your [target.vore_selected.name]!"))
|
||||
to_chat(src, span_vwarning("You phase into [target], having them [target.vore_selected.vore_verb] you into their [target.vore_selected.name]!"))
|
||||
to_chat(target,span_vwarning("\The [src] phases in around you, [vore_selected.vore_verb]ing you into their [vore_selected.name]!"))
|
||||
|
||||
ability_flags &= ~AB_PHASE_SHIFTING
|
||||
|
||||
//Affect nearby lights
|
||||
var/destroy_lights = 0
|
||||
|
||||
//CHOMPEdit start - Add back light destruction
|
||||
if(SK.get_shadekin_eyecolor(src) == RED_EYES)
|
||||
destroy_lights = 80
|
||||
else if(SK.get_shadekin_eyecolor(src) == PURPLE_EYES)
|
||||
destroy_lights = 25
|
||||
//CHOMPEdit end
|
||||
for(var/obj/machinery/light/L in machines)
|
||||
if(L.z != z || get_dist(src,L) > 10)
|
||||
continue
|
||||
|
||||
//CHOMPEdit start - Add gentle phasing
|
||||
if(SK.phase_gentle) // gentle case: No light destruction. Flicker in 4 tile radius once.
|
||||
for(var/obj/machinery/light/L in machines)
|
||||
if(L.z != z || get_dist(src,L) > 4)
|
||||
continue
|
||||
L.flicker(1)
|
||||
src.Stun(1)
|
||||
else
|
||||
//CHOMPEdit end
|
||||
for(var/obj/machinery/light/L in machines)
|
||||
if(L.z != z || get_dist(src,L) > 10)
|
||||
continue
|
||||
|
||||
if(prob(destroy_lights))
|
||||
spawn(rand(5,25))
|
||||
L.broken()
|
||||
else
|
||||
L.flicker(10)
|
||||
if(prob(destroy_lights))
|
||||
spawn(rand(5,25))
|
||||
L.broken()
|
||||
else
|
||||
L.flicker(10)
|
||||
|
||||
/mob/living/carbon/human/proc/phase_out(var/turf/T)
|
||||
if(!(ability_flags & AB_PHASE_SHIFTED))
|
||||
@@ -258,35 +196,23 @@
|
||||
// change
|
||||
ability_flags |= AB_PHASE_SHIFTED
|
||||
ability_flags |= AB_PHASE_SHIFTING
|
||||
mouse_opacity = 0
|
||||
throwpass = TRUE
|
||||
custom_emote(1,"phases out!")
|
||||
name = get_visible_name()
|
||||
|
||||
//CHOMPEdit begin - Unequipping slots when phasing in, and preventing pulling stuff while phased.
|
||||
if(l_hand)
|
||||
unEquip(l_hand)
|
||||
if(r_hand)
|
||||
unEquip(r_hand)
|
||||
if(back)
|
||||
unEquip(back)
|
||||
|
||||
can_pull_size = 0
|
||||
can_pull_mobs = MOB_PULL_NONE
|
||||
hovering = TRUE
|
||||
//CHOMPEdit end
|
||||
|
||||
for(var/obj/belly/B as anything in vore_organs)
|
||||
B.escapable = FALSE
|
||||
|
||||
var/obj/effect/temp_visual/shadekin/phase_out/phaseanim = new /obj/effect/temp_visual/shadekin/phase_out(src.loc)
|
||||
phaseanim.pixel_y = (src.size_multiplier - 1) * 16 // Pixel shift for the animation placement
|
||||
phaseanim.adjust_scale(src.size_multiplier, src.size_multiplier)
|
||||
phaseanim.dir = dir
|
||||
alpha = 0
|
||||
add_modifier(/datum/modifier/shadekin_phase_vision)
|
||||
add_modifier(/datum/modifier/shadekin_phase) //CHOMPEdit - Shadekin probably shouldn't be hit while phasing
|
||||
sleep(5)
|
||||
invisibility = INVISIBILITY_SHADEKIN
|
||||
see_invisible = INVISIBILITY_SHADEKIN
|
||||
see_invisible_default = INVISIBILITY_SHADEKIN // CHOMPEdit - Allow seeing phased entities while phased.
|
||||
see_invisible_default = INVISIBILITY_SHADEKIN // Allow seeing phased entities while phased.
|
||||
//cut_overlays()
|
||||
update_icon()
|
||||
alpha = 127
|
||||
@@ -296,33 +222,8 @@
|
||||
density = FALSE
|
||||
force_max_speed = TRUE
|
||||
ability_flags &= ~AB_PHASE_SHIFTING
|
||||
SK.doing_phase = FALSE //CHOMPEdit - Prevent bugs when spamming phase button
|
||||
*/ //ChompEDIT END - moved to modular_chomp
|
||||
|
||||
//CHOMPEdit Start - Toggle to Nutrition conversion
|
||||
/mob/living/carbon/human/proc/nutrition_conversion_toggle()
|
||||
set name = "Toggle Energy <-> Nutrition conversions"
|
||||
set desc = "Toggle dark energy and nutrition being converted into each other when full"
|
||||
set category = "Abilities.Shadekin" //ChompEDIT - TGPanel
|
||||
|
||||
var/datum/species/shadekin/SK = species
|
||||
if(!istype(SK))
|
||||
to_chat(src, span_warning("Only a shadekin can use that!"))
|
||||
return FALSE
|
||||
|
||||
if(SK.nutrition_energy_conversion)
|
||||
to_chat(src, span_notice("Nutrition and dark energy conversions disabled."))
|
||||
SK.nutrition_energy_conversion = 0
|
||||
else
|
||||
to_chat(src, span_notice("Nutrition and dark energy conversions enabled."))
|
||||
SK.nutrition_energy_conversion = 1
|
||||
//CHOMPEdit End
|
||||
|
||||
//CHOMPEdit Start - Shadekin probably shouldn't be hit while phasing
|
||||
/datum/modifier/shadekin_phase
|
||||
name = "Shadekin Phasing"
|
||||
evasion = 100
|
||||
//CHOMPEdit End
|
||||
|
||||
/datum/modifier/shadekin_phase_vision
|
||||
name = "Shadekin Phase Vision"
|
||||
@@ -481,334 +382,23 @@
|
||||
holder.set_light(0)
|
||||
my_kin = null
|
||||
|
||||
|
||||
//CHOMPEdit Begin - Add dark portal creation
|
||||
/datum/power/shadekin/dark_tunneling
|
||||
name = "Dark Tunneling (100) (Once)"
|
||||
desc = "Make a passage to the dark."
|
||||
verbpath = /mob/living/carbon/human/proc/dark_tunneling
|
||||
ability_icon_state = "minion0"
|
||||
|
||||
/mob/living/carbon/human/proc/dark_tunneling()
|
||||
set name = "Dark Tunneling (100) (Once)"
|
||||
set desc = "Make a passage to the dark."
|
||||
set category = "Abilities.Shadekin" //ChompEDIT - TGPanel
|
||||
|
||||
var/template_id = "dark_portal"
|
||||
var/datum/map_template/shelter/template
|
||||
|
||||
var/ability_cost = 100
|
||||
|
||||
/* CHOMPEdit start - general shadekin ability check
|
||||
// force dephase proc, to be called by other procs to dephase the shadekin. T is the target to force dephase them to.
|
||||
/mob/living/carbon/human/proc/attack_dephase(var/turf/T = null, atom/dephaser)
|
||||
var/datum/species/shadekin/SK = species
|
||||
if(!istype(SK))
|
||||
to_chat(src, span_warning("Only a shadekin can use that!"))
|
||||
return FALSE
|
||||
else if(stat)
|
||||
to_chat(src, span_warning("Can't use that ability in your state!"))
|
||||
return FALSE
|
||||
//CHOMPEdit Start - Dark Respite
|
||||
else if((ability_flags & AB_DARK_RESPITE || has_modifier_of_type(/datum/modifier/dark_respite)) && !(ability_flags & AB_PHASE_SHIFTED))
|
||||
to_chat(src, span_warning("You can't use that so soon after an emergency warp!"))
|
||||
return FALSE
|
||||
*/
|
||||
if(!shadekin_ability_check())
|
||||
return FALSE
|
||||
//CHOMPEdit End
|
||||
else if(ability_flags & AB_PHASE_SHIFTED)
|
||||
to_chat(src, span_warning("You can't use that while phase shifted!"))
|
||||
return FALSE
|
||||
else if(ability_flags & AB_DARK_TUNNEL)
|
||||
to_chat(src, span_warning("You have already made a tunnel to the Dark!"))
|
||||
|
||||
// no assigned dephase-target, just use our own
|
||||
if(!T)
|
||||
T = get_turf(src)
|
||||
|
||||
// make sure it's possible to be dephased (and we're in phase)
|
||||
if(!istype(SK) || SK.doing_phase || !T.CanPass(src,T) || loc != T || !(ability_flags & AB_PHASE_SHIFTED) )
|
||||
return FALSE
|
||||
|
||||
if(!template)
|
||||
template = SSmapping.shelter_templates[template_id]
|
||||
if(!template)
|
||||
throw EXCEPTION("Shelter template ([template_id]) not found!")
|
||||
return FALSE
|
||||
|
||||
var/turf/deploy_location = get_turf(src)
|
||||
var/status = template.check_deploy(deploy_location)
|
||||
|
||||
switch(status)
|
||||
//Not allowed due to /area technical reasons
|
||||
if(SHELTER_DEPLOY_BAD_AREA)
|
||||
to_chat(src, span_warning("A tunnel to the Dark will not function in this area."))
|
||||
|
||||
//Anchored objects or no space
|
||||
if(SHELTER_DEPLOY_BAD_TURFS, SHELTER_DEPLOY_ANCHORED_OBJECTS)
|
||||
var/width = template.width
|
||||
var/height = template.height
|
||||
to_chat(src, span_warning("There is not enough open area for a tunnel to the Dark to form! You need to clear a [width]x[height] area!"))
|
||||
|
||||
if(status != SHELTER_DEPLOY_ALLOWED)
|
||||
return FALSE
|
||||
|
||||
var/turf/T = deploy_location
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
|
||||
smoke.attach(T)
|
||||
smoke.set_up(10, 0, T)
|
||||
smoke.start()
|
||||
|
||||
src.visible_message(span_notice("[src] begins pulling dark energies around themselves."))
|
||||
if(do_after(src, 600)) //60 seconds
|
||||
playsound(src, 'sound/effects/phasein.ogg', 100, 1)
|
||||
src.visible_message(span_notice("[src] finishes pulling dark energies around themselves, creating a portal."))
|
||||
|
||||
log_and_message_admins("[key_name_admin(src)] created a tunnel to the dark at [get_area(T)]!")
|
||||
template.annihilate_plants(deploy_location)
|
||||
template.load(deploy_location, centered = TRUE)
|
||||
template.update_lighting(deploy_location)
|
||||
ability_flags |= AB_DARK_TUNNEL
|
||||
shadekin_adjust_energy(-(ability_cost - 10)) //Leaving enough energy to actually activate the portal
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/datum/power/shadekin/dark_respite
|
||||
name = "Dark Respite (Only in Dark)"
|
||||
desc = "Focus yourself on healing any injuries sustained."
|
||||
verbpath = /mob/living/carbon/human/proc/dark_respite
|
||||
ability_icon_state = "ling_anatomic_panacea"
|
||||
|
||||
/mob/living/carbon/human/proc/dark_respite()
|
||||
set name = "Dark Respite (Only in Dark)"
|
||||
set desc = "Focus yourself on healing any injuries sustained."
|
||||
set category = "Abilities.Shadekin" //ChompEDIT - TGPanel
|
||||
|
||||
var/datum/species/shadekin/SK = species
|
||||
if(!istype(SK))
|
||||
to_chat(src, span_warning("Only a shadekin can use that!"))
|
||||
return FALSE
|
||||
else if(!istype(get_area(src), /area/shadekin))
|
||||
to_chat(src, span_warning("Can only trigger Dark Respite in the Dark!"))
|
||||
return FALSE
|
||||
else if(stat)
|
||||
to_chat(src, span_warning("Can't use that ability in your state!"))
|
||||
return FALSE
|
||||
else if(ability_flags & AB_DARK_RESPITE)
|
||||
to_chat(src, span_warning("You can't use that so soon after an emergency warp!"))
|
||||
return FALSE
|
||||
else if(has_modifier_of_type(/datum/modifier/dark_respite) && !SK.manual_respite)
|
||||
to_chat(src, span_warning("You cannot manually end a Dark Respite triggered by an emergency warp!"))
|
||||
else if(ability_flags & AB_PHASE_SHIFTED)
|
||||
to_chat(src, span_warning("You can't use that while phase shifted!"))
|
||||
return FALSE
|
||||
|
||||
if(has_modifier_of_type(/datum/modifier/dark_respite))
|
||||
to_chat(src, span_notice("You stop focusing the Dark on healing yourself."))
|
||||
SK.manual_respite = FALSE
|
||||
remove_a_modifier_of_type(/datum/modifier/dark_respite)
|
||||
return TRUE
|
||||
to_chat(src, span_notice("You start focusing the Dark on healing yourself. (Leave the dark or trigger the ability again to end this.)"))
|
||||
SK.manual_respite = TRUE
|
||||
add_modifier(/datum/modifier/dark_respite)
|
||||
return TRUE
|
||||
|
||||
/datum/map_template/shelter/dark_portal
|
||||
name = "Dark Portal"
|
||||
shelter_id = "dark_portal"
|
||||
description = "A portal to a section of the Dark"
|
||||
mappath = "modular_chomp/maps/submaps/shelters/dark_portal.dmm"
|
||||
|
||||
/datum/map_template/shelter/dark_portal/New()
|
||||
. = ..()
|
||||
blacklisted_turfs = typecacheof(list(/turf/unsimulated))
|
||||
blacklisted_areas = typecacheof(list(/area/centcom, /area/shadekin))
|
||||
|
||||
/obj/effect/abstract/dark_maw
|
||||
var/mob/living/owner = null
|
||||
var/obj/belly/target = null
|
||||
icon = 'modular_chomp/icons/obj/Shadekin_powers_2.dmi'
|
||||
icon_state = "dark_maw_waiting"
|
||||
|
||||
/obj/effect/abstract/dark_maw/New(loc, var/mob/living/user, var/trigger_now = 0)
|
||||
. = ..()
|
||||
if(istype(user))
|
||||
owner = user
|
||||
target = owner.vore_selected
|
||||
|
||||
if(!isturf(loc))
|
||||
return INITIALIZE_HINT_QDEL
|
||||
var/turf/T = loc
|
||||
if(T.get_lumcount() >= 0.5)
|
||||
visible_message(span_notice("A set of shadowy lines flickers away in the light."))
|
||||
icon_state = "dark_maw_used"
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
var/mob/living/target_user = null
|
||||
for(var/mob/living/L in T)
|
||||
if(L != owner && !L.incorporeal_move)
|
||||
target_user = L
|
||||
break
|
||||
if(istype(target_user))
|
||||
triggered_by(target_user, 1)
|
||||
// to trigger rebuild
|
||||
else if(trigger_now)
|
||||
icon_state = "dark_maw_used"
|
||||
flick("dark_maw_tr", src)
|
||||
visible_message(span_warning("A set of crystals suddenly springs from the ground and shadowy tendrils wrap around nothing before vanishing."))
|
||||
spawn(30)
|
||||
qdel(src)
|
||||
else
|
||||
var/mob/living/carbon/human/carbon_owner = owner
|
||||
var/mob/living/simple_mob/shadekin/sm_owner = owner
|
||||
if(istype(carbon_owner))
|
||||
var/datum/species/shadekin/SK = carbon_owner.species
|
||||
if(istype(SK))
|
||||
SK.active_dark_maws += src
|
||||
else if(istype(sm_owner))
|
||||
sm_owner.active_dark_maws += src
|
||||
flick("dark_maw", src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/effect/abstract/dark_maw/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
if(istype(owner))
|
||||
var/mob/living/carbon/human/carbon_owner = owner
|
||||
var/mob/living/simple_mob/shadekin/sm_owner = owner
|
||||
if(istype(carbon_owner))
|
||||
var/datum/species/shadekin/SK = carbon_owner.species
|
||||
if(istype(SK))
|
||||
SK.active_dark_maws -= src
|
||||
else if(istype(sm_owner))
|
||||
sm_owner.active_dark_maws -= src
|
||||
return ..()
|
||||
|
||||
/obj/effect/abstract/dark_maw/Crossed(O)
|
||||
. = ..()
|
||||
if(!isliving(O))
|
||||
return
|
||||
if(icon_state != "dark_maw_waiting")
|
||||
return
|
||||
var/mob/living/L = O
|
||||
if(!L.incorporeal_move && (!owner || L != owner))
|
||||
triggered_by(L)
|
||||
|
||||
/obj/effect/abstract/dark_maw/process()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T) || T.get_lumcount() >= 0.5)
|
||||
dispel()
|
||||
|
||||
/obj/effect/abstract/dark_maw/proc/dispel()
|
||||
if(icon_state == "dark_maw_waiting")
|
||||
visible_message(span_notice("A set of shadowy lines flickers away in the light."))
|
||||
else
|
||||
visible_message(span_notice("The crystals and shadowy tendrils dissipate with the light shone on it."))
|
||||
icon_state = "dark_maw_used"
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/abstract/dark_maw/proc/triggered_by(var/mob/living/L, var/triggered_instantly = 0)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
icon_state = "dark_maw_used"
|
||||
flick("dark_maw_tr", src)
|
||||
L.AdjustStunned(4)
|
||||
visible_message(span_warning("A set of crystals spring out of the ground and shadowy tendrils start wrapping around [L]."))
|
||||
if(owner && !triggered_instantly)
|
||||
to_chat(owner, span_warning("A dark maw you deployed has triggered!"))
|
||||
spawn(10)
|
||||
var/will_vore = 1
|
||||
|
||||
if(!owner || !(target in owner) || !L.devourable || !L.can_be_drop_prey || !owner.can_be_drop_pred || !L.phase_vore)
|
||||
will_vore = 0
|
||||
|
||||
if(!src || src.gc_destroyed)
|
||||
//We got deleted probably, do nothing more
|
||||
return
|
||||
|
||||
if(L.loc != get_turf(src))
|
||||
visible_message(span_notice("The shadowy tendrils fail to catch anything and dissipate."))
|
||||
qdel(src)
|
||||
else if(will_vore)
|
||||
visible_message(span_warning("The shadowy tendrils grab around [L] and drag them into the floor, leaving nothing behind."))
|
||||
L.forceMove(target)
|
||||
qdel(src)
|
||||
else
|
||||
var/obj/effect/energy_net/dark/net = new /obj/effect/energy_net/dark(get_turf(src))
|
||||
if(net.buckle_mob(L))
|
||||
visible_message(span_warning("The shadowy tendrils wrap around [L] and traps them in a net of dark energy."))
|
||||
else
|
||||
visible_message(span_notice("The shadowy tendrils wrap around [L] and then dissipate, leaving them in place."))
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/energy_net/dark
|
||||
name = "dark net"
|
||||
desc = "It's a net made of dark energy."
|
||||
icon = 'modular_chomp/icons/obj/Shadekin_powers_2.dmi'
|
||||
icon_state = "dark_net"
|
||||
|
||||
escape_time = 30 SECONDS
|
||||
|
||||
/obj/effect/energy_net/dark/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
|
||||
if(istype(user,/mob/living/simple_mob/shadekin))
|
||||
visible_message(span_danger("[user] dissipates \the [src] with a touch!"))
|
||||
unbuckle_mob(buckled_mob)
|
||||
return
|
||||
else if(istype(user,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/datum/species/shadekin/SK = H.species
|
||||
if(istype(SK))
|
||||
visible_message(span_danger("[user] dissipates \the [src] with a touch!"))
|
||||
unbuckle_mob(buckled_mob)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/effect/energy_net/dark/process()
|
||||
. = ..()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T) || T.get_lumcount() >= 0.6)
|
||||
visible_message(span_notice("The tangle of dark tendrils fades away in the light."))
|
||||
qdel(src)
|
||||
|
||||
/datum/power/shadekin/dark_maw
|
||||
name = "Dark Maw (20)"
|
||||
desc = "Create a trap to capture others, or steal people from phase"
|
||||
verbpath = /mob/living/carbon/human/proc/dark_maw
|
||||
ability_icon_state = "dark_maw_ic"
|
||||
|
||||
/mob/living/carbon/human/proc/dark_maw()
|
||||
set name = "Dark Maw (20)"
|
||||
set desc = "Create a trap to capture others, or steal people from phase"
|
||||
set category = "Abilities.Shadekin" //ChompEDIT - TGPanel
|
||||
|
||||
var/ability_cost = 20
|
||||
|
||||
if(!shadekin_ability_check())
|
||||
return FALSE
|
||||
else if(shadekin_get_energy() < ability_cost)
|
||||
to_chat(src, span_warning("Not enough energy for that ability!"))
|
||||
return FALSE
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
to_chat(src, span_warning("You don't seem to be able to set a trap here!"))
|
||||
return FALSE
|
||||
else if(T.get_lumcount() >= 0.5)
|
||||
to_chat(src, span_warning("There is too much light here for your trap to last!"))
|
||||
return FALSE
|
||||
|
||||
if(do_after(src, 10))
|
||||
if(ability_flags & AB_PHASE_SHIFTED)
|
||||
new /obj/effect/abstract/dark_maw(loc, src, 1)
|
||||
else
|
||||
new /obj/effect/abstract/dark_maw(loc, src)
|
||||
shadekin_adjust_energy(-ability_cost)
|
||||
|
||||
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/proc/clear_dark_maws()
|
||||
set name = "Dispel dark maws"
|
||||
set desc = "Dispel any active dark maws in place"
|
||||
set category = "Abilities.Shadekin" //ChompEDIT - TGPanel
|
||||
|
||||
var/datum/species/shadekin/SK = species
|
||||
if(!istype(SK))
|
||||
to_chat(src, span_warning("Only a shadekin can use that!"))
|
||||
return FALSE
|
||||
|
||||
for(var/obj/effect/abstract/dark_maw/dm in SK.active_dark_maws)
|
||||
dm.dispel()
|
||||
log_admin("[key_name_admin(src)] was stunned out of phase at [T.x],[T.y],[T.z] by [dephaser.name], last touched by [dephaser.fingerprintslast].")
|
||||
message_admins("[key_name_admin(src)] was stunned out of phase at [T.x],[T.y],[T.z] by [dephaser.name], last touched by [dephaser.fingerprintslast]. (<A href='byond://?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)", 1)
|
||||
// start the dephase
|
||||
phase_in(T)
|
||||
shadekin_adjust_energy(-20) // loss of energy for the interception
|
||||
// apply a little extra stun for good measure
|
||||
src.Weaken(3)
|
||||
|
||||
@@ -1266,7 +1266,7 @@
|
||||
set category = "Abilities.Vore"
|
||||
set desc = "Grab a target with any of your appendages!"
|
||||
|
||||
if(stat || paralysis || weakened || stunned || world.time < last_special || is_incorporeal()) //No tongue flicking while stunned. // CHOMPEdit
|
||||
if(stat || paralysis || weakened || stunned || world.time < last_special || is_incorporeal()) //No tongue flicking while stunned.
|
||||
to_chat(src, span_warning("You can't do that in your current state."))
|
||||
return
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@
|
||||
// This handles the drag-open inventory panel.
|
||||
/mob/living/MouseDrop(atom/over_object)
|
||||
var/mob/living/L = over_object
|
||||
if(istype(L) && L != src && L == usr && Adjacent(L) && !L.is_incorporeal()) // CHOMPEdit
|
||||
if(istype(L) && L != src && L == usr && Adjacent(L) && !L.is_incorporeal())
|
||||
show_inventory_panel(L)
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -263,10 +263,8 @@
|
||||
|
||||
//this proc handles being hit by a thrown atom
|
||||
/mob/living/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR)//Standardization and logging -Sieve
|
||||
// CHOMPAdd Start
|
||||
if(is_incorporeal())
|
||||
return
|
||||
// CHOMPAdd End
|
||||
if(istype(AM,/obj/))
|
||||
var/obj/O = AM
|
||||
if(stat != DEAD && istype(O,/obj/item) && trash_catching && vore_selected) //ported from chompstation
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
if(istype(mover, /obj/item/projectile))
|
||||
var/obj/item/projectile/P = mover
|
||||
return !P.can_hit_target(src, P.permutated, src == P.original, TRUE)
|
||||
return (!mover.density || !density || lying || is_incorporeal()) // CHOMPEdit
|
||||
return (!mover.density || !density || lying || is_incorporeal())
|
||||
|
||||
/mob/CanZASPass(turf/T, is_zone)
|
||||
return ATMOS_PASS_YES
|
||||
|
||||
@@ -1337,7 +1337,7 @@
|
||||
|
||||
update_icon()
|
||||
|
||||
/mob/living/silicon/robot/verb/robot_nom(var/mob/living/T in living_mobs_in_view(1)) //CHOMPEdit
|
||||
/mob/living/silicon/robot/verb/robot_nom(var/mob/living/T in living_mobs_in_view(1))
|
||||
set name = "Robot Nom"
|
||||
set category = "Abilities.Vore"
|
||||
set desc = "Allows you to eat someone."
|
||||
|
||||
@@ -108,12 +108,10 @@
|
||||
if(src == M) //Don't eat YOURSELF dork
|
||||
//ai_log("vr/won't eat [M] because it's me!", 3) //VORESTATION AI TEMPORARY REMOVAL
|
||||
return 0
|
||||
//CHOMPSTATION add
|
||||
if(!M.devourable) //Why was there never a check for edibility to begin with
|
||||
if(!M.devourable) // Why was there never a check for edibility to begin with
|
||||
return 0
|
||||
if(M.is_incorporeal()) // CHOMPADD - No eating the phased ones
|
||||
if(M.is_incorporeal()) // No eating the phased ones
|
||||
return 0
|
||||
//CHOMPSTATION add end
|
||||
if(vore_ignores_undigestable && !M.digestable) //Don't eat people with nogurgle prefs
|
||||
//ai_log("vr/wont eat [M] because I am picky", 3) //VORESTATION AI TEMPORARY REMOVAL
|
||||
return 0
|
||||
@@ -157,10 +155,8 @@
|
||||
/mob/living/simple_mob/proc/CanPounceTarget(var/mob/living/M) //returns either FALSE or a %chance of success
|
||||
if(!M.canmove || issilicon(M) || world.time < vore_pounce_cooldown) //eliminate situations where pouncing CANNOT happen
|
||||
return FALSE
|
||||
// CHOMPADD Start - No pouncing on the shades
|
||||
if(M.is_incorporeal())
|
||||
return FALSE
|
||||
// CHOMPADD End
|
||||
if(!prob(vore_pounce_chance) || !will_eat(M)) //mob doesn't want to pounce
|
||||
return FALSE
|
||||
if(vore_standing_too) //100% chance of hitting people we can eat on the spot
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
if(ismob(AM))
|
||||
if(isliving(AM))
|
||||
var/mob/living/A = AM
|
||||
if(A.is_incorporeal()) // CHOMPADD - Bad kin, no squishing the roach
|
||||
if(A.is_incorporeal()) // Bad kin, no squishing the roach
|
||||
return
|
||||
if(A.mob_size > MOB_SMALL)
|
||||
if(prob(squish_chance))
|
||||
|
||||
@@ -16,12 +16,18 @@
|
||||
return FALSE
|
||||
//RS Port #658 End
|
||||
|
||||
else if(doing_phase)
|
||||
to_chat(src, span_warning("You are already trying to phase!"))
|
||||
return FALSE
|
||||
|
||||
doing_phase = TRUE
|
||||
//Shifting in
|
||||
if(ability_flags & AB_PHASE_SHIFTED)
|
||||
phase_in(T)
|
||||
//Shifting out
|
||||
else
|
||||
phase_out(T)
|
||||
doing_phase = FALSE
|
||||
|
||||
/mob/living/simple_mob/shadekin/proc/phase_in(var/turf/T)
|
||||
if(ability_flags & AB_PHASE_SHIFTED)
|
||||
@@ -40,8 +46,7 @@
|
||||
|
||||
// change
|
||||
ability_flags &= ~AB_PHASE_SHIFTED
|
||||
throwpass = FALSE // CHOMPAdd
|
||||
mouse_opacity = 1
|
||||
throwpass = FALSE
|
||||
name = real_name
|
||||
for(var/obj/belly/B as anything in vore_organs)
|
||||
B.escapable = initial(B.escapable)
|
||||
@@ -109,8 +114,7 @@
|
||||
|
||||
// change
|
||||
ability_flags |= AB_PHASE_SHIFTED
|
||||
throwpass = TRUE // CHOMPAdd
|
||||
mouse_opacity = 0
|
||||
throwpass = TRUE
|
||||
custom_emote(1,"phases out!")
|
||||
real_name = name
|
||||
name = "Something"
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
var/list/shadekin_abilities
|
||||
var/check_for_observer = FALSE
|
||||
var/check_timer = 0
|
||||
var/doing_phase = FALSE // Prevent bugs when spamming phase button
|
||||
|
||||
var/respite_activating = FALSE //CHOMPEdit - Dark Respite
|
||||
var/list/active_dark_maws = list()
|
||||
|
||||
@@ -1304,3 +1304,8 @@ GLOBAL_LIST_EMPTY_TYPED(living_players_by_zlevel, /list)
|
||||
/mob/proc/grab_ghost(force)
|
||||
if(mind)
|
||||
return mind.grab_ghost(force = force)
|
||||
|
||||
/mob/is_incorporeal()
|
||||
if(incorporeal_move)
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
@@ -696,6 +696,22 @@ var/global/image/backplane
|
||||
/mob/proc/can_feed()
|
||||
return TRUE
|
||||
|
||||
|
||||
/atom/proc/living_mobs_in_view(var/range = world.view, var/count_held = FALSE)
|
||||
var/list/viewers = oviewers(src, range)
|
||||
if(count_held)
|
||||
viewers = viewers(src,range)
|
||||
var/list/living = list()
|
||||
for(var/mob/living/L in viewers)
|
||||
if(L.is_incorporeal())
|
||||
continue
|
||||
living += L
|
||||
if(count_held)
|
||||
for(var/obj/item/holder/H in L.contents)
|
||||
if(istype(H.held_mob, /mob/living))
|
||||
living += H.held_mob
|
||||
return living
|
||||
|
||||
/proc/censor_swears(t)
|
||||
/* Bleeps our swearing */
|
||||
var/static/swear_censoring_list = list("fuck",
|
||||
|
||||
@@ -153,12 +153,22 @@
|
||||
Move_object(direct)
|
||||
|
||||
// Ghosty mob movement
|
||||
if(my_mob.incorporeal_move && isobserver(my_mob))
|
||||
Process_Incorpmove(direct)
|
||||
DEBUG_INPUT("--------")
|
||||
next_move_dir_add = 0 // This one I *think* exists so you can tap move and it will move even if delay isn't quite up.
|
||||
next_move_dir_sub = 0 // I'm not really sure why next_move_dir_sub even exists.
|
||||
return
|
||||
if(my_mob.is_incorporeal())
|
||||
if(isobserver(my_mob)) //We're an observer! Don't worry about any more checks. Be free!
|
||||
Process_Incorpmove(direct)
|
||||
DEBUG_INPUT("--------")
|
||||
next_move_dir_add = 0 // This one I *think* exists so you can tap move and it will move even if delay isn't quite up.
|
||||
next_move_dir_sub = 0 // I'm not really sure why next_move_dir_sub even exists.
|
||||
return
|
||||
else //We are anything BUT an observer.
|
||||
if(!my_mob.canmove)//If you want to be very restrictive, add my_mob.restrained() and it'll stop people cuffed/straight jacketed. For now, that's too restrictive for a bugfix PR.
|
||||
return
|
||||
else //Proceed like normal.
|
||||
Process_Incorpmove(direct)
|
||||
DEBUG_INPUT("--------")
|
||||
next_move_dir_add = 0
|
||||
next_move_dir_sub = 0
|
||||
return
|
||||
|
||||
// We're in the middle of another move we've already decided to do
|
||||
if(moving)
|
||||
@@ -191,7 +201,7 @@
|
||||
|
||||
if(isliving(my_mob))
|
||||
var/mob/living/L = my_mob
|
||||
if(L.incorporeal_move)//Move though walls
|
||||
if(L.is_incorporeal())//Move though walls
|
||||
Process_Incorpmove(direct)
|
||||
return
|
||||
/* TODO observer unzoom
|
||||
|
||||
@@ -32,10 +32,8 @@
|
||||
return 0
|
||||
|
||||
var/mob/living/pred = hit_atom
|
||||
// CHOMPAdd Start
|
||||
if(pred.is_incorporeal())
|
||||
return
|
||||
// CHOMPAdd End
|
||||
var/safe_fall = FALSE
|
||||
if(pred.softfall || (isanimal(pred) && pred.mob_size <= MOB_SMALL)) // TODO: add ability for mob below to be 'soft' and cushion fall
|
||||
safe_fall = TRUE
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
/obj/machinery/containment_field/Initialize()
|
||||
. = ..()
|
||||
shockdirs = list(turn(dir,90),turn(dir,-90))
|
||||
sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity)) // CHOMPEdit
|
||||
sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity))
|
||||
|
||||
/obj/machinery/containment_field/set_dir(new_dir)
|
||||
. = ..()
|
||||
@@ -48,11 +48,10 @@
|
||||
return 0
|
||||
|
||||
/obj/machinery/containment_field/Crossed(mob/living/L)
|
||||
if(!istype(L) || L.incorporeal_move)
|
||||
if(!istype(L) || L.is_incorporeal())
|
||||
return
|
||||
shock(L)
|
||||
|
||||
// CHOMPEdit Start
|
||||
/obj/machinery/containment_field/HasProximity(turf/T, datum/weakref/WF, old_loc)
|
||||
SIGNAL_HANDLER
|
||||
if(isnull(WF))
|
||||
@@ -61,8 +60,7 @@
|
||||
if(isnull(AM))
|
||||
log_debug("DEBUG: HasProximity called without reference on [src].")
|
||||
return
|
||||
// CHOMPEdit End
|
||||
if(!isliving(AM) || AM:incorporeal_move)
|
||||
if(!isliving(AM) || AM.is_incorporeal())
|
||||
return 0
|
||||
if(!(get_dir(src,AM) in shockdirs))
|
||||
return 0
|
||||
|
||||
@@ -433,7 +433,7 @@
|
||||
env.merge(removed)
|
||||
|
||||
for(var/mob/living/carbon/human/l in view(src, min(7, round(sqrt(power/6))))) // If they can see it without mesons on. Bad on them.
|
||||
if(!istype(l.glasses, /obj/item/clothing/glasses/meson) || l.is_incorporeal()) // VOREStation Edit - Only mesons can protect you! - CHOMPEdit - OR if they're not in the same plane of existence
|
||||
if(!istype(l.glasses, /obj/item/clothing/glasses/meson) || l.is_incorporeal()) // VOREStation Edit - Only mesons can protect you! OR if they're not in the same plane of existence
|
||||
l.hallucination = max(0, min(200, l.hallucination + power * config_hallucination_power * sqrt( 1 / max(1,get_dist(l, src)) ) ) )
|
||||
|
||||
SSradiation.radiate(src, max(power * 1.5, 50) ) //Better close those shutters!
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
|
||||
|
||||
/obj/singularity/energy_ball/proc/dust_mob(mob/living/L)
|
||||
if(!istype(L) || L.incorporeal_move)
|
||||
if(!istype(L) || L.is_incorporeal())
|
||||
return
|
||||
// L.dust() - Changing to do fatal elecrocution instead
|
||||
L.electrocute_act(500, src, def_zone = BP_TORSO)
|
||||
|
||||
@@ -687,6 +687,9 @@
|
||||
if(!istype(target_mob))
|
||||
return
|
||||
|
||||
if(target_mob.is_incorporeal())
|
||||
return
|
||||
|
||||
if(target_mob in impacted_mobs)
|
||||
return
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
user.face_atom(A)
|
||||
if(ismob(A) && user.aiming)
|
||||
user.aiming.aim_at(A, src)
|
||||
if(!isliving(A) || A.is_incorporeal()) // CHOMPEdit - Phase out can't be targetted when phased
|
||||
if(!isliving(A) || A.is_incorporeal()) // Phase out can't be targetted when phased
|
||||
return 0
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
return 1
|
||||
|
||||
/obj/structure/table/MouseDrop_T(obj/O, mob/user, src_location, over_location, src_control, over_control, params)
|
||||
if(user.is_incorporeal())
|
||||
return
|
||||
if(ismob(O.loc)) //If placing an item
|
||||
if(!isitem(O) || user.get_active_hand() != O)
|
||||
return ..()
|
||||
|
||||
@@ -516,7 +516,7 @@
|
||||
//
|
||||
// Clearly super important. Obviously.
|
||||
//
|
||||
/mob/living/proc/lick(mob/living/tasted in living_mobs_in_view(1, TRUE)) //CHOMPEdit
|
||||
/mob/living/proc/lick(mob/living/tasted in living_mobs_in_view(1, TRUE))
|
||||
set name = "Lick"
|
||||
set category = "IC.Game"
|
||||
set desc = "Lick someone nearby!"
|
||||
@@ -946,10 +946,8 @@
|
||||
//CHOMPEdit End
|
||||
|
||||
/mob/living/proc/feed_grabbed_to_self_falling_nom(var/mob/living/user, var/mob/living/prey)
|
||||
// CHOMPAdd Start
|
||||
if(user.is_incorporeal())
|
||||
return FALSE
|
||||
// CHOMPAdd End
|
||||
var/belly = user.vore_selected
|
||||
return perform_the_nom(user, prey, user, belly, delay = 1) //1/10th of a second is probably fine.
|
||||
|
||||
|
||||
@@ -8,10 +8,8 @@
|
||||
/mob/living/proc/can_slip_vore(var/mob/living/target)
|
||||
if(!target.is_slipping) //Obviously they have to be slipping to get slip vored
|
||||
return FALSE
|
||||
// CHOMPAdd Start
|
||||
if(is_incorporeal())
|
||||
return FALSE
|
||||
// CHOMPAdd End
|
||||
if(world.time <= target.slip_protect)
|
||||
return FALSE
|
||||
if(!(src.can_be_drop_pred && target.devourable && target.can_be_drop_prey)) //Make sure both of their prefs align with what we're gonna do.
|
||||
@@ -27,10 +25,8 @@
|
||||
/mob/living/proc/can_be_slip_vored_by(var/mob/living/target)
|
||||
if(!target.is_slipping) //Obviously they have to be slipping to get slip vored
|
||||
return FALSE
|
||||
// CHOMPAdd Start
|
||||
if(is_incorporeal())
|
||||
return FALSE
|
||||
// CHOMPAdd End
|
||||
if(world.time <= target.slip_protect)
|
||||
return FALSE
|
||||
if(!(target.can_be_drop_pred && src.devourable && src.can_be_drop_prey)) //Make sure both of their prefs align with what we're gonna do.
|
||||
@@ -46,7 +42,7 @@
|
||||
/mob/living/Crossed(var/atom/movable/AM)
|
||||
..()
|
||||
var/mob/living/target = AM
|
||||
if(istype(target) && !target.incorporeal_move && !src.incorporeal_move) //The slip vore begins
|
||||
if(istype(target) && !target.is_incorporeal() && !src.is_incorporeal()) //The slip vore begins
|
||||
if(can_slip_vore(target) && !src.slip_vore_in_progress && !target.slip_vore_in_progress) //If we can vore them go for it
|
||||
perform_the_nom(src,target,src,src.vore_selected,1)
|
||||
target.slip_vore_in_progress = FALSE
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/mob/living/proc/CanStumbleVore(mob/living/target)
|
||||
if(!can_be_drop_pred)
|
||||
return FALSE
|
||||
// CHOMPAdd Start
|
||||
if(is_incorporeal() || target.is_incorporeal())
|
||||
return FALSE
|
||||
// CHOMPAdd End
|
||||
if(!is_vore_predator(src))
|
||||
return FALSE
|
||||
if(!target.devourable)
|
||||
@@ -18,12 +16,10 @@
|
||||
/mob/living/Bump(atom/movable/AM)
|
||||
//. = ..()
|
||||
if(isliving(AM))
|
||||
// CHOMPEdit Start
|
||||
var/mob/living/L = AM
|
||||
if(!L.is_incorporeal())
|
||||
if(buckled != AM && (((confused || is_blind()) && stat == CONSCIOUS && prob(50) && m_intent==I_RUN) || flying && flight_vore))
|
||||
AM.stumble_into(src)
|
||||
// CHOMPEdit End
|
||||
return ..()
|
||||
// Because flips toggle density
|
||||
/mob/living/Crossed(var/atom/movable/AM)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
set desc = "Allows you to eat people who are below your tile or adjacent one. Requires passability."
|
||||
set category = "Abilities.Vore"
|
||||
|
||||
if(stat == DEAD || paralysis || weakened || stunned || is_incorporeal()) // CHOMPEdit
|
||||
if(stat == DEAD || paralysis || weakened || stunned || is_incorporeal())
|
||||
to_chat(src, span_notice("You cannot do that while in your current state."))
|
||||
return
|
||||
|
||||
|
||||
@@ -217,7 +217,6 @@
|
||||
* @return false if normal code should continue, true to prevent normal code.
|
||||
*/
|
||||
/mob/living/proc/handle_micro_bump_helping(mob/living/tmob)
|
||||
// CHOMPAdd - Phased
|
||||
if(is_incorporeal() || tmob.is_incorporeal())
|
||||
return FALSE
|
||||
//Riding and being moved to us or something similar
|
||||
@@ -279,7 +278,6 @@
|
||||
//We can't be stepping on anyone
|
||||
if(!canmove || buckled)
|
||||
return
|
||||
// CHOMPAdd - Phased
|
||||
if(is_incorporeal() || tmob.is_incorporeal())
|
||||
return
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/atom/proc/living_mobs_in_view(var/range = world.view, var/count_held = FALSE)
|
||||
var/list/viewers = oviewers(src, range)
|
||||
if(count_held)
|
||||
viewers = viewers(src,range)
|
||||
var/list/living = list()
|
||||
for(var/mob/living/L in viewers)
|
||||
if(L.is_incorporeal())
|
||||
continue
|
||||
living += L
|
||||
if(count_held)
|
||||
for(var/obj/item/holder/H in L.contents)
|
||||
if(istype(H.held_mob, /mob/living))
|
||||
living += H.held_mob
|
||||
return living
|
||||
@@ -1,7 +1,7 @@
|
||||
/mob/living/carbon/human/proc/phase_shift()
|
||||
set name = "Phase Shift (100)"
|
||||
set desc = "Shift yourself out of alignment with realspace to travel quickly to different areas."
|
||||
set category = "Abilities.Shadekin" //ChompEDIT - TGPanel
|
||||
set category = "Abilities.Shadekin"
|
||||
|
||||
var/ability_cost = 100
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
if(!T)
|
||||
to_chat(src,span_warning("You can't use that here!"))
|
||||
return FALSE
|
||||
if((get_area(src).flags & PHASE_SHIELDED)) //CHOMPAdd - Mapping tools to control phasing
|
||||
if((get_area(src).flags & PHASE_SHIELDED)) // Mapping tools to control phasing
|
||||
to_chat(src,span_warning("This area is preventing you from phasing!"))
|
||||
return FALSE
|
||||
//RS Port #658 Start
|
||||
@@ -27,11 +27,11 @@
|
||||
darkness = 1-brightness //Invert
|
||||
|
||||
var/watcher = 0
|
||||
//Chompedit start - Nerf to phasing
|
||||
// Nerf to phasing
|
||||
for(var/thing in orange(7, src))
|
||||
if(istype(thing, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/watchers = thing
|
||||
if((watchers in oviewers(7,src)) && watchers.species != SPECIES_SHADEKIN) // And they can see us... //CHOMPEDIT - (And aren't themselves a shadekin)
|
||||
if((watchers in oviewers(7,src)) && watchers.species != SPECIES_SHADEKIN) // And they can see us... (And aren't themselves a shadekin)
|
||||
if(!(watchers.stat) && !isbelly(watchers.loc) && !istype(watchers.loc, /obj/item/holder)) // And they are alive and not being held by someone...
|
||||
watcher++ // They are watching us!
|
||||
else if(istype(thing, /mob/living/silicon/robot))
|
||||
@@ -44,7 +44,6 @@
|
||||
if(watchers.can_use())
|
||||
if(src in watchers.can_see())
|
||||
watcher++ //The camera is watching us!
|
||||
//CHOMPedit end
|
||||
|
||||
|
||||
ability_cost = CLAMP(ability_cost/(0.01+darkness*2),50, 80)//This allows for 1 watcher in full light
|
||||
@@ -52,35 +51,20 @@
|
||||
ability_cost = ability_cost + ( 15 * watcher )
|
||||
if(!(ability_flags & AB_PHASE_SHIFTED))
|
||||
log_debug("[src] attempted to shift with [watcher] observers with a cost of [ability_cost] in a darkness level of [darkness]")
|
||||
//CHOMPEdit start - inform about the observers affecting phasing
|
||||
// inform about the observers affecting phasing
|
||||
if(darkness<=0.4 && watcher>=2)
|
||||
to_chat(src, span_warning("You have a few observers in a well-lit area! This may prevent phasing. (Working cameras count towards observers)"))
|
||||
else if(watcher>=3)
|
||||
to_chat(src, span_warning("You have a large number of observers! This may prevent phasing. (Working cameras count towards observers)"))
|
||||
//CHOMPEdit end
|
||||
|
||||
|
||||
var/datum/species/shadekin/SK = species
|
||||
/* CHOMPEdit start - general shadekin ability check
|
||||
if(!istype(SK))
|
||||
to_chat(src, span_warning("Only a shadekin can use that!"))
|
||||
return FALSE
|
||||
else if(stat)
|
||||
to_chat(src, span_warning("Can't use that ability in your state!"))
|
||||
return FALSE
|
||||
//CHOMPEdit Start - Dark Respite
|
||||
else if((ability_flags & AB_DARK_RESPITE || has_modifier_of_type(/datum/modifier/dark_respite)) && !(ability_flags & AB_PHASE_SHIFTED))
|
||||
to_chat(src, span_warning("You can't use that so soon after an emergency warp!"))
|
||||
return FALSE
|
||||
*/
|
||||
if(!shadekin_ability_check())
|
||||
return FALSE
|
||||
//CHOMPEdit End
|
||||
//CHOMPEdit Start - Prevent bugs when spamming phase button
|
||||
// Prevent bugs when spamming phase button
|
||||
else if(SK.doing_phase)
|
||||
to_chat(src, span_warning("You are already trying to phase!"))
|
||||
return FALSE
|
||||
//CHOMPEdit End
|
||||
|
||||
else if(shadekin_get_energy() < ability_cost && !(ability_flags & AB_PHASE_SHIFTED))
|
||||
to_chat(src, span_warning("Not enough energy for that ability!"))
|
||||
@@ -95,14 +79,14 @@
|
||||
return FALSE
|
||||
|
||||
|
||||
SK.doing_phase = TRUE //CHOMPEdit - Prevent bugs when spamming phase button
|
||||
SK.doing_phase = TRUE // Prevent bugs when spamming phase button
|
||||
//Shifting in
|
||||
if(ability_flags & AB_PHASE_SHIFTED)
|
||||
phase_in(T)
|
||||
//Shifting out
|
||||
else
|
||||
phase_out(T)
|
||||
SK.doing_phase = FALSE //CHOMPEdit - Prevent bugs when spamming phase button
|
||||
SK.doing_phase = FALSE // Prevent bugs when spamming phase button
|
||||
|
||||
|
||||
|
||||
@@ -133,15 +117,14 @@
|
||||
//cut_overlays()
|
||||
invisibility = initial(invisibility)
|
||||
see_invisible = initial(see_invisible)
|
||||
see_invisible_default = initial(see_invisible_default) // CHOMPEdit - Allow seeing phased entities while phased.
|
||||
see_invisible_default = initial(see_invisible_default) // Allow seeing phased entities while phased.
|
||||
incorporeal_move = initial(incorporeal_move)
|
||||
density = initial(density)
|
||||
force_max_speed = initial(force_max_speed)
|
||||
//CHOMPEdit begin - resetting pull ability after phasing back in
|
||||
// resetting pull ability after phasing back in
|
||||
can_pull_size = initial(can_pull_size)
|
||||
can_pull_mobs = initial(can_pull_mobs)
|
||||
hovering = initial(hovering)
|
||||
//CHOMPEdit end
|
||||
update_icon()
|
||||
|
||||
//Cosmetics mostly
|
||||
@@ -155,7 +138,7 @@
|
||||
canmove = original_canmove
|
||||
alpha = initial(alpha)
|
||||
remove_modifiers_of_type(/datum/modifier/shadekin_phase_vision)
|
||||
remove_modifiers_of_type(/datum/modifier/shadekin_phase) //CHOMPEdit - Shadekin probably shouldn't be hit while phasing
|
||||
remove_modifiers_of_type(/datum/modifier/shadekin_phase) // Shadekin probably shouldn't be hit while phasing
|
||||
|
||||
//Potential phase-in vore
|
||||
if(can_be_drop_pred || can_be_drop_prey) //Toggleable in vore panel
|
||||
@@ -176,14 +159,13 @@
|
||||
//Affect nearby lights
|
||||
var/destroy_lights = 0
|
||||
|
||||
//CHOMPEdit start - Add back light destruction
|
||||
// Add back light destruction
|
||||
if(SK.get_shadekin_eyecolor(src) == RED_EYES)
|
||||
destroy_lights = 80
|
||||
else if(SK.get_shadekin_eyecolor(src) == PURPLE_EYES)
|
||||
destroy_lights = 25
|
||||
//CHOMPEdit end
|
||||
|
||||
//CHOMPEdit start - Add gentle phasing
|
||||
// Add gentle phasing
|
||||
if(SK.phase_gentle) // gentle case: No light destruction. Flicker in 4 tile radius once.
|
||||
for(var/obj/machinery/light/L in machines)
|
||||
if(L.z != z || get_dist(src,L) > 4)
|
||||
@@ -191,7 +173,6 @@
|
||||
L.flicker(1)
|
||||
src.Stun(1)
|
||||
else
|
||||
//CHOMPEdit end
|
||||
for(var/obj/machinery/light/L in machines)
|
||||
if(L.z != z || get_dist(src,L) > 10)
|
||||
continue
|
||||
@@ -216,7 +197,6 @@
|
||||
stop_pulling()
|
||||
canmove = FALSE
|
||||
|
||||
//CHOMPAdd Start
|
||||
var/list/allowed_implants = list(
|
||||
/obj/item/implant/sizecontrol,
|
||||
/obj/item/implant/compliance,
|
||||
@@ -231,7 +211,6 @@
|
||||
organ.implants -= O
|
||||
if(!has_embedded_objects())
|
||||
clear_alert("embeddedobject")
|
||||
//CHOMPAdd End
|
||||
|
||||
// change
|
||||
ability_flags |= AB_PHASE_SHIFTED
|
||||
@@ -240,7 +219,7 @@
|
||||
custom_emote(1,"phases out!")
|
||||
name = get_visible_name()
|
||||
|
||||
//CHOMPEdit begin - Unequipping slots when phasing in, and preventing pulling stuff while phased.
|
||||
// Unequipping slots when phasing in, and preventing pulling stuff while phased.
|
||||
if(l_hand)
|
||||
unEquip(l_hand)
|
||||
if(r_hand)
|
||||
@@ -251,7 +230,6 @@
|
||||
can_pull_size = 0
|
||||
can_pull_mobs = MOB_PULL_NONE
|
||||
hovering = TRUE
|
||||
//CHOMPEdit end
|
||||
|
||||
for(var/obj/belly/B as anything in vore_organs)
|
||||
B.escapable = FALSE
|
||||
@@ -262,11 +240,11 @@
|
||||
phaseanim.dir = dir
|
||||
alpha = 0
|
||||
add_modifier(/datum/modifier/shadekin_phase_vision)
|
||||
add_modifier(/datum/modifier/shadekin_phase) //CHOMPEdit - Shadekin probably shouldn't be hit while phasing
|
||||
add_modifier(/datum/modifier/shadekin_phase) //Shadekin probably shouldn't be hit while phasing
|
||||
sleep(5)
|
||||
invisibility = INVISIBILITY_SHADEKIN
|
||||
see_invisible = INVISIBILITY_SHADEKIN
|
||||
see_invisible_default = INVISIBILITY_SHADEKIN // CHOMPEdit - Allow seeing phased entities while phased.
|
||||
see_invisible_default = INVISIBILITY_SHADEKIN // Allow seeing phased entities while phased.
|
||||
//cut_overlays()
|
||||
update_icon()
|
||||
alpha = 127
|
||||
@@ -277,33 +255,11 @@
|
||||
force_max_speed = TRUE
|
||||
ability_flags &= ~AB_PHASE_SHIFTING
|
||||
|
||||
//CHOMPEdit start - force dephase proc, to be called by other procs to dephase the shadekin. T is the target to force dephase them to.
|
||||
/mob/living/carbon/human/proc/attack_dephase(var/turf/T = null, atom/dephaser)
|
||||
var/datum/species/shadekin/SK = species
|
||||
|
||||
// no assigned dephase-target, just use our own
|
||||
if(!T)
|
||||
T = get_turf(src)
|
||||
|
||||
// make sure it's possible to be dephased (and we're in phase)
|
||||
if(!istype(SK) || SK.doing_phase || !T.CanPass(src,T) || loc != T || !(ability_flags & AB_PHASE_SHIFTED) )
|
||||
return FALSE
|
||||
|
||||
|
||||
log_admin("[key_name_admin(src)] was stunned out of phase at [T.x],[T.y],[T.z] by [dephaser.name], last touched by [dephaser.fingerprintslast].")
|
||||
message_admins("[key_name_admin(src)] was stunned out of phase at [T.x],[T.y],[T.z] by [dephaser.name], last touched by [dephaser.fingerprintslast]. (<A href='byond://?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)", 1)
|
||||
// start the dephase
|
||||
phase_in(T)
|
||||
shadekin_adjust_energy(-20) // loss of energy for the interception
|
||||
// apply a little extra stun for good measure
|
||||
src.Weaken(3)
|
||||
|
||||
//CHOMPEdit start - gentle phasing for carbonkin
|
||||
//toggle proc for toggling gentle/normal phasing
|
||||
/mob/living/carbon/human/proc/phase_strength_toggle()
|
||||
set name = "Toggle Phase Strength"
|
||||
set desc = "Toggle strength of phase. Gentle but slower, or faster but destructive to lights."
|
||||
set category = "Abilities.Shadekin" //ChompEDIT - TGPanel
|
||||
set category = "Abilities.Shadekin"
|
||||
|
||||
var/datum/species/shadekin/SK = species
|
||||
if(!istype(SK))
|
||||
@@ -316,4 +272,339 @@
|
||||
else
|
||||
to_chat(src, span_notice("Phasing toggled to Gentle. You won't damage lights, but concentrating on that incurs a short stun."))
|
||||
SK.phase_gentle = 1
|
||||
//CHOMPEdit End
|
||||
|
||||
/datum/power/shadekin/dark_tunneling
|
||||
name = "Dark Tunneling (100) (Once)"
|
||||
desc = "Make a passage to the dark."
|
||||
verbpath = /mob/living/carbon/human/proc/dark_tunneling
|
||||
ability_icon_state = "minion0"
|
||||
|
||||
/mob/living/carbon/human/proc/dark_tunneling()
|
||||
set name = "Dark Tunneling (100) (Once)"
|
||||
set desc = "Make a passage to the dark."
|
||||
set category = "Abilities.Shadekin"
|
||||
|
||||
var/template_id = "dark_portal"
|
||||
var/datum/map_template/shelter/template
|
||||
|
||||
var/ability_cost = 100
|
||||
|
||||
if(!shadekin_ability_check())
|
||||
return FALSE
|
||||
else if(ability_flags & AB_PHASE_SHIFTED)
|
||||
to_chat(src, span_warning("You can't use that while phase shifted!"))
|
||||
return FALSE
|
||||
else if(ability_flags & AB_DARK_TUNNEL)
|
||||
to_chat(src, span_warning("You have already made a tunnel to the Dark!"))
|
||||
return FALSE
|
||||
|
||||
if(!template)
|
||||
template = SSmapping.shelter_templates[template_id]
|
||||
if(!template)
|
||||
throw EXCEPTION("Shelter template ([template_id]) not found!")
|
||||
return FALSE
|
||||
|
||||
var/turf/deploy_location = get_turf(src)
|
||||
var/status = template.check_deploy(deploy_location)
|
||||
|
||||
switch(status)
|
||||
//Not allowed due to /area technical reasons
|
||||
if(SHELTER_DEPLOY_BAD_AREA)
|
||||
to_chat(src, span_warning("A tunnel to the Dark will not function in this area."))
|
||||
|
||||
//Anchored objects or no space
|
||||
if(SHELTER_DEPLOY_BAD_TURFS, SHELTER_DEPLOY_ANCHORED_OBJECTS)
|
||||
var/width = template.width
|
||||
var/height = template.height
|
||||
to_chat(src, span_warning("There is not enough open area for a tunnel to the Dark to form! You need to clear a [width]x[height] area!"))
|
||||
|
||||
if(status != SHELTER_DEPLOY_ALLOWED)
|
||||
return FALSE
|
||||
|
||||
var/turf/T = deploy_location
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
|
||||
smoke.attach(T)
|
||||
smoke.set_up(10, 0, T)
|
||||
smoke.start()
|
||||
|
||||
src.visible_message(span_notice("[src] begins pulling dark energies around themselves."))
|
||||
if(do_after(src, 600)) //60 seconds
|
||||
playsound(src, 'sound/effects/phasein.ogg', 100, 1)
|
||||
src.visible_message(span_notice("[src] finishes pulling dark energies around themselves, creating a portal."))
|
||||
|
||||
log_and_message_admins("[key_name_admin(src)] created a tunnel to the dark at [get_area(T)]!")
|
||||
template.annihilate_plants(deploy_location)
|
||||
template.load(deploy_location, centered = TRUE)
|
||||
template.update_lighting(deploy_location)
|
||||
ability_flags |= AB_DARK_TUNNEL
|
||||
shadekin_adjust_energy(-(ability_cost - 10)) //Leaving enough energy to actually activate the portal
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/datum/power/shadekin/dark_respite
|
||||
name = "Dark Respite (Only in Dark)"
|
||||
desc = "Focus yourself on healing any injuries sustained."
|
||||
verbpath = /mob/living/carbon/human/proc/dark_respite
|
||||
ability_icon_state = "ling_anatomic_panacea"
|
||||
|
||||
/mob/living/carbon/human/proc/dark_respite()
|
||||
set name = "Dark Respite (Only in Dark)"
|
||||
set desc = "Focus yourself on healing any injuries sustained."
|
||||
set category = "Abilities.Shadekin"
|
||||
|
||||
var/datum/species/shadekin/SK = species
|
||||
if(!istype(SK))
|
||||
to_chat(src, span_warning("Only a shadekin can use that!"))
|
||||
return FALSE
|
||||
else if(!istype(get_area(src), /area/shadekin))
|
||||
to_chat(src, span_warning("Can only trigger Dark Respite in the Dark!"))
|
||||
return FALSE
|
||||
else if(stat)
|
||||
to_chat(src, span_warning("Can't use that ability in your state!"))
|
||||
return FALSE
|
||||
else if(ability_flags & AB_DARK_RESPITE)
|
||||
to_chat(src, span_warning("You can't use that so soon after an emergency warp!"))
|
||||
return FALSE
|
||||
else if(has_modifier_of_type(/datum/modifier/dark_respite) && !SK.manual_respite)
|
||||
to_chat(src, span_warning("You cannot manually end a Dark Respite triggered by an emergency warp!"))
|
||||
else if(ability_flags & AB_PHASE_SHIFTED)
|
||||
to_chat(src, span_warning("You can't use that while phase shifted!"))
|
||||
return FALSE
|
||||
|
||||
if(has_modifier_of_type(/datum/modifier/dark_respite))
|
||||
to_chat(src, span_notice("You stop focusing the Dark on healing yourself."))
|
||||
SK.manual_respite = FALSE
|
||||
remove_a_modifier_of_type(/datum/modifier/dark_respite)
|
||||
return TRUE
|
||||
to_chat(src, span_notice("You start focusing the Dark on healing yourself. (Leave the dark or trigger the ability again to end this.)"))
|
||||
SK.manual_respite = TRUE
|
||||
add_modifier(/datum/modifier/dark_respite)
|
||||
return TRUE
|
||||
|
||||
/datum/map_template/shelter/dark_portal
|
||||
name = "Dark Portal"
|
||||
shelter_id = "dark_portal"
|
||||
description = "A portal to a section of the Dark"
|
||||
mappath = "modular_chomp/maps/submaps/shelters/dark_portal.dmm"
|
||||
|
||||
/datum/map_template/shelter/dark_portal/New()
|
||||
. = ..()
|
||||
blacklisted_turfs = typecacheof(list(/turf/unsimulated))
|
||||
blacklisted_areas = typecacheof(list(/area/centcom, /area/shadekin))
|
||||
|
||||
/obj/effect/abstract/dark_maw
|
||||
var/mob/living/owner = null
|
||||
var/obj/belly/target = null
|
||||
icon = 'modular_chomp/icons/obj/Shadekin_powers_2.dmi'
|
||||
icon_state = "dark_maw_waiting"
|
||||
|
||||
/obj/effect/abstract/dark_maw/New(loc, var/mob/living/user, var/trigger_now = 0)
|
||||
. = ..()
|
||||
if(istype(user))
|
||||
owner = user
|
||||
target = owner.vore_selected
|
||||
|
||||
if(!isturf(loc))
|
||||
return INITIALIZE_HINT_QDEL
|
||||
var/turf/T = loc
|
||||
if(T.get_lumcount() >= 0.5)
|
||||
visible_message(span_notice("A set of shadowy lines flickers away in the light."))
|
||||
icon_state = "dark_maw_used"
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
var/mob/living/target_user = null
|
||||
for(var/mob/living/L in T)
|
||||
if(L != owner && !L.incorporeal_move)
|
||||
target_user = L
|
||||
break
|
||||
if(istype(target_user))
|
||||
triggered_by(target_user, 1)
|
||||
// to trigger rebuild
|
||||
else if(trigger_now)
|
||||
icon_state = "dark_maw_used"
|
||||
flick("dark_maw_tr", src)
|
||||
visible_message(span_warning("A set of crystals suddenly springs from the ground and shadowy tendrils wrap around nothing before vanishing."))
|
||||
spawn(30)
|
||||
qdel(src)
|
||||
else
|
||||
var/mob/living/carbon/human/carbon_owner = owner
|
||||
var/mob/living/simple_mob/shadekin/sm_owner = owner
|
||||
if(istype(carbon_owner))
|
||||
var/datum/species/shadekin/SK = carbon_owner.species
|
||||
if(istype(SK))
|
||||
SK.active_dark_maws += src
|
||||
else if(istype(sm_owner))
|
||||
sm_owner.active_dark_maws += src
|
||||
flick("dark_maw", src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/effect/abstract/dark_maw/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
if(istype(owner))
|
||||
var/mob/living/carbon/human/carbon_owner = owner
|
||||
var/mob/living/simple_mob/shadekin/sm_owner = owner
|
||||
if(istype(carbon_owner))
|
||||
var/datum/species/shadekin/SK = carbon_owner.species
|
||||
if(istype(SK))
|
||||
SK.active_dark_maws -= src
|
||||
else if(istype(sm_owner))
|
||||
sm_owner.active_dark_maws -= src
|
||||
return ..()
|
||||
|
||||
/obj/effect/abstract/dark_maw/Crossed(O)
|
||||
. = ..()
|
||||
if(!isliving(O))
|
||||
return
|
||||
if(icon_state != "dark_maw_waiting")
|
||||
return
|
||||
var/mob/living/L = O
|
||||
if(!L.incorporeal_move && (!owner || L != owner))
|
||||
triggered_by(L)
|
||||
|
||||
/obj/effect/abstract/dark_maw/process()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T) || T.get_lumcount() >= 0.5)
|
||||
dispel()
|
||||
|
||||
/obj/effect/abstract/dark_maw/proc/dispel()
|
||||
if(icon_state == "dark_maw_waiting")
|
||||
visible_message(span_notice("A set of shadowy lines flickers away in the light."))
|
||||
else
|
||||
visible_message(span_notice("The crystals and shadowy tendrils dissipate with the light shone on it."))
|
||||
icon_state = "dark_maw_used"
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/abstract/dark_maw/proc/triggered_by(var/mob/living/L, var/triggered_instantly = 0)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
icon_state = "dark_maw_used"
|
||||
flick("dark_maw_tr", src)
|
||||
L.AdjustStunned(4)
|
||||
visible_message(span_warning("A set of crystals spring out of the ground and shadowy tendrils start wrapping around [L]."))
|
||||
if(owner && !triggered_instantly)
|
||||
to_chat(owner, span_warning("A dark maw you deployed has triggered!"))
|
||||
spawn(10)
|
||||
var/will_vore = 1
|
||||
|
||||
if(!owner || !(target in owner) || !L.devourable || !L.can_be_drop_prey || !owner.can_be_drop_pred || !L.phase_vore)
|
||||
will_vore = 0
|
||||
|
||||
if(!src || src.gc_destroyed)
|
||||
//We got deleted probably, do nothing more
|
||||
return
|
||||
|
||||
if(L.loc != get_turf(src))
|
||||
visible_message(span_notice("The shadowy tendrils fail to catch anything and dissipate."))
|
||||
qdel(src)
|
||||
else if(will_vore)
|
||||
visible_message(span_warning("The shadowy tendrils grab around [L] and drag them into the floor, leaving nothing behind."))
|
||||
L.forceMove(target)
|
||||
qdel(src)
|
||||
else
|
||||
var/obj/effect/energy_net/dark/net = new /obj/effect/energy_net/dark(get_turf(src))
|
||||
if(net.buckle_mob(L))
|
||||
visible_message(span_warning("The shadowy tendrils wrap around [L] and traps them in a net of dark energy."))
|
||||
else
|
||||
visible_message(span_notice("The shadowy tendrils wrap around [L] and then dissipate, leaving them in place."))
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/energy_net/dark
|
||||
name = "dark net"
|
||||
desc = "It's a net made of dark energy."
|
||||
icon = 'modular_chomp/icons/obj/Shadekin_powers_2.dmi'
|
||||
icon_state = "dark_net"
|
||||
|
||||
escape_time = 30 SECONDS
|
||||
|
||||
/obj/effect/energy_net/dark/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
|
||||
if(istype(user,/mob/living/simple_mob/shadekin))
|
||||
visible_message(span_danger("[user] dissipates \the [src] with a touch!"))
|
||||
unbuckle_mob(buckled_mob)
|
||||
return
|
||||
else if(istype(user,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/datum/species/shadekin/SK = H.species
|
||||
if(istype(SK))
|
||||
visible_message(span_danger("[user] dissipates \the [src] with a touch!"))
|
||||
unbuckle_mob(buckled_mob)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/effect/energy_net/dark/process()
|
||||
. = ..()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T) || T.get_lumcount() >= 0.6)
|
||||
visible_message(span_notice("The tangle of dark tendrils fades away in the light."))
|
||||
qdel(src)
|
||||
|
||||
/datum/power/shadekin/dark_maw
|
||||
name = "Dark Maw (20)"
|
||||
desc = "Create a trap to capture others, or steal people from phase"
|
||||
verbpath = /mob/living/carbon/human/proc/dark_maw
|
||||
ability_icon_state = "dark_maw_ic"
|
||||
|
||||
/mob/living/carbon/human/proc/dark_maw()
|
||||
set name = "Dark Maw (20)"
|
||||
set desc = "Create a trap to capture others, or steal people from phase"
|
||||
set category = "Abilities.Shadekin"
|
||||
|
||||
var/ability_cost = 20
|
||||
|
||||
if(!shadekin_ability_check())
|
||||
return FALSE
|
||||
else if(shadekin_get_energy() < ability_cost)
|
||||
to_chat(src, span_warning("Not enough energy for that ability!"))
|
||||
return FALSE
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
to_chat(src, span_warning("You don't seem to be able to set a trap here!"))
|
||||
return FALSE
|
||||
else if(T.get_lumcount() >= 0.5)
|
||||
to_chat(src, span_warning("There is too much light here for your trap to last!"))
|
||||
return FALSE
|
||||
|
||||
if(do_after(src, 10))
|
||||
if(ability_flags & AB_PHASE_SHIFTED)
|
||||
new /obj/effect/abstract/dark_maw(loc, src, 1)
|
||||
else
|
||||
new /obj/effect/abstract/dark_maw(loc, src)
|
||||
shadekin_adjust_energy(-ability_cost)
|
||||
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/proc/clear_dark_maws()
|
||||
set name = "Dispel dark maws"
|
||||
set desc = "Dispel any active dark maws in place"
|
||||
set category = "Abilities.Shadekin"
|
||||
|
||||
var/datum/species/shadekin/SK = species
|
||||
if(!istype(SK))
|
||||
to_chat(src, span_warning("Only a shadekin can use that!"))
|
||||
return FALSE
|
||||
|
||||
for(var/obj/effect/abstract/dark_maw/dm in SK.active_dark_maws)
|
||||
dm.dispel()
|
||||
|
||||
/mob/living/carbon/human/proc/nutrition_conversion_toggle()
|
||||
set name = "Toggle Energy <-> Nutrition conversions"
|
||||
set desc = "Toggle dark energy and nutrition being converted into each other when full"
|
||||
set category = "Abilities.Shadekin"
|
||||
|
||||
var/datum/species/shadekin/SK = species
|
||||
if(!istype(SK))
|
||||
to_chat(src, span_warning("Only a shadekin can use that!"))
|
||||
return FALSE
|
||||
|
||||
if(SK.nutrition_energy_conversion)
|
||||
to_chat(src, span_notice("Nutrition and dark energy conversions disabled."))
|
||||
SK.nutrition_energy_conversion = 0
|
||||
else
|
||||
to_chat(src, span_notice("Nutrition and dark energy conversions enabled."))
|
||||
SK.nutrition_energy_conversion = 1
|
||||
|
||||
/datum/modifier/shadekin_phase
|
||||
name = "Shadekin Phasing"
|
||||
evasion = 100
|
||||
|
||||
@@ -4779,7 +4779,6 @@
|
||||
#include "modular_chomp\code\__defines\text.dm"
|
||||
#include "modular_chomp\code\_global_vars\list\names.dm"
|
||||
#include "modular_chomp\code\_HELPERS\game.dm"
|
||||
#include "modular_chomp\code\_HELPERS\mobs.dm"
|
||||
#include "modular_chomp\code\_onclick\hud\alert.dm"
|
||||
#include "modular_chomp\code\ATMOSPHERICS\atmospherics.dm"
|
||||
#include "modular_chomp\code\datums\http.dm"
|
||||
|
||||
Reference in New Issue
Block a user