Merge remote-tracking branch 'remotes/upstream/master' into zandario-circuit-port
@@ -12,6 +12,7 @@
|
||||
#define ui_boxcraft "EAST-4:22,SOUTH+1:6"
|
||||
#define ui_boxarea "EAST-4:6,SOUTH+1:6"
|
||||
#define ui_boxlang "EAST-5:22,SOUTH+1:6"
|
||||
#define ui_boxvore "EAST-4:22,SOUTH+1:6"
|
||||
|
||||
//Filters
|
||||
#define CIT_FILTER_STAMINACRIT filter(type="drop_shadow", x=0, y=0, size=-3, border=0, color="#04080F")
|
||||
@@ -130,5 +131,7 @@
|
||||
//component stuff
|
||||
#define COMSIG_COMBAT_TOGGLED "combatmode_toggled" //called by combat mode toggle on all equipped items. args: (mob/user, combatmode)
|
||||
|
||||
#define COMSIG_VORE_TOGGLED "voremode_toggled" // totally not copypasta
|
||||
|
||||
//belly sound pref things
|
||||
#define NORMIE_HEARCHECK 4
|
||||
|
||||
@@ -18,39 +18,6 @@
|
||||
/* // removing sizeplay again
|
||||
GLOBAL_LIST_INIT(player_sizes_list, list("Macro" = SIZESCALE_HUGE, "Big" = SIZESCALE_BIG, "Normal" = SIZESCALE_NORMAL, "Small" = SIZESCALE_SMALL, "Tiny" = SIZESCALE_TINY))
|
||||
// Edited to make the new travis check go away
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(digest_pred, list(
|
||||
'sound/vore/pred/digest_01.ogg',
|
||||
'sound/vore/pred/digest_02.ogg',
|
||||
'sound/vore/pred/digest_03.ogg',
|
||||
'sound/vore/pred/digest_04.ogg',
|
||||
'sound/vore/pred/digest_05.ogg',
|
||||
'sound/vore/pred/digest_06.ogg',
|
||||
'sound/vore/pred/digest_07.ogg',
|
||||
'sound/vore/pred/digest_08.ogg',
|
||||
'sound/vore/pred/digest_09.ogg',
|
||||
'sound/vore/pred/digest_10.ogg',
|
||||
'sound/vore/pred/digest_11.ogg',
|
||||
'sound/vore/pred/digest_12.ogg',
|
||||
'sound/vore/pred/digest_13.ogg',
|
||||
'sound/vore/pred/digest_14.ogg',
|
||||
'sound/vore/pred/digest_15.ogg',
|
||||
'sound/vore/pred/digest_16.ogg',
|
||||
'sound/vore/pred/digest_17.ogg',
|
||||
'sound/vore/pred/digest_18.ogg'))
|
||||
|
||||
GLOBAL_LIST_INIT(death_pred, list(
|
||||
'sound/vore/pred/death_01.ogg',
|
||||
'sound/vore/pred/death_02.ogg',
|
||||
'sound/vore/pred/death_03.ogg',
|
||||
'sound/vore/pred/death_04.ogg',
|
||||
'sound/vore/pred/death_05.ogg',
|
||||
'sound/vore/pred/death_06.ogg',
|
||||
'sound/vore/pred/death_07.ogg',
|
||||
'sound/vore/pred/death_08.ogg',
|
||||
'sound/vore/pred/death_09.ogg',
|
||||
'sound/vore/pred/death_10.ogg'))
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_INIT(vore_sounds, list(
|
||||
@@ -66,79 +33,21 @@ GLOBAL_LIST_INIT(vore_sounds, list(
|
||||
"Squish3" = 'sound/vore/pred/squish_03.ogg',
|
||||
"Squish4" = 'sound/vore/pred/squish_04.ogg',
|
||||
"Rustle (cloth)" = 'sound/effects/rustle5.ogg',
|
||||
"rustle2(cloth)" = 'sound/effects/rustle2.ogg',
|
||||
"rustle3(cloth)" = 'sound/effects/rustle3.ogg',
|
||||
"rustle4(cloth)" = 'sound/effects/rustle4.ogg',
|
||||
"rustle5(cloth)" = 'sound/effects/rustle5.ogg',
|
||||
"None" = null))
|
||||
/*
|
||||
GLOBAL_LIST_INIT(pred_struggle_sounds, list(
|
||||
"Struggle1" = 'sound/vore/pred/struggle_01.ogg',
|
||||
"Struggle2" = 'sound/vore/pred/struggle_02.ogg',
|
||||
"Struggle3" = 'sound/vore/pred/struggle_03.ogg',
|
||||
"Struggle4" = 'sound/vore/pred/struggle_04.ogg',
|
||||
"Struggle5" = 'sound/vore/pred/struggle_05.ogg'))
|
||||
|
||||
GLOBAL_LIST_INIT(prey_vore_sounds, list(
|
||||
"Gulp" = 'sound/vore/prey/swallow_01.ogg',
|
||||
"Swallow" = 'sound/vore/prey/swallow_02.ogg',
|
||||
"Insertion1" = 'sound/vore/prey/insertion_01.ogg',
|
||||
"Insertion2" = 'sound/vore/prey/insertion_02.ogg',
|
||||
"Tauric Swallow" = 'sound/vore/prey/taurswallow.ogg',
|
||||
"Schlorp" = 'sound/vore/prey/schlorp.ogg',
|
||||
"Squish1" = 'sound/vore/prey/squish_01.ogg',
|
||||
"Squish2" = 'sound/vore/prey/squish_02.ogg',
|
||||
"Squish3" = 'sound/vore/prey/squish_03.ogg',
|
||||
"Squish4" = 'sound/vore/prey/squish_04.ogg'))
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(prey_struggle_sounds, list(
|
||||
"Struggle1" = 'sound/vore/prey/struggle_01.ogg',
|
||||
"Struggle2" = 'sound/vore/prey/struggle_02.ogg',
|
||||
"Struggle3" = 'sound/vore/prey/struggle_03.ogg',
|
||||
"Struggle4" = 'sound/vore/prey/struggle_04.ogg',
|
||||
"Struggle5" = 'sound/vore/prey/struggle_05.ogg'))
|
||||
|
||||
GLOBAL_LIST_INIT(digest_prey, list(
|
||||
"digest1" = 'sound/vore/prey/digest_01.ogg',
|
||||
"digest2" = 'sound/vore/prey/digest_02.ogg',
|
||||
"digest3" = 'sound/vore/prey/digest_03.ogg',
|
||||
"digest4" = 'sound/vore/prey/digest_04.ogg',
|
||||
"digest5" = 'sound/vore/prey/digest_05.ogg',
|
||||
"digest6" = 'sound/vore/prey/digest_06.ogg',
|
||||
"digest7" = 'sound/vore/prey/digest_07.ogg',
|
||||
"digest8" = 'sound/vore/prey/digest_08.ogg',
|
||||
"digest9" = 'sound/vore/prey/digest_09.ogg',
|
||||
"digest10" = 'sound/vore/prey/digest_10.ogg',
|
||||
"digest11" = 'sound/vore/prey/digest_11.ogg',
|
||||
"digest12" = 'sound/vore/prey/digest_12.ogg',
|
||||
"digest13" = 'sound/vore/prey/digest_13.ogg',
|
||||
"digest14" = 'sound/vore/prey/digest_14.ogg',
|
||||
"digest15" = 'sound/vore/prey/digest_15.ogg',
|
||||
"digest16" = 'sound/vore/prey/digest_16.ogg',
|
||||
"digest17" = 'sound/vore/prey/digest_17.ogg',
|
||||
"digest18" = 'sound/vore/prey/digest_18.ogg'))
|
||||
|
||||
GLOBAL_LIST_INIT(death_prey, list(
|
||||
"death1" = 'sound/vore/prey/death_01.ogg',
|
||||
"death2" = 'sound/vore/prey/death_02.ogg',
|
||||
"death3" = 'sound/vore/prey/death_03.ogg',
|
||||
"death4" = 'sound/vore/prey/death_04.ogg',
|
||||
"death5" = 'sound/vore/prey/death_05.ogg',
|
||||
"death6" = 'sound/vore/prey/death_06.ogg',
|
||||
"death7" = 'sound/vore/prey/death_07.ogg',
|
||||
"death8" = 'sound/vore/prey/death_08.ogg',
|
||||
"death9" = 'sound/vore/prey/death_09.ogg',
|
||||
"death10" = 'sound/vore/prey/death_10.ogg'))
|
||||
*/
|
||||
"Rustle 2 (cloth)" = 'sound/effects/rustle2.ogg',
|
||||
"Rustle 3 (cloth)" = 'sound/effects/rustle3.ogg',
|
||||
"Rustle 4 (cloth)" = 'sound/effects/rustle4.ogg',
|
||||
"Rustle 5 (cloth)" = 'sound/effects/rustle5.ogg',
|
||||
"None" = null
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(release_sounds, list(
|
||||
"rustle (cloth)" = 'sound/effects/rustle1.ogg',
|
||||
"rustle2 (cloth)" = 'sound/effects/rustle2.ogg',
|
||||
"rustle3 (cloth)" = 'sound/effects/rustle3.ogg',
|
||||
"rustle4 (cloth)" = 'sound/effects/rustle4.ogg',
|
||||
"rustle5 (cloth)" = 'sound/effects/rustle5.ogg',
|
||||
"Stomach Move" = 'sound/vore/pred/stomachmove.ogg',
|
||||
"Pred Escape" = 'sound/vore/pred/escape.ogg',
|
||||
"Splatter" = 'sound/effects/splat.ogg',
|
||||
"None" = null))
|
||||
"Rustle (cloth)" = 'sound/effects/rustle1.ogg',
|
||||
"Rustle 2 (cloth)" = 'sound/effects/rustle2.ogg',
|
||||
"Rustle 3 (cloth)" = 'sound/effects/rustle3.ogg',
|
||||
"Rustle 4 (cloth)" = 'sound/effects/rustle4.ogg',
|
||||
"Rustle 5 (cloth)" = 'sound/effects/rustle5.ogg',
|
||||
"Stomach Move" = 'sound/vore/pred/stomachmove.ogg',
|
||||
"Pred Escape" = 'sound/vore/pred/escape.ogg',
|
||||
"Splatter" = 'sound/effects/splat.ogg',
|
||||
"None" = null
|
||||
))
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
#define ui_crafting "EAST-5:20,SOUTH:5"//CIT CHANGE - moves this over one tile to accommodate for combat mode toggle
|
||||
#define ui_building "EAST-5:20,SOUTH:21"//CIT CHANGE - ditto
|
||||
#define ui_language_menu "EAST-5:4,SOUTH:21"//CIT CHANGE - ditto
|
||||
#define ui_voremode "EAST-5:20,SOUTH:5"
|
||||
|
||||
#define ui_borg_pull "EAST-2:26,SOUTH+1:7"
|
||||
#define ui_borg_radio "EAST-1:28,SOUTH+1:7"
|
||||
|
||||
@@ -109,6 +109,13 @@
|
||||
using.screen_loc = ui_boxarea // CIT CHANGE
|
||||
static_inventory += using
|
||||
|
||||
using = new /obj/screen/voretoggle() //We fancy Vore now
|
||||
using.icon = tg_ui_icon_to_cit_ui(ui_style)
|
||||
using.screen_loc = ui_voremode
|
||||
if(!widescreenlayout)
|
||||
using.screen_loc = ui_boxvore
|
||||
static_inventory += using
|
||||
|
||||
action_intent = new /obj/screen/act_intent/segmented
|
||||
action_intent.icon_state = mymob.a_intent
|
||||
static_inventory += action_intent
|
||||
|
||||
@@ -54,6 +54,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
var/lockdown = FALSE //disallow transit after nuke goes off
|
||||
|
||||
var/auto_call = 72000 //CIT CHANGE - time before in deciseconds in which the shuttle is auto called. Default is 2ish hours plus 15 for the shuttle. So total is 3.
|
||||
var/realtimeofstart = 0
|
||||
|
||||
/datum/controller/subsystem/shuttle/Initialize(timeofday)
|
||||
ordernum = rand(1, 9000)
|
||||
@@ -74,6 +75,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
WARNING("No /obj/docking_port/mobile/emergency/backup placed on the map!")
|
||||
if(!supply)
|
||||
WARNING("No /obj/docking_port/mobile/supply placed on the map!")
|
||||
realtimeofstart = world.realtime
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/initial_load()
|
||||
|
||||
@@ -304,6 +304,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
to_chat(world, "<h4>[holiday.greet()]</h4>")
|
||||
|
||||
PostSetup()
|
||||
SSshuttle.realtimeofstart = world.realtime
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -752,6 +752,11 @@
|
||||
for(var/X in spell_list)
|
||||
var/obj/effect/proc_holder/spell/S = X
|
||||
S.action.Grant(new_character)
|
||||
var/datum/antagonist/changeling/changeling = new_character.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(changeling)
|
||||
for(var/P in changeling.purchasedpowers)
|
||||
var/obj/effect/proc_holder/changeling/I = P
|
||||
I.action.Grant(new_character)
|
||||
|
||||
/datum/mind/proc/disrupt_spells(delay, list/exceptions = New())
|
||||
for(var/X in spell_list)
|
||||
|
||||
@@ -202,7 +202,7 @@
|
||||
state = STATE_CANCELSHUTTLE
|
||||
if("cancelshuttle2")
|
||||
if(authenticated)
|
||||
if(world.time > SSshuttle.auto_call) //Citadel Edit Removing auto_call caused recall.
|
||||
if((world.realtime - SSshuttle.realtimeofstart) > SSshuttle.auto_call) //Citadel Edit Removing auto_call caused recall.
|
||||
say("Warning: Emergency shuttle recalls have been blocked by Central Command due to ongoing crew transfer procedures.")
|
||||
else
|
||||
SSshuttle.cancelEvac(usr)
|
||||
|
||||
@@ -213,6 +213,9 @@
|
||||
'sound/vore/prey/death_04.ogg','sound/vore/prey/death_05.ogg','sound/vore/prey/death_06.ogg',
|
||||
'sound/vore/prey/death_07.ogg','sound/vore/prey/death_08.ogg','sound/vore/prey/death_09.ogg',
|
||||
'sound/vore/prey/death_10.ogg')
|
||||
if("hunger_sounds")
|
||||
soundin = pick( 'sound/vore/growl1.ogg','sound/vore/growl2.ogg','sound/vore/growl3.ogg','sound/vore/growl4.ogg',
|
||||
'sound/vore/growl5.ogg')
|
||||
if("clang")
|
||||
soundin = pick('sound/effects/clang1.ogg', 'sound/effects/clang2.ogg')
|
||||
if("clangsmall")
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
name = "Cellular Emporium"
|
||||
icon_icon = 'icons/obj/drinks.dmi'
|
||||
button_icon_state = "changelingsting"
|
||||
background_icon_state = "bg_alien"
|
||||
background_icon_state = "bg_ling"
|
||||
var/datum/cellular_emporium/cellular_emporium
|
||||
|
||||
/datum/action/innate/cellular_emporium/New(our_target)
|
||||
|
||||
@@ -20,10 +20,12 @@
|
||||
|
||||
|
||||
/obj/effect/proc_holder/changeling/proc/on_purchase(mob/user, is_respec)
|
||||
action.Grant(user)
|
||||
if(!is_respec)
|
||||
SSblackbox.record_feedback("tally", "changeling_power_purchase", 1, name)
|
||||
|
||||
/obj/effect/proc_holder/changeling/proc/on_refund(mob/user)
|
||||
action.Remove(user)
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/changeling/Click()
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
chemical_cost = 0
|
||||
dna_cost = 0
|
||||
req_human = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_absorb_dna"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/absorbDNA/can_sting(mob/living/carbon/user)
|
||||
if(!..())
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
dna_cost = 2
|
||||
req_human = 1
|
||||
req_stat = UNCONSCIOUS
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_adrenals"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
//Recover from stuns.
|
||||
/obj/effect/proc_holder/changeling/adrenaline/sting_action(mob/living/user)
|
||||
|
||||
@@ -8,12 +8,16 @@
|
||||
chemical_cost = 0
|
||||
dna_cost = 2 //Would be 1 without thermal vision
|
||||
active = FALSE
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_augmented_eyesight"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/augmented_eyesight/on_purchase(mob/user) //The ability starts inactive, so we should be protected from flashes.
|
||||
var/obj/item/organ/eyes/E = user.getorganslot(ORGAN_SLOT_EYES)
|
||||
if (E)
|
||||
E.flash_protect = 2 //Adjust the user's eyes' flash protection
|
||||
to_chat(user, "We adjust our eyes to protect them from bright lights.")
|
||||
action.Grant(user)
|
||||
else
|
||||
to_chat(user, "We can't adjust our eyes if we don't have any!")
|
||||
|
||||
@@ -42,6 +46,7 @@
|
||||
|
||||
|
||||
/obj/effect/proc_holder/changeling/augmented_eyesight/on_refund(mob/user) //Get rid of X-ray vision and flash protection when the user refunds this ability
|
||||
action.Remove(user)
|
||||
var/obj/item/organ/eyes/E = user.getorganslot(ORGAN_SLOT_EYES)
|
||||
if(E)
|
||||
if (active)
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
loudness = 1
|
||||
dna_cost = 2
|
||||
req_human = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_freedom"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/biodegrade/sting_action(mob/living/carbon/human/user)
|
||||
var/used = FALSE // only one form of shackles removed per use
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
dna_cost = 2
|
||||
chemical_cost = 25
|
||||
req_human = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_camouflage"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/chameleon_skin/sting_action(mob/user)
|
||||
var/mob/living/carbon/human/H = user //SHOULD always be human, because req_human = 1
|
||||
@@ -18,6 +21,7 @@
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/changeling/chameleon_skin/on_refund(mob/user)
|
||||
action.Remove(user)
|
||||
if(user.has_dna())
|
||||
var/mob/living/carbon/C = user
|
||||
var/datum/mutation/human/HM = GLOB.mutations_list[CHAMELEON]
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
helptext = "We cannot be tracked by camera or seen by AI units while using this skill. However, humans looking at us will find us... uncanny. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat."
|
||||
dna_cost = 1
|
||||
loudness = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_digital_camo"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
//Prevents AIs tracking you but makes you easily detectable to the human-eye.
|
||||
/obj/effect/proc_holder/changeling/digitalcamo/sting_action(mob/user)
|
||||
@@ -19,5 +22,6 @@
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/changeling/digitalcamo/on_refund(mob/user)
|
||||
action.Remove(user)
|
||||
user.digitalcamo = 0
|
||||
user.digitalinvis = 0
|
||||
@@ -6,6 +6,9 @@
|
||||
req_dna = 1
|
||||
req_stat = DEAD
|
||||
ignores_fakedeath = TRUE
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_regenerative_stasis"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
//Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay.
|
||||
/obj/effect/proc_holder/changeling/fakedeath/sting_action(mob/living/user)
|
||||
@@ -25,7 +28,9 @@
|
||||
var/datum/antagonist/changeling/C = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(C && C.purchasedpowers)
|
||||
to_chat(user, "<span class='notice'>We are ready to revive.</span>")
|
||||
C.purchasedpowers += new /obj/effect/proc_holder/changeling/revive(null)
|
||||
var/obj/effect/proc_holder/changeling/revive/RV = new /obj/effect/proc_holder/changeling/revive(null)
|
||||
C.purchasedpowers += RV
|
||||
RV.action.Grant(user)
|
||||
|
||||
/obj/effect/proc_holder/changeling/fakedeath/can_sting(mob/living/user)
|
||||
if(user.has_trait(TRAIT_DEATHCOMA, "changeling"))
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
chemical_cost = 20
|
||||
dna_cost = 2
|
||||
req_stat = UNCONSCIOUS
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_fleshmend"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
//Starts healing you every second for 10 seconds.
|
||||
//Can be used whilst unconscious.
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
dna_cost = 1
|
||||
loudness = 2
|
||||
req_human = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_explode"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/headcrab/sting_action(mob/user)
|
||||
set waitfor = FALSE
|
||||
|
||||
@@ -5,6 +5,16 @@
|
||||
helptext = "We will be able to talk with other changelings with :g. Exchanged DNA do not count towards absorb objectives."
|
||||
dna_cost = 1
|
||||
chemical_cost = -1
|
||||
action_icon = 'icons/mob/actions/actions_xeno.dmi'
|
||||
action_icon_state = "alien_whisper"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_comms/sting_action(var/mob/living/user)
|
||||
if (user.has_trait(CHANGELING_HIVEMIND_MUTE))
|
||||
to_chat(user, "<span class='warning'>The poison in the air hinders our ability to interact with the hivemind.</span>")
|
||||
return
|
||||
var/input = stripped_input(usr, "Please choose a message to transmit.", "Changeling Hivemind", "")
|
||||
user.say(".g[input]")
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_comms/on_purchase(mob/user, is_respec)
|
||||
..()
|
||||
@@ -14,12 +24,15 @@
|
||||
var/obj/effect/proc_holder/changeling/hivemind_upload/S1 = new
|
||||
if(!changeling.has_sting(S1))
|
||||
changeling.purchasedpowers+=S1
|
||||
S1.action.Grant(user)
|
||||
var/obj/effect/proc_holder/changeling/hivemind_download/S2 = new
|
||||
if(!changeling.has_sting(S2))
|
||||
changeling.purchasedpowers+=S2
|
||||
S2.action.Grant(user)
|
||||
var/obj/effect/proc_holder/changeling/linglink/S3 = new
|
||||
if(!changeling.has_sting(S3))
|
||||
changeling.purchasedpowers+=S3
|
||||
S3.action.Grant(user)
|
||||
|
||||
// HIVE MIND UPLOAD/DOWNLOAD DNA
|
||||
GLOBAL_LIST_EMPTY(hivemind_bank)
|
||||
@@ -29,6 +42,9 @@ GLOBAL_LIST_EMPTY(hivemind_bank)
|
||||
desc = "Allows us to channel DNA in the airwaves to allow other changelings to absorb it."
|
||||
chemical_cost = 10
|
||||
dna_cost = -1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_upload"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_upload/sting_action(var/mob/living/user)
|
||||
if (user.has_trait(CHANGELING_HIVEMIND_MUTE))
|
||||
@@ -63,6 +79,9 @@ GLOBAL_LIST_EMPTY(hivemind_bank)
|
||||
desc = "Allows us to absorb DNA that has been channeled to the airwaves. Does not count towards absorb objectives."
|
||||
chemical_cost = 10
|
||||
dna_cost = -1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_download"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_download/can_sting(mob/living/carbon/user)
|
||||
if(!..())
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
desc = "We change into a human."
|
||||
chemical_cost = 5
|
||||
req_dna = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_human"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
//Transform into a human.
|
||||
/obj/effect/proc_holder/changeling/humanform/sting_action(mob/living/carbon/user)
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
dna_cost = 1
|
||||
loudness = 2
|
||||
req_human = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_lesser"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
//Transform into a monkey.
|
||||
/obj/effect/proc_holder/changeling/lesserform/sting_action(mob/living/carbon/human/user)
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
chemical_cost = 0
|
||||
dna_cost = -1
|
||||
req_human = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_link"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/linglink/can_sting(mob/living/carbon/user)
|
||||
if(!..())
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
chemical_cost = 0 //constant chemical drain hardcoded
|
||||
dna_cost = 1
|
||||
req_human = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_mimic_voice"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
|
||||
// Fake Voice
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
return W
|
||||
|
||||
/obj/effect/proc_holder/changeling/weapon/on_refund(mob/user)
|
||||
action.Remove(user)
|
||||
for(var/obj/item/I in user.held_items)
|
||||
check_weapon(user, I)
|
||||
|
||||
@@ -105,6 +106,7 @@
|
||||
/obj/effect/proc_holder/changeling/suit/on_refund(mob/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
action.Remove(user)
|
||||
var/mob/living/carbon/human/H = user
|
||||
check_suit(H)
|
||||
|
||||
@@ -141,6 +143,9 @@
|
||||
req_human = 1
|
||||
weapon_type = /obj/item/melee/arm_blade
|
||||
weapon_name_simple = "blade"
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_armblade"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/item/melee/arm_blade
|
||||
name = "arm blade"
|
||||
@@ -225,6 +230,9 @@
|
||||
weapon_type = /obj/item/gun/magic/tentacle
|
||||
weapon_name_simple = "tentacle"
|
||||
silent = TRUE
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_tentacle"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/item/gun/magic/tentacle
|
||||
name = "tentacle"
|
||||
@@ -401,6 +409,9 @@
|
||||
dna_cost = 1
|
||||
loudness = 1
|
||||
req_human = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_shield"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
weapon_type = /obj/item/shield/changeling
|
||||
weapon_name_simple = "shield"
|
||||
@@ -454,6 +465,9 @@
|
||||
dna_cost = 2
|
||||
loudness = 1
|
||||
req_human = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_space_suit"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
suit_type = /obj/item/clothing/suit/space/changeling
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/changeling
|
||||
@@ -503,6 +517,9 @@
|
||||
loudness = 2
|
||||
req_human = 1
|
||||
recharge_slowdown = 0.25
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_armor"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
suit_type = /obj/item/clothing/suit/armor/changeling
|
||||
helmet_type = /obj/item/clothing/head/helmet/changeling
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
chemical_cost = 20
|
||||
dna_cost = 1
|
||||
req_stat = UNCONSCIOUS
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_anatomic_panacea"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
//Heals the things that the other regenerative abilities don't.
|
||||
/obj/effect/proc_holder/changeling/panacea/sting_action(mob/user)
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
chemical_cost = 0 //Reduces regain rate while active.
|
||||
dna_cost = 2
|
||||
var/receptors_active = FALSE
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_pheromone"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/pheromone_receptors/sting_action(mob/living/carbon/user)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
chemical_cost = 10
|
||||
dna_cost = 0
|
||||
req_stat = UNCONSCIOUS
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_regenerate"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/regenerate/sting_action(mob/living/user)
|
||||
to_chat(user, "<span class='notice'>You feel an itching, both inside and \
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
req_stat = DEAD
|
||||
always_keep = TRUE
|
||||
ignores_fakedeath = TRUE
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_revive"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
//Revive from revival stasis
|
||||
/obj/effect/proc_holder/changeling/revive/sting_action(mob/living/carbon/user)
|
||||
@@ -26,6 +29,7 @@
|
||||
to_chat(user, "<span class='notice'>We have revived ourselves.</span>")
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
changeling.purchasedpowers -= src
|
||||
src.action.Remove(user)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/changeling/revive/can_be_used_by(mob/living/user)
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
dna_cost = 1
|
||||
loudness = 1
|
||||
req_human = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_resonant"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
//A flashy ability, good for crowd control and sewing chaos.
|
||||
/obj/effect/proc_holder/changeling/resonant_shriek/sting_action(mob/user)
|
||||
@@ -36,6 +39,9 @@
|
||||
chemical_cost = 20
|
||||
dna_cost = 1
|
||||
loudness = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_dissonant"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
//A flashy ability, good for crowd control and sewing chaos.
|
||||
/obj/effect/proc_holder/changeling/dissonant_shriek/sting_action(mob/user)
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
dna_cost = 1
|
||||
loudness = 4
|
||||
req_absorbs = 3
|
||||
action_icon = 'icons/effects/effects.dmi'
|
||||
action_icon_state = "spiderling"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
//Makes some spiderlings. Good for setting traps and causing general trouble.
|
||||
/obj/effect/proc_holder/changeling/spiders/sting_action(mob/user)
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
req_human = 1
|
||||
var/stacks = 0 //Increments every 5 seconds; damage increases over time
|
||||
active = 0 //Whether or not you are a hedgehog
|
||||
action_icon = 'icons/obj/implants.dmi'
|
||||
action_icon_state = "adrenal"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/strained_muscles/sting_action(mob/living/carbon/user)
|
||||
active = !active
|
||||
|
||||
@@ -70,6 +70,9 @@
|
||||
dna_cost = 3
|
||||
loudness = 1
|
||||
var/datum/changelingprofile/selected_dna = null
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_sting_transform"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/transformation/Click()
|
||||
var/mob/user = usr
|
||||
@@ -117,6 +120,9 @@
|
||||
chemical_cost = 20
|
||||
dna_cost = 1
|
||||
loudness = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_sting_fake"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/item/melee/arm_blade/false
|
||||
desc = "A grotesque mass of flesh that used to be your arm. Although it looks dangerous at first, you can tell it's actually quite dull and useless."
|
||||
@@ -169,6 +175,9 @@
|
||||
sting_icon = "sting_extract"
|
||||
chemical_cost = 25
|
||||
dna_cost = 0
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_sting_extract"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/extract_dna/can_sting(mob/user, mob/target)
|
||||
if(..())
|
||||
@@ -190,6 +199,9 @@
|
||||
chemical_cost = 20
|
||||
dna_cost = 2
|
||||
loudness = 2
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_sting_mute"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/mute/sting_action(mob/user, mob/living/carbon/target)
|
||||
log_combat(user, target, "stung", "mute sting")
|
||||
@@ -204,6 +216,9 @@
|
||||
chemical_cost = 25
|
||||
dna_cost = 1
|
||||
loudness = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_sting_blind"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/blind/sting_action(mob/user, mob/living/carbon/target)
|
||||
log_combat(user, target, "stung", "blind sting")
|
||||
@@ -220,6 +235,9 @@
|
||||
sting_icon = "sting_lsd"
|
||||
chemical_cost = 10
|
||||
dna_cost = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_sting_lsd"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/LSD/sting_action(mob/user, mob/living/carbon/target)
|
||||
log_combat(user, target, "stung", "LSD sting")
|
||||
@@ -238,6 +256,9 @@
|
||||
chemical_cost = 15
|
||||
dna_cost = 2
|
||||
loudness = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_sting_cryo"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/cryo/sting_action(mob/user, mob/target)
|
||||
log_combat(user, target, "stung", "cryo sting")
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
dna_cost = 0
|
||||
req_dna = 1
|
||||
req_human = 1
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_transform"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/item/clothing/glasses/changeling
|
||||
name = "flesh"
|
||||
|
||||
@@ -112,7 +112,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
var/list/invokers = list() //people eligible to invoke the rune
|
||||
if(user)
|
||||
invokers += user
|
||||
if(req_cultists > 1 || istype(src, /obj/effect/rune/convert))
|
||||
if(req_cultists > 1 || istype(src, /obj/effect/rune/narsie) || istype(src, /obj/effect/rune/convert))
|
||||
var/list/things_in_range = range(1, src)
|
||||
var/obj/item/toy/plush/narplush/plushsie = locate() in things_in_range
|
||||
if(istype(plushsie) && plushsie.is_invoker)
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
reagentsAmount = 250
|
||||
|
||||
/datum/round_event_control/vent_clog/beer
|
||||
name = "Foamy beer stationwide"
|
||||
name = "Clogged Vents: Beer"
|
||||
typepath = /datum/round_event/vent_clog/beer
|
||||
max_occurrences = 0
|
||||
|
||||
@@ -83,12 +83,12 @@
|
||||
reagentsAmount = 100
|
||||
|
||||
/datum/round_event_control/vent_clog/plasma_decon
|
||||
name = "Plasma decontamination"
|
||||
name = "Anti-Plasma Flood"
|
||||
typepath = /datum/round_event/vent_clog/plasma_decon
|
||||
max_occurrences = 0
|
||||
|
||||
/datum/round_event_control/vent_clog/female
|
||||
name = "FemCum stationwide"
|
||||
name = "Clogged Vents; Girlcum"
|
||||
typepath = /datum/round_event/vent_clog/female
|
||||
max_occurrences = 0
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
reagentsAmount = 100
|
||||
|
||||
/datum/round_event_control/vent_clog/male
|
||||
name = "Semen stationwide"
|
||||
name = "Clogged Vents: Semen"
|
||||
typepath = /datum/round_event/vent_clog/male
|
||||
max_occurrences = 0
|
||||
|
||||
@@ -118,6 +118,9 @@
|
||||
foam.start()
|
||||
CHECK_TICK
|
||||
|
||||
/datum/round_event/vent_clog/male/announce()
|
||||
priority_announce("The scrubbers network is experiencing a backpressure surge. Some ejaculation of contents may occur.", "Atmospherics alert")
|
||||
|
||||
/datum/round_event/vent_clog/male/start()
|
||||
for(var/obj/machinery/atmospherics/components/unary/vent in vents)
|
||||
if(vent && vent.loc)
|
||||
@@ -130,6 +133,9 @@
|
||||
foam.start()
|
||||
CHECK_TICK
|
||||
|
||||
/datum/round_event/vent_clog/female/announce()
|
||||
priority_announce("The scrubbers network is experiencing a backpressure squirt. Some ejection of contents may occur.", "Atmospherics alert")
|
||||
|
||||
/datum/round_event/vent_clog/female/start()
|
||||
for(var/obj/machinery/atmospherics/components/unary/vent in vents)
|
||||
if(vent && vent.loc)
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
var/failed_last_breath = 0 //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks.
|
||||
|
||||
var/co2overloadtime = null
|
||||
var/o2overloadtime = null //for Ash walker's weaker lungs, and future atmosia hazards
|
||||
var/temperature_resistance = T0C+75
|
||||
var/obj/item/reagent_containers/food/snacks/meat/slab/type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab
|
||||
|
||||
|
||||
@@ -1143,7 +1143,15 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
H.add_trait(TRAIT_FAT, OBESITY)
|
||||
H.update_inv_w_uniform()
|
||||
H.update_inv_wear_suit()
|
||||
|
||||
|
||||
if(H.noisy && H.nutrition <= NUTRITION_LEVEL_STARVING)
|
||||
if(prob(10))
|
||||
playsound(get_turf(H),"hunger_sounds",35,0,-5,1,ignore_walls = FALSE,channel=CHANNEL_PRED)
|
||||
|
||||
else if(H.noisy && H.nutrition <= NUTRITION_LEVEL_HUNGRY)
|
||||
if(prob(10))
|
||||
playsound(get_turf(H),"hunger_sounds",15,0,-5,1,ignore_walls = FALSE,channel=CHANNEL_PRED)
|
||||
|
||||
// nutrition decrease and satiety
|
||||
if (H.nutrition > 0 && H.stat != DEAD && !H.has_trait(TRAIT_NOHUNGER))
|
||||
// THEY HUNGER
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
id = "ashlizard"
|
||||
limbs_id = "lizard"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,DIGITIGRADE)
|
||||
inherent_traits = list(TRAIT_NOGUNS,TRAIT_NOBREATH)
|
||||
inherent_traits = list(TRAIT_NOGUNS)
|
||||
mutantlungs = /obj/item/organ/lungs/ashwalker
|
||||
burnmod = 0.9
|
||||
brutemod = 0.9
|
||||
@@ -141,6 +141,7 @@
|
||||
return 0
|
||||
|
||||
var/safe_oxy_min = 16
|
||||
var/safe_oxy_max = 50
|
||||
var/safe_co2_max = 10
|
||||
var/safe_tox_max = 0.05
|
||||
var/SA_para_min = 1
|
||||
@@ -156,6 +157,19 @@
|
||||
|
||||
|
||||
//OXYGEN
|
||||
if(O2_partialpressure > safe_oxy_max) // Too much Oxygen - blatant CO2 effect copy/pasta
|
||||
if(!o2overloadtime)
|
||||
o2overloadtime = world.time
|
||||
else if(world.time - o2overloadtime > 120)
|
||||
Dizzy(10) // better than a minute of you're fucked KO, but certainly a wake up call. Honk.
|
||||
adjustOxyLoss(3)
|
||||
if(world.time - o2overloadtime > 300)
|
||||
adjustOxyLoss(8)
|
||||
if(prob(20))
|
||||
emote("cough")
|
||||
throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "suffocation", /datum/mood_event/suffocation)
|
||||
|
||||
if(O2_partialpressure < safe_oxy_min) //Not enough oxygen
|
||||
if(prob(20))
|
||||
emote("gasp")
|
||||
@@ -172,6 +186,7 @@
|
||||
|
||||
else //Enough oxygen
|
||||
failed_last_breath = 0
|
||||
o2overloadtime = 0 //reset our counter for this too
|
||||
if(health >= crit_threshold)
|
||||
adjustOxyLoss(-5)
|
||||
oxygen_used = breath_gases[/datum/gas/oxygen][MOLES]
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
spill_organs(no_brain, no_organs, no_bodyparts)
|
||||
|
||||
release_vore_contents(silent = TRUE) // return of the bomb safe internals.
|
||||
|
||||
if(!no_bodyparts)
|
||||
spread_bodyparts(no_brain, no_organs)
|
||||
|
||||
@@ -36,6 +38,7 @@
|
||||
buckled.unbuckle_mob(src, force = TRUE)
|
||||
|
||||
dust_animation()
|
||||
release_vore_contents(silent = TRUE) //technically grief protection, I guess? if they're SM'd it doesn't matter seconds after anyway.
|
||||
spawn_dust(just_ash)
|
||||
QDEL_IN(src,5) // since this is sometimes called in the middle of movement, allow half a second for movement to finish, ghosting to happen and animation to play. Looks much nicer and doesn't cause multiple runtimes.
|
||||
|
||||
|
||||
@@ -127,8 +127,18 @@
|
||||
IgniteMob()
|
||||
|
||||
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
if(user == src || anchored || !isturf(user.loc))
|
||||
if(user == anchored || !isturf(user.loc))
|
||||
return FALSE
|
||||
|
||||
if(user.pulling && user.grab_state == GRAB_AGGRESSIVE && user.voremode)
|
||||
if(ismob(user.pulling))
|
||||
var/mob/P = user.pulling
|
||||
user.vore_attack(user, P, src) // User, Pulled, Predator target (which can be user, pulling, or src)
|
||||
return
|
||||
|
||||
if(user == src) //we want to be able to self click if we're voracious
|
||||
return FALSE
|
||||
|
||||
if(!user.pulling || user.pulling != src)
|
||||
user.start_pulling(src, supress_message)
|
||||
return
|
||||
@@ -163,6 +173,8 @@
|
||||
return 0
|
||||
if(!user.pulling || user.pulling != src || user.grab_state != old_grab_state || user.a_intent != INTENT_GRAB)
|
||||
return 0
|
||||
if(user.voremode && user.grab_state == GRAB_AGGRESSIVE)
|
||||
return 0
|
||||
user.grab_state++
|
||||
switch(user.grab_state)
|
||||
if(GRAB_AGGRESSIVE)
|
||||
|
||||
@@ -63,6 +63,9 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/mouse/handle_automated_action()
|
||||
if(isbelly(loc))
|
||||
return
|
||||
|
||||
if(prob(chew_probability))
|
||||
var/turf/open/floor/F = get_turf(src)
|
||||
if(istype(F) && !F.intact)
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
if(!target || !isturf(target.loc) || !isturf(loc) || stat == DEAD)
|
||||
return
|
||||
var/target_dir = get_dir(src,target)
|
||||
|
||||
|
||||
var/static/list/cardinal_sidestep_directions = list(-90,-45,0,45,90)
|
||||
var/static/list/diagonal_sidestep_directions = list(-45,0,45)
|
||||
var/chosen_dir = 0
|
||||
@@ -202,6 +202,8 @@
|
||||
|
||||
if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
|
||||
return FALSE
|
||||
if(isbelly(the_target.loc)) //Target's inside a gut, forget about it too
|
||||
return FALSE
|
||||
if(search_objects < 2)
|
||||
if(isliving(the_target))
|
||||
var/mob/living/L = the_target
|
||||
@@ -301,7 +303,7 @@
|
||||
if(target)
|
||||
if(targets_from && isturf(targets_from.loc) && target.Adjacent(targets_from)) //If they're next to us, attack
|
||||
MeleeAction()
|
||||
else
|
||||
else
|
||||
if(rapid_melee > 1 && target_distance <= melee_queue_distance)
|
||||
MeleeAction(FALSE)
|
||||
in_melee = FALSE //If we're just preparing to strike do not enter sidestep mode
|
||||
|
||||
@@ -83,18 +83,12 @@
|
||||
if(L.stat != DEAD)
|
||||
if(!client && ranged && ranged_cooldown <= world.time)
|
||||
OpenFire()
|
||||
|
||||
else if(L.stat >= SOFT_CRIT)
|
||||
if(vore_active == TRUE && L.devourable == TRUE)
|
||||
if(isliving(target) && !target.Adjacent(targets_from))
|
||||
return
|
||||
else
|
||||
if(L.Adjacent(src) && (L.stat != CONSCIOUS))
|
||||
if(vore_active && L.devourable == TRUE)
|
||||
dragon_feeding(src,L)
|
||||
if(L.loc == src.contents)
|
||||
LoseTarget()
|
||||
return 0
|
||||
else
|
||||
devour(L)
|
||||
LoseTarget()
|
||||
else
|
||||
devour(L)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/proc/devour(mob/living/L)
|
||||
if(!L)
|
||||
|
||||
@@ -96,7 +96,9 @@
|
||||
mind.transfer_to(O)
|
||||
var/datum/antagonist/changeling/changeling = O.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(changeling)
|
||||
changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null)
|
||||
var/obj/effect/proc_holder/changeling/humanform/HF = new /obj/effect/proc_holder/changeling/humanform(null)
|
||||
changeling.purchasedpowers += HF
|
||||
HF.action.Grant(O)
|
||||
|
||||
for(var/X in internal_organs)
|
||||
var/obj/item/organ/I = X
|
||||
@@ -129,8 +131,9 @@
|
||||
mind.transfer_to(O)
|
||||
var/datum/antagonist/changeling/changeling = O.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(changeling)
|
||||
changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null)
|
||||
|
||||
var/obj/effect/proc_holder/changeling/humanform/HF = new /obj/effect/proc_holder/changeling/humanform(null)
|
||||
changeling.purchasedpowers += HF
|
||||
HF.action.Grant(O)
|
||||
|
||||
if (tr_flags & TR_DEFAULTMSG)
|
||||
to_chat(O, "<B>You are now a monkey.</B>")
|
||||
|
||||
@@ -1251,7 +1251,7 @@
|
||||
L.remove_trait(TRAIT_SLEEPIMMUNE, id)
|
||||
..()
|
||||
|
||||
/datum/reagent/stimulum/on_mob_life(mob/living/carbon/M)
|
||||
/datum/reagent/stimulum/on_mob_life(mob/living/carbon/M)
|
||||
M.adjustStaminaLoss(-2*REM, 0)
|
||||
current_cycle++
|
||||
holder.remove_reagent(id, 0.99) //Gives time for the next tick of life().
|
||||
|
||||
@@ -3,23 +3,25 @@
|
||||
id = "reagent_explosion"
|
||||
var/strengthdiv = 10
|
||||
var/modifier = 0
|
||||
var/noexplosion = FALSE
|
||||
|
||||
/datum/chemical_reaction/reagent_explosion/on_reaction(datum/reagents/holder, created_volume)
|
||||
var/turf/T = get_turf(holder.my_atom)
|
||||
var/inside_msg
|
||||
if(ismob(holder.my_atom))
|
||||
var/mob/M = holder.my_atom
|
||||
inside_msg = " inside [ADMIN_LOOKUPFLW(M)]"
|
||||
var/lastkey = holder.my_atom.fingerprintslast
|
||||
var/touch_msg = "N/A"
|
||||
if(lastkey)
|
||||
var/mob/toucher = get_mob_by_key(lastkey)
|
||||
touch_msg = "[ADMIN_LOOKUPFLW(toucher)]"
|
||||
message_admins("Reagent explosion reaction occurred at [ADMIN_VERBOSEJMP(T)][inside_msg]. Last Fingerprint: [touch_msg].")
|
||||
log_game("Reagent explosion reaction occurred at [AREACOORD(T)]. Last Fingerprint: [lastkey ? lastkey : "N/A"]." )
|
||||
var/datum/effect_system/reagents_explosion/e = new()
|
||||
e.set_up(modifier + round(created_volume/strengthdiv, 1), T, 0, 0)
|
||||
e.start()
|
||||
/datum/chemical_reaction/reagent_explosion/on_reaction(datum/reagents/holder, created_volume, turf/override)
|
||||
if(!noexplosion)
|
||||
var/turf/T = override || get_turf(holder.my_atom)
|
||||
var/inside_msg
|
||||
if(ismob(holder.my_atom))
|
||||
var/mob/M = holder.my_atom
|
||||
inside_msg = " inside [ADMIN_LOOKUPFLW(M)]"
|
||||
var/lastkey = holder.my_atom.fingerprintslast
|
||||
var/touch_msg = "N/A"
|
||||
if(lastkey)
|
||||
var/mob/toucher = get_mob_by_key(lastkey)
|
||||
touch_msg = "[ADMIN_LOOKUPFLW(toucher)]"
|
||||
message_admins("Reagent explosion reaction occurred at [ADMIN_VERBOSEJMP(T)][inside_msg]. Last Fingerprint: [touch_msg].")
|
||||
log_game("Reagent explosion reaction occurred at [AREACOORD(T)]. Last Fingerprint: [lastkey ? lastkey : "N/A"]." )
|
||||
var/datum/effect_system/reagents_explosion/e = new()
|
||||
e.set_up(modifier + round(created_volume/strengthdiv, 1), T, 0, 0)
|
||||
e.start()
|
||||
holder.clear_reagents()
|
||||
|
||||
|
||||
@@ -56,6 +58,7 @@
|
||||
required_reagents = list("holywater" = 1, "potassium" = 1)
|
||||
|
||||
/datum/chemical_reaction/reagent_explosion/potassium_explosion/holyboom/on_reaction(datum/reagents/holder, created_volume)
|
||||
var/turf/T = get_turf(holder.my_atom)
|
||||
if(created_volume >= 150)
|
||||
playsound(get_turf(holder.my_atom), 'sound/effects/pray.ogg', 80, 0, round(created_volume/48))
|
||||
strengthdiv = 8
|
||||
@@ -76,7 +79,7 @@
|
||||
C.Knockdown(40)
|
||||
C.adjust_fire_stacks(5)
|
||||
C.IgniteMob()
|
||||
..()
|
||||
..(holder, created_volume, T)
|
||||
|
||||
|
||||
/datum/chemical_reaction/blackpowder
|
||||
@@ -95,8 +98,9 @@
|
||||
mix_message = "<span class='boldannounce'>Sparks start flying around the black powder!</span>"
|
||||
|
||||
/datum/chemical_reaction/reagent_explosion/blackpowder_explosion/on_reaction(datum/reagents/holder, created_volume)
|
||||
var/turf/T = get_turf(holder.my_atom)
|
||||
sleep(rand(50,100))
|
||||
..()
|
||||
..(holder, created_volume, T)
|
||||
|
||||
/datum/chemical_reaction/thermite
|
||||
name = "Thermite"
|
||||
@@ -423,6 +427,7 @@
|
||||
required_reagents = list("teslium" = 1, "water" = 1)
|
||||
strengthdiv = 100
|
||||
modifier = -100
|
||||
noexplosion = TRUE
|
||||
mix_message = "<span class='boldannounce'>The teslium starts to spark as electricity arcs away from it!</span>"
|
||||
mix_sound = 'sound/machines/defib_zap.ogg'
|
||||
var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/revive
|
||||
name = "repair body"
|
||||
name = "electrically stimulate brain"
|
||||
implements = list(/obj/item/twohanded/shockpaddles = 100, /obj/item/abductor/gizmo = 100, /obj/item/melee/baton = 75, /obj/item/organ/cyberimp/arm/baton = 75, /obj/item/organ/cyberimp/arm/gun/taser = 60, /obj/item/gun/energy/e_gun/advtaser = 60, /obj/item/gun/energy/taser = 60)
|
||||
time = 120
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
//Breath damage
|
||||
|
||||
var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa
|
||||
var/safe_oxygen_max = 0
|
||||
var/safe_oxygen_max = 50 // Too much of a good thing, in kPa as well.
|
||||
var/safe_nitro_min = 0
|
||||
var/safe_nitro_max = 0
|
||||
var/safe_co2_min = 0
|
||||
@@ -97,11 +97,25 @@
|
||||
|
||||
//Too much oxygen! //Yes, some species may not like it.
|
||||
if(safe_oxygen_max)
|
||||
if(O2_pp > safe_oxygen_max)
|
||||
if((O2_pp > safe_oxygen_max) && safe_oxygen_max == 0) //I guess plasma men technically need to have a check.
|
||||
var/ratio = (breath_gases[/datum/gas/oxygen][MOLES]/safe_oxygen_max) * 10
|
||||
H.apply_damage_type(CLAMP(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type)
|
||||
H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy)
|
||||
|
||||
else if((O2_pp > safe_oxygen_max) && !(safe_oxygen_max == 0)) //Why yes, this is like too much CO2 and spahget. Dirty lizards.
|
||||
if(!H.o2overloadtime)
|
||||
H.o2overloadtime = world.time
|
||||
else if(world.time - H.o2overloadtime > 120)
|
||||
H.Dizzy(10) // better than a minute of you're fucked KO, but certainly a wake up call. Honk.
|
||||
H.adjustOxyLoss(3)
|
||||
if(world.time - H.o2overloadtime > 300)
|
||||
H.adjustOxyLoss(8)
|
||||
if(prob(20))
|
||||
H.emote("cough")
|
||||
H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy)
|
||||
|
||||
else
|
||||
H.o2overloadtime = 0
|
||||
H.clear_alert("too_much_oxy")
|
||||
|
||||
//Too little oxygen!
|
||||
@@ -129,6 +143,7 @@
|
||||
var/ratio = (breath_gases[/datum/gas/nitrogen][MOLES]/safe_nitro_max) * 10
|
||||
H.apply_damage_type(CLAMP(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type)
|
||||
H.throw_alert("too_much_nitro", /obj/screen/alert/too_much_nitro)
|
||||
H.losebreath += 2
|
||||
else
|
||||
H.clear_alert("too_much_nitro")
|
||||
|
||||
@@ -385,6 +400,7 @@
|
||||
icon_state = "lungs-plasma"
|
||||
|
||||
safe_oxygen_min = 0 //We don't breath this
|
||||
safe_oxygen_max = 0 // Like, at all.
|
||||
safe_toxins_min = 16 //We breath THIS!
|
||||
safe_toxins_max = 0
|
||||
|
||||
@@ -407,7 +423,24 @@
|
||||
icon_state = "lungs-c-u"
|
||||
safe_toxins_max = 20
|
||||
safe_co2_max = 20
|
||||
safe_oxygen_max = 250
|
||||
|
||||
cold_level_1_threshold = 200
|
||||
cold_level_2_threshold = 140
|
||||
cold_level_3_threshold = 100
|
||||
|
||||
/obj/item/organ/lungs/ashwalker
|
||||
name = "ash lungs"
|
||||
desc = "blackened lungs identical from specimens recovered from lavaland, unsuited to higher air pressures."
|
||||
icon_state = "lungs-ll"
|
||||
safe_oxygen_min = 3 //able to handle much thinner oxygen, something something ash storm adaptation
|
||||
safe_oxygen_max = 18 // Air standard is 22kpA of O2, LL is 14kpA
|
||||
safe_nitro_max = 28 // Air standard is 82kpA of N2, LL is 23kpA
|
||||
|
||||
cold_level_1_threshold = 280 // Ash Lizards can't take the cold very well, station air is only just warm enough
|
||||
cold_level_2_threshold = 240
|
||||
cold_level_3_threshold = 200
|
||||
|
||||
heat_level_1_threshold = 400 // better adapted for heat, obv. Lavaland standard is 300
|
||||
heat_level_2_threshold = 600 // up 200 from level 1, 1000 is silly but w/e for level 3
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
author: "Poojawa"
|
||||
delete-after: True
|
||||
changes:
|
||||
- balance: "Ashwalkers now have lungs. They cannot breath station air without suffocation effects, but are completely fine on their homeworld."
|
||||
- balance: "Carbon mobs now have a maximum tolerance to oxygen of 50kPa."
|
||||
- balance: "Deluxe synthetic lungs have a very high bonus to O2 tolerance."
|
||||
@@ -0,0 +1,12 @@
|
||||
author: "Poojawa"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Vore Panel restored to have various interactions available again. Semi-untested but should work as advertised."
|
||||
- tweak: "Vore Panel has more feedback."
|
||||
- rscadd: "is_wet var to bellies, toggled in the panel, will remove flesh sounding struggles and the internal loop. JSON version updated."
|
||||
- rscadd: "Feeding var. You will need to enable feeding to recieve any feed vore actions, but you can now feed yourself to mobs that have this set. TODO, Dogborg sleeper feeding."
|
||||
- rscadd: "vore mode button now required to be enabled to perform vore actions. It's the mouth icon!"
|
||||
- bugfix: "Ash Drake vore fixed for actual reals this time"
|
||||
- bugfix: "Mobs shouldn't spam the released contents announcement anymore on qdel or death. Only if triggered"
|
||||
- tweak: "Hostile mob code now properly ignores targets in bellies"
|
||||
- rscadd: "Your belly can quietly growl if you're starving now."
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "deathride58"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "The endgame narsie summon rune no longer requires 24 total sacrifices, and will now properly account for cultists that surround it"
|
||||
|
After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
@@ -47,3 +47,21 @@
|
||||
icon_state = "combat"
|
||||
else
|
||||
icon_state = "combat_off"
|
||||
|
||||
/obj/screen/voretoggle
|
||||
name = "toggle vore mode"
|
||||
icon = 'modular_citadel/icons/ui/screen_midnight.dmi'
|
||||
icon_state = "nom_off"
|
||||
|
||||
/obj/screen/voretoggle/Click()
|
||||
if(iscarbon(usr))
|
||||
var/mob/living/carbon/C = usr
|
||||
C.toggle_vore_mode()
|
||||
|
||||
/obj/screen/voretoggle/proc/rebaseintomygut(mob/living/carbon/C)
|
||||
if(!C)
|
||||
return
|
||||
if(C.voremode && !C.combatmode)
|
||||
icon_state = "nom"
|
||||
else
|
||||
icon_state = "nom_off"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/controller/subsystem/shuttle/proc/autoEnd() //CIT CHANGE - allows shift to end after 3 hours has passed.
|
||||
if(world.time > auto_call && EMERGENCY_IDLE_OR_RECALLED) //3 hours
|
||||
if((world.realtime - SSshuttle.realtimeofstart) > auto_call && EMERGENCY_IDLE_OR_RECALLED) //3 hours
|
||||
SSshuttle.emergency.request()
|
||||
priority_announce("The shift has come to an end and the shuttle called.")
|
||||
log_game("Round time limit reached. Shuttle has been auto-called.")
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
var/lastdirchange
|
||||
var/combatmessagecooldown
|
||||
|
||||
//oh no vore time
|
||||
var/voremode = FALSE
|
||||
|
||||
/mob/living/carbon/CanPass(atom/movable/mover, turf/target)
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -19,6 +22,8 @@
|
||||
if(recoveringstam)
|
||||
return TRUE
|
||||
combatmode = !combatmode
|
||||
if(voremode)
|
||||
toggle_vore_mode()
|
||||
if(combatmode)
|
||||
playsound_local(src, 'modular_citadel/sound/misc/ui_toggle.ogg', 50, FALSE, pressure_affected = FALSE) //Sound from interbay!
|
||||
else
|
||||
@@ -34,6 +39,16 @@
|
||||
SEND_SIGNAL(src, COMSIG_COMBAT_TOGGLED, src, combatmode)
|
||||
return TRUE
|
||||
|
||||
mob/living/carbon/proc/toggle_vore_mode()
|
||||
voremode = !voremode
|
||||
if(hud_used && hud_used.static_inventory)
|
||||
for(var/obj/screen/voretoggle/selector in hud_used.static_inventory)
|
||||
selector.rebaseintomygut(src)
|
||||
if(combatmode)
|
||||
return FALSE //let's not override the main draw of the game these days
|
||||
SEND_SIGNAL(src, COMSIG_VORE_TOGGLED, src, voremode)
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/Move(atom/newloc, direct = 0)
|
||||
var/currentdirection = dir
|
||||
. = ..()
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
/mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && isliving(pulling))
|
||||
vore_attack(user, pulling)
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/alt_attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
|
||||
@@ -233,3 +233,5 @@
|
||||
|
||||
/mob/living/carbon/human/vore
|
||||
devourable = TRUE
|
||||
digestable = TRUE
|
||||
feeding = TRUE
|
||||
|
||||
@@ -37,11 +37,6 @@
|
||||
..()
|
||||
dir = pick(1,2,4,8)
|
||||
|
||||
/datum/reagent/consumable/semen/reaction_turf(turf/T, reac_volume)
|
||||
if(!isspaceturf(T))
|
||||
var/obj/effect/decal/cleanable/reagentdecal = new/obj/effect/decal/cleanable/semen(T)
|
||||
reagentdecal.reagents.add_reagent("semen", reac_volume)
|
||||
|
||||
/datum/reagent/consumable/femcum
|
||||
name = "Female Ejaculate"
|
||||
id = "femcum"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
desc = "It's a belly! You're in it!" // Flavor text description of inside sight/sound/smells/feels.
|
||||
var/vore_sound = "Gulp" // Sound when ingesting someone
|
||||
var/vore_verb = "ingest" // Verb for eating with this in messages
|
||||
var/release_sound = "Splatter"
|
||||
var/release_sound = "Splatter" // Sound for letting someone out.
|
||||
var/human_prey_swallow_time = 100 // Time in deciseconds to swallow /mob/living/carbon/human
|
||||
var/nonhuman_prey_swallow_time = 30 // Time in deciseconds to swallow anything else
|
||||
var/emote_time = 60 SECONDS // How long between stomach emotes at prey
|
||||
@@ -26,18 +26,18 @@
|
||||
var/escapetime = 20 SECONDS // Deciseconds, how long to escape this belly
|
||||
var/digestchance = 0 // % Chance of stomach beginning to digest if prey struggles
|
||||
var/absorbchance = 0 // % Chance of stomach beginning to absorb if prey struggles
|
||||
var/escapechance = 100 // % Chance of prey beginning to escape if prey struggles.
|
||||
var/escapechance = 0 // % Chance of prey beginning to escape if prey struggles.
|
||||
var/can_taste = FALSE // If this belly prints the flavor of prey when it eats someone.
|
||||
var/bulge_size = 0.25 // The minimum size the prey has to be in order to show up on examine.
|
||||
// var/shrink_grow_size = 1 // This horribly named variable determines the minimum/maximum size it will shrink/grow prey to.
|
||||
var/silent = FALSE
|
||||
|
||||
var/transferlocation = null // Location that the prey is released if they struggle and get dropped off.
|
||||
var/transferlocation // Location that the prey is released if they struggle and get dropped off.
|
||||
var/transferchance = 0 // % Chance of prey being transferred to transfer location when resisting
|
||||
var/autotransferchance = 0 // % Chance of prey being autotransferred to transfer location
|
||||
var/autotransferwait = 10 // Time between trying to transfer.
|
||||
var/swallow_time = 10 SECONDS // for mob transfering automation
|
||||
var/vore_capacity = 1 // simple animal nom capacity
|
||||
var/is_wet = TRUE // Is this belly inside slimy parts?
|
||||
|
||||
//I don't think we've ever altered these lists. making them static until someone actually overrides them somewhere.
|
||||
var/tmp/static/list/digest_modes = list(DM_HOLD,DM_DIGEST,DM_HEAL,DM_NOISY,DM_ABSORB,DM_UNABSORB) // Possible digest modes
|
||||
@@ -126,7 +126,6 @@
|
||||
"escapechance",
|
||||
"can_taste",
|
||||
"bulge_size",
|
||||
"silent",
|
||||
"transferlocation",
|
||||
"transferchance",
|
||||
"autotransferchance",
|
||||
@@ -138,7 +137,8 @@
|
||||
"digest_messages_owner",
|
||||
"digest_messages_prey",
|
||||
"examine_messages",
|
||||
"emote_lists"
|
||||
"emote_lists",
|
||||
"is_wet"
|
||||
)
|
||||
|
||||
//ommitted list
|
||||
@@ -167,10 +167,11 @@
|
||||
to_chat(owner,"<span class='notice'>[thing] slides into your [lowertext(name)].</span>")
|
||||
|
||||
//Sound w/ antispam flag setting
|
||||
if(!silent && !recent_sound)
|
||||
for(var/mob/M in get_hearers_in_view(5, get_turf(owner)))
|
||||
if(is_wet && !recent_sound)
|
||||
for(var/mob/M in get_hearers_in_view(2, get_turf(owner)))
|
||||
if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES))
|
||||
playsound(get_turf(owner),"[src.vore_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
|
||||
var/sound/devourments = GLOB.vore_sounds[vore_sound]
|
||||
playsound(get_turf(owner),devourments,50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
|
||||
recent_sound = TRUE
|
||||
|
||||
//Messages if it's a mob
|
||||
@@ -182,8 +183,12 @@
|
||||
// Release all contents of this belly into the owning mob's location.
|
||||
// If that location is another mob, contents are transferred into whichever of its bellies the owning mob is in.
|
||||
// Returns the number of mobs so released.
|
||||
/obj/belly/proc/release_all_contents(var/include_absorbed = FALSE)
|
||||
/obj/belly/proc/release_all_contents(var/include_absorbed = FALSE, var/silent = FALSE)
|
||||
var/atom/destination = drop_location()
|
||||
//Don't bother if we don't have contents
|
||||
if(!contents.len)
|
||||
return 0
|
||||
|
||||
var/count = 0
|
||||
for(var/thing in contents)
|
||||
var/atom/movable/AM = thing
|
||||
@@ -201,9 +206,16 @@
|
||||
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "emptyprey", /datum/mood_event/emptyprey)
|
||||
AM.forceMove(destination) // Move the belly contents into the same location as belly's owner.
|
||||
count++
|
||||
for(var/mob/M in get_hearers_in_view(5, get_turf(owner)))
|
||||
for(var/mob/M in get_hearers_in_view(2, get_turf(owner)))
|
||||
if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES))
|
||||
playsound(get_turf(owner),"[src.release_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
|
||||
var/sound/releasement = GLOB.release_sounds[release_sound]
|
||||
playsound(get_turf(owner),releasement,50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
|
||||
|
||||
//Clean up our own business
|
||||
items_preserved.Cut()
|
||||
if(isanimal(owner))
|
||||
owner.update_icons()
|
||||
|
||||
if(!silent)
|
||||
owner.visible_message("<font color='green'><b>[owner] expels everything from their [lowertext(name)]!</b></font>")
|
||||
items_preserved.Cut()
|
||||
@@ -214,16 +226,16 @@
|
||||
// Release a specific atom from the contents of this belly into the owning mob's location.
|
||||
// If that location is another mob, the atom is transferred into whichever of its bellies the owning mob is in.
|
||||
// Returns the number of atoms so released.
|
||||
/obj/belly/proc/release_specific_contents(var/atom/movable/M)
|
||||
/obj/belly/proc/release_specific_contents(var/atom/movable/M, var/silent = FALSE)
|
||||
if (!(M in contents))
|
||||
return FALSE // They weren't in this belly anyway
|
||||
|
||||
M.forceMove(drop_location()) // Move the belly contents into the same location as belly's owner.
|
||||
items_preserved -= M
|
||||
if(release_sound)
|
||||
for(var/mob/H in get_hearers_in_view(5, get_turf(owner)))
|
||||
if(H.client && (H.client.prefs.cit_toggles & EATING_NOISES))
|
||||
playsound(get_turf(owner),"[src.release_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
|
||||
for(var/mob/H in get_hearers_in_view(2, get_turf(owner)))
|
||||
if(H.client && (H.client.prefs.cit_toggles & EATING_NOISES))
|
||||
var/sound/releasement = GLOB.release_sounds[release_sound]
|
||||
playsound(get_turf(owner),releasement,50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
|
||||
|
||||
if(istype(M,/mob/living))
|
||||
var/mob/living/ML = M
|
||||
@@ -245,6 +257,11 @@
|
||||
if(P.absorbed)
|
||||
absorbed_count++
|
||||
Pred.reagents.trans_to(Prey, Pred.reagents.total_volume / absorbed_count)
|
||||
|
||||
//Clean up our own business
|
||||
if(isanimal(owner))
|
||||
owner.update_icons()
|
||||
|
||||
if(!silent)
|
||||
owner.visible_message("<font color='green'><b>[owner] expels [M] from their [lowertext(name)]!</b></font>")
|
||||
owner.update_icons()
|
||||
@@ -268,8 +285,10 @@
|
||||
|
||||
prey.forceMove(src)
|
||||
var/sound/preyloop = sound('sound/vore/prey/loop.ogg', repeat = TRUE)
|
||||
if(!silent)
|
||||
|
||||
if(is_wet)
|
||||
prey.playsound_local(loc,preyloop,70,0, channel = CHANNEL_PREYLOOP)
|
||||
|
||||
owner.updateVRPanel()
|
||||
|
||||
for(var/mob/living/M in contents)
|
||||
@@ -299,7 +318,8 @@
|
||||
if(!silent)
|
||||
for(var/mob/M in get_hearers_in_view(5, get_turf(owner)))
|
||||
if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES))
|
||||
playsound(get_turf(owner),"[src.vore_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
|
||||
var/sound/devourments = GLOB.vore_sounds[vore_sound]
|
||||
playsound(get_turf(owner),devourments,50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
|
||||
owner.updateVRPanel()
|
||||
for(var/mob/living/M in contents)
|
||||
M.updateVRPanel()
|
||||
@@ -461,6 +481,9 @@
|
||||
//Yes, it's ""safe"" to drop items here
|
||||
/obj/belly/AllowDrop()
|
||||
return TRUE
|
||||
/*
|
||||
/obj/belly/onDropInto(var/atom/movable/AM)
|
||||
return null */
|
||||
|
||||
//Handle a mob struggling
|
||||
// Called from /mob/living/carbon/relaymove()
|
||||
@@ -469,6 +492,23 @@
|
||||
return // User is not in this belly
|
||||
|
||||
R.setClickCooldown(50)
|
||||
|
||||
if(owner.stat) //If owner is stat (dead, KO) we can actually escape
|
||||
to_chat(R,"<span class='warning'>You attempt to climb out of \the [lowertext(name)]. (This will take around [escapetime/10] seconds.)</span>")
|
||||
to_chat(owner,"<span class='warning'>Someone is attempting to climb out of your [lowertext(name)]!</span>")
|
||||
|
||||
if(do_after(R, owner, escapetime))
|
||||
if((owner.stat || escapable) && (R.loc == src)) //Can still escape?
|
||||
release_specific_contents(R)
|
||||
return
|
||||
else if(R.loc != src) //Aren't even in the belly. Quietly fail.
|
||||
return
|
||||
else //Belly became inescapable or mob revived
|
||||
to_chat(R,"<span class='warning'>Your attempt to escape [lowertext(name)] has failed!</span>")
|
||||
to_chat(owner,"<span class='notice'>The attempt to escape from your [lowertext(name)] has failed!</span>")
|
||||
return
|
||||
return
|
||||
|
||||
var/struggle_outer_message = pick(struggle_messages_outside)
|
||||
var/struggle_user_message = pick(struggle_messages_inside)
|
||||
|
||||
@@ -483,41 +523,38 @@
|
||||
struggle_outer_message = "<span class='alert'>" + struggle_outer_message + "</span>"
|
||||
struggle_user_message = "<span class='alert'>" + struggle_user_message + "</span>"
|
||||
|
||||
if((owner.stat || !owner.client) && (R.a_intent != INTENT_HELP)) //If owner is stat (dead, KO) we can actually escape
|
||||
to_chat(R,"<span class='warning'>You attempt to climb out of \the [lowertext(name)]. (This will take around 5 seconds.)</span>")
|
||||
to_chat(owner,"<span class='warning'>Someone is attempting to climb out of your [lowertext(name)]!</span>")
|
||||
|
||||
if(!do_mob(R,owner,50))
|
||||
return
|
||||
if(!(R in contents)) //Aren't even in the belly. Quietly fail.
|
||||
return
|
||||
if(R.a_intent != INTENT_HELP) //still want to?
|
||||
release_specific_contents(R)
|
||||
return
|
||||
else //Belly became inescapable or mob revived
|
||||
to_chat(R,"<span class='warning'>Your attempt to escape [lowertext(name)] has failed!</span>")
|
||||
to_chat(owner,"<span class='notice'>The attempt to escape from your [lowertext(name)] has failed!</span>")
|
||||
return
|
||||
else if(R.a_intent != INTENT_HELP) //failsafe to make sure people are able to struggle out. friendly ERP should be on help intent.
|
||||
to_chat(R,"<span class='warning'>You attempt to climb out of [lowertext(name)]. (This will take around [escapetime] seconds.)</span>")
|
||||
to_chat(owner,"<span class='warning'>Someone is attempting to climb out of your [lowertext(name)]!</span>")
|
||||
if(!do_mob(R,owner,escapetime))
|
||||
return
|
||||
release_specific_contents(R)
|
||||
return
|
||||
else if (R.a_intent == INTENT_HELP)
|
||||
for(var/mob/M in get_hearers_in_view(3, get_turf(owner)))
|
||||
M.show_message(struggle_outer_message, 1) // visible
|
||||
to_chat(R,struggle_user_message)
|
||||
|
||||
if(!silent)
|
||||
for(var/mob/M in get_hearers_in_view(5, get_turf(owner)))
|
||||
if(is_wet)
|
||||
for(var/mob/M in get_hearers_in_view(2, get_turf(owner)))
|
||||
if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES))
|
||||
playsound(get_turf(owner),"struggle_sound",35,0,-5,1,ignore_walls = FALSE,channel=CHANNEL_PRED)
|
||||
R.stop_sound_channel(CHANNEL_PRED)
|
||||
var/sound/prey_struggle = sound(get_sfx("prey_struggle"))
|
||||
R.playsound_local(get_turf(R),prey_struggle,45,0)
|
||||
|
||||
else
|
||||
for(var/mob/M in get_hearers_in_view(2, get_turf(owner)))
|
||||
if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES))
|
||||
playsound(get_turf(owner),"rustle",35,0,-5,1,ignore_walls = FALSE,channel=CHANNEL_PRED)
|
||||
|
||||
for(var/mob/M in get_hearers_in_view(3, get_turf(owner)))
|
||||
if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES)) //Might as well censor the normies here too.
|
||||
M.show_message(struggle_outer_message, 1) // visible
|
||||
to_chat(R,struggle_user_message)
|
||||
|
||||
if(escapable) //If the stomach has escapable enabled.
|
||||
if(prob(escapechance)) //Let's have it check to see if the prey escapes first.
|
||||
to_chat(R,"<span class='warning'>You start to climb out of \the [lowertext(name)].</span>")
|
||||
to_chat(owner,"<span class='warning'>Someone is attempting to climb out of your [lowertext(name)]!</span>")
|
||||
if(do_after(R, escapetime))
|
||||
if((owner.stat || escapable) && (R.loc == src)) //Can still escape?
|
||||
release_specific_contents(R)
|
||||
return
|
||||
else if(R.loc != src) //Aren't even in the belly. Quietly fail.
|
||||
return
|
||||
else //Belly became inescapable or mob revived
|
||||
to_chat(R,"<span class='warning'>Your attempt to escape [lowertext(name)] has failed!</span>")
|
||||
to_chat(owner,"<span class='notice'>The attempt to escape from your [lowertext(name)] has failed!</span>")
|
||||
return
|
||||
else if(prob(transferchance) && transferlocation) //Next, let's have it see if they end up getting into an even bigger mess then when they started.
|
||||
var/obj/belly/dest_belly
|
||||
for(var/belly in owner.vore_organs)
|
||||
@@ -525,6 +562,7 @@
|
||||
if(B.name == transferlocation)
|
||||
dest_belly = B
|
||||
break
|
||||
|
||||
if(!dest_belly)
|
||||
to_chat(owner, "<span class='warning'>Something went wrong with your belly transfer settings. Your <b>[lowertext(name)]</b> has had it's transfer chance and transfer location cleared as a precaution.</span>")
|
||||
transferchance = 0
|
||||
@@ -541,21 +579,10 @@
|
||||
to_chat(owner,"<span class='warning'>You feel your [lowertext(name)] start to cling onto its contents...</span>")
|
||||
digest_mode = DM_ABSORB
|
||||
return
|
||||
/*
|
||||
else if(prob(digestchance) && digest_mode != DM_ITEMWEAK && digest_mode != DM_DIGEST) //Finally, let's see if it should run the digest chance.
|
||||
|
||||
else if(prob(digestchance) && digest_mode != DM_DIGEST) //Finally, let's see if it should run the digest chance.
|
||||
to_chat(R,"<span class='warning'>In response to your struggling, \the [lowertext(name)] begins to get more active...</span>")
|
||||
to_chat(owner,"<span class='warning'>You feel your [lowertext(name)] beginning to become active!</span>")
|
||||
digest_mode = DM_ITEMWEAK
|
||||
return
|
||||
|
||||
else if(prob(digestchance) && digest_mode == DM_ITEMWEAK) //Oh god it gets even worse if you fail twice!
|
||||
to_chat(R,"<span class='warning'>In response to your struggling, \the [lowertext(name)] begins to get even more active!</span>")
|
||||
to_chat(owner,"<span class='warning'>You feel your [lowertext(name)] beginning to become even more active!</span>")
|
||||
digest_mode = DM_DIGEST
|
||||
return */
|
||||
else if(prob(digestchance)) //Finally, let's see if it should run the digest chance.)
|
||||
to_chat(R, "<span class='warning'>In response to your struggling, \the [name] begins to get more active...</span>")
|
||||
to_chat(owner, "<span class='warning'>You feel your [name] beginning to become active!</span>")
|
||||
digest_mode = DM_DIGEST
|
||||
return
|
||||
|
||||
@@ -602,13 +629,13 @@
|
||||
dupe.escapechance = escapechance
|
||||
dupe.can_taste = can_taste
|
||||
dupe.bulge_size = bulge_size
|
||||
dupe.silent = silent
|
||||
dupe.transferlocation = transferlocation
|
||||
dupe.transferchance = transferchance
|
||||
dupe.autotransferchance = autotransferchance
|
||||
dupe.autotransferwait = autotransferwait
|
||||
dupe.swallow_time = swallow_time
|
||||
dupe.vore_capacity = vore_capacity
|
||||
dupe.is_wet = is_wet
|
||||
|
||||
//// Object-holding variables
|
||||
//struggle_messages_outside - strings
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
for(var/mob/living/M in contents)
|
||||
if(isbelly(M.loc))
|
||||
if(world.time > M.next_preyloop)
|
||||
if(!silent)
|
||||
if(is_wet)
|
||||
M.stop_sound_channel(CHANNEL_PREYLOOP) // sanity just in case
|
||||
var/sound/preyloop = sound('sound/vore/prey/loop.ogg', repeat = TRUE)
|
||||
M.playsound_local(get_turf(src),preyloop,80,0, channel = CHANNEL_PREYLOOP)
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
///////////////////// Mob Living /////////////////////
|
||||
/mob/living
|
||||
var/digestable = FALSE // Can the mob be digested inside a belly?
|
||||
var/obj/belly/vore_selected // Default to no vore capability.
|
||||
var/list/vore_organs = list() // List of vore containers inside a mob
|
||||
var/showvoreprefs = TRUE // Determines if the mechanical vore preferences button will be displayed on the mob or not.
|
||||
var/obj/belly/vore_selected // Default to no vore capability.
|
||||
var/list/vore_organs = list() // List of vore containers inside a mob
|
||||
var/devourable = FALSE // Can the mob be vored at all?
|
||||
// var/feeding = FALSE // Are we going to feed someone else?
|
||||
var/vore_taste = null // What the character tastes like
|
||||
var/feeding = FALSE // Are we going to feed someone else?
|
||||
var/vore_taste = null // What the character tastes like
|
||||
var/no_vore = FALSE // If the character/mob can vore.
|
||||
var/openpanel = 0 // Is the vore panel open?
|
||||
var/noisy = FALSE // tummies are rumbly?
|
||||
var/absorbed = FALSE //are we absorbed?
|
||||
var/openpanel = 0 // Is the vore panel open?
|
||||
var/noisy = TRUE // tummies are rumbly?
|
||||
var/absorbed = FALSE //are we absorbed?
|
||||
var/next_preyloop
|
||||
|
||||
//
|
||||
@@ -26,7 +27,8 @@
|
||||
|
||||
//Tries to load prefs if a client is present otherwise gives freebie stomach
|
||||
spawn(10 SECONDS) // long delay because the server delays in its startup. just on the safe side.
|
||||
M.init_vore()
|
||||
if(M)
|
||||
M.init_vore()
|
||||
|
||||
//Return 1 to hook-caller
|
||||
return 1
|
||||
@@ -75,31 +77,42 @@
|
||||
|
||||
// Critical adjustments due to TG grab changes - Poojawa
|
||||
|
||||
/mob/living/proc/vore_attack(var/mob/living/user, var/mob/living/prey)
|
||||
if(!user || !prey)
|
||||
/mob/living/proc/vore_attack(var/mob/living/user, var/mob/living/prey, var/mob/living/pred)
|
||||
if(!user || !prey || !pred)
|
||||
return
|
||||
|
||||
if(prey == src && user.zone_selected == "mouth") //you click your target
|
||||
// if(!feeding(src))
|
||||
// return
|
||||
if(!is_vore_predator(prey))
|
||||
if(!isliving(pred)) //no badmin, you can't feed people to ghosts or objects.
|
||||
return
|
||||
|
||||
if(pred == prey) //you click your target
|
||||
if(!pred.feeding)
|
||||
to_chat(user, "<span class='notice'>They aren't able to be fed.</span>")
|
||||
to_chat(pred, "<span class='notice'>[user] tried to feed you themselves, but you aren't voracious enough to be fed.</span>")
|
||||
return
|
||||
if(!is_vore_predator(pred))
|
||||
to_chat(user, "<span class='notice'>They aren't voracious enough.</span>")
|
||||
return
|
||||
feed_self_to_grabbed(user, src)
|
||||
feed_self_to_grabbed(user, pred)
|
||||
|
||||
if(user == src) //you click yourself
|
||||
if(pred == user) //you click yourself
|
||||
if(!is_vore_predator(src))
|
||||
to_chat(user, "<span class='notice'>You aren't voracious enough.</span>")
|
||||
return
|
||||
user.feed_grabbed_to_self(src, prey)
|
||||
feed_grabbed_to_self(user, prey)
|
||||
|
||||
else // click someone other than you/prey
|
||||
// if(!feeding(src))
|
||||
// return
|
||||
if(!is_vore_predator(src))
|
||||
if(!pred.feeding)
|
||||
to_chat(user, "<span class='notice'>They aren't voracious enough to be fed.</span>")
|
||||
to_chat(pred, "<span class='notice'>[user] tried to feed you [prey], but you aren't voracious enough to be fed.</span>")
|
||||
return
|
||||
if(!prey.feeding)
|
||||
to_chat(user, "<span class='notice'>They aren't able to be fed to someone.</span>")
|
||||
to_chat(prey, "<span class='notice'>[user] tried to feed you to [pred], but you aren't able to be fed to them.</span>")
|
||||
return
|
||||
if(!is_vore_predator(pred))
|
||||
to_chat(user, "<span class='notice'>They aren't voracious enough.</span>")
|
||||
return
|
||||
feed_grabbed_to_other(user, prey, src)
|
||||
feed_grabbed_to_other(user, prey, pred)
|
||||
//
|
||||
// Eating procs depending on who clicked what
|
||||
//
|
||||
@@ -120,7 +133,7 @@
|
||||
return perform_the_nom(user, user, pred, belly)
|
||||
|
||||
/mob/living/proc/feed_grabbed_to_other(var/mob/living/user, var/mob/living/prey, var/mob/living/pred)
|
||||
return//disabled until I can make that toggle work
|
||||
// return//disabled until I can make that toggle work
|
||||
var/belly = input("Choose Belly") in pred.vore_organs
|
||||
return perform_the_nom(user, prey, pred, belly)
|
||||
|
||||
@@ -281,7 +294,7 @@
|
||||
*/
|
||||
|
||||
//
|
||||
// Custom resist catches for /mob/living
|
||||
// Our custom resist catches for /mob/living
|
||||
//
|
||||
/mob/living/proc/vore_process_resist()
|
||||
|
||||
@@ -293,7 +306,7 @@
|
||||
|
||||
//Other overridden resists go here
|
||||
|
||||
return FALSE
|
||||
return 0
|
||||
|
||||
// internal slimy button in case the loop stops playing but the player wants to hear it
|
||||
/mob/living/proc/preyloop_refresh()
|
||||
@@ -320,9 +333,9 @@
|
||||
return
|
||||
//Actual escaping
|
||||
forceMove(get_turf(src)) //Just move me up to the turf, let's not cascade through bellies, there's been a problem, let's just leave.
|
||||
if(is_blind(src) && !has_trait(TRAIT_BLIND))
|
||||
src.adjust_blindness(-1)
|
||||
src.cure_blind("belly_[REF(src)]")
|
||||
src.stop_sound_channel(CHANNEL_PREYLOOP)
|
||||
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "fedprey", /datum/mood_event/fedprey)
|
||||
for(var/mob/living/simple_animal/SA in range(10))
|
||||
SA.prey_excludes[src] = world.time
|
||||
|
||||
@@ -374,6 +387,7 @@
|
||||
|
||||
P.digestable = src.digestable
|
||||
P.devourable = src.devourable
|
||||
P.feeding = src.feeding
|
||||
P.vore_taste = src.vore_taste
|
||||
|
||||
var/list/serialized = list()
|
||||
@@ -397,6 +411,7 @@
|
||||
|
||||
digestable = P.digestable
|
||||
devourable = P.devourable
|
||||
feeding = P.feeding
|
||||
vore_taste = P.vore_taste
|
||||
|
||||
release_vore_contents(silent = TRUE)
|
||||
|
||||
@@ -28,7 +28,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
|
||||
// The datum type bolted onto normal preferences datums for storing Vore stuff
|
||||
//
|
||||
|
||||
#define VORE_VERSION 2
|
||||
#define VORE_VERSION 3
|
||||
|
||||
GLOBAL_LIST_EMPTY(vore_preferences_datums)
|
||||
|
||||
@@ -39,6 +39,7 @@ GLOBAL_LIST_EMPTY(vore_preferences_datums)
|
||||
//Actual preferences
|
||||
var/digestable = FALSE
|
||||
var/devourable = FALSE
|
||||
var/feeding = FALSE
|
||||
// var/allowmobvore = TRUE
|
||||
var/list/belly_prefs = list()
|
||||
var/vore_taste = "nothing in particular"
|
||||
@@ -105,6 +106,7 @@ GLOBAL_LIST_EMPTY(vore_preferences_datums)
|
||||
|
||||
digestable = json_from_file["digestable"]
|
||||
devourable = json_from_file["devourable"]
|
||||
feeding = json_from_file["feeding"]
|
||||
vore_taste = json_from_file["vore_taste"]
|
||||
belly_prefs = json_from_file["belly_prefs"]
|
||||
|
||||
@@ -113,6 +115,8 @@ GLOBAL_LIST_EMPTY(vore_preferences_datums)
|
||||
digestable = FALSE
|
||||
if(isnull(devourable))
|
||||
devourable = FALSE
|
||||
if(isnull(feeding))
|
||||
feeding = FALSE
|
||||
if(isnull(belly_prefs))
|
||||
belly_prefs = list()
|
||||
|
||||
@@ -127,6 +131,7 @@ GLOBAL_LIST_EMPTY(vore_preferences_datums)
|
||||
"version" = version,
|
||||
"digestable" = digestable,
|
||||
"devourable" = devourable,
|
||||
"feeding" = feeding,
|
||||
"vore_taste" = vore_taste,
|
||||
"belly_prefs" = belly_prefs,
|
||||
)
|
||||
|
||||
@@ -18,9 +18,10 @@
|
||||
|
||||
var/dat = picker_holder.gen_vui(src)
|
||||
|
||||
picker_holder.popup = new(src, "insidePanel","Vore Panel", 400, 600, picker_holder)
|
||||
picker_holder.popup = new(src, "insidePanel","Vore Panel", 450, 700, picker_holder)
|
||||
picker_holder.popup.set_content(dat)
|
||||
picker_holder.popup.open()
|
||||
src.openpanel = 1
|
||||
|
||||
/mob/living/proc/updateVRPanel() //Panel popup update call from belly events.
|
||||
if(src.openpanel == 1)
|
||||
@@ -30,7 +31,7 @@
|
||||
|
||||
var/dat = picker_holder.gen_vui(src)
|
||||
|
||||
picker_holder.popup = new(src, "insidePanel","Vore Panel", 400, 600, picker_holder)
|
||||
picker_holder.popup = new(src, "insidePanel","Vore Panel", 450, 700, picker_holder)
|
||||
picker_holder.popup.set_content(dat)
|
||||
picker_holder.popup.open()
|
||||
|
||||
@@ -39,7 +40,7 @@
|
||||
//
|
||||
/datum/vore_look
|
||||
var/obj/belly/selected
|
||||
var/show_interacts = TRUE
|
||||
var/show_interacts = 0
|
||||
var/datum/browser/popup
|
||||
var/loop = null; // Magic self-reference to stop the handler from being GC'd before user takes action.
|
||||
|
||||
@@ -55,13 +56,14 @@
|
||||
|
||||
/datum/vore_look/proc/gen_vui(var/mob/living/user)
|
||||
var/dat
|
||||
|
||||
dat += "Remember to toggle the vore mode, it's to the left of your combat toggle. Open mouth means you're voracious!<br>"
|
||||
dat += "<HR>"
|
||||
var/atom/userloc = user.loc
|
||||
if (isbelly(userloc))
|
||||
var/obj/belly/inside_belly = userloc
|
||||
var/mob/living/eater = inside_belly.owner
|
||||
|
||||
//Don't display this part if we couldn't find the belly since could be held in hand.
|
||||
//Don't display this part if we couldn't find the belly since could be held in hand.
|
||||
if(inside_belly)
|
||||
dat += "<font color = 'green'>You are currently [user.absorbed ? "absorbed into " : "inside "]</font> <font color = 'yellow'>[eater]'s</font> <font color = 'red'>[inside_belly]</font>!<br><br>"
|
||||
|
||||
@@ -102,7 +104,6 @@
|
||||
dat += "<li style='float: left'><a href='?src=\ref[src];bellypick=\ref[B]'><b>[B.name]</b>"
|
||||
else
|
||||
dat += "<li style='float: left'><a href='?src=\ref[src];bellypick=\ref[B]'>[B.name]"
|
||||
|
||||
var/spanstyle
|
||||
switch(B.digest_mode)
|
||||
if(DM_HOLD)
|
||||
@@ -110,11 +111,13 @@
|
||||
if(DM_DIGEST)
|
||||
spanstyle = "color:red;"
|
||||
if(DM_HEAL)
|
||||
spanstyle = "color:green;"
|
||||
spanstyle = "color:darkgreen;"
|
||||
if(DM_NOISY)
|
||||
spanstyle = "color:purple;"
|
||||
if(DM_ABSORB)
|
||||
spanstyle = "color:purple;"
|
||||
if(DM_DRAGON)
|
||||
spanstyle = "color:blue;"
|
||||
|
||||
dat += "<span style='[spanstyle]'> ([B.contents.len])</span></a></li>"
|
||||
|
||||
@@ -156,6 +159,10 @@
|
||||
dat += "<a href='?src=\ref[src];b_name=\ref[selected]'>Name:</a>"
|
||||
dat += " '[selected.name]'"
|
||||
|
||||
//Belly Type button
|
||||
dat += "<br><a href='?src=\ref[src];b_wetness=\ref[selected]'>Is Fleshy:</a>"
|
||||
dat += "[selected.is_wet ? "Yes" : "No"]"
|
||||
|
||||
//Digest Mode Button
|
||||
dat += "<br><a href='?src=\ref[src];b_mode=\ref[selected]'>Belly Mode:</a>"
|
||||
dat += " [selected.digest_mode]"
|
||||
@@ -169,11 +176,11 @@
|
||||
dat += " '[selected.desc]'"
|
||||
|
||||
//Belly sound
|
||||
dat += "<br><a href='?src=\ref[src];b_sound=\ref[selected]'>Set Vore Sound</a>"
|
||||
dat += "<br><a href='?src=\ref[src];b_sound=\ref[selected]'>Vore Sound: [selected.vore_sound]</a>"
|
||||
dat += "<a href='?src=\ref[src];b_soundtest=\ref[selected]'>Test</a>"
|
||||
|
||||
//Release sound
|
||||
dat += "<br><a href='?src=\ref[src];b_release=\ref[selected]'>Set Release Sound</a>"
|
||||
dat += "<br><a href='?src=\ref[src];b_release=\ref[selected]'>Release Sound: [selected.release_sound]</a>"
|
||||
dat += "<a href='?src=\ref[src];b_releasesoundtest=\ref[selected]'>Test</a>"
|
||||
|
||||
//Belly messages
|
||||
@@ -201,10 +208,6 @@
|
||||
dat += "<br><a href='?src=\ref[src];b_escapetime=\ref[selected]'>Set Belly Escape Time</a>"
|
||||
dat += " [selected.escapetime/10]s"
|
||||
|
||||
dat += "<br style='line-height:5px;'>"
|
||||
dat += "<br><a href='?src=\ref[src];b_absorbchance=\ref[selected]'>Set Belly Absorb Chance</a>"
|
||||
dat += " [selected.absorbchance]%"
|
||||
|
||||
//Special <br> here to add a gap
|
||||
dat += "<br style='line-height:5px;'>"
|
||||
dat += "<br><a href='?src=\ref[src];b_transferchance=\ref[selected]'>Set Belly Transfer Chance</a>"
|
||||
@@ -215,14 +218,13 @@
|
||||
|
||||
//Special <br> here to add a gap
|
||||
dat += "<br style='line-height:5px;'>"
|
||||
dat += "<br><a href='?src=\ref[src];b_absorbchance=\ref[selected]'>Set Belly Absorb Chance</a>"
|
||||
dat += " [selected.absorbchance]%"
|
||||
|
||||
dat += "<br><a href='?src=\ref[src];b_digestchance=\ref[selected]'>Set Belly Digest Chance</a>"
|
||||
dat += " [selected.digestchance]%"
|
||||
dat += "<HR>"
|
||||
|
||||
// Belly Silence
|
||||
dat += "<br><a href='?src=\ref[src];b_silent=\ref[selected]'>Belly Silence (for not belly bellies):</a>"
|
||||
dat += " [selected.silent ? "Yes" : "No"]"
|
||||
|
||||
//Delete button
|
||||
dat += "<br><a style='background:#990000;' href='?src=\ref[src];b_del=\ref[selected]'>Delete Belly</a>"
|
||||
|
||||
@@ -239,15 +241,21 @@
|
||||
dat += "<HR>"
|
||||
switch(user.digestable)
|
||||
if(TRUE)
|
||||
dat += "<a href='?src=\ref[src];toggledg=1'>Toggle Digestable (Currently: ON)</a>"
|
||||
dat += "<a href='?src=\ref[src];toggledg=1'>Toggle Digestable <font color='darkgreen'>(Currently: ON)</font></a>"
|
||||
if(FALSE)
|
||||
dat += "<a href='?src=\ref[src];toggledg=1'>Toggle Digestable (Currently: OFF)</a>"
|
||||
dat += "<a href='?src=\ref[src];toggledg=1'>Toggle Digestable <font color='red'>(Currently: OFF)</font></a>"
|
||||
|
||||
switch(user.devourable)
|
||||
if(TRUE)
|
||||
dat += "<a href='?src=\ref[src];toggledvor=1'>Toggle Devourable (Currently: ON)</a>"
|
||||
dat += "<br><a href='?src=\ref[src];toggledvor=1'>Toggle Devourable <font color='darkgreen'>(Currently: ON)</font></a>"
|
||||
if(FALSE)
|
||||
dat += "<a href='?src=\ref[src];toggledvor=1'>Toggle Devourable (Currently: OFF)</a>"
|
||||
dat += "<br><a href='?src=\ref[src];toggledvor=1'>Toggle Devourable <font color='red'>(Currently: OFF)</font></a>"
|
||||
|
||||
switch(user.feeding)
|
||||
if(TRUE)
|
||||
dat += "<br><a href='?src=\ref[src];toggledfeed=1'>Toggle Feeding <font color='darkgreen'>(Currently: ON)</font></a>"
|
||||
if(FALSE)
|
||||
dat += "<br><a href='?src=\ref[src];toggledfeed=1'>Toggle Feeding <font color='red'>(Currently: OFF)</font></a>"
|
||||
|
||||
//Returns the dat html to the vore_look
|
||||
return dat
|
||||
@@ -258,25 +266,26 @@
|
||||
|
||||
if(href_list["close"])
|
||||
qdel(src) // Cleanup
|
||||
user.openpanel = 0
|
||||
return
|
||||
|
||||
if(href_list["show_int"])
|
||||
show_interacts = !show_interacts
|
||||
return TRUE //Force update
|
||||
return 1 //Force update
|
||||
|
||||
if(href_list["int_help"])
|
||||
to_chat(usr,"These control how your belly responds to someone using 'resist' while inside you. The percent chance to trigger each is listed below, \
|
||||
alert("These control how your belly responds to someone using 'resist' while inside you. The percent chance to trigger each is listed below, \
|
||||
and you can change them to whatever you see fit. Setting them to 0% will disable the possibility of that interaction. \
|
||||
These only function as long as interactions are turned on in general. Keep in mind, the 'belly mode' interactions (digest) \
|
||||
will affect all prey in that belly, if one resists and triggers digestion. If multiple trigger at the same time, \
|
||||
only the first in the order of 'Escape > Transfer > Absorb > Digest' will occur.")
|
||||
return TRUE //Force update
|
||||
These only function as long as interactions are turned on in general. Keep in mind, the 'belly mode' interactions (digest/absorb) \
|
||||
will affect all prey in that belly, if one resists and triggers digestion/absorption. If multiple trigger at the same time, \
|
||||
only the first in the order of 'Escape > Transfer > Absorb > Digest' will occur.","Interactions Help")
|
||||
return 0 //Force update
|
||||
|
||||
if(href_list["outsidepick"])
|
||||
var/atom/movable/tgt = locate(href_list["outsidepick"])
|
||||
var/obj/belly/OB = locate(href_list["outsidebelly"])
|
||||
if(!(tgt in OB)) //Aren't here anymore, need to update menu.
|
||||
return TRUE
|
||||
return 1
|
||||
var/intent = "Examine"
|
||||
|
||||
if(istype(tgt,/mob/living))
|
||||
@@ -289,11 +298,11 @@
|
||||
if("Help Out") //Help the inside-mob out
|
||||
if(user.stat || user.absorbed || M.absorbed)
|
||||
to_chat(user,"<span class='warning'>You can't do that in your state!</span>")
|
||||
return
|
||||
return 1
|
||||
|
||||
to_chat(user,"<font color='green'>You begin to push [M] to freedom!</font>")
|
||||
to_chat(M,"[usr] begins to push you to freedom!")
|
||||
to_chat(OB.owner,"<span class='warning'>Someone is trying to escape from inside you!</span>")
|
||||
to_chat(M.loc,"<span class='warning'>Someone is trying to escape from inside you!</span>")
|
||||
sleep(50)
|
||||
if(prob(33))
|
||||
OB.release_specific_contents(M)
|
||||
@@ -305,15 +314,14 @@
|
||||
to_chat(M,"<span class='alert'> Even with [user]'s help, you slip back inside again.</span>")
|
||||
to_chat(OB.owner,"<font color='green'>Your body efficiently shoves [M] back where they belong.</font>")
|
||||
|
||||
|
||||
if("Devour") //Eat the inside mob
|
||||
if(user.absorbed || user.stat)
|
||||
to_chat(user,"<span class='warning'>You can't do that in your state!</span>")
|
||||
return
|
||||
return 1
|
||||
|
||||
if(!user.vore_selected)
|
||||
to_chat(user,"<span class='warning'>Pick a belly on yourself first!</span>")
|
||||
return
|
||||
return 1
|
||||
|
||||
var/obj/belly/TB = user.vore_selected
|
||||
to_chat(user,"<span class='warning'>You begin to [lowertext(TB.vore_verb)] [M] into your [lowertext(TB.name)]!</span>")
|
||||
@@ -329,9 +337,9 @@
|
||||
|
||||
else if(istype(tgt,/obj/item))
|
||||
var/obj/item/T = tgt
|
||||
if(!(tgt in OB.contents))
|
||||
if(!(tgt in OB))
|
||||
//Doesn't exist anymore, update.
|
||||
return TRUE
|
||||
return 1
|
||||
intent = alert("What do you want to do to that?","Query","Examine","Use Hand")
|
||||
switch(intent)
|
||||
if("Examine")
|
||||
@@ -339,8 +347,8 @@
|
||||
|
||||
if("Use Hand")
|
||||
if(user.stat)
|
||||
to_chat(user, "<span class='warning'>You can't do that in your state!</span>")
|
||||
return
|
||||
to_chat(user,"<span class='warning'>You can't do that in your state!</span>")
|
||||
return 1
|
||||
|
||||
user.ClickOn(T)
|
||||
sleep(5) //Seems to exit too fast for the panel to update
|
||||
@@ -353,32 +361,31 @@
|
||||
intent = alert("Eject all, Move all?","Query","Eject all","Cancel","Move all")
|
||||
switch(intent)
|
||||
if("Cancel")
|
||||
return
|
||||
return 0
|
||||
|
||||
if("Eject all")
|
||||
if(user.stat)
|
||||
to_chat(user, "<span class='warning'>You can't do that in your state!</span>")
|
||||
return
|
||||
to_chat(user,"<span class='warning'>You can't do that in your state!</span>")
|
||||
return 0
|
||||
|
||||
selected.release_all_contents()
|
||||
to_chat(user.loc,"<span class='danger'>Everything is released from [user]!</span>")
|
||||
|
||||
if("Move all")
|
||||
if(user.stat)
|
||||
to_chat(user, "<span class='warning'>You can't do that in your state!</span>")
|
||||
return FALSE
|
||||
to_chat(user,"<span class='warning'>You can't do that in your state!</span>")
|
||||
return 0
|
||||
|
||||
var/obj/belly/choice = input("Move all where?","Select Belly") as null|anything in user.vore_organs
|
||||
if(!choice)
|
||||
return FALSE
|
||||
return 0
|
||||
|
||||
for(var/atom/movable/tgt in selected)
|
||||
selected.transfer_contents(tgt, choice, 1)
|
||||
to_chat(tgt,"<span class='warning'>You're squished from [user]'s [lowertext(selected)] to their [lowertext(choice.name)]!</span>")
|
||||
selected.transfer_contents(tgt, choice, 1)
|
||||
|
||||
var/atom/movable/tgt = locate(href_list["insidepick"])
|
||||
if(!(tgt in selected)) //Old menu, needs updating because they aren't really there.
|
||||
return TRUE//Forces update
|
||||
return 1 //Forces update
|
||||
intent = "Examine"
|
||||
intent = alert("Examine, Eject, Move? Examine if you want to leave this box.","Query","Examine","Eject","Move")
|
||||
switch(intent)
|
||||
@@ -387,11 +394,10 @@
|
||||
|
||||
if("Eject")
|
||||
if(user.stat)
|
||||
to_chat(user, "<span class='warning'>You can't do that in your state!</span>")
|
||||
return FALSE
|
||||
to_chat(user,"<span class='warning'>You can't do that in your state!</span>")
|
||||
return 0
|
||||
|
||||
selected.release_specific_contents(tgt)
|
||||
user.loc << "<span class='danger'>[tgt] is released from [user]!</span>"
|
||||
|
||||
if("Move")
|
||||
if(user.stat)
|
||||
@@ -457,6 +463,9 @@
|
||||
|
||||
selected.name = new_name
|
||||
|
||||
if(href_list["b_wetness"])
|
||||
selected.is_wet = !selected.is_wet
|
||||
|
||||
if(href_list["b_mode"])
|
||||
var/list/menu_list = selected.digest_modes
|
||||
|
||||
@@ -540,12 +549,12 @@
|
||||
if(!choice)
|
||||
return
|
||||
|
||||
selected.release_sound = GLOB.release_sounds[choice]
|
||||
selected.release_sound = choice
|
||||
|
||||
if(href_list["b_releasesoundtest"])
|
||||
var/soundfile = selected.release_sound
|
||||
if(soundfile)
|
||||
user << soundfile
|
||||
var/sound/releasetest = GLOB.release_sounds[selected.release_sound]
|
||||
if(releasetest)
|
||||
user << releasetest
|
||||
|
||||
if(href_list["b_sound"])
|
||||
var/choice = input(user,"Currently set to [selected.vore_sound]","Select Sound") as null|anything in GLOB.vore_sounds
|
||||
@@ -553,12 +562,12 @@
|
||||
if(!choice)
|
||||
return
|
||||
|
||||
selected.vore_sound = GLOB.vore_sounds[choice]
|
||||
selected.vore_sound = choice
|
||||
|
||||
if(href_list["b_soundtest"])
|
||||
var/soundfile = selected.vore_sound
|
||||
if(soundfile)
|
||||
user << soundfile
|
||||
var/sound/voretest = GLOB.vore_sounds[selected.vore_sound]
|
||||
if(voretest)
|
||||
user << voretest
|
||||
|
||||
if(href_list["b_tastes"])
|
||||
selected.can_taste = !selected.can_taste
|
||||
@@ -577,17 +586,17 @@
|
||||
selected.bulge_size = (new_bulge/100)
|
||||
|
||||
if(href_list["b_escapable"])
|
||||
if(selected.escapable == FALSE) //Possibly escapable and special interactions.
|
||||
selected.escapable = TRUE
|
||||
to_chat(usr,"<span class='warning'>Prey now have special interactions with your [selected.name] depending on your settings.</span>")
|
||||
else if(selected.escapable == TRUE) //Never escapable.
|
||||
selected.escapable = FALSE
|
||||
to_chat(usr,"<span class='warning'>Prey will not be able to have special interactions with your [selected.name].</span>")
|
||||
show_interacts = FALSE //Force the hiding of the panel
|
||||
if(selected.escapable == 0) //Possibly escapable and special interactions.
|
||||
selected.escapable = 1
|
||||
to_chat(usr,"<span class='warning'>Prey now have special interactions with your [lowertext(selected.name)] depending on your settings.</span>")
|
||||
else if(selected.escapable == 1) //Never escapable.
|
||||
selected.escapable = 0
|
||||
to_chat(usr,"<span class='warning'>Prey will not be able to have special interactions with your [lowertext(selected.name)].</span>")
|
||||
show_interacts = 0 //Force the hiding of the panel
|
||||
else
|
||||
to_chat(usr,"<span class='warning'>Something went wrong. Your stomach will now not have special interactions. Press the button enable them again and tell a dev.") //If they somehow have a varable that's not 0 or 1
|
||||
selected.escapable = TRUE
|
||||
show_interacts = FALSE //Force the hiding of the panel
|
||||
alert("Something went wrong. Your stomach will now not have special interactions. Press the button enable them again and tell a dev.","Error") //If they somehow have a varable that's not 0 or 1
|
||||
selected.escapable = 0
|
||||
show_interacts = 0 //Force the hiding of the panel
|
||||
|
||||
if(href_list["b_escapechance"])
|
||||
var/escape_chance_input = input(user, "Set prey escape chance on resist (as %)", "Prey Escape Chance") as num|null
|
||||
@@ -605,14 +614,14 @@
|
||||
selected.transferchance = sanitize_integer(transfer_chance_input, 0, 100, initial(selected.transferchance))
|
||||
|
||||
if(href_list["b_transferlocation"])
|
||||
var/choice = input("Where do you want your [selected.name] to lead if prey resists?","Select Belly") as null|anything in (user.vore_organs + "None - Remove" - selected.name)
|
||||
var/obj/belly/choice = input("Where do you want your [lowertext(selected.name)] to lead if prey resists?","Select Belly") as null|anything in (user.vore_organs + "None - Remove" - selected)
|
||||
|
||||
if(!choice) //They cancelled, no changes
|
||||
return FALSE
|
||||
return 0
|
||||
else if(choice == "None - Remove")
|
||||
selected.transferlocation = null
|
||||
else
|
||||
selected.transferlocation = user.vore_organs[choice]
|
||||
selected.transferlocation = choice.name
|
||||
|
||||
if(href_list["b_absorbchance"])
|
||||
var/absorb_chance_input = input(user, "Set belly absorb mode chance on resist (as %)", "Prey Absorb Chance") as num|null
|
||||
@@ -624,13 +633,10 @@
|
||||
if(!isnull(digest_chance_input))
|
||||
selected.digestchance = sanitize_integer(digest_chance_input, 0, 100, initial(selected.digestchance))
|
||||
|
||||
if(href_list["b_silent"])
|
||||
selected.silent = !selected.silent
|
||||
|
||||
if(href_list["b_del"])
|
||||
var/alert = alert("Are you sure you want to delete your [lowertext(selected.name)]?","Confirmation","Delete","Cancel")
|
||||
if(!alert == "Delete")
|
||||
return FALSE
|
||||
return 0
|
||||
|
||||
var/failure_msg = ""
|
||||
|
||||
@@ -651,7 +657,7 @@
|
||||
|
||||
if(failure_msg)
|
||||
alert(user,failure_msg,"Error!")
|
||||
return FALSE
|
||||
return 0
|
||||
|
||||
qdel(selected)
|
||||
selected = user.vore_organs[1]
|
||||
@@ -711,5 +717,18 @@
|
||||
if(user.client.prefs_vr)
|
||||
user.client.prefs_vr.devourable = user.devourable
|
||||
|
||||
if(href_list["toggledfeed"])
|
||||
var/choice = alert(user, "This button is to toggle your ability to be fed to others. Feeding predators is currently: [user.feeding ? "Allowed" : "Prevented"]", "", "Allow Feeding", "Cancel", "Prevent Feeding")
|
||||
switch(choice)
|
||||
if("Cancel")
|
||||
return
|
||||
if("Allow Feeding")
|
||||
user.feeding = TRUE
|
||||
if("Prevent Feeding")
|
||||
user.feeding = FALSE
|
||||
|
||||
if(user.client.prefs_vr)
|
||||
user.client.prefs_vr.feeding = user.feeding
|
||||
|
||||
//Refresh when interacted with, returning 1 makes vore_look.Topic update
|
||||
return 1
|
||||
|
Before Width: | Height: | Size: 347 B After Width: | Height: | Size: 547 B |
|
Before Width: | Height: | Size: 423 B |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.7 KiB |