diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index ddb80a3319..e0dfa2ab74 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -60,7 +60,9 @@
/obj/structure/cable{
icon_state = "4-8"
},
-/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 5
+ },
/turf/open/floor/plasteel,
/area/security/main)
"aai" = (
@@ -2696,6 +2698,9 @@
/obj/effect/turf_decal/tile/red{
dir = 8
},
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
+ },
/turf/open/floor/plasteel,
/area/security/main)
"afp" = (
@@ -4439,9 +4444,6 @@
/obj/structure/cable{
icon_state = "4-8"
},
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
- dir = 4
- },
/obj/effect/turf_decal/tile/red{
dir = 1
},
@@ -5100,9 +5102,6 @@
/obj/structure/cable{
icon_state = "2-4"
},
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
- dir = 4
- },
/obj/structure/disposalpipe/segment{
dir = 6
},
@@ -5528,9 +5527,6 @@
dir = 1;
pixel_y = -24
},
-/obj/machinery/atmospherics/pipe/simple/supply/hidden{
- dir = 4
- },
/obj/effect/turf_decal/tile/red{
dir = 1
},
@@ -5546,14 +5542,14 @@
/obj/structure/cable{
icon_state = "1-2"
},
-/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
- dir = 1
- },
/obj/effect/turf_decal/tile/red,
/obj/effect/turf_decal/tile/red{
dir = 8
},
/obj/structure/disposalpipe/segment,
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 6
+ },
/turf/open/floor/plasteel,
/area/security/main)
"akj" = (
@@ -7986,6 +7982,9 @@
/obj/structure/disposalpipe/segment{
dir = 6
},
+/obj/structure/cable{
+ icon_state = "2-8"
+ },
/turf/open/floor/plating,
/area/maintenance/fore/secondary)
"aqm" = (
@@ -9816,6 +9815,9 @@
name = "Dormitories Maintenance";
req_access_txt = "12"
},
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
/turf/open/floor/plating,
/area/maintenance/fore/secondary)
"avy" = (
@@ -10271,6 +10273,9 @@
/obj/structure/disposalpipe/segment{
dir = 5
},
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
/turf/open/floor/plasteel,
/area/crew_quarters/dorms)
"awz" = (
@@ -23786,9 +23791,6 @@
"bfC" = (
/obj/structure/table/wood,
/obj/item/flashlight/lamp/green,
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
- dir = 5
- },
/turf/open/floor/wood,
/area/crew_quarters/heads/captain)
"bfD" = (
@@ -55616,6 +55618,10 @@
},
/turf/open/floor/wood,
/area/crew_quarters/bar)
+"iUK" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/turf/open/floor/plasteel,
+/area/security/vacantoffice/b)
"iVU" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -56974,6 +56980,12 @@
/obj/machinery/vending/autodrobe,
/turf/open/floor/wood,
/area/maintenance/bar)
+"nfw" = (
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/turf/open/floor/plasteel,
+/area/crew_quarters/dorms)
"ngs" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on{
dir = 8
@@ -57837,6 +57849,13 @@
},
/turf/open/floor/plating,
/area/crew_quarters/fitness)
+"pRW" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/turf/open/floor/plating,
+/area/maintenance/fore/secondary)
"pTB" = (
/obj/structure/lattice/catwalk,
/obj/structure/cable{
@@ -59423,6 +59442,15 @@
},
/turf/open/floor/plating,
/area/space/nearstation)
+"vaW" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/turf/open/floor/plasteel,
+/area/crew_quarters/dorms)
"vbi" = (
/obj/structure/table,
/obj/item/instrument/guitar{
@@ -59990,6 +60018,9 @@
dir = 1;
pixel_y = -22
},
+/obj/structure/cable{
+ icon_state = "1-4"
+ },
/turf/open/floor/plasteel,
/area/crew_quarters/dorms)
"wrp" = (
@@ -86195,7 +86226,7 @@ cCi
aqX
arR
asj
-arT
+iUK
ajr
atY
auo
@@ -94674,15 +94705,15 @@ aoa
ajo
apt
aql
-aoJ
-aoJ
-aoJ
-aoJ
+pRW
+pRW
+pRW
+pRW
avw
awy
-awr
-awr
-avG
+nfw
+nfw
+vaW
wqF
aAh
aAh
diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm
index 578255d086..82dc87e465 100644
--- a/code/__DEFINES/citadel_defines.dm
+++ b/code/__DEFINES/citadel_defines.dm
@@ -99,7 +99,7 @@
#define NO_ASS_SLAP (1<<10)
#define BIMBOFICATION (1<<11)
-#define TOGGLES_CITADEL (EATING_NOISES|DIGESTION_NOISES|BREAST_ENLARGEMENT|PENIS_ENLARGEMENT)
+#define TOGGLES_CITADEL 0
//component stuff
#define COMSIG_VORE_TOGGLED "voremode_toggled" // totally not copypasta
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index b4735cd0d8..e5f817614b 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -36,16 +36,16 @@
#define BLOODCRAWL_EAT 2
//Mob bio-types flags
-#define MOB_ORGANIC 1 << 0
-#define MOB_MINERAL 1 << 1
-#define MOB_ROBOTIC 1 << 2
-#define MOB_UNDEAD 1 << 3
-#define MOB_HUMANOID 1 << 4
-#define MOB_BUG 1 << 5
-#define MOB_BEAST 1 << 6
-#define MOB_EPIC 1 << 7 //megafauna
-#define MOB_REPTILE 1 << 8
-#define MOB_SPIRIT 1 << 9
+#define MOB_ORGANIC (1 << 0)
+#define MOB_MINERAL (1 << 1)
+#define MOB_ROBOTIC (1 << 2)
+#define MOB_UNDEAD (1 << 3)
+#define MOB_HUMANOID (1 << 4)
+#define MOB_BUG (1 << 5)
+#define MOB_BEAST (1 << 6)
+#define MOB_EPIC (1 << 7) //megafauna
+#define MOB_REPTILE (1 << 8)
+#define MOB_SPIRIT (1 << 9)
//Organ defines for carbon mobs
#define ORGAN_ORGANIC 1
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 3979274951..cadc1113c5 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -91,12 +91,12 @@
// Subsystem fire priority, from lowest to highest priority
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
+#define FIRE_PRIORITY_VORE 5
#define FIRE_PRIORITY_PING 10
#define FIRE_PRIORITY_IDLE_NPC 10
#define FIRE_PRIORITY_SERVER_MAINT 10
#define FIRE_PRIORITY_RESEARCH 10
#define FIRE_PRIORITY_VIS 10
-#define FIRE_PRIORITY_VORE 10
#define FIRE_PRIORITY_GARBAGE 15
#define FIRE_PRIORITY_WET_FLOORS 20
#define FIRE_PRIORITY_AIR 20
diff --git a/code/__DEFINES/voreconstants.dm b/code/__DEFINES/voreconstants.dm
index 9c91de0be2..d2eb034813 100644
--- a/code/__DEFINES/voreconstants.dm
+++ b/code/__DEFINES/voreconstants.dm
@@ -7,6 +7,19 @@
#define DM_ABSORB "Absorb"
#define DM_UNABSORB "Un-absorb"
+#define DIGESTABLE (1<<0)
+#define SHOW_VORE_PREFS (1<<1)
+#define DEVOURABLE (1<<2)
+#define FEEDING (1<<3)
+#define NO_VORE (1<<4)
+#define OPEN_PANEL (1<<5)
+#define ABSORBED (1<<6)
+#define VORE_INIT (1<<7)
+#define VOREPREF_INIT (1<<8)
+#define LICKABLE (1<<9)
+
+#define MAX_VORE_FLAG (1<<10)-1 // change this whenever you add a vore flag, must be largest vore flag*2-1
+
#define isbelly(A) istype(A, /obj/belly)
#define QDEL_NULL_LIST(x) if(x) { for(var/y in x) { qdel(y) } ; x = null }
diff --git a/code/datums/components/riding.dm b/code/datums/components/riding.dm
index 4e0dfb343f..4d8cfc4412 100644
--- a/code/datums/components/riding.dm
+++ b/code/datums/components/riding.dm
@@ -84,10 +84,8 @@
if(offsetdir == AM_dir)
var/list/diroffsets = offsets[offsetdir]
buckled_mob.pixel_x = diroffsets[1]
- message_admins(diroffsets[1])
if(diroffsets.len >= 2)
buckled_mob.pixel_y = diroffsets[2]
- message_admins(diroffsets[2])
if(diroffsets.len == 3)
buckled_mob.layer = diroffsets[3]
break
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 45a0f86a98..31704d5451 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -511,6 +511,19 @@
message_admins("[key_name_admin(usr)] edited [current]'s objective to [new_objective.explanation_text]")
log_admin("[key_name(usr)] edited [current]'s objective to [new_objective.explanation_text]")
+ else if(href_list["traitor_class"])
+ var/static/list/choices
+ if(!choices)
+ choices = list()
+ for(var/C in GLOB.traitor_classes)
+ var/datum/traitor_class/t = C
+ choices[initial(t.employer)] = C
+ var/datum/antagonist/traitor/T = locate(href_list["target_antag"]) in antag_datums
+ if(T)
+ var/selected_type = input("Select traitor class:", "Traitor class", T.traitor_kind.employer) as null|anything in choices
+ selected_type = choices[selected_type]
+ T.set_traitor_kind(selected_type)
+
else if (href_list["obj_delete"])
var/datum/objective/objective
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 44a891e24a..40090c35c5 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -397,13 +397,13 @@
//returns the mob's dna info as a list, to be inserted in an object's blood_DNA list
/mob/living/proc/get_blood_dna_list()
var/blood_id = get_blood_id()
- if(!(blood_id =="blood" || blood_id == "jellyblood"))
+ if(!(blood_id in GLOB.blood_reagent_types))
return
return list("ANIMAL DNA" = "Y-")
/mob/living/carbon/get_blood_dna_list()
var/blood_id = get_blood_id()
- if(!(blood_id =="blood" || blood_id == "jellyblood"))
+ if(!(blood_id in GLOB.blood_reagent_types))
return
var/list/blood_dna = list()
if(dna)
diff --git a/code/game/objects/items/devices/dogborg_sleeper.dm b/code/game/objects/items/devices/dogborg_sleeper.dm
index 748c494737..2614775906 100644
--- a/code/game/objects/items/devices/dogborg_sleeper.dm
+++ b/code/game/objects/items/devices/dogborg_sleeper.dm
@@ -324,7 +324,7 @@
cleaning_cycles--
cleaning = TRUE
for(var/mob/living/carbon/C in (touchable_items))
- if((C.status_flags & GODMODE) || !C.digestable)
+ if((C.status_flags & GODMODE) || !CHECK_BITFIELD(C.vore_flags, DIGESTABLE))
items_preserved += C
else
C.adjustBruteLoss(2)
@@ -333,7 +333,7 @@
var/atom/target = pick(touchable_items)
if(iscarbon(target)) //Handle the target being a mob
var/mob/living/carbon/T = target
- if(T.stat == DEAD && T.digestable) //Mob is now dead
+ if(T.stat == DEAD && CHECK_BITFIELD(T.vore_flags, DIGESTABLE)) //Mob is now dead
message_admins("[key_name(hound)] has digested [key_name(T)] as a dogborg. ([hound ? "JMP" : "null"])")
to_chat(hound,"You feel your belly slowly churn around [T], breaking them down into a soft slurry to be used as power for your systems.")
to_chat(T,"You feel [hound]'s belly slowly churn around your form, breaking you down into a soft slurry to be used as power for [hound]'s systems.")
@@ -445,7 +445,7 @@
var/mob/living/silicon/robot/hound = get_host()
if(!hound || !istype(target) || !proximity || target.anchored)
return
- if (!target.devourable)
+ if (!CHECK_BITFIELD(target.vore_flags,DEVOURABLE))
to_chat(user, "The target registers an error code. Unable to insert into [src].")
return
if(patient)
@@ -509,7 +509,7 @@
if(iscarbon(target) || issilicon(target))
var/mob/living/trashman = target
- if(!trashman.devourable)
+ if(!CHECK_BITFIELD(trashman.vore_flags,DEVOURABLE))
to_chat(user, "[target] registers an error code to your [src]")
return
if(patient)
@@ -528,4 +528,4 @@
/obj/item/dogborg/sleeper/K9/flavour
name = "Recreational Sleeper"
- desc = "A mounted, underslung sleeper, intended for holding willing occupants for leisurely purposes."
\ No newline at end of file
+ desc = "A mounted, underslung sleeper, intended for holding willing occupants for leisurely purposes."
diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm
index 22767a66ea..6d8e582c29 100644
--- a/code/game/objects/items/shields.dm
+++ b/code/game/objects/items/shields.dm
@@ -360,7 +360,6 @@ obj/item/shield/riot/bullet_proof
desc = "A massive shield that can block a lot of attacks and can take a lot of abuse before breaking." //It cant break unless it is removed from the implant
item_state = "metal"
icon_state = "metal"
- icon = 'icons/obj/items_and_weapons.dmi'
block_chance = 30 //May be big but hard to move around to block.
slowdown = 1
shield_flags = SHIELD_FLAGS_DEFAULT
diff --git a/code/game/objects/items/storage/storage.dm b/code/game/objects/items/storage/storage.dm
index 8f4cb99048..fd4cc793ab 100644
--- a/code/game/objects/items/storage/storage.dm
+++ b/code/game/objects/items/storage/storage.dm
@@ -16,7 +16,7 @@
AddComponent(component_type)
/obj/item/storage/AllowDrop()
- return FALSE
+ return TRUE
/obj/item/storage/contents_explosion(severity, target)
for(var/atom/A in contents)
diff --git a/code/game/objects/structures/crates_lockers/crates/critter.dm b/code/game/objects/structures/crates_lockers/crates/critter.dm
index 3dbbfd5c23..4b33f33c99 100644
--- a/code/game/objects/structures/crates_lockers/crates/critter.dm
+++ b/code/game/objects/structures/crates_lockers/crates/critter.dm
@@ -22,6 +22,9 @@
return ..()
+/obj/structure/closet/crate/critter/update_icon_state()
+ return
+
/obj/structure/closet/crate/critter/closet_update_overlays(list/new_overlays)
. = new_overlays
if(opened)
@@ -35,4 +38,4 @@
if(tank)
return tank.air_contents
else
- return loc.return_air()
\ No newline at end of file
+ return loc.return_air()
diff --git a/code/modules/admin/antag_panel.dm b/code/modules/admin/antag_panel.dm
index 19e53b09b4..88aab2c4ce 100644
--- a/code/modules/admin/antag_panel.dm
+++ b/code/modules/admin/antag_panel.dm
@@ -104,7 +104,7 @@ GLOBAL_VAR(antag_prototypes)
var/special_statuses = get_special_statuses()
if(length(special_statuses))
- out += get_special_statuses() + "
"
+ out += special_statuses + "
"
if(!GLOB.antag_prototypes)
GLOB.antag_prototypes = list()
diff --git a/code/modules/antagonists/traitor/classes/hijack.dm b/code/modules/antagonists/traitor/classes/hijack.dm
index 59e0591600..dbfa78eb96 100644
--- a/code/modules/antagonists/traitor/classes/hijack.dm
+++ b/code/modules/antagonists/traitor/classes/hijack.dm
@@ -16,3 +16,6 @@
/datum/traitor_class/human/hijack/finalize_traitor(datum/antagonist/traitor/T)
T.hijack_speed=1
return TRUE
+
+/datum/traitor_class/human/hijack/clean_up_traitor(datum/antagonist/traitor/T)
+ T.hijack_speed = 0.5
diff --git a/code/modules/antagonists/traitor/classes/traitor_class.dm b/code/modules/antagonists/traitor/classes/traitor_class.dm
index 012a269572..260e978bec 100644
--- a/code/modules/antagonists/traitor/classes/traitor_class.dm
+++ b/code/modules/antagonists/traitor/classes/traitor_class.dm
@@ -38,3 +38,7 @@ GLOBAL_LIST_EMPTY(traitor_classes)
/datum/traitor_class/proc/finalize_traitor(datum/antagonist/traitor/T)
// Finalization. Return TRUE if should play standard traitor sound/equip, return FALSE if both are special case
return TRUE
+
+/datum/traitor_class/proc/clean_up_traitor(datum/antagonist/traitor/T)
+ // Any effects that need to be cleaned up if traitor class is being swapped.
+
\ No newline at end of file
diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm
index f7dc7ad6d1..cf10f87bf8 100644
--- a/code/modules/antagonists/traitor/datum_traitor.dm
+++ b/code/modules/antagonists/traitor/datum_traitor.dm
@@ -15,36 +15,53 @@
threat = 5
/datum/antagonist/traitor/New()
- ..()
if(!GLOB.traitor_classes.len)//Only need to fill the list when it's needed.
for(var/I in subtypesof(/datum/traitor_class))
new I
+ ..()
-/datum/antagonist/traitor/proc/set_traitor_kind(var/kind)
+/datum/antagonist/traitor/proc/set_traitor_kind(kind)
+ var/swap_from_old = FALSE
+ if(traitor_kind)
+ traitor_kind.remove_innate_effects(owner.current)
+ traitor_kind.clean_up_traitor(src)
+ swap_from_old = TRUE
traitor_kind = GLOB.traitor_classes[kind]
+ traitor_kind.apply_innate_effects(owner.current)
+ if(give_objectives)
+ for(var/O in objectives)
+ qdel(O)
+ traitor_kind.forge_objectives(src)
+ if(swap_from_old)
+ traitor_kind.finalize_traitor(src)
+ traitor_kind.greet(src)
+ owner.announce_objectives()
+
+/proc/get_random_traitor_kind(var/list/blacklist = list())
+ var/chaos_weight = 0
+ if(istype(SSticker.mode,/datum/game_mode/dynamic))
+ var/datum/game_mode/dynamic/mode = SSticker.mode
+ chaos_weight = (mode.threat - 50)/50
+ var/list/weights = list()
+ for(var/C in GLOB.traitor_classes)
+ if(!(C in blacklist))
+ var/datum/traitor_class/class = GLOB.traitor_classes[C]
+ var/weight = LOGISTIC_FUNCTION(1.5*class.weight,chaos_weight,class.chaos,0)
+ weights[C] = weight * 1000
+ var/choice = pickweightAllowZero(weights)
+ if(!choice)
+ choice = TRAITOR_HUMAN // it's an "easter egg"
+ var/datum/traitor_class/actual_class = GLOB.traitor_classes[choice]
+ actual_class.weight *= 0.8 // less likely this round
+ return choice
/datum/antagonist/traitor/on_gain()
if(owner.current && isAI(owner.current))
set_traitor_kind(TRAITOR_AI)
else
- var/chaos_weight = 0
- if(istype(SSticker.mode,/datum/game_mode/dynamic))
- var/datum/game_mode/dynamic/mode = SSticker.mode
- chaos_weight = (mode.threat - 50)/50
- var/list/weights = list()
- for(var/C in GLOB.traitor_classes)
- var/datum/traitor_class/class = GLOB.traitor_classes[C]
- var/weight = LOGISTIC_FUNCTION(1.5*class.weight,chaos_weight,class.chaos,0)
- weights[C] = weight
- var/choice = pickweightAllowZero(weights)
- if(!choice)
- choice = GLOB.traitor_classes[TRAITOR_HUMAN] // it's an "easter egg"
- set_traitor_kind(choice)
- traitor_kind.weight *= 0.8 // less likely this round
+ set_traitor_kind(get_random_traitor_kind())
SSticker.mode.traitors += owner
owner.special_role = special_role
- if(give_objectives)
- traitor_kind.forge_objectives(src)
finalize_traitor()
..()
@@ -97,7 +114,8 @@
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/tatoralert.ogg', 100, FALSE, pressure_affected = FALSE)
/datum/antagonist/traitor/antag_panel_objectives()
- . = ..()
+ . += "Traitor class: [traitor_kind.employer]
"
+ . += ..()
if(contractor_hub?.assigned_targets && length(contractor_hub.assigned_targets))
. += "Contract Targets:
"
for(var/datum/mind/M in contractor_hub.assigned_targets)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index d44b2ffa04..0e5e80eaf3 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -197,10 +197,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/action_buttons_screen_locs = list()
//bad stuff
- var/digestable = FALSE
- var/devourable = FALSE
- var/feeding = FALSE
- var/lickable = FALSE
+ var/vore_flags = 0
var/list/belly_prefs = list()
var/vore_taste = "nothing in particular"
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 05ad9a16d6..b145cc9a34 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
-#define SAVEFILE_VERSION_MAX 28
+#define SAVEFILE_VERSION_MAX 29
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -120,10 +120,14 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(fexists(vr_path))
var/list/json_from_file = json_decode(file2text(vr_path))
if(json_from_file)
- digestable = json_from_file["digestable"]
- devourable = json_from_file["devourable"]
- feeding = json_from_file["feeding"]
- lickable = json_from_file["lickable"]
+ if(json_from_file["digestable"])
+ ENABLE_BITFIELD(vore_flags,DIGESTABLE)
+ if(json_from_file["devourable"])
+ ENABLE_BITFIELD(vore_flags,DEVOURABLE)
+ if(json_from_file["feeding"])
+ ENABLE_BITFIELD(vore_flags,FEEDING)
+ if(json_from_file["lickable"])
+ ENABLE_BITFIELD(vore_flags,LICKABLE)
belly_prefs = json_from_file["belly_prefs"]
vore_taste = json_from_file["vore_taste"]
@@ -158,6 +162,24 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(malformed_hockeys[hockey])
features["cock_shape"] = malformed_hockeys[hockey]
features["cock_taur"] = TRUE
+
+ if(current_version < 29)
+ var/digestable
+ var/devourable
+ var/feeding
+ var/lickable
+ S["digestable"] >> digestable
+ S["devourable"] >> devourable
+ S["feeding"] >> feeding
+ S["lickable"] >> lickable
+ if(digestable)
+ ENABLE_BITFIELD(vore_flags,DIGESTABLE)
+ if(devourable)
+ ENABLE_BITFIELD(vore_flags,DEVOURABLE)
+ if(feeding)
+ ENABLE_BITFIELD(vore_flags,FEEDING)
+ if(lickable)
+ ENABLE_BITFIELD(vore_flags,LICKABLE)
if(current_version < 29)
switch(features["taur"])
@@ -508,11 +530,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
else //We have no old flavortext, default to new
S["feature_flavor_text"] >> features["flavor_text"]
- S["digestable"] >> digestable
- S["devourable"] >> devourable
- S["feeding"] >> feeding
+ S["vore_flags"] >> vore_flags
S["vore_taste"] >> vore_taste
- S["lickable"] >> lickable
S["belly_prefs"] >> belly_prefs
//try to fix any outdated data if necessary
@@ -632,10 +651,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
all_quirks = SANITIZE_LIST(all_quirks)
- lickable = sanitize_integer(lickable, FALSE, TRUE, initial(lickable))
- devourable = sanitize_integer(devourable, FALSE, TRUE, initial(devourable))
- digestable = sanitize_integer(digestable, FALSE, TRUE, initial(digestable))
- feeding = sanitize_integer(feeding, FALSE, TRUE, initial(feeding))
+ vore_flags = sanitize_integer(vore_flags, 0, MAX_VORE_FLAG, 0)
vore_taste = copytext(vore_taste, 1, MAX_TASTE_LEN)
belly_prefs = SANITIZE_LIST(belly_prefs)
@@ -745,11 +761,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//Quirks
WRITE_FILE(S["all_quirks"] , all_quirks)
- WRITE_FILE(S["digestable"] , digestable)
- WRITE_FILE(S["devourable"] , devourable)
- WRITE_FILE(S["feeding"] , feeding)
+ WRITE_FILE(S["vore_flags"] , vore_flags)
WRITE_FILE(S["vore_taste"] , vore_taste)
- WRITE_FILE(S["lickable"] , lickable)
WRITE_FILE(S["belly_prefs"] , belly_prefs)
cit_character_pref_save(S)
diff --git a/code/modules/clothing/under/trek.dm b/code/modules/clothing/under/trek.dm
index a9709a4c95..bc64168142 100644
--- a/code/modules/clothing/under/trek.dm
+++ b/code/modules/clothing/under/trek.dm
@@ -44,6 +44,7 @@
/obj/item/clothing/under/trek/medsci/next
desc = "The uniform worn by medsci officers. This one's from the mid 2360s."
icon_state = "trek_next_medsci"
+ item_state = "b_suit"
//ENT
@@ -67,35 +68,51 @@
/obj/item/clothing/under/trek/command/voy
desc = "The uniform worn by command officers of the 2370s."
icon_state = "trek_voy_command"
- item_state = "trek_voy_command"
+ item_state = "r_suit"
/obj/item/clothing/under/trek/engsec/voy
desc = "The uniform worn by operations officers of the 2370s."
icon_state = "trek_voy_engsec"
- item_state = "trek_voy_engsec"
+ item_state = "y_suit"
/obj/item/clothing/under/trek/medsci/voy
desc = "The uniform worn by medsci officers of the 2370s."
icon_state = "trek_voy_medsci"
- item_state = "trek_voy_medsci"
+ item_state = "b_suit"
//DS9
/obj/item/clothing/under/trek/command/ds9
desc = "The uniform worn by command officers of the 2380s."
icon_state = "trek_ds9_command"
- item_state = "trek_ds9_command"
+ item_state = "r_suit"
/obj/item/clothing/under/trek/engsec/ds9
desc = "The uniform worn by operations officers of the 2380s."
icon_state = "trek_ds9_engsec"
- item_state = "trek_ds9_engsec"
+ item_state = "y_suit"
/obj/item/clothing/under/trek/medsci/ds9
desc = "The uniform undershirt worn by medsci officers of the 2380s."
icon_state = "trek_ds9_medsci"
- item_state = "trek_ds9_medsci"
+ item_state = "b_suit"
+//The Motion Picture
+/obj/item/clothing/under/trek/fedutil
+ name = "federation utility uniform"
+ desc = "The uniform worn by United Federation enlisted crew members in 2285s."
+ icon_state = "trek_tmp_enlist"
+ item_state = "r_suit"
+
+/obj/item/clothing/under/trek/fedutil/trainee
+ name = "federation trainee utility uniform"
+ desc = "The uniform worn by United Federation enlisted trainees in 2285s."
+ icon_state = "trek_tmp_trainee"
+
+/obj/item/clothing/under/trek/fedutil/service
+ name = "federation service uniform"
+ desc = "The uniform worn by United Federation enlists for service work in 2285s."
+ icon_state = "trek_tmp_service"
//Q
/obj/item/clothing/under/trek/Q
diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm
index 0b277e328b..8476795a1a 100644
--- a/code/modules/food_and_drinks/food/snacks.dm
+++ b/code/modules/food_and_drinks/food/snacks.dm
@@ -283,7 +283,7 @@ All foods are distributed among various categories. Use common sense.
S.create_reagents(S.volume, reagent_flags, reagent_value)
if(reagents)
reagents.trans_to(S, reagents.total_volume)
- if(S.bonus_reagents && S.bonus_reagents.len)
+ if(cooking_efficiency && length(S.bonus_reagents))
for(var/r_id in S.bonus_reagents)
var/amount = S.bonus_reagents[r_id] * cooking_efficiency
if(r_id == /datum/reagent/consumable/nutriment || r_id == /datum/reagent/consumable/nutriment/vitamin)
diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm
index ecd9074950..c5268380a1 100644
--- a/code/modules/food_and_drinks/food/snacks_pastry.dm
+++ b/code/modules/food_and_drinks/food/snacks_pastry.dm
@@ -440,6 +440,40 @@
filling_color = "#CD853F"
tastes = list("meat" = 2, "dough" = 2, "laziness" = 1)
foodtype = GRAIN
+ var/list/cached_reagents_amount
+ var/previous_typepath
+
+/obj/item/reagent_containers/food/snacks/donkpocket/Initialize(mapload)
+ . = ..()
+ if(!cooked_type) //maploaded cooked donk pockets won't cool down anyway.
+ desc += " This one will stay warm for a long time, great."
+
+/obj/item/reagent_containers/food/snacks/donkpocket/initialize_cooked_food(obj/item/reagent_containers/food/snacks/donkpocket/S, cooking_efficiency = 1)
+ . = ..()
+ if(istype(S))
+ desc = initial(desc) //reset the desc since will now cool down.
+ for(var/R in S.bonus_reagents)
+ LAZYSET(S.cached_reagents_amount, R, S.reagents.get_reagent_amount(R))
+ S.previous_typepath = type
+ addtimer(CALLBACK(S, .proc/cool_down), 7 MINUTES) //canonically they reverted back to normal after 7 minutes.
+
+/obj/item/reagent_containers/food/snacks/donkpocket/proc/cool_down()
+ if(!previous_typepath) //This shouldn't happen.
+ qdel(src)
+ return
+ var/spoiled = FALSE
+ for(var/R in cached_reagents_amount)
+ var/amount = cached_reagents_amount[R]
+ if(reagents.get_reagent_amount(R) < amount)
+ spoiled = TRUE
+ reagents.remove_reagent(R, amount) //no reagent duping please.
+ var/obj/item/reagent_containers/food/snacks/donkpocket/D = new previous_typepath(drop_location())
+ D.create_reagents(D.volume, reagent_flags, reagent_value)
+ reagents.trans_to(D, reagents.total_volume)
+ if(spoiled)
+ D.cooked_type = null
+ D.desc += " This one has gone cold and mushy, pretty unsuitable for cooking."
+ qdel(src)
/obj/item/reagent_containers/food/snacks/donkpocket/warm
name = "warm Donk-pocket"
diff --git a/code/modules/holodeck/holo_effect.dm b/code/modules/holodeck/holo_effect.dm
index 308cec1cbd..7c3754b616 100644
--- a/code/modules/holodeck/holo_effect.dm
+++ b/code/modules/holodeck/holo_effect.dm
@@ -81,9 +81,7 @@
ENABLE_BITFIELD(mob.flags_1, HOLOGRAM_1)
if(isliving(mob))
var/mob/living/L = mob
- L.feeding = FALSE
- L.devourable = FALSE
- L.digestable = FALSE
+ L.vore_flags = 0
return mob
/obj/effect/holodeck_effect/mobspawner/deactivate(var/obj/machinery/computer/holodeck/HC)
diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm
index 95746afb73..7918e303e8 100644
--- a/code/modules/mob/living/carbon/human/dummy.dm
+++ b/code/modules/mob/living/carbon/human/dummy.dm
@@ -4,7 +4,6 @@
status_flags = GODMODE|CANPUSH
mouse_drag_pointer = MOUSE_INACTIVE_POINTER
var/in_use = FALSE
- no_vore = TRUE
INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
diff --git a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
index d4b8ea7897..b6d56b8e5d 100644
--- a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
@@ -74,9 +74,7 @@
//misc
/mob/living/carbon/human/dummy
- no_vore = TRUE
+ vore_flags = NO_VORE
/mob/living/carbon/human/vore
- devourable = TRUE
- digestable = TRUE
- feeding = TRUE
+ vore_flags = DEVOURABLE | DIGESTABLE | FEEDING
diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm
index e0bd8a16b3..931f87eb7c 100644
--- a/code/modules/mob/living/login.dm
+++ b/code/modules/mob/living/login.dm
@@ -23,5 +23,5 @@
if(ranged_ability)
ranged_ability.add_ranged_ability(src, "You currently have [ranged_ability] active!")
- if(vore_init && !vorepref_init) //Vore's been initialized, voreprefs haven't. If this triggers then that means that voreprefs failed to load due to the client being missing.
+ if((vore_flags & VORE_INIT) && !(vore_flags & VOREPREF_INIT)) //Vore's been initialized, voreprefs haven't. If this triggers then that means that voreprefs failed to load due to the client being missing.
copy_from_prefs_vr()
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 7ebd11319d..a4aeeb2ffc 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -14,7 +14,7 @@
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
speech_span = SPAN_ROBOT
flags_1 = PREVENT_CONTENTS_EXPLOSION_1 | HEAR_1
- no_vore = TRUE
+ vore_flags = NO_VORE
/// Enable sprint system but not stamina
combat_flags = COMBAT_FLAGS_STAMEXEMPT_YESSPRINT
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index e496d007a2..cae8948fdd 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -347,10 +347,11 @@
/mob/living/simple_animal/hostile/proc/AttackingTarget()
SEND_SIGNAL(src, COMSIG_HOSTILE_ATTACKINGTARGET, target)
in_melee = TRUE
+ /* sorry for the simplemob vore fans
if(vore_active)
if(isliving(target))
var/mob/living/L = target
- if(!client && L.Adjacent(src) && L.devourable) // aggressive check to ensure vore attacks can be made
+ if(!client && L.Adjacent(src) && CHECK_BITFIELD(L.vore_flags,DEVOURABLE)) // aggressive check to ensure vore attacks can be made
if(prob(voracious_chance))
vore_attack(src,L,src)
else
@@ -361,6 +362,8 @@
return target.attack_animal(src)
else
return target.attack_animal(src)
+ */
+ return target.attack_animal(src)
/mob/living/simple_animal/hostile/proc/Aggro()
vision_range = aggro_vision_range
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm
index 8c06b01402..a2d18c508e 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm
@@ -1,6 +1,5 @@
/mob/living/simple_animal/hostile/megafauna/dragon
vore_active = TRUE
- no_vore = FALSE
isPredator = TRUE
/mob/living/simple_animal/hostile/megafauna/dragon/Initialize()
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
index 8aed1ede30..8958916880 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
@@ -87,7 +87,7 @@
if(!client && ranged && ranged_cooldown <= world.time)
OpenFire()
if(L.Adjacent(src) && (L.stat != CONSCIOUS))
- if(vore_active && L.devourable == TRUE)
+ if(vore_active && CHECK_BITFIELD(L.vore_flags,DEVOURABLE))
vore_attack(src,L,src)
LoseTarget()
else
diff --git a/code/modules/mob/living/simple_animal/simple_animal_vr.dm b/code/modules/mob/living/simple_animal/simple_animal_vr.dm
index 700ee3b7ce..de5bb578b8 100644
--- a/code/modules/mob/living/simple_animal/simple_animal_vr.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal_vr.dm
@@ -49,54 +49,53 @@
// Simple animals have only one belly. This creates it (if it isn't already set up)
/mob/living/simple_animal/init_vore()
- vore_init = TRUE
+ ENABLE_BITFIELD(vore_flags, VORE_INIT)
if(CHECK_BITFIELD(flags_1, HOLOGRAM_1))
return
- if(!vore_active || no_vore) //If it can't vore, let's not give it a stomach.
+ if(!vore_active || CHECK_BITFIELD(vore_flags, NO_VORE)) //If it can't vore, let's not give it a stomach.
return
if(vore_active && !IsAdvancedToolUser()) //vore active, but doesn't have thumbs to grab people with.
verbs |= /mob/living/simple_animal/proc/animal_nom
- if(LAZYLEN(vore_organs))
- return
-
- LAZYINITLIST(vore_organs)
- var/obj/belly/B = new (src)
- vore_selected = B
- B.immutable = TRUE
- B.name = vore_stomach_name ? vore_stomach_name : "stomach"
- B.desc = vore_stomach_flavor ? vore_stomach_flavor : "Your surroundings are warm, soft, and slimy. Makes sense, considering you're inside \the [name]."
- B.digest_mode = vore_default_mode
- B.vore_sound = vore_default_sound
- B.release_sound = vore_default_release
- B.is_wet = vore_wetness
- B.escapable = vore_escape_chance > 0
- B.escapechance = vore_escape_chance
- B.digestchance = vore_digest_chance
- B.absorbchance = vore_absorb_chance
- B.human_prey_swallow_time = swallowTime
- B.nonhuman_prey_swallow_time = swallowTime
- B.vore_verb = "swallow"
- B.emote_lists[DM_HOLD] = list( // We need more that aren't repetitive. I suck at endo. -Ace
- "The insides knead at you gently for a moment.",
- "The guts glorp wetly around you as some air shifts.",
- "The predator takes a deep breath and sighs, shifting you somewhat.",
- "The stomach squeezes you tight for a moment, then relaxes harmlessly.",
- "The predator's calm breathing and thumping heartbeat pulses around you.",
- "The warm walls kneads harmlessly against you.",
- "The liquids churn around you, though there doesn't seem to be much effect.",
- "The sound of bodily movements drown out everything for a moment.",
- "The predator's movements gently force you into a different position.")
- B.emote_lists[DM_DIGEST] = list(
- "The burning acids eat away at your form.",
- "The muscular stomach flesh grinds harshly against you.",
- "The caustic air stings your chest when you try to breathe.",
- "The slimy guts squeeze inward to help the digestive juices soften you up.",
- "The onslaught against your body doesn't seem to be letting up; you're food now.",
- "The predator's body ripples and crushes against you as digestive enzymes pull you apart.",
- "The juices pooling beneath you sizzle against your sore skin.",
- "The churning walls slowly pulverize you into meaty nutrients.",
- "The stomach glorps and gurgles as it tries to work you into slop.")
+/mob/living/simple_animal/lazy_init_belly()
+ if(!LAZYLEN(vore_organs))
+ LAZYINITLIST(vore_organs)
+ var/obj/belly/B = new (src)
+ vore_selected = B
+ B.immutable = TRUE
+ B.name = vore_stomach_name ? vore_stomach_name : "stomach"
+ B.desc = vore_stomach_flavor ? vore_stomach_flavor : "Your surroundings are warm, soft, and slimy. Makes sense, considering you're inside \the [name]."
+ B.digest_mode = vore_default_mode
+ B.vore_sound = vore_default_sound
+ B.release_sound = vore_default_release
+ B.is_wet = vore_wetness
+ B.escapable = vore_escape_chance > 0
+ B.escapechance = vore_escape_chance
+ B.digestchance = vore_digest_chance
+ B.absorbchance = vore_absorb_chance
+ B.human_prey_swallow_time = swallowTime
+ B.nonhuman_prey_swallow_time = swallowTime
+ B.vore_verb = "swallow"
+ B.emote_lists[DM_HOLD] = list( // We need more that aren't repetitive. I suck at endo. -Ace
+ "The insides knead at you gently for a moment.",
+ "The guts glorp wetly around you as some air shifts.",
+ "The predator takes a deep breath and sighs, shifting you somewhat.",
+ "The stomach squeezes you tight for a moment, then relaxes harmlessly.",
+ "The predator's calm breathing and thumping heartbeat pulses around you.",
+ "The warm walls kneads harmlessly against you.",
+ "The liquids churn around you, though there doesn't seem to be much effect.",
+ "The sound of bodily movements drown out everything for a moment.",
+ "The predator's movements gently force you into a different position.")
+ B.emote_lists[DM_DIGEST] = list(
+ "The burning acids eat away at your form.",
+ "The muscular stomach flesh grinds harshly against you.",
+ "The caustic air stings your chest when you try to breathe.",
+ "The slimy guts squeeze inward to help the digestive juices soften you up.",
+ "The onslaught against your body doesn't seem to be letting up; you're food now.",
+ "The predator's body ripples and crushes against you as digestive enzymes pull you apart.",
+ "The juices pooling beneath you sizzle against your sore skin.",
+ "The churning walls slowly pulverize you into meaty nutrients.",
+ "The stomach glorps and gurgles as it tries to work you into slop.")
//
// Simple proc for animals to have their digestion toggled on/off externally
@@ -134,6 +133,6 @@
if (stat != CONSCIOUS)
return
- if(!T.devourable)
+ if(!CHECK_BITFIELD(T.vore_flags,DEVOURABLE))
return
return vore_attack(src,T,src)
diff --git a/code/modules/mob/living/simple_animal/simplemob_vore_values.dm b/code/modules/mob/living/simple_animal/simplemob_vore_values.dm
index 22ed5e3ab4..3c911c1fcf 100644
--- a/code/modules/mob/living/simple_animal/simplemob_vore_values.dm
+++ b/code/modules/mob/living/simple_animal/simplemob_vore_values.dm
@@ -1,13 +1,9 @@
//CARBON MOBS
/mob/living/carbon/alien
- devourable = TRUE
- digestable = TRUE
- feeding = TRUE
+ vore_flags = DEVOURABLE | DIGESTABLE | FEEDING
/mob/living/carbon/monkey
- devourable = TRUE
- digestable = TRUE
- feeding = TRUE
+ vore_flags = DEVOURABLE | DIGESTABLE | FEEDING
/*
@@ -17,121 +13,68 @@
//NUETRAL MOBS
/mob/living/simple_animal/crab
- devourable = TRUE
- digestable = TRUE
- feeding = TRUE
+ vore_flags = DEVOURABLE | DIGESTABLE | FEEDING
/mob/living/simple_animal/cow
- devourable = TRUE
- digestable = TRUE
- feeding = TRUE
- vore_active = TRUE
- isPredator = TRUE
- vore_default_mode = DM_HOLD
+ vore_flags = DEVOURABLE | DIGESTABLE | FEEDING
/mob/living/simple_animal/chick
- devourable = TRUE
- digestable = TRUE
+ vore_flags = DEVOURABLE | DIGESTABLE
/mob/living/simple_animal/chicken
- devourable = TRUE
- digestable = TRUE
+ vore_flags = DEVOURABLE | DIGESTABLE
/mob/living/simple_animal/mouse
- devourable = TRUE
- digestable = TRUE
+ vore_flags = DEVOURABLE | DIGESTABLE
/mob/living/simple_animal/kiwi
- devourable = TRUE
- digestable = TRUE
+ vore_flags = DEVOURABLE | DIGESTABLE
//STATION PETS
/mob/living/simple_animal/pet
- devourable = TRUE
- digestable = TRUE
- feeding = TRUE
-
-/mob/living/simple_animal/pet/fox
- vore_active = TRUE
- isPredator = TRUE
- vore_default_mode = DM_HOLD
-
-/mob/living/simple_animal/pet/cat
- vore_active = TRUE
- isPredator = TRUE
- vore_default_mode = DM_HOLD
-
-/mob/living/simple_animal/pet/dog
- vore_active = TRUE
- isPredator = TRUE
+ vore_flags = DEVOURABLE | DIGESTABLE | FEEDING
vore_default_mode = DM_HOLD
/mob/living/simple_animal/sloth
- devourable = TRUE
- digestable = TRUE
+ vore_flags = DEVOURABLE | DIGESTABLE
/mob/living/simple_animal/parrot
- devourable = TRUE
- digestable = TRUE
+ vore_flags = DEVOURABLE | DIGESTABLE
//HOSTILE MOBS
/mob/living/simple_animal/hostile/retaliate/goat
- devourable = TRUE
- digestable = TRUE
- feeding = TRUE
- vore_active = TRUE
- isPredator = TRUE
- vore_stomach_flavor = "You find yourself squeezed into the hollow of the goat, the smell of oats and hay thick in the tight space, all of which grinds in on you. Harmless for now..."
+ vore_flags = DEVOURABLE | DIGESTABLE | FEEDING
vore_default_mode = DM_HOLD
+
/mob/living/simple_animal/hostile/lizard
- devourable = TRUE
- digestable = TRUE
- feeding = TRUE
- vore_active = TRUE
- isPredator = TRUE
+ vore_flags = DEVOURABLE | DIGESTABLE | FEEDING
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/alien
- feeding = TRUE
- vore_active = TRUE
- isPredator = TRUE
+ vore_flags = FEEDING
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/bear
- feeding = TRUE
- vore_active = TRUE
- isPredator = TRUE
+ vore_flags = FEEDING
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/poison/giant_spider
- feeding = TRUE
- vore_active = TRUE
- isPredator = TRUE
+ vore_flags = FEEDING
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/retaliate/poison/snake
- feeding = TRUE
- vore_active = TRUE
- isPredator = TRUE
+ vore_flags = FEEDING
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/gorilla
- feeding = TRUE
- vore_active = TRUE
- isPredator = TRUE
+ vore_flags = FEEDING
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/asteroid/goliath
- feeding = TRUE //for pet Goliaths I guess or something.
- vore_active = TRUE
- isPredator = TRUE
+ vore_flags = FEEDING
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/carp
- devourable = TRUE
- digestable = TRUE
- feeding = TRUE
- vore_active = TRUE
- isPredator = TRUE
+ vore_flags = DEVOURABLE | DIGESTABLE | FEEDING
vore_default_mode = DM_DIGEST
diff --git a/code/modules/uplink/uplink_items/uplink_bundles.dm b/code/modules/uplink/uplink_items/uplink_bundles.dm
index 7d0e52947a..f3e95fa61c 100644
--- a/code/modules/uplink/uplink_items/uplink_bundles.dm
+++ b/code/modules/uplink/uplink_items/uplink_bundles.dm
@@ -150,6 +150,23 @@
U.purchase_log.LogPurchase(goods, I, 0)
return C
+/datum/uplink_item/bundles_TC/reroll
+ name = "Renegotiate Contract"
+ desc = "Selecting this will inform the syndicate that you wish to change employers. Can only be done once; no take-backs."
+ item = /obj/effect/gibspawner/generic
+ cost = 0
+ cant_discount = TRUE
+ restricted = TRUE
+ limited_stock = 1
+
+/datum/uplink_item/bundles_TC/reroll/purchase(mob/user, datum/component/uplink/U)
+ var/datum/antagonist/traitor/T = user?.mind?.has_antag_datum(/datum/antagonist/traitor)
+ if(istype(T))
+ var/new_traitor_kind = get_random_traitor_kind(list(T.traitor_kind.type))
+ T.set_traitor_kind(new_traitor_kind)
+ else
+ to_chat(user,"Invalid user for contract renegotiation.")
+
/datum/uplink_item/bundles_TC/random
name = "Random Item"
desc = "Picking this will purchase a random item. Useful if you have some TC to spare or if you haven't decided on a strategy yet."
diff --git a/code/modules/vore/eating/belly_obj.dm b/code/modules/vore/eating/belly_obj.dm
index ca774ed1f6..b188cc0a99 100644
--- a/code/modules/vore/eating/belly_obj.dm
+++ b/code/modules/vore/eating/belly_obj.dm
@@ -221,9 +221,9 @@
if(isliving(AM))
var/mob/living/L = AM
var/mob/living/OW = owner
- if(L.absorbed && !include_absorbed)
+ if(L.vore_flags & ABSORBED && !include_absorbed)
continue
- L.absorbed = FALSE
+ L.vore_flags &= ~ABSORBED
L.stop_sound_channel(CHANNEL_PREYLOOP)
SEND_SIGNAL(OW, COMSIG_CLEAR_MOOD_EVENT, "fedpred", /datum/mood_event/fedpred)
SEND_SIGNAL(L, COMSIG_CLEAR_MOOD_EVENT, "fedprey", /datum/mood_event/fedprey)
@@ -277,14 +277,14 @@
SEND_SIGNAL(OW, COMSIG_ADD_MOOD_EVENT, "emptypred", /datum/mood_event/emptypred)
SEND_SIGNAL(ML, COMSIG_ADD_MOOD_EVENT, "emptyprey", /datum/mood_event/emptyprey)
- if(ML.absorbed)
- ML.absorbed = FALSE
+ if(CHECK_BITFIELD(ML.vore_flags,ABSORBED))
+ DISABLE_BITFIELD(ML.vore_flags,ABSORBED)
if(ishuman(M) && ishuman(OW))
var/mob/living/carbon/human/Prey = M
var/mob/living/carbon/human/Pred = OW
var/absorbed_count = 2 //Prey that we were, plus the pred gets a portion
for(var/mob/living/P in contents)
- if(P.absorbed)
+ if(CHECK_BITFIELD(P.vore_flags,ABSORBED))
absorbed_count++
Pred.reagents.trans_to(Prey, Pred.reagents.total_volume / absorbed_count)
@@ -389,7 +389,7 @@
formatted_message = replacetext(formatted_message,"%pred",owner)
formatted_message = replacetext(formatted_message,"%prey",english_list(contents))
for(var/mob/living/P in contents)
- if(!P.absorbed) //This is required first, in case there's a person absorbed and not absorbed in a stomach.
+ if(!CHECK_BITFIELD(P.vore_flags, ABSORBED)) //This is required first, in case there's a person absorbed and not absorbed in a stomach.
total_bulge += P.mob_size
if(total_bulge >= bulge_size && bulge_size != 0)
return("[formatted_message]
")
@@ -484,7 +484,7 @@
// Handle a mob being absorbed
/obj/belly/proc/absorb_living(var/mob/living/M)
- M.absorbed = TRUE
+ ENABLE_BITFIELD(M.vore_flags, ABSORBED)
to_chat(M,"[owner]'s [lowertext(name)] absorbs your body, making you part of them.")
to_chat(owner,"Your [lowertext(name)] absorbs [M]'s body, making them part of you.")
@@ -498,7 +498,7 @@
for(var/belly in M.vore_organs)
var/obj/belly/B = belly
for(var/mob/living/Mm in B)
- if(Mm.absorbed)
+ if(CHECK_BITFIELD(Mm.vore_flags, ABSORBED))
absorb_living(Mm)
//Update owner
diff --git a/code/modules/vore/eating/bellymodes.dm b/code/modules/vore/eating/bellymodes.dm
index 965648eb5a..2caaae401e 100644
--- a/code/modules/vore/eating/bellymodes.dm
+++ b/code/modules/vore/eating/bellymodes.dm
@@ -1,6 +1,6 @@
// Process the predator's effects upon the contents of its belly (i.e digestion/transformation etc)
/obj/belly/proc/process_belly(var/times_fired,var/wait) //Passed by controller
- if((times_fired < next_process) || !contents.len)
+ if((times_fired < next_process) || !length(contents))
recent_sound = FALSE
return SSBELLIES_IGNORED
@@ -27,7 +27,7 @@
var/list/EL = emote_lists[digest_mode]
if(LAZYLEN(EL))
for(var/mob/living/M in contents)
- if(M.digestable || !(digest_mode == DM_DIGEST)) // don't give digesty messages to indigestible people
+ if((M.vore_flags & DIGESTABLE) || !(digest_mode == DM_DIGEST)) // don't give digesty messages to indigestible people
to_chat(M,"[pick(EL)]")
///////////////////// Prey Loop Refresh/hack //////////////////////
@@ -51,7 +51,7 @@
//////////////////////// Absorbed Handling ////////////////////////
for(var/mob/living/M in contents)
- if(M.absorbed)
+ if(M.vore_flags & ABSORBED)
M.Stun(5)
////////////////////////// Sound vars /////////////////////////////
@@ -76,7 +76,7 @@
play_sound = pick(pred_digest)
//Pref protection!
- if (!M.digestable || M.absorbed)
+ if (!M.vore_flags & DIGESTABLE || M.vore_flags & ABSORBED)
continue
//Person just died in guts!
@@ -150,7 +150,7 @@
SEND_SOUND(M,prey_digest)
play_sound = pick(pred_digest)
- if(M.absorbed)
+ if(M.vore_flags & ABSORBED)
continue
if(M.nutrition >= 100) //Drain them until there's no nutrients left. Slowly "absorb" them.
@@ -164,8 +164,8 @@
if(DM_UNABSORB)
for (var/mob/living/M in contents)
- if(M.absorbed && owner.nutrition >= 100)
- M.absorbed = FALSE
+ if(M.vore_flags & ABSORBED && owner.nutrition >= 100)
+ DISABLE_BITFIELD(M.vore_flags, ABSORBED)
to_chat(M,"You suddenly feel solid again ")
to_chat(owner,"You feel like a part of you is missing.")
owner.nutrition -= 100
diff --git a/code/modules/vore/eating/living.dm b/code/modules/vore/eating/living.dm
index c59662d5b6..33f8d78300 100644
--- a/code/modules/vore/eating/living.dm
+++ b/code/modules/vore/eating/living.dm
@@ -1,18 +1,11 @@
///////////////////// Mob Living /////////////////////
/mob/living
- var/digestable = FALSE // Can the mob be digested inside a belly?
+ var/vore_flags = 0
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/no_vore = FALSE // If the character/mob can vore.
- var/openpanel = FALSE // Is the vore panel open?
- var/absorbed = FALSE //are we absorbed?
var/next_preyloop
- var/vore_init = FALSE //Has this mob's vore been initialized yet?
- var/vorepref_init = FALSE //Has this mob's voreprefs been initialized?
//
// Hook for generic creation of stuff on new creatures
@@ -22,7 +15,7 @@
M.verbs += /mob/living/proc/lick
M.verbs += /mob/living/proc/escapeOOC
- if(M.no_vore) //If the mob isn't supposed to have a stomach, let's not give it an insidepanel so it can make one for itself, or a stomach.
+ if(M.vore_flags & NO_VORE) //If the mob isn't supposed to have a stomach, let's not give it an insidepanel so it can make one for itself, or a stomach.
return TRUE
M.verbs += /mob/living/proc/insidePanel
@@ -35,7 +28,7 @@
return TRUE
/mob/living/proc/init_vore()
- vore_init = TRUE
+ ENABLE_BITFIELD(vore_flags, VORE_INIT)
//Something else made organs, meanwhile.
if(LAZYLEN(vore_organs))
return TRUE
@@ -49,8 +42,8 @@
vore_selected = vore_organs[1]
return TRUE
- //Or, we can create a basic one for them
- if(!LAZYLEN(vore_organs))
+/mob/living/proc/lazy_init_belly()
+ if(!length(vore_organs))
LAZYINITLIST(vore_organs)
var/obj/belly/B = new /obj/belly(src)
vore_selected = B
@@ -68,6 +61,7 @@
// Critical adjustments due to TG grab changes - Poojawa
/mob/living/proc/vore_attack(var/mob/living/user, var/mob/living/prey, var/mob/living/pred)
+ lazy_init_belly()
if(!user || !prey || !pred)
return
@@ -75,7 +69,7 @@
return
if(pred == prey) //you click your target
- if(!pred.feeding)
+ if(!CHECK_BITFIELD(pred.vore_flags,FEEDING))
to_chat(user, "They aren't able to be fed.")
to_chat(pred, "[user] tried to feed you themselves, but you aren't voracious enough to be fed.")
return
@@ -91,11 +85,11 @@
feed_grabbed_to_self(user, prey)
else // click someone other than you/prey
- if(!pred.feeding)
+ if(!CHECK_BITFIELD(pred.vore_flags,FEEDING))
to_chat(user, "They aren't voracious enough to be fed.")
to_chat(pred, "[user] tried to feed you [prey], but you aren't voracious enough to be fed.")
return
- if(!prey.feeding)
+ if(!CHECK_BITFIELD(prey.vore_flags,FEEDING))
to_chat(user, "They aren't able to be fed to someone.")
to_chat(prey, "[user] tried to feed you to [pred], but you aren't able to be fed to them.")
return
@@ -107,14 +101,17 @@
// Eating procs depending on who clicked what
//
/mob/living/proc/feed_grabbed_to_self(var/mob/living/user, var/mob/living/prey)
+ user.lazy_init_belly()
var/belly = user.vore_selected
return perform_the_nom(user, prey, user, belly)
/mob/living/proc/feed_self_to_grabbed(var/mob/living/user, var/mob/living/pred)
+ pred.lazy_init_belly()
var/belly = input("Choose Belly") in pred.vore_organs
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)
+ pred.lazy_init_belly()
var/belly = input("Choose Belly") in pred.vore_organs
return perform_the_nom(user, prey, pred, belly)
@@ -128,7 +125,7 @@
testing("[user] attempted to feed [prey] to [pred], via [lowertext(belly.name)] but it went wrong.")
return
- if (!prey.devourable)
+ if (!prey.vore_flags & DEVOURABLE)
to_chat(user, "This can't be eaten!")
return FALSE
@@ -267,9 +264,7 @@
to_chat(src,"You attempted to save your vore prefs but somehow you're in this character without a client.prefs variable. Tell a dev.")
return FALSE
- client.prefs.digestable = digestable
- client.prefs.devourable = devourable
- client.prefs.feeding = feeding
+ client.prefs.vore_flags = vore_flags // there's garbage data in here, but it doesn't matter
client.prefs.vore_taste = vore_taste
var/list/serialized = list()
@@ -288,12 +283,17 @@
if(!client || !client.prefs)
to_chat(src,"You attempted to apply your vore prefs but somehow you're in this character without a client.prefs variable. Tell a dev.")
return FALSE
- vorepref_init = TRUE
+ ENABLE_BITFIELD(vore_flags,VOREPREF_INIT)
+ // garbage data coming back the other way or breaking absorbed would be bad, so instead we do this
+ vore_flags |= CHECK_BITFIELD(client.prefs.vore_flags,DIGESTABLE) // set to 1 if prefs is 1
+ vore_flags |= CHECK_BITFIELD(client.prefs.vore_flags,DEVOURABLE)
+ vore_flags |= CHECK_BITFIELD(client.prefs.vore_flags,FEEDING)
+
+ vore_flags &= CHECK_BITFIELD(client.prefs.vore_flags,DIGESTABLE) // set to 0 if prefs is 0
+ vore_flags &= CHECK_BITFIELD(client.prefs.vore_flags,DEVOURABLE)
+ vore_flags &= CHECK_BITFIELD(client.prefs.vore_flags,FEEDING)
- digestable = client.prefs.digestable
- devourable = client.prefs.devourable
- feeding = client.prefs.feeding
vore_taste = client.prefs.vore_taste
release_vore_contents(silent = TRUE)
@@ -361,7 +361,7 @@
var/list/choices
for(var/mob/living/L in view(1))
- if(L != src && (!L.ckey || L.client?.prefs.lickable) && Adjacent(L))
+ if(L != src && (!L.ckey || L.client?.prefs.vore_flags & LICKABLE) && Adjacent(L))
LAZYADD(choices, L)
if(!choices)
@@ -369,7 +369,7 @@
var/mob/living/tasted = input(src, "Who would you like to lick? (Excluding yourself and those with the preference disabled)", "Licking") as null|anything in choices
- if(QDELETED(tasted) || (tasted.ckey && !(tasted.client?.prefs.lickable)) || !Adjacent(tasted) || incapacitated(ignore_restraints = TRUE))
+ if(QDELETED(tasted) || (tasted.ckey && !(tasted.client?.prefs.vore_flags & LICKABLE)) || !Adjacent(tasted) || incapacitated(ignore_restraints = TRUE))
return
setClickCooldown(100)
diff --git a/code/modules/vore/eating/vorepanel.dm b/code/modules/vore/eating/vorepanel.dm
index 9c1ff4a84e..1adf5ef6e7 100644
--- a/code/modules/vore/eating/vorepanel.dm
+++ b/code/modules/vore/eating/vorepanel.dm
@@ -20,10 +20,10 @@
picker_holder.popup = new(src, "insidePanel","Vore Panel", 450, 700, picker_holder)
picker_holder.popup.set_content(dat)
picker_holder.popup.open()
- src.openpanel = TRUE
+ vore_flags |= OPEN_PANEL
/mob/living/proc/updateVRPanel() //Panel popup update call from belly events.
- if(src.openpanel == TRUE)
+ if(vore_flags & OPEN_PANEL)
var/datum/vore_look/picker_holder = new()
picker_holder.loop = picker_holder
picker_holder.selected = vore_selected
@@ -65,7 +65,7 @@
//Don't display this part if we couldn't find the belly since could be held in hand.
if(inside_belly)
- dat += "You are currently [user.absorbed ? "absorbed into " : "inside "] [eater]'s [inside_belly]!
"
+ dat += "You are currently [(user.vore_flags & ABSORBED) ? "absorbed into " : "inside "] [eater]'s [inside_belly]!
"
if(inside_belly.desc)
dat += "[inside_belly.desc]
"
@@ -80,8 +80,8 @@
continue
//That's an absorbed person you're checking
- if(M.absorbed)
- if(user.absorbed)
+ if(M.vore_flags & ABSORBED)
+ if(user.vore_flags & ABSORBED)
dat += "[O]"
continue
else
@@ -139,7 +139,7 @@
var/mob/living/M = O
//Absorbed gets special color OOoOOOOoooo
- if(M.absorbed)
+ if(M.vore_flags & ABSORBED)
dat += "[O]"
continue
@@ -243,11 +243,11 @@
dat += "