mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-27 14:08:44 +01:00
Adds the "absorbed prey can devour" addon (#18906)
* we gots this * removes verb implementation * no clue why that was such a mess * clean up the rest * implementation * cleanup * . * hide it otherwise * quick fix * missing stackitem --------- Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
@@ -181,7 +181,6 @@
|
||||
H.muffled = FALSE
|
||||
H.forced_psay = FALSE
|
||||
|
||||
|
||||
addtimer(CALLBACK(H, TYPE_PROC_REF(/mob/living, can_leave_dark)), 5 MINUTES, TIMER_DELETE_ME)
|
||||
else
|
||||
H.add_modifier(/datum/modifier/dark_respite, 25 MINUTES)
|
||||
|
||||
@@ -1364,3 +1364,50 @@ var/eggs = 0
|
||||
src.visible_message(span_infoplain(span_red("[src] sinks their stinger into [T]!")))
|
||||
T.bloodstr.add_reagent(REAGENT_ID_CONDENSEDCAPSAICINV,3)
|
||||
last_special = world.time + (5 SECONDS) // Many little jabs instead of one big one
|
||||
|
||||
/mob/living/proc/absorb_devour()
|
||||
if(!absorbed || !isbelly(loc))
|
||||
return
|
||||
if(!isliving(loc.loc))
|
||||
return
|
||||
var/mob/living/pred = loc.loc
|
||||
var/obj/belly/belly = loc
|
||||
var/list/targets = list()
|
||||
for(var/mob/living/potentialtarget in range(1, pred))
|
||||
if(!isliving(potentialtarget)) //Don't eat anything that isn't mob/living. Failsafe.
|
||||
continue
|
||||
if(potentialtarget == pred)
|
||||
continue
|
||||
if(potentialtarget.devourable)
|
||||
targets += potentialtarget
|
||||
if(!(targets.len))
|
||||
to_chat(src, span_notice("No eligible targets found."))
|
||||
return
|
||||
var/mob/living/target = tgui_input_list(src, "Please select a target.", "Victim", targets)
|
||||
if(!absorbed || !isbelly(loc))
|
||||
return
|
||||
if(!isliving(loc.loc))
|
||||
return
|
||||
if(!target)
|
||||
return
|
||||
if(!isliving(target)) //Safety.
|
||||
to_chat(src, span_warning("You need to select a living target!"))
|
||||
return
|
||||
if (get_dist(src,target) >= 2)
|
||||
to_chat(src, span_warning("You need to be closer to do that."))
|
||||
return
|
||||
target.visible_message(span_vnotice("\The [pred]'s [belly] seems interested in \the [target]."),\
|
||||
span_vwarning("\The [pred]'s [belly] threatens to [lowertext(belly.vore_verb)] you!"))
|
||||
to_chat(pred, span_vnotice("Your [belly] tries to [lowertext(belly.vore_verb)] \the [target].")) //people who want this will often be unaware pred players, so I'm making the warning a bit smaller text for them
|
||||
to_chat(pred, span_vwarning("You look for a chance to [lowertext(belly.vore_verb)] \the [target]."))
|
||||
var/starting_loc = target.loc
|
||||
if(do_after(src, 5 SECONDS, target))
|
||||
if(target.loc != starting_loc)
|
||||
to_chat(src, span_notice("\The [target] is no longer within reach."))
|
||||
return
|
||||
if(target.buckled)
|
||||
target.buckled.unbuckle_mob()
|
||||
to_chat(src, span_vwarning("You manage to [lowertext(belly.vore_verb)] \the [target]!"))
|
||||
to_chat(pred, span_vnotice("Your [belly] manages to [lowertext(belly.vore_verb)] \the [target]."))
|
||||
to_chat(target, span_vwarning("You are [lowertext(belly.vore_verb)]ed by \The [pred]'s [belly]!"))
|
||||
return pred.begin_instant_nom(src, target, pred, belly, FALSE)
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
//Actual full digest modes
|
||||
var/tmp/static/list/digest_modes = list(DM_HOLD,DM_DIGEST,DM_ABSORB,DM_DRAIN,DM_SELECT,DM_UNABSORB,DM_HEAL,DM_SHRINK,DM_GROW,DM_SIZE_STEAL,DM_EGG)
|
||||
//Digest mode addon flags
|
||||
var/tmp/static/list/mode_flag_list = list("Numbing" = DM_FLAG_NUMBING, "Stripping" = DM_FLAG_STRIPPING, "Leave Remains" = DM_FLAG_LEAVEREMAINS, "Muffles" = DM_FLAG_THICKBELLY, "Affect Worn Items" = DM_FLAG_AFFECTWORN, "Jams Sensors" = DM_FLAG_JAMSENSORS, "Complete Absorb" = DM_FLAG_FORCEPSAY, "Spare Prosthetics" = DM_FLAG_SPARELIMB, "Slow Body Digestion" = DM_FLAG_SLOWBODY, "Muffle Items" = DM_FLAG_MUFFLEITEMS, "TURBO MODE" = DM_FLAG_TURBOMODE)
|
||||
var/tmp/static/list/mode_flag_list = list("Numbing" = DM_FLAG_NUMBING, "Stripping" = DM_FLAG_STRIPPING, "Leave Remains" = DM_FLAG_LEAVEREMAINS, "Muffles" = DM_FLAG_THICKBELLY, "Affect Worn Items" = DM_FLAG_AFFECTWORN, "Jams Sensors" = DM_FLAG_JAMSENSORS, "Complete Absorb" = DM_FLAG_FORCEPSAY, "Spare Prosthetics" = DM_FLAG_SPARELIMB, "Slow Body Digestion" = DM_FLAG_SLOWBODY, "Muffle Items" = DM_FLAG_MUFFLEITEMS, "TURBO MODE" = DM_FLAG_TURBOMODE, "Absorbed prey can devour" = DM_FLAG_ABSORBEDVORE)
|
||||
//Item related modes
|
||||
var/tmp/static/list/item_digest_modes = list(IM_HOLD,IM_DIGEST_FOOD,IM_DIGEST,IM_DIGEST_PARALLEL)
|
||||
//drain modes
|
||||
|
||||
@@ -186,6 +186,20 @@
|
||||
if(L.absorbed && !issilicon(L))
|
||||
L.Weaken(5)
|
||||
|
||||
//Thickbelly flag
|
||||
if((mode_flags & DM_FLAG_THICKBELLY) && !L.muffled)
|
||||
L.muffled = TRUE
|
||||
//Fix muffled sometimes being sticky.
|
||||
else if(!(mode_flags & DM_FLAG_THICKBELLY) && L.muffled)
|
||||
L.muffled = FALSE
|
||||
|
||||
//Force psay
|
||||
if((mode_flags & DM_FLAG_FORCEPSAY) && !L.forced_psay && L.absorbed)
|
||||
L.forced_psay = TRUE
|
||||
//Fix forcepsay sometimes being sticky.
|
||||
else if(!(mode_flags & DM_FLAG_FORCEPSAY) && L.forced_psay)
|
||||
L.forced_psay = FALSE
|
||||
|
||||
//Handle 'human'
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
@@ -195,20 +209,6 @@
|
||||
if(H.bloodstr.get_reagent_amount(REAGENT_ID_NUMBENZYME) < 2)
|
||||
H.bloodstr.add_reagent(REAGENT_ID_NUMBENZYME,4)
|
||||
|
||||
//Thickbelly flag
|
||||
if((mode_flags & DM_FLAG_THICKBELLY) && !H.muffled)
|
||||
H.muffled = TRUE
|
||||
//Fix muffled sometimes being sticky.
|
||||
else if(!(mode_flags & DM_FLAG_THICKBELLY) && H.muffled)
|
||||
H.muffled = FALSE
|
||||
|
||||
//Force psay
|
||||
if((mode_flags & DM_FLAG_FORCEPSAY) && !H.forced_psay && H.absorbed)
|
||||
H.forced_psay = TRUE
|
||||
//Fix forcepsay sometimes being sticky.
|
||||
else if(!(mode_flags & DM_FLAG_FORCEPSAY) && H.forced_psay)
|
||||
H.forced_psay = FALSE
|
||||
|
||||
//Worn items flag
|
||||
if((mode_flags & DM_FLAG_AFFECTWORN) && H.contaminate_pref)
|
||||
for(var/slot in slots)
|
||||
|
||||
@@ -28,70 +28,86 @@
|
||||
|
||||
/datum/vore_look/proc/get_inside_data(mob/owner)
|
||||
var/atom/hostloc = owner.loc
|
||||
//Allow VorePanel to show pred belly details even while indirectly inside
|
||||
// Allow VorePanel to show pred belly details even while indirectly inside
|
||||
if(isliving(owner))
|
||||
var/mob/living/H = owner
|
||||
hostloc = H.surrounding_belly()
|
||||
//End of indirect vorefx additions
|
||||
if(!isbelly(hostloc))
|
||||
return list()
|
||||
|
||||
var/list/inside = list()
|
||||
if(isbelly(hostloc))
|
||||
var/obj/belly/inside_belly = hostloc
|
||||
var/mob/living/pred = inside_belly.owner
|
||||
var/obj/belly/inside_belly = hostloc
|
||||
var/mob/living/pred = inside_belly.owner
|
||||
|
||||
var/inside_desc = "No description."
|
||||
if(owner.absorbed && inside_belly.absorbed_desc)
|
||||
inside_desc = inside_belly.absorbed_desc
|
||||
else if(inside_belly.desc)
|
||||
inside_desc = inside_belly.desc
|
||||
var/inside_desc = "No description."
|
||||
if(owner.absorbed && inside_belly.absorbed_desc)
|
||||
inside_desc = inside_belly.absorbed_desc
|
||||
else if(inside_belly.desc)
|
||||
inside_desc = inside_belly.desc
|
||||
|
||||
if(inside_desc != "No description.")
|
||||
inside_desc = inside_belly.belly_format_string(inside_desc, owner, use_first_only = TRUE)
|
||||
if(inside_desc != "No description.")
|
||||
inside_desc = inside_belly.belly_format_string(inside_desc, owner, use_first_only = TRUE)
|
||||
|
||||
inside = list(
|
||||
"absorbed" = owner.absorbed,
|
||||
"belly_name" = inside_belly.name,
|
||||
"belly_mode" = inside_belly.digest_mode,
|
||||
"desc" = inside_desc,
|
||||
"pred" = pred,
|
||||
"ref" = "\ref[inside_belly]",
|
||||
"liq_lvl" = inside_belly.reagents.total_volume,
|
||||
"liq_reagent_type" = inside_belly.reagent_chosen,
|
||||
"liuq_name" = inside_belly.reagent_name,
|
||||
inside = list(
|
||||
"absorbed" = owner.absorbed,
|
||||
"belly_name" = inside_belly.name,
|
||||
"belly_mode" = inside_belly.digest_mode,
|
||||
"desc" = inside_desc,
|
||||
"pred" = pred,
|
||||
"ref" = "\ref[inside_belly]",
|
||||
"liq_lvl" = inside_belly.reagents.total_volume,
|
||||
"liq_reagent_type" = inside_belly.reagent_chosen,
|
||||
"liuq_name" = inside_belly.reagent_name,
|
||||
)
|
||||
|
||||
var/list/inside_contents = list()
|
||||
for(var/atom/movable/O in inside_belly)
|
||||
if(O == owner)
|
||||
continue
|
||||
var/our_type
|
||||
if(isliving(O))
|
||||
our_type = "Living"
|
||||
else if(isitem(O))
|
||||
our_type = "Item"
|
||||
|
||||
var/list/info = list(
|
||||
"name" = "[O]",
|
||||
"absorbed" = FALSE,
|
||||
"stat" = 0,
|
||||
"ref" = "\ref[O]",
|
||||
"outside" = FALSE,
|
||||
"our_type" = our_type
|
||||
)
|
||||
|
||||
var/list/inside_contents = list()
|
||||
for(var/atom/movable/O in inside_belly)
|
||||
if(O == owner)
|
||||
continue
|
||||
var/our_type
|
||||
if(isliving(O))
|
||||
our_type = "Living"
|
||||
else if(isitem(O))
|
||||
our_type = "Item"
|
||||
|
||||
var/list/info = list(
|
||||
"name" = "[O]",
|
||||
"absorbed" = FALSE,
|
||||
"stat" = 0,
|
||||
"ref" = "\ref[O]",
|
||||
"outside" = FALSE,
|
||||
"our_type" = our_type
|
||||
)
|
||||
if(show_pictures) //disables icon mode
|
||||
if(inside_belly.contents.len <= max_icon_content)
|
||||
icon_overflow = FALSE
|
||||
info["icon"] = cached_nom_icon(O)
|
||||
else
|
||||
icon_overflow = TRUE
|
||||
if(isliving(O))
|
||||
var/mob/living/M = O
|
||||
info["stat"] = M.stat
|
||||
if(M.absorbed)
|
||||
info["absorbed"] = TRUE
|
||||
UNTYPED_LIST_ADD(inside_contents, info)
|
||||
inside["contents"] = inside_contents
|
||||
if(show_pictures) //disables icon mode
|
||||
if(inside_belly.contents.len <= max_icon_content)
|
||||
icon_overflow = FALSE
|
||||
info["icon"] = cached_nom_icon(O)
|
||||
else
|
||||
icon_overflow = TRUE
|
||||
if(isliving(O))
|
||||
var/mob/living/M = O
|
||||
info["stat"] = M.stat
|
||||
if(M.absorbed)
|
||||
info["absorbed"] = TRUE
|
||||
UNTYPED_LIST_ADD(inside_contents, info)
|
||||
inside["contents"] = inside_contents
|
||||
return inside
|
||||
|
||||
/datum/vore_look/proc/get_prey_abilities(mob/owner)
|
||||
var/atom/hostloc = owner.loc
|
||||
// Allow VorePanel to show pred belly details even while indirectly inside
|
||||
if(isliving(owner))
|
||||
var/mob/living/H = owner
|
||||
hostloc = H.surrounding_belly()
|
||||
if(!isbelly(hostloc))
|
||||
return list()
|
||||
|
||||
var/obj/belly/inside_belly = hostloc
|
||||
var/list/abilities = list()
|
||||
if(inside_belly.mode_flags & DM_FLAG_ABSORBEDVORE)
|
||||
UNTYPED_LIST_ADD(abilities, list("name" = "devour_as_absorbed", "available" = owner.absorbed))
|
||||
return abilities
|
||||
|
||||
/datum/vore_look/proc/get_host_mobtype(mob/owner)
|
||||
var/list/host_mobtype = list("is_cyborg" = FALSE, "is_vore_simple_mob" = FALSE)
|
||||
if(isrobot(owner))
|
||||
|
||||
@@ -133,6 +133,7 @@
|
||||
data["host_mobtype"] = null
|
||||
data["show_pictures"] = null
|
||||
data["icon_overflow"] = null
|
||||
data["prey_abilities"] = null
|
||||
data["our_bellies"] = null
|
||||
data["selected"] = null
|
||||
data["soulcatcher"] = null
|
||||
@@ -159,6 +160,7 @@
|
||||
// Content Data
|
||||
data["show_pictures"] = show_pictures
|
||||
data["icon_overflow"] = icon_overflow
|
||||
data["prey_abilities"] = get_prey_abilities(host)
|
||||
|
||||
if(SOULCATCHER_TAB)
|
||||
// Soulcatcher and abilities
|
||||
@@ -237,6 +239,11 @@
|
||||
host.persistend_edit_mode = !host.persistend_edit_mode
|
||||
return TRUE
|
||||
|
||||
if("prey_ability")
|
||||
if(!isliving(ui.user))
|
||||
return FALSE
|
||||
return perform_prey_ability(ui.user, params)
|
||||
|
||||
// Host is inside someone else, and is trying to interact with something else inside that person.
|
||||
if("pick_from_inside")
|
||||
return pick_from_inside(ui.user, params)
|
||||
@@ -1361,6 +1368,22 @@
|
||||
to_chat(user, span_vwarning("\The [target] is currently [condition], they will not be able to [condition_consequences]."))
|
||||
return FALSE
|
||||
|
||||
/datum/vore_look/proc/perform_prey_ability(mob/living/user, params)
|
||||
var/obj/belly/OB = locate(params["belly"])
|
||||
|
||||
if(!(user in OB))
|
||||
return TRUE // Aren't here anymore, need to update menu
|
||||
|
||||
var/ability = params["ability"]
|
||||
if(!(ability in list("devour_as_absorbed")))
|
||||
return FALSE
|
||||
|
||||
switch(ability)
|
||||
if("devour_as_absorbed")
|
||||
user.absorb_devour()
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/vore_look/proc/sanitize_fixed_list(var/list/messages, type, delim = "\n\n", limit)
|
||||
if(!limit)
|
||||
CRASH("[type] set message called without limit!")
|
||||
|
||||
Reference in New Issue
Block a user