Merge branch 'master' into food-quality

This commit is contained in:
Timothy Teakettle
2020-04-20 19:53:39 +01:00
committed by GitHub
316 changed files with 1172 additions and 686 deletions
+1 -1
View File
@@ -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
+2
View File
@@ -73,6 +73,8 @@
#define CAT_AMMO "Ammunition"
#define CAT_ROBOT "Robots"
#define CAT_MISC "Misc"
#define CAT_TOOL "Tools & Storage"
#define CAT_FURNITURE "Furniture"
#define CAT_PRIMAL "Tribal"
#define CAT_CLOTHING "Clothing"
#define CAT_FOOD "Foods"
+18
View File
@@ -0,0 +1,18 @@
/// Transparent, let beams pass
#define SHIELD_TRANSPARENT (1<<0)
/// Can shield bash
#define SHIELD_CAN_BASH (1<<1)
/// Shield bash knockdown on wall hit
#define SHIELD_BASH_WALL_KNOCKDOWN (1<<2)
/// Shield bash always knockdown
#define SHIELD_BASH_ALWAYS_KNOCKDOWN (1<<3)
/// Shield bash disarm on wall hit
#define SHIELD_BASH_WALL_DISARM (1<<4)
/// Shield bash always disarm
#define SHIELD_BASH_ALWAYS_DISARM (1<<5)
/// You can shieldbash target someone on the ground for ground slam
#define SHIELD_BASH_GROUND_SLAM (1<<6)
/// Shield bashing someone on the ground will disarm
#define SHIELD_BASH_GROUND_SLAM_DISARM (1<<7)
#define SHIELD_FLAGS_DEFAULT (SHIELD_CAN_BASH | SHIELD_BASH_WALL_KNOCKDOWN | SHIELD_BASH_WALL_DISARM | SHIELD_BASH_GROUND_SLAM)
+10 -10
View File
@@ -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
+3 -2
View File
@@ -62,9 +62,10 @@
#define INIT_ORDER_JOBS 65
#define INIT_ORDER_QUIRKS 60
#define INIT_ORDER_TICKER 55
#define INIT_ORDER_INSTRUMENTS 53
#define INIT_ORDER_INSTRUMENTS 53
#define INIT_ORDER_MAPPING 50
#define INIT_ORDER_NETWORKS 45
#define INIT_ORDER_HOLODECK 35
#define INIT_ORDER_ATOMS 30
#define INIT_ORDER_LANGUAGE 25
#define INIT_ORDER_MACHINES 20
@@ -90,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
+13
View File
@@ -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 }
-8
View File
@@ -89,14 +89,6 @@
INVOKE_ASYNC(GLOBAL_PROC, /proc/init_ref_coin_values) //so the current procedure doesn't sleep because of UNTIL()
for(var/path in subtypesof(/area/holodeck))
var/area/holodeck/A = path
var/list/compatibles = initial(A.compatible_holodeck_comps)
if(!compatibles || initial(A.abstract_type) == path)
continue
for(var/comp in compatibles)
LAZYADD(GLOB.holodeck_areas_prototypes[comp], A)
//creates every subtype of prototype (excluding prototype) and adds it to list L.
//if no list/L is provided, one is created.
/proc/init_subtypes(prototype, list/L)
+10
View File
@@ -250,6 +250,16 @@ GLOBAL_LIST_INIT(bitfields, list(
"COMBAT_FLAG_INTENTIONALLY_RESTING" = COMBAT_FLAG_INTENTIONALLY_RESTING,
"COMBAT_FLAG_RESISTING_REST" = COMBAT_FLAG_RESISTING_REST
),
"shield_flags" = list(
"SHIELD_TRANSPARENT" = SHIELD_TRANSPARENT,
"SHIELD_CAN_BASH" = SHIELD_CAN_BASH,
"SHIELD_BASH_WALL_KNOCKDOWN" = SHIELD_BASH_WALL_KNOCKDOWN,
"SHIELD_BASH_ALWAYS_KNOCKDOWN" = SHIELD_BASH_ALWAYS_KNOCKDOWN,
"SHIELD_BASH_WALL_DISARM" = SHIELD_BASH_WALL_DISARM,
"SHIELD_BASH_ALWAYS_DISARM" = SHIELD_BASH_ALWAYS_DISARM,
"SHIELD_BASH_GROUND_SLAM" = SHIELD_BASH_GROUND_SLAM,
"SHIELD_BASH_GROUND_SLAM_DISARM" = SHIELD_BASH_GROUND_SLAM_DISARM
),
"storage_flags" = list(
"STORAGE_LIMIT_MAX_ITEMS" = STORAGE_LIMIT_MAX_ITEMS,
"STORAGE_LIMIT_MAX_W_CLASS" = STORAGE_LIMIT_MAX_W_CLASS,
-2
View File
@@ -50,5 +50,3 @@ GLOBAL_LIST_EMPTY_TYPED(areas_by_type, /area)
GLOBAL_LIST_EMPTY(all_abstract_markers)
GLOBAL_LIST_EMPTY(stationroom_landmarks) //List of all spawns for stationrooms
GLOBAL_LIST_EMPTY(holodeck_areas_prototypes) //List of holodeck area prototypes per holodeck computer type
@@ -67,6 +67,9 @@
/obj/screen/storage/volumetric_box/Click(location, control, params)
return our_item.Click(location, control, params)
/obj/screen/storage/volumetric_box/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params)
return our_item.MouseDrop(over, src_location, over_location, src_control, over_control, params)
/obj/screen/storage/volumetric_box/center
icon_state = "stored_continue"
var/obj/screen/storage/stored_left/left
+56
View File
@@ -0,0 +1,56 @@
SUBSYSTEM_DEF(holodeck)
name = "Holodeck"
init_order = INIT_ORDER_HOLODECK
flags = SS_NO_FIRE
var/list/program_cache = list() //list of safe holodeck programs.
var/list/emag_program_cache = list() //like above, but dangerous.
var/list/offline_programs = list() //default when offline.
var/list/target_holodeck_area = list()
var/list/rejected_areas = list()
/datum/controller/subsystem/holodeck/Initialize()
. = ..()
//generates the list of available holodeck programs.
for(var/path in subtypesof(/datum/holodeck_cache))
new path
for(var/path in typesof(/obj/machinery/computer/holodeck)) //The istances will be handled by SSatoms.
var/obj/machinery/computer/holodeck/H = path
offline_programs[path] = pop(get_areas(initial(H.offline_program)), FALSE)
target_holodeck_area[path] = pop(get_areas(initial(H.holodeck_type)), FALSE)
/*
* The sole scope of this datum is to generate lists of holodeck programs caches per holodeck computer type.
*/
/datum/holodeck_cache
var/area/holodeck/master_type //the /area/holodeck typepath we'll be using for typesof loop.
var/skip_types //Areas that won't be added to the global list category.
var/list/compatible_holodeck_comps //list of typepaths of holodeck computers that can access this category.
/datum/holodeck_cache/New()
if(!master_type || !compatible_holodeck_comps)
return
var/list/to_add = typesof(master_type) - skip_types
var/list/programs
var/list/emag_programs
for(var/typekey in to_add)
var/area/holodeck/A = GLOB.areas_by_type[typekey]
if(!A || !A.contents.len)
LAZYOR(SSholodeck.rejected_areas[typekey], compatible_holodeck_comps)
continue
var/list/info_this = list("name" = A.name, "type" = A.type)
if(A.restricted)
LAZYADD(emag_programs, list(info_this))
else
LAZYADD(programs, list(info_this))
for(var/comp in compatible_holodeck_comps)
if(programs)
LAZYADD(SSholodeck.program_cache[comp], programs)
if(emag_programs)
LAZYADD(SSholodeck.emag_program_cache[comp], emag_programs)
/datum/holodeck_cache/standard
master_type = /area/holodeck/rec_center
skip_types = /area/holodeck/rec_center
compatible_holodeck_comps = list(/obj/machinery/computer/holodeck)
+2
View File
@@ -428,6 +428,8 @@ SUBSYSTEM_DEF(job)
if(!joined_late)
var/obj/S = null
for(var/obj/effect/landmark/start/sloc in GLOB.start_landmarks_list)
if(!sloc.job_spawnpoint)
continue
if(sloc.name != rank)
S = sloc //so we can revert to spawning them on top of eachother if something goes wrong
continue
+6 -2
View File
@@ -15,7 +15,7 @@
/datum/component/personal_crafting
var/busy
var/viewing_category = 1 //typical powergamer starting on the Weapons tab
var/viewing_category = 1
var/viewing_subcategory = 1
var/list/categories = list(
CAT_WEAPONRY = list(
@@ -23,7 +23,11 @@
CAT_AMMO,
),
CAT_ROBOT = CAT_NONE,
CAT_MISC = CAT_NONE,
CAT_MISC = list(
CAT_MISC,
CAT_TOOL,
CAT_FURNITURE,
),
CAT_PRIMAL = CAT_NONE,
CAT_FOOD = list(
CAT_BREAD,
@@ -41,7 +41,7 @@
category = CAT_CLOTHING
/datum/crafting_recipe/armwraps
name = "armwraps"
name = "Armwraps"
result = /obj/item/clothing/gloves/fingerless/pugilist
time = 60
tools = list(TOOL_WIRECUTTER)
@@ -51,7 +51,7 @@
category = CAT_CLOTHING
/datum/crafting_recipe/armwrapsplusone
name = "armwraps of mighty fists"
name = "Armwraps of Mighty Fists"
result = /obj/item/clothing/gloves/fingerless/pugilist/magic
time = 300
tools = list(TOOL_WIRECUTTER, /obj/item/book/codex_gigas, /obj/item/clothing/head/wizard, /obj/item/clothing/suit/wizrobe)
@@ -8,6 +8,7 @@
/obj/item/stack/sheet/plastic = 2,
/obj/item/stack/rods = 1)
result = /obj/structure/curtain
subcategory = CAT_FURNITURE
category = CAT_MISC
/datum/crafting_recipe/guillotine
@@ -42,6 +43,7 @@
/obj/item/pipe = 3,
/obj/item/stack/cable_coil = 30)
category = CAT_MISC
subcategory = CAT_TOOL
tools = list(TOOL_WRENCH, TOOL_WELDER, TOOL_WIRECUTTER)
/datum/crafting_recipe/goldenbox
@@ -53,6 +55,23 @@
/obj/item/stack/sheet/mineral/gold = 1,
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
/datum/crafting_recipe/papersack
name = "Paper Sack"
result = /obj/item/storage/box/papersack
time = 10
reqs = list(/obj/item/paper = 5)
subcategory = CAT_TOOL
category = CAT_MISC
/datum/crafting_recipe/smallcarton
name = "Small Carton"
result = /obj/item/reagent_containers/food/drinks/sillycup/smallcarton
time = 10
reqs = list(/obj/item/stack/sheet/cardboard = 1)
subcategory = CAT_TOOL
category = CAT_MISC
/datum/crafting_recipe/bronze_driver
@@ -64,6 +83,7 @@
/obj/item/stack/tile/bronze = 1,
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
/datum/crafting_recipe/bronze_welder
@@ -75,6 +95,7 @@
/obj/item/stack/tile/bronze = 1,
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
/datum/crafting_recipe/bronze_wirecutters
@@ -86,6 +107,7 @@
/obj/item/stack/tile/bronze = 1,
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
/datum/crafting_recipe/bronze_crowbar
@@ -97,6 +119,7 @@
/obj/item/stack/tile/bronze = 1,
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
/datum/crafting_recipe/bronze_wrench
@@ -108,6 +131,7 @@
/obj/item/stack/tile/bronze = 1,
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
/datum/crafting_recipe/rcl
@@ -116,6 +140,16 @@
time = 40
tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
reqs = list(/obj/item/stack/sheet/metal = 15)
subcategory = CAT_TOOL
category = CAT_MISC
/datum/crafting_recipe/picket_sign
name = "Picket Sign"
result = /obj/item/picket_sign
reqs = list(/obj/item/stack/rods = 1,
/obj/item/stack/sheet/cardboard = 2)
time = 80
subcategory = CAT_TOOL
category = CAT_MISC
////////////
@@ -210,13 +244,6 @@
/obj/item/stack/rods = 1)
category = CAT_MISC
/datum/crafting_recipe/papersack
name = "Paper Sack"
result = /obj/item/storage/box/papersack
time = 10
reqs = list(/obj/item/paper = 5)
category = CAT_MISC
/datum/crafting_recipe/flashlight_eyes
name = "Flashlight Eyes"
result = /obj/item/organ/eyes/robotic/flashlight
@@ -227,13 +254,6 @@
)
category = CAT_MISC
/datum/crafting_recipe/smallcarton
name = "Small Carton"
result = /obj/item/reagent_containers/food/drinks/sillycup/smallcarton
time = 10
reqs = list(/obj/item/stack/sheet/cardboard = 1)
category = CAT_MISC
/datum/crafting_recipe/pressureplate
name = "Pressure Plate"
result = /obj/item/pressure_plate
@@ -269,6 +289,14 @@
reqs = list(/obj/item/folder/paperwork = 1)
category = CAT_MISC
/datum/crafting_recipe/coconut_bong
name = "Coconut Bong"
result = /obj/item/bong/coconut
reqs = list(/obj/item/stack/sheet/mineral/bamboo = 2,
/obj/item/reagent_containers/food/snacks/grown/coconut = 1)
time = 70
category = CAT_MISC
//////////////
//Banners/////
//////////////
@@ -279,6 +307,7 @@
time = 40
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/captain/parade = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
/datum/crafting_recipe/engineering_banner
@@ -287,6 +316,7 @@
time = 40
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/engineering/engineer = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
/datum/crafting_recipe/cargo_banner
@@ -295,6 +325,7 @@
time = 40
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/cargo/tech = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
/datum/crafting_recipe/science_banner
@@ -303,6 +334,7 @@
time = 40
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/rnd/scientist = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
/datum/crafting_recipe/medical_banner
@@ -311,6 +343,7 @@
time = 40
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/medical/doctor = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
/datum/crafting_recipe/security_banner
@@ -319,50 +352,43 @@
time = 40
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/security/officer = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
/datum/crafting_recipe/bloodsucker/vassalrack
name = "Persuasion Rack"
//desc = "For converting crewmembers into loyal Vassals."
result = /obj/structure/bloodsucker/vassalrack
tools = list(/obj/item/weldingtool,
///obj/item/screwdriver,
/obj/item/wrench
/datum/crafting_recipe/bloodsucker/vassalrack
name = "Persuasion Rack"
//desc = "For converting crewmembers into loyal Vassals."
result = /obj/structure/bloodsucker/vassalrack
tools = list(/obj/item/weldingtool,
//obj/item/screwdriver,
/obj/item/wrench
)
reqs = list(/obj/item/stack/sheet/mineral/wood = 3,
/obj/item/stack/sheet/metal = 2,
/obj/item/restraints/handcuffs/cable = 2,
///obj/item/storage/belt = 1
///obj/item/stack/sheet/animalhide = 1, // /obj/item/stack/sheet/leather = 1,
///obj/item/stack/sheet/plasteel = 5
)
reqs = list(/obj/item/stack/sheet/mineral/wood = 3,
/obj/item/stack/sheet/metal = 2,
/obj/item/restraints/handcuffs/cable = 2,
//obj/item/storage/belt = 1,
//obj/item/stack/sheet/animalhide = 1,
//obj/item/stack/sheet/leather = 1,
//obj/item/stack/sheet/plasteel = 5
)
//parts = list(/obj/item/storage/belt = 1
// )
time = 150
category = CAT_MISC
always_availible = FALSE // Disabled til learned
time = 150
category = CAT_MISC
always_availible = FALSE // Disabled til learned
/datum/crafting_recipe/bloodsucker/candelabrum
name = "Candelabrum"
//desc = "For converting crewmembers into loyal Vassals."
result = /obj/structure/bloodsucker/candelabrum
tools = list(/obj/item/weldingtool,
/obj/item/wrench
)
reqs = list(/obj/item/stack/sheet/metal = 3,
/obj/item/stack/rods = 1,
/obj/item/candle = 1
)
time = 100
category = CAT_MISC
always_availible = FALSE // Disabled til learned
/datum/crafting_recipe/coconut_bong
name = "Coconut Bong"
result = /obj/item/bong/coconut
reqs = list(/obj/item/stack/sheet/mineral/bamboo = 2,
/obj/item/reagent_containers/food/snacks/grown/coconut = 1)
time = 70
category = CAT_MISC
/datum/crafting_recipe/bloodsucker/candelabrum
name = "Candelabrum"
//desc = "For converting crewmembers into loyal Vassals."
result = /obj/structure/bloodsucker/candelabrum
tools = list(/obj/item/weldingtool,
/obj/item/wrench
)
reqs = list(/obj/item/stack/sheet/metal = 3,
/obj/item/stack/rods = 1,
/obj/item/candle = 1
)
time = 100
category = CAT_MISC
always_availible = FALSE // Disabled til learned
+20 -18
View File
@@ -26,7 +26,6 @@
RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, .proc/vehicle_mob_buckle)
RegisterSignal(parent, COMSIG_MOVABLE_UNBUCKLE, .proc/vehicle_mob_unbuckle)
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/vehicle_moved)
RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, .proc/vehicle_dir_changed)
/datum/component/riding/proc/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE)
restore_position(M)
@@ -48,11 +47,6 @@
/datum/component/riding/proc/set_vehicle_dir_layer(dir, layer)
directional_vehicle_layers["[dir]"] = layer
/datum/component/riding/proc/vehicle_dir_changed(from_dir, to_dir)
spawn
handle_vehicle_offsets()
handle_vehicle_layer()
/datum/component/riding/proc/vehicle_moved(datum/source)
var/atom/movable/AM = parent
for(var/i in AM.buckled_mobs)
@@ -72,6 +66,9 @@
var/atom/movable/AM = parent
AM.unbuckle_mob(M)
/datum/component/riding/proc/additional_offset_checks()
return TRUE
/datum/component/riding/proc/handle_vehicle_offsets()
var/atom/movable/AM = parent
var/AM_dir = "[AM.dir]"
@@ -83,16 +80,17 @@
var/list/offsets = get_offsets(passindex)
var/rider_dir = get_rider_dir(passindex)
buckled_mob.setDir(rider_dir)
dir_loop:
for(var/offsetdir in offsets)
if(offsetdir == AM_dir)
var/list/diroffsets = offsets[offsetdir]
buckled_mob.pixel_x = diroffsets[1]
if(diroffsets.len >= 2)
buckled_mob.pixel_y = diroffsets[2]
if(diroffsets.len == 3)
buckled_mob.layer = diroffsets[3]
break dir_loop
for(var/offsetdir in offsets)
if(offsetdir == AM_dir)
var/list/diroffsets = offsets[offsetdir]
buckled_mob.pixel_x = diroffsets[1]
if(diroffsets.len >= 2)
buckled_mob.pixel_y = diroffsets[2]
if(diroffsets.len == 3)
buckled_mob.layer = diroffsets[3]
break
if (!additional_offset_checks())
return
var/list/static/default_vehicle_pixel_offsets = list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0))
var/px = default_vehicle_pixel_offsets[AM_dir]
var/py = default_vehicle_pixel_offsets[AM_dir]
@@ -153,7 +151,6 @@
if(user.incapacitated())
Unbuckle(user)
return
if(world.time < last_vehicle_move + ((last_move_diagonal? 2 : 1) * vehicle_move_delay))
return
last_vehicle_move = world.time
@@ -175,8 +172,8 @@
else
last_move_diagonal = FALSE
handle_vehicle_layer()
handle_vehicle_offsets()
handle_vehicle_layer()
else
to_chat(user, "<span class='notice'>You'll need the keys in one of your hands to [drive_verb] [AM].</span>")
@@ -226,6 +223,7 @@
force_dismount(target)
/datum/component/riding/human/handle_vehicle_layer()
. = ..()
var/atom/movable/AM = parent
if(AM.buckled_mobs && AM.buckled_mobs.len)
for(var/mob/M in AM.buckled_mobs) //ensure proper layering of piggyback and carry, sometimes weird offsets get applied
@@ -250,6 +248,10 @@
else
return list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(-6, 4), TEXT_WEST = list( 6, 4))
/datum/component/riding/human/additional_offset_checks()
var/mob/living/carbon/human/H = parent
return !H.buckled
/datum/component/riding/human/force_dismount(mob/living/user)
var/atom/movable/AM = parent
AM.unbuckle_mob(user)
+1 -1
View File
@@ -175,7 +175,7 @@
. += ui_left
// Then, closer, which is also our right element.
ui_close = get_ui_close()
ui_close.screen_loc = "[screen_start_x + maxcolumns]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x + maxcolumns]:[screen_pixel_x],[screen_start_y + row - 1]:[screen_pixel_y]"
ui_close.screen_loc = "[screen_start_x + maxcolumns]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x + maxcolumns]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]"
. += ui_close
/**
+1 -1
View File
@@ -18,7 +18,7 @@
UnregisterSignal(parent, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED))
unmodify()
/datum/component/fantasy/Destroy()
/datum/component/tactical/Destroy()
unmodify()
return ..()
+3 -1
View File
@@ -10,6 +10,7 @@
var/help_verb
var/pacifism_check = TRUE //are the martial arts combos/attacks unable to be used by pacifist.
var/allow_temp_override = TRUE //if this martial art can be overridden by temporary martial arts
var/pugilist = FALSE
/datum/martial_art/proc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
return FALSE
@@ -61,7 +62,8 @@
if(help_verb)
H.verbs += help_verb
H.mind.martial_art = src
ADD_TRAIT(H, TRAIT_PUGILIST, MARTIAL_ARTIST_TRAIT)
if(pugilist)
ADD_TRAIT(H, TRAIT_PUGILIST, MARTIAL_ARTIST_TRAIT)
return TRUE
/datum/martial_art/proc/store(datum/martial_art/M,mob/living/carbon/human/H)
+1
View File
@@ -2,6 +2,7 @@
name = "Boxing"
id = MARTIALART_BOXING
pacifism_check = FALSE //Let's pretend pacifists can boxe the heck out of other people, it only deals stamina damage right now.
pugilist = TRUE
/datum/martial_art/boxing/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
to_chat(A, "<span class='warning'>Can't disarm while boxing!</span>")
+1
View File
@@ -9,6 +9,7 @@
id = MARTIALART_CQC
help_verb = /mob/living/carbon/human/proc/CQC_help
block_chance = 75
pugilist = TRUE
var/old_grab_state = null
/datum/martial_art/cqc/reset_streak(mob/living/carbon/human/new_target)
+1
View File
@@ -1,6 +1,7 @@
/datum/martial_art/krav_maga
name = "Krav Maga"
id = MARTIALART_KRAVMAGA
pugilist = TRUE
var/datum/action/neck_chop/neckchop = new/datum/action/neck_chop()
var/datum/action/leg_sweep/legsweep = new/datum/action/leg_sweep()
var/datum/action/lung_punch/lungpunch = new/datum/action/lung_punch()
+1
View File
@@ -6,6 +6,7 @@
name = "Plasma Fist"
id = MARTIALART_PLASMAFIST
help_verb = /mob/living/carbon/human/proc/plasma_fist_help
pugilist = TRUE
/datum/martial_art/plasma_fist/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
+1
View File
@@ -9,6 +9,7 @@
id = MARTIALART_RISINGBASS
allow_temp_override = FALSE
help_verb = /mob/living/carbon/human/proc/rising_bass_help
pugilist = TRUE
var/datum/action/risingbassmove/sidekick = new/datum/action/risingbassmove/sidekick()
var/datum/action/risingbassmove/deftswitch = new/datum/action/risingbassmove/deftswitch()
var/repulsecool = 0
+5
View File
@@ -7,6 +7,7 @@
id = MARTIALART_SLEEPINGCARP
allow_temp_override = FALSE
help_verb = /mob/living/carbon/human/proc/sleeping_carp_help
pugilist = TRUE
/datum/martial_art/the_sleeping_carp/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(findtext(streak,STRONG_PUNCH_COMBO))
@@ -140,8 +141,10 @@
ADD_TRAIT(H, TRAIT_NOGUNS, SLEEPING_CARP_TRAIT)
ADD_TRAIT(H, TRAIT_PIERCEIMMUNE, SLEEPING_CARP_TRAIT)
ADD_TRAIT(H, TRAIT_NODISMEMBER, SLEEPING_CARP_TRAIT)
ADD_TRAIT(H, TRAIT_TASED_RESISTANCE, SLEEPING_CARP_TRAIT)
H.physiology.brute_mod *= 0.4 //brute is really not gonna cut it
H.physiology.burn_mod *= 0.7 //burn is distinctly more useful against them than brute but they're still resistant
H.physiology.stamina_mod *= 0.5 //You take less stamina damage overall, but you do not reduce the damage from stun batons
H.physiology.stun_mod *= 0.3 //for those rare stuns
H.physiology.pressure_mod *= 0.3 //go hang out with carp
H.physiology.cold_mod *= 0.3 //cold mods are different to burn mods, they do stack however
@@ -154,8 +157,10 @@
REMOVE_TRAIT(H, TRAIT_NOGUNS, SLEEPING_CARP_TRAIT)
REMOVE_TRAIT(H, TRAIT_PIERCEIMMUNE, SLEEPING_CARP_TRAIT)
REMOVE_TRAIT(H, TRAIT_NODISMEMBER, SLEEPING_CARP_TRAIT)
REMOVE_TRAIT(H, TRAIT_TASED_RESISTANCE, SLEEPING_CARP_TRAIT)
H.physiology.brute_mod = initial(H.physiology.brute_mod)
H.physiology.burn_mod = initial(H.physiology.burn_mod)
H.physiology.stamina_mod = initial(H.physiology.stamina_mod)
H.physiology.stun_mod = initial(H.physiology.stun_mod)
H.physiology.pressure_mod = initial(H.physiology.pressure_mod) //no more carpies
H.physiology.cold_mod = initial(H.physiology.cold_mod)
+13
View File
@@ -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
-1
View File
@@ -108,7 +108,6 @@
message = replacetext(message," drink "," liquid ")
message = replacetext(message," feminist "," empowered woman ")
message = replacetext(message," i hate you "," you're a mean ")
message = replacetext(message," jew "," jewish ")
message = replacetext(message," shit "," shiz ")
message = replacetext(message," crap "," poo ")
message = replacetext(message," slut "," tease ")
+3 -3
View File
@@ -117,10 +117,10 @@
continue
contam_atoms += thing
var/did_contam = 0
if(can_contam)
if(can_contam && contam_atoms.len)
var/rad_strength = ((strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_STR_COEFFICIENT)/contam_atoms.len
for(var/k in 1 to contam_atoms.len)
var/atom/thing = contam_atoms[k]
for(var/A in contam_atoms)
var/atom/thing = A
thing.AddComponent(/datum/component/radioactive, rad_strength, source)
did_contam = 1
return did_contam
+10 -4
View File
@@ -6,8 +6,6 @@
hidden = TRUE
var/obj/machinery/computer/holodeck/linked
var/list/compatible_holodeck_comps
var/abstract_type = /area/holodeck
var/restricted = 0 // if true, program goes on emag list
/*
@@ -15,6 +13,16 @@
Asserts are to avoid the inevitable infinite loops
*/
/area/holodeck/Initialize()
. = ..()
var/list/update_holodeck_cache = SSholodeck?.rejected_areas[type]
if(update_holodeck_cache)
var/list/info_this = list("name" = name, "type" = type)
var/list/target = restricted ? SSholodeck.emag_program_cache : SSholodeck.program_cache
for(var/A in update_holodeck_cache)
LAZYADD(target[A], info_this)
SSholodeck.rejected_areas -= type
/area/holodeck/powered(var/chan)
if(!requires_power)
return 1
@@ -55,8 +63,6 @@
*/
/area/holodeck/rec_center
name = "\improper Recreational Holodeck"
compatible_holodeck_comps = list(/obj/machinery/computer/holodeck)
abstract_type = /area/holodeck/rec_center
/area/holodeck/rec_center/offline
name = "Holodeck - Offline"
+2 -2
View File
@@ -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)
+1 -1
View File
@@ -32,7 +32,7 @@
/datum/antagonist/gang/farewell()
if(ishuman(owner.current))
owner.current.visible_message("<span class='deconversion_message'>[owner.current] looks like [owner.current.p_theyve()] just remembered [owner.current.p_their()] real allegiance!</span>", null, null, null, owner.current)
to_chat(owner, "<span class='userdanger'>You are no longer a gangster!</span>")
to_chat(owner, "<span class='userdanger'>You are no longer a gangster! Your memories from the time you were in a gang are hazy... You don't seem to be able to recall the names of your previous allies, not even your bosses...</span>")
/datum/antagonist/gang/on_gain()
if(!gang)
+9
View File
@@ -19,6 +19,15 @@ GLOBAL_LIST_EMPTY(objectives)
if(text)
explanation_text = text
/datum/objective/Destroy(force, ...)
GLOB.objectives -= src
if(owner)
for(var/datum/antagonist/A in owner.antag_datums)
A.objectives -= src
if(team)
team.objectives -= src
. = ..()
/datum/objective/proc/get_owners() // Combine owner and team into a single list.
. = (team && team.members) ? team.members.Copy() : list()
if(owner)
+2
View File
@@ -36,6 +36,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark)
var/jobspawn_override = FALSE
var/delete_after_roundstart = TRUE
var/used = FALSE
var/job_spawnpoint = TRUE //Is it a potential job spawnpoint or should we skip it?
/obj/effect/landmark/start/proc/after_round_start()
if(delete_after_roundstart)
@@ -281,6 +282,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
name = "bomb or clown beacon spawner"
var/nukie_path = /obj/item/sbeacondrop/bomb
var/clown_path = /obj/item/sbeacondrop/clownbomb
job_spawnpoint = FALSE
/obj/effect/landmark/start/nuclear_equipment/after_round_start()
var/npath = nukie_path
@@ -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 ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "null"])")
to_chat(hound,"<span class='notice'>You feel your belly slowly churn around [T], breaking them down into a soft slurry to be used as power for your systems.</span>")
to_chat(T,"<span class='notice'>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.</span>")
@@ -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, "<span class='warning'>[target] registers an error code to your [src]</span>")
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."
desc = "A mounted, underslung sleeper, intended for holding willing occupants for leisurely purposes."
+4 -2
View File
@@ -163,7 +163,6 @@
color = pick(cable_colors)
/obj/item/restraints/handcuffs/cable/attackby(obj/item/I, mob/user, params)
..()
if(istype(I, /obj/item/stack/rods))
var/obj/item/stack/rods/R = I
if (R.use(1))
@@ -197,12 +196,15 @@
name = "zipties"
desc = "Plastic, disposable zipties that can be used to restrain temporarily but are destroyed after use."
item_state = "zipties"
color = "white"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
custom_materials = null
breakouttime = 450 //Deciseconds = 45s
trashtype = /obj/item/restraints/handcuffs/cable/zipties/used
color = null
/obj/item/restraints/handcuffs/cable/zipties/attack_self() //Zipties arent cable
return
/obj/item/restraints/handcuffs/cable/zipties/used
desc = "A pair of broken zipties."
+228 -62
View File
@@ -1,13 +1,153 @@
/obj/item/shield
name = "shield"
icon = 'icons/obj/items_and_weapons.dmi'
icon = 'icons/obj/shields.dmi'
block_chance = 50
armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70)
var/transparent = FALSE // makes beam projectiles pass through the shield
/// Shield flags
var/shield_flags = SHIELD_FLAGS_DEFAULT
/// Last shieldbash world.time
var/last_shieldbash = 0
/// Shieldbashing cooldown
var/shieldbash_cooldown = 5 SECONDS
/// Shieldbashing stamina cost
var/shieldbash_stamcost = 7.5
/// Shieldbashing knockback
var/shieldbash_knockback = 2
/// Shield bashing brute damage
var/shieldbash_brutedamage = 5
/// Shield bashing stamina damage
var/shieldbash_stamdmg = 15
/// Shield bashing stagger duration
var/shieldbash_stagger_duration = 3.5 SECONDS
/// Shield bashing push distance
var/shieldbash_push_distance = 1
/obj/item/shield/examine(mob/user)
. = ..()
if(shield_flags & SHIELD_CAN_BASH)
. += "<span class='notice'>Right click on combat mode attack with [src] to shield bash!</span>"
if(shield_flags & SHIELD_BASH_GROUND_SLAM)
. += "<span class='notice'>Directly rightclicking on a downed target with [src] will slam them instead of bashing.</span>"
/obj/item/shield/proc/on_shield_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance)
return TRUE
/obj/item/shield/alt_pre_attack(atom/A, mob/living/user, params)
user_shieldbash(user, A, user.a_intent != INTENT_HARM)
return TRUE
/obj/item/shield/altafterattack(atom/target, mob/user, proximity_flag, click_parameters)
user_shieldbash(user, target, user.a_intent != INTENT_HARM)
return TRUE
/obj/item/shield/proc/do_shieldbash_effect(mob/living/user, dir, harmful)
var/px = 0
var/py = 0
switch(dir)
if(NORTH)
py = 12
if(SOUTH)
py = -12
if(EAST)
px = 12
if(WEST)
px = -12
var/oldpx = user.pixel_x
var/oldpy = user.pixel_y
animate(user, pixel_x = px, pixel_y = py, time = 3, easing = SINE_EASING | EASE_OUT, flags = ANIMATION_END_NOW)
animate(user, pixel_x = oldpx, pixel_y = oldpy, time = 3)
user.visible_message("<span class='warning'>[user] [harmful? "charges forwards with" : "sweeps"] [src]!</span>")
var/obj/effect/temp_visual/dir_setting/shield_bash/effect = new(user.loc, dir)
animate(effect, alpha = 0, pixel_x = px + 4, pixel_y = py + 4, time = 3)
/obj/item/shield/proc/bash_target(mob/living/user, mob/living/target, bashdir, harmful)
if(!(target.status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)) // should probably add stun absorption check at some point I guess..
// unified stun absorption system when lol
target.visible_message("<span class='warning'>[user] slams [target] with [src], but [target] doesn't falter!</span>", "<span class='userdanger'>[user] slams you with [src], but it barely fazes you!</span>")
return FALSE
var/target_downed = !CHECK_MOBILITY(target, MOBILITY_STAND)
var/wallhit = FALSE
var/turf/target_current_turf = get_turf(target)
if(harmful)
target.visible_message("<span class='warning'>[target_downed? "[user] slams [src] into [target]" : "[user] bashes [target] with [src]"]!</span>",
"<span class='warning'>[target_downed? "[user] slams [src] into you" : "[user] bashes you with [src]"]!</span>")
else
target.visible_message("<span class='warning'>[user] shoves [target] with [src]!</span>",
"<span class='warning'>[user] shoves you with [src]!</span>")
for(var/i in 1 to harmful? shieldbash_knockback : shieldbash_push_distance)
var/turf/new_turf = get_step(target, bashdir)
var/mob/living/carbon/human/H = locate() in new_turf
if(H && harmful)
H.visible_message("<span class='warning'>[target] is sent crashing into [H]!</span>",
"<span class='userdanger'>[target] is sent crashing into you!</span>")
H.KnockToFloor()
wallhit = TRUE
break
else
step(target, bashdir)
if(get_turf(target) == target_current_turf)
wallhit = TRUE
break
else
target_current_turf = get_turf(target)
var/disarming = (target_downed && (shield_flags & SHIELD_BASH_GROUND_SLAM_DISARM)) || (shield_flags & SHIELD_BASH_ALWAYS_DISARM) || (wallhit && (shield_flags & SHIELD_BASH_WALL_DISARM))
var/knockdown = !target_downed && ((shield_flags & SHIELD_BASH_ALWAYS_KNOCKDOWN) || (wallhit && (shield_flags & SHIELD_BASH_WALL_KNOCKDOWN)))
if(shieldbash_stagger_duration || knockdown)
target.visible_message("<span class='warning'>[target] is knocked [knockdown? "to the floor" : "off balanace"]!</span>",
"<span class='userdanger'>You are knocked [knockdown? "to the floor" : "off balanace"]!</span>")
if(knockdown)
target.KnockToFloor(disarming)
else if(disarming)
target.drop_all_held_items()
if(harmful)
target.apply_damage(shieldbash_stamdmg, STAMINA, BODY_ZONE_CHEST)
target.apply_damage(shieldbash_brutedamage, BRUTE, BODY_ZONE_CHEST)
target.Stagger(shieldbash_stagger_duration)
return TRUE
/obj/item/shield/proc/user_shieldbash(mob/living/user, atom/target, harmful)
if(!(shield_flags & SHIELD_CAN_BASH))
to_chat(user, "<span class='warning'>[src] can't be used to shield bash!</span>")
return FALSE
if(world.time < last_shieldbash + shieldbash_cooldown)
to_chat(user, "<span class='warning'>You can't bash with [src] again so soon!</span>")
return FALSE
if(isliving(target)) //GROUND SLAAAM
if(!(shield_flags & SHIELD_BASH_GROUND_SLAM))
to_chat(user, "<span class='warning'>You can't ground slam with [src]!</span>")
return FALSE
bash_target(user, target, NONE, harmful)
user.do_attack_animation(target, used_item = src)
playsound(src, harmful? "swing_hit" : 'sound/weapons/thudswoosh.ogg', 75, 1)
last_shieldbash = world.time
user.adjustStaminaLossBuffered(shieldbash_stamcost)
return 1
// Directional sweep!
last_shieldbash = world.time
user.adjustStaminaLossBuffered(shieldbash_stamcost)
// Since we are in combat mode, we can probably safely use the user's dir instead of getting their mouse pointing cardinal dir.
var/bashdir = user.dir
do_shieldbash_effect(user, bashdir, harmful)
var/list/checking = list(get_step(user, user.dir), get_step(user, turn(user.dir, 45)), get_step(user, turn(user.dir, -45)))
var/list/victims = list()
for(var/i in checking)
var/turf/T = i
for(var/mob/living/L in T.contents)
victims += L
if(length(victims))
for(var/i in victims)
bash_target(user, i, bashdir, harmful)
playsound(src, harmful? "swing_hit" : 'sound/weapons/thudswoosh.ogg', 75, 1)
else
playsound(src, 'sound/weapons/punchmiss.ogg', 75, 1)
return length(victims)
/obj/effect/temp_visual/dir_setting/shield_bash
icon = 'icons/effects/96x96_attack_sweep.dmi'
icon_state = "shield_bash"
duration = 3
/obj/item/shield/riot
name = "riot shield"
desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder."
@@ -23,13 +163,14 @@
custom_materials = list(/datum/material/glass=7500, /datum/material/iron=1000)
attack_verb = list("shoved", "bashed")
var/cooldown = 0 //shield bash cooldown. based on world.time
transparent = TRUE
var/repair_material = /obj/item/stack/sheet/mineral/titanium
shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_TRANSPARENT
max_integrity = 75
/obj/item/shield/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(ismovableatom(object))
var/atom/movable/AM = object
if(transparent && (AM.pass_flags & PASSGLASS))
if(CHECK_BITFIELD(shield_flags, SHIELD_TRANSPARENT) && (AM.pass_flags & PASSGLASS))
return BLOCK_NONE
if(attack_type & ATTACK_TYPE_THROWN)
final_block_chance += 30
@@ -45,7 +186,7 @@
user.visible_message("<span class='warning'>[user] bashes [src] with [W]!</span>")
playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1)
cooldown = world.time
else if(istype(W, /obj/item/stack/sheet/mineral/titanium))
else if(istype(W, repair_material))
if(obj_integrity >= max_integrity)
to_chat(user, "<span class='warning'>[src] is already in perfect condition.</span>")
else
@@ -81,6 +222,23 @@
take_damage(damage)
return ..()
/obj/item/shield/riot/laser_proof
name = "laser resistant shield"
desc = "A far more frail shield made of dark glass meant to block lasers but suffers from being being weak to ballistic projectiles."
armor = list("melee" = 30, "bullet" = -10, "laser" = 80, "energy" = 80, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
icon_state = "riot_laser"
item_state = "riot_laser"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
shield_flags = SHIELD_FLAGS_DEFAULT
max_integrity = 55 //Weak
obj/item/shield/riot/bullet_proof
name = "bullet resistant shield"
desc = "A far more frail shield made of resistant plastics and kevlar meant to block ballistics."
armor = list("melee" = 30, "bullet" = 80, "laser" = 0, "energy" = 0, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
max_integrity = 55 //Weaker
/obj/item/shield/riot/roman
name = "\improper Roman shield"
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>."
@@ -88,7 +246,8 @@
item_state = "roman_shield"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
transparent = FALSE
repair_material = /obj/item/stack/sheet/mineral/wood
shield_flags = SHIELD_FLAGS_DEFAULT
max_integrity = 65
/obj/item/shield/riot/roman/fake
@@ -110,66 +269,15 @@
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
custom_materials = null
resistance_flags = FLAMMABLE
repair_material = /obj/item/stack/sheet/mineral/wood
block_chance = 30
transparent = FALSE
shield_flags = SHIELD_FLAGS_DEFAULT
max_integrity = 55
/obj/item/shield/riot/buckler/shatter(mob/living/carbon/human/owner)
playsound(owner, 'sound/effects/bang.ogg', 50)
new /obj/item/stack/sheet/mineral/wood(get_turf(src))
/obj/item/shield/energy
name = "energy combat shield"
desc = "A shield that reflects almost all energy projectiles, but is useless against physical attacks. It can be retracted, expanded, and stored anywhere."
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
attack_verb = list("shoved", "bashed")
throw_range = 5
force = 3
throwforce = 3
throw_speed = 3
var/base_icon_state = "eshield" // [base_icon_state]1 for expanded, [base_icon_state]0 for contracted
var/on_force = 10
var/on_throwforce = 8
var/on_throw_speed = 2
var/active = 0
var/clumsy_check = TRUE
/obj/item/shield/energy/Initialize()
. = ..()
icon_state = "[base_icon_state]0"
/obj/item/shield/energy/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if((attack_type & ATTACK_TYPE_PROJECTILE) && is_energy_reflectable_projectile(object))
block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_DEFLECT
return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT
return ..()
/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
to_chat(user, "<span class='userdanger'>You beat yourself in the head with [src]!</span>")
user.take_bodypart_damage(5)
active = !active
icon_state = "[base_icon_state][active]"
if(active)
force = on_force
throwforce = on_throwforce
throw_speed = on_throw_speed
w_class = WEIGHT_CLASS_BULKY
playsound(user, 'sound/weapons/saberon.ogg', 35, TRUE)
to_chat(user, "<span class='notice'>[src] is now active.</span>")
else
force = initial(force)
throwforce = initial(throwforce)
throw_speed = initial(throw_speed)
w_class = WEIGHT_CLASS_TINY
playsound(user, 'sound/weapons/saberoff.ogg', 35, TRUE)
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
add_fingerprint(user)
/obj/item/shield/riot/tele
name = "telescopic shield"
desc = "An advanced riot shield made of lightweight materials that collapses for easy storage."
@@ -222,6 +330,7 @@
custom_materials = list(/datum/material/iron = 18000)
slot_flags = null
block_chance = 35
max_integrity = 100 //Made of metal welded together its strong but not unkillable
force = 10
throwforce = 7
@@ -238,20 +347,77 @@
throwforce = 15 //Massive pice of metal
w_class = WEIGHT_CLASS_HUGE
item_flags = SLOWS_WHILE_IN_HAND
transparent = FALSE
shield_flags = SHIELD_FLAGS_DEFAULT
/obj/item/shield/riot/tower/swat
name = "swat shield"
desc = "A massive, heavy shield that can block a lot of attacks, can take a lot of abuse before breaking."
max_integrity = 175
block_chance = 50
/obj/item/shield/riot/implant
name = "riot tower shield"
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
transparent = FALSE
shield_flags = SHIELD_FLAGS_DEFAULT
item_flags = SLOWS_WHILE_IN_HAND
/obj/item/shield/riot/implant/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(attack_type & ATTACK_TYPE_PROJECTILE)
final_block_chance = 60 //Massive shield
return ..()
/obj/item/shield/energy
name = "energy combat shield"
desc = "A shield that reflects almost all energy projectiles, but is useless against physical attacks. It can be retracted, expanded, and stored anywhere."
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
attack_verb = list("shoved", "bashed")
throw_range = 5
force = 3
throwforce = 3
throw_speed = 3
var/base_icon_state = "eshield" // [base_icon_state]1 for expanded, [base_icon_state]0 for contracted
var/on_force = 10
var/on_throwforce = 8
var/on_throw_speed = 2
var/active = 0
var/clumsy_check = TRUE
/obj/item/shield/energy/Initialize()
. = ..()
icon_state = "[base_icon_state]0"
/obj/item/shield/energy/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if((attack_type & ATTACK_TYPE_PROJECTILE) && is_energy_reflectable_projectile(object))
block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_DEFLECT
return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT
return ..()
/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
to_chat(user, "<span class='userdanger'>You beat yourself in the head with [src]!</span>")
user.take_bodypart_damage(5)
active = !active
icon_state = "[base_icon_state][active]"
if(active)
force = on_force
throwforce = on_throwforce
throw_speed = on_throw_speed
w_class = WEIGHT_CLASS_BULKY
playsound(user, 'sound/weapons/saberon.ogg', 35, TRUE)
to_chat(user, "<span class='notice'>[src] is now active.</span>")
else
force = initial(force)
throwforce = initial(throwforce)
throw_speed = initial(throw_speed)
w_class = WEIGHT_CLASS_TINY
playsound(user, 'sound/weapons/saberoff.ogg', 35, TRUE)
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
add_fingerprint(user)
+1 -9
View File
@@ -40,12 +40,4 @@
user.visible_message("<span class='warning'>[user] waves around \the \"[label]\" sign.</span>")
else
user.visible_message("<span class='warning'>[user] waves around blank sign.</span>")
user.changeNext_move(CLICK_CD_MELEE)
/datum/crafting_recipe/picket_sign
name = "Picket Sign"
result = /obj/item/picket_sign
reqs = list(/obj/item/stack/rods = 1,
/obj/item/stack/sheet/cardboard = 2)
time = 80
category = CAT_MISC
user.changeNext_move(CLICK_CD_MELEE)
+5
View File
@@ -274,6 +274,7 @@
w_class = WEIGHT_CLASS_TINY
icon = 'icons/obj/cigarettes.dmi'
icon_state = "cig_paper_pack"
///The value in here has NOTHING to do with icons. It needs to be this for the proper examine.
icon_type = "rolling paper"
spawn_type = /obj/item/rollingpaper
@@ -283,6 +284,10 @@
STR.max_items = 10
STR.can_hold = typecacheof(list(/obj/item/rollingpaper))
///Overrides to do nothing because fancy boxes are fucking insane.
/obj/item/storage/fancy/rollingpapers/update_icon_state()
return
/obj/item/storage/fancy/rollingpapers/update_overlays()
. = ..()
if(!contents.len)
+1 -1
View File
@@ -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)
@@ -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()
return loc.return_air()
+1 -1
View File
@@ -104,7 +104,7 @@ GLOBAL_VAR(antag_prototypes)
var/special_statuses = get_special_statuses()
if(length(special_statuses))
out += get_special_statuses() + "<br>"
out += special_statuses + "<br>"
if(!GLOB.antag_prototypes)
GLOB.antag_prototypes = list()
@@ -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
@@ -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.
@@ -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()
. = ..()
. += "<i><b>Traitor class:</b></i> <a href='?src=[REF(owner)];traitor_class=1;target_antag=[REF(src)]'>[traitor_kind.employer]</a><br>"
. += ..()
if(contractor_hub?.assigned_targets && length(contractor_hub.assigned_targets))
. += "<i><b>Contract Targets</b></i>:<br>"
for(var/datum/mind/M in contractor_hub.assigned_targets)
+1 -1
View File
@@ -330,7 +330,7 @@
/datum/supply_pack/misc/religious_supplies
name = "Religious Supplies Crate"
desc = "Keep your local chaplain happy and well-supplied, lest they call down judgement upon your cargo bay. Contains two bottles of holywater, bibles, chaplain robes, and burial garmets."
cost = 4000 // it costs so much because the Space Church is ran by Space Jews
cost = 4000 // it costs so much because the Space Church needs funding to build a cathedral
contains = list(/obj/item/reagent_containers/food/drinks/bottle/holywater,
/obj/item/reagent_containers/food/drinks/bottle/holywater,
/obj/item/storage/book/bible/booze,
+1 -4
View File
@@ -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"
+30 -17
View File
@@ -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)
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
if(!ckey)
@@ -499,11 +521,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
@@ -623,10 +642,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)
@@ -736,11 +752,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)
+1 -1
View File
@@ -996,7 +996,7 @@
item_state = "coatpoly"
hoodtype = /obj/item/clothing/head/hooded/winterhood/polychromic
/obj/item/clothing/suit/hooded/wintercoat/ComponentInitialize()
/obj/item/clothing/suit/hooded/wintercoat/polychromic/ComponentInitialize()
. = ..()
AddElement(/datum/element/polychromic, list("#6A6964", "#C4B8A6", "#0000FF"), 3)
+9 -8
View File
@@ -37,7 +37,6 @@
..()
/obj/item/clothing/suit/hooded/proc/RemoveHood()
src.icon_state = "[initial(icon_state)]"
suittoggled = FALSE
if(ishuman(hood.loc))
var/mob/living/carbon/H = hood.loc
@@ -45,9 +44,14 @@
H.update_inv_wear_suit()
else
hood.forceMove(src)
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
update_icon()
/obj/item/clothing/suit/hooded/update_icon_state()
icon_state = "[initial(icon_state)]"
if(ishuman(hood.loc))
var/mob/living/carbon/human/H = hood.loc
if(H.head == hood)
icon_state += "_t"
/obj/item/clothing/suit/hooded/dropped(mob/user)
..()
@@ -65,11 +69,8 @@
return
else if(H.equip_to_slot_if_possible(hood,SLOT_HEAD,0,0,1))
suittoggled = TRUE
src.icon_state = "[initial(icon_state)]_t"
update_icon()
H.update_inv_wear_suit()
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
else
RemoveHood()
+1 -1
View File
@@ -18,7 +18,7 @@
/obj/item/clothing/under/rank/cargo/tech
name = "cargo technician's jumpsuit"
desc = "Shooooorts! They're comfy and easy to wear!"
icon_state = "cargotech"
icon_state = "cargo"
item_state = "lb_suit"
body_parts_covered = CHEST|GROIN|ARMS
alt_covers_chest = TRUE
+23 -6
View File
@@ -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
+2 -2
View File
@@ -289,9 +289,9 @@ 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
var/amount = round(S.bonus_reagents[r_id] * cooking_efficiency)
if(r_id == /datum/reagent/consumable/nutriment || r_id == /datum/reagent/consumable/nutriment/vitamin)
S.reagents.add_reagent(r_id, amount, tastes)
else
@@ -365,7 +365,7 @@
/obj/item/reagent_containers/food/snacks/burger/chicken
name = "chicken sandwich" //Apparently the proud people of Americlapstan object to this thing being called a burger. Apparently McDonald's just calls it a burger in Europe as to not scare and confuse us.
desc = "A delicious chicken sandwich, it is said the proceeds from this treat helps criminalize homosexuality on the space frontier."
desc = "A delicious chicken sandwich, it is said the proceeds from this treat helps criminalize disarming people on the space frontier."
icon_state = "chickenburger"
tastes = list("bun" = 2, "chicken" = 4, "God's covenant" = 1)
bonus_reagents = list(/datum/reagent/consumable/mayonnaise = 3, /datum/reagent/consumable/cooking_oil = 2, /datum/reagent/consumable/nutriment = 2)
@@ -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"
@@ -20,6 +20,7 @@
var/max_n_of_items = 10
var/efficiency = 0
var/quality_increase = 5 // how much do we increase the quality of microwaved items
var/productivity = 0
var/datum/looping_sound/microwave/soundloop
var/list/ingredients = list() // may only contain /atom/movables
@@ -44,10 +45,14 @@
. = ..()
/obj/machinery/microwave/RefreshParts()
efficiency = 0
efficiency = 0.6
productivity = 0
max_n_of_items = 5
for(var/obj/item/stock_parts/micro_laser/M in component_parts)
efficiency += M.rating
efficiency += M.rating * 0.4
productivity += M.rating
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
max_n_of_items = 10 * M.rating
quality_increase = M.rating * 5
break
@@ -85,7 +90,7 @@
if(!(stat & (NOPOWER|BROKEN)))
. += "<span class='notice'>The status display reads:</span>"
. += "<span class='notice'>- Capacity: <b>[max_n_of_items]</b> items.<span>"
. += "<span class='notice'>- Cook time reduced by <b>[(efficiency - 1) * 25]%</b>.<span>"
. += "<span class='notice'>- Cook time reduced by <b>[(productivity - 1) * 25]%</b>.<span>"
/obj/machinery/microwave/update_icon_state()
if(broken)
@@ -242,7 +247,7 @@
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0)
return
if(prob(max((5 / efficiency) - 5, dirty * 5))) //a clean unupgraded microwave has no risk of failure
if(prob(dirty * 5 / (5 * efficiency))) //a clean unupgraded microwave has no risk of failure
muck()
return
for(var/obj/O in ingredients)
@@ -287,7 +292,7 @@
update_icon()
loop(MICROWAVE_MUCK, 4)
/obj/machinery/microwave/proc/loop(type, time, wait = max(12 - 2 * efficiency, 2)) // standard wait is 10
/obj/machinery/microwave/proc/loop(type, time, wait = max(12 - 2 * productivity, 2)) // standard wait is 10
if(stat & (NOPOWER|BROKEN))
if(type == MICROWAVE_PRE)
pre_fail()
+2 -2
View File
@@ -70,7 +70,7 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars_by_type, typecacheof_assoc_list(list(
for (var/turf/T in turfs_src)
src_min_x = min(src_min_x,T.x)
src_min_y = min(src_min_y,T.y)
src_max_x = max(src_max_x,T.y)
src_max_x = max(src_max_x,T.x)
src_max_y = max(src_max_y,T.y)
for (var/turf/T in turfs_src)
refined_src[T] = "[T.x - src_min_x].[T.y - src_min_y]"
@@ -84,7 +84,7 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars_by_type, typecacheof_assoc_list(list(
for (var/turf/T in turfs_trg)
trg_min_x = min(trg_min_x,T.x)
trg_min_y = min(trg_min_y,T.y)
trg_max_x = max(trg_max_x,T.y)
trg_max_x = max(trg_max_x,T.x)
trg_max_y = max(trg_max_y,T.y)
var/diff_x = round(((src_max_x - src_min_x) - (trg_max_x - trg_min_x))/2)
+12 -24
View File
@@ -31,12 +31,12 @@
var/area/holodeck/last_program
var/area/offline_program = /area/holodeck/rec_center/offline
var/list/program_cache
var/list/emag_programs
// Splitting this up allows two holodecks of the same size
// to use the same source patterns. Y'know, if you want to.
var/holodeck_type = /area/holodeck/rec_center // locate(this) to get the target holodeck
var/holodeck_type = /area/holodeck/rec_center
var/list/program_cache
var/list/emag_programs
var/active = FALSE
var/damaged = FALSE
@@ -49,16 +49,18 @@
return INITIALIZE_HINT_LATELOAD
/obj/machinery/computer/holodeck/LateInitialize()
if(ispath(holodeck_type, /area))
linked = pop(get_areas(holodeck_type, FALSE))
if(ispath(offline_program, /area))
offline_program = pop(get_areas(offline_program), FALSE)
// the following is necessary for power reasons
linked = SSholodeck.target_holodeck_area[type]
offline_program = SSholodeck.offline_programs[type]
if(!linked || !offline_program)
log_world("No matching holodeck area found")
qdel(src)
return
var/area/AS = get_area(src)
program_cache = SSholodeck.program_cache[type]
emag_programs = SSholodeck.emag_program_cache[type]
// the following is necessary for power reasons
var/area/AS = get_base_area(src)
if(istype(AS, /area/holodeck))
log_mapping("Holodeck computer cannot be in a holodeck, This would cause circular power dependency.")
qdel(src)
@@ -66,7 +68,6 @@
else
linked.linked = src
generate_program_list()
load_program(offline_program, FALSE, FALSE)
/obj/machinery/computer/holodeck/Destroy()
@@ -181,19 +182,6 @@
emergency_shutdown()
return ..()
/obj/machinery/computer/holodeck/proc/generate_program_list()
for(var/typekey in GLOB.holodeck_areas_prototypes[type])
var/area/holodeck/A = GLOB.areas_by_type[typekey]
if(!A || !A.contents.len)
continue
var/list/info_this = list()
info_this["name"] = A.name
info_this["type"] = A.type
if(A.restricted)
LAZYADD(emag_programs, list(info_this))
else
LAZYADD(program_cache, list(info_this))
/obj/machinery/computer/holodeck/proc/toggle_power(toggleOn = FALSE)
if(active == toggleOn)
return
+1 -3
View File
@@ -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)
-2
View File
@@ -206,8 +206,6 @@
newtonian_move(get_dir(target, src))
thrown_thing.safe_throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src, null, null, null, move_force, random_turn)
/mob/living/carbon/restrained(ignore_grab)
. = (handcuffed || (!ignore_grab && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE))
@@ -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)
@@ -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
@@ -283,7 +283,7 @@ There are several things that need to be remembered:
alt_icon = S.anthro_mob_worn_overlay || 'icons/mob/clothing/feet_digi.dmi'
variation_flag |= STYLE_DIGITIGRADE
overlays_standing[SHOES_LAYER] = shoes.build_worn_icon(SHOES_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, variation_flag, FALSE)
overlays_standing[SHOES_LAYER] = shoes.build_worn_icon(SHOES_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, S.icon_state, variation_flag, FALSE)
var/mutable_appearance/shoes_overlay = overlays_standing[SHOES_LAYER]
if(OFFSET_SHOES in dna.species.offset_features)
shoes_overlay.pixel_x += dna.species.offset_features[OFFSET_SHOES][1]
+1 -1
View File
@@ -23,5 +23,5 @@
if(ranged_ability)
ranged_ability.add_ranged_ability(src, "<span class='notice'>You currently have <b>[ranged_ability]</b> active!</span>")
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()
+1 -1
View File
@@ -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
@@ -152,7 +152,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
to_chat(src, "<span class='warning'>Not a valid name, please try again.</span>")
guardianrename()
return
visible_message("<span class='notice'>Your new name <span class='name'>[new_name]</span> anchors itself in your mind.</span>")
to_chat(src, "<span class='notice'>Your new name <span class='name'>[new_name]</span> anchors itself in your mind.</span>")
fully_replace_character_name(null, new_name)
/mob/living/simple_animal/hostile/guardian/Life() //Dies if the summoner dies
@@ -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
@@ -103,7 +103,7 @@ Difficulty: Hard
if(.)
SSshuttle.shuttle_purchase_requirements_met |= "bubblegum"
/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A)
/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
if(charging)
return
..()
@@ -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()
@@ -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
@@ -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)
@@ -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
+1 -1
View File
@@ -146,7 +146,7 @@
//CITADEL EDIT, required for vore code to remove (T != loc && T != src)) as a check
if(M.see_invisible<invisibility) //if src is invisible to us,
msg = blind_message
else if(T.lighting_object && T.lighting_object.invisibility <= M.see_invisible && T.is_softly_lit()) //the light object is dark and not invisible to us
else if(T.lighting_object && T.lighting_object.invisibility <= M.see_invisible && T.is_softly_lit() && !in_range(T,M)) //the light object is dark and not invisible to us, darkness does not matter if you're directly next to the target
msg = blind_message
if(!msg)
+4 -5
View File
@@ -556,13 +556,12 @@ By design, d1 is the smallest direction and d2 is the highest
new_cable.update_icon()
/obj/item/stack/cable_coil/attack_self(mob/user)
if(!use(15))
to_chat(user, "<span class='notice'>You dont have enough cable coil to make restraints out of them</span>")
if(amount < 15)
to_chat(user, "<span class='notice'>You don't have enough cable coil to make restraints out of them</span>")
return
to_chat(user, "<span class='notice'>You start making some cable restraints.</span>")
if(!do_after(user, 30, TRUE, user, TRUE))
to_chat(user, "<span class='notice'>You fail to make cable restraints, you need to stand still while doing so.</span>")
give(15)
if(!do_after(user, 30, TRUE, user, TRUE) || !use(15))
to_chat(user, "<span class='notice'>You fail to make cable restraints, you need to be standing still to do it</span>")
return
var/obj/item/restraints/handcuffs/cable/result = new(get_turf(user))
user.put_in_hands(result)
@@ -508,7 +508,6 @@
upgrade_reagents3 = list(
/datum/reagent/drug/mushroomhallucinogen,
/datum/reagent/consumable/nothing,
/datum/reagent/medicine/cryoxadone,
/datum/reagent/consumable/peachjuice
)
emagged_reagents = list(
@@ -516,7 +515,8 @@
/datum/reagent/consumable/ethanol/changelingsting,
/datum/reagent/consumable/ethanol/whiskey_cola,
/datum/reagent/toxin/mindbreaker,
/datum/reagent/toxin/staminatoxin
/datum/reagent/toxin/staminatoxin,
/datum/reagent/medicine/cryoxadone
)
/obj/machinery/chem_dispenser/drinks/fullupgrade //fully ugpraded stock parts, emagged
@@ -722,4 +722,4 @@
component_parts += new /obj/item/stock_parts/manipulator/femto(null)
component_parts += new /obj/item/stack/sheet/glass(null)
component_parts += new /obj/item/stock_parts/cell/bluespace(null)
RefreshParts()
RefreshParts()
@@ -353,7 +353,7 @@
/datum/reagent/drug/aranesp
name = "Aranesp"
description = "Amps you up and gets you going, fixes all stamina damage you might have but can cause toxin and oxygen damage."
description = "Amps you up and gets you going, fixing stamina damage but possibly causing toxin and oxygen damage."
reagent_state = LIQUID
color = "#78FFF0"
pH = 9.2
@@ -362,7 +362,7 @@
var/high_message = pick("You feel amped up.", "You feel ready.", "You feel like you can push it to the limit.")
if(prob(5))
to_chat(M, "<span class='notice'>[high_message]</span>")
M.adjustStaminaLoss(-18, 0)
M.adjustStaminaLoss(-10, 0)
M.adjustToxLoss(0.5, 0)
if(prob(50))
M.losebreath++
+25 -4
View File
@@ -293,20 +293,20 @@
name = "Broom"
desc = "Just your everyday standard broom."
id = "broom"
build_type = PROTOLATHE
build_type = PROTOLATHE | AUTOLATHE
materials = list(/datum/material/iron = 1000, /datum/material/glass = 600)
build_path = /obj/item/twohanded/broom
category = list("Equipment")
category = list("initial", "Equipment", "Misc")
departmental_flags = DEPARTMENTAL_FLAG_SERVICE
/datum/design/mop
name = "Mop"
desc = "Just your everyday standard mop."
id = "mop"
build_type = PROTOLATHE
build_type = PROTOLATHE | AUTOLATHE
materials = list(/datum/material/iron = 1200, /datum/material/glass = 100)
build_path = /obj/item/mop
category = list("Equipment")
category = list("initial", "Equipment", "Misc")
departmental_flags = DEPARTMENTAL_FLAG_SERVICE
/datum/design/advmop
@@ -329,6 +329,16 @@
category = list("Equipment")
departmental_flags = DEPARTMENTAL_FLAG_SERVICE
/datum/design/normtrash
name = "Trashbag"
desc = "It's a bag for trash, you put garbage in it."
id = "normtrash"
build_type = PROTOLATHE
materials = list(/datum/material/plastic = 2000)
build_path = /obj/item/storage/bag/trash
category = list("Equipment")
departmental_flags = DEPARTMENTAL_FLAG_SERVICE
/datum/design/blutrash
name = "Trashbag of Holding"
desc = "An advanced trash bag with bluespace properties; capable of holding a plethora of garbage."
@@ -349,6 +359,17 @@
category = list("Equipment")
departmental_flags = DEPARTMENTAL_FLAG_SERVICE
/datum/design/paint_remover
name = "Paint Remover"
desc = "Removes stains from the floor, and not much else."
id = "paint_remover"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 1000)
reagents_list = list(/datum/reagent/acetone = 60)
build_path = /obj/item/paint/paint_remover
category = list("Equipment")
departmental_flags = DEPARTMENTAL_FLAG_SERVICE
/datum/design/spraybottle
name = "Spray Bottle"
desc = "A spray bottle, with an unscrewable top."
@@ -435,9 +435,9 @@
category = list("Weapons")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
//////////
//MISC////
//////////
///////////
//Shields//
///////////
/datum/design/tele_shield
name = "Telescopic Riot Shield"
@@ -449,6 +449,30 @@
category = list("Weapons")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
/datum/design/laser_shield
name = "Laser Resistant Riot Shield"
desc = "An advanced riot shield made of darker glasses to prevent laser fire from passing through."
id = "laser_shield"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 4000, /datum/material/glass = 1000, /datum/material/plastic = 4000, /datum/material/silver = 800, /datum/material/titanium = 600, /datum/material/plasma = 5000)
build_path = /obj/item/shield/riot/laser_proof
category = list("Weapons")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
/datum/design/bullet_shield
name = "Bullet Resistant Riot Shield"
desc = "An advanced riot shield made bullet resistant plastics and heavy metals to protect against projectile harm."
id = "bullet_shield"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 4000, /datum/material/glass = 1000, /datum/material/silver = 2000, /datum/material/titanium = 1200, /datum/material/plastic = 2500)
build_path = /obj/item/shield/riot/bullet_proof
category = list("Weapons")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
//////////
//MISC////
//////////
/datum/design/suppressor
name = "Suppressor"
desc = "A reverse-engineered suppressor that fits on most small arms with threaded barrels."
+4 -4
View File
@@ -535,7 +535,7 @@
display_name = "Combat Cybernetic Implants"
description = "Military grade combat implants to improve performance."
prereq_ids = list("adv_cyber_implants","weaponry","NVGtech","high_efficiency")
design_ids = list("ci-xray", "ci-thermals", "ci-antidrop", "ci-antistun", "ci-thrusters")
design_ids = list("ci-xray", "ci-thermals", "ci-antidrop", "ci-antistun", "ci-thrusters", "ci-shield")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
////////////////////////Tools////////////////////////
@@ -544,7 +544,7 @@
display_name = "Basic Tools"
description = "Basic mechanical, electronic, surgical and botanical tools."
prereq_ids = list("base")
design_ids = list("screwdriver", "wrench", "wirecutters", "crowbar", "multitool", "welding_tool", "tscanner", "analyzer", "cable_coil", "pipe_painter", "airlock_painter", "scalpel", "circular_saw", "surgicaldrill", "retractor", "cautery", "hemostat", "cultivator", "plant_analyzer", "shovel", "spade", "hatchet", "mop", "broom")
design_ids = list("screwdriver", "wrench", "wirecutters", "crowbar", "multitool", "welding_tool", "tscanner", "analyzer", "cable_coil", "pipe_painter", "airlock_painter", "scalpel", "circular_saw", "surgicaldrill", "retractor", "cautery", "hemostat", "cultivator", "plant_analyzer", "shovel", "spade", "hatchet", "mop", "broom", "normtrash")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 500)
/datum/techweb_node/basic_mining
@@ -568,7 +568,7 @@
display_name = "Advanced Sanitation Technology"
description = "Clean things better, faster, stronger, and harder!"
prereq_ids = list("adv_engi")
design_ids = list("advmop", "buffer", "light_replacer", "spraybottle", "beartrap", "ci-janitor")
design_ids = list("advmop", "buffer", "light_replacer", "spraybottle", "beartrap", "ci-janitor", "paint_remover")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1750) // No longer has its bag
/datum/techweb_node/botany
@@ -609,7 +609,7 @@
display_name = "Advanced Weapon Development Technology"
description = "Our weapons are breaking the rules of reality by now."
prereq_ids = list("adv_engi", "weaponry")
design_ids = list("pin_loyalty")
design_ids = list("pin_loyalty", "laser_shield", "bullet_shield")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7500)
/datum/techweb_node/electric_weapons
+13 -8
View File
@@ -89,18 +89,23 @@
"<span class='notice'>You remove [I] from [M]'s [parse_zone(selected_zone)].</span>")
qdel(S)
else if(S.can_cancel)
var/close_tool_type = /obj/item/cautery
var/required_tool_type = TOOL_CAUTERY
var/obj/item/close_tool = user.get_inactive_held_item()
var/is_robotic = S.requires_bodypart_type == BODYPART_ROBOTIC
if(is_robotic)
close_tool_type = /obj/item/screwdriver
if(istype(close_tool, close_tool_type) || iscyborg(user))
M.surgeries -= S
user.visible_message("[user] closes [M]'s [parse_zone(selected_zone)] with [close_tool] and removes [I].", \
"<span class='notice'>You close [M]'s [parse_zone(selected_zone)] with [close_tool] and remove [I].</span>")
qdel(S)
else
required_tool_type = TOOL_SCREWDRIVER
if(iscyborg(user))
close_tool = locate(/obj/item/cautery) in user.held_items
if(!close_tool)
to_chat(user, "<span class='warning'>You need to equip a cautery in an inactive slot to stop [M]'s surgery!</span>")
return
else if(!close_tool || close_tool.tool_behaviour != required_tool_type)
to_chat(user, "<span class='warning'>You need to hold a [is_robotic ? "screwdriver" : "cautery"] in your inactive hand to stop [M]'s surgery!</span>")
return
M.surgeries -= S
user.visible_message("<span class='notice'>[user] closes [M]'s [parse_zone(selected_zone)] with [close_tool] and removes [I].</span>", \
"<span class='notice'>You close [M]'s [parse_zone(selected_zone)] with [close_tool] and remove [I].</span>")
qdel(S)
/proc/get_location_modifier(mob/M)
var/turf/T = get_turf(M)
@@ -24,13 +24,6 @@
Radio headset does not include encryption key. No gun included."
item = /obj/item/storage/box/syndie_kit/centcom_costume
/datum/uplink_item/badass/claymore
name = "Claymore"
cost = 8
player_minimum = 25
desc = "A claymore. We don't know why you'd do this."
item = /obj/item/claymore
/datum/uplink_item/badass/costumes/clown
name = "Clown Costume"
desc = "Nothing is more terrifying than clowns with fully automatic weaponry."
@@ -84,11 +77,3 @@
limited_stock = 1
cant_discount = TRUE
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/badass/shades
name = "Big Sunglasses"
desc = "Prevents flashes and looks badbass with some Smokes."
item = /obj/item/clothing/glasses/sunglasses/big
cost = 1
surplus = 5
illegal_tech = FALSE
@@ -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."
@@ -117,17 +117,6 @@
/datum/uplink_item/dangerous/doublesword/get_discount()
return pick(4;0.8,2;0.65,1;0.5)
/datum/uplink_item/dangerous/cxneb
name = "Dragon's Tooth Non-Eutactic Blade"
desc = "An illegal modification of a weapon that is functionally identical to the energy sword, \
the Non-Eutactic Blade (NEB) forges a hardlight blade on-demand, \
generating an extremely sharp, unbreakable edge that is guaranteed to satisfy your every need. \
This particular model has a polychromic hardlight generator, allowing you to murder in style! \
The illegal modifications bring this weapon up to par with the classic energy sword, and also gives it the energy sword's distinctive sounds."
item = /obj/item/melee/transforming/energy/sword/cx/traitor
cost = 8
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/dangerous/sword
name = "Energy Sword"
desc = "The energy sword is an edged weapon with a blade of pure energy. The sword is small enough to be \
@@ -64,14 +64,6 @@
restricted_roles = list("Clown")
*/
/datum/uplink_item/role_restricted/clumsyDNA
name = "Clumsy Clown DNA"
desc = "A DNA injector that has been loaded with the clown gene that makes people clumsy.. \
Making someone clumsy will allow them to use clown firing pins as well as Reverse Revolvers. For a laugh try using this on the HOS to see how many times they shoot themselves in the foot!"
cost = 1
item = /obj/item/dnainjector/clumsymut
restricted_roles = list("Clown")
/datum/uplink_item/role_restricted/haunted_magic_eightball
name = "Haunted Magic Eightball"
desc = "Most magic eightballs are toys with dice inside. Although identical in appearance to the harmless toys, this occult device reaches into the spirit world to find its answers. \
@@ -116,19 +108,11 @@
cost = 4
restricted_roles = list("Cook", "Botanist", "Clown", "Mime")
/datum/uplink_item/role_restricted/strange_seeds
name = "Pack of strange seeds"
desc = "Mysterious seeds as strange as their name implies. Spooky."
item = /obj/item/seeds/random
cost = 2
restricted_roles = list("Botanist")
illegal_tech = FALSE
/datum/uplink_item/role_restricted/strange_seeds_10pack
name = "Pack of strange seeds x10"
name = "Pack of strange seeds"
desc = "Mysterious seeds as strange as their name implies. Spooky. These come in bulk"
item = /obj/item/storage/box/strange_seeds_10pack
cost = 20
cost = 10
restricted_roles = list("Botanist")
/datum/uplink_item/role_restricted/ez_clean_bundle
+8 -8
View File
@@ -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("<span class='warning'>[formatted_message]</span><BR>")
@@ -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,"<span class='notice'>[owner]'s [lowertext(name)] absorbs your body, making you part of them.</span>")
to_chat(owner,"<span class='notice'>Your [lowertext(name)] absorbs [M]'s body, making them part of you.</span>")
@@ -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
+7 -7
View File
@@ -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,"<span class='notice'>[pick(EL)]</span>")
///////////////////// 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,"<span class='notice'>You suddenly feel solid again </span>")
to_chat(owner,"<span class='notice'>You feel like a part of you is missing.</span>")
owner.nutrition -= 100
+25 -25
View File
@@ -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, "<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
@@ -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, "<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)
if(!CHECK_BITFIELD(prey.vore_flags,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
@@ -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,"<span class='warning'>You attempted to save your vore prefs but somehow you're in this character without a client.prefs variable. Tell a dev.</span>")
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,"<span class='warning'>You attempted to apply your vore prefs but somehow you're in this character without a client.prefs variable. Tell a dev.</span>")
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)
+31 -31
View File
@@ -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 += "<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>"
dat += "<font color = 'green'>You are currently [(user.vore_flags & ABSORBED) ? "absorbed into " : "inside "]</font> <font color = 'yellow'>[eater]'s</font> <font color = 'red'>[inside_belly]</font>!<br><br>"
if(inside_belly.desc)
dat += "[inside_belly.desc]<br><br>"
@@ -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 += "<a href='?src=\ref[src];outsidepick=\ref[O];outsidebelly=\ref[inside_belly]'><span style='color:purple;'>[O]</span></a>"
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 += "<a href='?src=\ref[src];insidepick=\ref[O]'><span style='color:purple;'>[O]</span></a>"
continue
@@ -243,11 +243,11 @@
dat += "<HR>"
var/pref_on = "#173d15"
var/pref_off = "#990000"
dat += "<br><a style='background:[user.digestable ? pref_on : pref_off];' href='?src=\ref[src];toggledg=1'>Toggle Digestable (Currently: [user.digestable ? "ON" : "OFF"])</a>"
dat += "<br><a style='background:[user.devourable ? pref_on : pref_off];' href='?src=\ref[src];toggledvor=1'>Toggle Devourable (Currently: [user.devourable ? "ON" : "OFF"])</a>"
dat += "<br><a style='background:[user.feeding ? pref_on : pref_off];' href='?src=\ref[src];toggledfeed=1'>Toggle Feeding (Currently: [user.feeding ? "ON" : "OFF"])</a>"
dat += "<br><a style='background:[(user.vore_flags & DIGESTABLE) ? pref_on : pref_off];' href='?src=\ref[src];toggledg=1'>Toggle Digestable (Currently: [(user.vore_flags & DIGESTABLE) ? "ON" : "OFF"])</a>"
dat += "<br><a style='background:[(user.vore_flags & DEVOURABLE) ? pref_on : pref_off];' href='?src=\ref[src];toggledvor=1'>Toggle Devourable (Currently: [(user.vore_flags & DEVOURABLE) ? "ON" : "OFF"])</a>"
dat += "<br><a style='background:[(user.vore_flags & FEEDING) ? pref_on : pref_off];' href='?src=\ref[src];toggledfeed=1'>Toggle Feeding (Currently: [(user.vore_flags & FEEDING) ? "ON" : "OFF"])</a>"
if(user.client.prefs)
dat += "<br><a style='background:[user.client.prefs.lickable ? pref_on : pref_off];' href='?src=\ref[src];toggledlickable=1'>Toggle Licking (Currently: [user.client.prefs.lickable ? "ON" : "OFF"])</a>"
dat += "<br><a style='background:[(user.client.prefs.vore_flags & LICKABLE) ? pref_on : pref_off];' href='?src=\ref[src];toggledlickable=1'>Toggle Licking (Currently: [(user.client.prefs.vore_flags & LICKABLE) ? "ON" : "OFF"])</a>"
//Returns the dat html to the vore_look
return dat
@@ -257,7 +257,7 @@
if(href_list["close"])
qdel(src) // Cleanup
user.openpanel = FALSE
user.vore_flags &= ~OPEN_PANEL
return
if(href_list["show_int"])
@@ -287,7 +287,7 @@
M.examine(user)
if("Help Out") //Help the inside-mob out
if(user.stat || user.absorbed || M.absorbed)
if(user.stat || user.vore_flags & ABSORBED || M.vore_flags & ABSORBED)
to_chat(user,"<span class='warning'>You can't do that in your state!</span>")
return TRUE
@@ -306,7 +306,7 @@
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)
if(user.vore_flags & ABSORBED || user.stat)
to_chat(user,"<span class='warning'>You can't do that in your state!</span>")
return TRUE
@@ -687,58 +687,58 @@
user.vore_taste = new_flavor
if(href_list["toggledg"])
var/choice = alert(user, "This button is for those who don't like being digested. It can make you undigestable to all mobs. Digesting you is currently: [user.digestable ? "Allowed" : "Prevented"]", "", "Allow Digestion", "Cancel", "Prevent Digestion")
var/choice = alert(user, "This button is for those who don't like being digested. It can make you undigestable to all mobs. Digesting you is currently: [(user.vore_flags & DIGESTABLE) ? "Allowed" : "Prevented"]", "", "Allow Digestion", "Cancel", "Prevent Digestion")
if(!user || !user.client)
return
switch(choice)
if("Cancel")
return FALSE
if("Allow Digestion")
user.digestable = TRUE
user.vore_flags |= DIGESTABLE
user.client.prefs.vore_flags |= DIGESTABLE
if("Prevent Digestion")
user.digestable = FALSE
user.client.prefs.digestable = user.digestable
user.vore_flags &= ~DIGESTABLE
user.client.prefs.vore_flags &= ~DIGESTABLE
if(href_list["toggledvor"])
var/choice = alert(user, "This button is for those who don't like vore at all. Devouring you is currently: [user.devourable ? "Allowed" : "Prevented"]", "", "Allow Devourment", "Cancel", "Prevent Devourment")
var/choice = alert(user, "This button is for those who don't like vore at all. Devouring you is currently: [(user.vore_flags & DEVOURABLE) ? "Allowed" : "Prevented"]", "", "Allow Devourment", "Cancel", "Prevent Devourment")
if(!user || !user.client)
return
switch(choice)
if("Cancel")
return FALSE
if("Allow Devourment")
user.devourable = TRUE
user.vore_flags |= DEVOURABLE
user.client.prefs.vore_flags |= DEVOURABLE
if("Prevent Devourment")
user.devourable = FALSE
user.client.prefs.devourable = user.devourable
user.vore_flags &= ~DEVOURABLE
user.client.prefs.vore_flags &= ~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")
var/choice = alert(user, "This button is to toggle your ability to be fed to others. Feeding predators is currently: [(user.vore_flags & FEEDING) ? "Allowed" : "Prevented"]", "", "Allow Feeding", "Cancel", "Prevent Feeding")
if(!user || !user.client)
return
switch(choice)
if("Cancel")
return FALSE
if("Allow Feeding")
user.feeding = TRUE
user.vore_flags |= FEEDING
user.client.prefs.vore_flags |= FEEDING
if("Prevent Feeding")
user.feeding = FALSE
user.client.prefs.feeding = user.feeding
user.vore_flags &= ~FEEDING
user.client.prefs.vore_flags &= ~FEEDING
if(href_list["toggledlickable"])
var/choice = alert(user, "This button is to toggle your ability to be licked. Being licked is currently: [user.client.prefs.lickable ? "Allowed" : "Prevented"]", "", "Allow Licking", "Cancel", "Prevent Licking")
var/choice = alert(user, "This button is to toggle your ability to be licked. Being licked is currently: [(user.client.prefs.vore_flags & LICKABLE) ? "Allowed" : "Prevented"]", "", "Allow Licking", "Cancel", "Prevent Licking")
if(!user || !user.client)
return
switch(choice)
if("Cancel")
return FALSE
if("Allow Licking")
user.client.prefs.lickable = TRUE
user.client.prefs.vore_flags |= LICKABLE
if("Prevent Licking")
user.client.prefs.lickable = FALSE
user.client.prefs.vore_flags &= ~LICKABLE
//Refresh when interacted with, returning 1 makes vore_look.Topic update
return TRUE