Merge remote-tracking branch 'citadel/master' into combat_patches_1

This commit is contained in:
silicons
2021-07-18 15:12:52 -07:00
159 changed files with 132112 additions and 130447 deletions
+1
View File
@@ -101,6 +101,7 @@
#define NO_AUTO_WAG (1<<12)
#define GENITAL_EXAMINE (1<<13)
#define VORE_EXAMINE (1<<14)
#define TRASH_FORCEFEED (1<<15)
#define TOGGLES_CITADEL 0
//belly sound pref things
-1
View File
@@ -81,7 +81,6 @@
#define CAT_AMMO "Ammunition"
#define CAT_PARTS "Weapon Parts"
#define CAT_ROBOT "Robots"
#define CAT_MISC "Misc"
#define CAT_MISCELLANEOUS "Miscellaneous"
#define CAT_TOOL "Tools & Storage"
#define CAT_FURNITURE "Furniture"
+12
View File
@@ -159,6 +159,18 @@
#define TINT_DARKENED 2 //Threshold of tint level to apply weld mask overlay
#define TINT_BLIND 3 //Threshold of tint level to obscure vision fully
// defines for AFK theft
/// How many messages you can remember while logged out before you stop remembering new ones
#define AFK_THEFT_MAX_MESSAGES 10
/// If someone logs back in and there are entries older than this, just tell them they can't remember who it was or when
#define AFK_THEFT_FORGET_DETAILS_TIME 5 MINUTES
/// The index of the entry in 'afk_thefts' with the person's visible name at the time
#define AFK_THEFT_NAME 1
/// The index of the entry in 'afk_thefts' with the text
#define AFK_THEFT_MESSAGE 2
/// The index of the entry in 'afk_thefts' with the time it happened
#define AFK_THEFT_TIME 3
//Allowed equipment lists for security vests and hardsuits.
GLOBAL_LIST_INIT(advanced_hardsuit_allowed, typecacheof(list(
+2
View File
@@ -4,6 +4,8 @@
#define NUM_E 2.71828183
#define SQRT_2 1.414214
#define PI 3.1416
#define INFINITY 1e31 //closer then enough
+1
View File
@@ -221,6 +221,7 @@
#define TRAIT_LIVING_NO_DENSITY "living_no_density"
/// forces us to not render our overlays
#define TRAIT_HUMAN_NO_RENDER "human_no_render"
#define TRAIT_TRASHCAN "trashcan"
// mobility flag traits
// IN THE FUTURE, IT WOULD BE NICE TO DO SOMETHING SIMILAR TO https://github.com/tgstation/tgstation/pull/48923/files (ofcourse not nearly the same because I have my.. thoughts on it)
+15 -10
View File
@@ -8,17 +8,22 @@
#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 DEVOURABLE (1<<1)
#define FEEDING (1<<2)
#define NO_VORE (1<<3)
#define ABSORBED (1<<4)
#define VORE_INIT (1<<5)
#define VOREPREF_INIT (1<<6)
#define LICKABLE (1<<7)
/// Can be smelled?
#define SMELLABLE (1<<8)
/// Can get absorbed?
#define ABSORBABLE (1<<9)
/// Can get simplemob vored?
#define MOBVORE (1<<10)
#define MAX_VORE_FLAG (1<<10)-1 // change this whenever you add a vore flag, must be largest vore flag*2-1
/// Change this whenever you add a vore flag, must be largest vore flag*2-1
#define MAX_VORE_FLAG (1<<11)-1
#define isbelly(A) istype(A, /obj/belly)
+2
View File
@@ -19,6 +19,8 @@
#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= length(L) ? L[I] : null) : L[I]) : null)
#define LAZYSET(L, K, V) if(!L) { L = list(); } L[K] = V;
#define LAZYLEN(L) length(L)
//Sets a list to null
#define LAZYNULL(L) L = null
#define LAZYCLEARLIST(L) if(L) L.Cut()
#define SANITIZE_LIST(L) ( islist(L) ? L : list() )
#define reverseList(L) reverseRange(L.Copy())
+1 -1
View File
@@ -75,7 +75,7 @@
while(timeleft > 0)
stoplag(1)
var/timepassed = world.time - tick_time
timepassed = world.time
tick_time = world.time
progbar?.update(TIMELEFT)
if(QDELETED(user) || QDELETED(target) || (user.loc == null) || (target.loc == null))
. = FALSE
@@ -112,6 +112,7 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
/obj/item/storage/box/marshmallow = 2,
/obj/item/clothing/gloves/tackler/offbrand = 1,
/obj/item/stack/sticky_tape = 1,
/obj/effect/spawner/lootdrop/grille_or_trash = 15,
"" = 3
))
-37
View File
@@ -1,37 +0,0 @@
SUBSYSTEM_DEF(acid)
name = "Acid"
priority = FIRE_PRIORITY_ACID
flags = SS_NO_INIT|SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/list/currentrun = list()
var/list/processing = list()
/datum/controller/subsystem/acid/stat_entry(msg)
msg = "P:[length(processing)]"
return ..()
/datum/controller/subsystem/acid/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
while (currentrun.len)
var/obj/O = currentrun[currentrun.len]
currentrun.len--
if (!O || QDELETED(O))
processing -= O
if (MC_TICK_CHECK)
return
continue
if(O.acid_level && O.acid_processing())
else
O.update_icon()
processing -= O
if (MC_TICK_CHECK)
return
+2 -2
View File
@@ -1,5 +1,5 @@
PROCESSING_SUBSYSTEM_DEF(fluids)
name = "Fluids"
wait = 20
wait = 10
stat_tag = "FD" //its actually Fluid Ducts
flags = SS_NO_INIT | SS_TICKER
flags = SS_NO_INIT
+1
View File
@@ -42,6 +42,7 @@ SUBSYSTEM_DEF(nightshift)
update_nightshift(night_time, announcing)
/datum/controller/subsystem/nightshift/proc/update_nightshift(active, announce = TRUE, max_level_override)
set waitfor = FALSE
nightshift_active = active
if(announce)
if (active)
@@ -47,5 +47,5 @@ SUBSYSTEM_DEF(processing)
* If you override this do not call parent, as it will return PROCESS_KILL. This is done to prevent objects that dont override process() from staying in the processing list
*/
/datum/proc/process(delta_time)
// SHOULD_NOT_SLEEP(TRUE)
SHOULD_NOT_SLEEP(TRUE)
return PROCESS_KILL
+65
View File
@@ -0,0 +1,65 @@
/datum/component/acid
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
var/level = 0
/datum/component/acid/Initialize(acidpwr, acid_volume)
if(!isobj(parent))
return COMPONENT_INCOMPATIBLE
var/obj/O = parent
var/acid_cap = acidpwr * 300
level = min(acidpwr * acid_volume, acid_cap)
START_PROCESSING(SSprocessing, src)
RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/add_acid_overlay)
if(isitem(parent))
RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand)
O.update_icon()
/datum/component/acid/proc/on_attack_hand(datum/source, mob/user)
var/obj/item/I = parent
if(istype(I) && level > 20 && !ismob(I.loc))// so we can still remove the clothes on us that have acid.
var/mob/living/carbon/C = user
if(istype(C))
if(!C.gloves || (!(C.gloves.resistance_flags & (UNACIDABLE|ACID_PROOF))))
to_chat(user, "<span class='warning'>The acid on [I] burns your hand!</span>")
var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm")
if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage
C.update_damage_overlays()
/datum/component/acid/InheritComponent(datum/component/C, i_am_original, acidpwr, acid_volume)
if(!i_am_original)
return
var/acid_cap = acidpwr * 300
if(level < acid_cap)
if(C)
var/datum/component/acid/other = C
level = min(level + other.level, acid_cap)
else
level = min(level + acidpwr * acid_volume, acid_cap)
/datum/component/acid/Destroy()
STOP_PROCESSING(SSprocessing, src)
var/obj/O = parent
level = 0
O.update_overlays()
return ..()
/datum/component/acid/process()
var/obj/O = parent
if(!istype(O))
qdel(src)
return PROCESS_KILL
if(!(O.resistance_flags & ACID_PROOF))
if(prob(33))
playsound(O.loc, 'sound/items/welder.ogg', 150, 1)
O.take_damage(min(1 + round(sqrt(level)*0.3), 300), BURN, "acid", 0)
level = max(level - (5 + 3*round(sqrt(level))), 0)
if(level <= 0)
qdel(src)
return PROCESS_KILL
else
O.update_icon()
return TRUE
/datum/component/acid/proc/add_acid_overlay(atom/source, list/overlay_list)
overlay_list += GLOB.acid_overlay
+1 -1
View File
@@ -16,7 +16,7 @@
RegisterSignal(L, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_ATTACK_RANGED, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_THROW, COMSIG_MOVABLE_TELEPORTED, COMSIG_LIVING_GUN_PROCESS_FIRE, COMSIG_MOB_APPLY_DAMAGE), .proc/minor_activity)
/datum/component/activity/proc/log_activity()
historical_activity_levels[world.time] = activity_level
historical_activity_levels["[world.time]"] = activity_level
/datum/component/activity/proc/minor_activity(datum/source)
activity_level += 1
-491
View File
@@ -1,491 +0,0 @@
/datum/component/personal_crafting/Initialize()
if(!ismob(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(parent, COMSIG_MOB_CLIENT_LOGIN, .proc/create_mob_button)
/datum/component/personal_crafting/proc/create_mob_button(mob/user, client/CL)
var/datum/hud/H = user.hud_used
var/obj/screen/craft/C = new()
C.icon = H.ui_style
H.static_inventory += C
if(!CL.prefs.widescreenpref)
C.screen_loc = ui_boxcraft
CL.screen += C
RegisterSignal(C, COMSIG_CLICK, .proc/component_ui_interact)
/datum/component/personal_crafting
var/busy
var/viewing_category = 1
var/viewing_subcategory = 1
var/list/categories = list(
CAT_WEAPONRY = list(
CAT_WEAPON,
CAT_AMMO,
),
CAT_ROBOT = CAT_NONE,
CAT_MISC = list(
CAT_MISCELLANEOUS,
CAT_TOOL,
CAT_FURNITURE,
),
CAT_PRIMAL = CAT_NONE,
CAT_FOOD = list(
CAT_BREAD,
CAT_BURGER,
CAT_CAKE,
CAT_DONUT,
CAT_EGG,
CAT_ICE,
CAT_MEAT,
CAT_MEXICAN,
CAT_MISCFOOD,
CAT_PASTRY,
CAT_PIE,
CAT_PIZZA,
CAT_SEAFOOD,
CAT_SALAD,
CAT_SANDWICH,
CAT_SOUP,
CAT_SPAGHETTI,
),
CAT_DRINK = CAT_NONE,
CAT_CLOTHING = CAT_NONE,
)
var/cur_category = CAT_NONE
var/cur_subcategory = CAT_NONE
var/datum/action/innate/crafting/button
var/display_craftable_only = FALSE
var/display_compact = TRUE
/* This is what procs do:
get_environment - gets a list of things accessable for crafting by user
get_surroundings - takes a list of things and makes a list of key-types to values-amounts of said type in the list
check_contents - takes a recipe and a key-type list and checks if said recipe can be done with available stuff
check_tools - takes recipe, a key-type list, and a user and checks if there are enough tools to do the stuff, checks bugs one level deep
construct_item - takes a recipe and a user, call all the checking procs, calls do_after, checks all the things again, calls del_reqs, creates result, calls CheckParts of said result with argument being list returned by deel_reqs
del_reqs - takes recipe and a user, loops over the recipes reqs var and tries to find everything in the list make by get_environment and delete it/add to parts list, then returns the said list
*/
/**
* Check that the contents of the recipe meet the requirements.
*
* user: The /mob that initated the crafting.
* R: The /datum/crafting_recipe being attempted.
* contents: List of items to search for R's reqs.
*/
/datum/component/personal_crafting/proc/check_contents(mob/user, datum/crafting_recipe/R, list/contents)
var/list/item_instances = contents["instances"]
contents = contents["other"]
var/list/requirements_list = list()
// Process all requirements
for(var/requirement_path in R.reqs)
// Check we have the appropriate amount available in the contents list
var/needed_amount = R.reqs[requirement_path]
for(var/content_item_path in contents)
// Right path and not blacklisted
if(!ispath(content_item_path, requirement_path) || R.blacklist.Find(requirement_path))
continue
needed_amount -= contents[content_item_path]
if(needed_amount <= 0)
break
if(needed_amount > 0)
return FALSE
// Store the instances of what we will use for R.check_requirements() for requirement_path
var/list/instances_list = list()
for(var/instance_path in item_instances)
if(ispath(instance_path, requirement_path))
instances_list += item_instances[instance_path]
requirements_list[requirement_path] = instances_list
for(var/requirement_path in R.chem_catalysts)
if(contents[requirement_path] < R.chem_catalysts[requirement_path])
return FALSE
return R.check_requirements(user, requirements_list)
/datum/component/personal_crafting/proc/get_environment(mob/user)
. = list()
for(var/obj/item/I in user.held_items)
. += I
if(!isturf(user.loc))
return
var/list/L = block(get_step(user, SOUTHWEST), get_step(user, NORTHEAST))
for(var/A in L)
var/turf/T = A
if(T.Adjacent(user))
for(var/B in T)
var/atom/movable/AM = B
if(AM.flags_1 & HOLOGRAM_1)
continue
. += AM
for(var/slot in list(SLOT_R_STORE, SLOT_L_STORE))
. += user.get_item_by_slot(slot)
/datum/component/personal_crafting/proc/get_surroundings(mob/user)
. = list()
.["tool_behaviour"] = list()
.["other"] = list()
.["instances"] = list()
for(var/obj/item/I in get_environment(user))
if(I.flags_1 & HOLOGRAM_1)
continue
if(.["instances"][I.type])
.["instances"][I.type] += I
else
.["instances"][I.type] = list(I)
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I
.["other"][I.type] += S.amount
else if(I.tool_behaviour)
.["tool_behaviour"] += I.tool_behaviour
.["other"][I.type] += 1
else
if(istype(I, /obj/item/reagent_containers))
var/obj/item/reagent_containers/RC = I
if(RC.is_drainable())
for(var/datum/reagent/A in RC.reagents.reagent_list)
.["other"][A.type] += A.volume
.["other"][I.type] += 1
/datum/component/personal_crafting/proc/check_tools(mob/user, datum/crafting_recipe/R, list/contents)
if(!R.tools.len)
return TRUE
var/list/possible_tools = list()
var/list/present_qualities = list()
present_qualities |= contents["tool_behaviour"]
for(var/obj/item/I in user.contents)
if(istype(I, /obj/item/storage))
for(var/obj/item/SI in I.contents)
possible_tools += SI.type
if(SI.tool_behaviour)
present_qualities.Add(SI.tool_behaviour)
possible_tools += I.type
if(I.tool_behaviour)
present_qualities.Add(I.tool_behaviour)
possible_tools |= contents["other"]
main_loop:
for(var/A in R.tools)
if(A in present_qualities)
continue
else
for(var/I in possible_tools)
if(ispath(I, A))
continue main_loop
return FALSE
return TRUE
/datum/component/personal_crafting/proc/construct_item(mob/user, datum/crafting_recipe/R)
var/list/contents = get_surroundings(user)
var/send_feedback = TRUE
if(check_contents(user, R, contents))
if(check_tools(user, R, contents))
if(do_after(user, R.time, target = user))
contents = get_surroundings(user)
if(!check_contents(user, R, contents))
return ", missing component."
if(!check_tools(user, R, contents))
return ", missing tool."
var/list/parts = del_reqs(R, user)
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/reagent_containers/food/ingredient in parts)
total_items += 1
total_quality += 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)
log_craft("[I] crafted by [user] at [loc_name(I.loc)]")
return FALSE
return "."
return ", missing tool."
return ", missing component."
/*Del reqs works like this:
Loop over reqs var of the recipe
Set var amt to the value current cycle req is pointing to, its amount of type we need to delete
Get var/surroundings list of things accessable to crafting by get_environment()
Check the type of the current cycle req
If its reagent then do a while loop, inside it try to locate() reagent containers, inside such containers try to locate needed reagent, if there isnt remove thing from surroundings
If there is enough reagent in the search result then delete the needed amount, create the same type of reagent with the same data var and put it into deletion list
If there isnt enough take all of that reagent from the container, put into deletion list, substract the amt var by the volume of reagent, remove the container from surroundings list and keep searching
While doing above stuff check deletion list if it already has such reagnet, if yes merge instead of adding second one
If its stack check if it has enough amount
If yes create new stack with the needed amount and put in into deletion list, substract taken amount from the stack
If no put all of the stack in the deletion list, substract its amount from amt and keep searching
While doing above stuff check deletion list if it already has such stack type, if yes try to merge them instead of adding new one
If its anything else just locate() in in the list in a while loop, each find --s the amt var and puts the found stuff in deletion loop
Then do a loop over parts var of the recipe
Do similar stuff to what we have done above, but now in deletion list, until the parts conditions are satisfied keep taking from the deletion list and putting it into parts list for return
After its done loop over deletion list and delete all the shit that wasnt taken by parts loop
del_reqs return the list of parts resulting object will receive as argument of CheckParts proc, on the atom level it will add them all to the contents, on all other levels it calls ..() and does whatever is needed afterwards but from contents list already
*/
/datum/component/personal_crafting/proc/del_reqs(datum/crafting_recipe/R, mob/user)
var/list/surroundings
var/list/Deletion = list()
. = list()
var/data
var/amt
main_loop:
for(var/A in R.reqs)
amt = R.reqs[A]
surroundings = get_environment(user)
surroundings -= Deletion
if(ispath(A, /datum/reagent))
var/datum/reagent/RG = new A
var/datum/reagent/RGNT
while(amt > 0)
var/obj/item/reagent_containers/RC = locate() in surroundings
RG = RC.reagents.get_reagent(A)
if(RG)
if(!locate(RG.type) in Deletion)
Deletion += new RG.type()
if(RG.volume > amt)
RG.volume -= amt
data = RG.data
RC.reagents.conditional_update(RC)
RG = locate(RG.type) in Deletion
RG.volume = amt
RG.data += data
continue main_loop
else
surroundings -= RC
amt -= RG.volume
RC.reagents.reagent_list -= RG
RC.reagents.conditional_update(RC)
RGNT = locate(RG.type) in Deletion
RGNT.volume += RG.volume
RGNT.data += RG.data
qdel(RG)
RC.on_reagent_change()
else
surroundings -= RC
else if(ispath(A, /obj/item/stack))
var/obj/item/stack/S
var/obj/item/stack/SD
while(amt > 0)
S = locate(A) in surroundings
if(S.amount >= amt)
if(!locate(S.type) in Deletion)
SD = new S.type()
Deletion += SD
S.use(amt)
SD = locate(S.type) in Deletion
SD.amount += amt
continue main_loop
else
amt -= S.amount
if(!locate(S.type) in Deletion)
Deletion += S
else
data = S.amount
S = locate(S.type) in Deletion
S.add(data)
surroundings -= S
else
var/atom/movable/I
while(amt > 0)
I = locate(A) in surroundings
Deletion += I
surroundings -= I
amt--
var/list/partlist = list(R.parts.len)
for(var/M in R.parts)
partlist[M] = R.parts[M]
for(var/A in R.parts)
if(istype(A, /datum/reagent))
var/datum/reagent/RG = locate(A) in Deletion
if(RG.volume > partlist[A])
RG.volume = partlist[A]
. += RG
Deletion -= RG
continue
else if(istype(A, /obj/item/stack))
var/obj/item/stack/ST = locate(A) in Deletion
if(ST.amount > partlist[A])
ST.amount = partlist[A]
. += ST
Deletion -= ST
continue
else
while(partlist[A] > 0)
var/atom/movable/AM = locate(A) in Deletion
. += AM
Deletion -= AM
partlist[A] -= 1
while(Deletion.len)
var/DL = Deletion[Deletion.len]
Deletion.Cut(Deletion.len)
qdel(DL)
/datum/component/personal_crafting/proc/component_ui_interact(obj/screen/craft/image, location, control, params, user)
if(user == parent)
ui_interact(user)
/datum/component/personal_crafting/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.not_incapacitated_turf_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
cur_category = categories[1]
if(islist(categories[cur_category]))
var/list/subcats = categories[cur_category]
cur_subcategory = subcats[1]
else
cur_subcategory = CAT_NONE
ui = new(user, src, ui_key, "personal_crafting", "Crafting Menu", 700, 800, master_ui, state)
ui.open()
/datum/component/personal_crafting/ui_data(mob/user)
var/list/data = list()
data["busy"] = busy
data["category"] = cur_category
data["subcategory"] = cur_subcategory
data["display_craftable_only"] = display_craftable_only
data["display_compact"] = display_compact
var/list/surroundings = get_surroundings(user)
var/list/craftability = list()
for(var/rec in GLOB.crafting_recipes)
var/datum/crafting_recipe/R = rec
if(!R.always_availible && !(R.type in user?.mind?.learned_recipes)) //User doesn't actually know how to make this.
continue
if((R.category != cur_category) || (R.subcategory != cur_subcategory))
continue
craftability["[REF(R)]"] = check_contents(user, R, surroundings)
data["craftability"] = craftability
return data
/datum/component/personal_crafting/ui_static_data(mob/user)
var/list/data = list()
var/list/crafting_recipes = list()
for(var/rec in GLOB.crafting_recipes)
var/datum/crafting_recipe/R = rec
if(R.name == "") //This is one of the invalid parents that sneaks in
continue
if(!R.always_availible && !(R.type in user?.mind?.learned_recipes)) //User doesn't actually know how to make this.
continue
if(isnull(crafting_recipes[R.category]))
crafting_recipes[R.category] = list()
if(R.subcategory == CAT_NONE)
crafting_recipes[R.category] += list(build_recipe_data(R))
else
if(isnull(crafting_recipes[R.category][R.subcategory]))
crafting_recipes[R.category][R.subcategory] = list()
crafting_recipes[R.category]["has_subcats"] = TRUE
crafting_recipes[R.category][R.subcategory] += list(build_recipe_data(R))
data["crafting_recipes"] = crafting_recipes
return data
/datum/component/personal_crafting/ui_act(action, params)
if(..())
return
switch(action)
if("make")
var/datum/crafting_recipe/TR = locate(params["recipe"]) in GLOB.crafting_recipes
ui_interact(usr)
if(busy)
to_chat(usr, "<span class='warning'>You are already making something!</span>")
return
busy = TRUE
var/fail_msg = construct_item(usr, TR)
if(!fail_msg)
to_chat(usr, "<span class='notice'>[TR.name] constructed.</span>")
else
to_chat(usr, "<span class='warning'>Construction failed[fail_msg]</span>")
busy = FALSE
if("toggle_recipes")
display_craftable_only = !display_craftable_only
. = TRUE
if("toggle_compact")
display_compact = !display_compact
. = TRUE
if("set_category")
if(!isnull(params["category"]))
cur_category = params["category"]
if(!isnull(params["subcategory"]))
if(params["subcategory"] == "0")
cur_subcategory = ""
else
cur_subcategory = params["subcategory"]
. = TRUE
/datum/component/personal_crafting/proc/build_recipe_data(datum/crafting_recipe/R)
var/list/data = list()
data["name"] = R.name
data["ref"] = "[REF(R)]"
var/req_text = ""
var/tool_text = ""
var/catalyst_text = ""
for(var/a in R.reqs)
//We just need the name, so cheat-typecast to /atom for speed (even tho Reagents are /datum they DO have a "name" var)
//Also these are typepaths so sadly we can't just do "[a]"
var/atom/A = a
req_text += " [R.reqs[A]] [initial(A.name)],"
req_text = replacetext(req_text,",","",-1)
data["req_text"] = req_text
for(var/a in R.chem_catalysts)
var/atom/A = a //cheat-typecast
catalyst_text += " [R.chem_catalysts[A]] [initial(A.name)],"
catalyst_text = replacetext(catalyst_text,",","",-1)
data["catalyst_text"] = catalyst_text
for(var/a in R.tools)
if(ispath(a, /obj/item))
var/obj/item/b = a
tool_text += " [initial(b.name)],"
else
tool_text += " [a],"
tool_text = replacetext(tool_text,",","",-1)
data["tool_text"] = tool_text
return data
//Mind helpers
/datum/mind/proc/teach_crafting_recipe(R)
if(!learned_recipes)
learned_recipes = list()
learned_recipes |= R
+5 -1
View File
@@ -4,6 +4,10 @@
/datum/component/personal_crafting/proc/create_mob_button(mob/user, client/CL)
var/datum/hud/H = user.hud_used
for(var/huds in H.static_inventory)
if(istype(huds, /obj/screen/craft))
return
//We don't want to be stacking multiple crafting huds on relogs
var/obj/screen/craft/C = new()
C.icon = H.ui_style
H.static_inventory += C
@@ -20,7 +24,7 @@
CAT_AMMO,
),
CAT_ROBOT = CAT_NONE,
CAT_MISC = list(
CAT_MISCELLANEOUS = list(
CAT_MISCELLANEOUS,
CAT_TOOL,
CAT_FURNITURE,
@@ -8,7 +8,7 @@
time = 1
reqs = list(/obj/item/stack/sheet/plastic = 1,
/obj/item/stack/sheet/mineral/wood = 1)
category = CAT_MISC
category = CAT_MISCELLANEOUS
subcategory = CAT_TOOL
/datum/crafting_recipe/showercurtain
@@ -18,7 +18,7 @@
/obj/item/stack/rods = 1)
result = /obj/structure/curtain
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/guillotine
name = "Guillotine"
@@ -29,7 +29,7 @@
/obj/item/stack/cable_coil = 10)
tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/femur_breaker
name = "Femur Breaker"
@@ -39,7 +39,7 @@
/obj/item/stack/cable_coil = 30)
tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
// Blood Sucker stuff //
/datum/crafting_recipe/bloodsucker/blackcoffin
@@ -54,7 +54,7 @@
///obj/item/pipe = 2)
time = 150
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
always_availible = TRUE
/datum/crafting_recipe/bloodsucker/meatcoffin
@@ -66,7 +66,7 @@
/obj/item/restraints/handcuffs/cable = 1)
time = 150
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
always_availible = TRUE
/datum/crafting_recipe/bloodsucker/metalcoffin
@@ -77,7 +77,7 @@
reqs = list(/obj/item/stack/sheet/metal = 5)
time = 100
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
always_availible = TRUE
/datum/crafting_recipe/bloodsucker/vassalrack
@@ -100,7 +100,7 @@
// )
time = 150
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
always_availible = FALSE // Disabled until learned
@@ -117,7 +117,7 @@
)
time = 100
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
always_availible = FALSE // Disabled til learned
/datum/crafting_recipe/furnace
@@ -129,7 +129,7 @@
/obj/item/stack/rods = 2)
tools = list(TOOL_CROWBAR)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/tableanvil
name = "Table Anvil"
@@ -139,7 +139,7 @@
/obj/item/stack/rods = 2)
tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/sandvil
name = "Sandstone Anvil"
@@ -148,7 +148,7 @@
reqs = list(/obj/item/stack/sheet/mineral/sandstone = 24)
tools = list(TOOL_CROWBAR)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/basaltblock
name = "Sintered Basalt Block"
@@ -157,7 +157,7 @@
reqs = list(/obj/item/stack/ore/glass/basalt = 50)
tools = list(TOOL_WELDER)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/basaltanvil
name = "Basalt Anvil"
@@ -166,7 +166,7 @@
reqs = list(/obj/item/basaltblock = 5)
tools = list(TOOL_CROWBAR)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
///////////////////
//Tools & Storage//
///////////////////
@@ -177,7 +177,7 @@
time = 1
reqs = list(/obj/item/stack/medical/gauze = 1,
/datum/reagent/space_cleaner/sterilizine = 5)
category = CAT_MISC
category = CAT_MISCELLANEOUS
subcategory = CAT_TOOL
/datum/crafting_recipe/brute_pack
@@ -186,7 +186,7 @@
time = 1
reqs = list(/obj/item/stack/medical/gauze/adv = 1,
/datum/reagent/medicine/styptic_powder = 10)
category = CAT_MISC
category = CAT_MISCELLANEOUS
subcategory = CAT_TOOL
/datum/crafting_recipe/burn_pack
@@ -195,7 +195,7 @@
time = 1
reqs = list(/obj/item/stack/medical/gauze/adv = 1,
/datum/reagent/medicine/silver_sulfadiazine = 10)
category = CAT_MISC
category = CAT_MISCELLANEOUS
subcategory = CAT_TOOL
/datum/crafting_recipe/ghettojetpack
@@ -206,7 +206,7 @@
/obj/item/extinguisher = 1,
/obj/item/pipe = 3,
/obj/item/stack/cable_coil = 30)
category = CAT_MISC
category = CAT_MISCELLANEOUS
subcategory = CAT_TOOL
tools = list(TOOL_WRENCH, TOOL_WELDER, TOOL_WIRECUTTER)
@@ -220,7 +220,7 @@
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/toolboxhammer
name = "Toolbox Hammer"
@@ -231,7 +231,7 @@
/obj/item/stack/rods = 2)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/papersack
name = "Paper Sack"
@@ -239,7 +239,7 @@
time = 10
reqs = list(/obj/item/paper = 5)
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/smallcarton
name = "Small Carton"
@@ -247,7 +247,7 @@
time = 10
reqs = list(/obj/item/stack/sheet/cardboard = 1)
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/bronze_driver
name = "Bronze Plated Screwdriver"
@@ -259,7 +259,7 @@
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/bronze_welder
name = "Bronze Plated Welding Tool"
@@ -271,7 +271,7 @@
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/bronze_wirecutters
name = "Bronze Plated Wirecutters"
@@ -283,7 +283,7 @@
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/bronze_crowbar
name = "Bronze Plated Crowbar"
@@ -295,7 +295,7 @@
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/bronze_wrench
name = "Bronze Plated Wrench"
@@ -307,7 +307,7 @@
/datum/reagent/water = 15)
time = 40
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/rcl
name = "Makeshift Rapid Cable Layer"
@@ -316,7 +316,7 @@
tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
reqs = list(/obj/item/stack/sheet/metal = 15)
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/picket_sign
name = "Picket Sign"
@@ -325,7 +325,7 @@
/obj/item/stack/sheet/cardboard = 2)
time = 80
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/electrochromatic_kit
name = "Electrochromatic Kit"
@@ -334,7 +334,7 @@
/obj/item/stack/cable_coil = 1)
time = 5
subcategory = CAT_TOOL
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/blackmarket_uplink
name = "Black Market Uplink"
@@ -346,7 +346,7 @@
/obj/item/radio = 1,
/obj/item/analyzer = 1)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/heretic/codex
name = "Codex Cicatrix"
@@ -358,7 +358,7 @@
/obj/item/stack/sheet/animalhide/human = 1)
time = 150
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
always_availible = FALSE
////////////
@@ -372,7 +372,21 @@
/obj/item/stack/rods = 8)
time = 100
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/motorized_wheelchair
name = "Hoverchair"
result = /obj/vehicle/ridden/wheelchair/motorized
reqs = list(/obj/item/stack/sheet/plasteel = 10,
/obj/item/stack/rods = 8,
/obj/item/stock_parts/manipulator = 2,
/obj/item/stock_parts/capacitor = 1)
parts = list(/obj/item/stock_parts/manipulator = 2,
/obj/item/stock_parts/capacitor = 1)
tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
time = 200
subcategory = CAT_MISCELLANEOUS
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/skateboard
name = "Skateboard"
@@ -381,7 +395,7 @@
reqs = list(/obj/item/stack/sheet/metal = 5,
/obj/item/stack/rods = 10)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/scooter
name = "Scooter"
@@ -390,7 +404,7 @@
reqs = list(/obj/item/stack/sheet/metal = 5,
/obj/item/stack/rods = 12)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/////////
//Toys///
@@ -401,28 +415,28 @@
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
category = CAT_MISCELLANEOUS
/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
category = CAT_MISCELLANEOUS
/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
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/catgirlplushie
name = "Catgirl Plushie"
reqs = list(/obj/item/toy/plush/hairball = 3)
result = /obj/item/toy/plush/catgirl
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
////////////
//Unsorted//
@@ -436,7 +450,7 @@
reqs = list(/obj/item/stack/sheet/mineral/wood = 1)
result = /obj/item/stick
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/swordhilt
@@ -445,14 +459,14 @@
reqs = list(/obj/item/stack/sheet/mineral/wood = 2)
result = /obj/item/swordhandle
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/blackcarpet
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
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/paperframes
name = "Paper Frames"
@@ -460,7 +474,7 @@
time = 10
reqs = list(/obj/item/stack/sheet/mineral/wood = 5, /obj/item/paper = 20)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/naturalpaper
name = "Hand-Pressed Paper"
@@ -469,7 +483,7 @@
tools = list(/obj/item/hatchet)
result = /obj/item/paper_bin/bundlenatural
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/bluespacehonker
name = "Bluespace Bike horn"
@@ -479,7 +493,7 @@
/obj/item/toy/crayon/blue = 1,
/obj/item/bikehorn = 1)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/mousetrap
name = "Mouse Trap"
@@ -488,7 +502,7 @@
reqs = list(/obj/item/stack/sheet/cardboard = 1,
/obj/item/stack/rods = 1)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/flashlight_eyes
name = "Flashlight Eyes"
@@ -499,7 +513,7 @@
/obj/item/restraints/handcuffs/cable = 1
)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/pressureplate
name = "Pressure Plate"
@@ -510,7 +524,7 @@
/obj/item/stack/cable_coil = 2,
/obj/item/assembly/igniter = 1)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/gold_horn
name = "Golden Bike Horn"
@@ -519,7 +533,7 @@
reqs = list(/obj/item/stack/sheet/mineral/bananium = 5,
/obj/item/bikehorn = 1)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/spooky_camera
name = "Camera Obscura"
@@ -529,7 +543,7 @@
/datum/reagent/water/holywater = 10)
parts = list(/obj/item/camera = 1)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/coconut_bong
name = "Coconut Bong"
@@ -538,7 +552,7 @@
/obj/item/reagent_containers/food/snacks/grown/coconut = 1)
time = 70
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
category = CAT_MISCELLANEOUS
//////////////
//Banners/////
@@ -551,7 +565,7 @@
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/captain/parade = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/engineering_banner
name = "Engitopia Banner"
@@ -560,7 +574,7 @@
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/engineering/engineer = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/cargo_banner
name = "Cargonia Banner"
@@ -569,7 +583,7 @@
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/cargo/tech = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/science_banner
name = "Sciencia Banner"
@@ -578,7 +592,7 @@
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/rnd/scientist = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/medical_banner
name = "Meditopia Banner"
@@ -587,7 +601,7 @@
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/medical/doctor = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/security_banner
name = "Securistan Banner"
@@ -596,4 +610,4 @@
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/security/officer = 1)
subcategory = CAT_FURNITURE
category = CAT_MISC
category = CAT_MISCELLANEOUS
@@ -72,6 +72,16 @@
category = CAT_WEAPONRY
subcategory = CAT_MELEE
/datum/crafting_recipe/newsbaton
name = "Newspaper Baton"
result = /obj/item/melee/classic_baton/telescopic/newspaper
reqs = list(/obj/item/melee/classic_baton/telescopic = 1,
/obj/item/newspaper = 1,
/obj/item/stack/sticky_tape = 2)
time = 40
category = CAT_WEAPONRY
subcategory = CAT_MELEE
/datum/crafting_recipe/bokken
name = "Training Bokken"
result = /obj/item/melee/bokken
+1
View File
@@ -265,6 +265,7 @@
/// Items embedded/stuck to carbons both check whether they randomly fall out (if applicable), as well as if the target mob and limb still exists.
/// Items harmfully embedded in carbons have an additional check for random pain (if applicable)
/datum/component/embedded/proc/processCarbon()
set waitfor = FALSE
var/mob/living/carbon/victim = parent
if(!victim || !limb) // in case the victim and/or their limbs exploded (say, due to a sticky bomb)
+1
View File
@@ -158,6 +158,7 @@
autolock()
/datum/component/lockon_aiming/proc/autolock()
set waitfor = FALSE
var/mob/M = parent
if(!M.client)
return FALSE
+1 -1
View File
@@ -405,7 +405,7 @@
/mob/living/carbon/human/proc/hardset_dna(ui, list/mutation_index, newreal_name, newblood_type, datum/species/mrace, newfeatures, list/default_mutation_genes)
set waitfor = FALSE
if(newreal_name)
real_name = newreal_name
dna.generate_unique_enzymes()
+5 -1
View File
@@ -24,7 +24,8 @@
else
user_by_item -= source
/datum/element/earhealing/process()
/datum/element/earhealing/proc/do_process()
set waitfor = FALSE
for(var/i in user_by_item)
var/mob/living/carbon/user = user_by_item[i]
if(HAS_TRAIT(user, TRAIT_DEAF))
@@ -35,3 +36,6 @@
ears.deaf = max(ears.deaf - 0.25, (ears.damage < ears.maxHealth ? 0 : 1)) // Do not clear deafness if our ears are too damaged
ears.damage = max(ears.damage - 0.025, 0)
CHECK_TICK
/datum/element/earhealing/process()
do_process()
+1 -1
View File
@@ -59,7 +59,7 @@
var/mob/living/L = AM
if(L.stat == DEAD)
continue
if(light_nutrition_gain)
if(light_nutrition_gain && L.nutrition < NUTRITION_LEVEL_WELL_FED)
L.adjust_nutrition(light_amount * light_nutrition_gain * attached_atoms[AM], NUTRITION_LEVEL_WELL_FED)
if(light_amount > bonus_lum || light_amount < malus_lum)
var/mult = ((light_amount > bonus_lum) ? 1 : -1) * attached_atoms[AM]
+19
View File
@@ -0,0 +1,19 @@
/datum/element/trash
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
/datum/element/trash/Attach(datum/target)
. = ..()
RegisterSignal(target, COMSIG_ITEM_ATTACK, .proc/UseFromHand)
/datum/element/trash/proc/UseFromHand(obj/item/source, mob/living/M, mob/living/user)
if((M == user || user.vore_flags & TRASH_FORCEFEED) && ishuman(user))
var/mob/living/carbon/human/H = user
if(HAS_TRAIT(H, TRAIT_TRASHCAN))
playsound(H.loc,'sound/items/eatfood.ogg', rand(10,50), 1)
if(H.vore_selected)
H.visible_message("<span class='notice'>[H] [H.vore_selected.vore_verb]s the [source] into their [H.vore_selected]</span>",
"<span class='notice'>You [H.vore_selected.vore_verb]s the [source] into your [H.vore_selected]</span>")
source.forceMove(H.vore_selected)
else
H.visible_message("<span class='notice'>[H] consumes the [source].")
qdel(source)
+8
View File
@@ -154,3 +154,11 @@
/datum/quirk/longtimer/on_spawn()
var/mob/living/carbon/C = quirk_holder
C.generate_fake_scars(rand(min_scars, max_scars))
/datum/quirk/trashcan
name = "Trashcan"
desc = "You are able to consume and digest trash."
value = 0
gain_text = "<span class='notice'>You feel like munching on a can of soda.</span>"
lose_text = "<span class='notice'>You no longer feel like you should be eating trash.</span>"
mob_trait = TRAIT_TRASHCAN
+1
View File
@@ -166,6 +166,7 @@
on_pulse(wire, user)
/datum/wires/proc/pulse_color(color, mob/living/user)
set waitfor = FALSE
LAZYINITLIST(current_users)
if(current_users[user])
return FALSE
+9 -4
View File
@@ -711,10 +711,15 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
update_playercounts()
if (storyteller.should_inject_antag())
SSblackbox.record_feedback("tally","dynamic",1,"Attempted midround injections")
var/list/drafted_rules = storyteller.midround_draft()
if (drafted_rules.len > 0)
SSblackbox.record_feedback("tally","dynamic",1,"Successful midround injections")
picking_midround_latejoin_rule(drafted_rules)
do_midround_injection()
/datum/game_mode/dynamic/proc/do_midround_injection()
set waitfor = FALSE
var/list/drafted_rules = storyteller.midround_draft()
if (drafted_rules.len > 0)
SSblackbox.record_feedback("tally","dynamic",1,"Successful midround injections")
picking_midround_latejoin_rule(drafted_rules)
/// Updates current_players.
/datum/game_mode/dynamic/proc/update_playercounts()
+8 -4
View File
@@ -105,14 +105,18 @@
if(tempgang != gang)
tempgang.message_gangtools("WARNING: [gang.name] Gang takeover imminent. Their dominator at [domloc.map_name] must be destroyed!",1,1)
else
Cinematic(CINEMATIC_MALF,world) //Here is the gang victory trigger on the dominator ending.
gang.winner = TRUE
SSticker.news_report = GANG_VICTORY
SSticker.force_ending = TRUE
endgame()
if(!.)
STOP_PROCESSING(SSmachines, src)
/obj/machinery/dominator/proc/endgame()
set waitfor = FALSE
Cinematic(CINEMATIC_MALF,world) //Here is the gang victory trigger on the dominator ending.
gang.winner = TRUE
SSticker.news_report = GANG_VICTORY
SSticker.force_ending = TRUE
/obj/machinery/dominator/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
+8 -4
View File
@@ -173,10 +173,7 @@
clonemind.transfer_to(H)
else if(get_clone_mind == CLONEPOD_POLL_MIND)
var/list/candidates = pollCandidatesForMob("Do you want to play as [clonename]'s defective clone? (Don't ERP without permission from the original)", null, null, null, 100, H, POLL_IGNORE_CLONE)
if(LAZYLEN(candidates))
var/mob/C = pick(candidates)
H.key = C.key
poll_for_mind(H, clonename)
if(grab_ghost_when == CLONER_FRESH_CLONE)
H.grab_ghost()
@@ -206,6 +203,13 @@
attempting = FALSE
return TRUE
/obj/machinery/clonepod/proc/poll_for_mind(mob/living/carbon/human/H, clonename)
set waitfor = FALSE
var/list/candidates = pollCandidatesForMob("Do you want to play as [clonename]'s defective clone? (Don't ERP without permission from the original)", null, null, null, 100, H, POLL_IGNORE_CLONE)
if(LAZYLEN(candidates))
var/mob/C = pick(candidates)
H.key = C.key
//Grow clones to maturity then kick them out. FREELOADERS
/obj/machinery/clonepod/process()
var/mob/living/mob_occupant = occupant
+1
View File
@@ -34,6 +34,7 @@
* Initiates launching sequence by checking if all components are functional, opening poddoors, firing mass drivers and then closing poddoors
*/
/obj/machinery/computer/pod/proc/alarm()
set waitfor = FALSE
if(stat & (NOPOWER|BROKEN))
return
@@ -459,11 +459,11 @@
else if(iscarbon(A))
var/mob/living/carbon/C = A
//If not emagged, only target carbons that can use items
if(mode != TURRET_LETHAL && (C.stat || C.handcuffed || !(C.mobility_flags & MOBILITY_USE)))
//If not on lethal, only target carbons that aren't cuffed nor stamcrit or just plain crit.
if(mode != TURRET_LETHAL && (C.stat || C.handcuffed || IS_STAMCRIT(C)))
continue
//If emagged, target all but dead carbons
//If on lethal, target all but dead carbons
if(mode == TURRET_LETHAL && C.stat == DEAD)
continue
@@ -503,6 +503,7 @@
return 1
/obj/machinery/porta_turret/proc/popUp() //pops the turret up
set waitfor = FALSE
if(!anchored)
return
if(raising || raised)
@@ -521,6 +522,7 @@
layer = MOB_LAYER
/obj/machinery/porta_turret/proc/popDown() //pops the turret down
set waitfor = FALSE
if(raising || !raised)
return
if(stat & BROKEN)
+1
View File
@@ -288,6 +288,7 @@
qdel(src)
/obj/item/bombcore/proc/defuse()
set waitfor = FALSE
//Note: Because of how var/defused is used you shouldn't override this UNLESS you intend to set the var to 0 or
// otherwise remove the core/reset the wires before the end of defuse(). It will repeatedly be called otherwise.
-2
View File
@@ -70,7 +70,6 @@
cell.charge = INFINITY
max_integrity = INFINITY
obj_integrity = max_integrity
CHECK_TICK //Just to be on the safe side lag wise
else
if(cell.charge < cell.maxcharge)
for(var/obj/effect/clockwork/sigil/transmission/T in range(SIGIL_ACCESS_RANGE, src))
@@ -80,7 +79,6 @@
adjust_clockwork_power(-delta)
if(obj_integrity < max_integrity && istype(loc, /turf/open/floor/clockwork))
obj_integrity += min(max_integrity - obj_integrity, max_integrity / 200)
CHECK_TICK
/obj/mecha/combat/neovgre/Initialize()
.=..()
+2 -1
View File
@@ -9,6 +9,7 @@
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
layer = ABOVE_NORMAL_TURF_LAYER
var/turf/target
var/acid_level = 0 // Removed from obj, so it goes here now
/obj/effect/acid/Initialize(mapload, acid_pwr, acid_amt)
@@ -42,7 +43,7 @@
for(var/obj/O in target)
if(prob(20) && !(resistance_flags & UNACIDABLE))
if(O.acid_level < acid_level*0.3)
if(O.acid_level() < acid_level*0.3)
var/acid_used = min(acid_level*0.05, 20)
O.acid_act(10, acid_used)
acid_level = max(0, acid_level - acid_used*10)
+53 -22
View File
@@ -24,55 +24,86 @@
var/range = 3
var/hits_left = 3
var/range_left = 3
var/firstmove = TRUE
var/list/hit
/obj/effect/decal/chempuff/blob_act(obj/structure/blob/B)
return
/obj/effect/decal/chempuff/Initialize(mapload, stream_mode, speed, range, hits_left)
/obj/effect/decal/chempuff/Initialize(mapload, stream_mode, speed, range, hits_left, size)
. = ..()
create_reagents(size, NONE, NO_REAGENTS_VALUE)
stream = stream_mode
src.speed = speed
src.range = src.range_left = range
src.hits_left = hits_left
hit = list()
/obj/effect/decal/chempuff/proc/hit_thing(atom/A)
/obj/effect/decal/chempuff/Destroy()
hit = null
return ..()
/// proc called to handle us hitting something
/obj/effect/decal/chempuff/proc/hit_thing(atom/A, bump_hit)
// if the thing is invisible it usually is abstract/underfloor. also, don't hit ourselves.
if(A == src || A.invisibility)
return
if(!hits_left)
// don't hit anything on the first move unless overridden (see: we're colliding a wall blocking our move out of the first tile)
if(firstmove && !bump_hit)
return
if(stream)
if(ismob(A))
var/mob/M = A
if(!M.lying || !range_left)
reagents.reaction(M, VAPOR)
hits_left--
else
if(!range_left)
reagents.reaction(A, VAPOR)
else
reagents.reaction(A)
if(ismob(A))
hits_left--
// we're out of hits or we already hit it
if(!hits_left || hit[A])
return
var/living = isliving(A)
// if it's not dense and we're a stream instead of a mist, and we're not out of range
if(!A.density && stream && range_left && !bump_hit)
return
// non living mobs are effectively abstract
if(ismob(A) && !living)
return
hit[A] = TRUE
reagents.reaction(A, VAPOR)
// mobs absorb enough to decrement hits_left, as well as stuff blocking us.
if(ismob(A) || bump_hit)
hits_left--
/obj/effect/decal/chempuff/Crossed(atom/movable/AM, oldloc)
. = ..()
// bump things moving into us as long as we're not on our first move/moving out of origin tile
hit_thing(AM)
/obj/effect/decal/chempuff/Bump(atom/A)
. = ..()
// if we hit something blocking our movement, collide it regardless even if we're still on our origin tile
hit_thing(A, TRUE)
/obj/effect/decal/chempuff/proc/run_puff(atom/target)
set waitfor = FALSE
for(var/i in 1 to range)
var/safety = 255
while(range_left)
if(!safety--)
CRASH("Spray ran out of safety.")
// move towards new turf
step_towards(src, target)
if(firstmove)
// mark first movement so future Cross()es result in collisions
firstmove = FALSE
// decrement range
range_left--
// if we got nullspaced, exit
if(!isturf(loc))
break
// hit everything in it
for(var/atom/T in loc)
hit_thing(T)
// if we got deleted or ran out of hits, stop
if(!hits_left || !isturf(loc))
break
if(hits_left && isturf(loc) && (!stream || !range_left))
reagents.reaction(loc, VAPOR)
hits_left--
if(!hits_left)
if(!hits_left || !isturf(loc))
// yeah yeah sue me it's copypasted code but I don't want to declare a var.
break
// hit the turf
hit_thing(loc)
sleep(speed)
qdel(src)
/obj/effect/decal/fakelattice
@@ -17,7 +17,7 @@
line = null
if(qdel_in)
QDEL_IN(PB, qdel_in)
d
/obj/effect/projectile/tracer
name = "beam"
icon = 'icons/obj/projectiles_tracer.dmi'
-9
View File
@@ -352,15 +352,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
C.update_damage_overlays()
return
if(acid_level > 20 && ismob(loc))// so we can still remove the clothes on us that have acid.
var/mob/living/carbon/C = user
if(istype(C))
if(!C.gloves || (!(C.gloves.resistance_flags & (UNACIDABLE|ACID_PROOF))))
to_chat(user, "<span class='warning'>The acid on [src] burns your hand!</span>")
var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm")
if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage
C.update_damage_overlays()
if(!(interaction_flags_item & INTERACT_ITEM_ATTACK_HAND_PICKUP)) //See if we're supposed to auto pickup.
return
+4
View File
@@ -387,6 +387,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM
throwforce = 0
grind_results = list(/datum/reagent/carbon = 2)
/obj/item/cigbutt/Initialize()
. = ..()
AddElement(/datum/element/trash)
/obj/item/cigbutt/cigarbutt
name = "cigar butt"
desc = "A manky old cigar butt."
+6 -3
View File
@@ -1,6 +1,8 @@
/obj/item/restraints
breakouttime = 600
var/demoralize_criminals = TRUE // checked on carbon/carbon.dm to decide wheter to apply the handcuffed negative moodlet or not.
/// allow movement at all during breakout
var/allow_breakout_movement = FALSE
/obj/item/restraints/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] is strangling [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -243,6 +245,7 @@
throwforce = 0
w_class = WEIGHT_CLASS_NORMAL
slowdown = 7
allow_breakout_movement = TRUE
breakouttime = 300 //Deciseconds = 30s = 0.5 minute
/obj/item/restraints/legcuffs/proc/on_removed()
@@ -312,7 +315,7 @@
trap_damage = 0
item_flags = DROPDEL
flags_1 = NONE
breakouttime = 25
breakouttime = 50
/obj/item/restraints/legcuffs/beartrap/energy/New()
..()
@@ -328,7 +331,7 @@
. = ..()
/obj/item/restraints/legcuffs/beartrap/energy/cyborg
breakouttime = 20 // Cyborgs shouldn't have a strong restraint
breakouttime = 40 // Cyborgs shouldn't have a strong restraint
/obj/item/restraints/legcuffs/bola
name = "bola"
@@ -379,7 +382,7 @@
icon_state = "ebola"
hitsound = 'sound/weapons/taserhit.ogg'
w_class = WEIGHT_CLASS_SMALL
breakouttime = 25
breakouttime = 50
/obj/item/restraints/legcuffs/bola/energy/on_removed()
do_sparks(1, TRUE, src)
+12
View File
@@ -457,6 +457,18 @@
playsound(src.loc, on_sound, 50, 1)
add_fingerprint(user)
/obj/item/melee/classic_baton/telescopic/newspaper
name = "The Daily Whiplash"
desc = "A newspaper wrapped around a telescopic baton in such a way that it looks like you're beating people with a rolled up newspaper."
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "newspaper"
lefthand_file = 'icons/mob/inhands/misc/books_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/books_righthand.dmi'
on_sound = 'sound/weapons/batonextend.ogg'
on_icon_state = "newspaper2"
off_icon_state = "newspaper"
on_item_state = "newspaper"
/obj/item/melee/classic_baton/telescopic/contractor_baton
name = "contractor baton"
desc = "A compact, specialised baton assigned to Syndicate contractors. Applies light electrical shocks to targets."
+118 -44
View File
@@ -612,6 +612,12 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
icon_state = "kobold"
item_state = "kobold"
/obj/item/toy/plush/lizardplushie/kobold
name = "spacelizard plushie"
desc = "An adorable stuffed toy that resembles a lizard in a suit."
icon_state = "plushie_spacelizard"
item_state = "plushie_spacelizard"
/obj/item/toy/plush/nukeplushie
name = "operative plushie"
desc = "A stuffed toy that resembles a syndicate nuclear operative. The tag claims operatives to be purely fictitious."
@@ -643,17 +649,17 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
/obj/item/toy/plush/beeplushie
name = "bee plushie"
desc = "A cute toy that resembles an even cuter bee."
icon_state = "plushie_h"
item_state = "plushie_h"
icon_state = "plushie_bee"
item_state = "plushie_bee"
attack_verb = list("stung")
gender = FEMALE
squeak_override = list('modular_citadel/sound/voice/scream_moth.ogg' = 1)
/obj/item/toy/plush/mothplushie
name = "insect plushie"
name = "moth plushie"
desc = "An adorable stuffed toy that resembles some kind of insect."
icon_state = "bumble"
item_state = "bumble"
icon_state = "moff"
item_state = "moff"
squeak_override = list('modular_citadel/sound/voice/mothsqueak.ogg' = 1)
can_random_spawn = FALSE
@@ -665,6 +671,20 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
attack_verb = list("lit", "flickered", "flashed")
squeak_override = list('sound/weapons/magout.ogg' = 1)
/obj/item/toy/plush/drake
name = "drake plushie"
desc = "A large beast from lavaland turned into a marketable plushie!"
icon_state = "drake"
item_state = "drake"
attack_verb = list("bit", "devoured", "burned")
/obj/item/toy/plush/deer
name = "deer plushie"
desc = "Oh deer, a plushie!"
icon_state = "deer"
item_state = "deer"
attack_verb = list("bleated", "rammed", "kicked")
/obj/item/toy/plush/box
name = "cardboard plushie"
desc = "A toy box plushie, it holds cotten. Only a baddie would place a bomb through the postal system..."
@@ -694,7 +714,7 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
attack_verb = list("scanned", "beeped", "stared")
/obj/item/toy/plush/borgplushie
name = "robot plushie"
name = "K9 plushie"
desc = "An adorable stuffed toy of a robot."
icon_state = "securityk9"
item_state = "securityk9"
@@ -702,25 +722,28 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
squeak_override = list('sound/machines/beep.ogg' = 1)
/obj/item/toy/plush/borgplushie/medihound
name = "medihound plushie"
icon_state = "medihound"
item_state = "medihound"
/obj/item/toy/plush/borgplushie/scrubpuppy
name = "scrubpuppy plushie"
icon_state = "scrubpuppy"
item_state = "scrubpuppy"
/obj/item/toy/plush/borgplushie/pupdozer
name = "pupdozer plushie"
icon_state = "pupdozer"
item_state = "pupdozer"
/obj/item/toy/plush/aiplush
name = "AI plushie"
desc = "A little stuffed toy AI core... it appears to be malfunctioning."
icon_state = "exo"
item_state = "exo"
icon_state = "malfai"
item_state = "malfai"
attack_verb = list("hacked", "detonated", "overloaded")
squeak_override = list('sound/machines/beep.ogg' = 9, 'sound/machines/buzz-two.ogg' = 1)
/obj/item/toy/plush/mammal/fox
icon_state = "fox"
item_state = "fox"
/obj/item/toy/plush/snakeplushie
name = "snake plushie"
desc = "An adorable stuffed toy that resembles a snake. Not to be mistaken for the real thing."
@@ -732,6 +755,72 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
/obj/item/toy/plush/mammal
name = "mammal plushie"
desc = "An adorable stuffed toy resembling some sort of crew member."
icon_state = "ych"
item_state = "ych"
can_random_spawn = FALSE
/obj/item/toy/plush/mammal/fox
name = "fox plushie"
desc = "An adorable stuffed toy resembling a fox."
icon_state = "fox"
item_state = "fox"
attack_verb = list("yipped", "geckered", "yapped")
/obj/item/toy/plush/mammal/dog
name = "dog plushie"
icon_state = "corgi"
item_state = "corgi"
desc = "An adorable stuffed toy that resembles a dog."
attack_verb = list("barked", "boofed", "borked")
squeak_override = list(
'modular_citadel/sound/voice/bark1.ogg' = 1,
'modular_citadel/sound/voice/bark2.ogg' = 1
)
/obj/item/toy/plush/mammal/dog/fcorgi
name = "corgi plushie"
icon_state = "girlycorgi"
item_state = "girlycorgi"
desc = "An adorable stuffed toy that resembles a dog. This one dons a pink ribbon."
/obj/item/toy/plush/mammal/dog/borgi
name = "borgi plushie"
icon_state = "borgi"
item_state = "borgi"
desc = "An adorable stuffed toy that resembles a robot dog."
/obj/item/toy/plush/xeno
name = "xenohybrid plushie"
desc = "An adorable stuffed toy that resembles a xenomorphic crewmember."
icon_state = "xeno"
item_state = "xeno"
squeak_override = list('sound/voice/hiss2.ogg' = 1)
can_random_spawn = FALSE
/obj/item/toy/plush/bird
name = "bird plushie"
desc = "An adorable stuffed plushie that resembles an avian."
icon_state = "bird"
item_state = "bird"
attack_verb = list("peeped", "beeped", "poofed")
squeak_override = list('modular_citadel/sound/voice/peep.ogg' = 1)
can_random_spawn = FALSE
/obj/item/toy/plush/sergal
name = "sergal plushie"
desc = "An adorable stuffed plushie that resembles a sagaru."
icon_state = "sergal"
item_state = "sergal"
squeak_override = list('modular_citadel/sound/voice/merp.ogg' = 1)
can_random_spawn = FALSE
/obj/item/toy/plush/catgirl
name = "feline plushie"
desc = "An adorable stuffed toy that resembles a feline."
icon_state = "cat"
item_state = "cat"
attack_verb = list("headbutt", "scritched", "bit")
squeak_override = list('modular_citadel/sound/voice/nya.ogg' = 1)
can_random_spawn = FALSE
/obj/item/toy/plush/catgirl/fermis
@@ -742,40 +831,25 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
attack_verb = list("cuddled", "petpatted", "wigglepurred")
squeak_override = list('modular_citadel/sound/voice/merowr.ogg' = 1)
/obj/item/toy/plush/xeno
name = "xenohybrid plushie"
desc = "An adorable stuffed toy that resmembles a xenomorphic crewmember."
squeak_override = list('sound/voice/hiss2.ogg' = 1)
can_random_spawn = FALSE
/obj/item/toy/plush/teddybear
name = "teddy"
desc = "It's a teddy bear!"
icon_state = "teddy"
item_state = "teddy"
/obj/item/toy/plush/bird
name = "bird plushie"
desc = "An adorable stuffed plushie that resembles an avian."
attack_verb = list("peeped", "beeped", "poofed")
squeak_override = list('modular_citadel/sound/voice/peep.ogg' = 1)
can_random_spawn = FALSE
/obj/item/toy/plush/sergal
name = "sergal plushie"
desc = "An adorable stuffed plushie that resembles a sagaru."
squeak_override = list('modular_citadel/sound/voice/merp.ogg' = 1)
can_random_spawn = FALSE
/obj/item/toy/plush/mammal/dog
desc = "An adorable stuffed toy that resembles a canine."
attack_verb = list("barked", "boofed", "borked")
squeak_override = list(
'modular_citadel/sound/voice/bark1.ogg' = 1,
'modular_citadel/sound/voice/bark2.ogg' = 1
)
/obj/item/toy/plush/catgirl
name = "feline plushie"
desc = "An adorable stuffed toy that resembles a feline."
attack_verb = list("headbutt", "scritched", "bit")
squeak_override = list('modular_citadel/sound/voice/nya.ogg' = 1)
can_random_spawn = FALSE
/obj/item/toy/plush/crab
name = "crab plushie"
desc = "Fewer pinches than a real one, but it still clicks."
icon_state = "crab"
item_state = "crab"
attack_verb = list("clicked", "clacked", "pinched")
/obj/item/toy/plush/gondola
name = "gondola plushie"
desc = "Just looking at it seems to calm you down. Please do not eat it though."
icon_state = "gondola"
item_state = "gondola"
attack_verb = list("calmed", "smiled", "peaced")
/obj/item/toy/plush/hairball
name = "Hairball"
@@ -266,6 +266,7 @@
. += tank.icon_state
/obj/item/pneumatic_cannon/proc/fill_with_type(type, amount)
set waitfor = FALSE
if(!ispath(type, /obj) && !ispath(type, /mob))
return FALSE
var/loaded = 0
@@ -13,6 +13,7 @@
GLOBAL_LIST_INIT(human_recipes, list( \
new/datum/stack_recipe("bloated human costume", /obj/item/clothing/suit/hooded/bloated_human, 5), \
new/datum/stack_recipe("human skin hat", /obj/item/clothing/head/human_leather, 1), \
))
/obj/item/stack/sheet/animalhide/human/get_main_recipes()
@@ -179,6 +179,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
GLOBAL_LIST_INIT(plasteel_recipes, list ( \
new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = TRUE), \
new/datum/stack_recipe("bomb assembly", /obj/machinery/syndicatebomb/empty, 10, time = 50), \
new/datum/stack_recipe("plasteel keg", /obj/structure/custom_keg, 10, time = 50), \
new/datum/stack_recipe("micro powered fan assembly", /obj/machinery/fan_assembly, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
new /datum/stack_recipe_list("crates", list( \
new /datum/stack_recipe("gray crate", /obj/structure/closet/crate, 5, time = 50, one_per_turf = 1, on_floor = 1), \
+6
View File
@@ -67,6 +67,12 @@
item_state = "crowbar"
toolspeed = 0.5
/obj/item/crowbar/large/heavy
name = "heavy crowbar"
desc = "It's a big crowbar. It doesn't fit in your pockets, because it's big. It feels oddly heavy.."
force = 20
icon_state = "crowbar_powergame"
/obj/item/crowbar/cyborg
name = "hydraulic crowbar"
desc = "A hydraulic prying tool, compact but powerful. Designed to replace crowbar in construction cyborgs."
+24 -7
View File
@@ -23,13 +23,13 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
var/random_color = TRUE
var/static/list/wirecutter_colors = list(
"blue" = "#1861d5",
"red" = "#951710",
"pink" = "#d5188d",
"brown" = "#a05212",
"green" = "#0e7f1b",
"cyan" = "#18a2d5",
"yellow" = "#d58c18"
"blue" = rgb(24, 97, 213),
"red" = rgb(255, 0, 0),
"pink" = rgb(213, 24, 141),
"brown" = rgb(160, 82, 18),
"green" = rgb(14, 127, 27),
"cyan" = rgb(24, 162, 213),
"yellow" = rgb(255, 165, 0)
)
@@ -49,6 +49,23 @@
base_overlay.appearance_flags = RESET_COLOR
. += base_overlay
/obj/item/wirecutters/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(isinhands && random_color)
var/mutable_appearance/M = mutable_appearance(icon_file, "cutters_cutty_thingy")
M.appearance_flags = RESET_COLOR
. += M
/obj/item/wirecutters/get_belt_overlay()
if(random_color)
var/mutable_appearance/body = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "cutters")
var/mutable_appearance/head = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "cutters_cutty_thingy")
body.color = color
head.add_overlay(body)
return head
else
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state)
/obj/item/wirecutters/attack(mob/living/carbon/C, mob/user)
if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/restraints/handcuffs/cable))
user.visible_message("<span class='notice'>[user] cuts [C]'s restraints with [src]!</span>")
+4 -3
View File
@@ -7,6 +7,10 @@
w_class = WEIGHT_CLASS_TINY
resistance_flags = FLAMMABLE
/obj/item/trash/Initialize()
. = ..()
AddElement(/datum/element/trash)
/obj/item/trash/raisins
name = "\improper 4no raisins"
icon_state= "4no_raisins"
@@ -80,6 +84,3 @@
name = "boritos bag"
icon_state = "boritos"
grind_results = list(/datum/reagent/aluminium = 1) //from the mylar bag
/obj/item/trash/attack(mob/M, mob/living/user)
return
+11 -20
View File
@@ -204,32 +204,23 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
//the obj's reaction when touched by acid
/obj/acid_act(acidpwr, acid_volume)
if(!(resistance_flags & UNACIDABLE) && acid_volume)
if(!acid_level)
SSacid.processing[src] = src
update_icon()
var/acid_cap = acidpwr * 300 //so we cannot use huge amounts of weak acids to do as well as strong acids.
if(acid_level < acid_cap)
acid_level = min(acid_level + acidpwr * acid_volume, acid_cap)
AddComponent(/datum/component/acid, acidpwr, acid_volume)
return 1
//the proc called by the acid subsystem to process the acid that's on the obj
/obj/proc/acid_processing()
. = 1
if(!(resistance_flags & ACID_PROOF))
if(prob(33))
playsound(loc, 'sound/items/welder.ogg', 150, 1)
take_damage(min(1 + round(sqrt(acid_level)*0.3), 300), BURN, "acid", 0)
acid_level = max(acid_level - (5 + 3*round(sqrt(acid_level))), 0)
if(!acid_level)
return 0
//called when the obj is destroyed by acid.
/obj/proc/acid_melt()
SSacid.processing -= src
var/datum/component/acid/acid = GetComponent(/datum/component/acid)
if(acid)
acid.RemoveComponent()
deconstruct(FALSE)
/obj/proc/acid_level()
var/datum/component/acid/acid = GetComponent(/datum/component/acid)
if(acid)
return acid.level
else
return 0
//// FIRE
/obj/fire_act(exposed_temperature, exposed_volume)
-4
View File
@@ -22,8 +22,6 @@
var/resistance_flags = NONE // INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ON_FIRE | UNACIDABLE | ACID_PROOF
var/acid_level = 0 //how much acid is on that obj
var/persistence_replacement //have something WAY too amazing to live to the next round? Set a new path here. Overuse of this var will make me upset.
var/current_skin //the item reskin
var/list/unique_reskin //List of options to reskin.
@@ -369,8 +367,6 @@
/obj/update_overlays()
. = ..()
if(acid_level)
. += GLOB.acid_overlay
if(resistance_flags & ON_FIRE)
. += GLOB.fire_overlay
+27 -7
View File
@@ -48,14 +48,34 @@
return // no message spam
..()
/obj/structure/mirror/attacked_by(obj/item/I, mob/living/user)
if(broken || !istype(user) || !I.force)
return ..()
. = ..()
if(broken) // breaking a mirror truly gets you bad luck!
to_chat(user, "<span class='warning'>A chill runs down your spine as [src] shatters...</span>")
user.AddComponent(/datum/component/omen, silent=TRUE) // we have our own message
/obj/structure/mirror/bullet_act(obj/item/projectile/P)
if(broken || !isliving(P.firer) || !P.damage)
return ..()
. = ..()
if(broken) // breaking a mirror truly gets you bad luck!
var/mob/living/unlucky_dude = P.firer
to_chat(unlucky_dude, "<span class='warning'>A chill runs down your spine as [src] shatters...</span>")
unlucky_dude.AddComponent(/datum/component/omen, silent=TRUE) // we have our own message
/obj/structure/mirror/obj_break(damage_flag, mapload)
if(!broken && !(flags_1 & NODECONSTRUCT_1))
icon_state = "mirror_broke"
if(!mapload)
playsound(src, "shatter", 70, 1)
if(desc == initial(desc))
desc = "Oh no, seven years of bad luck!"
broken = TRUE
if(broken || (flags_1 & NODECONSTRUCT_1))
return
icon_state = "mirror_broke"
if(!mapload)
playsound(src, "shatter", 70, TRUE)
if(desc == initial(desc))
desc = "Oh no, seven years of bad luck!"
broken = TRUE
/obj/structure/mirror/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
@@ -121,6 +121,7 @@
/obj/structure/transit_tube/station/proc/launch_pod()
set waitfor = FALSE
if(launch_cooldown >= world.time)
return
for(var/obj/structure/transit_tube_pod/pod in loc)
+7 -5
View File
@@ -354,10 +354,10 @@
. = SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
. = O.clean_blood()
O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
if(isitem(O))
var/obj/item/I = O
I.acid_level = 0
I.extinguish()
var/datum/component/acid/acid = O.GetComponent(/datum/component/acid)
if(acid)
acid.level = 0
O.extinguish()
/obj/machinery/shower/proc/wash_turf()
if(isturf(loc))
@@ -601,7 +601,9 @@
busy = FALSE
SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
O.clean_blood()
O.acid_level = 0
var/datum/component/acid/acid = O.GetComponent(/datum/component/acid)
if(acid)
acid.level = 0
create_reagents(5)
reagents.add_reagent(dispensedreagent, 5)
reagents.reaction(O, TOUCH)
+1 -1
View File
@@ -72,7 +72,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
// basic doesn't initialize and this will cause issues
// no warning though because this can happen naturaly as a result of it being built on top of
path = /turf/open/space
if(!GLOB.use_preloader && path == type && !(flags & CHANGETURF_FORCEOP)) // Don't no-op if the map loader requires it to be reconstructed
if(!GLOB.use_preloader && path == type && !(flags & CHANGETURF_FORCEOP) && (baseturfs == new_baseturfs)) // Don't no-op if the map loader requires it to be reconstructed, or if this is a new set of baseturfs
return src
if(flags & CHANGETURF_SKIP)
return new path(src)
@@ -96,6 +96,7 @@ GLOBAL_LIST_EMPTY(antagonists)
//Proc called when the datum is given to a mind.
/datum/antagonist/proc/on_gain()
set waitfor = FALSE
if(!(owner?.current))
return
if(!silent)
@@ -225,18 +225,22 @@
return ..()
/obj/effect/clockwork/sigil/transmission/process()
var/power_drained = 0
var/power_mod = 0.005
for(var/t in spiral_range_turfs(SIGIL_ACCESS_RANGE, src))
var/turf/T = t
for(var/M in T)
var/atom/movable/A = M
power_drained += A.power_drain(TRUE)
do_process()
CHECK_TICK
/obj/effect/clockwork/sigil/transmission/proc/do_process()
set waitfor = FALSE
var/power_drained = 0
var/power_mod = 0.005
for(var/t in spiral_range_turfs(SIGIL_ACCESS_RANGE, src))
var/turf/T = t
for(var/M in T)
var/atom/movable/A = M
power_drained += A.power_drain(TRUE)
adjust_clockwork_power(power_drained * power_mod * 15)
new /obj/effect/temp_visual/ratvar/sigil/transmission(loc, 1 + (power_drained * 0.0035))
CHECK_TICK
adjust_clockwork_power(power_drained * power_mod * 15)
new /obj/effect/temp_visual/ratvar/sigil/transmission(loc, 1 + (power_drained * 0.0035))
/obj/effect/clockwork/sigil/transmission/proc/charge_cyborg(mob/living/silicon/robot/cyborg)
if(!cyborg_checks(cyborg))
@@ -246,6 +246,36 @@
if(GATEWAY_RATVAR_COMING to INFINITY)
. += "<span class='boldwarning'>The anomaly is stable! Something is coming through!</span>"
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/fulfill_purpose()
set waitfor = FALSE
countdown.stop()
resistance_flags |= INDESTRUCTIBLE
purpose_fulfilled = TRUE
make_glow()
animate(glow, transform = matrix() * 1.5, alpha = 255, time = 125)
sound_to_playing_players(volume = 100, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/ratvar_rises.ogg')) //End the sounds
sleep(125)
make_glow()
animate(glow, transform = matrix() * 3, alpha = 0, time = 5)
QDEL_IN(src, 3)
sleep(3)
GLOB.clockwork_gateway_activated = TRUE
var/turf/T = SSmapping.get_station_center()
new /obj/structure/destructible/clockwork/massive/ratvar(T)
var/x0 = T.x
var/y0 = T.y
for(var/I in spiral_range_turfs(255, T, tick_checked = TRUE))
var/turf/T2 = I
if(!T2)
continue
var/dist = cheap_hypotenuse(T2.x, T2.y, x0, y0)
if(dist < 100)
dist = TRUE
else
dist = FALSE
T.ratvar_act(dist)
CHECK_TICK
/obj/structure/destructible/clockwork/massive/celestial_gateway/process()
adjust_clockwork_power(2.5) //Provides weak power generation on its own
if(seconds_until_activation)
@@ -306,33 +336,7 @@
glow.icon_state = "clockwork_gateway_closing"
if(GATEWAY_RATVAR_ARRIVAL to INFINITY)
if(!purpose_fulfilled)
countdown.stop()
resistance_flags |= INDESTRUCTIBLE
purpose_fulfilled = TRUE
make_glow()
animate(glow, transform = matrix() * 1.5, alpha = 255, time = 125)
sound_to_playing_players(volume = 100, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/ratvar_rises.ogg')) //End the sounds
sleep(125)
make_glow()
animate(glow, transform = matrix() * 3, alpha = 0, time = 5)
QDEL_IN(src, 3)
sleep(3)
GLOB.clockwork_gateway_activated = TRUE
var/turf/T = SSmapping.get_station_center()
new /obj/structure/destructible/clockwork/massive/ratvar(T)
var/x0 = T.x
var/y0 = T.y
for(var/I in spiral_range_turfs(255, T, tick_checked = TRUE))
var/turf/T2 = I
if(!T2)
continue
var/dist = cheap_hypotenuse(T2.x, T2.y, x0, y0)
if(dist < 100)
dist = TRUE
else
dist = FALSE
T.ratvar_act(dist)
CHECK_TICK
fulfill_purpose()
//Converts nearby turfs into their clockwork equivalent, with ever-increasing range the closer the ark is to summoning Ratvar
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/conversion_pulse()
@@ -60,12 +60,8 @@
delay_remaining += PRISM_DELAY_DURATION
toggle(0, user)
/obj/structure/destructible/clockwork/powered/prolonging_prism/process()
var/turf/own_turf = get_turf(src)
if(SSshuttle.emergency.mode != SHUTTLE_CALL || delay_remaining <= 0 || !own_turf || !is_station_level(own_turf.z))
forced_disable(FALSE)
return
. = ..()
/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/do_process()
set waitfor = FALSE
var/delay_amount = 40
delay_remaining -= delay_amount
var/efficiency = get_efficiency_mod()
@@ -114,6 +110,14 @@
new /obj/effect/temp_visual/ratvar/prolonging_prism(T)
CHECK_TICK //we may be going over a hell of a lot of turfs
/obj/structure/destructible/clockwork/powered/prolonging_prism/process()
var/turf/own_turf = get_turf(src)
if(SSshuttle.emergency.mode != SHUTTLE_CALL || delay_remaining <= 0 || !own_turf || !is_station_level(own_turf.z))
forced_disable(FALSE)
return
. = ..()
do_process()
/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/get_delay_cost()
return FLOOR(delay_cost, MIN_CLOCKCULT_POWER)
@@ -110,6 +110,7 @@
//Put me in Reebe, will you? Ratvar has found and is going to do a hecking murder on Nar'Sie
/obj/structure/destructible/clockwork/massive/ratvar/proc/clash_of_the_titans(obj/singularity/narsie/narsie)
set waitfor = FALSE
var/winner = "Undeclared"
var/base_victory_chance = 1
while(src && narsie)
@@ -204,26 +204,31 @@
STOP_PROCESSING(SSfastprocess, src)
return ..()
/obj/structure/destructible/cult/pylon/proc/heal_friends()
set waitfor = FALSE
for(var/mob/living/L in range(5, src))
if(iscultist(L) || isshade(L) || isconstruct(L))
if(L.health != L.maxHealth)
new /obj/effect/temp_visual/heal(get_turf(src), "#960000")
if(ishuman(L))
L.adjustBruteLoss(-1, 0, only_organic = FALSE)
L.adjustFireLoss(-1, 0, only_organic = FALSE)
L.updatehealth()
if(isshade(L) || isconstruct(L))
var/mob/living/simple_animal/M = L
if(M.health < M.maxHealth)
M.adjustHealth(-3)
if(ishuman(L) && L.blood_volume < (BLOOD_VOLUME_NORMAL * L.blood_ratio))
L.blood_volume += 1.0
CHECK_TICK
/obj/structure/destructible/cult/pylon/process()
if(!anchored)
return
if(last_heal <= world.time)
last_heal = world.time + heal_delay
for(var/mob/living/L in range(5, src))
if(iscultist(L) || isshade(L) || isconstruct(L))
if(L.health != L.maxHealth)
new /obj/effect/temp_visual/heal(get_turf(src), "#960000")
if(ishuman(L))
L.adjustBruteLoss(-1, 0, only_organic = FALSE)
L.adjustFireLoss(-1, 0, only_organic = FALSE)
L.updatehealth()
if(isshade(L) || isconstruct(L))
var/mob/living/simple_animal/M = L
if(M.health < M.maxHealth)
M.adjustHealth(-3)
if(ishuman(L) && L.blood_volume < (BLOOD_VOLUME_NORMAL * L.blood_ratio))
L.blood_volume += 1.0
CHECK_TICK
heal_friends()
if(last_corrupt <= world.time)
var/list/validturfs = list()
var/list/cultturfs = list()
-1
View File
@@ -515,7 +515,6 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
var/mob/living/silicon/robot_devil = owner.current
var/laws = list("You may not use violence to coerce someone into selling their soul.", "You may not directly and knowingly physically harm a devil, other than yourself.", GLOB.lawlorify[LAW][ban], GLOB.lawlorify[LAW][obligation], "Accomplish your objectives at all costs.")
robot_devil.set_law_sixsixsix(laws)
sleep(10)
if(owner.assigned_role == "Clown" && ishuman(owner.current))
var/mob/living/carbon/human/S = owner.current
to_chat(S, "<span class='notice'>Your infernal nature has allowed you to overcome your clownishness.</span>")
@@ -401,6 +401,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
next_announce += DOOMSDAY_ANNOUNCE_INTERVAL
/obj/machinery/doomsday_device/proc/detonate()
set waitfor = FALSE
sound_to_playing_players('sound/machines/alarm.ogg')
sleep(100)
for(var/i in GLOB.mob_living_list)
+1
View File
@@ -197,6 +197,7 @@
//Here's the main proc itself
/mob/living/carbon/human/proc/mob_climax(forced_climax=FALSE,cause = "") //Forced is instead of the other proc, makes you cum if you have the tools for it, ignoring restraints
set waitfor = FALSE
if(mb_cd_timer > world.time)
if(!forced_climax) //Don't spam the message to the victim if forced to come too fast
to_chat(src, "<span class='warning'>You need to wait [DisplayTimeText((mb_cd_timer - world.time), TRUE)] before you can do that again!</span>")
+1
View File
@@ -81,6 +81,7 @@
return
/obj/item/assembly/infra/proc/refreshBeam()
set waitfor = FALSE
QDEL_LIST(beams)
if(throwing || !on || !secured)
return
@@ -13,7 +13,7 @@
if(!air)
return
if (air.get_oxidation_power(exposed_temperature) < 0.5)
if (air.get_oxidation_power(exposed_temperature) < 0.5 || air.get_moles(GAS_HYPERNOB) > 5)
return
var/has_fuel = air.get_moles(GAS_PLASMA) > 0.5 || air.get_moles(GAS_TRITIUM) > 0.5 || air.get_fuel_amount(exposed_temperature) > 0.5
if(active_hotspot)
@@ -152,7 +152,7 @@
if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1))
qdel(src)
return
if(!location.air || location.air.get_oxidation_power() < 0.5 || (INSUFFICIENT(GAS_PLASMA) && INSUFFICIENT(GAS_TRITIUM) && location.air.get_fuel_amount() < 0.5))
if(!location.air || location.air.get_moles(GAS_HYPERNOB) > 5 || location.air.get_oxidation_power() < 0.5 || (INSUFFICIENT(GAS_PLASMA) && INSUFFICIENT(GAS_TRITIUM) && location.air.get_fuel_amount() < 0.5))
qdel(src)
return
+5
View File
@@ -187,6 +187,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/vore_flags = 0
var/list/belly_prefs = list()
var/vore_taste = "nothing in particular"
var/vore_smell = null
var/toggleeatingnoise = TRUE
var/toggledigestionnoise = TRUE
var/hound_sleeper = TRUE
@@ -1068,6 +1069,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<b>Voracious MediHound sleepers:</b> <a href='?_src_=prefs;preference=hound_sleeper'>[(cit_toggles & MEDIHOUND_SLEEPER) ? "Yes" : "No"]</a><br>"
dat += "<b>Hear Vore Sounds:</b> <a href='?_src_=prefs;preference=toggleeatingnoise'>[(cit_toggles & EATING_NOISES) ? "Yes" : "No"]</a><br>"
dat += "<b>Hear Vore Digestion Sounds:</b> <a href='?_src_=prefs;preference=toggledigestionnoise'>[(cit_toggles & DIGESTION_NOISES) ? "Yes" : "No"]</a><br>"
dat += "<b>Allow trash forcefeeding (requires Trashcan quirk)</b> <a href='?_src_=prefs;preference=toggleforcefeedtrash'>[(cit_toggles & TRASH_FORCEFEED) ? "Yes" : "No"]</a><br>"
dat += "<b>Forced Feminization:</b> <a href='?_src_=prefs;preference=feminization'>[(cit_toggles & FORCED_FEM) ? "Allowed" : "Disallowed"]</a><br>"
dat += "<b>Forced Masculinization:</b> <a href='?_src_=prefs;preference=masculinization'>[(cit_toggles & FORCED_MASC) ? "Allowed" : "Disallowed"]</a><br>"
dat += "<b>Lewd Hypno:</b> <a href='?_src_=prefs;preference=hypno'>[(cit_toggles & HYPNO) ? "Allowed" : "Disallowed"]</a><br>"
@@ -2800,6 +2802,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("toggledigestionnoise")
cit_toggles ^= DIGESTION_NOISES
if("toggleforcefeedtrash")
cit_toggles ^= TRASH_FORCEFEED
if("breast_enlargement")
cit_toggles ^= BREAST_ENLARGEMENT
@@ -821,6 +821,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["vore_flags"] >> vore_flags
S["vore_taste"] >> vore_taste
S["vore_smell"] >> vore_smell
var/char_vr_path = "[vr_path]/character_[default_slot]_v2.json"
if(fexists(char_vr_path))
var/list/json_from_file = json_decode(file2text(char_vr_path))
@@ -994,6 +995,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
vore_flags = sanitize_integer(vore_flags, 0, MAX_VORE_FLAG, 0)
vore_taste = copytext(vore_taste, 1, MAX_TASTE_LEN)
vore_smell = copytext(vore_smell, 1, MAX_TASTE_LEN)
belly_prefs = SANITIZE_LIST(belly_prefs)
cit_character_pref_load(S)
@@ -1147,6 +1149,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["vore_flags"] , vore_flags)
WRITE_FILE(S["vore_taste"] , vore_taste)
WRITE_FILE(S["vore_smell"] , vore_smell)
var/char_vr_path = "[vr_path]/character_[default_slot]_v2.json"
var/belly_prefs_json = safe_json_encode(list("belly_prefs" = belly_prefs))
if(fexists(char_vr_path))
+6
View File
@@ -482,3 +482,9 @@
icon_state = "kabuto"
item_state = "kabuto"
flags_inv = HIDEHAIR|HIDEEARS
/obj/item/clothing/head/human_leather
name = "human skin hat"
desc = "This will scare them. All will know my power."
icon_state = "human_leather"
item_state = "human_leather"
+1 -1
View File
@@ -5,7 +5,7 @@
weight = 8
/datum/round_event/cat_surgeon/announce(fake)
priority_announce("One of our... ahem... 'special' cases has escaped. Our sensors now show their tracker implant on your station. On an unrelated note, has anyone seen our cats?",
priority_announce("One of our... ahem... 'special' cases has escaped. As it happens their last known location before their tracker went dead is your station so keep an eye out for them. On an unrelated note, has anyone seen our cats?",
sender_override = "Nanotrasen Psych Ward")
/datum/round_event/cat_surgeon/start()
+4 -1
View File
@@ -56,7 +56,10 @@
next_boss_spawn = startWhen + CEILING(2 * number_of_hostiles / number_of_bosses, 1)
/datum/round_event/portal_storm/announce(fake)
set waitfor = 0
do_announce()
/datum/round_event/portal_storm/proc/do_announce()
set waitfor = FALSE
sound_to_playing_players('sound/magic/lightning_chargeup.ogg')
sleep(80)
priority_announce("Massive bluespace anomaly detected en route to [station_name()]. Brace for impact.")
+1 -2
View File
@@ -7,5 +7,4 @@
/datum/round_event/wizard/fake_explosion/start()
sound_to_playing_players('sound/machines/alarm.ogg')
sleep(100)
Cinematic(CINEMATIC_NUKE_FAKE,world)
addtimer(CALLBACK(GLOBAL_PROC,.proc/Cinematic, CINEMATIC_NUKE_FAKE, world), 100)
+6 -2
View File
@@ -64,7 +64,8 @@
pass = FALSE
return pass
/datum/proximity_monitor/advanced/process()
/datum/proximity_monitor/advanced/proc/lag_checked_process()
set waitfor = FALSE
if(process_inner_turfs)
for(var/turf/T in field_turfs)
process_inner_turf(T)
@@ -72,7 +73,10 @@
if(process_edge_turfs)
for(var/turf/T in edge_turfs)
process_edge_turf(T)
CHECK_TICK //Same here.
CHECK_TICK //Same here.
/datum/proximity_monitor/advanced/process()
lag_checked_process()
/datum/proximity_monitor/advanced/proc/process_inner_turf(turf/T)
@@ -73,3 +73,40 @@
icon_state = "barrel_open"
else
icon_state = "barrel"
/obj/structure/custom_keg
name = "Plasteel Keg"
desc = "A large plasteel keg. You can use it to hold liquids. You may wanna label this, too."
icon = 'icons/obj/objects.dmi'
icon_state = "keg"
density = TRUE
anchored = FALSE
pressure_resistance = 2 * ONE_ATMOSPHERE
max_integrity = 300
var/open = FALSE
/obj/structure/custom_keg/Initialize()
create_reagents(1000, DRAINABLE | AMOUNT_VISIBLE)
. = ..()
/obj/structure/custom_keg/examine(mob/user)
. = ..()
. += "<span class='notice'>It is currently [open?"open, letting you pour liquids in.":"closed, letting you draw liquids from the tap."]</span>"
/obj/structure/custom_keg/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
open = !open
if(open)
DISABLE_BITFIELD(reagents.reagents_holder_flags, DRAINABLE)
ENABLE_BITFIELD(reagents.reagents_holder_flags, REFILLABLE)
to_chat(user, "<span class='notice'>You open [src], letting you fill it.</span>")
else
DISABLE_BITFIELD(reagents.reagents_holder_flags, REFILLABLE)
ENABLE_BITFIELD(reagents.reagents_holder_flags, DRAINABLE)
to_chat(user, "<span class='notice'>You close [src], letting you draw from its tap.</span>")
update_icon()
/obj/structure/custom_keg/update_icon_state()
if(open)
icon_state = "keg_open"
else
icon_state = "keg"
+1
View File
@@ -391,6 +391,7 @@
mutate(4, 10, 2, 4, 50, 4, 10, 3)
/obj/machinery/hydroponics/proc/mutatespecie() // Mutagent produced a new plant!
set waitfor = FALSE
if(!myseed || dead)
return
@@ -23,14 +23,14 @@
ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS,
ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_MAINT_TUNNELS, ACCESS_BAR, ACCESS_JANITOR, ACCESS_CONSTRUCTION, ACCESS_MORGUE,
ACCESS_CREMATORIUM, ACCESS_KITCHEN, ACCESS_HYDROPONICS, ACCESS_LAWYER,
ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_VAULT, ACCESS_MINING_STATION,
ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM)
ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_VAULT,
ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY)
minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_COURT, ACCESS_WEAPONS,
ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS,
ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_MAINT_TUNNELS, ACCESS_BAR, ACCESS_JANITOR, ACCESS_CONSTRUCTION, ACCESS_MORGUE,
ACCESS_CREMATORIUM, ACCESS_KITCHEN, ACCESS_HYDROPONICS, ACCESS_LAWYER,
ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_VAULT, ACCESS_MINING_STATION,
ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM)
ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_VAULT,
ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY)
paycheck = PAYCHECK_COMMAND
paycheck_department = ACCOUNT_SRV
+1 -1
View File
@@ -25,7 +25,7 @@
minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINING,
ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_KEYCARD_AUTH, ACCESS_RC_ANNOUNCE,
ACCESS_SEC_DOORS, ACCESS_HEADS)
paycheck = PAYCHECK_HARD //They can already buy stuff using cargo budget, don't give em a command-level paycheck.
paycheck = PAYCHECK_HARD //They can already buy stuff using cargo budget, don't give em a command-level paycheck. //alright i'll agree to that -qweq
paycheck_department = ACCOUNT_CAR
display_order = JOB_DISPLAY_ORDER_QUARTERMASTER
@@ -89,6 +89,11 @@
name = "large empty capsule"
desc = "An extremly large capsule which requires power. Useful for projects all over."
template_id = "shelter_delta"
/obj/item/survivalcapsule/luxury/penthouse
name = "penthouse bluespace sheler capsule"
desc = "The absolute pinnacle of luxury in terms of survival capsules. While exuberantly expensive it has everything needed to make a small home in lavaland."
template_id = "shelter_epsilon"
//Pod objects
//Window
@@ -61,37 +61,32 @@
new /obj/item/guardiancreator(src)
/obj/structure/closet/crate/necropolis/tendril/weapon_armor/PopulateContents()
var/loot = rand(1,11)
var/loot = rand(1,10)
switch(loot)
if(1)
new /obj/item/clothing/suit/space/hardsuit/cult(src)
if(2)
new /obj/item/katana/lavaland(src)
if(3)
if(prob(50))
new /obj/item/disk/design_disk/modkit_disc/resonator_blast(src)
else
new /obj/item/disk/design_disk/modkit_disc/rapid_repeater(src)
if(4)
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker/old(src)
if(5)
if(4)
new /obj/item/nullrod/scythe/talking(src)
if(6)
if(5)
new /obj/item/nullrod/armblade(src)
if(7)
if(6)
new /obj/item/reagent_containers/food/drinks/bottle/holywater/hell(src)
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor/old(src)
if(8)
if(7)
new /obj/item/grenade/clusterbuster/inferno(src)
if(9)
if(8)
new /obj/item/gun/magic/wand/book/shock(src)
if(10)
if(9)
new /obj/item/gun/magic/wand/book/page(src)
if(11)
if(10)
new /obj/item/gun/magic/wand/book/spark(src)
/obj/structure/closet/crate/necropolis/tendril/misc/PopulateContents()
var/loot = rand(1,14)
var/loot = rand(1,12)
switch(loot)
if(1)
new /obj/item/shared_storage/red(src)
@@ -106,31 +101,21 @@
if(6)
new /obj/item/jacobs_ladder(src)
if(7)
if(prob(50))
new /obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe(src)
else
new /obj/item/disk/design_disk/modkit_disc/bounty(src)
if(8)
new /obj/item/wisp_lantern(src)
if(9)
if(8)
new /obj/item/pickaxe/rosegold(src)
if(10)
if(9)
new /obj/item/bedsheet/cosmos(src)
new /obj/item/melee/skateboard/hoverboard(src)
if(11)
if(10)
new /obj/item/disk/tech_disk/illegal(src)
if(12)
if(11)
new /obj/item/clothing/suit/space/hardsuit/cult(src)
if(13)
if(12)
new /obj/item/katana/lavaland(src)
if(14)
if(prob(50))
new /obj/item/disk/design_disk/modkit_disc/resonator_blast(src)
else
new /obj/item/disk/design_disk/modkit_disc/rapid_repeater(src)
/obj/structure/closet/crate/necropolis/tendril/all/PopulateContents()
var/loot = rand(1,29)
var/loot = rand(1,28)
switch(loot)
if(1)
new /obj/item/shared_storage/red(src)
@@ -145,56 +130,51 @@
if(6)
new /obj/item/jacobs_ladder(src)
if(7)
if(prob(50))
new /obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe(src)
else
new /obj/item/disk/design_disk/modkit_disc/bounty(src)
if(8)
new /obj/item/wisp_lantern(src)
if(9)
if(8)
new /obj/item/pickaxe/rosegold(src)
if(10)
if(9)
new /obj/item/bedsheet/cosmos(src)
new /obj/item/melee/skateboard/hoverboard(src)
if(11)
if(10)
new /obj/item/disk/tech_disk/illegal(src)
if(12)
if(11)
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker/old(src)
if(13)
if(12)
new /obj/item/nullrod/scythe/talking(src)
if(14)
if(13)
new /obj/item/nullrod/armblade(src)
if(15)
if(14)
new /obj/item/reagent_containers/food/drinks/bottle/holywater/hell(src)
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor/old(src)
if(16)
if(15)
new /obj/item/grenade/clusterbuster/inferno(src)
if(17)
if(16)
new /obj/item/gun/magic/wand/book/shock(src)
if(18)
if(17)
new /obj/item/gun/magic/wand/book/page(src)
if(19)
if(18)
new /obj/item/gun/magic/wand/book/spark(src)
if(20)
if(19)
new /obj/item/soulstone/anybody(src)
if(21)
if(20)
new /obj/item/rod_of_asclepius(src)
if(22)
if(21)
new /obj/item/organ/heart/cursed/wizard(src)
if(23)
if(22)
new /obj/item/book/granter/spell/summonitem(src)
if(24)
if(23)
new /obj/item/borg/upgrade/modkit/lifesteal(src)
new /obj/item/bedsheet/cult(src)
if(25)
if(24)
new /obj/item/clothing/neck/necklace/memento_mori(src)
if(26)
if(25)
new /obj/item/warp_cube/red(src)
if(27)
if(26)
new /obj/item/immortality_talisman(src)
if(28)
if(27)
new /obj/item/gun/magic/wand/book/healing(src)
if(29)
if(28)
new /obj/item/guardiancreator(src)
//KA modkit design discs
+6 -2
View File
@@ -145,8 +145,11 @@
D.createmessage("Ore Redemption Machine", "New minerals available!", msg, 1, 0)
/obj/machinery/mineral/ore_redemption/process()
if(!materials.mat_container || panel_open || !powered())
return
if(materials.mat_container && !panel_open && powered())
process_all_ores()
/obj/machinery/mineral/ore_redemption/proc/process_all_ores()
set waitfor = FALSE
var/atom/input = get_step(src, input_dir)
var/obj/structure/ore_box/OB = locate() in input
if(OB)
@@ -165,6 +168,7 @@
else if(!message_sent)
send_console_message()
/obj/machinery/mineral/ore_redemption/attackby(obj/item/W, mob/user, params)
if(default_unfasten_wrench(user, W))
return
+18 -15
View File
@@ -10,22 +10,25 @@
output_dir = EAST
speed_process = TRUE
/obj/machinery/mineral/unloading_machine/process()
var/turf/T = get_step(src,input_dir)
if(T)
var/limit
for(var/obj/structure/ore_box/B in T)
for (var/obj/item/stack/ore/O in B)
B.contents -= O
unload_mineral(O)
limit++
if (limit>=10)
return
CHECK_TICK
CHECK_TICK
for(var/obj/item/I in T)
unload_mineral(I)
/obj/machinery/mineral/unloading_machine/proc/horrible_quadratic_monster(var/turf/T)
set waitfor = FALSE
var/limit = 0
for(var/obj/structure/ore_box/B in T)
for (var/obj/item/stack/ore/O in B)
B.contents -= O
unload_mineral(O)
limit++
if (limit>=10)
return
CHECK_TICK
for(var/obj/item/I in T)
unload_mineral(I)
limit++
if (limit>=10)
return
CHECK_TICK
/obj/machinery/mineral/unloading_machine/process()
var/turf/T = get_step(src,input_dir)
if(T)
horrible_quadratic_monster(T)
+1
View File
@@ -57,6 +57,7 @@
new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/survivalcapsule/luxury, 3000),
new /datum/data/mining_equipment("Luxury Bar Capsule", /obj/item/survivalcapsule/luxury/elitebar, 10000),
new /datum/data/mining_equipment("Empty Capsule", /obj/item/survivalcapsule/luxury/empty, 5000),
new /datum/data/mining_equipment("Penthouse Capsule", /obj/item/survivalcapsule/luxury/penthouse, 15000),
new /datum/data/mining_equipment("Nanotrasen Minebot", /mob/living/simple_animal/hostile/mining_drone, 800),
new /datum/data/mining_equipment("Minebot Melee Upgrade", /obj/item/mine_bot_upgrade, 400),
new /datum/data/mining_equipment("Minebot Armor Upgrade", /obj/item/mine_bot_upgrade/health, 400),
+3 -2
View File
@@ -64,8 +64,6 @@
if(materials.use_amount_mat(coin_mat, chosen))
for(var/coin_to_make in 1 to 5)
create_coins()
produced_coins++
CHECK_TICK
else
var/found_new = FALSE
for(var/datum/material/inserted_material in materials.materials)
@@ -131,6 +129,7 @@
return TRUE
/obj/machinery/mineral/mint/proc/create_coins()
set waitfor = FALSE
var/turf/T = get_step(src,output_dir)
var/temp_list = list()
temp_list[chosen] = 400
@@ -143,3 +142,5 @@
O.forceMove(bag_to_use) //don't bother sending the signal, the new bag is empty and all that.
SSblackbox.record_feedback("amount", "coins_minted", 1)
produced_coins++
CHECK_TICK
+11
View File
@@ -85,3 +85,14 @@
. = ..()
whitelisted_turfs = typecacheof(/turf/closed/mineral)
banned_objects = typecacheof(/obj/structure/stone_tile)
/datum/map_template/shelter/epsilon
name = "Shelter Epsilon"
shelter_id = "shelter_epsilon"
description = "A small apartment in the palm of your hand."
mappath = "_maps/templates/shelter_5.dmm"
/datum/map_template/shelter/epsilon/New()
. = ..()
whitelisted_turfs = typecacheof(/turf/closed/mineral)
banned_objects = typecacheof(/obj/structure/stone_tile)
@@ -679,7 +679,7 @@
icon_state = "crow"
matrixed_sections = MATRIX_RED
/datum/sprite_accessory/tails/mam_tail/cow
/datum/sprite_accessory/tails/mam_tails/cow
name = "Cow"
icon_state = "cow"
matrixed_sections = MATRIX_RED
+11 -3
View File
@@ -358,7 +358,7 @@
return
I.item_flags |= BEING_REMOVED
breakouttime = I.breakouttime
var/datum/cuffbreak_checker/cuffbreak_checker = new(get_turf(src))
var/datum/cuffbreak_checker/cuffbreak_checker = new(get_turf(src), istype(I, /obj/item/restraints)? I : null)
if(!cuff_break)
visible_message("<span class='warning'>[src] attempts to remove [I]!</span>")
to_chat(src, "<span class='notice'>You attempt to remove [I]... (This will take around [DisplayTimeText(breakouttime)] and you need to stand still.)</span>")
@@ -384,16 +384,22 @@
/datum/cuffbreak_checker
var/turf/last
var/obj/item/restraints/cuffs
/datum/cuffbreak_checker/New(turf/initial_turf)
/datum/cuffbreak_checker/New(turf/initial_turf, obj/item/restraints/R)
last = initial_turf
if(R)
cuffs = R
/datum/cuffbreak_checker/proc/check_movement(atom/user, delay, atom/target, time_left, do_after_flags, required_mobility_flags, required_combat_flags, mob_redirect, stage, initially_held_item, tool, list/passed_in)
if(get_turf(user) != last)
last = get_turf(user)
passed_in[1] = 0.5
if(cuffs && !cuffs.allow_breakout_movement)
return DO_AFTER_STOP
else
passed_in[1] = 1
return DO_AFTER_CONTINUE
/mob/living/carbon/proc/uncuff()
if (handcuffed)
@@ -961,7 +967,9 @@
/mob/living/carbon/ExtinguishMob()
for(var/X in get_equipped_items())
var/obj/item/I = X
I.acid_level = 0 //washes off the acid on our clothes
var/datum/component/acid/acid = I.GetComponent(/datum/component/acid)
if(acid)
acid.level = 0
I.extinguish() //extinguishes our clothes
..()
@@ -1101,9 +1101,9 @@
if(HAS_TRAIT(src, TRAIT_TOXINLOVER))
return "<font color='#00ffff'>"
if(isplasmaman(src))
return "<font color='#800080'"
return "<font color='#800080'>"
if(isgolem(src))
return "<font color='#8b4513'"
return "<font color='#8b4513'>"
return "<font color='#18d855'>"
@@ -15,7 +15,6 @@
block_parry_data = /datum/block_parry_data/unarmed/human
default_block_parry_data = /datum/block_parry_data/unarmed/human
causes_dirt_buildup_on_floor = TRUE
//Hair colour and style
var/hair_color = "000"
@@ -52,6 +51,9 @@
var/obj/item/l_store = null
var/obj/item/s_store = null
/// When an braindead player has their equipment fiddled with, we log that info here for when they come back so they know who took their ID while they were DC'd for 30 seconds
var/list/afk_thefts
var/special_voice = "" // For changing our voice. Used by a symptom.
var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding
@@ -90,13 +90,31 @@
//End bloody footprints
S.step_action()
if(movement_type & GROUND)
dirt_buildup()
/mob/living/carbon/human/Process_Spacemove(movement_dir = 0) //Temporary laziness thing. Will change to handles by species reee.
if(dna.species.space_move(src))
return TRUE
return ..()
/mob/living/carbon/human/dirt_buildup(strength)
/mob/living/carbon/human/proc/dirt_buildup(strength = 1)
if(!shoes || !(shoes.body_parts_covered & FEET))
return // barefoot advantage
return ..()
var/turf/open/T = loc
if(!istype(T) || !T.dirt_buildup_allowed)
return
var/area/A = T.loc
if(!A.dirt_buildup_allowed)
return
var/multiplier = CONFIG_GET(number/turf_dirty_multiplier)
strength *= multiplier
var/obj/effect/decal/cleanable/dirt/D = locate() in T
if(D)
D.dirty(strength)
else
T.dirtyness += strength
if(T.dirtyness >= (isnull(T.dirt_spawn_threshold)? CONFIG_GET(number/turf_dirt_threshold) : T.dirt_spawn_threshold))
D = new /obj/effect/decal/cleanable/dirt(T)
D.dirty(T.dirt_spawn_threshold - T.dirtyness)
T.dirtyness = 0 // reset.
@@ -2,3 +2,33 @@
..()
if(dna?.species?.has_field_of_vision && CONFIG_GET(flag/use_field_of_vision))
LoadComponent(/datum/component/field_of_vision, field_of_vision_type)
if(!LAZYLEN(afk_thefts))
return
var/list/print_msg = list()
print_msg += "<span class='info'>*---------*</span>"
print_msg += "<span class='userdanger'>As you snap back to consciousness, you recall people messing with your stuff...</span>"
afk_thefts = reverseRange(afk_thefts)
for(var/list/iter_theft as anything in afk_thefts)
if(!islist(iter_theft) || LAZYLEN(iter_theft) != AFK_THEFT_TIME)
stack_trace("[src] ([ckey]) returned to their body and had a null/malformed afk_theft entry. Contents: [json_encode(iter_theft)]")
continue
var/thief_name = iter_theft[AFK_THEFT_NAME]
var/theft_message = iter_theft[AFK_THEFT_MESSAGE]
var/time_since = world.time - iter_theft[AFK_THEFT_TIME]
if(time_since > AFK_THEFT_FORGET_DETAILS_TIME)
print_msg += "\t<span class='danger'><b>Someone [theft_message], but it was at least [DisplayTimeText(AFK_THEFT_FORGET_DETAILS_TIME)] ago.</b></span>"
else
print_msg += "\t<span class='danger'><b>[thief_name] [theft_message] roughly [DisplayTimeText(time_since, 10)] ago.</b></span>"
if(LAZYLEN(afk_thefts) >= AFK_THEFT_MAX_MESSAGES)
print_msg += "<span class='warning'>There may have been more, but that's all you can remember...</span>"
print_msg += "<span class='info'>*---------*</span>"
to_chat(src, print_msg.Join("\n"))
LAZYNULL(afk_thefts)
+13
View File
@@ -911,6 +911,12 @@
"<span class='userdanger'>[src] tries to remove your [what.name].</span>", target = src,
target_message = "<span class='danger'>You try to remove [who]'s [what.name].</span>")
what.add_fingerprint(src)
if(ishuman(who))
var/mob/living/carbon/human/victim_human = who
if(victim_human.key && !victim_human.client) // AKA braindead
if(victim_human.stat <= SOFT_CRIT && LAZYLEN(victim_human.afk_thefts) <= AFK_THEFT_MAX_MESSAGES)
var/list/new_entry = list(list(src.name, "tried unequipping your [what]", world.time))
LAZYADD(victim_human.afk_thefts, new_entry)
else
to_chat(src,"<span class='notice'>You try to remove [who]'s [what.name].</span>")
what.add_fingerprint(src)
@@ -957,6 +963,13 @@
to_chat(src, "<span class='warning'>\The [what.name] doesn't fit in that place!</span>")
return
if(ishuman(who))
var/mob/living/carbon/human/victim_human = who
if(victim_human.key && !victim_human.client) // AKA braindead
if(victim_human.stat <= SOFT_CRIT && LAZYLEN(victim_human.afk_thefts) <= AFK_THEFT_MAX_MESSAGES)
var/list/new_entry = list(list(src.name, "tried equipping you with [what]", world.time))
LAZYADD(victim_human.afk_thefts, new_entry)
who.visible_message("<span class='notice'>[src] tries to put [what] on [who].</span>",
"<span class='notice'>[src] tries to put [what] on you.</span>", target = src,
target_message = "<span class='notice'>You try to put [what] on [who].</span>")
@@ -67,8 +67,6 @@
//Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects.
var/incorporeal_move = FALSE //FALSE is off, INCORPOREAL_MOVE_BASIC is normal, INCORPOREAL_MOVE_SHADOW is for ninjas
//and INCORPOREAL_MOVE_JAUNT is blocked by holy water/salt
/// Do we make floors dirty as we move?
var/causes_dirt_buildup_on_floor = FALSE
var/list/roundstart_quirks = list()
@@ -102,31 +102,6 @@
if(lying && !buckled && prob(getBruteLoss()*200/maxHealth))
makeTrail(newloc, T, old_direction)
if(causes_dirt_buildup_on_floor && (movement_type & GROUND))
dirt_buildup()
/**
* Attempts to make the floor dirty.
*/
/mob/living/proc/dirt_buildup(strength = 1)
var/turf/open/T = loc
if(!istype(T) || !T.dirt_buildup_allowed)
return
var/area/A = T.loc
if(!A.dirt_buildup_allowed)
return
var/multiplier = CONFIG_GET(number/turf_dirty_multiplier)
strength *= multiplier
var/obj/effect/decal/cleanable/dirt/D = locate() in T
if(D)
D.dirty(strength)
else
T.dirtyness += strength
if(T.dirtyness >= (isnull(T.dirt_spawn_threshold)? CONFIG_GET(number/turf_dirt_threshold) : T.dirt_spawn_threshold))
D = new /obj/effect/decal/cleanable/dirt(T)
D.dirty(T.dirt_spawn_threshold - T.dirtyness)
T.dirtyness = 0 // reset.
/mob/living/Move_Pulled(atom/A)
. = ..()
if(!. || !isliving(A))
+1
View File
@@ -182,6 +182,7 @@
. = ..()
/mob/living/silicon/ai/proc/set_core_display_icon(input, client/C)
set waitfor = FALSE
if(client && !C)
C = client
if(!input && !C?.prefs?.preferred_ai_core_display)
@@ -133,6 +133,10 @@
chance_to_hold_onto_points = highest_cost*0.5
if(points != max_points && prob(chance_to_hold_onto_points))
return //Let's save our points for a better ability (unless we're at max points, in which case we can't save anymore!)
do_ability()
/datum/boss_active_timed_battle/proc/do_ability()
set waitfor = FALSE
if(!boss.client)
abilities = shuffle(abilities)
for(var/ab in abilities)
@@ -364,11 +364,10 @@
/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) && CHECK_BITFIELD(L.vore_flags,DEVOURABLE)) // aggressive check to ensure vore attacks can be made
if(!client && L.Adjacent(src) && CHECK_BITFIELD(L.vore_flags, DEVOURABLE) && CHECK_BITFIELD(L.vore_flags, MOBVORE)) // aggressive check to ensure vore attacks can be made
if(prob(voracious_chance))
vore_attack(src,L,src)
else
@@ -379,7 +378,6 @@
return target.attack_animal(src)
else
return target.attack_animal(src)
*/
return target.attack_animal(src)
/mob/living/simple_animal/hostile/proc/Aggro()
@@ -40,8 +40,10 @@ Difficulty: Medium
ranged = 1
ranged_cooldown_time = 16
pixel_x = -16
crusher_loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator/premiumka, /obj/item/crusher_trophy/miner_eye)
loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator/premiumka)
crusher_loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator/premiumka, /obj/item/crusher_trophy/miner_eye, /obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe,
/obj/item/disk/design_disk/modkit_disc/bounty,/obj/item/disk/design_disk/modkit_disc/resonator_blast,/obj/item/disk/design_disk/modkit_disc/rapid_repeater)
loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator/premiumka,/obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe,
/obj/item/disk/design_disk/modkit_disc/bounty,/obj/item/disk/design_disk/modkit_disc/resonator_blast,/obj/item/disk/design_disk/modkit_disc/rapid_repeater)
wander = FALSE
del_on_death = TRUE
blood_volume = BLOOD_VOLUME_NORMAL
@@ -26,8 +26,10 @@ Difficulty: Extremely Hard
speed = 20
move_to_delay = 20
ranged = TRUE
crusher_loot = list(/obj/effect/decal/remains/plasma, /obj/item/crusher_trophy/ice_block_talisman)
loot = list(/obj/effect/decal/remains/plasma)
crusher_loot = list(/obj/effect/decal/remains/plasma, /obj/item/crusher_trophy/ice_block_talisman, ,/obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe,
/obj/item/disk/design_disk/modkit_disc/bounty,/obj/item/disk/design_disk/modkit_disc/resonator_blast,/obj/item/disk/design_disk/modkit_disc/rapid_repeater)
loot = list(/obj/effect/decal/remains/plasma, ,/obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe,
/obj/item/disk/design_disk/modkit_disc/bounty,/obj/item/disk/design_disk/modkit_disc/resonator_blast,/obj/item/disk/design_disk/modkit_disc/rapid_repeater)
wander = FALSE
del_on_death = TRUE
blood_volume = BLOOD_VOLUME_NORMAL
@@ -102,23 +102,13 @@
consume_bait()
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/proc/consume_bait()
var/list/L = list()
for(var/obj/O in view(src, 9))
L += O
var/obj/item/stack/ore/diamond/diamonds = locate(/obj/item/stack/ore/diamond) in L
if(diamonds)
var/distanced = 0
distanced = get_dist(loc,diamonds.loc)
if(distanced <= 1 && diamonds)
qdel(diamonds)
src.visible_message("<span class='notice'>[src] consumes [diamonds], and it disappears! ...At least, you think.</span>")
var/obj/item/pen/survival/bait = locate(/obj/item/pen/survival) in L
if(bait)
var/distanceb = 0
distanceb = get_dist(loc,bait.loc)
if(distanceb <= 1 && bait)
qdel(bait)
visible_message("<span class='notice'>[src] examines [bait] closer, and telekinetically shatters the pen.</span>")
for(var/obj/O in view(1, src))
if(istype(O, /obj/item/stack/ore/diamond))
qdel(O)
src.visible_message("<span class='notice'>[src] consumes [O], and it disappears! ...At least, you think.</span>")
else if(istype(O, /obj/item/pen/survival))
qdel(O)
src.visible_message("<span class='notice'>[src] examines [O] closer, and telekinetically shatters the pen.</span>")
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random/Initialize()
. = ..()
+1 -1
View File
@@ -95,7 +95,7 @@
. = ..()
if((direction & (direction - 1)) && mob.loc == n) //moved diagonally successfully
add_delay *= 2
add_delay *= SQRT_2
mob.set_glide_size(DELAY_TO_GLIDE_SIZE(add_delay), FALSE)
move_delay += add_delay
if(.) // If mob is null here, we deserve the runtime
@@ -349,6 +349,7 @@
// Relays kill program request to currently active program. Use this to quit current program.
/obj/item/modular_computer/proc/kill_program(forced = FALSE)
set waitfor = FALSE
if(active_program)
active_program.kill_program(forced)
active_program = null

Some files were not shown because too many files have changed in this diff Show More