Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit685
This commit is contained in:
@@ -60,7 +60,9 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden,
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 5
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/security/main)
|
||||
"aai" = (
|
||||
@@ -2696,6 +2698,9 @@
|
||||
/obj/effect/turf_decal/tile/red{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/security/main)
|
||||
"afp" = (
|
||||
@@ -4439,9 +4444,6 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/tile/red{
|
||||
dir = 1
|
||||
},
|
||||
@@ -5100,9 +5102,6 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "2-4"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 6
|
||||
},
|
||||
@@ -5528,9 +5527,6 @@
|
||||
dir = 1;
|
||||
pixel_y = -24
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/tile/red{
|
||||
dir = 1
|
||||
},
|
||||
@@ -5546,14 +5542,14 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/turf_decal/tile/red,
|
||||
/obj/effect/turf_decal/tile/red{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 6
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/security/main)
|
||||
"akj" = (
|
||||
@@ -7986,6 +7982,9 @@
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 6
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "2-8"
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/maintenance/fore/secondary)
|
||||
"aqm" = (
|
||||
@@ -9816,6 +9815,9 @@
|
||||
name = "Dormitories Maintenance";
|
||||
req_access_txt = "12"
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/maintenance/fore/secondary)
|
||||
"avy" = (
|
||||
@@ -10271,6 +10273,9 @@
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 5
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/crew_quarters/dorms)
|
||||
"awz" = (
|
||||
@@ -23786,9 +23791,6 @@
|
||||
"bfC" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/flashlight/lamp/green,
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 5
|
||||
},
|
||||
/turf/open/floor/wood,
|
||||
/area/crew_quarters/heads/captain)
|
||||
"bfD" = (
|
||||
@@ -55616,6 +55618,10 @@
|
||||
},
|
||||
/turf/open/floor/wood,
|
||||
/area/crew_quarters/bar)
|
||||
"iUK" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/security/vacantoffice/b)
|
||||
"iVU" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
@@ -56974,6 +56980,12 @@
|
||||
/obj/machinery/vending/autodrobe,
|
||||
/turf/open/floor/wood,
|
||||
/area/maintenance/bar)
|
||||
"nfw" = (
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/crew_quarters/dorms)
|
||||
"ngs" = (
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/on{
|
||||
dir = 8
|
||||
@@ -57837,6 +57849,13 @@
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/crew_quarters/fitness)
|
||||
"pRW" = (
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/maintenance/fore/secondary)
|
||||
"pTB" = (
|
||||
/obj/structure/lattice/catwalk,
|
||||
/obj/structure/cable{
|
||||
@@ -59423,6 +59442,15 @@
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/space/nearstation)
|
||||
"vaW" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/crew_quarters/dorms)
|
||||
"vbi" = (
|
||||
/obj/structure/table,
|
||||
/obj/item/instrument/guitar{
|
||||
@@ -59990,6 +60018,9 @@
|
||||
dir = 1;
|
||||
pixel_y = -22
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-4"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/crew_quarters/dorms)
|
||||
"wrp" = (
|
||||
@@ -86195,7 +86226,7 @@ cCi
|
||||
aqX
|
||||
arR
|
||||
asj
|
||||
arT
|
||||
iUK
|
||||
ajr
|
||||
atY
|
||||
auo
|
||||
@@ -94674,15 +94705,15 @@ aoa
|
||||
ajo
|
||||
apt
|
||||
aql
|
||||
aoJ
|
||||
aoJ
|
||||
aoJ
|
||||
aoJ
|
||||
pRW
|
||||
pRW
|
||||
pRW
|
||||
pRW
|
||||
avw
|
||||
awy
|
||||
awr
|
||||
awr
|
||||
avG
|
||||
nfw
|
||||
nfw
|
||||
vaW
|
||||
wqF
|
||||
aAh
|
||||
aAh
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -73,6 +73,9 @@
|
||||
#define CAT_AMMO "Ammunition"
|
||||
#define CAT_ROBOT "Robots"
|
||||
#define CAT_MISC "Misc"
|
||||
#define CAT_MISCELLANEOUS "Miscellaneous"
|
||||
#define CAT_TOOL "Tools & Storage"
|
||||
#define CAT_FURNITURE "Furniture"
|
||||
#define CAT_PRIMAL "Tribal"
|
||||
#define CAT_CLOTHING "Clothing"
|
||||
#define CAT_FOOD "Foods"
|
||||
|
||||
@@ -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)
|
||||
@@ -246,6 +246,8 @@ GLOBAL_LIST_INIT(pointed_types, typecacheof(list(
|
||||
|
||||
#define isgun(A) (istype(A, /obj/item/gun))
|
||||
|
||||
#define isfood(A) (istype(A, /obj/item/reagent_containers/food))
|
||||
|
||||
//Assemblies
|
||||
#define isassembly(O) (istype(O, /obj/item/assembly))
|
||||
|
||||
|
||||
+10
-10
@@ -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
|
||||
|
||||
@@ -62,10 +62,11 @@
|
||||
#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 40
|
||||
#define INIT_ORDER_ECONOMY 45
|
||||
#define INIT_ORDER_NETWORKS 40
|
||||
#define INIT_ORDER_HOLODECK 35
|
||||
#define INIT_ORDER_ATOMS 30
|
||||
#define INIT_ORDER_LANGUAGE 25
|
||||
#define INIT_ORDER_MACHINES 20
|
||||
@@ -91,12 +92,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
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -69,9 +69,13 @@
|
||||
H.apply_status_effect(/datum/status_effect/neck_slice)
|
||||
|
||||
/datum/component/butchering/proc/Butcher(mob/living/butcher, mob/living/meat)
|
||||
var/meat_quality = 50 + (bonus_modifier/10) //increases through quality of butchering tool, and through if it was butchered in the kitchen or not
|
||||
if(istype(get_area(butcher), /area/crew_quarters/kitchen))
|
||||
meat_quality = meat_quality + 10
|
||||
var/turf/T = meat.drop_location()
|
||||
var/final_effectiveness = effectiveness - meat.butcher_difficulty
|
||||
var/bonus_chance = max(0, (final_effectiveness - 100) + bonus_modifier) //so 125 total effectiveness = 25% extra chance
|
||||
var/list/butchered_items = list()
|
||||
for(var/V in meat.butcher_results)
|
||||
var/obj/bones = V
|
||||
var/amount = meat.butcher_results[bones]
|
||||
@@ -83,16 +87,21 @@
|
||||
if(butcher)
|
||||
to_chat(butcher, "<span class='info'>You harvest some extra [initial(bones.name)] from [meat]!</span>")
|
||||
for(var/i in 1 to 2)
|
||||
new bones (T)
|
||||
butchered_items += new bones (T)
|
||||
|
||||
else
|
||||
new bones (T)
|
||||
butchered_items += new bones (T)
|
||||
meat.butcher_results.Remove(bones) //in case you want to, say, have it drop its results on gib
|
||||
for(var/V in meat.guaranteed_butcher_results)
|
||||
var/obj/sinew = V
|
||||
var/amount = meat.guaranteed_butcher_results[sinew]
|
||||
for(var/i in 1 to amount)
|
||||
new sinew (T)
|
||||
butchered_items += new sinew (T)
|
||||
meat.guaranteed_butcher_results.Remove(sinew)
|
||||
for(var/butchered_item in butchered_items)
|
||||
if(isfood(butchered_item))
|
||||
var/obj/item/reagent_containers/food/butchered_meat = butchered_item
|
||||
butchered_meat.food_quality = meat_quality
|
||||
if(butcher)
|
||||
meat.visible_message("<span class='notice'>[butcher] butchers [meat].</span>")
|
||||
ButcherEffects(meat)
|
||||
|
||||
@@ -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_MISCELLANEOUS,
|
||||
CAT_TOOL,
|
||||
CAT_FURNITURE,
|
||||
),
|
||||
CAT_PRIMAL = CAT_NONE,
|
||||
CAT_FOOD = list(
|
||||
CAT_BREAD,
|
||||
@@ -201,6 +205,18 @@
|
||||
var/atom/movable/I = new R.result (get_turf(user.loc))
|
||||
I.CheckParts(parts, R)
|
||||
if(isitem(I))
|
||||
if(isfood(I))
|
||||
var/obj/item/reagent_containers/food/food_result = I
|
||||
var/total_quality = 0
|
||||
var/total_items = 0
|
||||
for(var/obj/item/ingredient in parts)
|
||||
var/obj/item/reagent_containers/food/food_ingredient = ingredient
|
||||
total_items += 1
|
||||
total_quality += food_ingredient.food_quality
|
||||
if(total_items == 0)
|
||||
food_result.adjust_food_quality(50)
|
||||
else
|
||||
food_result.adjust_food_quality(total_quality / total_items)
|
||||
user.put_in_hands(I)
|
||||
if(send_feedback)
|
||||
SSblackbox.record_feedback("tally", "object_crafted", 1, I.type)
|
||||
|
||||
@@ -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
|
||||
@@ -18,6 +19,7 @@
|
||||
/obj/item/stack/sheet/mineral/wood = 20,
|
||||
/obj/item/stack/cable_coil = 10)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/femur_breaker
|
||||
@@ -27,8 +29,88 @@
|
||||
reqs = list(/obj/item/stack/sheet/metal = 20,
|
||||
/obj/item/stack/cable_coil = 30)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
// Blood Sucker stuff //
|
||||
/datum/crafting_recipe/bloodsucker/blackcoffin
|
||||
name = "Black Coffin"
|
||||
result = /obj/structure/closet/crate/coffin/blackcoffin
|
||||
tools = list(/obj/item/weldingtool,
|
||||
/obj/item/screwdriver)
|
||||
reqs = list(/obj/item/stack/sheet/cloth = 1,
|
||||
/obj/item/stack/sheet/mineral/wood = 5,
|
||||
/obj/item/stack/sheet/metal = 1)
|
||||
///obj/item/stack/packageWrap = 8,
|
||||
///obj/item/pipe = 2)
|
||||
time = 150
|
||||
subcategory = CAT_FURNITURE
|
||||
category = CAT_MISC
|
||||
always_availible = TRUE
|
||||
|
||||
/datum/crafting_recipe/bloodsucker/meatcoffin
|
||||
name = "Meat Coffin"
|
||||
result =/obj/structure/closet/crate/coffin/meatcoffin
|
||||
tools = list(/obj/item/kitchen/knife,
|
||||
/obj/item/kitchen/rollingpin)
|
||||
reqs = list(/obj/item/reagent_containers/food/snacks/meat/slab = 5,
|
||||
/obj/item/restraints/handcuffs/cable = 1)
|
||||
time = 150
|
||||
subcategory = CAT_FURNITURE
|
||||
category = CAT_MISC
|
||||
always_availible = TRUE
|
||||
|
||||
/datum/crafting_recipe/bloodsucker/metalcoffin
|
||||
name = "Metal Coffin"
|
||||
result =/obj/structure/closet/crate/coffin/metalcoffin
|
||||
tools = list(/obj/item/weldingtool,
|
||||
/obj/item/screwdriver)
|
||||
reqs = list(/obj/item/stack/sheet/metal = 5)
|
||||
time = 100
|
||||
subcategory = CAT_FURNITURE
|
||||
category = CAT_MISC
|
||||
always_availible = TRUE
|
||||
|
||||
/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
|
||||
)
|
||||
//parts = list(/obj/item/storage/belt = 1
|
||||
// )
|
||||
time = 150
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
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
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
always_availible = FALSE // Disabled til learned
|
||||
|
||||
///////////////////
|
||||
//Tools & Storage//
|
||||
///////////////////
|
||||
@@ -42,6 +124,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 +136,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 +164,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 +176,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 +188,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 +200,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 +212,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 +221,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
|
||||
|
||||
////////////
|
||||
@@ -128,6 +243,7 @@
|
||||
reqs = list(/obj/item/stack/sheet/plasteel = 2,
|
||||
/obj/item/stack/rods = 8)
|
||||
time = 100
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/skateboard
|
||||
@@ -136,6 +252,7 @@
|
||||
time = 60
|
||||
reqs = list(/obj/item/stack/sheet/metal = 5,
|
||||
/obj/item/stack/rods = 10)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/scooter
|
||||
@@ -144,6 +261,7 @@
|
||||
time = 65
|
||||
reqs = list(/obj/item/stack/sheet/metal = 5,
|
||||
/obj/item/stack/rods = 12)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/////////
|
||||
@@ -154,18 +272,21 @@
|
||||
name = "Toy Sword"
|
||||
reqs = list(/obj/item/light/bulb = 1, /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/plastic = 4)
|
||||
result = /obj/item/toy/sword
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/extendohand
|
||||
name = "Extendo-Hand"
|
||||
reqs = list(/obj/item/bodypart/r_arm/robot = 1, /obj/item/clothing/gloves/boxing = 1)
|
||||
result = /obj/item/extendohand
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/toyneb
|
||||
name = "Non-Euplastic Blade"
|
||||
reqs = list(/obj/item/light/tube = 1, /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/plastic = 4)
|
||||
result = /obj/item/toy/sword/cx
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
////////////
|
||||
@@ -176,6 +297,7 @@
|
||||
name = "Black Carpet"
|
||||
reqs = list(/obj/item/stack/tile/carpet = 50, /obj/item/toy/crayon/black = 1)
|
||||
result = /obj/item/stack/tile/carpet/black/fifty
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/paperframes
|
||||
@@ -183,6 +305,7 @@
|
||||
result = /obj/item/stack/sheet/paperframes/five
|
||||
time = 10
|
||||
reqs = list(/obj/item/stack/sheet/mineral/wood = 5, /obj/item/paper = 20)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/naturalpaper
|
||||
@@ -191,6 +314,7 @@
|
||||
reqs = list(/datum/reagent/water = 50, /obj/item/stack/sheet/mineral/wood = 1)
|
||||
tools = list(/obj/item/hatchet)
|
||||
result = /obj/item/paper_bin/bundlenatural
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/bluespacehonker
|
||||
@@ -200,6 +324,7 @@
|
||||
reqs = list(/obj/item/stack/ore/bluespace_crystal = 1,
|
||||
/obj/item/toy/crayon/blue = 1,
|
||||
/obj/item/bikehorn = 1)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/mousetrap
|
||||
@@ -208,13 +333,7 @@
|
||||
time = 10
|
||||
reqs = list(/obj/item/stack/sheet/cardboard = 1,
|
||||
/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)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/flashlight_eyes
|
||||
@@ -225,13 +344,7 @@
|
||||
/obj/item/flashlight = 2,
|
||||
/obj/item/restraints/handcuffs/cable = 1
|
||||
)
|
||||
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_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/pressureplate
|
||||
@@ -242,6 +355,7 @@
|
||||
/obj/item/stack/tile/plasteel = 1,
|
||||
/obj/item/stack/cable_coil = 2,
|
||||
/obj/item/assembly/igniter = 1)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/gold_horn
|
||||
@@ -250,6 +364,7 @@
|
||||
time = 20
|
||||
reqs = list(/obj/item/stack/sheet/mineral/bananium = 5,
|
||||
/obj/item/bikehorn = 1)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/spooky_camera
|
||||
@@ -259,6 +374,7 @@
|
||||
reqs = list(/obj/item/camera = 1,
|
||||
/datum/reagent/water/holywater = 10)
|
||||
parts = list(/obj/item/camera = 1)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/paperwork
|
||||
@@ -267,6 +383,16 @@
|
||||
time = 10 //Takes time for people to file and complete paper work!
|
||||
tools = list(/obj/item/pen)
|
||||
reqs = list(/obj/item/folder/paperwork = 1)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
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
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
//////////////
|
||||
@@ -279,6 +405,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 +414,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 +423,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 +432,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 +441,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 +450,5 @@
|
||||
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
|
||||
)
|
||||
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
|
||||
|
||||
|
||||
/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
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
UnregisterSignal(parent, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED))
|
||||
unmodify()
|
||||
|
||||
/datum/component/fantasy/Destroy()
|
||||
/datum/component/tactical/Destroy()
|
||||
unmodify()
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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,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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 ")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -400,13 +400,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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -239,19 +239,29 @@
|
||||
if(user.mind && (user.mind.isholy) && !reskinned)
|
||||
reskin_holy_weapon(user)
|
||||
|
||||
/**
|
||||
* reskin_holy_weapon: Shows a user a list of all available nullrod reskins and based on his choice replaces the nullrod with the reskinned version
|
||||
*
|
||||
* Arguments:
|
||||
* * M The mob choosing a nullrod reskin
|
||||
*/
|
||||
/obj/item/nullrod/proc/reskin_holy_weapon(mob/living/L)
|
||||
if(GLOB.holy_weapon_type)
|
||||
return
|
||||
var/obj/item/holy_weapon
|
||||
var/list/holy_weapons_list = subtypesof(/obj/item/nullrod) + list(HOLY_WEAPONS)
|
||||
var/list/display_names = list()
|
||||
var/list/nullrod_icons = list()
|
||||
for(var/V in holy_weapons_list)
|
||||
var/obj/item/nullrod/rodtype = V
|
||||
if (initial(rodtype.chaplain_spawnable))
|
||||
display_names[initial(rodtype.name)] = rodtype
|
||||
nullrod_icons += list(initial(rodtype.name) = image(icon = initial(rodtype.icon), icon_state = initial(rodtype.icon_state)))
|
||||
|
||||
var/choice = input(L, "What theme would you like for your holy weapon?","Holy Weapon Theme") as null|anything in display_names
|
||||
if(QDELETED(src) || !choice || !in_range(L, src) || !CHECK_MOBILITY(L, MOBILITY_USE) || reskinned)
|
||||
nullrod_icons = sortList(nullrod_icons)
|
||||
|
||||
var/choice = show_radial_menu(L, src , nullrod_icons, custom_check = CALLBACK(src, .proc/check_menu, L), radius = 42, require_near = TRUE)
|
||||
if(!choice || !check_menu(L))
|
||||
return
|
||||
|
||||
var/A = display_names[choice] // This needs to be on a separate var as list member access is not allowed for new
|
||||
@@ -266,6 +276,21 @@
|
||||
qdel(src)
|
||||
L.put_in_active_hand(holy_weapon)
|
||||
|
||||
/**
|
||||
* check_menu: Checks if we are allowed to interact with a radial menu
|
||||
*
|
||||
* Arguments:
|
||||
* * user The mob interacting with a menu
|
||||
*/
|
||||
/obj/item/nullrod/proc/check_menu(mob/user)
|
||||
if(!istype(user))
|
||||
return FALSE
|
||||
if(QDELETED(src) || reskinned)
|
||||
return FALSE
|
||||
if(user.incapacitated() || !user.is_holding(src))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/nullrod/proc/jedi_spin(mob/living/user)
|
||||
for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH))
|
||||
user.setDir(i)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -275,6 +275,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
|
||||
custom_price = 25
|
||||
@@ -285,6 +286,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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -200,39 +200,3 @@
|
||||
to_chat(resident, "<span class='notice'>You fix the mechanism and lock it.</span>")
|
||||
broken = FALSE
|
||||
locked = TRUE
|
||||
|
||||
// Look up recipes.dm OR pneumaticCannon.dm
|
||||
/datum/crafting_recipe/bloodsucker/blackcoffin
|
||||
name = "Black Coffin"
|
||||
result = /obj/structure/closet/crate/coffin/blackcoffin
|
||||
tools = list(/obj/item/weldingtool,
|
||||
/obj/item/screwdriver)
|
||||
reqs = list(/obj/item/stack/sheet/cloth = 1,
|
||||
/obj/item/stack/sheet/mineral/wood = 5,
|
||||
/obj/item/stack/sheet/metal = 1)
|
||||
///obj/item/stack/packageWrap = 8,
|
||||
///obj/item/pipe = 2)
|
||||
time = 150
|
||||
category = CAT_MISC
|
||||
always_availible = TRUE
|
||||
|
||||
/datum/crafting_recipe/bloodsucker/meatcoffin
|
||||
name = "Meat Coffin"
|
||||
result =/obj/structure/closet/crate/coffin/meatcoffin
|
||||
tools = list(/obj/item/kitchen/knife,
|
||||
/obj/item/kitchen/rollingpin)
|
||||
reqs = list(/obj/item/reagent_containers/food/snacks/meat/slab = 5,
|
||||
/obj/item/restraints/handcuffs/cable = 1)
|
||||
time = 150
|
||||
category = CAT_MISC
|
||||
always_availible = TRUE
|
||||
|
||||
/datum/crafting_recipe/bloodsucker/metalcoffin
|
||||
name = "Metal Coffin"
|
||||
result =/obj/structure/closet/crate/coffin/metalcoffin
|
||||
tools = list(/obj/item/weldingtool,
|
||||
/obj/item/screwdriver)
|
||||
reqs = list(/obj/item/stack/sheet/metal = 5)
|
||||
time = 100
|
||||
category = CAT_MISC
|
||||
always_availible = TRUE
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
resistance_flags = FLAMMABLE
|
||||
var/foodtype = NONE
|
||||
var/last_check_time
|
||||
var/food_quality = 50
|
||||
|
||||
/obj/item/reagent_containers/food/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -23,6 +24,9 @@
|
||||
pixel_x = rand(-5, 5)
|
||||
pixel_y = rand(-5, 5)
|
||||
|
||||
/obj/item/reagent_containers/food/proc/adjust_food_quality(new_quality)
|
||||
food_quality = CLAMP(new_quality,0,100)
|
||||
|
||||
/obj/item/reagent_containers/food/proc/checkLiked(var/fraction, mob/M)
|
||||
if(last_check_time + 50 < world.time)
|
||||
if(ishuman(M))
|
||||
@@ -32,13 +36,13 @@
|
||||
to_chat(H,"<span class='warning'>What the hell was that thing?!</span>")
|
||||
H.adjust_disgust(25 + 30 * fraction)
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "toxic_food", /datum/mood_event/disgusting_food)
|
||||
else if(foodtype & H.dna.species.disliked_food)
|
||||
else if((foodtype & H.dna.species.disliked_food) || food_quality <= 30)
|
||||
to_chat(H,"<span class='notice'>That didn't taste very good...</span>")
|
||||
H.adjust_disgust(11 + 15 * fraction)
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "gross_food", /datum/mood_event/gross_food)
|
||||
else if(foodtype & H.dna.species.liked_food)
|
||||
else if(((foodtype & H.dna.species.liked_food) && food_quality >= 50) || food_quality >= 70) //you like food of high quality, and food of regular quality you have a preference for
|
||||
to_chat(H,"<span class='notice'>I love this taste!</span>")
|
||||
H.adjust_disgust(-5 + -2.5 * fraction)
|
||||
H.adjust_disgust(-5 + (-2.5 * food_quality/50) + -2.5 * fraction)
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "fav_food", /datum/mood_event/favorite_food)
|
||||
else
|
||||
if(foodtype & H.dna.species.toxic_food)
|
||||
@@ -48,4 +52,4 @@
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "breakfast", /datum/mood_event/breakfast)
|
||||
last_check_time = world.time
|
||||
|
||||
#undef STOP_SERVING_BREAKFAST
|
||||
#undef STOP_SERVING_BREAKFAST
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
var/list/ingredients = list()
|
||||
var/ingredients_placement = INGREDIENTS_FILL
|
||||
var/customname = "custom"
|
||||
var/total_quality = 0 //quality of all ingredients added together
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/customizable/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -56,6 +57,9 @@
|
||||
S.reagents.trans_to(src,min(S.reagents.total_volume, 15)) //limit of 15, we don't want our custom food to be completely filled by just one ingredient with large reagent volume.
|
||||
foodtype |= S.foodtype
|
||||
update_snack_overlays(S)
|
||||
//quality of customised food is average of the ingredient's qualities
|
||||
total_quality += S.food_quality
|
||||
food_quality = total_quality / length(ingredients)
|
||||
to_chat(user, "<span class='notice'>You add the [I.name] to the [name].</span>")
|
||||
update_name(S)
|
||||
else
|
||||
|
||||
@@ -153,6 +153,12 @@ All foods are distributed among various categories. Use common sense.
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/examine(mob/user)
|
||||
. = ..()
|
||||
if(food_quality >= 70)
|
||||
. += "It is of a high quality."
|
||||
else
|
||||
if(food_quality <= 30)
|
||||
. += "It is of a low quality."
|
||||
|
||||
if(bitecount == 0)
|
||||
return
|
||||
else if(bitecount == 1)
|
||||
@@ -283,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
|
||||
@@ -296,6 +302,10 @@ All foods are distributed among various categories. Use common sense.
|
||||
var/obj/item/result
|
||||
if(cooked_type)
|
||||
result = new cooked_type(T)
|
||||
//if the result is food, set its food quality to the original food item's quality
|
||||
if(isfood(result))
|
||||
var/obj/item/reagent_containers/food/food_output = result
|
||||
food_output.adjust_food_quality(food_quality + M.quality_increase)
|
||||
if(istype(M))
|
||||
initialize_cooked_food(result, M.efficiency)
|
||||
else
|
||||
|
||||
@@ -197,6 +197,7 @@
|
||||
icon = 'icons/obj/food/food.dmi'
|
||||
icon_state = ""
|
||||
bitesize = 2
|
||||
var/fried_garbage = FALSE //did you really fry a fire extinguisher?
|
||||
|
||||
GLOBAL_VAR_INIT(frying_hardmode, TRUE)
|
||||
GLOBAL_VAR_INIT(frying_bad_chem_add_volume, TRUE)
|
||||
@@ -227,21 +228,13 @@ GLOBAL_LIST_INIT(frying_bad_chems, list(
|
||||
item_flags = fried.item_flags
|
||||
obj_flags = fried.obj_flags
|
||||
|
||||
if(istype(fried, /obj/item/reagent_containers/food/snacks))
|
||||
if(isfood(fried))
|
||||
fried.reagents.trans_to(src, fried.reagents.total_volume)
|
||||
qdel(fried)
|
||||
else
|
||||
fried.forceMove(src)
|
||||
trash = fried
|
||||
if(!istype(fried, /obj/item/reagent_containers/food) && GLOB.frying_hardmode && GLOB.frying_bad_chems.len)
|
||||
var/R = rand(1, GLOB.frying_bad_chems.len)
|
||||
var/bad_chem = GLOB.frying_bad_chems[R]
|
||||
var/bad_chem_amount = GLOB.frying_bad_chems[bad_chem]
|
||||
if(GLOB.frying_bad_chem_add_volume)
|
||||
reagents.maximum_volume += bad_chem_amount + 2 //Added room for condensed cooking oil
|
||||
reagents.add_reagent(bad_chem, bad_chem_amount)
|
||||
//All fried inedible items also get condensed cooking oil added, which induces minor vomiting and heart damage
|
||||
reagents.add_reagent(/datum/reagent/toxin/condensed_cooking_oil, 2)
|
||||
fried_garbage = TRUE
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/deepfryholder/Destroy()
|
||||
if(trash)
|
||||
@@ -249,6 +242,13 @@ GLOBAL_LIST_INIT(frying_bad_chems, list(
|
||||
. = ..()
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/deepfryholder/On_Consume(mob/living/eater)
|
||||
if(fried_garbage && GLOB.frying_hardmode && GLOB.frying_bad_chems.len)
|
||||
var/R = rand(1, GLOB.frying_bad_chems.len)
|
||||
var/bad_chem = GLOB.frying_bad_chems[R]
|
||||
var/bad_chem_amount = GLOB.frying_bad_chems[bad_chem]
|
||||
eater.reagents.add_reagent(bad_chem, bad_chem_amount)
|
||||
//All fried inedible items also get condensed cooking oil added, which induces minor vomiting and heart damage
|
||||
eater.reagents.add_reagent(/datum/reagent/toxin/condensed_cooking_oil, 2)
|
||||
if(trash)
|
||||
QDEL_NULL(trash)
|
||||
..()
|
||||
@@ -259,18 +259,22 @@ GLOBAL_LIST_INIT(frying_bad_chems, list(
|
||||
add_atom_colour(rgb(166,103,54), FIXED_COLOUR_PRIORITY)
|
||||
name = "lightly-fried [name]"
|
||||
desc = "[desc] It's been lightly fried in a deep fryer."
|
||||
adjust_food_quality(food_quality - 5)
|
||||
if(16 to 49)
|
||||
add_atom_colour(rgb(103,63,24), FIXED_COLOUR_PRIORITY)
|
||||
name = "fried [name]"
|
||||
desc = "[desc] It's been fried, increasing its tastiness value by [rand(1, 75)]%."
|
||||
adjust_food_quality(food_quality - 10)
|
||||
if(50 to 59)
|
||||
add_atom_colour(rgb(63,23,4), FIXED_COLOUR_PRIORITY)
|
||||
name = "deep-fried [name]"
|
||||
desc = "[desc] Deep-fried to perfection."
|
||||
adjust_food_quality(food_quality) //we shouldn't punish perfection in the fried arts
|
||||
if(60 to INFINITY)
|
||||
add_atom_colour(rgb(33,19,9), FIXED_COLOUR_PRIORITY)
|
||||
name = "the physical manifestation of the very concept of fried foods"
|
||||
desc = "A heavily-fried...something. Who can tell anymore?"
|
||||
adjust_food_quality(0) //good job, you're truly the best cook.
|
||||
filling_color = color
|
||||
foodtype |= FRIED
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -104,6 +104,12 @@ God bless America.
|
||||
else if(!frying && user.transferItemToLoc(I, src))
|
||||
to_chat(user, "<span class='notice'>You put [I] into [src].</span>")
|
||||
frying = new/obj/item/reagent_containers/food/snacks/deepfryholder(src, I)
|
||||
//setup food quality for item depending on if it's edible or not
|
||||
if(isfood(I))
|
||||
var/obj/item/reagent_containers/food/original_food = I
|
||||
frying.adjust_food_quality(original_food.food_quality) //food quality remains unchanged until degree of frying is calculated
|
||||
else
|
||||
frying.adjust_food_quality(10) //inedible fried item has low quality
|
||||
icon_state = "fryer_on"
|
||||
fry_loop.start()
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
var/gibtime = 40 // Time from starting until meat appears
|
||||
var/meat_produced = 0
|
||||
var/ignore_clothing = FALSE
|
||||
var/meat_quality = 35 //food_quality of meat produced
|
||||
|
||||
|
||||
/obj/machinery/gibber/Initialize()
|
||||
@@ -23,8 +24,10 @@
|
||||
/obj/machinery/gibber/RefreshParts()
|
||||
gibtime = 40
|
||||
meat_produced = 0
|
||||
meat_quality = 35 // unupgraded this means quality is 50, and max upgraded it is 95
|
||||
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
|
||||
meat_produced += B.rating
|
||||
meat_quality += B.rating * 15
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
gibtime -= 5 * M.rating
|
||||
if(M.rating >= 2)
|
||||
@@ -181,6 +184,7 @@
|
||||
|
||||
for (var/i=1 to meat_produced)
|
||||
var/obj/item/reagent_containers/food/snacks/meat/slab/newmeat = new typeofmeat
|
||||
newmeat.adjust_food_quality(meat_quality)
|
||||
newmeat.name = "[sourcename] [newmeat.name]"
|
||||
if(istype(newmeat))
|
||||
newmeat.subjectname = sourcename
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
var/broken = 0 // 0, 1 or 2 // How broken is it???
|
||||
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
|
||||
|
||||
@@ -43,11 +45,16 @@
|
||||
. = ..()
|
||||
|
||||
/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
|
||||
|
||||
/obj/machinery/microwave/examine(mob/user)
|
||||
@@ -83,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)
|
||||
@@ -240,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)
|
||||
@@ -285,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()
|
||||
|
||||
@@ -14,10 +14,13 @@
|
||||
var/processing = FALSE
|
||||
var/rating_speed = 1
|
||||
var/rating_amount = 1
|
||||
var/quality_increase = 5
|
||||
|
||||
/obj/machinery/processor/RefreshParts()
|
||||
quality_increase = 0
|
||||
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
|
||||
rating_amount = B.rating
|
||||
quality_increase += B.rating * 5
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
rating_speed = M.rating
|
||||
|
||||
@@ -28,8 +31,10 @@
|
||||
|
||||
/obj/machinery/processor/proc/process_food(datum/food_processor_process/recipe, atom/movable/what)
|
||||
if (recipe.output && loc && !QDELETED(src))
|
||||
var/obj/item/reagent_containers/food/food_input = what
|
||||
for(var/i = 0, i < rating_amount, i++)
|
||||
new recipe.output(drop_location())
|
||||
var/obj/item/reagent_containers/food/food_output = new recipe.output(drop_location())
|
||||
food_output.adjust_food_quality(food_input.food_quality + quality_increase)
|
||||
if (ismob(what))
|
||||
var/mob/themob = what
|
||||
themob.gib(TRUE,TRUE,TRUE)
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
parts |= reqs
|
||||
|
||||
//////////////////////////////////////////FOOD MIXTURES////////////////////////////////////
|
||||
|
||||
/datum/chemical_reaction/tofu
|
||||
name = "Tofu"
|
||||
id = "tofu"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -645,7 +645,7 @@
|
||||
attempt_resist_grab(FALSE)
|
||||
// Return as we should only resist one thing at a time. Give clickdelay if the grab wasn't passive.
|
||||
return old_gs? TRUE : FALSE
|
||||
|
||||
|
||||
// unbuckling yourself. stops the chain if you try it.
|
||||
if(buckled && last_special <= world.time)
|
||||
log_combat(src, buckled, "resisted buckle")
|
||||
@@ -668,19 +668,22 @@
|
||||
resist_fire() //stop, drop, and roll
|
||||
// Give clickdelay
|
||||
return TRUE
|
||||
|
||||
if(resting) //cit change - allows resisting out of resting
|
||||
resist_a_rest() // ditto
|
||||
// DO NOT GIVE CLCIKDELAY - resist_a_rest() handles spam prevention. Somewhat.
|
||||
return FALSE
|
||||
if(last_special <= world.time)
|
||||
resist_restraints() //trying to remove cuffs.
|
||||
// DO NOT GIVE CLICKDELAY - last_special handles this.
|
||||
return FALSE
|
||||
|
||||
if(CHECK_MOBILITY(src, MOBILITY_USE) && resist_embedded()) //Citadel Change for embedded removal memes - requires being able to use items.
|
||||
// DO NOT GIVE DEFAULT CLICKDELAY - This is a combat action.
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
return FALSE
|
||||
|
||||
if(last_special <= world.time)
|
||||
resist_restraints() //trying to remove cuffs.
|
||||
// DO NOT GIVE CLICKDELAY - last_special handles this.
|
||||
return FALSE
|
||||
|
||||
/// Proc to resist a grab. moving_resist is TRUE if this began by someone attempting to move. Return FALSE if still grabbed/failed to break out. Use this instead of resist_grab() directly.
|
||||
/mob/proc/attempt_resist_grab(moving_resist, forced, log = TRUE)
|
||||
if(!pulledby) //not being grabbed
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -557,13 +557,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++
|
||||
|
||||
@@ -35,8 +35,6 @@
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_fantastic)
|
||||
if (RACE_DRINK)
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/race_drink)
|
||||
if (FOOD_AMAZING)
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_food", /datum/mood_event/amazingtaste)
|
||||
return ..()
|
||||
|
||||
/datum/reagent/consumable/nutriment
|
||||
@@ -819,11 +817,20 @@
|
||||
nutriment_factor = 2 * REAGENTS_METABOLISM
|
||||
color = "#792300"
|
||||
taste_description = "indescribable"
|
||||
quality = FOOD_AMAZING
|
||||
taste_mult = 100
|
||||
can_synth = FALSE
|
||||
pH = 6.1
|
||||
|
||||
/datum/reagent/consumable/secretsauce/reaction_obj(obj/O, reac_volume)
|
||||
//splashing any amount above or equal to 1u of secret sauce onto a piece of food turns its quality to 100
|
||||
if(reac_volume >= 1 && isfood(O))
|
||||
var/obj/item/reagent_containers/food/splashed_food = O
|
||||
splashed_food.adjust_food_quality(100)
|
||||
// if it's a customisable food, we need to edit its total quality too, to prevent its quality resetting from adding more ingredients!
|
||||
if(istype(O, /obj/item/reagent_containers/food/snacks/customizable))
|
||||
var/obj/item/reagent_containers/food/snacks/customizable/splashed_custom_food = O
|
||||
splashed_custom_food.total_quality += 10000
|
||||
|
||||
/datum/reagent/consumable/char
|
||||
name = "Char"
|
||||
description = "Essence of the grill. Has strange properties when overdosed."
|
||||
|
||||
@@ -506,7 +506,7 @@
|
||||
taste_description = "awful cooking"
|
||||
|
||||
/datum/reagent/toxin/condensed_cooking_oil/on_mob_life(mob/living/carbon/M)
|
||||
if(prob(15))
|
||||
if(prob(5))
|
||||
M.vomit()
|
||||
else
|
||||
if(prob(40))
|
||||
|
||||
@@ -330,7 +330,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
|
||||
desc = "A conveyor control switch assembly."
|
||||
icon = 'icons/obj/recycling.dmi'
|
||||
icon_state = "switch-off"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/id = "" //inherited by the switch
|
||||
|
||||
/obj/item/conveyor_switch_construct/Initialize()
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
/obj/item/organ/liver/applyOrganDamage(d, maximum = maxHealth)
|
||||
. = ..()
|
||||
if(!.)
|
||||
if(!. || QDELETED(owner))
|
||||
return
|
||||
if(damage >= high_threshold)
|
||||
var/move_calc = 1+((round(damage) - high_threshold)/(high_threshold/3))
|
||||
|
||||
@@ -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."
|
||||
@@ -85,11 +78,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
|
||||
|
||||
@@ -151,6 +151,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
|
||||
|
||||
@@ -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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user